summaryrefslogtreecommitdiffstats
path: root/src/etc/inc/ipsec.inc
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2015-08-25 08:08:24 -0300
committerRenato Botelho <renato@netgate.com>2015-08-25 14:49:54 -0300
commit46bc6e545a17e77202aaf01ec0cd8d5a46567525 (patch)
tree32d18dda436ec739c67c489ceb771e8629cd926f /src/etc/inc/ipsec.inc
parent4d9801c2dbd2b3e54a39578ee62b93af66607227 (diff)
downloadpfsense-46bc6e545a17e77202aaf01ec0cd8d5a46567525.zip
pfsense-46bc6e545a17e77202aaf01ec0cd8d5a46567525.tar.gz
Move main pfSense content to src/
Diffstat (limited to 'src/etc/inc/ipsec.inc')
-rw-r--r--src/etc/inc/ipsec.inc777
1 files changed, 777 insertions, 0 deletions
diff --git a/src/etc/inc/ipsec.inc b/src/etc/inc/ipsec.inc
new file mode 100644
index 0000000..6654166
--- /dev/null
+++ b/src/etc/inc/ipsec.inc
@@ -0,0 +1,777 @@
+<?php
+/*
+ ipsec.inc
+ Copyright (C) 2007 Scott Ullrich
+ Copyright (C) 2008 Shrew Soft Inc
+ All rights reserved.
+
+ Parts of this code was originally based on vpn_ipsec_sad.php
+ Copyright (C) 2003-2004 Manuel Kasper
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ pfSense_BUILDER_BINARIES: /sbin/setkey /sbin/route
+ pfSense_MODULE: ipsec
+
+*/
+
+/* IPsec defines */
+global $ipsec_loglevels;
+$ipsec_loglevels = array("dmn" => "Daemon", "mgr" => "SA Manager", "ike" => "IKE SA", "chd" => "IKE Child SA",
+ "job" => "Job Processing", "cfg" => "Configuration backend", "knl" => "Kernel Interface",
+ "net" => "Networking", "asn" => "ASN encoding", "enc" => "Message encoding",
+ "imc" => "Integrity checker", "imv" => "Integrity Verifier", "pts" => "Platform Trust Service",
+ "tls" => "TLS handler", "esp" => "IPsec traffic", "lib" => "StrongSwan Lib");
+
+global $my_identifier_list;
+$my_identifier_list = array(
+ 'myaddress' => array('desc' => gettext('My IP address'), 'mobile' => true),
+ 'address' => array('desc' => gettext('IP address'), 'mobile' => true),
+ 'fqdn' => array('desc' => gettext('Distinguished name'), 'mobile' => true),
+ 'user_fqdn' => array('desc' => gettext('User distinguished name'), 'mobile' => true),
+ 'asn1dn' => array('desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true),
+ 'keyid tag' => array('desc' => gettext('KeyID tag'), 'mobile' => true),
+ 'dyn_dns' => array('desc' => gettext('Dynamic DNS'), 'mobile' => true));
+
+global $peer_identifier_list;
+$peer_identifier_list = array(
+ 'any' => array('desc' => gettext('Any'), 'mobile' => true),
+ 'peeraddress' => array('desc' => gettext('Peer IP address'), 'mobile' => false),
+ 'address' => array('desc' => gettext('IP address'), 'mobile' => false),
+ 'fqdn' => array('desc' => gettext('Distinguished name'), 'mobile' => true),
+ 'user_fqdn' => array('desc' => gettext('User distinguished name'), 'mobile' => true),
+ 'asn1dn' => array('desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true),
+ 'keyid tag' => array('desc' =>gettext('KeyID tag'), 'mobile' => true));
+
+global $ipsec_idhandling;
+$ipsec_idhandling = array(
+ 'yes' => 'YES', 'no' => 'NO', 'never' => 'NEVER', 'keep' => 'KEEP'
+ );
+
+global $p1_ealgos;
+$p1_ealgos = array(
+ 'aes' => array('name' => 'AES', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
+ 'aes128gcm' => array('name' => 'AES128-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
+ 'aes192gcm' => array('name' => 'AES192-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
+ 'aes256gcm' => array('name' => 'AES256-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
+ 'blowfish' => array('name' => 'Blowfish', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
+ '3des' => array('name' => '3DES'),
+ 'cast128' => array('name' => 'CAST128'),
+ 'des' => array('name' => 'DES'));
+
+global $p2_ealgos;
+$p2_ealgos = array(
+ 'aes' => array('name' => 'AES', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
+ 'aes128gcm' => array('name' => 'AES128-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
+ 'aes192gcm' => array('name' => 'AES192-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
+ 'aes256gcm' => array('name' => 'AES256-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
+ 'blowfish' => array('name' => 'Blowfish', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
+ '3des' => array('name' => '3DES'),
+ 'cast128' => array('name' => 'CAST128'),
+ 'des' => array('name' => 'DES'));
+
+global $p1_halgos;
+$p1_halgos = array(
+ 'md5' => 'MD5',
+ 'sha1' => 'SHA1',
+ 'sha256' => 'SHA256',
+ 'sha384' => 'SHA384',
+ 'sha512' => 'SHA512',
+ 'aesxcbc' => 'AES-XCBC'
+);
+
+global $p1_dhgroups;
+$p1_dhgroups = array(
+ 1 => '1 (768 bit)',
+ 2 => '2 (1024 bit)',
+ 5 => '5 (1536 bit)',
+ 14 => '14 (2048 bit)',
+ 15 => '15 (3072 bit)',
+ 16 => '16 (4096 bit)',
+ 17 => '17 (6144 bit)',
+ 18 => '18 (8192 bit)',
+ 19 => '19 (nist ecp256)',
+ 20 => '20 (nist ecp384)',
+ 21 => '21 (nist ecp521)',
+ 22 => '22 (1024(sub 160) bit)',
+ 23 => '23 (2048(sub 224) bit)',
+ 24 => '24 (2048(sub 256) bit)',
+ 28 => '28 (brainpool ecp256)',
+ 29 => '29 (brainpool ecp384)',
+ 30 => '30 (brainpool ecp512)'
+);
+
+global $p2_halgos;
+$p2_halgos = array(
+ 'hmac_md5' => 'MD5',
+ 'hmac_sha1' => 'SHA1',
+ 'hmac_sha256' => 'SHA256',
+ 'hmac_sha384' => 'SHA384',
+ 'hmac_sha512' => 'SHA512',
+ 'aesxcbc' => 'AES-XCBC'
+);
+
+global $p1_authentication_methods;
+$p1_authentication_methods = array(
+ 'hybrid_rsa_server' => array('name' => 'Hybrid RSA + Xauth', 'mobile' => true),
+ 'xauth_rsa_server' => array('name' => 'Mutual RSA + Xauth', 'mobile' => true),
+ 'xauth_psk_server' => array('name' => 'Mutual PSK + Xauth', 'mobile' => true),
+ 'eap-tls' => array('name' => 'EAP-TLS', 'mobile' => true),
+ 'eap-radius' => array('name' => 'EAP-RADIUS', 'mobile' => true),
+ 'eap-mschapv2' => array('name' => 'EAP-MSChapv2', 'mobile' => true),
+ 'rsasig' => array('name' => 'Mutual RSA', 'mobile' => false),
+ 'pre_shared_key' => array('name' => 'Mutual PSK', 'mobile' => false));
+
+global $ipsec_preshared_key_type;
+$ipsec_preshared_key_type = array(
+ 'PSK' => 'PSK',
+ 'EAP' => 'EAP'
+ );
+
+global $p2_modes;
+$p2_modes = array(
+ 'tunnel' => 'Tunnel IPv4',
+ 'tunnel6' => 'Tunnel IPv6',
+ 'transport' => 'Transport');
+
+global $p2_protos;
+$p2_protos = array(
+ 'esp' => 'ESP',
+ 'ah' => 'AH');
+
+global $p2_pfskeygroups;
+$p2_pfskeygroups = array(
+ 0 => 'off',
+ 1 => '1 (768 bit)',
+ 2 => '2 (1024 bit)',
+ 5 => '5 (1536 bit)',
+ 14 => '14 (2048 bit)',
+ 15 => '15 (3072 bit)',
+ 16 => '16 (4096 bit)',
+ 17 => '17 (6144 bit)',
+ 18 => '18 (8192 bit)',
+ 19 => '19 (nist ecp256)',
+ 20 => '20 (nist ecp384)',
+ 21 => '21 (nist ecp521)',
+ 28 => '28 (brainpool ecp256)',
+ 29 => '29 (brainpool ecp384)',
+ 30 => '30 (brainpool ecp512)'
+);
+
+/*
+ * ikeid management functions
+ */
+
+function ipsec_ikeid_used($ikeid) {
+ global $config;
+
+ foreach ($config['ipsec']['phase1'] as $ph1ent) {
+ if ($ikeid == $ph1ent['ikeid']) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+function ipsec_ikeid_next() {
+
+ $ikeid = 1;
+ while (ipsec_ikeid_used($ikeid)) {
+ $ikeid++;
+ }
+
+ return $ikeid;
+}
+
+/*
+ * Return phase1 local address
+ */
+function ipsec_get_phase1_src(& $ph1ent) {
+
+ if ($ph1ent['interface']) {
+ if (!is_ipaddr($ph1ent['interface'])) {
+ if (strpos($ph1ent['interface'], '_vip')) {
+ $if = $ph1ent['interface'];
+ } else {
+ $if = get_failover_interface($ph1ent['interface']);
+ }
+ if ($ph1ent['protocol'] == "inet6") {
+ $interfaceip = get_interface_ipv6($if);
+ } else {
+ $interfaceip = get_interface_ip($if);
+ }
+ } else {
+ $interfaceip = $ph1ent['interface'];
+ }
+ } else {
+ $if = "wan";
+ if ($ph1ent['protocol'] == "inet6") {
+ $interfaceip = get_interface_ipv6($if);
+ } else {
+ $interfaceip = get_interface_ip($if);
+ }
+ }
+
+ return $interfaceip;
+}
+
+/*
+ * Return phase1 local address
+ */
+function ipsec_get_phase1_dst(& $ph1ent) {
+ global $g;
+
+ if (empty($ph1ent['remote-gateway'])) {
+ return false;
+ }
+ $rg = $ph1ent['remote-gateway'];
+ if (!is_ipaddr($rg)) {
+ if (!platform_booting()) {
+ return resolve_retry($rg);
+ }
+ }
+ if (!is_ipaddr($rg)) {
+ return false;
+ }
+
+ return $rg;
+}
+
+/*
+ * Return phase2 idinfo in cidr format
+ */
+function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
+ global $config;
+
+ switch ($idinfo['type']) {
+ case "address":
+ if ($addrbits) {
+ if ($mode == "tunnel6") {
+ return $idinfo['address']."/128";
+ } else {
+ return $idinfo['address']."/32";
+ }
+ } else {
+ return $idinfo['address'];
+ }
+ break; /* NOTREACHED */
+ case "network":
+ return "{$idinfo['address']}/{$idinfo['netbits']}";
+ break; /* NOTREACHED */
+ case "none":
+ case "mobile":
+ return '0.0.0.0/0';
+ break; /* NOTREACHED */
+ default:
+ if (empty($mode) && !empty($idinfo['mode'])) {
+ $mode = $idinfo['mode'];
+ }
+
+ if ($mode == "tunnel6") {
+ $address = get_interface_ipv6($idinfo['type']);
+ $netbits = get_interface_subnetv6($idinfo['type']);
+ $address = gen_subnetv6($address, $netbits);
+ return "{$address}/{$netbits}";
+ } else {
+ $address = get_interface_ip($idinfo['type']);
+ $netbits = get_interface_subnet($idinfo['type']);
+ $address = gen_subnet($address, $netbits);
+ return "{$address}/{$netbits}";
+ }
+ break; /* NOTREACHED */
+ }
+}
+
+/*
+ * Return phase2 idinfo in address/netmask format
+ */
+function ipsec_idinfo_to_subnet(& $idinfo, $addrbits = false) {
+ global $config;
+
+ switch ($idinfo['type']) {
+ case "address":
+ if ($addrbits) {
+ if ($idinfo['mode'] == "tunnel6") {
+ return $idinfo['address']."/128";
+ } else {
+ return $idinfo['address']."/255.255.255.255";
+ }
+ } else {
+ return $idinfo['address'];
+ }
+ break; /* NOTREACHED */
+ case "none":
+ case "network":
+ return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
+ break; /* NOTREACHED */
+ case "mobile":
+ return "0.0.0.0/0";
+ break; /* NOTREACHED */
+ default:
+ if ($idinfo['mode'] == "tunnel6") {
+ $address = get_interface_ipv6($idinfo['type']);
+ $netbits = get_interface_subnetv6($idinfo['type']);
+ $address = gen_subnetv6($address, $netbits);
+ return $address."/".$netbits;
+ } else {
+ $address = get_interface_ip($idinfo['type']);
+ $netbits = get_interface_subnet($idinfo['type']);
+ $address = gen_subnet($address, $netbits);
+ return $address."/".$netbits;
+ }
+ break; /* NOTREACHED */
+ }
+}
+
+/*
+ * Return phase2 idinfo in text format
+ */
+function ipsec_idinfo_to_text(& $idinfo) {
+ global $config;
+
+ switch ($idinfo['type']) {
+ case "address":
+ return $idinfo['address'];
+ break; /* NOTREACHED */
+ case "network":
+ return $idinfo['address']."/".$idinfo['netbits'];
+ break; /* NOTREACHED */
+ case "mobile":
+ return gettext("Mobile Client");
+ break; /* NOTREACHED */
+ case "none":
+ return gettext("None");
+ break; /* NOTREACHED */
+ default:
+ if (!empty($config['interfaces'][$idinfo['type']])) {
+ return convert_friendly_interface_to_friendly_descr($idinfo['type']);
+ } else {
+ return strtoupper($idinfo['type']);
+ }
+ break; /* NOTREACHED */
+ }
+}
+
+/*
+ * Return phase1 association for phase2
+ */
+function ipsec_lookup_phase1(& $ph2ent, & $ph1ent) {
+ global $config;
+
+ if (!is_array($config['ipsec'])) {
+ return false;
+ }
+ if (!is_array($config['ipsec']['phase1'])) {
+ return false;
+ }
+ if (empty($config['ipsec']['phase1'])) {
+ return false;
+ }
+
+ foreach ($config['ipsec']['phase1'] as $ph1tmp) {
+ if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
+ $ph1ent = $ph1tmp;
+ return $ph1ent;
+ }
+ }
+
+ return false;
+}
+
+/*
+ * Check phase1 communications status
+ */
+function ipsec_phase1_status(&$ipsec_status, $ikeid) {
+
+ foreach ($ipsec_status as $ike) {
+ if ($ike['id'] == $ikeid) {
+ if ($ike['status'] == 'established') {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/*
+ * Check phase2 communications status
+ */
+function ipsec_phase2_status(&$ipsec_status, &$phase2) {
+
+ if (ipsec_lookup_phase1($ph2ent, $ph1ent)) {
+ return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
+ }
+
+ return false;
+}
+
+function ipsec_smp_dump_status() {
+ global $config, $g, $custom_listtags;
+
+ if (isset($config['ipsec']['enable'])) {
+ if (!file_exists("{$g['varrun_path']}/charon.xml")) {
+ log_error("IPsec daemon not running or has a problem!");
+ return;
+ }
+ } else {
+ return;
+ }
+
+ $fd = @fsockopen("unix://{$g['varrun_path']}/charon.xml");
+ if (!$fd) {
+ log_error("Could not read status from IPsec");
+ return;
+ }
+ $query = '<?xml version="1.0"?><message xmlns="http://www.strongswan.org/smp/1.0" type="request" id="1">';
+ $query .= '<query><ikesalist/></query></message>';
+
+ @fwrite($fd, $query);
+ $response = "";
+ while (!strstr($sread, "</message>")) {
+ $sread = fgets($fd);
+ if ($sread === false) {
+ break;
+ }
+ $response .= $sread;
+ }
+ fclose($fd);
+
+ if ($sread === false) {
+ log_error("Error during reading of status from IPsec");
+ return;
+ }
+
+ @file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
+ unset($response, $sread);
+
+ $custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
+ $response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
+ @unlink("{$g['tmp_path']}/smp_status.xml");
+ unset($custom_listtags);
+
+ return $response;
+}
+
+/*
+ * Return dump of SPD table
+ */
+function ipsec_dump_spd() {
+ $fd = @popen("/sbin/setkey -DP", "r");
+ $spd = array();
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = chop(fgets($fd));
+ if (!$line) {
+ continue;
+ }
+ if ($line == "No SPD entries.") {
+ break;
+ }
+ if ($line[0] != "\t") {
+ if (is_array($cursp)) {
+ $spd[] = $cursp;
+ }
+ $cursp = array();
+ $linea = explode(" ", $line);
+ $cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
+ $cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
+ $i = 0;
+ } else if (is_array($cursp)) {
+ $line = trim($line, "\t\r\n ");
+ $linea = explode(" ", $line);
+ switch ($i) {
+ case 1:
+ if ($linea[1] == "none") /* don't show default anti-lockout rule */ {
+ unset($cursp);
+ } else {
+ $cursp['dir'] = $linea[0];
+ }
+ break;
+ case 2:
+ $upperspec = explode("/", $linea[0]);
+ $cursp['proto'] = $upperspec[0];
+ list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
+ $cursp['reqid'] = substr($upperspec[3], strpos($upperspec[3], "#")+1);
+ break;
+ }
+ }
+ $i++;
+ }
+ if (is_array($cursp) && count($cursp)) {
+ $spd[] = $cursp;
+ }
+ pclose($fd);
+ }
+
+ return $spd;
+}
+
+/*
+ * Return dump of SAD table
+ */
+function ipsec_dump_sad() {
+ $fd = @popen("/sbin/setkey -D", "r");
+ $sad = array();
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = chop(fgets($fd));
+ if (!$line || $line[0] == " ") {
+ continue;
+ }
+ if ($line == "No SAD entries.") {
+ break;
+ }
+ if ($line[0] != "\t") {
+ if (is_array($cursa)) {
+ $sad[] = $cursa;
+ }
+ $cursa = array();
+ list($cursa['src'], $cursa['dst']) = explode(" ", $line);
+ } else {
+ $line = trim($line, "\t\n\r ");
+ $linea = explode(" ", $line);
+ foreach ($linea as $idx => $linee) {
+ if ($linee == 'esp' || $linee == 'ah' || $linee[0] == '#') {
+ $cursa['proto'] = $linee;
+ } else if (substr($linee, 0, 3) == 'spi') {
+ $cursa['spi'] = substr($linee, strpos($linee, 'x') + 1, -1);
+ } else if (substr($linee, 0, 5) == 'reqid') {
+ $cursa['reqid'] = substr($linee, strpos($linee, 'x') + 1, -1);
+ } else if (substr($linee, 0, 2) == 'E:') {
+ $cursa['ealgo'] = $linea[$idx + 1];
+ break;
+ } else if (substr($linee, 0, 2) == 'A:') {
+ $cursa['aalgo'] = $linea[$idx + 1];
+ break;
+ } else if (substr($linee, 0, 8) == 'current:') {
+ $cursa['data'] = substr($linea[$idx + 1], 0, strpos($linea[$idx + 1], 'bytes') - 1) . ' B';
+ break;
+ }
+ }
+ }
+ }
+ if (is_array($cursa) && count($cursa)) {
+ $sad[] = $cursa;
+ }
+ pclose($fd);
+ }
+
+ return $sad;
+}
+
+/*
+ * Return dump of mobile user list
+ */
+function ipsec_dump_mobile() {
+ global $g, $custom_listtags;
+
+ $_gb = exec("/usr/local/sbin/ipsec stroke leases > {$g['tmp_path']}/strongswan_leases.xml");
+
+ if (!file_exists("{$g['tmp_path']}/strongswan_leases.xml")) {
+ log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
+ return array();
+ }
+
+ /* This is needed for fixing #4130 */
+ if (filesize("{$g['tmp_path']}/strongswan_leases.xml") < 200) {
+ return array();
+ }
+
+ $custom_listtags = array('lease', 'pool');
+ $response = parse_xml_config("{$g['tmp_path']}/strongswan_leases.xml", "leases");
+ @unlink("{$g['tmp_path']}/strongswan_leases.xml");
+ unset($custom_listtags, $_gb);
+
+ return $response;
+}
+
+function ipsec_mobilekey_sort() {
+ global $config;
+
+ function mobilekeycmp($a, $b) {
+ return strcmp($a['ident'][0], $b['ident'][0]);
+ }
+
+ usort($config['ipsec']['mobilekey'], "mobilekeycmp");
+}
+
+function ipsec_get_number_of_phase2($ikeid) {
+ global $config;
+ $a_phase2 = $config['ipsec']['phase2'];
+
+ $nbph2 = 0;
+
+ if (is_array($a_phase2) && count($a_phase2)) {
+ foreach ($a_phase2 as $ph2tmp) {
+ if ($ph2tmp['ikeid'] == $ikeid) {
+ $nbph2++;
+ }
+ }
+ }
+
+ return $nbph2;
+}
+
+function ipsec_get_descr($ikeid) {
+ global $config;
+
+ if (!isset($config['ipsec']['phase1']) ||
+ !is_array($config['ipsec']['phase1'])) {
+ return '';
+ }
+
+ foreach ($config['ipsec']['phase1'] as $p1) {
+ if ($p1['ikeid'] == $ikeid) {
+ return $p1['descr'];
+ }
+ }
+
+ return '';
+}
+
+function ipsec_get_phase1($ikeid) {
+ global $config;
+
+ if (!isset($config['ipsec']['phase1']) ||
+ !is_array($config['ipsec']['phase1'])) {
+ return '';
+ }
+
+ $a_phase1 = $config['ipsec']['phase1'];
+ foreach ($a_phase1 as $p1) {
+ if ($p1['ikeid'] == $ikeid) {
+ return $p1;
+ }
+ }
+ unset($a_phase1);
+}
+
+function ipsec_fixup_ip($ipaddr) {
+ if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr)) {
+ return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
+ } else {
+ return $ipaddr;
+ }
+}
+
+function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
+ if ($side == "local") {
+ $id_type = $ph1ent['myid_type'];
+ $id_data = $ph1ent['myid_data'];
+
+ $addr = ipsec_get_phase1_src($ph1ent);
+ if (!$addr) {
+ return array();
+ }
+ } elseif ($side == "peer") {
+ $id_type = $ph1ent['peerid_type'];
+ $id_data = $ph1ent['peerid_data'];
+
+ if (isset($ph1ent['mobile'])) {
+ $addr = "%any";
+ } else {
+ $addr = $ph1ent['remote-gateway'];
+ }
+ } else {
+ return array();
+ }
+
+
+ $thisid_type = $id_type;
+ switch ($thisid_type) {
+ case 'myaddress':
+ $thisid_type = 'address';
+ $thisid_data = $addr;
+ break;
+ case 'dyn_dns':
+ $thisid_type = 'dns';
+ $thisid_data = $id_data;
+ break;
+ case 'peeraddress':
+ $thisid_type = 'address';
+ $thisid_data = $rgmap[$ph1ent['remote-gateway']];
+ break;
+ case 'address':
+ $thisid_data = $id_data;
+ break;
+ case 'fqdn':
+ $thisid_data = "{$id_data}";
+ break;
+ case 'keyid tag':
+ $thisid_type = 'keyid';
+ $thisid_data = "{$id_data}";
+ break;
+ case 'user_fqdn':
+ $thisid_type = 'userfqdn';
+ $thisid_data = "{$id_data}";
+ break;
+ case 'asn1dn':
+ $thisid_data = $id_data;
+ break;
+ }
+ return array($thisid_type, $thisid_data);
+}
+
+function ipsec_fixup_network($network) {
+ if (substr($network, -3) == '|/0') {
+ $result = substr($network, 0, -3);
+ } else {
+ $tmp = explode('|', $network);
+ if (isset($tmp[1])) {
+ $result = $tmp[1];
+ } else {
+ $result = $tmp[0];
+ }
+ unset($tmp);
+ }
+
+ return $result;
+}
+
+function ipsec_new_reqid() {
+ global $config;
+
+ if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2'])) {
+ return;
+ }
+
+ $ipsecreqid = lock('ipsecreqids', LOCK_EX);
+ $keyids = array();
+ $keyid = 1;
+ foreach ($config['ipsec']['phase2'] as $ph2) {
+ $keyids[$ph2['reqid']] = $ph2['reqid'];
+ }
+
+ for ($i = 1; $i < 16000; $i++) {
+ if (!isset($keyids[$i])) {
+ $keyid = $i;
+ break;
+ }
+ }
+ unlock($ipsecreqid);
+
+ return $keyid;
+}
+
+?>
OpenPOWER on IntegriCloud