diff options
-rw-r--r-- | etc/inc/config.inc | 178 | ||||
-rw-r--r-- | etc/inc/filter.inc | 243 | ||||
-rw-r--r-- | etc/inc/functions.inc | 3 | ||||
-rw-r--r-- | etc/inc/globals.inc | 4 | ||||
-rw-r--r-- | etc/inc/ipsec.inc | 344 | ||||
-rw-r--r-- | etc/inc/vpn.inc | 864 | ||||
-rw-r--r-- | etc/inc/xmlparse.inc | 2 | ||||
-rw-r--r-- | usr/local/www/diag_ipsec.php | 236 | ||||
-rwxr-xr-x | usr/local/www/diag_ipsec_sad.php | 174 | ||||
-rwxr-xr-x | usr/local/www/diag_ipsec_spd.php | 201 | ||||
-rwxr-xr-x | usr/local/www/diag_logs_ipsec.php | 8 | ||||
-rwxr-xr-x | usr/local/www/guiconfig.inc | 19 | ||||
-rwxr-xr-x | usr/local/www/pkg_edit.php | 2 | ||||
-rwxr-xr-x | usr/local/www/vpn_ipsec.php | 435 | ||||
-rwxr-xr-x | usr/local/www/vpn_ipsec_ca.php | 16 | ||||
-rwxr-xr-x | usr/local/www/vpn_ipsec_edit.php | 662 | ||||
-rwxr-xr-x | usr/local/www/vpn_ipsec_keys.php | 120 | ||||
-rwxr-xr-x | usr/local/www/vpn_ipsec_keys_edit.php | 128 | ||||
-rwxr-xr-x | usr/local/www/vpn_ipsec_mobile.php | 3 | ||||
-rw-r--r-- | usr/local/www/vpn_ipsec_phase1.php | 635 | ||||
-rw-r--r-- | usr/local/www/vpn_ipsec_phase2.php | 489 | ||||
-rw-r--r-- | usr/local/www/widgets/include/ipsec.inc | 81 | ||||
-rw-r--r-- | usr/local/www/widgets/widgets/ipsec.widget.php | 26 |
23 files changed, 2824 insertions, 2049 deletions
diff --git a/etc/inc/config.inc b/etc/inc/config.inc index 2914bae..121a659 100644 --- a/etc/inc/config.inc +++ b/etc/inc/config.inc @@ -1260,7 +1260,183 @@ function convert_config() { $config['version'] = "4.6"; } - if ($prev_version != $config['version']) + /* Convert 4.6 -> 4.7 */ + if ($config['version'] <= 4.7) { + + /* Upgrade IPsec from tunnel to phase1/phase2 */ + + echo "Beginning upgrade to version 4.7\n"; + + if(is_array($config['ipsec']['tunnel'])) { + + $a_phase1 = array(); + $a_phase2 = array(); + $ikeid = 0; + + foreach ($config['ipsec']['tunnel'] as $tunnel) { + + /* build new phase1 entry */ + + $ph1ent['ikeid'] = ++$ikeid; + + if (isset($tunnel['disabled'])) + $ph1ent['disabled'] = $tunnel['disabled']; + + $ph1ent['interface'] = $tunnel['interface']; + $ph1ent['remote-gateway'] = $tunnel['remote-gateway']; + $ph1ent['descr'] = $tunnel['descr']; + + $ph1ent['mode'] = $tunnel['p1']['mode']; + + if (isset($tunnel['p1']['myident']['myaddress'])) + $ph1ent['myid_type'] = "myaddress"; + if (isset($tunnel['p1']['myident']['address'])) { + $ph1ent['myid_type'] = "address"; + $ph1ent['myid_data'] = $tunnel['p1']['myident']['address']; + } + if (isset($tunnel['p1']['myident']['fqdn'])) { + $ph1ent['myid_type'] = "fqdn"; + $ph1ent['myid_data'] = $tunnel['p1']['myident']['fqdn']; + } + if (isset($tunnel['p1']['myident']['user_fqdn'])) { + $ph1ent['myid_type'] = "user_fqdn"; + $ph1ent['myid_data'] = $tunnel['p1']['myident']['user_fqdn']; + } + if (isset($tunnel['p1']['myident']['asn1dn'])) { + $ph1ent['myid_type'] = "asn1dn"; + $ph1ent['myid_data'] = $tunnel['p1']['myident']['asn1dn']; + } + if (isset($tunnel['p1']['myident']['dyn_dns'])) { + $ph1ent['myid_type'] = "dyn_dns"; + $ph1ent['myid_data'] = $tunnel['p1']['myident']['dyn_dns']; + } + + $ph1ent['peerid_type'] = "peeraddress"; + + switch ($tunnel['p1']['encryption-algorithm']) { + case "des": + $ph1alg = array( 'name' => 'des' ); + break; + case "3des": + $ph1alg = array( 'name' => '3des' ); + break; + case "blowfish": + $ph1alg = array( 'name' => 'blowfish', 'keylen' => 'auto' ); + break; + case "cast128": + $ph1alg = array( 'name' => 'cast128' ); + break; + case "rijndael": + $ph1alg = array( 'name' => 'aes', 'keylen' => 'auto' ); + break; + case "rijndael 256": + $ph1alg = array( 'name' => 'aes', 'keylen' => '256' ); + break; + } + + $ph1ent['encryption-algorithm'] = $ph1alg; + $ph1ent['hash-algorithm'] = $tunnel['p1']['hash-algorithm']; + $ph1ent['dhgroup'] = $tunnel['p1']['dhgroup']; + $ph1ent['lifetime'] = $tunnel['p1']['lifetime']; + $ph1ent['authentication_method'] = $tunnel['p1']['authentication_method']; + + if (isset($tunnel['p1']['pre-shared-key'])) + $ph1ent['pre-shared-key'] = $tunnel['p1']['pre-shared-key']; + if (isset($tunnel['p1']['cert'])) + $ph1ent['cert'] = $tunnel['p1']['cert']; + if (isset($tunnel['p1']['peercert'])) + $ph1ent['peercert'] = $tunnel['p1']['peercert']; + if (isset($tunnel['p1']['private-key'])) + $ph1ent['private-key'] = $tunnel['p1']['private-key']; + + if (isset($tunnel['pinghost']['pinghost'])) + $ph1ent['pinghost'] = $tunnel['pinghost']; + + $ph1ent['nat_traversal'] = "on"; + $ph1ent['dpd_enable'] = 1; + $ph1ent['dpd_delay'] = 10; + $ph1ent['dpd_maxfail'] = 5; + + $a_phase1[] = $ph1ent; + + /* build new phase2 entry */ + + $ph2ent['ikeid'] = $ikeid; + + if (isset($tunnel['disabled'])) + $ph1ent['disabled'] = $tunnel['disabled']; + + $ph2ent['descr'] = "phase2 for ".$tunnel['descr']; + + $type = "lan"; + if ($tunnel['local-subnet']['network']) + $type = $tunnel['local-subnet']['network']; + if ($tunnel['local-subnet']['address']) { + list($address,$netbits) = explode("/",$tunnel['local-subnet']['address']); + if (is_null($netbits)) + $type = "address"; + else + $type = "network"; + } + + switch ($type) { + case "address": + $ph2ent['localid'] = array('type' => $type,'address' => $address); + break; + case "network": + $ph2ent['localid'] = array('type' => $type,'address' => $address,'netbits' => $netbits); + break; + default: + $ph2ent['localid'] = array('type' => $type); + break; + } + + list($address,$netbits) = explode("/",$tunnel['remote-subnet']); + $ph2ent['remoteid'] = array('type' => 'network','address' => $address,'netbits' => $netbits); + + $ph2ent['protocol'] = $tunnel['p2']['protocol']; + + foreach( $tunnel['p2']['encryption-algorithm-option'] as $tunalg ) { + switch ($tunalg) { + case "des": + $ph2alg = array( 'name' => 'des' ); + break; + case "3des": + $ph2alg = array( 'name' => '3des' ); + break; + case "blowfish": + $ph2alg = array( 'name' => 'blowfish', 'keylen' => 'auto' ); + break; + case "cast128": + $ph2alg = array( 'name' => 'cast128' ); + break; + case "rijndael": + $ph2alg = array( 'name' => 'aes', 'keylen' => 'auto' ); + break; + case "rijndael 256": + $ph2alg = array( 'name' => 'aes', 'keylen' => '256' ); + break; + } + + $ph2ent['encryption-algorithm-option'][] = $ph2alg; + } + + $ph2ent['hash-algorithm-option'] = $tunnel['p2']['hash-algorithm-option']; + $ph2ent['pfsgroup'] = $tunnel['p2']['pfsgroup']; + $ph2ent['lifetime'] = $tunnel['p2']['lifetime']; + + $a_phase2[] = $ph2ent; + } + + unset($config['ipsec']['tunnel']); + $config['ipsec']['phase1'] = $a_phase1; + $config['ipsec']['phase2'] = $a_phase2; + } + + $config['version'] = "4.7"; + } + +// if ($prev_version != $config['version']) write_config("Upgraded config version level from {$prev_version} to {$config['version']}"); } diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc index ebf445d..01b9fd8 100644 --- a/etc/inc/filter.inc +++ b/etc/inc/filter.inc @@ -445,10 +445,10 @@ function get_vpns_list() { $vpns = ""; $vpns_arr = array(); /* ipsec */ - if ($config['ipsec']['tunnel']) { - foreach ($config['ipsec']['tunnel'] as $tunnel) { - if(is_subnet($tunnel['remote-subnet'])) { - $vpns_arr[] = $tunnel['remote-subnet']; + if ($config['ipsec']['phase2']) { + foreach ($config['ipsec']['phase2'] as $ph2ent) { + if(is_subnet($ph2ent['remote-subnet'])) { + $vpns_arr[] = $ph2ent['remote-subnet']; } } } @@ -2953,128 +2953,165 @@ EOD; update_filter_reload_status("Creating carp rules..."); $ipfrules .= "\n# VPN Rules\n"; - /* is mobile ipsec enabled? if so lets allow some pretty - * loose rules to allow mobile clients to phone in. - */ - $ipseccfg = $config['ipsec']; - if (isset($ipseccfg['mobileclients']['enable'])) { - $ifdescrs = get_configured_interface_with_descr(); - foreach($ifdescrs as $ifr => $iface) { - /* only process interfaces with gateway */ - if(! interface_has_gateway($ifr)) - continue; - - /* FIXME: make dynamic interface compatible */ - $gateway = lookup_gateway_ip_by_name($config['interfaces'][$ifr]['gateway']); - $interface = convert_friendly_interface_to_real_interface_name($iface); - if((is_ipaddr($gateway)) && ($interface <> "")) { - $route_to = " route-to ( $interface $gateway ) "; - $reply_to = " reply-to ( $interface $gateway ) "; - } - $ifalias = convert_friendly_interface_to_friendly_descr($ifr); - - /* pass in rules for IPSEC with reply-to */ - $ipfrules .= "pass in on \${$ifalias} $reply_to proto udp from any to any port = 500 keep state label \"IPsec: Mobile - inbound isakmp\"\n"; - $ipfrules .= "pass in on \${$ifalias} $reply_to proto esp from any to any keep state label \"IPsec: Mobile - inbound esp proto\"\n"; - $ipfrules .= "pass in on \${$ifalias} $reply_to proto ah from any to any keep state label \"IPsec: Mobile - inbound ah proto\"\n"; - /* Pass out rules for IPSEC with route-to */ - $ipfrules .= "pass out on \${$ifalias} $route_to proto udp from any to any port = 500 keep state label \"IPsec: Mobile - inbound isakmp\"\n"; - $ipfrules .= "pass out on \${$ifalias} $route_to proto esp from any to any keep state label \"IPsec: Mobile - inbound esp proto\"\n"; - $ipfrules .= "pass out on \${$ifalias} $route_to proto ah from any to any keep state label \"IPsec: Mobile - inbound ah proto\"\n"; - } - } if($config['interfaces']['lan']) { $lan_ip = $config['interfaces']['lan']['ipaddr']; $lan_subnet = $config['interfaces']['lan']['subnet']; } + $wanif = get_real_wan_interface(); $wan_ip = find_interface_ip($wanif); - if($wan_ip) { - if($config['interfaces']['lan']) - $internal_subnet = gen_subnet($lan_ip, $lan_subnet) . "/" . $config['interfaces']['lan']['subnet']; + + if ($wan_ip) { + /* Is IP Compression enabled? */ - if(isset($config['ipsec']['ipcomp'])) + if (isset($config['ipsec']['ipcomp'])) exec("/sbin/sysctl net.inet.ipcomp.ipcomp_enable=1"); else exec("/sbin/sysctl net.inet.ipcomp.ipcomp_enable=0"); /* if list */ - $ifdescrs = get_configured_interface_with_descr(); + $ifdescrs = get_configured_interface_with_descr(); - if(is_array($config['ipsec']['tunnel']) && isset($config['ipsec']['enable']) && (! isset($ipseccfg['mobileclients']['enable']))) { - foreach ($config['ipsec']['tunnel'] as $tunnel) { - if(isset($tunnel['disabled'])) + /* NOTE : The ipsec related code was odd. I will + * need feedback from other developers to get it + * completelely sorted out. + * -mgrooms 06/07/2008 + */ + if(isset($config['ipsec']['enable']) && + is_array($config['ipsec']['phase1']) && + is_array($config['ipsec']['phase2'])) { + /* step through all phase1 entries */ + foreach ($config['ipsec']['phase1'] as $ph1ent) { + + if (isset ($ph1ent['disabled'])) + continue; + + update_filter_reload_status("Creating IPsec phase1 items for {$ph1ent['descr']}..."); + + /* NOTE : the old code built an array with a single + * element for each tunnel entry. Why? It was getting + * reset on each loop iteration. + * + * ipsec_ips = array(get_current_wan_address($tunnel['interface'])); + * + * Is the get_current_wan_address function name + * misleading or did we always assume the local + * endpoint was the WAN interface? + */ + + /* determine local and remote peer addresses */ + + $lgip = vpn_endpoint_determine($ph1ent, $wan_ip); + + $rgip = $ph1ent['remote-gateway']; + if(!is_ipaddr($rgip)) + $rgip = resolve_retry($rgip); + + if (!$lgip) { + $ipfrules .= "# ERROR! Unable to determine local IPsec peer address for {$ph1ent['remote-gateway']}\n"; continue; - update_filter_reload_status("Creating IPsec tunnel items {$tunnel['descr']}..."); - /* if tunnel is disabled, lets skip to next item */ - $ipsec_ips = array(get_current_wan_address($tunnel['interface'])); - /* is this a dynamic dns hostname? */ - $remote_gateway = gethostbyname($tunnel['remote-gateway']); - if($remote_gateway == "") - $remote_gateway = $tunnel['remote-gateway']; - /* do not add items with blank remote_gateway */ - if(!$remote_gateway) { - $ipfrules .= "# ERROR! Remote gateway not found on {$tunnel['remote-gateway']}\n"; + } + if (!$rgip) { + $ipfrules .= "# ERROR! Unable to determine remote IPsec peer address for {$ph1ent['remote-gateway']}\n"; continue; } - $local_subnet = return_vpn_subnet($tunnel['local-subnet']); - foreach($ifdescrs as $ifr => $iface) { - /* XXX: really needed?! */ - if ($ifr == "lan") + + /* Step through the interface list and the assigned IP + * addresses. + * + * NOTE : I'm not really sure why this is neccessary. We + * have already resolved the local and remote endpoints + * and the interface is known. If vpn_endpoint_determine + * is not good enough to use here, it should be modified + * instead of doing the work locally. Otherwise we will + * have pf rules that don't match SPD. + * -mgrooms 06/07/2008 + */ + foreach ($ifdescrs as $ifr => $iface) { + + /* Are we doing the lookups below just to ensure the + * interface has an IP address configured? + * -mgrooms 06/07/2008 + */ + + if($ifr == "wan") + $interface_ip = find_interface_ip(get_real_wan_interface()); + else + $interface_ip = find_interface_ip(convert_friendly_interface_to_real_interface_name($iface)); + + if(!$interface_ip) continue; - foreach($ipsec_ips as $interface_ip) { - if($ifr == "wan") - $interface_ip = find_interface_ip(get_real_wan_interface()); - else - $interface_ip = find_interface_ip(convert_friendly_interface_to_real_interface_name($iface)); - if(!$interface_ip) - continue; - if(!$remote_gateway) - continue; - /* only process interfaces with gateway */ - if(! interface_has_gateway($ifr)) + /* NOTES : We went through a lot of trouble to determine the + * real interface address but we still use $lgip ( previously + * named $remote_gateway ) below in our rules. Why? + * + * There is also no statement to avoid adding rules/routes + * for interfaces that don't match the one defined in our + * phase1 entry ( previously a $tunnel ). Why do we loop if + * there is no qualification? + * -mgrooms 06/07/2008 + */ + + /* Only process interfaces with gateway */ + if(! interface_has_gateway($ifr)) + continue; + + $gateway = lookup_gateway_ip_by_name($config['interfaces'][$ifr]['gateway']); + $interface = convert_friendly_interface_to_real_interface_name($iface); + + $route_to = " route-to ( $interface $gateway ) "; + $reply_to = " reply-to ( $interface $gateway ) "; + + /* Another conversion. Why? */ + $ifalias = convert_friendly_interface_to_friendly_descr($ifr); + + /* Add rules to allow IKE to pass */ + $ipfrules .= "pass out on \${$ifalias} $route_to proto udp from any to {$rgip} port = 500 keep state label \"IPsec: {$ph1ent['descr']} - outbound isakmp\"\n"; + $ipfrules .= "pass in on \${$ifalias} $reply_to proto udp from {$rgip} to any port = 500 keep state label \"IPsec: {$ph1ent['descr']} - inbound isakmp\"\n"; + + /* If NAT-T is enabled, add additional rules */ + if ($ph1ent['nat_traversal'] != "off" ) { + $ipfrules .= "pass out on \${$ifalias} $route_to proto udp from any to {$rgip} port = 4500 keep state label \"IPsec: {$ph1ent['descr']} - outbound nat-t\"\n"; + $ipfrules .= "pass in on \${$ifalias} $reply_to proto udp from {$rgip} to any port = 4500 keep state label \"IPsec: {$ph1ent['descr']} - inbound nat-t\"\n"; + } + + /* Step through all phase2 entries and determine + * which protocols are in use with this peer + */ + $prot_used_esp = false; + $prot_used_ah = false; + + foreach ($config['ipsec']['phase2'] as $ph2ent) { + + /* only evaluate ph2's bound to our ph1 */ + if ($ph2ent['ikeid'] != $ph1ent['ikeid']) continue; - /* FIXME: make dynamic interface compatible */ - $gateway = lookup_gateway_ip_by_name($config['interfaces'][$ifr]['gateway']); - $interface = convert_friendly_interface_to_real_interface_name($iface); - if((is_ipaddr($gateway)) && ($interface <> "")) { - $route_to = " route-to ( $interface $gateway ) "; - $reply_to = " reply-to ( $interface $gateway ) "; - } - $ifalias = convert_friendly_interface_to_friendly_descr($ifr); - $ipfrules .= "pass out on \${$ifalias} $route_to proto udp from any to {$remote_gateway} port = 500 keep state label \"IPsec: {$tunnel['descr']} - outbound isakmp\"\n"; - $ipfrules .= "pass in on \${$ifalias} $reply_to proto udp from {$remote_gateway} to any port = 500 keep state label \"IPsec: {$tunnel['descr']} - inbound isakmp\"\n"; - if ($tunnel['p2']['protocol'] == 'esp') { - $ipfrules .= "pass out on \${$ifalias} $route_to proto esp from any to {$remote_gateway} keep state label \"IPsec: {$tunnel['descr']} - outbound esp proto\"\n"; - $ipfrules .= "pass in on \${$ifalias} $reply_to proto esp from {$remote_gateway} to any keep state label \"IPsec: {$tunnel['descr']} - inbound esp proto\"\n"; - } - if ($tunnel['p2']['protocol'] == 'ah') { - $ipfrules .= "pass out on \${$ifalias} $route_to proto ah from any to {$remote_gateway} keep state label \"IPsec: {$tunnel['descr']} - outbound ah proto\"\n"; - $ipfrules .= "pass in on \${$ifalias} $reply_to proto ah from {$remote_gateway} to any keep state label \"IPsec: {$tunnel['descr']} - inbound ah proto\"\n"; - } + if ($ph2ent['protocol'] == 'esp') + $prot_used_esp = true; + + if ($ph2ent['protocol'] == 'ah') + $prot_used_ah = true; } - } - } - } - /* is mobile ipsec enabled? if so lets allow some pretty - * loose rules to allow mobile clients to phone in. - */ - $ipseccfg = $config['ipsec']; - if (isset($ipseccfg['mobileclients']['enable'])) { - foreach($ifdescrs as $ifr => $iface) { - $ifalias = convert_friendly_interface_to_friendly_descr($ifr); - - $ipfrules .= "pass in on \${$ifalias} proto udp from any to any port = 500 keep state label \"IPsec: Mobile - inbound isakmp\"\n"; - $ipfrules .= "pass in on \${$ifalias} proto esp from any to any keep state label \"IPsec: Mobile - inbound esp proto\"\n"; - $ipfrules .= "pass in on \${$ifalias} proto ah from any to any keep state label \"IPsec: Mobile - inbound ah proto\"\n"; + /* Add rules to allow the protocols in use */ + if ($prot_used_esp) { + $ipfrules .= "pass out on \${$ifalias} $route_to proto esp from any to {$rgip} keep state label \"IPsec: {$ph1ent['descr']} - outbound esp proto\"\n"; + $ipfrules .= "pass in on \${$ifalias} $reply_to proto esp from {$rgip} to any keep state label \"IPsec: {$ph1ent['descr']} - inbound esp proto\"\n"; + } + if ($prot_used_ah) { + $ipfrules .= "pass out on \${$ifalias} $route_to proto ah from any to {$rgip} keep state label \"IPsec: {$ph1ent['descr']} - outbound ah proto\"\n"; + $ipfrules .= "pass in on \${$ifalias} $reply_to proto ah from {$rgip} to any keep state label \"IPsec: {$ph1ent['descr']} - inbound ah proto\"\n"; + } + } } } } + $ipfrules .= <<<EOD + # Support for allow limiting of TCP connections by establishment rate anchor "limitingesr" pass in on $wanif inet proto tcp from port 20 to ($wanif) port > 49000 user proxy flags S/SA keep state label "FTP PROXY: PASV mode data connection" @@ -3273,10 +3310,10 @@ function carp_sync_xml($url, $password, $sections, $port = 80, $method = 'pfsens unset ($config_copy['virtualip']['vip'][$x]); $config_copy['virtualip']['vip'][$x]['descr'] = remove_special_characters($config_copy['virtualip']['vip'][$x]['descr']); } - for ($x = 0; $x < count($config_copy['ipsec']['tunnel']); $x++) { - if (isset ($config_copy['ipsec']['tunnel'][$x]['nosync'])) - unset ($config_copy['ipsec']['tunnel'][$x]); - $config_copy['ipsec']['tunnel'][$x]['descr'] = remove_special_characters($config_copy['ipsec']['tunnel'][$x]['descr']); + for ($x = 0; $x < count($config_copy['ipsec']['phase1']); $x++) { + if (isset ($config_copy['ipsec']['phase1'][$x]['nosync'])) + unset ($config_copy['ipsec']['phase1'][$x]); + $config_copy['ipsec']['phase1'][$x]['descr'] = remove_special_characters($config_copy['ipsec']['phase1'][$x]['descr']); } foreach($sections as $section) { diff --git a/etc/inc/functions.inc b/etc/inc/functions.inc index 8415def..b8ab7fb 100644 --- a/etc/inc/functions.inc +++ b/etc/inc/functions.inc @@ -79,9 +79,10 @@ require_once("system.inc"); require_once("openvpn.inc"); require_once("pfsense-utils.inc"); require_once("util.inc"); +require_once("ipsec.inc"); require_once("vpn.inc"); require_once("vslb.inc"); require_once("gwlb.inc"); require_once("notices.inc"); -?>
\ No newline at end of file +?> diff --git a/etc/inc/globals.inc b/etc/inc/globals.inc index ec5733a..4e27774 100644 --- a/etc/inc/globals.inc +++ b/etc/inc/globals.inc @@ -60,7 +60,7 @@ $g = array( "n_pppoe_units" => 16, /* this value can be overriden in pppoe->n_pppoe_units */ "pppoe_subnet" => 28, /* this value can be overriden in pppoe->pppoe_subnet */ "debug" => false, - "latest_config" => "4.6", + "latest_config" => "4.7", "nopkg_platforms" => array("cdrom"), "minimum_ram_warning" => "115", "minimum_ram_warning_text" => "128 megabytes", @@ -87,4 +87,4 @@ $iptos = array("lowdelay", "throughput", "reliability"); /* TCP flags */ $tcpflags = array("syn", "ack", "fin", "rst", "psh", "urg"); -?>
\ No newline at end of file +?> diff --git a/etc/inc/ipsec.inc b/etc/inc/ipsec.inc new file mode 100644 index 0000000..23cd4ba --- /dev/null +++ b/etc/inc/ipsec.inc @@ -0,0 +1,344 @@ +<?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. +*/ + +/* + * Return phase1 local address + */ +function ipsec_get_phase1_src(& $ph1ent) { + + if ($ph1ent['interface']) + $if = $ph1ent['interface']; + else + $if = "WAN"; + + $realinterface = convert_friendly_interface_to_real_interface_name($if); + $interfaceip = find_interface_ip($realinterface); + + return $interfaceip; +} + +/* + * Return phase2 idinfo in cidr format + */ +function ipsec_idinfo_to_cidr(& $idinfo,$addrbits = false) { + global $config; + + switch ($idinfo['type']) + { + case "address": + if ($addrbits) + return $idinfo['address']."/32"; + else + return $idinfo['address']; + case "network": + return $idinfo['address']."/".$idinfo['netbits']; + default: + $address = $config['interfaces']['lan']['ipaddr']; + $netbits = $config['interfaces'][$idinfo['type']]['subnet']; + $address = gen_subnet($address,$netbits); + return $address."/".$netbits; + } +} + +/* + * Return phase2 idinfo in address/netmask format + */ +function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) { + global $config; + + switch ($idinfo['type']) + { + case "address": + if ($addrbits) + return $idinfo['address']."/255.255.255.255"; + else + return $idinfo['address']; + case "network": + return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']); + default: + $address = $config['interfaces']['lan']['ipaddr']; + $netbits = $config['interfaces'][$idinfo['type']]['subnet']; + $address = gen_subnet($address,$netbits); + $netbits = gen_subnet_mask($netbits); + return $address."/".netbits; + } +} + +/* + * Return phase2 idinfo in text format + */ +function ipsec_idinfo_to_text(& $idinfo) { + + switch ($idinfo['type']) + { + case "address": + return $idinfo['address']; + case "network": + return $idinfo['address']."/".$idinfo['netbits']; + default: + return strtoupper($idinfo['type']); + } +} + +/* + * Return phase1 association for phase2 + */ +function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) +{ + global $config; + $a_phase1 = $config['ipsec']['phase1']; + + if (is_array($a_phase1) && count($a_phase1)) { + foreach ($a_phase1 as $ph1tmp) { + if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) { + $ph1ent = $ph1tmp; + return $ph1ent; + } + } + } + + return false; +} + +/* + * Check phase1 communications status + */ +function ipsec_phase1_status(& $ph1ent) { + + $loc_ip = get_ipsec_tunnel_src($ph1ent); + $rmt_ip = $ph1ent['remote-gateway']; + + if(ipsec_lookup_ipsakmp_sa($loc_ip,$rmt_ip)) + return true; + + return false; +} + +/* + * Check phase2 communications status + */ +function ipsec_phase2_status(& $spd,& $sad,& $ph1ent,& $ph2ent) { + + $loc_ip = ipsec_get_phase1_src($ph1ent); + $rmt_ip = $ph1ent['remote-gateway']; + + $loc_id = ipsec_idinfo_to_cidr($ph2ent['localid'],true); + $rmt_id = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true); + + /* check for established SA in both directions */ + if( ipsec_lookup_ipsec_sa($spd,$sad,"out",$loc_ip,$rmt_ip,$loc_id,$rmt_id) && + ipsec_lookup_ipsec_sa($spd,$sad,"in",$rmt_ip,$loc_ip,$rmt_id,$loc_id)) + return true; + + return false; +} + +/* + * Return ISAKMP SA details + */ +function ipsec_lookup_isakmp_sa($in_srcip,$in_dstip) { + /* TODO : use racconctl to lookup iskamp SA */ + return NULL; +} + +/* + * Return IPsec SA details + */ +function ipsec_lookup_ipsec_sa(& $spd,& $sad,$dir,$in_srcip,$in_dstip,$in_srcid,$in_dstid) { + + /* match the phase1/2 to an SP */ + + foreach($spd as $sp) { + + /* match direction */ + + if($dir != $sp['dir']) + continue; + + /* match IPs */ + + if($in_srcip != $sp['src']) + continue; + if($in_dstip != $sp['dst']) + continue; + + /* add netbits for address IDs */ + + $sp_srcid = $sp['srcid']; + $sp_dstid = $sp['dstid']; + + if (!strstr($sp_srcid,"/")) + $sp_srcid .= '/32'; + if (!strstr($sp_dstid,"/")) + $sp_dstid .= '/32'; + + /* match IDs */ + + if($in_srcid != $sp_srcid) + continue; + if($in_dstid != $sp_dstid) + continue; + + /* match the SP to a unique SA by reqid */ + + foreach($sad as $sa) { + + /* match REQIDs */ + + if($sa[reqid] != $sp[reqid]) + continue; + + /* sanitize for NAT-T ports */ + + $sa_srcip = $sa['src']; + $sa_dstip = $sa['dst']; + + if (strstr($sa_srcip,"[")) + $sa_srcip = substr($sa_srcip,0,strcspn($sa_srcip,"[")); + if (strstr($sa_dstip,"[")) + $sa_dstip = substr($sa_dstip,0,strcspn($sa_dstip,"[")); + + /* match IPs */ + + if($in_srcip != $sa_srcip) + continue; + if($in_dstip != $sa_dstip) + continue; + + return $sa; + } + } + + return NULL; +} + +/* + * Return dump of SPD table + */ +function ipsec_dump_spd() +{ + $fd = @popen("/usr/local/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)) { + $linea = explode(" ", trim($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("/usr/local/sbin/setkey -D", "r"); + $sad = array(); + if ($fd) { + while (!feof($fd)) { + $line = chop(fgets($fd)); + if (!$line) + 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); + $i = 0; + } + else + { + $linea = explode(" ", trim($line)); + switch ($i) { + case 1: + $cursa['proto'] = $linea[0]; + $cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1); + $reqid = substr($linea[3], strpos($linea[3], "=")+1); + $cursa['reqid'] = substr($reqid, 0, strcspn($reqid,"(")); + break; + case 2: + $cursa['ealgo'] = $linea[1]; + break; + case 3: + $cursa['aalgo'] = $linea[1]; + break; + } + } + $i++; + } + if (is_array($cursa) && count($cursa)) + $sad[] = $cursa; + pclose($fd); + } + + return $sad; +} + +?> diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc index 91cbdb5..95a115b 100644 --- a/etc/inc/vpn.inc +++ b/etc/inc/vpn.inc @@ -3,6 +3,7 @@ /* vpn.inc Copyright (C) 2004 Scott Ullrich + Copyright (C) 2008 Shrew Soft Inc All rights reserved. originally part of m0n0wall (http://m0n0.ch/wall) @@ -34,6 +35,42 @@ /* include all configuration functions */ require_once ("functions.inc"); +/* IPsec defines */ +$my_identifier_list = array('myaddress' => 'My IP address', + 'address' => 'IP address', + 'keyid tag' => 'KeyID Tag', + 'fqdn' => 'Domain name', + 'user_fqdn' => 'User FQDN', + 'asn1dn' => 'Distinguished Name', + 'dyn_dns' => 'Dynamic DNS'); + +$peer_identifier_list = array('peeraddress' => 'Peer IP address', + 'address' => 'IP address', + 'keyid tag' => 'KeyID Tag', + 'fqdn' => 'Domain name', + 'user_fqdn' => 'User FQDN', + 'asn1dn' => 'Distinguished Name'); + +$p1_ealgos = array( + 'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ), + 'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 8 ) ), + '3des' => array( 'name' => '3DES' ), + 'cast128' => array( 'name' => 'CAST128' ), + 'des' => array( 'name' => 'DES' ) ); + +$p2_ealgos = array( + 'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ), + 'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 8 ) ), + '3des' => array( 'name' => '3DES' ), + 'cast128' => array( 'name' => 'CAST128' ), + 'des' => array( 'name' => 'DES' ) ); + +$p1_halgos = array('sha1' => 'SHA1', 'md5' => 'MD5'); +$p1_authentication_methods = array('pre_shared_key' => 'Pre-shared key', 'rsasig' => 'RSA signature'); +$p2_halgos = array('hmac_sha1' => 'SHA1', 'hmac_md5' => 'MD5'); +$p2_protos = array('esp' => 'ESP', 'ah' => 'AH'); +$p2_pfskeygroups = array('0' => 'off', '1' => '1', '2' => '2', '5' => '5'); + /* master setup for vpn (mpd) */ function vpn_setup() { /* start pptpd */ @@ -98,8 +135,9 @@ function find_last_gif_device() { return $last_gif_found; } -function vpn_ipsec_configure($ipchg = false) { - global $config, $g, $sa, $sn; +function vpn_ipsec_configure($ipchg = false) +{ + global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos; mwexec("/sbin/ifconfig enc0 up"); @@ -120,27 +158,26 @@ function vpn_ipsec_configure($ipchg = false) { } } - if(isset($config['ipsec']['preferredoldsa'])) { + if(isset($config['ipsec']['preferredoldsa'])) mwexec("/sbin/sysctl net.key.preferred_oldsa=0"); - } else { + else mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30"); - } $number_of_gifs = find_last_gif_device(); - for ($x = 0; $x < $number_of_gifs; $x++) { + for ($x = 0; $x < $number_of_gifs; $x++) mwexec("/sbin/ifconfig gif" . $x . " delete"); - } $curwanip = get_current_wan_address(); $syscfg = $config['system']; $ipseccfg = $config['ipsec']; + $a_phase1 = $config['ipsec']['phase1']; + $a_phase2 = $config['ipsec']['phase2']; $lancfg = $config['interfaces']['lan']; $lanip = $lancfg['ipaddr']; $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']); $lansn = $lancfg['subnet']; - if (!isset($ipseccfg['enable'])) { mwexec("/sbin/ifconfig enc0 down"); mwexec("/sbin/ifconfig enc0 destroy"); @@ -162,9 +199,8 @@ function vpn_ipsec_configure($ipchg = false) { return true; } - if ($g['booting']) { + if ($g['booting']) echo "Configuring IPsec VPN... "; - } if (isset ($ipseccfg['enable'])) { /* fastforwarding is not compatible with ipsec tunnels */ @@ -177,127 +213,128 @@ function vpn_ipsec_configure($ipchg = false) { return 0; } - if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) || - isset ($ipseccfg['mobileclients']['enable'])) { - - $dnswatch_list = array(); - $rgmap = array(); - - if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) { - /* generate spd.conf */ - $fd = fopen("{$g['varetc_path']}/spd.conf", "w"); - if (!$fd) { - printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n"); - return 1; - } + /* resolve all local, peer addresses and setup pings */ + $ipmap = array(); + $rgmap = array(); + $dnswatch_list = array(); + if (is_array($a_phase1) && count($a_phase1)) { + foreach ($a_phase1 as $ph1ent) { + if (isset($ph1ent['disabled'])) + continue; - $spdconf = ""; + $ep = vpn_endpoint_determine($ph1ent, $curwanip); + if (!$ep) + continue; - $spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n"; - $spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n"; + if(!in_array($ep,$ipmap)) + $ipmap[] = $ep; - foreach ($ipseccfg['tunnel'] as $tunnel) { - if (isset ($tunnel['disabled'])) - continue; + /* see if this tunnel has a hostname for the remote-gateway. If so, + try to resolve it now and add it to the list for dnswatch */ - /* see if this tunnel has a hostname for the remote-gateway, and if so, - try to resolve it now and add it to the list for dnswatch */ - if (!is_ipaddr($tunnel['remote-gateway'])) { - $dnswatch_list[] = $tunnel['remote-gateway']; - $rgip = resolve_retry($tunnel['remote-gateway']); - - if (!$rgip) - continue; - - } else { - $rgip = $tunnel['remote-gateway']; - } - $rgmap[$tunnel['remote-gateway']] = $rgip; + $rg = $ph1ent['remote-gateway']; - $ep = vpn_endpoint_determine($tunnel, $curwanip); - if (!$ep) + if (!is_ipaddr($rg)) { + $dnswatch_list[] = $rg; + $rg = resolve_retry($rg); + + if (!$rgip) continue; + } - vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn); + $rgmap[$ph1ent['remote-gateway']] = $rg; - if (is_domain($tunnel['remote-gateway'])) { - $tmp = gethostbyname($tunnel['remote-gateway']); - if ($tmp) - $tunnel['remote-gateway'] = $tmp; - } + /* add an ipsec pinghosts entry */ - /* add entry to host pinger */ - if ($tunnel['pinghost']) { - $pfd = fopen("/var/db/ipsecpinghosts", "a"); - - /* if list */ - $iflist = get_configured_interface_list(); - - foreach ($iflist as $ifent => $ifname) { - $interface_ip = find_interface_ip($config['interfaces'][$ifname]['if']); - if (ip_in_subnet($interface_ip, $sa . "/" . $sn)) - $srcip = find_interface_ip($config['interfaces'][$ifname]['if']); - } - $dstip = $tunnel['pinghost']; - fwrite($pfd, "$srcip|$dstip|3\n"); - fclose($pfd); - } - - if (isset ($tunnel['creategif'])) { - $number_of_gifs = find_last_gif_device(); - $number_of_gifs++; - $curwanip = get_current_wan_address(); - if ($config['installedpackages']['sasyncd']['config'] <> "") - foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) { - if ($sasyncd['ip'] <> "") - $curwanip = $sasyncd['ip']; - } - mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']); - mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32"); + if ($ph1ent['pinghost']) { + $pfd = fopen("/var/db/ipsecpinghosts", "a"); + $iflist = array("lan" => "lan", "wan" => "wan"); + for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) + $iflist['opt' . $i] = "opt{$i}"; + foreach ($iflist as $ifent => $ifname) { + $interface_ip = find_interface_ip($config['interfaces'][$ifname]['if']); + if (ip_in_subnet($interface_ip, $sa . "/" . $sn)) + $srcip = find_interface_ip($config['interfaces'][$ifname]['if']); } + $dstip = $ph1ent['pinghost']; + fwrite($pfd, "$srcip|$dstip|3\n"); + fclose($pfd); + } + } + } - $spdconf .= "spdadd {$sa}/{$sn} " . - "{$tunnel['remote-subnet']} any -P out ipsec " . - "{$tunnel['p2']['protocol']}/tunnel/{$ep}-" . - "{$rgip}/unique;\n"; - - $spdconf .= "spdadd {$tunnel['remote-subnet']} " . - "{$sa}/{$sn} any -P in ipsec " . - "{$tunnel['p2']['protocol']}/tunnel/{$rgip}-" . - "{$ep}/unique;\n"; - - /* static route needed? */ - if(preg_match("/^carp/i", $tunnel['interface'])) { - $parentinterface = link_carp_interface_to_parent($tunnel['interface']); - } else { - $parentinterface = $tunnel['interface']; - } - if($parentinterface <> "wan") { - /* add endpoint routes to correct gateway on interface */ - if(interface_has_gateway($parentinterface)) { - $gatewayip = get_interface_gateway("$parentinterface"); - $interfaceip = $config['interfaces'][$parentinterface]['ipaddr']; - $subnet_bits = $config['interfaces'][$parentinterface]['subnet']; - $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}"); - /* if the remote gateway is in the local subnet, then don't add a route */ - if(! ip_in_subnet($tunnel['remote-gateway'], "{$subnet_ip}/{$subnet_bits}")) { - if(is_ipaddr($gatewayip)) { - log_error("IPSEC interface is not WAN but {$tunnel['interface']}, adding static route for VPN endpoint {$tunnel['remote-gateway']} via {$gatewayip}"); - mwexec("/sbin/route delete -host {$tunnel['remote-gateway']};/sbin/route add -host {$tunnel['remote-gateway']} {$gatewayip}"); - } - } + /* generate CA certificates files */ + $cacertnum = 0; + if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert'])) { + foreach ($ipseccfg['cacert'] as $cacert) { + ++ $cacertnum; + if (isset ($cacert['cert'])) { + $cert = base64_decode($cacert['cert']); + $x509cert = openssl_x509_parse(openssl_x509_read($cert)); + if (is_array($x509cert) && isset ($x509cert['hash'])) { + $fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w"); + if (!$fd1) { + printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n"); + return 1; } - } else { - mwexec("/sbin/route delete -host {$tunnel['remote-gateway']}"); + chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600); + fwrite($fd1, $cert); + fclose($fd1); } + } + } + } + + /* generate psk.txt */ + $fd = fopen("{$g['varetc_path']}/psk.txt", "w"); + if (!$fd) { + printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n"); + return 1; + } + + $pskconf = ""; + if (is_array($a_phase1) && count($a_phase1)) { + foreach ($a_phase1 as $ph1ent) { + + if (isset($ph1ent['disabled'])) + continue; + + $rgip = $rgmap[$ph1ent['remote-gateway']]; + if (!$rgip) + continue; + + $peerid_type = $ph1ent['peerid_type']; + + switch ($peerid_type) { + case "peeraddress": + $peerid_type = "address"; + $peerid_data = $rgip; + break; + + case "address"; + $peerid_data = $ph1ent['peerid_data']; + break; + + case "fqdn"; + case "keyid tag"; + case "user_fqdn"; + $peerid_data = $ph1ent['peerid_data']; + break; } - fwrite($fd, $spdconf); - fclose($fd); + $pskconf .= "{$peerid_data}\t\t\t{$ph1ent['pre-shared-key']}\n"; } + } + + fwrite($fd, $pskconf); + fclose($fd); + chmod("{$g['varetc_path']}/psk.txt", 0600); + + /* begin racoon.conf */ + if ((is_array($a_phase1) && count($a_phase1)) || + (is_array($a_phase2) && count($a_phase2))) { - /* generate racoon.conf */ $fd = fopen("{$g['varetc_path']}/racoon.conf", "w"); if (!$fd) { printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n"); @@ -309,395 +346,400 @@ function vpn_ipsec_configure($ipchg = false) { $racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n"; $racoonconf .= "path certificate \"{$g['varetc_path']}\";\n\n"; - /* generate CA certificates files */ - $cacertnum = 0; - if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert'])) - foreach ($ipseccfg['cacert'] as $cacert) { - ++ $cacertnum; - if (isset ($cacert['cert'])) { - $cert = base64_decode($cacert['cert']); - $x509cert = openssl_x509_parse(openssl_x509_read($cert)); - if (is_array($x509cert) && isset ($x509cert['hash'])) { - $fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w"); - if (!$fd1) { - printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n"); - return 1; - } - chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600); - fwrite($fd1, $cert); - fclose($fd1); - } - } + /* begin listen section */ + if (count($ipmap)) { + $racoonconf .= "\nlisten\n"; + $racoonconf .= "{\n"; + foreach ($ipmap as $addr) { + $racoonconf .= "\tisakmp {$addr} [500];\n"; + $racoonconf .= "\tisakmp_natt {$addr} [4500];\n"; } + $racoonconf .= "}\n\n"; + } - $tunnelnumber = 0; - if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) - foreach ($ipseccfg['tunnel'] as $tunnel) { + /* begin remote sections */ + if (is_array($a_phase1) && count($a_phase1)) { + /* begin remote */ + foreach ($a_phase1 as $ph1ent) { + if (isset($ph1ent['disabled'])) + continue; - ++ $tunnelnumber; + $ikeid = $ph1ent['ikeid']; - if (isset ($tunnel['disabled'])) + $ep = vpn_endpoint_determine($ph1ent, $curwanip); + if (!$ep) continue; + $myid_type = $ph1ent['myid_type']; - $rgip = $rgmap[$tunnel['remote-gateway']]; - if (!$rgip) - continue; + switch ($myid_type) { - $ep = vpn_endpoint_determine($tunnel, $curwanip); - if (!$ep) - continue; + case "myaddress": + $myid_type = "address"; + $myid_data = $ep; + break; + + case "dyn_dns": + $myid_data = gethostbyname($ph1ent['myid_data']); + break; - vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn); - - if (isset ($tunnel['p1']['myident']['myaddress'])) { - $myidentt = "address"; - $myident = $ep; - } elseif (isset ($tunnel['p1']['myident']['address'])) { - $myidentt = "address"; - $myident = $tunnel['p1']['myident']['address']; - } elseif (isset ($tunnel['p1']['myident']['fqdn'])) { - $myidentt = "fqdn"; - $myident = $tunnel['p1']['myident']['fqdn']; - } elseif (isset ($tunnel['p1']['myident']['ufqdn'])) { - $myidentt = "user_fqdn"; - $myident = $tunnel['p1']['myident']['ufqdn']; - } else if (isset($tunnel['p1']['myident']['asn1dn'])) { - $myidentt = "asn1dn"; - $myident = $tunnel['p1']['myident']['asn1dn']; - } else if (isset($tunnel['p1']['myident']['asn1dn'])) { - $myidentt = "asn1dn"; - $myident = $tunnel['p1']['myident']['asn1dn']; - } elseif (isset ($tunnel['p1']['myident']['dyn_dns'])) { - $myidentt = "dyn_dns"; - $myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']); + case "address"; + $myid_data = $ph1ent['myid_data']; + break; + + case "fqdn"; + case "keyid tag"; + case "user_fqdn"; + case "asn1dn"; + $myid_data = $ph1ent['myid_data']; + if( $myid_data ) + $myid_data = "\"".$myid_data."\""; + break; } - if (!($myidentt == "asn1dn" && $myident == "")) { - $myident = " \"{$myident}\""; + $rgip = $rgmap[$ph1ent['remote-gateway']]; + if (!$rgip) + continue; + + $peerid_type = $ph1ent['peerid_type']; + + switch ($peerid_type) { + case "peeraddress": + $peerid_type = "address"; + $peerid_data = $rgip; + break; + + case "address"; + $peerid_data = $ph1ent['peerid_data']; + break; + + case "fqdn"; + case "keyid tag"; + case "user_fqdn"; + case "asn1dn"; + $peerid_data = $ph1ent['peerid_data']; + if( $peerid_data ) + $peerid_data = "\"".$peerid_data."\""; + break; } $nattline = ''; - if (isset($tunnel['natt'])) { - $nattline = "nat_traversal on;"; - } + if (isset($ph1ent['nat_traversal'])) + $nattline = "nat_traversal {$ph1ent['nat_traversal']};"; - if (isset ($tunnel['p1']['authentication_method'])) { - $authmethod = $tunnel['p1']['authentication_method']; - } else { + if (isset ($ph1ent['authentication_method'])) + $authmethod = $ph1ent['authentication_method']; + else $authmethod = 'pre_shared_key'; - } $certline = ''; if ($authmethod == 'rsasig') { - if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) { - $cert = base64_decode($tunnel['p1']['cert']); - $private_key = base64_decode($tunnel['p1']['private-key']); + if ($ph1ent['cert'] && $ph1ent['private-key']) { + $cert = base64_decode($ph1ent['cert']); + $private_key = base64_decode($ph1ent['private-key']); } else { /* null certificate/key */ $cert = ''; $private_key = ''; } - if ($tunnel['p1']['peercert']) - $peercert = base64_decode($tunnel['p1']['peercert']); + if ($ph1ent['peercert']) + $peercert = base64_decode($ph1ent['peercert']); else $peercert = ''; - $fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w"); + $fd1 = fopen("{$g['varetc_path']}/server{$ikeid}-signed.pem", "w"); if (!$fd1) { - printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n"); + printf("Error: cannot open server{$ikeid}-signed.pem in vpn.\n"); return 1; } - chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600); + + chmod("{$g['varetc_path']}/server{$ikeid}-signed.pem", 0600); fwrite($fd1, $cert); fclose($fd1); - $fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w"); + $fd1 = fopen("{$g['varetc_path']}/server{$ikeid}-key.pem", "w"); if (!$fd1) { - printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n"); + printf("Error: cannot open server{$ikeid}-key.pem in vpn.\n"); return 1; } - chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600); + chmod("{$g['varetc_path']}/server{$ikeid}-key.pem", 0600); fwrite($fd1, $private_key); fclose($fd1); - $certline = "certificate_type x509 \"server{$tunnelnumber}-signed.pem\" \"server{$tunnelnumber}-key.pem\";"; + $certline = "certificate_type x509 \"server{$ikeid}-signed.pem\" \"server{$ikeid}-key.pem\";"; if ($peercert != '') { - $fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w"); + $fd1 = fopen("{$g['varetc_path']}/peer{$ikeid}-signed.pem", "w"); if (!$fd1) { - printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n"); + printf("Error: cannot open server{$ikeid}-signed.pem in vpn.\n"); return 1; } - chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600); + chmod("{$g['varetc_path']}/peer{$ikeid}-signed.pem", 0600); fwrite($fd1, $peercert); fclose($fd1); - $certline .=<<<EOD - - peers_certfile "peer{$tunnelnumber}-signed.pem"; -EOD; + $certline .="peers_certfile \"peer{$ikeid}-signed.pem\""; } } - $myidentifier = $myidentt; - if (!empty($myident)) - $myidentifier .= ' "' . $myident . '"'; + + $ealgos = ''; + $ealg_id = $ph1ent['encryption-algorithm']['name']; + $ealg_kl = $ph1ent['encryption-algorithm']['keylen']; + if ($ealg_kl) + $ealgos = $ealgos.$ealg_id." ".$ealg_kl; + else + $ealgos = $ealgos.$ealg_id; + + $lifeline = ''; + if ($ph1ent['lifetime']) + $lifeline = "lifetime time {$ph1ent['lifetime']} secs;"; + + /* add remote section to configuration */ + $racoonconf .=<<<EOD -remote {$tunnel['remote-gateway']} { - exchange_mode {$tunnel['p1']['mode']}; - my_identifier {$myidentt}{$myident}; + +remote {$rgip} +{ + ph1id {$ikeid}; + exchange_mode {$ph1ent['mode']}; + my_identifier {$myid_type} {$myid_data}; + peers_identifier {$peerid_type} {$peerid_data}; + ike_frag on; {$nattline} {$certline} - peers_identifier address {$rgip}; initial_contact on; - dpd_delay 120; # DPD poll every 120 seconds - ike_frag on; support_proxy on; - proposal_check obey; + proposal_check claim; - proposal \{ - encryption_algorithm {$tunnel['p1']['encryption-algorithm']}; - hash_algorithm {$tunnel['p1']['hash-algorithm']}; + proposal + { authentication_method {$authmethod}; - dh_group {$tunnel['p1']['dhgroup']}; + encryption_algorithm ${ealgos}; + hash_algorithm {$ph1ent['hash-algorithm']}; + dh_group {$ph1ent['dhgroup']}; + ${lifeline} + } +} EOD; - if ($tunnel['p1']['lifetime']) - $racoonconf .= " lifetime time {$tunnel['p1']['lifetime']} secs;\n"; - - $racoonconf .= " }\n"; + } + /* end remote */ + } + /* end remote sections */ + + /* begin sainfo sections */ + if (is_array($a_phase2) && count($a_phase2)) { + /* begin sainfo */ + foreach ($a_phase2 as $ph2ent) { - if ($tunnel['p1']['lifetime']) - $racoonconf .= " lifetime time {$tunnel['p1']['lifetime']} secs;\n"; + $ikeid = $ph2ent['ikeid']; - $racoonconf .= "}\n\n"; + $localid_type = $ph2ent['localid']['type']; + if ($localid_type != "address") + $localid_type = "subnet"; - $p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']); - $p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']); + $remoteid_type = $ph2ent['remoteid']['type']; + if ($remoteid_type != "address") + $remoteid_type = "subnet"; - $racoonconf .=<<<EOD -sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{ - encryption_algorithm {$p2ealgos}; - authentication_algorithm {$p2halgos}; - compression_algorithm deflate; + $localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']); + $remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']); -EOD; + $ealgos = ''; + $halgos = join(",", $ph2ent['hash-algorithm-option']); - if ($tunnel['p2']['pfsgroup']) - $racoonconf .= " pfs_group {$tunnel['p2']['pfsgroup']};\n"; + $pfsline = ''; + if ($ph2ent['pfsgroup']) + $pfsline = "pfs_group {$ph2ent['pfsgroup']};"; - if ($tunnel['p2']['lifetime']) - $racoonconf .= " lifetime time {$tunnel['p2']['lifetime']} secs;\n"; + $lifeline = ''; + if ($ph2ent['lifetime']) + $lifeline = "lifetime time {$ph2ent['lifetime']} secs;"; - $racoonconf .= "}\n\n"; - } + foreach ($ph2ent['encryption-algorithm-option'] as $ealg) { - /* mobile clients? */ - if (isset ($ipseccfg['mobileclients']['enable'])) { + $ealg_id = $ealg['name']; + $ealg_kl = $ealg['keylen']; - $tunnel = $ipseccfg['mobileclients']; + if ($ealg_kl) { + if( $ealg_kl == "auto" ) { + $key_hi = $p2_ealgos[$ealg_id]['keysel']['hi']; + $key_lo = $p2_ealgos[$ealg_id]['keysel']['lo']; + $key_step = $p2_ealgos[$ealg_id]['keysel']['step']; - if (isset ($tunnel['p1']['myident']['myaddress'])) { - $myidentt = "address"; - $myident = $curwanip; - } else - if (isset ($tunnel['p1']['myident']['address'])) { - $myidentt = "address"; - $myident = $tunnel['p1']['myident']['address']; - } else - if (isset ($tunnel['p1']['myident']['fqdn'])) { - $myidentt = "fqdn"; - $myident = $tunnel['p1']['myident']['fqdn']; - } else - if (isset ($tunnel['p1']['myident']['ufqdn'])) { - $myidentt = "user_fqdn"; - $myident = $tunnel['p1']['myident']['ufqdn']; + for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) { + if( $ealgos ) + $ealgos = $ealgos.", "; + $ealgos = $ealgos.$ealg_id." ".$keylen; + } + } else { + if ($ealgos) + $ealgos = $ealgos.", "; + $ealgos = $ealgos.$ealg_id." ".$ealg_kl; } - - if (isset ($tunnel['p1']['authentication_method'])) { - $authmethod = $tunnel['p1']['authentication_method']; - } else { - $authmethod = 'pre_shared_key'; - } - - $certline = ''; - if ($authmethod == 'rsasig') { - if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) { - $cert = base64_decode($tunnel['p1']['cert']); - $private_key = base64_decode($tunnel['p1']['private-key']); - } else { - /* null certificate/key */ - $cert = ''; - $private_key = ''; - } - - if ($tunnel['p1']['peercert']) - $peercert = base64_decode($tunnel['p1']['peercert']); - else - $peercert = ''; - - $fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w"); - if (!$fd1) { - printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n"); - return 1; - } - chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600); - fwrite($fd1, $cert); - fclose($fd1); - - $fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w"); - if (!$fd1) { - printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n"); - return 1; + } else { + if ($ealgos) + $ealgos = $ealgos.", "; + $ealgos = $ealgos.$ealg_id; + } } - chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600); - fwrite($fd1, $private_key); - fclose($fd1); - - $certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";"; - } - $racoonconf .=<<<EOD -remote anonymous \{ - exchange_mode {$tunnel['p1']['mode']}; - my_identifier {$myidentt}{$myident}; - {$certline} - initial_contact on; - dpd_delay 120; # DPD poll every 120 seconds - ike_frag on; - passive on; - generate_policy on; - support_proxy on; - proposal_check obey; - - proposal \{ - encryption_algorithm {$tunnel['p1']['encryption-algorithm']}; - hash_algorithm {$tunnel['p1']['hash-algorithm']}; - authentication_method {$authmethod}; - dh_group {$tunnel['p1']['dhgroup']}; - -EOD; - if ($tunnel['p1']['lifetime']) - $racoonconf .= " lifetime time {$tunnel['p1']['lifetime']} secs;\n"; - - $racoonconf .= " }\n"; - if ($tunnel['p1']['lifetime']) - $racoonconf .= " lifetime time {$tunnel['p1']['lifetime']} secs;\n"; - - $racoonconf .= "}\n\n"; - - $p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']); - $p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']); - - $racoonconf .=<<<EOD -sainfo anonymous \{ - encryption_algorithm {$p2ealgos}; - authentication_algorithm {$p2halgos}; + /* add sainfo section to configuration */ + + $racoonconf .=<<<EOD + +sainfo {$localid_type} {$localid_data} any {$remoteid_type} {$remoteid_data} any +{ + remoteid {$ikeid}; + encryption_algorithm {$ealgos}; + authentication_algorithm {$halgos}; compression_algorithm deflate; + ${pfsline} + ${lifeline} +} EOD; - - if ($tunnel['p2']['pfsgroup']) - $racoonconf .= " pfs_group {$tunnel['p2']['pfsgroup']};\n"; - - if ($tunnel['p2']['lifetime']) - $racoonconf .= " lifetime time {$tunnel['p2']['lifetime']} secs;\n"; - - $racoonconf .= "}\n\n"; + } + /* end sainfo */ } + /* end sainfo sections */ fwrite($fd, $racoonconf); fclose($fd); + } + /* end racoon.conf */ - /* generate psk.txt */ - $fd = fopen("{$g['varetc_path']}/psk.txt", "w"); + /* generate IPsec policies */ + if (is_array($a_phase2) && count($a_phase2)) { + /* generate spd.conf */ + $fd = fopen("{$g['varetc_path']}/spd.conf", "w"); if (!$fd) { - printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n"); + printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n"); return 1; } - $pskconf = ""; + $spdconf = ""; - if (is_array($ipseccfg['tunnel'])) { - foreach ($ipseccfg['tunnel'] as $tunnel) { - if (isset ($tunnel['disabled'])) - continue; - $rgip = $rgmap[$tunnel['remote-gateway']]; - if (!$rgip) - continue; - $pskconf .= "{$rgip} {$tunnel['p1']['pre-shared-key']}\n"; - } - } + /* What are these SPD entries for? + * -mgrooms 07/10/2008 + */ + $spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n"; + $spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n"; - /* add PSKs for mobile clients */ - if (is_array($ipseccfg['mobilekey'])) { - foreach ($ipseccfg['mobilekey'] as $key) { - $pskconf .= "{$key['ident']} {$key['pre-shared-key']}\n"; - } - } + foreach ($a_phase2 as $ph2ent) { + if( !ipsec_lookup_phase1($ph2ent,$ph1ent)) + continue; - fwrite($fd, $pskconf); - fclose($fd); - chmod("{$g['varetc_path']}/psk.txt", 0600); - - - if(is_process_running("racoon")) { - /* We are already online, reload */ - mwexec("/usr/bin/killall -HUP racoon"); - /* flush SPD entries */ - mwexec("/usr/local/sbin/setkey -FP"); - mwexec("/usr/local/sbin/setkey -F"); - /* load SPD */ - mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf"); - sleep(1); - /* We are already online, reload */ - mwexec("/usr/bin/killall -HUP racoon"); - sleep(1); - mwexec("/usr/bin/killall -HUP racoon"); - } else { - /* start racoon */ - mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf"); - /* flush SA + SPD entries*/ - mwexec("/usr/local/sbin/setkey -FP"); - mwexec("/usr/local/sbin/setkey -F"); - /* load SPD */ - mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf"); - sleep(1); - /* We are already online, reload */ - mwexec("/usr/bin/killall -HUP racoon"); - sleep(1); - mwexec("/usr/bin/killall -HUP racoon"); - - /* start dnswatch, if necessary */ - if (count($dnswatch_list) > 0) { - $interval = 60; - if ($ipseccfg['dns-interval']) { - $interval = $ipseccfg['dns-interval']; - } - - $hostnames = ""; - foreach ($dnswatch_list as $dns) { - $hostnames .= " " . escapeshellarg($dns); + if (isset ($ph1ent['disabled'])) + continue; + + if (isset ($ph2ent['disabled'])) + continue; + + $ep = vpn_endpoint_determine($ph1ent, $curwanip); + if (!$ep) + continue; + + $rgip = $rgmap[$ph1ent['remote-gateway']]; + + $localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true); + $remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true); + + if (isset ($ph2ent['creategif'])) { + $number_of_gifs = find_last_gif_device(); + $number_of_gifs++; + $curwanip = get_current_wan_address(); + if ($config['installedpackages']['sasyncd']['config'] <> "") { + foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) { + if ($sasyncd['ip'] <> "") + $curwanip = $sasyncd['ip']; + } } - mwexec("/usr/local/bin/dnswatch {$g['varrun_path']}/dnswatch-ipsec.pid $interval " . - escapeshellarg("/etc/rc.newipsecdns") . $hostnames); + mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $rgip); + mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32"); } - } - if (is_array($ipseccfg['tunnel'])) { - foreach ($ipseccfg['tunnel'] as $tunnel) { - if (isset ($tunnel['auto'])) { - $remotehost = substr($tunnel['remote-subnet'], 0, strpos($tunnel['remote-subnet'], "/")); - $srchost = vpn_endpoint_determine($tunnel, $curwanip); - if ($srchost) - mwexec_bg("/sbin/ping -c 10 -S {$srchost} {$remotehost}"); + $spdconf .= "spdadd {$localid} {$remoteid} any -P out ipsec " . + "{$ph2ent['protocol']}/tunnel/{$ep}-{$rgip}/unique;\n"; + + $spdconf .= "spdadd {$remoteid} {$localid} any -P in ipsec " . + "{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n"; + + /* static route needed? */ + if (preg_match("/^carp/i", $ph1ent['interface'])) + $parentinterface = link_carp_interface_to_parent($ph1ent['interface']); + else + $parentinterface = $ph1ent['interface']; + + if ($parentinterface <> "wan") { + /* add endpoint routes to correct gateway on interface */ + if (interface_has_gateway($parentinterface)) { + $gatewayip = get_interface_gateway("$parentinterface"); + $interfaceip = $config['interfaces'][$parentinterface]['ipaddr']; + $subnet_bits = $config['interfaces'][$parentinterface]['subnet']; + $subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}"); + /* if the remote gateway is in the local subnet, then don't add a route */ + if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) { + if(is_ipaddr($gatewayip)) { + log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}"); + mwexec("/sbin/route delete -host {$rgip};/sbin/route add -host {$rgip} {$gatewayip}"); + } + } } } + else + mwexec("/sbin/route delete -host {$rgip}"); + } + + fwrite($fd, $spdconf); + fclose($fd); + } + + /* mange racoon process */ + if (is_process_running("racoon")) { + /* We are already online, reload */ + mwexec("/usr/bin/killall -HUP racoon"); + /* flush SPD entries */ + mwexec("/usr/local/sbin/setkey -FP"); + mwexec("/usr/local/sbin/setkey -F"); + /* load SPD */ + mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf"); + sleep(1); + /* We are already online, reload */ + mwexec("/usr/bin/killall -HUP racoon"); + sleep(1); + mwexec("/usr/bin/killall -HUP racoon"); + } else { + /* start racoon */ + mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf"); + /* flush SA + SPD entries */ + mwexec("/usr/local/sbin/setkey -FP"); + mwexec("/usr/local/sbin/setkey -F"); + /* load SPD */ + mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf"); + sleep(1); + /* We are already online, reload */ + mwexec("/usr/bin/killall -HUP racoon"); + sleep(1); + mwexec("/usr/bin/killall -HUP racoon"); + + /* start dnswatch, if necessary */ + if (count($dnswatch_list) > 0) { + $interval = 60; + if ($ipseccfg['dns-interval']) + $interval = $ipseccfg['dns-interval']; + + $hostnames = ""; + foreach ($dnswatch_list as $dns) + $hostnames .= " " . escapeshellarg($dns); + + mwexec("/usr/local/bin/dnswatch {$g['varrun_path']}/dnswatch-ipsec.pid $interval " . + escapeshellarg("/etc/rc.newipsecdns") . $hostname); } } } - + vpn_ipsec_failover_configure(); if (!$g['booting']) { @@ -943,20 +985,20 @@ function vpn_localnet_determine($adr, & $sa, & $sn) { } } -function vpn_endpoint_determine($tunnel, $curwanip) { +function vpn_endpoint_determine($ph1ent, $curwanip) { global $g, $config; - if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) { + if ((!$ph1ent['interface']) || ($ph1ent['interface'] == "wan")) { if ($curwanip) return $curwanip; else return null; - } elseif ($tunnel['interface'] == "lan") { + } elseif ($ph1ent['interface'] == "lan") { return $config['interfaces']['lan']['ipaddr']; } else { - $iface = $config['interfaces'][$tunnel['interface']]['if']; - $oc = $config['interfaces'][$tunnel['interface']]; + $iface = $config['interfaces'][$ph1ent['interface']]['if']; + $oc = $config['interfaces'][$ph1ent['interface']]; /* carp ips, etc */ $ip = find_interface_ip($iface); if($ip) diff --git a/etc/inc/xmlparse.inc b/etc/inc/xmlparse.inc index 6eabbe1..64179d7 100644 --- a/etc/inc/xmlparse.inc +++ b/etc/inc/xmlparse.inc @@ -34,7 +34,7 @@ function listtags() { $ret = explode(" ", "element alias aliasurl allowedip cacert config columnitem disk dnsserver domainoverrides " . "earlyshellcmd encryption-algorithm-option field fieldname hash-algorithm-option " . - "hosts group interface_array item key lbpool menu mobilekey mount onetoone option ppp package passthrumac priv proxyarpnet " . + "hosts group interface_array item key lbpool menu mobilekey mount onetoone option ppp package passthrumac phase1 phase2 priv proxyarpnet " . "queue pages pipe route row rule schedule service servernat servers serversdisabled earlyshellcmd shellcmd staticmap subqueue " . "timerange tunnel user vip virtual_server vlan winsserver ntpserver wolentry widget depends_on_package gateway_item gateway_group"); return $ret; diff --git a/usr/local/www/diag_ipsec.php b/usr/local/www/diag_ipsec.php index 4b16fe5..a61a5a1 100644 --- a/usr/local/www/diag_ipsec.php +++ b/usr/local/www/diag_ipsec.php @@ -3,6 +3,7 @@ /* diag_ipsec.php Copyright (C) 2007 Scott Ullrich + Copyright (C) 2008 Shrew Soft Inc <mgrooms@shrew.net>. All rights reserved. Parts of this code was originally based on vpn_ipsec_sad.php @@ -30,170 +31,111 @@ POSSIBILITY OF SUCH DAMAGE. */ +global $g; + $pgtitle = array("Status","IPsec"); require("guiconfig.inc"); include("head.inc"); + +if (!is_array($config['ipsec']['phase2'])) + $config['ipsec']['phase2'] = array(); + +$a_phase2 = &$config['ipsec']['phase2']; + +$spd = ipsec_dump_spd(); +$sad = ipsec_dump_sad(); + ?> <body link="#0000CC" vlink="#0000CC" alink="#0000CC" onload="<?= $jsevents["body"]["onload"] ?>"> <?php include("fbegin.inc"); ?> <div id="inputerrors"></div> <table width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr> - <td> -<?php - $tab_array = array(); - $tab_array[0] = array("Overview", true, "diag_ipsec.php"); - $tab_array[1] = array("SAD", false, "diag_ipsec_sad.php"); - $tab_array[2] = array("SPD", false, "diag_ipsec_spd.php"); - display_top_tabs($tab_array); -?> - </td> - </tr> - <tr> - <td> -<?php - -if (!is_array($config['ipsec']['tunnel'])) { - $config['ipsec']['tunnel'] = array(); -} - -/* query SAD */ -$fd = @popen("/sbin/setkey -D", "r"); -$sad = array(); -if ($fd) { - while (!feof($fd)) { - $line = chop(fgets($fd)); - if (!$line) - 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); - $i = 0; - } else { - $linea = explode(" ", trim($line)); - if ($i == 1) { - $cursa['proto'] = $linea[0]; - $cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1); - } else if ($i == 2) { - $cursa['ealgo'] = $linea[1]; - } else if ($i == 3) { - $cursa['aalgo'] = $linea[1]; - } - } - $i++; - } - if (is_array($cursa) && count($cursa)) - $sad[] = $cursa; - pclose($fd); -} -?> - <div id="mainarea"> - <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> -<?php if (count($sad)): ?> - <tr> - <td nowrap class="listhdrr">Source</td> - <td nowrap class="listhdrr">Destination</a></td> - <td nowrap class="listhdrr">Description</a></td> - <td nowrap class="listhdrr">Status</td> - </tr> -<?php -foreach ($config['ipsec']['tunnel'] as $ipsec) { - if(! isset($ipsec['disabled'])) { -?> <tr> - <td class="listlr"><?=htmlspecialchars(get_ipsec_tunnel_src($ipsec));?> - <br/> - <?php if ($ipsec['local-subnet']['network']) - echo strtoupper($ipsecent['local-subnet']['network']); - else - echo $ipsec['local-subnet']['address']; - ?> + <td> + <?php + $tab_array = array(); + $tab_array[0] = array("Overview", true, "diag_ipsec.php"); + $tab_array[1] = array("SAD", false, "diag_ipsec_sad.php"); + $tab_array[2] = array("SPD", false, "diag_ipsec_spd.php"); + display_top_tabs($tab_array); + ?> </td> - <td class="listr"><?=htmlspecialchars($ipsec['remote-gateway']);?> - <br/> - <?=$ipsec['remote-subnet'];?> - </td> - <td class="listr"><?=htmlspecialchars($ipsec['descr']);?></td> - <td class="listr"><?php echo output_ipsec_tunnel_status($ipsec); ?></td> </tr> -<?php - } -} -?> -<?php else: ?> - <tr> - <td> - <p> - <strong>No IPsec security associations.</strong> - </p> - </td> - </tr> -<?php endif; ?> - <tr> - <td colspan="4"> - <p> - <span class="vexpl"> - <span class="red"> - <strong> - Note:<br /> - </strong> - </span> - You can configure your IPsec - <a href="vpn_ipsec.php">here</a>. - </span> - </p> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> + <?php if (count($sad)): ?> + <tr> + <td nowrap class="listhdrr">Local IP</td> + <td nowrap class="listhdrr">Remote IP</a></td> + <td nowrap class="listhdrr">Local Network</td> + <td nowrap class="listhdrr">Remote Network</a></td> + <td nowrap class="listhdrr">Description</a></td> + <td nowrap class="listhdrr">Status</td> + </tr> + <?php + foreach ($a_phase2 as $ph2ent) { + if (!isset($ph2ent['disabled'])) { + ipsec_lookup_phase1($ph2ent,$ph1ent); + if(ipsec_phase2_status($spd,$sad,$ph1ent,$ph2ent)) + $icon = "pass"; + else + $icon = "reject"; + ?> + <tr> + <td class="listlr"> + <?=htmlspecialchars(ipsec_get_phase1_src($ph1ent));?> + </td> + <td class="listr"> + <?=htmlspecialchars($ph1ent['remote-gateway']);?> + </td> + <td class="listr"> + <?php echo ipsec_idinfo_to_text($ph2ent['localid']); ?> + </td> + <td class="listr"> + <?php echo ipsec_idinfo_to_text($ph2ent['remoteid']); ?> + </td> + <td class="listr"><?=htmlspecialchars($ph2ent['descr']);?></td> + <td class="listr"> + <img src ="/themes/<?=$g['theme']?>/images/icons/icon_<?=$icon?>.gif"> + </td> + </tr> + <?php + } + } + ?> + <?php else: ?> + <tr> + <td> + <p> + <strong>No IPsec security associations.</strong> + </p> + </td> + </tr> + <?php endif; ?> + <tr> + <td colspan="4"> + <p> + <span class="vexpl"> + <span class="red"> + <strong>Note:<br /></strong> + </span> + You can configure your IPsec + <a href="vpn_ipsec.php">here</a>. + </span> + </p> + </td> + </tr> + </table> + </div> </td> - </tr> -</table> -</div> - -</td></tr> - + </tr> </table> <?php include("fend.inc"); ?> </body> </html> -<?php - -function get_ipsec_tunnel_src($tunnel) { - global $g, $config, $sad; - $if = "WAN"; - if ($tunnel['interface']) { - $if = $tunnel['interface']; - $realinterface = convert_friendly_interface_to_real_interface_name($if); - $interfaceip = find_interface_ip($realinterface); - } - return $interfaceip; -} - -function output_ipsec_tunnel_status($tunnel) { - global $g, $config, $sad; - $if = "WAN"; - $interfaceip = get_ipsec_tunnel_src($tunnel); - $foundsrc = false; - $founddst = false; - foreach($sad as $sa) { - if($sa['src'] == $interfaceip) - $foundsrc = true; - if($sa['dst'] == $tunnel['remote-gateway']) - $founddst = true; - } - if($foundsrc && $founddst) { - /* tunnel is up */ - $iconfn = "pass"; - } else { - /* tunnel is down */ - $iconfn = "reject"; - } - echo "<img src ='/themes/{$g['theme']}/images/icons/icon_{$iconfn}.gif'>"; -} - -?> diff --git a/usr/local/www/diag_ipsec_sad.php b/usr/local/www/diag_ipsec_sad.php index 5d5b738..f2a08af 100755 --- a/usr/local/www/diag_ipsec_sad.php +++ b/usr/local/www/diag_ipsec_sad.php @@ -33,30 +33,14 @@ require("guiconfig.inc"); -$pgtitle = array("Status","IPsec","SA"); +$pgtitle = array("Status","IPsec","SAD"); include("head.inc"); -?> - -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> -<?php include("fbegin.inc"); ?> -<table width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr><td> -<?php - $tab_array = array(); - $tab_array[0] = array("Overview", false, "diag_ipsec.php"); - $tab_array[1] = array("SAD", true, "diag_ipsec_sad.php"); - $tab_array[2] = array("SPD", false, "diag_ipsec_spd.php"); - display_top_tabs($tab_array); -?> - </td></tr> - <tr> - <td> -<?php +$sad = ipsec_dump_sad(); /* delete any SA? */ if ($_GET['act'] == "del") { - $fd = @popen("/sbin/setkey -c > /dev/null 2>&1", "w"); + $fd = @popen("/usr/local/sbin/setkey -c > /dev/null 2>&1", "w"); if ($fd) { fwrite($fd, "delete {$_GET['src']} {$_GET['dst']} {$_GET['proto']} {$_GET['spi']} ;\n"); pclose($fd); @@ -64,87 +48,79 @@ if ($_GET['act'] == "del") { } } -/* query SAD */ -$fd = @popen("/sbin/setkey -D", "r"); -$sad = array(); -if ($fd) { - while (!feof($fd)) { - $line = chop(fgets($fd)); - if (!$line) - 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); - $i = 0; - } else { - $linea = explode(" ", trim($line)); - if ($i == 1) { - $cursa['proto'] = $linea[0]; - $cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1); - } else if ($i == 2) { - $cursa['ealgo'] = $linea[1]; - } else if ($i == 3) { - $cursa['aalgo'] = $linea[1]; - } - } - $i++; - } - if (is_array($cursa) && count($cursa)) - $sad[] = $cursa; - pclose($fd); -} ?> - <div id="mainarea"> - <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> -<?php if (count($sad)): ?> - <tr> - <td nowrap class="listhdrr">Source</td> - <td nowrap class="listhdrr">Destination</a></td> - <td nowrap class="listhdrr">Protocol</td> - <td nowrap class="listhdrr">SPI</td> - <td nowrap class="listhdrr">Enc. alg.</td> - <td nowrap class="listhdr">Auth. alg.</td> - <td nowrap class="list"></td> - </tr> -<?php -foreach ($sad as $sa): ?> - <tr> - <td class="listlr"><?=htmlspecialchars($sa['src']);?></td> - <td class="listr"><?=htmlspecialchars($sa['dst']);?></td> - <td class="listr"><?=htmlspecialchars(strtoupper($sa['proto']));?></td> - <td class="listr"><?=htmlspecialchars($sa['spi']);?></td> - <td class="listr"><?=htmlspecialchars($sa['ealgo']);?></td> - <td class="listr"><?=htmlspecialchars($sa['aalgo']);?></td> - <td class="list" nowrap> - <?php - $args = "src=" . rawurlencode($sa['src']); - $args .= "&dst=" . rawurlencode($sa['dst']); - $args .= "&proto=" . rawurlencode($sa['proto']); - $args .= "&spi=" . rawurlencode("0x" . $sa['spi']); - ?> - <a href="diag_ipsec_sad.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security association?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a> - </td> - - </tr> -<?php endforeach; ?> -<?php else: ?> -<tr><td><p><strong>No IPsec security associations.</strong></p></td></tr> -<?php endif; ?> -<td colspan="4"> - <p><span class="vexpl"><span class="red"><strong>Note:<br> - </strong></span>You can configure your IPsec <a href="vpn_ipsec.php">here</a>.</span></p> - </td> -</table> -</div> -</td></tr> - -</table> - -<?php include("fend.inc"); ?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> + <?php include("fbegin.inc"); ?> + <table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <?php + $tab_array = array(); + $tab_array[0] = array("Overview", false, "diag_ipsec.php"); + $tab_array[1] = array("SAD", true, "diag_ipsec_sad.php"); + $tab_array[2] = array("SPD", false, "diag_ipsec_spd.php"); + display_top_tabs($tab_array); + ?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> + <?php if (count($sad)): ?> + <tr> + <td nowrap class="listhdrr">Source</td> + <td nowrap class="listhdrr">Destination</a></td> + <td nowrap class="listhdrr">Protocol</td> + <td nowrap class="listhdrr">SPI</td> + <td nowrap class="listhdrr">Enc. alg.</td> + <td nowrap class="listhdr">Auth. alg.</td> + <td nowrap class="list"></td> + </tr> + <?php foreach ($sad as $sa): ?> + <tr> + <td class="listlr"><?=htmlspecialchars($sa['src']);?></td> + <td class="listr"><?=htmlspecialchars($sa['dst']);?></td> + <td class="listr"><?=htmlspecialchars(strtoupper($sa['proto']));?></td> + <td class="listr"><?=htmlspecialchars($sa['spi']);?></td> + <td class="listr"><?=htmlspecialchars($sa['ealgo']);?></td> + <td class="listr"><?=htmlspecialchars($sa['aalgo']);?></td> + <td class="list" nowrap> + <?php + $args = "src=" . rawurlencode($sa['src']); + $args .= "&dst=" . rawurlencode($sa['dst']); + $args .= "&proto=" . rawurlencode($sa['proto']); + $args .= "&spi=" . rawurlencode("0x" . $sa['spi']); + ?> + <a href="diag_ipsec_sad.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security association?')"> + <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"> + </a> + </td> + </tr> + <?php endforeach; ?> + <?php else: ?> + <tr> + <td> + <p><strong>No IPsec security associations.</strong></p> + </td> + </tr> + <?php endif; ?> + <td colspan="4"> + <p> + <span class="vexpl"> + <span class="red"> + <strong>Note:<br></strong> + </span> + You can configure your IPsec <a href="vpn_ipsec.php">here</a>. + </span> + </p> + </td> + </table> + </div> + </td> + </tr> + </table> + <?php include("fend.inc"); ?> </body> </html> diff --git a/usr/local/www/diag_ipsec_spd.php b/usr/local/www/diag_ipsec_spd.php index dc6ee6f..d9dfe54 100755 --- a/usr/local/www/diag_ipsec_spd.php +++ b/usr/local/www/diag_ipsec_spd.php @@ -36,129 +36,104 @@ require("guiconfig.inc"); $pgtitle = array("Status","IPsec","SPD"); include("head.inc"); -?> - -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> -<?php include("fbegin.inc"); ?> -<table width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr><td> -<?php - $tab_array = array(); - $tab_array[0] = array("Overview", false, "diag_ipsec.php"); - $tab_array[1] = array("SAD", false, "diag_ipsec_sad.php"); - $tab_array[2] = array("SPD", true, "diag_ipsec_spd.php"); - display_top_tabs($tab_array); -?> - </td></tr> - <tr> - <td> -<?php - /* delete any SP? */ if ($_GET['act'] == "del") { - $fd = @popen("/sbin/setkey -c > /dev/null 2>&1", "w"); + $fd = @popen("/usr/local/sbin/setkey -c > /dev/null 2>&1", "w"); if ($fd) { - fwrite($fd, "spddelete {$_GET['src']} {$_GET['dst']} any -P {$_GET['dir']} ;\n"); + fwrite($fd, "spddelete {$_GET['srcid']} {$_GET['dstid']} any -P {$_GET['dir']} ;\n"); pclose($fd); sleep(1); } } -/* query SAD */ -$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['src'] = substr($linea[0], 0, strpos($linea[0], "[")); - $cursp['dst'] = substr($linea[1], 0, strpos($linea[1], "[")); - $i = 0; - } else if (is_array($cursp)) { - $linea = explode(" ", trim($line)); - if ($i == 1) { - if ($linea[1] == "none") /* don't show default anti-lockout rule */ - unset($cursp); - else - $cursp['dir'] = $linea[0]; - } else if ($i == 2) { - $upperspec = explode("/", $linea[0]); - $cursp['proto'] = $upperspec[0]; - list($cursp['ep_src'], $cursp['ep_dst']) = explode("-", $upperspec[2]); - } - } - $i++; - } - if (is_array($cursp) && count($cursp)) - $spd[] = $cursp; - pclose($fd); -} +$spd = ipsec_dump_spd(); ?> -<div id="mainarea" style="background:#eeeeee"> - <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> -<?php if (count($spd)): ?> - <tr> - <td nowrap class="listhdrr">Source</td> - <td nowrap class="listhdrr">Destination</a></td> - <td nowrap class="listhdrr">Direction</td> - <td nowrap class="listhdrr">Protocol</td> - <td nowrap class="listhdrr">Tunnel endpoints</td> - <td nowrap class="list"></td> - </tr> -<?php -foreach ($spd as $sp): ?> - <tr> - <td class="listlr" valign="top"><?=htmlspecialchars($sp['src']);?></td> - <td class="listr" valign="top"><?=htmlspecialchars($sp['dst']);?></td> - <td class="listr" valign="top"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_<?=$sp['dir'];?>.gif" width="11" height="11" style="margin-top: 2px"></td> - <td class="listr" valign="top"><?=htmlspecialchars(strtoupper($sp['proto']));?></td> - <td class="listr" valign="top"><?=htmlspecialchars($sp['ep_src']);?> - <br> - <?=htmlspecialchars($sp['ep_dst']);?></td> - <td class="list" nowrap> - <?php - $args = "src=" . rawurlencode($sp['src']); - $args .= "&dst=" . rawurlencode($sp['dst']); - $args .= "&dir=" . rawurlencode($sp['dir']); - ?> - <a href="diag_ipsec_spd.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security policy?')"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a> - </td> - </tr> -<?php endforeach; ?> -</table> -<br> -<table class="tabcont" border="0" cellspacing="0" cellpadding="6"> - <tr> - <td width="16"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_in.gif" width="11" height="11"></td> - <td>incoming (as seen by firewall)</td> - </tr> - <tr> - <td colspan="5" height="4"></td> - </tr> - <tr> - <td><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_out.gif" width="11" height="11"></td> - <td>outgoing (as seen by firewall)</td> - </tr> -<?php else: ?> -<tr><td><p><strong>No IPsec security policies.</strong></p></td></tr> -<?php endif; ?> -<td colspan="4"> - <p><span class="vexpl"><span class="red"><strong>Note:<br> - </strong></span>You can configure your IPsec <a href="vpn_ipsec.php">here</a>.</span></p> - </td> -</table> -</div> -</td></tr></table> -<?php include("fend.inc"); ?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> + <?php include("fbegin.inc"); ?> + <table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <?php + $tab_array = array(); + $tab_array[0] = array("Overview", false, "diag_ipsec.php"); + $tab_array[1] = array("SAD", false, "diag_ipsec_sad.php"); + $tab_array[2] = array("SPD", true, "diag_ipsec_spd.php"); + display_top_tabs($tab_array); + ?> + </td> + </tr> + <tr> + <td> + <div id="mainarea" style="background:#eeeeee"> + <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> + <?php if (count($spd)): ?> + <tr> + <td nowrap class="listhdrr">Source</td> + <td nowrap class="listhdrr">Destination</td> + <td nowrap class="listhdrr">Direction</td> + <td nowrap class="listhdrr">Protocol</td> + <td nowrap class="listhdrr">Tunnel endpoints</td> + <td nowrap class="list"></td> + </tr> + <?php foreach ($spd as $sp): ?> + <tr> + <td class="listlr" valign="top"><?=htmlspecialchars($sp['srcid']);?></td> + <td class="listr" valign="top"><?=htmlspecialchars($sp['dstid']);?></td> + <td class="listr" valign="top"> + <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_<?=$sp['dir'];?>.gif" width="11" height="11" style="margin-top: 2px"> + </td> + <td class="listr" valign="top"><?=htmlspecialchars(strtoupper($sp['proto']));?></td> + <td class="listr" valign="top"><?=htmlspecialchars($sp['src']);?> -> <?=htmlspecialchars($sp['dst']);?></td> + <td class="list" nowrap> + <?php + $args = "srcid=".rawurlencode($sp['srcid']); + $args .= "&dstid=".rawurlencode($sp['dstid']); + $args .= "&dir=".rawurlencode($sp['dir']); + ?> + <a href="diag_ipsec_spd.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security policy?')"> + <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"> + </a> + </td> + </tr> + <?php endforeach; ?> + </table> + <br> + <table class="tabcont" border="0" cellspacing="0" cellpadding="6"> + <tr> + <td width="16"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_in.gif" width="11" height="11"></td> + <td>incoming (as seen by firewall)</td> + </tr> + <tr> + <td colspan="5" height="4"></td> + </tr> + <tr> + <td><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_out.gif" width="11" height="11"></td> + <td>outgoing (as seen by firewall)</td> + </tr> + <?php else: ?> + <tr> + <td> + <p><strong>No IPsec security policies.</strong></p> + </td> + </tr> + <?php endif; ?> + <td colspan="4"> + <p> + <span class="vexpl"> + <span class="red"> + <strong>Note:<br></strong> + </span> + You can configure your IPsec <a href="vpn_ipsec.php">here</a>. + </span> + </p> + </td> + </table> + </div> + </td> + </tr> + </table> + <?php include("fend.inc"); ?> </body> </html> diff --git a/usr/local/www/diag_logs_ipsec.php b/usr/local/www/diag_logs_ipsec.php index a6b8ae6..74cf757 100755 --- a/usr/local/www/diag_logs_ipsec.php +++ b/usr/local/www/diag_logs_ipsec.php @@ -38,11 +38,11 @@ $ipsec_logfile = "{$g['varlog_path']}/ipsec.log"; /* Create array with all IPsec tunnel descriptions */ $search = array(); $replace = array(); -if(is_array($config['ipsec']['tunnel'])) - foreach($config['ipsec']['tunnel'] as $tunnel) { - $gateway = "{$tunnel['remote-gateway']}"; +if(is_array($config['ipsec']['phase1'])) + foreach($config['ipsec']['phase1'] as $ph1ent) { + $gateway = "{$ph1ent['remote-gateway']}"; $search[] = "/(racoon: )([A-Z:].*?)({$gateway}\[[0-9].+\]|{$gateway})(.*)/i"; - $replace[] = "$1<strong>[{$tunnel['descr']}]</strong>: $2$3$4"; + $replace[] = "$1<strong>[{$ph1ent['descr']}]</strong>: $2$3$4"; } /* collect all our own ip addresses */ exec("/sbin/ifconfig|/usr/bin/awk '/inet / {print $2}'", $ip_address_list); diff --git a/usr/local/www/guiconfig.inc b/usr/local/www/guiconfig.inc index 1c6ab78..9fecc45 100755 --- a/usr/local/www/guiconfig.inc +++ b/usr/local/www/guiconfig.inc @@ -157,25 +157,6 @@ $medias = array("auto" => "autoselect", "100full" => "100BASE-TX full-duplex", /* platforms that support firmware updating */ $fwupplatforms = array('pfSense', 'net45xx', 'net48xx', 'generic-pc', 'embedded', 'wrap'); -/* IPsec defines */ -$my_identifier_list = array('myaddress' => 'My IP address', - 'address' => 'IP address', - 'fqdn' => 'Domain name', - 'user_fqdn' => 'User FQDN', - 'asn1dn' => 'Distinguished Name', - 'dyn_dns' => 'Dynamic DNS'); - -$p1_ealgos = array('des' => 'DES', '3des' => '3DES', 'blowfish' => 'Blowfish', - 'cast128' => 'CAST128','rijndael' => 'Rijndael (AES)', 'rijndael 256' => 'Rijndael 256'); -$p2_ealgos = array('des' => 'DES', '3des' => '3DES', 'blowfish' => 'Blowfish', - 'cast128' => 'CAST128', 'rijndael' => 'Rijndael (AES)', 'rijndael 256' => 'Rijndael 256'); - -$p1_halgos = array('sha1' => 'SHA1', 'md5' => 'MD5'); -$p1_authentication_methods = array('pre_shared_key' => 'Pre-shared key', 'rsasig' => 'RSA signature'); -$p2_halgos = array('hmac_sha1' => 'SHA1', 'hmac_md5' => 'MD5'); -$p2_protos = array('esp' => 'ESP', 'ah' => 'AH'); -$p2_pfskeygroups = array('0' => 'off', '1' => '1', '2' => '2', '5' => '5'); - function do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) { /* check for bad control characters */ diff --git a/usr/local/www/pkg_edit.php b/usr/local/www/pkg_edit.php index a2a2442..64826d0 100755 --- a/usr/local/www/pkg_edit.php +++ b/usr/local/www/pkg_edit.php @@ -381,7 +381,7 @@ if ($pkg['tabs'] <> "") { print("</select>\n<br />\n" . fixup_string($pkga['description']) . "\n"); } else if($pkga['type'] == "vpn_selection") { echo "<select id='" . $pkga['fieldname'] . "' name='" . $vpn['name'] . "'>\n"; - foreach ($config['ipsec']['tunnel'] as $vpn) { + foreach ($config['ipsec']['phase1'] as $vpn) { echo "\t<option value=\"" . $vpn['descr'] . "\">" . $vpn['descr'] . "</option>\n"; } echo "</select>\n"; diff --git a/usr/local/www/vpn_ipsec.php b/usr/local/www/vpn_ipsec.php index 4946d73..94f4c37 100755 --- a/usr/local/www/vpn_ipsec.php +++ b/usr/local/www/vpn_ipsec.php @@ -4,6 +4,7 @@ part of m0n0wall (http://m0n0.ch/wall) Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>. + Copyright (C) 2008 Shrew Soft Inc All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,14 +31,18 @@ require("guiconfig.inc"); -if (!is_array($config['ipsec']['tunnel'])) { - $config['ipsec']['tunnel'] = array(); -} -$a_ipsec = &$config['ipsec']['tunnel']; +if (!is_array($config['ipsec']['phase1'])) + $config['ipsec']['phase1'] = array(); + +if (!is_array($config['ipsec']['phase2'])) + $config['ipsec']['phase2'] = array(); + +$a_phase1 = &$config['ipsec']['phase1']; +$a_phase2 = &$config['ipsec']['phase2']; + $wancfg = &$config['interfaces']['wan']; $pconfig['enable'] = isset($config['ipsec']['enable']); -$pconfig['ipcomp'] = isset($config['ipsec']['ipcomp']); if ($_POST) { @@ -53,7 +58,6 @@ if ($_POST) { $pconfig = $_POST; $config['ipsec']['enable'] = $_POST['enable'] ? true : false; - $config['ipsec']['ipcomp'] = $_POST['ipcomp'] ? true : false; write_config(); @@ -72,13 +76,41 @@ if ($_POST) { } } -if ($_GET['act'] == "del") { - if ($a_ipsec[$_GET['id']]) { +if ($_GET['act'] == "delph1") +{ + if ($a_phase1[$_GET['p1index']]) { /* remove static route if interface is not WAN */ - if($a_ipsec[$_GET['id']]['interface'] <> "wan") { - mwexec("/sbin/route delete -host {$$a_ipsec[$_GET['id']]['remote-gateway']}"); + if ($a_phase1[$_GET['p1index']]['interface'] <> "wan") { + mwexec("/sbin/route delete -host {$$a_phase1[$_GET['p1index']]['remote-gateway']}"); + } + + /* remove all phase2 entries that match the ikeid */ + $ikeid = $a_phase1[$_GET['p1index']]['ikeid']; + $p2index = 0; + foreach ($a_phase2 as $ph2tmp) { + if ($ph2tmp['ikeid'] == $ikeid) { + /* remove the phase2 entry */ + unset($a_phase2[$p2index]); + continue; + } + /* only skip if we remove an entry */ + $p2index++; } - unset($a_ipsec[$_GET['id']]); + + /* remove the phase1 entry */ + unset($a_phase1[$_GET['p1index']]); + filter_configure(); + write_config(); + header("Location: vpn_ipsec.php"); + exit; + } +} + +if ($_GET['act'] == "delph2") +{ + if ($a_phase2[$_GET['p2index']]) { + /* remove the phase2 entry */ + unset($a_phase2[$_GET['p2index']]); filter_configure(); write_config(); header("Location: vpn_ipsec.php"); @@ -95,133 +127,270 @@ include("head.inc"); <body link="#0000CC" vlink="#0000CC" alink="#0000CC"> <?php include("fbegin.inc"); ?> <form action="vpn_ipsec.php" method="post"> -<?php if ($savemsg) print_info_box($savemsg); ?> -<?php if (file_exists($d_ipsecconfdirty_path)): ?><p> -<?php if ($pconfig['enable']) - print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> -<?php endif; ?> -<table width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr><td class="tabnavtbl"> <?php - $tab_array = array(); - $tab_array[0] = array("Tunnels", true, "vpn_ipsec.php"); - $tab_array[1] = array("Mobile clients", false, "vpn_ipsec_mobile.php"); - $tab_array[2] = array("Pre-shared keys", false, "vpn_ipsec_keys.php"); - $tab_array[3] = array("CAs", false, "vpn_ipsec_ca.php"); - display_top_tabs($tab_array); + if ($savemsg) + print_info_box($savemsg); + if ($pconfig['enable'] && file_exists($d_ipsecconfdirty_path)) + print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect."); ?> - </td></tr> - <tr> - <td> - <div id="mainarea"> - <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> - <tr> - <td class="vtable"> - <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable']) echo "checked";?>> - <strong>Enable IPsec</strong></td> - </tr> - <tr> - <td> <input name="submit" type="submit" class="formbtn" value="Save"> - </td> - </tr> - </table> - <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr> - <td nowrap class="listhdrr">Local net<br> - Remote net</td> - <td class="listhdrr">Interface<br>Remote gw</td> - <td class="listhdrr">P1 mode</td> - <td class="listhdrr">P1 Enc. Algo</td> - <td class="listhdrr">P1 Hash Algo</td> - <td class="listhdr">Description</td> - <td class="list" > - <table border="0" cellspacing="0" cellpadding="1"> - <tr> - <td width="17" heigth="17"></td> - <td><a href="vpn_ipsec_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add tunnel" width="17" height="17" border="0"></a></td> - </tr> - </table> - </td> - </tr> - <?php $i = 0; foreach ($a_ipsec as $ipsecent): - if (isset($ipsecent['disabled'])) { - $spans = "<span class=\"gray\">"; - $spane = "</span>"; - } else { - $spans = $spane = ""; - } - ?> - <tr valign="top"> - <td nowrap class="listlr" ondblclick="document.location='vpn_ipsec_edit.php?id=<?=$i;?>'"><?=$spans;?> - <?php if ($ipsecent['local-subnet']['network']) - echo strtoupper($ipsecent['local-subnet']['network']); +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td class="tabnavtbl"> + <?php + $tab_array = array(); + $tab_array[0] = array("Tunnels", true, "vpn_ipsec.php"); +// $tab_array[1] = array("Mobile clients", false, "vpn_ipsec_mobile.php"); + $tab_array[2] = array("CAs", false, "vpn_ipsec_ca.php"); + display_top_tabs($tab_array); + ?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td class="vtable"> + <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable']) echo "checked";?>> + <strong>Enable IPsec</strong> + </td> + </tr> + <tr> + <td> + <input name="submit" type="submit" class="formbtn" value="Save"> + </td> + </tr> + </table> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td class="listhdrr">Interface<br>Remote gw</td> + <td class="listhdrr">P1 mode</td> + <td class="listhdrr">P1 Enc. Algo</td> + <td class="listhdrr">P1 Hash Algo</td> + <td class="listhdr">Description</td> + <td class="list" > + <table border="0" cellspacing="0" cellpadding="o"> + <tr> + <td width="17" heigth="17"></td> + <td> + <a href="vpn_ipsec_phase1.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add phase1 entry" width="17" height="17" border="0"></a> + </td> + </tr> + </table> + </td> + </tr> + <?php + $i = 0; + foreach ($a_phase1 as $ph1ent) { + if (isset( $ph1ent['disabled'])) { + $spans = "<span class=\"gray\">"; + $spane = "</span>"; + } else - echo $ipsecent['local-subnet']['address']; + $spans = $spane = ""; ?> - <br> - <?=$ipsecent['remote-subnet'];?> - <?=$spane;?></td> - <td class="listr" ondblclick="document.location='vpn_ipsec_edit.php?id=<?=$i;?>'"><?=$spans;?> - <?php if ($ipsecent['interface']) { - $iflabels = get_configured_interface_with_descr(); - $carpips = find_number_of_needed_carp_interfaces(); - for($j=0; $j<$carpips; $j++) { - $carpip = find_interface_ip("carp" . $j); - $iflabels['carp' . $j] = "CARP{$j} ({$carpip})"; - } - $if = htmlspecialchars($iflabels[$ipsecent['interface']]); - } else - $if = "WAN"; - - echo $if . "<br>" . $ipsecent['remote-gateway']; + <tr valign="top"> + <td class="listlr" ondblclick="document.location='vpn_ipsec_phase1.php?id=<?=$i;?>'"> + <?=$spans;?> + <?php + if ($ph1ent['interface']) { + $iflabels = get_configured_interface_with_descr(); + $carpips = find_number_of_needed_carp_interfaces(); + for( $j=0; $j<$carpips; $j++ ) { + $carpip = find_interface_ip("carp" . $j); + $iflabels['carp' . $j] = "CARP{$j} ({$carpip})"; + } + $if = htmlspecialchars($iflabels[$ph1ent['interface']]); + } + else + $if = "WAN"; + + echo $if . "<br>" . $ph1ent['remote-gateway']; + ?> + <?=$spane;?> + </td> + <td class="listr" ondblclick="document.location='vpn_ipsec_phase1.php?id=<?=$i;?>'"> + <?=$spans;?> + <?=$ph1ent['mode'];?> + <?=$spane;?> + </td> + <td class="listr" ondblclick="document.location='vpn_ipsec_phase1.php?id=<?=$i;?>'"> + <?=$spans;?> + <?=$p1_ealgos[$ph1ent['encryption-algorithm']['name']]['name'];?> + <?php + if ($ph1ent['encryption-algorithm']['keylen']) { + if ($ph1ent['encryption-algorithm']['keylen']=="auto") + echo " (auto)"; + else + echo " ({$ph1ent['encryption-algorithm']['keylen']} bits)"; + } + ?> + <?=$spane;?> + </td> + <td class="listr" ondblclick="document.location='vpn_ipsec_phase1.php?id=<?=$i;?>'"> + <?=$spans;?> + <?=$p1_halgos[$ph1ent['hash-algorithm']];?> + <?=$spane;?> + </td> + <td class="listtopic" ondblclick="document.location='vpn_ipsec_phase1.php?id=<?=$i;?>'"> + <?=$spans;?> + <font color="#FFFFFF"> + <?=htmlspecialchars($ph1ent['descr']);?> + </font> + <?=$spane;?> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td> + <a href="vpn_ipsec_phase1.php?p1index=<?=$i;?>"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="edit phase1 entry" width="17" height="17" border="0"> + </a> + </td> + <td> + <a href="vpn_ipsec.php?act=delph1&p1index=<?=$i;?>" onclick="return confirm('Do you really want to delete this phase1 and all associated phase2 entries?')"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete phase1 entry" width="17" height="17" border="0"> + </a> + </td> + </tr> + <tr> + <td> + </td> + <td> + <a href="vpn_ipsec_phase1.php?dup=<?=$i;?>"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="copy phase1 entry" width="17" height="17" border="0"> + </a> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td class="listbg" colspan="5"> + <table width="100%" height="100%"border="0" cellspacing="0" cellpadding="0"> + <tr> + <td class="listhdrr">Local Network</td> + <td class="listhdrr">Remote Network</td> + <td class="listhdrr">P2 Protocol</td> + <td class="listhdrr">P2 Transforms</td> + <td class="listhdrr">P2 Auth Methods</td> + <td class ="list"> + <a href="vpn_ipsec_phase2.php?ikeid=<?=$ph1ent['ikeid'];?>"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add phase2 entry" width="17" height="17" border="0"> + </a> + </td> + </tr> + <?php + $j = 0; + foreach ($a_phase2 as $ph2ent) { + if ($ph2ent['ikeid'] != $ph1ent['ikeid']) { + $j++; + continue; + } + + if (isset( $ph2ent['disabled']) || isset($ph1ent['disabled'])) { + $spans = "<span class=\"gray\">"; + $spane = "</span>"; + } + else + $spans = $spane = ""; + ?> + <tr valign="top"> + <td nowrap class="listr" ondblclick="document.location='vpn_ipsec_phase2.php?id=<?=$i;?>'"> + <?=$spans;?> + <?php echo ipsec_idinfo_to_text($ph2ent['localid']); ?> + <?=$spane;?> + </td> + <td nowrap class="listr" ondblclick="document.location='vpn_ipsec_phase2.php?id=<?=$i;?>'"> + <?=$spans;?> + <?php echo ipsec_idinfo_to_text($ph2ent['remoteid']); ?> + <?=$spane;?> + </td> + <td nowrap class="listr" ondblclick="document.location='vpn_ipsec_phase2.php?id=<?=$i;?>'"> + <?=$spans;?> + <?php echo $p2_protos[$ph2ent['protocol']]; ?> + <?=$spane;?> + </td> + <td nowrap class="listr" ondblclick="document.location='vpn_ipsec_phase2.php?id=<?=$i;?>'"> + <?=$spans;?> + <?php + $k = 0; + foreach ($ph2ent['encryption-algorithm-option'] as $ph2ea) { + if ($k++) + echo ", "; + echo $p2_ealgos[$ph2ea['name']]['name']; + if ($ph2ea['keylen']) { + if ($ph2ea['keylen']=="auto") + echo " (auto)"; + else + echo " ({$ph2ea['keylen']} bits)"; + } + } + ?> + <?=$spane;?> + </td> + <td nowrap class="listr" ondblclick="document.location='vpn_ipsec_phase2.php?id=<?=$i;?>'"> + <?=$spans;?> + <?php + $k = 0; + foreach ($ph2ent['hash-algorithm-option'] as $ph2ha) { + if ($k++) + echo ", "; + echo $p2_halgos[$ph2ha]; + } + ?> + <?=$spane;?> + </td> + <td nowrap class="list"> + <a href="vpn_ipsec_phase2.php?p2index=<?=$j;?>"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="edit phase2 entry" width="17" height="17" border="0"> + </a> + <a href="vpn_ipsec.php?act=delph2&p2index=<?=$j;?>" onclick="return confirm('Do you really want to delete this phase2 entry?')"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete phase2 entry" width="17" height="17" border="0"> + </a> + </td> + </tr> + <?php + $j++; + } + ?> + </table> + </td> + </tr> + <?php + $i++; + } ?> - <?=$spane;?></td> - <td class="listr" ondblclick="document.location='vpn_ipsec_edit.php?id=<?=$i;?>'"><?=$spans;?> - <?=$ipsecent['p1']['mode'];?> - <?=$spane;?></td> - <td class="listr" ondblclick="document.location='vpn_ipsec_edit.php?id=<?=$i;?>'"><?=$spans;?> - <?=$p1_ealgos[$ipsecent['p1']['encryption-algorithm']];?> - <?=$spane;?></td> - <td class="listr" ondblclick="document.location='vpn_ipsec_edit.php?id=<?=$i;?>'"><?=$spans;?> - <?=$p1_halgos[$ipsecent['p1']['hash-algorithm']];?> - <?=$spane;?></td> - <td class="listbg" ondblclick="document.location='vpn_ipsec_edit.php?id=<?=$i;?>'"><?=$spans;?><font color="#FFFFFF"> - <?=htmlspecialchars($ipsecent['descr']);?> - <?=$spane;?></td> - <td valign="middle" nowrap class="list"> - <table border="0" cellspacing="0" cellpadding="1"> - <tr> - <td><a href="vpn_ipsec_edit.php?id=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="edit tunnel" width="17" height="17" border="0"></a></td> - <td><a href="vpn_ipsec.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this tunnel?')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete tunnel" width="17" height="17" border="0"></a></td> - </tr> - <tr> - <td></td> - <td><a href="vpn_ipsec_edit.php?dup=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add a new rule based on this one" width="17" height="17" border="0"></a></td> - </tr> - </table> - </td> - </tr> - <?php $i++; endforeach; ?> - <tr> - <td class="list" colspan="6"></td> - <td class="list"> - <table border="0" cellspacing="0" cellpadding="1"> - <tr> - <td width="17"></td> - <td><a href="vpn_ipsec_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add tunnel" width="17" height="17" border="0"></a></td> - </tr> - </table> - <td> - </tr> - <tr> - <td colspan="4"> - <p><span class="vexpl"><span class="red"><strong>Note:<br> - </strong></span>You can check your IPsec status at <a href="diag_ipsec_sad.php">Status:IPsec</a>.</span></p> - </td> - </tr> - </table> - </div> - </td> + <tr> + <td class="list" colspan="5"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td width="17"></td> + <td> + <a href="vpn_ipsec_phase1.php"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add phase1 entry" width="17" height="17" border="0"> + </a> + </td> + </tr> + </table> + <td> + </tr> + <tr> + <td colspan="4"> + <p> + <span class="vexpl"> + <span class="red"> + <strong>Note:<br></strong> + </span> + You can check your IPsec status at <a href="diag_ipsec.php">Status:IPsec</a>. + </span> + </p> + </td> + </tr> + </table> + </div> + </td> </tr> </table> </form> diff --git a/usr/local/www/vpn_ipsec_ca.php b/usr/local/www/vpn_ipsec_ca.php index 17195ae..b94c66d 100755 --- a/usr/local/www/vpn_ipsec_ca.php +++ b/usr/local/www/vpn_ipsec_ca.php @@ -51,22 +51,22 @@ include("head.inc"); ?> - <body link="#0000CC" vlink="#0000CC" alink="#0000CC"> <?php include("fbegin.inc"); ?> <form action="vpn_ipsec.php" method="post"> -<?php if ($savemsg) print_info_box($savemsg); ?> -<?php if (file_exists($d_ipsecconfdirty_path)): ?><p> -<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> -<?php endif; ?> +<?php + if ($savemsg) + print_info_box($savemsg); + if ($pconfig['enable'] && file_exists($d_ipsecconfdirty_path)) + print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect."); +?> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td> <?php $tab_array = array(); $tab_array[0] = array("Tunnels", false, "vpn_ipsec.php"); - $tab_array[1] = array("Mobile clients", false, "vpn_ipsec_mobile.php"); - $tab_array[2] = array("Pre-shared keys", false, "vpn_ipsec_keys.php"); - $tab_array[3] = array("CAs", true, "vpn_ipsec_ca.php"); +// $tab_array[1] = array("Mobile clients", false, "vpn_ipsec_mobile.php"); + $tab_array[2] = array("CAs", true, "vpn_ipsec_ca.php"); display_top_tabs($tab_array); ?> </td></tr> diff --git a/usr/local/www/vpn_ipsec_edit.php b/usr/local/www/vpn_ipsec_edit.php deleted file mode 100755 index 74de623..0000000 --- a/usr/local/www/vpn_ipsec_edit.php +++ /dev/null @@ -1,662 +0,0 @@ -<?php -/* - vpn_ipsec_edit.php - part of m0n0wall (http://m0n0.ch/wall) - - Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>. - All rights reserved. - - 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. -*/ - -require("guiconfig.inc"); - -if (!is_array($config['ipsec']['tunnel'])) { - $config['ipsec']['tunnel'] = array(); -} -$a_ipsec = &$config['ipsec']['tunnel']; - -if($config['interfaces']['lan']) - $specialsrcdst = explode(" ", "lan"); - -$id = $_GET['id']; -if (isset($_POST['id'])) - $id = $_POST['id']; - -if (isset($_GET['dup'])) { - $id = $_GET['dup']; -} - -if (isset($id) && $a_ipsec[$id]) { - $pconfig['disabled'] = isset($a_ipsec[$id]['disabled']); - $pconfig['auto'] = isset($a_ipsec[$id]['auto']); - - if (!isset($a_ipsec[$id]['local-subnet'])) { - if($config['interfaces']['lan']) - $pconfig['localnet'] = "lan"; - } else { - if($config['interfaces']['lan']) - address_to_pconfig_vpn($a_ipsec[$id]['local-subnet'], $pconfig['localnet'], $pconfig['localnetmask']); - } - - if ($a_ipsec[$id]['interface']) - $pconfig['interface'] = $a_ipsec[$id]['interface']; - else - $pconfig['interface'] = "wan"; - - list($pconfig['remotenet'],$pconfig['remotebits']) = explode("/", $a_ipsec[$id]['remote-subnet']); - $pconfig['remotegw'] = $a_ipsec[$id]['remote-gateway']; - $pconfig['p1mode'] = $a_ipsec[$id]['p1']['mode']; - - if (isset($a_ipsec[$id]['p1']['myident']['myaddress'])) - $pconfig['p1myidentt'] = 'myaddress'; - else if (isset($a_ipsec[$id]['p1']['myident']['address'])) { - $pconfig['p1myidentt'] = 'address'; - $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['address']; - } else if (isset($a_ipsec[$id]['p1']['myident']['fqdn'])) { - $pconfig['p1myidentt'] = 'fqdn'; - $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['fqdn']; - } else if (isset($a_ipsec[$id]['p1']['myident']['ufqdn'])) { - $pconfig['p1myidentt'] = 'user_fqdn'; - $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['ufqdn']; - } else if (isset($a_ipsec[$id]['p1']['myident']['asn1dn'])) { - $pconfig['p1myidentt'] = 'asn1dn'; - $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['asn1dn']; - } else if (isset($a_ipsec[$id]['p1']['myident']['dyn_dns'])) { - $pconfig['p1myidentt'] = 'dyn_dns'; - $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['dyn_dns']; - } - - $pconfig['p1ealgo'] = $a_ipsec[$id]['p1']['encryption-algorithm']; - $pconfig['p1halgo'] = $a_ipsec[$id]['p1']['hash-algorithm']; - $pconfig['p1dhgroup'] = $a_ipsec[$id]['p1']['dhgroup']; - $pconfig['p1lifetime'] = $a_ipsec[$id]['p1']['lifetime']; - $pconfig['p1authentication_method'] = $a_ipsec[$id]['p1']['authentication_method']; - $pconfig['p1pskey'] = $a_ipsec[$id]['p1']['pre-shared-key']; - $pconfig['p1cert'] = base64_decode($a_ipsec[$id]['p1']['cert']); - $pconfig['p1peercert'] = base64_decode($a_ipsec[$id]['p1']['peercert']); - $pconfig['p1privatekey'] = base64_decode($a_ipsec[$id]['p1']['private-key']); - $pconfig['p2proto'] = $a_ipsec[$id]['p2']['protocol']; - $pconfig['p2ealgos'] = $a_ipsec[$id]['p2']['encryption-algorithm-option']; - $pconfig['p2halgos'] = $a_ipsec[$id]['p2']['hash-algorithm-option']; - $pconfig['p2pfsgroup'] = $a_ipsec[$id]['p2']['pfsgroup']; - $pconfig['p2lifetime'] = $a_ipsec[$id]['p2']['lifetime']; - $pconfig['descr'] = $a_ipsec[$id]['descr']; - $pconfig['pinghost'] = $a_ipsec[$id]['pinghost']; - -} else { - /* defaults */ - $pconfig['interface'] = "wan"; - if($config['interfaces']['lan']) - $pconfig['localnet'] = "lan"; - $pconfig['p1mode'] = "aggressive"; - $pconfig['p1myidentt'] = "myaddress"; - $pconfig['p1authentication_method'] = "pre_shared_key"; - $pconfig['p1ealgo'] = "3des"; - $pconfig['p1halgo'] = "sha1"; - $pconfig['p1dhgroup'] = "2"; - $pconfig['p2proto'] = "esp"; - $pconfig['p2ealgos'] = explode(",", "3des,blowfish,cast128,rijndael,rijndael 256"); - $pconfig['p2halgos'] = explode(",", "hmac_sha1,hmac_md5"); - $pconfig['p2pfsgroup'] = "0"; - $pconfig['remotebits'] = 32; -} - -if (isset($_GET['dup'])) - unset($id); - -if ($_POST) { - if (is_specialnet($_POST['localnettype'])) { - $_POST['localnet'] = $_POST['localnettype']; - $_POST['localnetmask'] = 0; - } else if ($_POST['localnettype'] == "single") { - $_POST['localnetmask'] = 32; - } - - unset($input_errors); - $pconfig = $_POST; - - /* input validation */ - if ($_POST['p1authentication_method'] == "pre_shared_key") { - $reqdfields = explode(" ", "localnet remotenet remotebits remotegw p1pskey p2ealgos p2halgos"); - $reqdfieldsn = explode(",", "Local network,Remote network,Remote network bits,Remote gateway,Pre-Shared Key,P2 Encryption Algorithms,P2 Hash Algorithms"); - } - else { - $reqdfields = explode(" ", "localnet remotenet remotebits remotegw p2ealgos p2halgos"); - $reqdfieldsn = explode(",", "Local network,Remote network,Remote network bits,Remote gateway,P2 Encryption Algorithms,P2 Hash Algorithms"); - if (!strstr($_POST['p1cert'], "BEGIN CERTIFICATE") || !strstr($_POST['p1cert'], "END CERTIFICATE")) - $input_errors[] = "This certificate does not appear to be valid."; - if (!strstr($_POST['p1privatekey'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['p1privatekey'], "END RSA PRIVATE KEY")) - $input_errors[] = "This key does not appear to be valid."; - if ($_POST['p1peercert']!="" && (!strstr($_POST['p1peercert'], "BEGIN CERTIFICATE") || !strstr($_POST['p1peercert'], "END CERTIFICATE"))) - $input_errors[] = "This peer certificate does not appear to be valid."; - } - - do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); - - if (!is_specialnet($_POST['localnettype'])) { - if (($_POST['localnet'] && !is_ipaddr($_POST['localnet']))) { - $input_errors[] = "A valid local network IP address must be specified."; - } - if (($_POST['localnetmask'] && !is_numeric($_POST['localnetmask']))) { - $input_errors[] = "A valid local network bit count must be specified."; - } - } - if (($_POST['p1lifetime'] && !is_numeric($_POST['p1lifetime']))) { - $input_errors[] = "The P1 lifetime must be an integer."; - } - if (($_POST['p2lifetime'] && !is_numeric($_POST['p2lifetime']))) { - $input_errors[] = "The P2 lifetime must be an integer."; - } - if ($_POST['remotebits'] && (!is_numeric($_POST['remotebits']) || ($_POST['remotebits'] < 0) || ($_POST['remotebits'] > 32))) { - if(!$_POST['remotebits'] == "0.0.0.0") - $input_errors[] = "The remote network bits are invalid."; - } - if (($_POST['remotenet'] && !is_ipaddr($_POST['remotenet'])) or $_POST['remotenet'] == "0.0.0.0") { - /* allow 0.0.0.0 remote net usage */ - if($_POST['remotenet'] <> "0.0.0.0") - $input_errors[] = "A valid remote network address must be specified."; - } - if (($_POST['remotenet'] && is_ipaddr($_POST['remotenet']) && !isset($_POST['disabled']) )) { - $t = 0; - foreach($a_ipsec as $tunnel) { - if($id <> $t) { - $tremotecidr = $pconfig['remotenet'] ."/". $pconfig['remotebits']; - if(($tunnel['remote-subnet'] == $tremotecidr) && !isset($tunnel['disabled'])) { - $input_errors[] = "The remote network \"$tremotecidr\" is already used by tunnel \"${tunnel['descr']}\"."; - } - } - $t++; - } - } - if (($_POST['remotegw'] && !is_ipaddr($_POST['remotegw']) && !is_domain($_POST['remotegw']))) - $input_errors[] = "A valid remote gateway address or host name must be specified."; - if (($_POST['remotegw'] && is_ipaddr($_POST['remotegw']) && !isset($_POST['disabled']) )) { - $t = 0; - foreach($a_ipsec as $tunnel) { - if($id <> $t) { - $tremotegw = $pconfig['remotegw']; - if(($tunnel['remote-gateway'] == $tremotegw) && !isset($tunnel['disabled'])) { - $input_errors[] = "The remote gateway \"$tremotegw\" is already used by tunnel \"${tunnel['descr']}\"."; - } - } - $t++; - } - } - if ((($_POST['p1myidentt'] == "address") && !is_ipaddr($_POST['p1myident']))) { - $input_errors[] = "A valid IP address for 'My identifier' must be specified."; - } - if ((($_POST['p1myidentt'] == "fqdn") && !is_domain($_POST['p1myident']))) { - $input_errors[] = "A valid domain name for 'My identifier' must be specified."; - } - if ($_POST['p1myidentt'] == "user_fqdn") { - $ufqdn = explode("@",$_POST['p1myident']); - if (is_domain($ufqdn[1]) == false) - $input_errors[] = "A valid User FQDN in the form of user@my.domain.com for 'My identifier' must be specified."; - } - if ($_POST['p1myidentt'] == "dyn_dns") { - if (is_domain($_POST['p1myidentt']) == false) - $input_errors[] = "A valid Dynamic DNS address for 'My identifier' must be specified."; - } - - if($_POST['p1myidentt'] == "fqdn" and $_POST['p1myident'] == "") - $input_errors[] = gettext("Please enter a domain name for 'My Identifier'"); - - if($_POST['p1myidentt'] == "dyn_dns" and $_POST['p1myident'] == "") - $input_errors[] = gettext("Please enter a domain name for 'My Identifier'"); - - if($_POST['p1myidentt'] == "address" and $_POST['p1myident'] == "") - $input_errors[] = gettext("Please enter a domain name for 'My Identifier'"); - - if($_POST['p1myidentt'] == "user_fqdn" and $_POST['p1myident'] == "") - $input_errors[] = gettext("Please enter a domain name for 'My Identifier'"); - - if ($_POST['p1myidentt'] == "myaddress") - $_POST['p1myident'] = ""; - - if (!$input_errors) { - $ipsecent['disabled'] = $_POST['disabled'] ? true : false; - //$ipsecent['auto'] = $_POST['auto'] ? true : false; - $ipsecent['interface'] = $pconfig['interface']; - pconfig_to_address($ipsecent['local-subnet'], $_POST['localnet'], $_POST['localnetmask']); - $ipsecent['remote-subnet'] = $_POST['remotenet'] . "/" . $_POST['remotebits']; - /* if the remote gateway changed and the interface is not WAN then remove route */ - /* the vpn_ipsec_configure() handles adding the route */ - if($_POST['interface'] <> "wan") { - if($ipsecent['remote-gateway'] <> $_POST['remotegw']) { - mwexec("/sbin/route delete -host {$ipsecent['remote-gateway']}"); - } - } - $ipsecent['remote-gateway'] = $_POST['remotegw']; - $ipsecent['p1']['mode'] = $_POST['p1mode']; - - $ipsecent['p1']['myident'] = array(); - switch ($_POST['p1myidentt']) { - case 'myaddress': - $ipsecent['p1']['myident']['myaddress'] = true; - break; - case 'address': - $ipsecent['p1']['myident']['address'] = $_POST['p1myident']; - break; - case 'fqdn': - $ipsecent['p1']['myident']['fqdn'] = $_POST['p1myident']; - break; - case 'user_fqdn': - $ipsecent['p1']['myident']['ufqdn'] = $_POST['p1myident']; - break; - case 'asn1dn': - $ipsecent['p1']['myident']['asn1dn'] = $_POST['p1myident']; - break; - case 'dyn_dns': - $ipsecent['p1']['myident']['dyn_dns'] = $_POST['p1myident']; - break; - } - - $ipsecent['p1']['encryption-algorithm'] = $_POST['p1ealgo']; - $ipsecent['p1']['hash-algorithm'] = $_POST['p1halgo']; - $ipsecent['p1']['dhgroup'] = $_POST['p1dhgroup']; - $ipsecent['p1']['lifetime'] = $_POST['p1lifetime']; - $ipsecent['p1']['pre-shared-key'] = $_POST['p1pskey']; - $ipsecent['p1']['private-key'] = base64_encode($_POST['p1privatekey']); - $ipsecent['p1']['cert'] = base64_encode($_POST['p1cert']); - $ipsecent['p1']['peercert'] = base64_encode($_POST['p1peercert']); - $ipsecent['p1']['authentication_method'] = $_POST['p1authentication_method']; - $ipsecent['p2']['protocol'] = $_POST['p2proto']; - $ipsecent['p2']['encryption-algorithm-option'] = $_POST['p2ealgos']; - $ipsecent['p2']['hash-algorithm-option'] = $_POST['p2halgos']; - $ipsecent['p2']['pfsgroup'] = $_POST['p2pfsgroup']; - $ipsecent['p2']['lifetime'] = $_POST['p2lifetime']; - $ipsecent['descr'] = $_POST['descr']; - $ipsecent['pinghost'] = $_POST['pinghost']; - - if (isset($id) && $a_ipsec[$id]) - $a_ipsec[$id] = $ipsecent; - else - $a_ipsec[] = $ipsecent; - - write_config(); - touch($d_ipsecconfdirty_path); - - header("Location: vpn_ipsec.php"); - exit; - } -} - -$pgtitle = array("VPN","IPsec","Edit tunnel"); -include("head.inc"); - -?> - -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> -<?php include("fbegin.inc"); ?> -<script language="JavaScript"> -<!-- -function typesel_change() { - switch (document.iform.localnettype.selectedIndex) { - case 0: /* single */ - document.iform.localnet.disabled = 0; - document.iform.localnetmask.value = ""; - document.iform.localnetmask.disabled = 1; - break; - case 1: /* network */ - document.iform.localnet.disabled = 0; - document.iform.localnetmask.disabled = 0; - break; - default: - document.iform.localnet.value = ""; - document.iform.localnet.disabled = 1; - document.iform.localnetmask.value = ""; - document.iform.localnetmask.disabled = 1; - break; - } -} -function methodsel_change() { - switch (document.iform.p1authentication_method.selectedIndex) { - case 1: /* rsa */ - document.iform.p1pskey.disabled = 1; - document.iform.p1privatekey.disabled = 0; - document.iform.p1cert.disabled = 0; - document.iform.p1peercert.disabled = 0; - break; - default: /* pre-shared */ - document.iform.p1pskey.disabled = 0; - document.iform.p1privatekey.disabled = 1; - document.iform.p1cert.disabled = 1; - document.iform.p1peercert.disabled = 1; - break; - } -} -//--> -</script> -<?php if ($input_errors) print_input_errors($input_errors); ?> - <form action="vpn_ipsec_edit.php" method="post" name="iform" id="iform"> - <table width="100%" border="0" cellpadding="6" cellspacing="0"> - <tr> - <td width="22%" valign="top" class="vncellreq">Mode</td> - <td width="78%" class="vtable"> Tunnel</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Disabled</td> - <td width="78%" class="vtable"> - <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>> - <strong>Disable this tunnel</strong><br> - <span class="vexpl">Set this option to disable this tunnel without - removing it from the list.</span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Interface</td> - <td width="78%" class="vtable"><select name="interface" class="formselect"> - <?php - $interfaces = get_configured_interface_with_descr(); - $carpips = find_number_of_needed_carp_interfaces(); - for($i=0; $i<$carpips; $i++) { - $carpip = find_interface_ip("carp" . $i); - $interfaces['carp' . $i] = "CARP{$i} ({$carpip})"; - } - foreach ($interfaces as $iface => $ifacename): ?> - <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>> - <?=htmlspecialchars($ifacename);?> - </option> - <?php endforeach; ?> - </select> <br> - <span class="vexpl">Select the interface for the local endpoint of this tunnel.</span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Local subnet</td> - <td width="78%" class="vtable"> - <table border="0" cellspacing="0" cellpadding="0"> - <tr> - <td>Type: </td> - <td></td> - <td><select name="localnettype" class="formselect" onChange="typesel_change()"> - <?php $sel = is_specialnet($pconfig['localnet']); ?> - <option value="single" <?php if (($pconfig['localnetmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>> - Single host</option> - <option value="network" <?php if (!$sel) echo "selected"; ?>> - Network</option> - <?php if($config['interfaces']['lan']): ?> - <option value="lan" <?php if ($pconfig['localnet'] == "lan") { echo "selected"; } ?>> - LAN subnet</option> - <?php endif; ?> - </select></td> - </tr> - <tr> - <td>Address: </td> - <td><?=$mandfldhtmlspc;?></td> - <td><input name="localnet" type="text" class="formfld unknown" id="localnet" size="20" value="<?php if (!is_specialnet($pconfig['localnet'])) echo htmlspecialchars($pconfig['localnet']);?>"> - / - <select name="localnetmask" class="formselect" id="localnetmask"> - <?php for ($i = 31; $i >= 0; $i--): ?> - <option value="<?=$i;?>" <?php if ($i == $pconfig['localnetmask']) echo "selected"; ?>> - <?=$i;?> - </option> - <?php endfor; ?> - </select> </td> - </tr> - </table></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Remote subnet</td> - <td width="78%" class="vtable"> - <?=$mandfldhtml;?><input name="remotenet" type="text" class="formfld unknown" id="remotenet" size="20" value="<?=$pconfig['remotenet'];?>"> - / - <select name="remotebits" class="formselect" id="remotebits"> - <?php for ($i = 32; $i >= 0; $i--): ?> - <option value="<?=$i;?>" <?php if ($i == $pconfig['remotebits']) echo "selected"; ?>> - <?=$i;?> - </option> - <?php endfor; ?> - </select></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Remote gateway</td> - <td width="78%" class="vtable"> - <?=$mandfldhtml;?><input name="remotegw" type="text" class="formfld unknown" id="remotegw" size="20" value="<?=$pconfig['remotegw'];?>"> - <br> - Enter the public IP address or host name of the remote gateway</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell">Description</td> - <td width="78%" class="vtable"> - <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> - <br> <span class="vexpl">You may enter a description here - for your reference (not parsed).</span></td> - </tr> - <tr> - <td colspan="2" class="list" height="12"></td> - </tr> - <tr> - <td colspan="2" valign="top" class="listtopic">Phase 1 proposal - (Authentication)</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Negotiation mode</td> - <td width="78%" class="vtable"> - <select name="p1mode" class="formfld unknown"> - <?php $modes = explode(" ", "main aggressive"); foreach ($modes as $mode): ?> - <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1mode']) echo "selected"; ?>> - <?=htmlspecialchars($mode);?> - </option> - <?php endforeach; ?> - </select> <br> <span class="vexpl">Aggressive is faster, but - less secure.</span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">My identifier</td> - <td width="78%" class="vtable"> - <select name="p1myidentt" class="formselect"> - <?php foreach ($my_identifier_list as $mode => $modename): ?> - <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1myidentt']) echo "selected"; ?>> - <?=htmlspecialchars($modename);?> - </option> - <?php endforeach; ?> - </select> <input name="p1myident" type="text" class="formfld unknown" id="p1myident" size="30" value="<?=$pconfig['p1myident'];?>"> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Encryption algorithm</td> - <td width="78%" class="vtable"> - <select name="p1ealgo" class="formselect"> - <?php foreach ($p1_ealgos as $algo => $algoname): ?> - <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1ealgo']) echo "selected"; ?>> - <?=htmlspecialchars($algoname);?> - </option> - <?php endforeach; ?> - </select> <br> <span class="vexpl">Must match the setting - chosen on the remote side. </span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Hash algorithm</td> - <td width="78%" class="vtable"> - <select name="p1halgo" class="formselect"> - <?php foreach ($p1_halgos as $algo => $algoname): ?> - <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1halgo']) echo "selected"; ?>> - <?=htmlspecialchars($algoname);?> - </option> - <?php endforeach; ?> - </select> <br> <span class="vexpl">Must match the setting - chosen on the remote side. </span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">DH key group</td> - <td width="78%" class="vtable"> - <select name="p1dhgroup" class="formselect"> - <?php $keygroups = explode(" ", "1 2 5"); foreach ($keygroups as $keygroup): ?> - <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p1dhgroup']) echo "selected"; ?>> - <?=htmlspecialchars($keygroup);?> - </option> - <?php endforeach; ?> - </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024 - bit, 5 = 1536 bit</em><br> - Must match the setting chosen on the remote side. </span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell">Lifetime</td> - <td width="78%" class="vtable"> - <input name="p1lifetime" type="text" class="formfld unknown" id="p1lifetime" size="20" value="<?=$pconfig['p1lifetime'];?>"> - seconds</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Authentication method</td> - <td width="78%" class="vtable"> - <select name="p1authentication_method" class="formselect" onChange="methodsel_change()"> - <?php foreach ($p1_authentication_methods as $method => $methodname): ?> - <option value="<?=$method;?>" <?php if ($method == $pconfig['p1authentication_method']) echo "selected"; ?>> - <?=htmlspecialchars($methodname);?> - </option> - <?php endforeach; ?> - </select> <br> <span class="vexpl">Must match the setting - chosen on the remote side.</span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Pre-Shared Key</td> - <td width="78%" class="vtable"> - <?=$mandfldhtml;?><input name="p1pskey" type="text" class="formfld unknown" id="p1pskey" size="40" value="<?=htmlspecialchars($pconfig['p1pskey']);?>"> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Certificate</td> - <td width="78%" class="vtable"> - <textarea name="p1cert" cols="65" rows="7" id="p1cert" class="formpre"><?=htmlspecialchars($pconfig['p1cert']);?></textarea> - <br> - Paste a certificate in X.509 PEM format here.</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Key</td> - <td width="78%" class="vtable"> - <textarea name="p1privatekey" cols="65" rows="7" id="p1privatekey" class="formpre"><?=htmlspecialchars($pconfig['p1privatekey']);?></textarea> - <br> - Paste an RSA private key in PEM format here.</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell">Peer certificate</td> - <td width="78%" class="vtable"> - <textarea name="p1peercert" cols="65" rows="7" id="p1peercert" class="formpre"><?=htmlspecialchars($pconfig['p1peercert']);?></textarea> - <br> - Paste the peer X.509 certificate in PEM format here.<br> - Leave this blank if you want to use a CA certificate for identity validation.</td> - </tr> - <tr> - <td colspan="2" class="list" height="12"></td> - </tr> - <tr> - <td colspan="2" valign="top" class="listtopic">Phase 2 proposal - (SA/Key Exchange)</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Protocol</td> - <td width="78%" class="vtable"> - <select name="p2proto" class="formselect"> - <?php foreach ($p2_protos as $proto => $protoname): ?> - <option value="<?=$proto;?>" <?php if ($proto == $pconfig['p2proto']) echo "selected"; ?>> - <?=htmlspecialchars($protoname);?> - </option> - <?php endforeach; ?> - </select> <br> <span class="vexpl">ESP is encryption, AH is - authentication only </span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Encryption algorithms</td> - <td width="78%" class="vtable"> - <?php foreach ($p2_ealgos as $algo => $algoname): ?> - <input type="checkbox" name="p2ealgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2ealgos'])) echo "checked"; ?>> - <?=htmlspecialchars($algoname);?> - <br> - <?php endforeach; ?> - <br> - Hint: use 3DES for best compatibility or if you have a hardware - crypto accelerator card. Blowfish is usually the fastest in - software encryption. </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Hash algorithms</td> - <td width="78%" class="vtable"> - <?php foreach ($p2_halgos as $algo => $algoname): ?> - <input type="checkbox" name="p2halgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2halgos'])) echo "checked"; ?>> - <?=htmlspecialchars($algoname);?> - <br> - <?php endforeach; ?> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">PFS key group</td> - <td width="78%" class="vtable"> - <select name="p2pfsgroup" class="formselect"> - <?php foreach ($p2_pfskeygroups as $keygroup => $keygroupname): ?> - <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p2pfsgroup']) echo "selected"; ?>> - <?=htmlspecialchars($keygroupname);?> - </option> - <?php endforeach; ?> - </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024 - bit, 5 = 1536 bit</em></span></td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell">Lifetime</td> - <td width="78%" class="vtable"> - <input name="p2lifetime" type="text" class="formfld unknown" id="p2lifetime" size="20" value="<?=$pconfig['p2lifetime'];?>"> - seconds</td> - </tr> - <tr> - <td colspan="2" class="list" height="12"></td> - </tr> - <tr> - <td colspan="2" valign="top" class="listtopic">Keep alive</td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell">Automatically ping host</td> - <td width="78%" class="vtable"> - <input name="pinghost" type="text" class="formfld unknown" id="pinghost" size="20" value="<?=$pconfig['pinghost'];?>"> IP address</td> - </tr> - <tr> - <td width="22%" valign="top"> </td> - <td width="78%"> - <input name="Submit" type="submit" class="formbtn" value="Save"> - <?php if (isset($id) && $a_ipsec[$id]): ?> - <input name="id" type="hidden" value="<?=$id;?>"> - <?php endif; ?> - </td> - </tr> - </table> -</form> -<script lannguage="JavaScript"> -<!-- -typesel_change(); -methodsel_change(); -//--> -</script> -<?php include("fend.inc"); ?> - - -<?php - -function address_to_pconfig_vpn($adr, &$padr, &$pmask) { - - if ($adr['network']) - $padr = $adr['network']; - else if ($adr['address']) { - list($padr, $pmask) = explode("/", $adr['address']); - if (is_null($pmask)) - $pmask = 32; - } -} - -?> diff --git a/usr/local/www/vpn_ipsec_keys.php b/usr/local/www/vpn_ipsec_keys.php deleted file mode 100755 index 49112ff..0000000 --- a/usr/local/www/vpn_ipsec_keys.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php -/* - vpn_ipsec_keys.php - part of m0n0wall (http://m0n0.ch/wall) - - Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>. - All rights reserved. - - 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. -*/ - -require("guiconfig.inc"); - -if (!is_array($config['ipsec']['mobilekey'])) { - $config['ipsec']['mobilekey'] = array(); -} -ipsec_mobilekey_sort(); -$a_secret = &$config['ipsec']['mobilekey']; - -if ($_GET['act'] == "del") { - if ($a_secret[$_GET['id']]) { - unset($a_secret[$_GET['id']]); - write_config(); - touch($d_ipsecconfdirty_path); - header("Location: vpn_ipsec_keys.php"); - exit; - } -} - -$pgtitle = array("VPN","IPsec","Keys"); - -include("head.inc"); - -?> - -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> -<?php include("fbegin.inc"); ?> -<form action="vpn_ipsec.php" method="post"> -<?php if ($savemsg) print_info_box($savemsg); ?> -<?php if (file_exists($d_ipsecconfdirty_path)): ?><p> -<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> -<?php endif; ?> -<table width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr><td class="tabnavtbl"> -<?php - $tab_array = array(); - $tab_array[0] = array("Tunnels", false, "vpn_ipsec.php"); - $tab_array[1] = array("Mobile clients", false, "vpn_ipsec_mobile.php"); - $tab_array[2] = array("Pre-shared keys", true, "vpn_ipsec_keys.php"); - $tab_array[3] = array("CAs", false, "vpn_ipsec_ca.php"); - display_top_tabs($tab_array); -?> - </td></tr> - <tr> - <td> - <div id="mainarea"> - <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr> - <td class="listhdrr">Identifier</td> - <td class="listhdr">Pre-shared key</td> - <td class="list"> - <table border="0" cellspacing="0" cellpadding="1"> - <tr> - <td width="20" heigth="17"></td> - <td><a href="vpn_ipsec_keys_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add key" width="17" height="17" border="0"></a></td> - </tr> - </table> - </td> - </tr> - <?php $i = 0; foreach ($a_secret as $secretent): ?> - <tr> - <td class="listlr"> - <?=htmlspecialchars($secretent['ident']);?> - </td> - <td class="listr"> - <?=htmlspecialchars($secretent['pre-shared-key']);?> - </td> - <td class="list" nowrap> <a href="vpn_ipsec_keys_edit.php?id=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="edit key" width="17" height="17" border="0"></a> - <a href="vpn_ipsec_keys.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this pre-shared key?')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete key" width="17" height="17" border="0"></a></td> - </tr> - <?php $i++; endforeach; ?> - <tr> - <td class="list" colspan="2"></td> - <td class="list"> - <table border="0" cellspacing="0" cellpadding="1"> - <tr> - <td width="20" heigth="17"></td> - <td><a href="vpn_ipsec_keys_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add key" width="17" height="17" border="0"></a></td> - </tr> - </table> - </td> - </tr> - </table> - </div> - </td> - </tr> -</table> -</form> -<?php include("fend.inc"); ?> -</body> -</html> diff --git a/usr/local/www/vpn_ipsec_keys_edit.php b/usr/local/www/vpn_ipsec_keys_edit.php deleted file mode 100755 index f612bcc..0000000 --- a/usr/local/www/vpn_ipsec_keys_edit.php +++ /dev/null @@ -1,128 +0,0 @@ -<?php -/* - vpn_ipsec_keys_edit.php - part of m0n0wall (http://m0n0.ch/wall) - - Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>. - All rights reserved. - - 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. -*/ - -require("guiconfig.inc"); - -if (!is_array($config['ipsec']['mobilekey'])) { - $config['ipsec']['mobilekey'] = array(); -} -ipsec_mobilekey_sort(); -$a_secret = &$config['ipsec']['mobilekey']; - -$id = $_GET['id']; -if (isset($_POST['id'])) - $id = $_POST['id']; - -if (isset($id) && $a_secret[$id]) { - $pconfig['ident'] = $a_secret[$id]['ident']; - $pconfig['psk'] = $a_secret[$id]['pre-shared-key']; -} - -if ($_POST) { - - unset($input_errors); - $pconfig = $_POST; - - /* input validation */ - $reqdfields = explode(" ", "ident psk"); - $reqdfieldsn = explode(",", "Identifier,Pre-shared key"); - - do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); - - if (preg_match("/[^a-zA-Z0-9@\.\-]/", $_POST['ident'])) - $input_errors[] = "The identifier contains invalid characters."; - - if (!$input_errors && !(isset($id) && $a_secret[$id])) { - /* make sure there are no dupes */ - foreach ($a_secret as $secretent) { - if ($secretent['ident'] == $_POST['ident']) { - $input_errors[] = "Another entry with the same identifier already exists."; - break; - } - } - } - - if (!$input_errors) { - - if (isset($id) && $a_secret[$id]) - $secretent = $a_secret[$id]; - - $secretent['ident'] = $_POST['ident']; - $secretent['pre-shared-key'] = $_POST['psk']; - - if (isset($id) && $a_secret[$id]) - $a_secret[$id] = $secretent; - else - $a_secret[] = $secretent; - - write_config(); - touch($d_ipsecconfdirty_path); - - header("Location: vpn_ipsec_keys.php"); - exit; - } -} - -$pgtitle = array("VPN","IPsec","Edit pre-shared key"); -include("head.inc"); - -?> - -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> -<?php include("fbegin.inc"); ?> -<?php if ($input_errors) print_input_errors($input_errors); ?> - <form action="vpn_ipsec_keys_edit.php" method="post" name="iform" id="iform"> - <table width="100%" border="0" cellpadding="6" cellspacing="0"> - <tr> - <td valign="top" class="vncellreq">Identifier</td> - <td class="vtable"> - <?=$mandfldhtml;?><input name="ident" type="text" class="formfld" id="ident" size="30" value="<?=$pconfig['ident'];?>"> - <br> -This can be either an IP address, fully qualified domain name or an e-mail address. - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Pre-shared key</td> - <td width="78%" class="vtable"> - <?=$mandfldhtml;?><input name="psk" type="text" class="formfld" id="psk" size="40" value="<?=htmlspecialchars($pconfig['psk']);?>"> - </td> - </tr> - <tr> - <td width="22%" valign="top"> </td> - <td width="78%"> - <input name="Submit" type="submit" class="formbtn" value="Save"> - <?php if (isset($id) && $a_secret[$id]): ?> - <input name="id" type="hidden" value="<?=$id;?>"> - <?php endif; ?> - </td> - </tr> - </table> -</form> -<?php include("fend.inc"); ?> diff --git a/usr/local/www/vpn_ipsec_mobile.php b/usr/local/www/vpn_ipsec_mobile.php index 6a105e3..5a88b66 100755 --- a/usr/local/www/vpn_ipsec_mobile.php +++ b/usr/local/www/vpn_ipsec_mobile.php @@ -197,8 +197,7 @@ function methodsel_change() { $tab_array = array(); $tab_array[0] = array("Tunnels", false, "vpn_ipsec.php"); $tab_array[1] = array("Mobile clients", true, "vpn_ipsec_mobile.php"); - $tab_array[2] = array("Pre-shared keys", false, "vpn_ipsec_keys.php"); - $tab_array[3] = array("CAs", false, "vpn_ipsec_ca.php"); + $tab_array[2] = array("CAs", false, "vpn_ipsec_ca.php"); display_top_tabs($tab_array); ?> </td></tr> diff --git a/usr/local/www/vpn_ipsec_phase1.php b/usr/local/www/vpn_ipsec_phase1.php new file mode 100644 index 0000000..0a21362 --- /dev/null +++ b/usr/local/www/vpn_ipsec_phase1.php @@ -0,0 +1,635 @@ +<?php +/* + vpn_ipsec_phase1.php + part of m0n0wall (http://m0n0.ch/wall) + + Copyright (C) 2008 Shrew Soft Inc + Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>. + All rights reserved. + + 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. +*/ + +require("guiconfig.inc"); + +if (!is_array($config['ipsec']['phase1'])) + $config['ipsec']['phase1'] = array(); + +$a_phase1 = &$config['ipsec']['phase1']; + +if($config['interfaces']['lan']) + $specialsrcdst = explode(" ", "lan"); + +$p1index = $_GET['p1index']; +if (isset($_POST['p1index'])) + $p1index = $_POST['p1index']; + +if (isset($_GET['dup'])) { + $p1index = $_GET['dup']; +} + +if (isset($p1index) && $a_phase1[$p1index]) +{ + $pconfig['ikeid'] = $a_phase1[$p1index]['ikeid']; + $pconfig['disabled'] = isset($a_phase1[$p1index]['disabled']); + + if ($a_phase1[$p1index]['interface']) + $pconfig['interface'] = $a_phase1[$p1index]['interface']; + else + $pconfig['interface'] = "wan"; + + list($pconfig['remotenet'],$pconfig['remotebits']) = explode("/", $a_phase1[$p1index]['remote-subnet']); + $pconfig['remotegw'] = $a_phase1[$p1index]['remote-gateway']; + $pconfig['mode'] = $a_phase1[$p1index]['mode']; + $pconfig['myid_type'] = $a_phase1[$p1index]['myid_type']; + $pconfig['myid_data'] = $a_phase1[$p1index]['myid_data']; + $pconfig['peerid_type'] = $a_phase1[$p1index]['peerid_type']; + $pconfig['peerid_data'] = $a_phase1[$p1index]['peerid_data']; + $pconfig['ealgo'] = $a_phase1[$p1index]['encryption-algorithm']; + $pconfig['halgo'] = $a_phase1[$p1index]['hash-algorithm']; + $pconfig['dhgroup'] = $a_phase1[$p1index]['dhgroup']; + $pconfig['lifetime'] = $a_phase1[$p1index]['lifetime']; + $pconfig['authentication_method'] = $a_phase1[$p1index]['authentication_method']; + $pconfig['pskey'] = $a_phase1[$p1index]['pre-shared-key']; + $pconfig['cert'] = base64_decode($a_phase1[$p1index]['cert']); + $pconfig['peercert'] = base64_decode($a_phase1[$p1index]['peercert']); + $pconfig['privatekey'] = base64_decode($a_phase1[$p1index]['private-key']); + + $pconfig['descr'] = $a_phase1[$p1index]['descr']; + $pconfig['nat_traversal'] = $a_phase1[$p1index]['nat_traversal']; + $pconfig['dpd_enable'] = $a_phase1[$p1index]['dpd_enable']; + $pconfig['dpd_delay'] = $a_phase1[$p1index]['dpd_delay']; + $pconfig['dpd_maxfail'] = $a_phase1[$p1index]['dpd_maxfail']; + $pconfig['pinghost'] = $a_phase1[$p1index]['pinghost']; +} +else +{ + /* defaults */ + $pconfig['interface'] = "wan"; + if($config['interfaces']['lan']) + $pconfig['localnet'] = "lan"; + $pconfig['mode'] = "aggressive"; + $pconfig['myid_type'] = "myaddress"; + $pconfig['peerid_type'] = "peeraddress"; + $pconfig['authentication_method'] = "pre_shared_key"; + $pconfig['ealgo'] = array( name => "3des" ); + $pconfig['halgo'] = "sha1"; + $pconfig['dhgroup'] = "2"; + $pconfig['lifetime'] = "28800"; + $pconfig['nat_traversal'] = "on"; + $pconfig['dpd_enable'] = 1; + $pconfig['dpd_delay'] = 10; + $pconfig['dpd_maxfail'] = 5; +} + +if (isset($_GET['dup'])) + unset($p1index); + +if ($_POST) { + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + if ($_POST['authentication_method'] == "pre_shared_key") { + $reqdfields = explode(" ", "remotegw pskey"); + $reqdfieldsn = explode(",", "Remote gateway,Pre-Shared Key"); + } else { + $reqdfields = explode(" ", "remotegw"); + $reqdfieldsn = explode(",", "Remote gateway"); + if (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE")) + $input_errors[] = "This certificate does not appear to be valid."; + if (!strstr($_POST['privatekey'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['privatekey'], "END RSA PRIVATE KEY")) + $input_errors[] = "This key does not appear to be valid."; + if ($_POST['peercert']!="" && (!strstr($_POST['peercert'], "BEGIN CERTIFICATE") || !strstr($_POST['peercert'], "END CERTIFICATE"))) + $input_errors[] = "This peer certificate does not appear to be valid."; + } + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if (($_POST['lifetime'] && !is_numeric($_POST['lifetime']))) + $input_errors[] = "The P1 lifetime must be an integer."; + + if (($_POST['remotegw'] && !is_ipaddr($_POST['remotegw']) && !is_domain($_POST['remotegw']))) + $input_errors[] = "A valid remote gateway address or host name must be specified."; + + if (($_POST['remotegw'] && is_ipaddr($_POST['remotegw']) && !isset($_POST['disabled']) )) { + $t = 0; + foreach ($a_phase1 as $ph1tmp) { + if ($p1index <> $t) { + $tremotegw = $pconfig['remotegw']; + if (($ph1tmp['remote-gateway'] == $tremotegw) && !isset($ph1tmp['disabled'])) { + $input_errors[] = "The remote gateway \"$tremotegw\" is already used by phase1 \"${ph1tmp['descr']}\"."; + } + } + $t++; + } + } + + /* My identity */ + + if ($_POST['myid_type'] == "myaddress") + $_POST['myid_data'] = ""; + + if ($_POST['myid_type'] == "address" and $_POST['myid_data'] == "") + $input_errors[] = gettext("Please enter an address for 'My Identifier'"); + + if ($_POST['myid_type'] == "keyid tag" and $_POST['myid_data'] == "") + $input_errors[] = gettext("Please enter a keyid tag for 'My Identifier'"); + + if ($_POST['myid_type'] == "fqdn" and $_POST['myid_data'] == "") + $input_errors[] = gettext("Please enter a fully qualified domain name for 'My Identifier'"); + + if ($_POST['myid_type'] == "user_fqdn" and $_POST['myid_data'] == "") + $input_errors[] = gettext("Please enter a user and fully qualified domain name for 'My Identifier'"); + + if ($_POST['myid_type'] == "dyn_dns" and $_POST['myid_data'] == "") + $input_errors[] = gettext("Please enter a dynamic domain name for 'My Identifier'"); + + if ((($_POST['myid_type'] == "address") && !is_ipaddr($_POST['myid_data']))) + $input_errors[] = "A valid IP address for 'My identifier' must be specified."; + + if ((($_POST['myid_type'] == "fqdn") && !is_domain($_POST['myid_data']))) + $input_errors[] = "A valid domain name for 'My identifier' must be specified."; + + if ($_POST['myid_type'] == "fqdn") + if (is_domain($_POST['myid_data']) == false) + $input_errors[] = "A valid FQDN for 'My identifier' must be specified."; + + if ($_POST['myid_type'] == "user_fqdn") { + $user_fqdn = explode("@",$_POST['myid_data']); + if (is_domain($user_fqdn[1]) == false) + $input_errors[] = "A valid User FQDN in the form of user@my.domain.com for 'My identifier' must be specified."; + } + + if ($_POST['myid_type'] == "dyn_dns") + if (is_domain($_POST['myid_data']) == false) + $input_errors[] = "A valid Dynamic DNS address for 'My identifier' must be specified."; + + /* Peer identity */ + + if ($_POST['peerid_type'] == "address" and $_POST['peerid_data'] == "") + $input_errors[] = gettext("Please enter an address for 'Peer Identifier'"); + + if ($_POST['peerid_type'] == "keyid tag" and $_POST['peerid_data'] == "") + $input_errors[] = gettext("Please enter a keyid tag for 'Peer Identifier'"); + + if ($_POST['peerid_type'] == "fqdn" and $_POST['peerid_data'] == "") + $input_errors[] = gettext("Please enter a fully qualified domain name for 'Peer Identifier'"); + + if ($_POST['peerid_type'] == "user_fqdn" and $_POST['peerid_data'] == "") + $input_errors[] = gettext("Please enter a user and fully qualified domain name for 'Peer Identifier'"); + + if ((($_POST['peerid_type'] == "address") && !is_ipaddr($_POST['peerid_data']))) + $input_errors[] = "A valid IP address for 'Peer identifier' must be specified."; + + if ((($_POST['peerid_type'] == "fqdn") && !is_domain($_POST['peerid_data']))) + $input_errors[] = "A valid domain name for 'Peer identifier' must be specified."; + + if ($_POST['peerid_type'] == "fqdn") + if (is_domain($_POST['peerid_data']) == false) + $input_errors[] = "A valid FQDN for 'Peer identifier' must be specified."; + + if ($_POST['peerid_type'] == "user_fqdn") { + $user_fqdn = explode("@",$_POST['peerid_data']); + if (is_domain($user_fqdn[1]) == false) + $input_errors[] = "A valid User FQDN in the form of user@my.domain.com for 'Peer identifier' must be specified."; + } + + if ($_POST['dpd_enable']) { + if (!is_numeric($_POST['dpd_delay'])) + $input_errors[] = "A numeric value must be specified for DPD delay."; + + if (!is_numeric($_POST['dpd_maxfail'])) + $input_errors[] = "A numeric value must be specified for DPD retries."; + } + + /* build our encryption algorithms array */ + $pconfig['ealgo'] = array(); + $pconfig['ealgo']['name'] = $_POST['ealgo']; + if($_POST['ealgo_keylen']) + $pconfig['ealgo']['keylen'] = $_POST['ealgo_keylen']; + + if (!$input_errors) { + $ph1ent['ikeid'] = $_POST['ikeid']; + $ph1ent['disabled'] = $_POST['disabled'] ? true : false; + $ph1ent['interface'] = $pconfig['interface']; + /* if the remote gateway changed and the interface is not WAN then remove route */ + /* the vpn_ipsec_configure() handles adding the route */ + if ($_POST['interface'] <> "wan") { + if($ph1ent['remote-gateway'] <> $_POST['remotegw']) { + mwexec("/sbin/route delete -host {$ph1ent['remote-gateway']}"); + } + } + $ph1ent['remote-gateway'] = $_POST['remotegw']; + $ph1ent['mode'] = $_POST['mode']; + + $ph1ent['myid_type'] = $_POST['myid_type']; + $ph1ent['myid_data'] = $_POST['myid_data']; + $ph1ent['peerid_type'] = $_POST['peerid_type']; + $ph1ent['peerid_data'] = $_POST['peerid_data']; + + $ph1ent['encryption-algorithm'] = $pconfig['ealgo']; + $ph1ent['hash-algorithm'] = $_POST['halgo']; + $ph1ent['dhgroup'] = $_POST['dhgroup']; + $ph1ent['lifetime'] = $_POST['lifetime']; + $ph1ent['pre-shared-key'] = $_POST['pskey']; + $ph1ent['private-key'] = base64_encode($_POST['privatekey']); + $ph1ent['cert'] = base64_encode($_POST['cert']); + $ph1ent['peercert'] = base64_encode($_POST['peercert']); + $ph1ent['authentication_method'] = $_POST['authentication_method']; + + $ph1ent['descr'] = $_POST['descr']; + $ph1ent['nat_traversal'] = $_POST['nat_traversal']; + $ph1ent['dpd_enable'] = $_POST['dpd_enable']; + $ph1ent['dpd_delay'] = $_POST['dpd_delay']; + $ph1ent['dpd_maxfail'] = $_POST['dpd_maxfail']; + $ph1ent['pinghost'] = $_POST['pinghost']; + + /* generate unique phase1 ikeid */ + if ($ph1ent['ikeid'] == 0) { + while (true) { + $ph1ent['ikeid']++; + foreach ($a_phase1 as $ph1tmp) + if( $ph1ent['ikeid'] == $ph1tmp['ikeid'] ) + break; + + if( $ph1ent['ikeid'] != $ph1tmp['ikeid'] ) + break; + } + } + + if (isset($p1index) && $a_phase1[$p1index]) + $a_phase1[$p1index] = $ph1ent; + else + $a_phase1[] = $ph1ent; + + write_config(); + touch($d_ipsecconfdirty_path); + + header("Location: vpn_ipsec.php"); + exit; + } +} + +$pgtitle = array("VPN","IPsec","Edit Phase 1"); +include("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<script language="JavaScript"> +<!-- +function methodsel_change() { + switch (document.iform.authentication_method.selectedIndex) { + case 1: /* rsa */ + document.iform.pskey.disabled = 1; + document.iform.privatekey.disabled = 0; + document.iform.cert.disabled = 0; + document.iform.peercert.disabled = 0; + break; + default: /* pre-shared */ + document.iform.pskey.disabled = 0; + document.iform.privatekey.disabled = 1; + document.iform.cert.disabled = 1; + document.iform.peercert.disabled = 1; + break; + } +} + +/* PHP generated java script for variable length keys */ +function ealgosel_change(bits) { + switch (document.iform.ealgo.selectedIndex) { +<?php + $i = 0; + foreach ($p1_ealgos as $algo => $algodata) { + if (is_array($algodata['keysel'])) { + echo " case {$i}:\n"; + echo " document.iform.ealgo_keylen.style.visibility = 'visible';\n"; + echo " document.iform.ealgo_keylen.options.length = 0;\n"; +// echo " document.iform.ealgo_keylen.options[document.iform.ealgo_keylen.options.length] = new Option( 'auto', 'auto' );\n"; + + $key_hi = $algodata['keysel']['hi']; + $key_lo = $algodata['keysel']['lo']; + $key_step = $algodata['keysel']['step']; + + for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) + echo " document.iform.ealgo_keylen.options[document.iform.ealgo_keylen.options.length] = new Option( '{$keylen} bits', '{$keylen}' );\n"; + echo " break;\n"; + } else { + echo " case {$i}:\n"; + echo " document.iform.ealgo_keylen.style.visibility = 'hidden';\n"; + echo " document.iform.ealgo_keylen.options.length = 0;\n"; + echo " break;\n"; + } + $i++; + } +?> + } + + if( bits ) + document.iform.ealgo_keylen.value = bits; +} +function dpdchkbox_change() { + if( document.iform.dpd_enable.checked ) { + document.iform.dpd_delay.disabled = 0; + document.iform.dpd_maxfail.disabled = 0; + } else { + document.iform.dpd_delay.disabled = 1; + document.iform.dpd_maxfail.disabled = 1; + } +} +//--> +</script> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="vpn_ipsec_phase1.php" method="post" name="iform" id="iform"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq">Disabled</td> + <td width="78%" class="vtable"> + <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>> + <strong>Disable this phase1 entry</strong><br> + <span class="vexpl">Set this option to disable this phase1 without + removing it from the list. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Interface</td> + <td width="78%" class="vtable"> + <select name="interface" class="formselect"> + <?php + $interfaces = get_configured_interface_with_descr(); + $carpips = find_number_of_needed_carp_interfaces(); + for ($i=0; $i<$carpips; $i++) { + $carpip = find_interface_ip("carp" . $i); + $interfaces['carp' . $i] = "CARP{$i} ({$carpip})"; + } + foreach ($interfaces as $iface => $ifacename): + ?> + <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>> + <?=htmlspecialchars($ifacename);?> + </option> + <?php endforeach; ?> + </select> <br> + <span class="vexpl">Select the interface for the local endpoint of this phase1 entry.</span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Remote gateway</td> + <td width="78%" class="vtable"> + <?=$mandfldhtml;?><input name="remotegw" type="text" class="formfld unknown" id="remotegw" size="20" value="<?=$pconfig['remotegw'];?>"> + <br> + Enter the public IP address or host name of the remote gateway + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Description</td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl">You may enter a description here + for your reference (not parsed).</span> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"></td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic">Phase 1 proposal + (Authentication) + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Negotiation mode</td> + <td width="78%" class="vtable"> + <select name="mode" class="formselect"> + <?php + $modes = explode(" ", "main aggressive"); + foreach ($modes as $mode): + ?> + <option value="<?=$mode;?>" <?php if ($mode == $pconfig['mode']) echo "selected"; ?>> + <?=htmlspecialchars($mode);?> + </option> + <?php endforeach; ?> + </select> <br> <span class="vexpl">Aggressive is more flexible, but less secure.</span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">My identifier</td> + <td width="78%" class="vtable"> + <select name="myid_type" class="formselect"> + <?php foreach ($my_identifier_list as $mode => $modename): ?> + <option value="<?=$mode;?>" <?php if ($mode == $pconfig['myid_type']) echo "selected"; ?>> + <?=htmlspecialchars($modename);?> + </option> + <?php endforeach; ?> + </select> + <input name="myid_data" type="text" class="formfld unknown" id="myid_data" size="30" value="<?=$pconfig['myid_data'];?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Peer identifier</td> + <td width="78%" class="vtable"> + <select name="peerid_type" class="formselect"> + <?php foreach ($peer_identifier_list as $mode => $modename): ?> + <option value="<?=$mode;?>" <?php if ($mode == $pconfig['peerid_type']) echo "selected"; ?>> + <?=htmlspecialchars($modename);?> + </option> + <?php endforeach; ?> + </select> + <input name="peerid_data" type="text" class="formfld unknown" id="peerid_data" size="30" value="<?=$pconfig['peerid_data'];?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Encryption algorithm</td> + <td width="78%" class="vtable"> + <select name="ealgo" class="formselect" onChange="ealgosel_change()"> + <?php + foreach ($p1_ealgos as $algo => $algodata): + $selected = ''; + if ($algo == $pconfig['ealgo']['name']) + $selected = ' selected'; + ?> + <option value="<?=$algo;?>"<?=$selected?>> + <?=htmlspecialchars($algodata['name']);?> + </option> + <?php endforeach; ?> + </select> + <select name="ealgo_keylen" width="30" class="formselect"> + </select> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Hash algorithm</td> + <td width="78%" class="vtable"> + <select name="halgo" class="formselect"> + <?php foreach ($p1_halgos as $algo => $algoname): ?> + <option value="<?=$algo;?>" <?php if ($algo == $pconfig['halgo']) echo "selected"; ?>> + <?=htmlspecialchars($algoname);?> + </option> + <?php endforeach; ?> + </select> + <br> + <span class="vexpl"> + Must match the setting chosen on the remote side. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">DH key group</td> + <td width="78%" class="vtable"> + <select name="dhgroup" class="formselect"> + <?php $keygroups = explode(" ", "1 2 5"); foreach ($keygroups as $keygroup): ?> + <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['dhgroup']) echo "selected"; ?>> + <?=htmlspecialchars($keygroup);?> + </option> + <?php endforeach; ?> + </select> + <br> + <span class="vexpl"> + <em>1 = 768 bit, 2 = 1024 bit, 5 = 1536 bit</em> + <br> + Must match the setting chosen on the remote side. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Lifetime</td> + <td width="78%" class="vtable"> + <input name="lifetime" type="text" class="formfld unknown" id="lifetime" size="20" value="<?=$pconfig['lifetime'];?>"> + seconds + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Authentication method</td> + <td width="78%" class="vtable"> + <select name="authentication_method" class="formselect" onChange="methodsel_change()"> + <?php foreach ($p1_authentication_methods as $method => $methodname): ?> + <option value="<?=$method;?>" <?php if ($method == $pconfig['authentication_method']) echo "selected"; ?>> + <?=htmlspecialchars($methodname);?> + </option> + <?php endforeach; ?> + </select> + <br> + <span class="vexpl">Must match the setting chosen on the remote side.</span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Pre-Shared Key</td> + <td width="78%" class="vtable"> + <?=$mandfldhtml;?><input name="pskey" type="text" class="formfld unknown" id="pskey" size="40" value="<?=htmlspecialchars($pconfig['pskey']);?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">My Certificate</td> + <td width="78%" class="vtable"> + <textarea name="cert" cols="65" rows="7" id="cert" class="formpre"><?=htmlspecialchars($pconfig['cert']);?></textarea> + <br> + Paste a certificate in X.509 PEM format here.</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">My Private Key</td> + <td width="78%" class="vtable"> + <textarea name="privatekey" cols="65" rows="7" id="privatekey" class="formpre"><?=htmlspecialchars($pconfig['privatekey']);?></textarea> + <br> + Paste an RSA private key in PEM format here. + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Peer certificate</td> + <td width="78%" class="vtable"> + <textarea name="peercert" cols="65" rows="7" id="peercert" class="formpre"><?=htmlspecialchars($pconfig['peercert']);?></textarea> + <br> + Paste the peer X.509 certificate in PEM format here.<br> + Leave this blank if you want to use a CA certificate for identity validation. + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"></td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic">Advanced Options</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">NAT Traversal</td> + <td width="78%" class="vtable"> + <select name="nat_traversal" class="formselect"> + <option value="off" <?php if ($pconfig['nat_traversal'] == "off") echo "selected"; ?>>Disable</option> + <option value="on" <?php if ($pconfig['nat_traversal'] == "on") echo "selected"; ?>>Enable</option> + <option value="force" <?php if ($pconfig['nat_traversal'] == "force") echo "selected"; ?>>Force</option> + </select> + <br/> + <span class="vexpl"> + Set this option to enable the use of NAT-T (i.e. the encapsulation of ESP in UDP packets) if needed, + which can help with clients that are behind restrictive firewalls. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Dead Peer Detection</td> + <td width="78%" class="vtable"> + <input name="dpd_enable" type="checkbox" id="dpd_enable" value="yes" <?php if ($pconfig['dpd_enable']) echo "checked"; ?> onClick="dpdchkbox_change()"> + Enable DPD<br> + <br> + <input name="dpd_delay" type="text" class="formfld unknown" id="dpd_delay" size="5" value="<?=$pconfig['dpd_delay'];?>"> + seconds<br> + <span class="vexpl">Delay between requesting peer acknowledgement.</span><br> + <br> + <input name="dpd_maxfail" type="text" class="formfld unknown" id="dpd_maxfail" size="5" value="<?=$pconfig['dpd_maxfail'];?>"> + retries<br> + <span class="vexpl">Number consecutive failures allowed before disconnect.</span><br> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Automatically ping host</td> + <td width="78%" class="vtable"> + <input name="pinghost" type="text" class="formfld unknown" id="pinghost" size="20" value="<?=$pconfig['pinghost'];?>"> + IP address + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="Save"> + <input name="ikeid" type="hidden" value="<?=$pconfig['ikeid'];?>"> + <?php if (isset($p1index) && $a_phase1[$p1index]): ?> + <input name="p1index" type="hidden" value="<?=$p1index;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<script lannguage="JavaScript"> +<!-- +<?php + /* determine if we should init the key length */ + $keyset = ''; + if (isset($pconfig['ealgo']['keylen'])) + if (is_numeric($pconfig['ealgo']['keylen'])) + $keyset = $pconfig['ealgo']['keylen']; +?> +methodsel_change(); +ealgosel_change(<?=$keyset;?>); +dpdchkbox_change(); +//--> +</script> +<?php include("fend.inc"); ?> diff --git a/usr/local/www/vpn_ipsec_phase2.php b/usr/local/www/vpn_ipsec_phase2.php new file mode 100644 index 0000000..7a3c5ce --- /dev/null +++ b/usr/local/www/vpn_ipsec_phase2.php @@ -0,0 +1,489 @@ +<?php +/* + vpn_ipsec_phase2.php + part of m0n0wall (http://m0n0.ch/wall) + + Copyright (C) 2008 Shrew Soft Inc + Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>. + All rights reserved. + + 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. +*/ + +require("guiconfig.inc"); + +if (!is_array($config['ipsec']['phase2'])) + $config['ipsec']['phase2'] = array(); + +$a_phase2 = &$config['ipsec']['phase2']; + +if($config['interfaces']['lan']) + $specialsrcdst = explode(" ", "lan"); + +$p2index = $_GET['p2index']; +if (isset($_POST['p2index'])) + $p2index = $_POST['p2index']; + +if (isset($_GET['dup'])) + $p2index = $_GET['dup']; + +if (isset($p2index) && $a_phase2[$p2index]) +{ + $pconfig['ikeid'] = $a_phase2[$p2index]['ikeid']; + $pconfig['disabled'] = isset($a_phase2[$p2index]['disabled']); + $pconfig['descr'] = $a_phase2[$p2index]['descr']; + + idinfo_to_pconfig("local",$a_phase2[$p2index]['localid'],$pconfig); + idinfo_to_pconfig("remote",$a_phase2[$p2index]['remoteid'],$pconfig); + + $pconfig['proto'] = $a_phase2[$p2index]['protocol']; + ealgos_to_pconfig($a_phase2[$p2index]['encryption-algorithm-option'],$pconfig); + $pconfig['halgos'] = $a_phase2[$p2index]['hash-algorithm-option']; + $pconfig['pfsgroup'] = $a_phase2[$p2index]['pfsgroup']; + $pconfig['lifetime'] = $a_phase2[$p2index]['lifetime']; +} +else +{ + $pconfig['ikeid'] = $_GET['ikeid']; + + /* defaults */ + $pconfig['localid_type'] = "lan"; + $pconfig['remoteid_type'] = "network"; + $pconfig['proto'] = "esp"; + $pconfig['ealgos'] = explode(",", "3des,blowfish,cast128,aes"); + $pconfig['halgos'] = explode(",", "hmac_sha1,hmac_md5"); + $pconfig['pfsgroup'] = "0"; + $pconfig['lifetime'] = "3600"; +} + +if (isset($_GET['dup'])) + unset($p2index); + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + $ealgos = pconfig_to_ealgos($pconfig); + $localid = pconfig_to_idinfo("local",$pconfig); + $remoteid = pconfig_to_idinfo("remote",$pconfig); + + if (!isset( $_POST['ikeid'])) + $input_errors[] = "A valid ikeid must be specified."; + + /* input validation */ + $reqdfields = explode(" ", "localid_type remoteid_type halgos"); + $reqdfieldsn = explode(",", "Local network type,Remote network type,P2 Hash Algorithms"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + switch ($_POST['localid_type']) { + case "network": + if (!$_POST['localid_netbits'] || !is_numeric($_POST['localid_netbits'])) + $input_errors[] = "A valid local network bit count must be specified.."; + case "address": + if (!$_POST['localid_address'] || !is_ipaddr($_POST['localid_address'])) + $input_errors[] = "A valid local network IP address must be specified."; + break; + } + + switch ($_POST['remoteid_type']) { + case "network": + if (!$_POST['remoteid_netbits'] || !is_numeric($_POST['remoteid_netbits'])) + $input_errors[] = "A valid remote network bit count must be specified.."; + case "address": + if (!$_POST['remoteid_address'] || !is_ipaddr($_POST['remoteid_address'])) + $input_errors[] = "A valid remote network IP address must be specified."; + break; + } + +/* TODO : Validate enabled phase2's are not duplicates */ + + if (!count($ealgos)) { + $input_errors[] = "At least one encryption algorithm must be selected."; + } + if (($_POST['lifetime'] && !is_numeric($_POST['lifetime']))) { + $input_errors[] = "The P2 lifetime must be an integer."; + } + + if (!$input_errors) { + $ph2ent['ikeid'] = $_POST['ikeid']; + $ph2ent['disabled'] = $_POST['disabled'] ? true : false; + $ph2ent['localid'] = $localid; + $ph2ent['remoteid'] = $remoteid; + $ph2ent['protocol'] = $_POST['proto']; + $ph2ent['encryption-algorithm-option'] = $ealgos; + $ph2ent['hash-algorithm-option'] = $_POST['halgos']; + $ph2ent['pfsgroup'] = $_POST['pfsgroup']; + $ph2ent['lifetime'] = $_POST['lifetime']; + $ph2ent['descr'] = $_POST['descr']; + + if (isset($p2index) && $a_phase2[$p2index]) + $a_phase2[$p2index] = $ph2ent; + else + $a_phase2[] = $ph2ent; + + write_config(); + touch($d_ipsecconfdirty_path); + + header("Location: vpn_ipsec.php"); + exit; + } +} + +$pgtitle = array("VPN","IPsec","Edit Phase 2"); +include("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<script language="JavaScript"> +<!-- +function typesel_change_local(bits) { + + if (!bits) + bits = 24; + + switch (document.iform.localid_type.selectedIndex) { + case 0: /* single */ + document.iform.localid_address.disabled = 0; + document.iform.localid_netbits.value = 0; + document.iform.localid_netbits.disabled = 1; + break; + case 1: /* network */ + document.iform.localid_address.disabled = 0; + document.iform.localid_netbits.value = bits; + document.iform.localid_netbits.disabled = 0; + break; + default: + document.iform.localid_address.value = ""; + document.iform.localid_address.disabled = 1; + document.iform.localid_netbits.value = 0; + document.iform.localid_netbits.disabled = 1; + break; + } +} +function typesel_change_remote(bits) { + + if (!bits) + bits = 24; + + switch (document.iform.remoteid_type.selectedIndex) { + case 0: /* single */ + document.iform.remoteid_address.disabled = 0; + document.iform.remoteid_netbits.value = 0; + document.iform.remoteid_netbits.disabled = 1; + break; + case 1: /* network */ + document.iform.remoteid_address.disabled = 0; + document.iform.remoteid_netbits.value = bits; + document.iform.remoteid_netbits.disabled = 0; + break; + default: + document.iform.remoteid_address.value = ""; + document.iform.remoteid_address.disabled = 1; + document.iform.remoteid_netbits.value = 0; + document.iform.remoteid_netbits.disabled = 1; + break; + } +} +//--> + +</script> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="vpn_ipsec_phase2.php" method="post" name="iform" id="iform"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq">Mode</td> + <td width="78%" class="vtable"> Tunnel</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Disabled</td> + <td width="78%" class="vtable"> + <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>> + <strong>Disable this phase2 entry</strong><br> + <span class="vexpl">Set this option to disable this phase2 entry without + removing it from the list. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Local Network</td> + <td width="78%" class="vtable"> + <table border="0" cellspacing="0" cellpadding="0"> + <tr> + <td>Type: </td> + <td></td> + <td> + <select name="localid_type" class="formselect" onChange="typesel_change_local()"> + <option value="address" <?php if ($pconfig['localid_type'] == "address") echo "selected";?>>Address</option> + <option value="network" <?php if ($pconfig['localid_type'] == "network") echo "selected";?>>Network</option> + <option value="lan" <?php if ($pconfig['localid_type'] == "lan" ) echo "selected";?>>LAN subnet</option> + </select> + </td> + </tr> + <tr> + <td>Address: </td> + <td><?=$mandfldhtmlspc;?></td> + <td> + <input name="localid_address" type="text" class="formfld unknown" id="localid_address" size="20" value="<?=$pconfig['localid_address'];?>"> + / + <select name="localid_netbits" class="formselect" id="localid_netbits"> + <?php for ($i = 32; $i >= 0; $i--): ?> + <option value="<?=$i;?>" <?php if ($i == $pconfig['localid_netbits']) echo "selected"; ?>> + <?=$i;?> + </option> + <?php endfor; ?> + </select> + </td> + </tr> + </table> + </td> + </tr> + <td width="22%" valign="top" class="vncellreq">Remote Network</td> + <td width="78%" class="vtable"> + <table border="0" cellspacing="0" cellpadding="0"> + <tr> + <td>Type: </td> + <td></td> + <td> + <select name="remoteid_type" class="formselect" onChange="typesel_change_remote()"> + <option value="address" <?php if ($pconfig['remoteid_type'] == "address") echo "selected"; ?>>Address</option> + <option value="network" <?php if ($pconfig['remoteid_type'] == "network") echo "selected"; ?>>Network</option> + </select> + </td> + </tr> + <tr> + <td>Address: </td> + <td><?=$mandfldhtmlspc;?></td> + <td> + <input name="remoteid_address" type="text" class="formfld unknown" id="remoteid_address" size="20" value="<?=$pconfig['remoteid_address'];?>"> + / + <select name="remoteid_netbits" class="formselect" id="remoteid_netbits"> + <?php for ($i = 32; $i >= 0; $i--): ?> + <option value="<?=$i;?>" <?php if ($i == $pconfig['remoteid_netbits']) echo "selected"; ?>> + <?=$i;?> + </option> + <?php endfor; ?> + </select> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Description</td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl">You may enter a description here + for your reference (not parsed).</span> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"></td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic">Phase 2 proposal + (SA/Key Exchange) + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Protocol</td> + <td width="78%" class="vtable"> + <select name="proto" class="formselect"> + <?php foreach ($p2_protos as $proto => $protoname): ?> + <option value="<?=$proto;?>" <?php if ($proto == $pconfig['proto']) echo "selected"; ?>> + <?=htmlspecialchars($protoname);?> + </option> + <?php endforeach; ?> + </select> + <br> + <span class="vexpl">ESP is encryption, AH is authentication only </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Encryption algorithms</td> + <td width="78%" class="vtable"> + <table border="0" cellspacing="0" cellpadding="0"> + <?php + foreach ($p2_ealgos as $algo => $algodata): + $checked = ''; + if (in_array($algo,$pconfig['ealgos'])) + $checked = " checked"; + ?> + <tr> + <td> + <input type="checkbox" name="ealgos[]?>" value="<?=$algo;?>"<?=$checked?>> + </td> + <td> + <?=htmlspecialchars($algodata['name']);?> + </td> + <td> + <?php if(is_array($algodata['keysel'])): ?> + + <select name="keylen_<?=$algo;?>" class="formselect"> + <option value="auto">auto</option> + <?php + $key_hi = $algodata['keysel']['hi']; + $key_lo = $algodata['keysel']['lo']; + $key_step = $algodata['keysel']['step']; + for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step): + $selected = ''; +// if ($checked && in_array("keylen_".$algo,$pconfig)) + if ($keylen == $pconfig["keylen_".$algo]) + $selected = " selected"; + ?> + <option value="<?=$keylen;?>"<?=$selected;?>><?=$keylen;?> bits</option> + <?php endfor; ?> + </select> + <?php endif; ?> + </td> + </tr> + <?php endforeach; ?> + </table> + <br> + Hint: use 3DES for best compatibility or if you have a hardware + crypto accelerator card. Blowfish is usually the fastest in + software encryption. + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">Hash algorithms</td> + <td width="78%" class="vtable"> + <?php foreach ($p2_halgos as $algo => $algoname): ?> + <input type="checkbox" name="halgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['halgos'])) echo "checked"; ?>> + <?=htmlspecialchars($algoname);?> + <br> + <?php endforeach; ?> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq">PFS key group</td> + <td width="78%" class="vtable"> + <select name="pfsgroup" class="formselect"> + <?php foreach ($p2_pfskeygroups as $keygroup => $keygroupname): ?> + <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['pfsgroup']) echo "selected"; ?>> + <?=htmlspecialchars($keygroupname);?> + </option> + <?php endforeach; ?> + </select> + <br> + <span class="vexpl"><em>1 = 768 bit, 2 = 1024 bit, 5 = 1536 bit</em></span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Lifetime</td> + <td width="78%" class="vtable"> + <input name="lifetime" type="text" class="formfld unknown" id="lifetime" size="20" value="<?=$pconfig['lifetime'];?>"> + seconds + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="Save"> + <input name="ikeid" type="hidden" value="<?=$pconfig['ikeid'];?>"> + <?php if (isset($p2index) && $a_phase2[$p2index]): ?> + <input name="p2index" type="hidden" value="<?=$p2index;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<script lannguage="JavaScript"> +<!-- +typesel_change_local(<?=$pconfig['localid_netbits']?>); +typesel_change_remote(<?=$pconfig['remoteid_netbits']?>); +//--> +</script> +<?php include("fend.inc"); ?> + +<?php + +function pconfig_to_ealgos(& $pconfig) { + + global $p2_ealgos; + + $ealgos = array(); + foreach ($p2_ealgos as $algo_name => $algo_data) { + if (in_array($algo_name,$pconfig['ealgos'])) { + $ealg = array(); + $ealg['name'] = $algo_name; + if (is_array($algo_data['keysel'])) + $ealg['keylen'] = $_POST["keylen_".$algo_name]; + $ealgos[] = $ealg; + } + } + + return $ealgos; +} + +function ealgos_to_pconfig(& $ealgos,& $pconfig) { + + $pconfig['ealgos'] = array(); + foreach ($ealgos as $algo_data) { + $pconfig['ealgos'][] = $algo_data['name']; + if (isset($algo_data['keylen'])) + $pconfig["keylen_".$algo_data['name']] = $algo_data['keylen']; + } + + return $ealgos; +} + +function pconfig_to_idinfo($prefix,& $pconfig) { + + $type = $pconfig[$prefix."id_type"]; + $address = $pconfig[$prefix."id_address"]; + $netbits = $pconfig[$prefix."id_netbits"]; + + switch( $type ) + { + case "address": + return array('type' => $type, 'address' => $address); + case "network": + return array('type' => $type, 'address' => $address, 'netbits' => $netbits); + default: + return array('type' => $type ); + } +} + +function idinfo_to_pconfig($prefix,& $idinfo,& $pconfig) { + + switch( $idinfo['type'] ) + { + case "address": + $pconfig[$prefix."id_type"] = $idinfo['type']; + $pconfig[$prefix."id_address"] = $idinfo['address']; + break; + case "network": + $pconfig[$prefix."id_type"] = $idinfo['type']; + $pconfig[$prefix."id_address"] = $idinfo['address']; + $pconfig[$prefix."id_netbits"] = $idinfo['netbits']; + break; + default: + $pconfig[$prefix."id_type"] = $idinfo['type']; + break; + } +} + +?> diff --git a/usr/local/www/widgets/include/ipsec.inc b/usr/local/www/widgets/include/ipsec.inc deleted file mode 100644 index 5484d63..0000000 --- a/usr/local/www/widgets/include/ipsec.inc +++ /dev/null @@ -1,81 +0,0 @@ -<?php -//set variable for custom title -$ipsec_title = "IPsec"; - -function get_ipsec_tunnel_sad() { - /* query SAD */ - $fd = @popen("/usr/local/sbin/setkey -D", "r"); - $sad = array(); - if ($fd) { - while (!feof($fd)) { - $line = chop(fgets($fd)); - if (!$line) - 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); - $i = 0; - } else { - $linea = explode(" ", trim($line)); - if ($i == 1) { - $cursa['proto'] = $linea[0]; - $cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1); - } else if ($i == 2) { - $cursa['ealgo'] = $linea[1]; - } else if ($i == 3) { - $cursa['aalgo'] = $linea[1]; - } - } - $i++; - } - if (is_array($cursa) && count($cursa)) - $sad[] = $cursa; - pclose($fd); - } - return($sad); -} - -function get_ipsec_tunnel_src($tunnel) { - global $g, $config, $sad; - $if = "WAN"; - if ($tunnel['interface']) { - $if = $tunnel['interface']; - $realinterface = convert_friendly_interface_to_real_interface_name($if); - $interfaceip = find_interface_ip($realinterface); - } - return $interfaceip; -} - -function output_ipsec_tunnel_status($tunnel) { - global $g, $config, $sad; - $if = "WAN"; - $interfaceip = get_ipsec_tunnel_src($tunnel); - $foundsrc = false; - $founddst = false; - - if(!is_array($sad)) { - /* we have no sad array, bail */ - return(false); - } - foreach($sad as $sa) { - if($sa['src'] == $interfaceip) - $foundsrc = true; - if($sa['dst'] == $tunnel['remote-gateway']) - $founddst = true; - } - if($foundsrc && $founddst) { - /* tunnel is up */ - $iconfn = "pass"; - return(true); - } else { - /* tunnel is down */ - $iconfn = "reject"; - return(false); - } -} - -?> diff --git a/usr/local/www/widgets/widgets/ipsec.widget.php b/usr/local/www/widgets/widgets/ipsec.widget.php index dd033c0..1a63029 100644 --- a/usr/local/www/widgets/widgets/ipsec.widget.php +++ b/usr/local/www/widgets/widgets/ipsec.widget.php @@ -33,9 +33,8 @@ require_once("guiconfig.inc"); require_once("pfsense-utils.inc"); require_once("functions.inc"); -require_once("/usr/local/www/widgets/include/ipsec.inc"); - if (isset($config['ipsec']['tunnel'])){?> + if (isset($config['ipsec']['phase1'])){?> <div> </div> <?php $tab_array = array(); @@ -43,26 +42,27 @@ require_once("/usr/local/www/widgets/include/ipsec.inc"); $tab_array[1] = array("Tunnel Status", false, "ipsec-tunnel"); display_widget_tabs($tab_array); - $sad = array(); - $sad = get_ipsec_tunnel_sad(); + $spd = ipsec_dump_spd(); + $sad = ipsec_dump_sad(); $activecounter = 0; $inactivecounter = 0; $ipsec_detail_array = array(); - foreach ($config['ipsec']['tunnel'] as $tunnel){ + foreach ($config['ipsec']['phase2'] as $ph2ent){ + ipsec_lookup_phase1($ph2ent,$ph1ent); $ipsecstatus = false; $tun_disabled = "false"; $foundsrc = false; $founddst = false; - if (isset($tunnel['disabled'])) { + if (isset($ph1ent['disabled']) || isset($ph2ent['disabled'])) { $tun_disabled = "true"; continue; - } + } - if(output_ipsec_tunnel_status($tunnel)) { + if(ipsec_phase2_status($spd,$sad,$ph1ent,$ph2ent)) { /* tunnel is up */ $iconfn = "true"; $activecounter++; @@ -72,16 +72,16 @@ require_once("/usr/local/www/widgets/include/ipsec.inc"); $inactivecounter++; } - $ipsec_detail_array[] = array('src' => $tunnel['interface'], - 'dest' => $tunnel['remote-gateway'], - 'remote-subnet' => $tunnel['remote-subnet'], - 'descr' => $tunnel['descr'], + $ipsec_detail_array[] = array('src' => $ph1ent['interface'], + 'dest' => $ph1ent['remote-gateway'], + 'remote-subnet' => ipsec_idinfo_to_text($ph2ent['remoteid']), + 'descr' => $ph2ent['descr'], 'status' => $iconfn, 'disabled' => $tun_disabled); } } - if (isset($config['ipsec']['tunnel'])){ ?> + if (isset($config['ipsec']['phase2'])){ ?> <div id="ipsec-Overview" style="display:block;background-color:#EEEEEE;"> <div> |