From c3dd5934b4f08d054e9fd15cf9246fb4796ca07e Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Sat, 19 Jul 2025 15:51:12 +0200 Subject: [PATCH] ipsec: removal of legacy pages #8348 (cherry picked from commit d2fd23c28d37a836f9e0cc3768cf4615211e0bb0) (cherry picked from commit 1a5ee9d1f699e384f6d27f3ff4bc5671f350a168) (cherry picked from commit da08c7a227d23496917fff64c0ba76b9eff962c3) (cherry picked from commit af997f1dd01f0e77f908b6ab430bc97c6f3e3c7f) --- LICENSE | 2 +- plist | 3 - src/etc/inc/plugins.inc.d/ipsec.inc | 43 +- .../System/Status/IPsecOverrideStatus.php | 1 - .../mvc/app/models/OPNsense/IPsec/ACL/ACL.xml | 29 - .../app/models/OPNsense/IPsec/Menu/Menu.xml | 7 - src/www/vpn_ipsec_mobile.php | 310 ---- src/www/vpn_ipsec_phase1.php | 1351 ----------------- src/www/vpn_ipsec_phase2.php | 842 ---------- 9 files changed, 31 insertions(+), 2557 deletions(-) delete mode 100644 src/www/vpn_ipsec_mobile.php delete mode 100644 src/www/vpn_ipsec_phase1.php delete mode 100644 src/www/vpn_ipsec_phase2.php diff --git a/LICENSE b/LICENSE index 95a484a4a4..c909fb5751 100644 --- a/LICENSE +++ b/LICENSE @@ -11,7 +11,7 @@ Copyright (c) 2005-2012 David Zeller Copyright (c) 2014-2025 Deciso B.V. Copyright (c) 2010 Erik Fonnesbeck Copyright (c) 2009 Erik Kristensen -Copyright (c) 2008-2014 Ermal Luçi +Copyright (c) 2008-2011 Ermal Luçi Copyright (c) 2005 Espen Johansen Copyright (c) 2016-2019 EURO-LOG AG Copyright (c) 2017-2019 Fabian Franz diff --git a/plist b/plist index 4ccd859c54..2a61b62bee 100644 --- a/plist +++ b/plist @@ -2467,9 +2467,6 @@ /usr/local/www/system_general.php /usr/local/www/system_usermanager_passwordmg.php /usr/local/www/system_usermanager_settings_ldapacpicker.php -/usr/local/www/vpn_ipsec_mobile.php -/usr/local/www/vpn_ipsec_phase1.php -/usr/local/www/vpn_ipsec_phase2.php /usr/local/www/xmlrpc.php @sample /usr/local/etc/bogons.sample @sample /usr/local/etc/bogonsv6.sample diff --git a/src/etc/inc/plugins.inc.d/ipsec.inc b/src/etc/inc/plugins.inc.d/ipsec.inc index b4083ebf4c..da8e5c4509 100644 --- a/src/etc/inc/plugins.inc.d/ipsec.inc +++ b/src/etc/inc/plugins.inc.d/ipsec.inc @@ -135,6 +135,14 @@ function ipsec_syslog() return $logfacilities; } +function ipsec_legacy() +{ + global $config; + + /* latch on to this legacy file for detection enhanced by old config 'phase1' presence */ + return file_exists('/usr/local/www/vpn_ipsec_phase1.php') && !empty($config['ipsec']['phase1']); +} + function ipsec_services() { global $config; @@ -165,7 +173,8 @@ function ipsec_interfaces() $interfaces = []; $is_enabled = $swanctl->isEnabled(); - if (!$is_enabled && isset($config['ipsec']['phase1'])) { + + if (!$is_enabled && ipsec_legacy()) { foreach ($config['ipsec']['phase1'] as $ph1ent) { if (empty($ph1ent['disabled'])) { $is_enabled = true; @@ -227,9 +236,10 @@ function ipsec_devices() function ipsec_firewall(\OPNsense\Firewall\Plugin $fw) { global $config; + if ( (string)(new \OPNsense\IPsec\IPsec())->general->disablevpnrules == '0' && - isset($config['ipsec']['enable']) && isset($config['ipsec']['phase1']) + isset($config['ipsec']['enable']) && ipsec_legacy() ) { $enable_replyto = empty($config['system']['disablereplyto']); $enable_routeto = empty($config['system']['pf_disable_force_gw']); @@ -374,6 +384,7 @@ function ipsec_get_phase1_src(&$ph1ent) function ipsec_parse_phase2($ikeid) { global $config; + $result = [ "type" => "tunnel", // strongswan's default when type is not specified "local_ts" => [], @@ -387,12 +398,13 @@ function ipsec_parse_phase2($ikeid) "uniqid_reqid" => [] ]; - $a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : []; + $a_phase1 = ipsec_legacy() ? $config['ipsec']['phase1'] : []; $a_phase2 = isset($config['ipsec']['phase2']) ? $config['ipsec']['phase2'] : []; $a_client = isset($config['ipsec']['client']) ? $config['ipsec']['client'] : []; $ph1ent = current(array_filter($a_phase1, function ($e) use ($ikeid) { return $e['ikeid'] == $ikeid; })); + if ($ph1ent) { $uniqids = []; $keyexchange = !empty($ph1ent['iketype']) ? $ph1ent['iketype'] : "ikev1"; @@ -541,6 +553,7 @@ function ipsec_parse_phase2($ikeid) $result['ah_proposals'] = $ah_content; } } + return $result; } @@ -718,8 +731,8 @@ function ipsec_configure_spd() $line_count++; } - // process manual added spd entries - if (!empty($config['ipsec']['phase1']) && !empty($config['ipsec']['phase2'])) { + /* process manual added spd entries */ + if (ipsec_legacy() && !empty($config['ipsec']['phase2'])) { foreach ($config['ipsec']['phase1'] as $ph1ent) { if (!empty($ph1ent['disabled'])) { continue; @@ -785,7 +798,7 @@ function ipsec_setup_pinghosts() { global $config; - $a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : []; + $a_phase1 = ipsec_legacy() ? $config['ipsec']['phase1'] : []; $a_phase2 = isset($config['ipsec']['phase2']) ? $config['ipsec']['phase2'] : []; @unlink('/var/db/ipsecpinghosts'); @@ -873,7 +886,8 @@ function ipsec_setup_pinghosts() function ipsec_write_strongswan_conf() { global $config; - $a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : []; + + $a_phase1 = ipsec_legacy() ? $config['ipsec']['phase1'] : []; $a_phase2 = isset($config['ipsec']['phase2']) ? $config['ipsec']['phase2'] : []; $a_client = isset($config['ipsec']['client']) ? $config['ipsec']['client'] : []; @@ -959,7 +973,8 @@ function ipsec_write_cas() function ipsec_write_certs() { global $config; - $a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : []; + + $a_phase1 = ipsec_legacy() ? $config['ipsec']['phase1'] : []; foreach ((new \OPNsense\IPsec\Swanctl())->getUsedCertrefs() as $certref) { $cert = lookup_cert($certref); @@ -978,6 +993,7 @@ function ipsec_write_certs() @chmod($ph1certfile, 0600); file_put_contents($ph1certfile, base64_decode($cert['crt'])); } + foreach ($a_phase1 as $ph1ent) { if (isset($ph1ent['disabled'])) { continue; @@ -1039,8 +1055,9 @@ function ipsec_write_keypairs() function ipsec_write_secrets() { global $config; + + $a_phase1 = ipsec_legacy() ? $config['ipsec']['phase1'] : []; $secrets = []; - $a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : []; foreach ($a_phase1 as $seq => $ph1ent) { if (isset($ph1ent['disabled'])) { @@ -1091,7 +1108,7 @@ function ipsec_configure_do($verbose = false, $interface_map = null) if (!empty($interface_map)) { $active = false; - if (isset($config['ipsec']['phase1'])) { + if (ipsec_legacy()) { foreach ($config['ipsec']['phase1'] as $phase1) { if (!isset($phase1['disabled']) && in_array($phase1['interface'], $interface_map)) { $active = true; @@ -1119,9 +1136,8 @@ function ipsec_configure_do($verbose = false, $interface_map = null) set_single_sysctl('net.key.preferred_oldsa', '0'); } - $ipseccfg = $config['ipsec'] ?? []; - $a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : []; + $a_phase1 = ipsec_legacy() ? $config['ipsec']['phase1'] : []; $a_phase2 = isset($config['ipsec']['phase2']) ? $config['ipsec']['phase2'] : []; $a_client = isset($config['ipsec']['client']) ? $config['ipsec']['client'] : []; @@ -1172,6 +1188,7 @@ function ipsec_configure_do($verbose = false, $interface_map = null) ] ]; } + if (count($a_phase1)) { foreach ($a_phase1 as $ph1ent) { if (isset($ph1ent['disabled'])) { @@ -1480,7 +1497,7 @@ function ipsec_get_configured_vtis() { global $config; - $a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : []; + $a_phase1 = ipsec_legacy() ? $config['ipsec']['phase1'] : []; $a_phase2 = isset($config['ipsec']['phase2']) ? $config['ipsec']['phase2'] : []; $configured_intf = []; diff --git a/src/opnsense/mvc/app/library/OPNsense/System/Status/IPsecOverrideStatus.php b/src/opnsense/mvc/app/library/OPNsense/System/Status/IPsecOverrideStatus.php index 242f04a344..b5843a2097 100644 --- a/src/opnsense/mvc/app/library/OPNsense/System/Status/IPsecOverrideStatus.php +++ b/src/opnsense/mvc/app/library/OPNsense/System/Status/IPsecOverrideStatus.php @@ -41,7 +41,6 @@ class IPsecOverrideStatus extends AbstractStatus $this->internalIsBanner = true; $this->internalScope[] = '/ui/ipsec/connections*'; $this->internalScope[] = '/ui/ipsec/tunnels*'; - $this->internalScope[] = '/vpn_ipsec_mobile.php'; } public function collectStatus() diff --git a/src/opnsense/mvc/app/models/OPNsense/IPsec/ACL/ACL.xml b/src/opnsense/mvc/app/models/OPNsense/IPsec/ACL/ACL.xml index 353f6c49f1..97267e7eb8 100644 --- a/src/opnsense/mvc/app/models/OPNsense/IPsec/ACL/ACL.xml +++ b/src/opnsense/mvc/app/models/OPNsense/IPsec/ACL/ACL.xml @@ -1,5 +1,4 @@ - VPN: IPsec: Key Pairs Allow access to the IPsec Key Pairs @@ -9,14 +8,6 @@ api/ipsec/service/* - - VPN: IPsec: Tunnels [legacy] - - ui/ipsec/tunnels - api/ipsec/tunnel/* - api/ipsec/legacy_subsystem/* - - VPN: IPsec: Connections @@ -29,20 +20,6 @@ api/ipsec/vti/* - - - - VPN: IPsec: Edit Phase 1 - - vpn_ipsec_phase1.php* - - - - VPN: IPsec: Edit Phase 2 - - vpn_ipsec_phase2.php* - - VPN: IPsec: Edit Pre-Shared Keys @@ -51,12 +28,6 @@ api/ipsec/service/* - - VPN: IPsec: Mobile [legacy] - - vpn_ipsec_mobile.php* - - Status: IPsec diff --git a/src/opnsense/mvc/app/models/OPNsense/IPsec/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/IPsec/Menu/Menu.xml index 7d959fd983..eeb2e88b32 100644 --- a/src/opnsense/mvc/app/models/OPNsense/IPsec/Menu/Menu.xml +++ b/src/opnsense/mvc/app/models/OPNsense/IPsec/Menu/Menu.xml @@ -2,13 +2,6 @@ - - - - - - - diff --git a/src/www/vpn_ipsec_mobile.php b/src/www/vpn_ipsec_mobile.php deleted file mode 100644 index 23d00589aa..0000000000 --- a/src/www/vpn_ipsec_mobile.php +++ /dev/null @@ -1,310 +0,0 @@ - - * 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_once("guiconfig.inc"); -require_once("interfaces.inc"); -require_once("filter.inc"); -require_once("system.inc"); -require_once("plugins.inc.d/ipsec.inc"); - -config_read_array('ipsec', 'client'); -config_read_array('ipsec', 'phase1'); - -// define formfields -$form_fields = "pool_address,pool_netbits,pool_address_v6,pool_netbits_v6"; - -if ($_SERVER['REQUEST_METHOD'] === 'GET') { - // pass savemessage - if (isset($_GET['savemsg'])) { - $savemsg = htmlspecialchars($_GET['savemsg']); - } - $pconfig = array(); - // defaults - $pconfig['pool_netbits'] = 24; - $pconfig['pool_netbits_v6'] = 64; - - // copy / initialize $pconfig attributes - foreach (explode(",", $form_fields) as $fieldname) { - $fieldname = trim($fieldname); - if (isset($config['ipsec']['client'][$fieldname])) { - $pconfig[$fieldname] = $config['ipsec']['client'][$fieldname]; - } elseif (!isset($pconfig[$fieldname])) { - // initialize element - $pconfig[$fieldname] = null; - } - } - if (isset($config['ipsec']['client']['enable'])) { - $pconfig['enable'] = true; - } - -} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { - $input_errors = array(); - $pconfig = $_POST; - if (isset($_POST['create'])) { - // create new phase1 entry - header(url_safe('Location: /vpn_ipsec_phase1.php?mobile=true')); - exit; - } elseif (isset($_POST['apply'])) { - // apply changes - ipsec_configure_do(); - $savemsg = get_std_save_message(true); - clear_subsystem_dirty('ipsec'); - header(url_safe('Location: /vpn_ipsec_mobile.php?savemsg=%s', array($savemsg))); - exit; - } elseif (isset($_POST['submit'])) { - // save form changes - if (!empty($pconfig['pool_address']) && !is_ipaddr($pconfig['pool_address'])) { - $input_errors[] = gettext("A valid IPv4 address for 'Virtual IPv4 Address Pool Network' must be specified."); - } - - if (!empty($pconfig['pool_address_v6']) && !is_ipaddr($pconfig['pool_address_v6'])) { - $input_errors[] = gettext("A valid IPv6 address for 'Virtual IPv6 Address Pool Network' must be specified."); - } - - - if (count($input_errors) == 0) { - $client = array(); - $copy_fields = "pool_address,pool_netbits,pool_address_v6,pool_netbits_v6"; - foreach (explode(",", $copy_fields) as $fieldname) { - $fieldname = trim($fieldname); - if (!empty($pconfig[$fieldname])) { - $client[$fieldname] = $pconfig[$fieldname]; - } - } - if (!empty($pconfig['enable'])) { - $client['enable'] = true; - } - - $config['ipsec']['client'] = $client; - - write_config(); - mark_subsystem_dirty('ipsec'); - header(url_safe('Location: /vpn_ipsec_mobile.php')); - exit; - } - } - - // initialize missing post attributes - foreach (explode(",", $form_fields) as $fieldname) { - $fieldname = trim($fieldname); - if (!isset($pconfig[$fieldname])) { - $pconfig[$fieldname] = null; - } - } -} - -legacy_html_escape_form_data($pconfig); - -$service_hook = 'strongswan'; - -include("head.inc"); - -?> - - - - - - - -
-
-
-" . gettext("You must apply the changes in order for them to take effect.")); -} -$ph1found = false; -$legacy_radius_configured = false; -foreach ($config['ipsec']['phase1'] as $ph1ent) { - if (!isset($ph1ent['disabled']) && isset($ph1ent['mobile'])) { - $ph1found = true; - if (($ph1ent['authentication_method'] ?? '') == 'eap-radius') { - $legacy_radius_configured = true; - } - } -} - -function print_legacy_box($msg, $name, $value) -{ - $savebutton = "
"; - $savebutton .= ""; - if (!empty($_POST['if'])) { - $savebutton .= ""; - } - $savebutton .= '
'; - - echo << - -
- -EOFnp; -} - -if (!empty($pconfig['enable']) && !$ph1found && !(new OPNsense\IPsec\Swanctl())->isEnabled()) { - print_legacy_box(gettext("Support for IPsec Mobile clients is enabled but a Phase1 definition was not found") . ".
" . gettext("When using (legacy) tunnels, please click Create to define one."), "create", gettext("Create Phase1")); -} -if (isset($input_errors) && count($input_errors) > 0) { - print_input_errors($input_errors); -} -?> -
-
-
- - - - - - - - - - - - - - - - - - - - -
- - -
- /> - - -
- onclick="pool_change()" /> - -
- - -
-
- onclick="pool_v6_change()" /> - -
- - -
-
-
-
-
-
- - - - - -
  - -
-
-
-
- - - - - - diff --git a/src/www/vpn_ipsec_phase1.php b/src/www/vpn_ipsec_phase1.php deleted file mode 100644 index f2548491cb..0000000000 --- a/src/www/vpn_ipsec_phase1.php +++ /dev/null @@ -1,1351 +0,0 @@ - - * Copyright (C) 2014-2015 Deciso B.V. - * Copyright (C) 2008 Shrew Soft Inc. - * Copyright (C) 2003-2005 Manuel Kasper - * Copyright (C) 2014 Ermal Luçi - * 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_once("guiconfig.inc"); -require_once("system.inc"); -require_once("filter.inc"); -require_once("interfaces.inc"); -require_once("plugins.inc.d/ipsec.inc"); - -/* - * ikeid management functions - */ - -function ipsec_ikeid_used($ikeid) { - global $config; - - if (!empty($config['ipsec']['phase1'])) { - foreach ($config['ipsec']['phase1'] as $ph1ent) { - if( $ikeid == $ph1ent['ikeid'] ) { - return true; - } - } - } - return false; -} - -function ipsec_ikeid_next() { - $ikeid = 1; - while(ipsec_ikeid_used($ikeid)) { - $ikeid++; - } - - return $ikeid; -} - -function ipsec_keypairs() -{ - $mdl = new \OPNsense\IPsec\IPsec(); - $node = $mdl->getNodeByReference('keyPairs.keyPair'); - - return $node ? $node->getNodes() : []; -} - -config_read_array('ipsec', 'phase1'); -config_read_array('ipsec', 'phase2'); - -if ($_SERVER['REQUEST_METHOD'] === 'GET') { - // fetch data - if (isset($_GET['dup']) && is_numericint($_GET['dup'])) { - $p1index = $_GET['dup']; - } elseif (isset($_GET['p1index']) && is_numericint($_GET['p1index'])) { - $p1index = $_GET['p1index']; - } - $pconfig = array(); - - // generice defaults - $pconfig['interface'] = "wan"; - $pconfig['iketype'] = "ikev2"; - $phase1_fields = "mode,protocol,myid_type,myid_data,peerid_type,peerid_data - ,encryption-algorithm,lifetime,authentication_method,descr,nat_traversal,rightallowany,inactivity_timeout - ,interface,iketype,dpd_delay,dpd_maxfail,dpd_action,remote-gateway,pre-shared-key,certref,margintime,rekeyfuzz - ,caref,local-kpref,peer-kpref,reauth_enable,rekey_enable,auto,tunnel_isolation,authservers,mobike,keyingtries - ,closeaction,unique"; - if (isset($p1index) && isset($config['ipsec']['phase1'][$p1index])) { - // 1-on-1 copy - foreach (explode(",", $phase1_fields) as $fieldname) { - $fieldname = trim($fieldname); - if(isset($config['ipsec']['phase1'][$p1index][$fieldname])) { - $pconfig[$fieldname] = $config['ipsec']['phase1'][$p1index][$fieldname]; - } elseif (!isset($pconfig[$fieldname])) { - // initialize element - $pconfig[$fieldname] = null; - } - } - - // attributes with some kind of logic behind them... - if (!isset($_GET['dup']) || !is_numericint($_GET['dup'])) { - // don't copy the ikeid on dup - $pconfig['ikeid'] = $config['ipsec']['phase1'][$p1index]['ikeid']; - } - $pconfig['disabled'] = isset($config['ipsec']['phase1'][$p1index]['disabled']); - $pconfig['sha256_96'] = !empty($config['ipsec']['phase1'][$p1index]['sha256_96']); - $pconfig['installpolicy'] = empty($config['ipsec']['phase1'][$p1index]['noinstallpolicy']); // XXX: reversed - - foreach (array('authservers', 'dhgroup', 'hash-algorithm') as $fieldname) { - if (!empty($config['ipsec']['phase1'][$p1index][$fieldname])) { - $pconfig[$fieldname] = explode(',', $config['ipsec']['phase1'][$p1index][$fieldname]); - } else { - $pconfig[$fieldname] = array(); - } - } - - $pconfig['remotebits'] = null; - $pconfig['remotenet'] = null ; - if (isset($a_phase1[$p1index]['remote-subnet']) && strpos($config['ipsec']['phase1'][$p1index]['remote-subnet'],'/') !== false) { - list($pconfig['remotenet'],$pconfig['remotebits']) = explode("/", $config['ipsec']['phase1'][$p1index]['remote-subnet']); - } elseif (isset($config['ipsec']['phase1'][$p1index]['remote-subnet'])) { - $pconfig['remotenet'] = $config['ipsec']['phase1'][$p1index]['remote-subnet']; - } - - if (isset($config['ipsec']['phase1'][$p1index]['mobile'])) { - $pconfig['mobile'] = true; - } - } else { - /* defaults new */ - if (isset($config['interfaces']['lan'])) { - $pconfig['localnet'] = "lan"; - } - $pconfig['mode'] = "main"; - $pconfig['protocol'] = "inet"; - $pconfig['myid_type'] = "myaddress"; - $pconfig['peerid_type'] = "peeraddress"; - $pconfig['authentication_method'] = "pre_shared_key"; - $pconfig['encryption-algorithm'] = ["name" => "aes256gcm16"]; - $pconfig['hash-algorithm'] = ['sha256']; - $pconfig['dhgroup'] = array('14'); - $pconfig['nat_traversal'] = "on"; - $pconfig['installpolicy'] = true; - $pconfig['authservers'] = array(); - - /* mobile client */ - if (isset($_GET['mobile'])) { - $pconfig['mobile'] = true; - } - // init empty - foreach (explode(",", $phase1_fields) as $fieldname) { - $fieldname = trim($fieldname); - if (!isset($pconfig[$fieldname])) { - $pconfig[$fieldname] = null; - } - } - } -} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { - $a_phase1 = &config_read_array('ipsec', 'phase1'); - if (isset($_POST['p1index']) && is_numericint($_POST['p1index'])) { - $p1index = $_POST['p1index']; - } - $input_errors = array(); - $pconfig = $_POST; - $old_ph1ent = $a_phase1[$p1index]; - - // unset dpd on post - if (!isset($pconfig['dpd_enable'])) { - unset($pconfig['dpd_delay']); - unset($pconfig['dpd_maxfail']); - unset($pconfig['dpd_action']); - } - - /* My identity */ - if ($pconfig['myid_type'] == "myaddress") { - $pconfig['myid_data'] = ""; - } - /* Peer identity */ - if ($pconfig['myid_type'] == "peeraddress") { - $pconfig['peerid_data'] = ""; - } - - /* input validation */ - $method = $pconfig['authentication_method']; - - // Only require PSK here for normal PSK tunnels (not mobile) or xauth. - // For RSA methods, require the CA/Cert. - switch ($method) { - case "eap-tls": - case "psk_eap-tls": - case "eap-mschapv2": - case "rsa_eap-mschapv2": - case "eap-radius": - if (!in_array($pconfig['iketype'], array('ikev2', 'ike'))) { - $input_errors[] = sprintf(gettext("%s can only be used with IKEv2 type VPNs."), strtoupper($method)); - } - if ($method == 'eap-radius' && empty($pconfig['authservers'])) { - $input_errors[] = gettext("Please select radius servers to use."); - } - break; - case "pre_shared_key": - // If this is a mobile PSK tunnel the user PSKs go on - // the PSK tab, not here, so skip the check. - if ($pconfig['mobile']) { - break; - } - case "xauth_psk_server": - $reqdfields = explode(" ", "pre-shared-key"); - $reqdfieldsn = array(gettext("Pre-Shared Key")); - break; - case "hybrid_rsa_server": - $reqdfields = explode(' ', 'certref'); - $reqdfieldsn = array(gettext("Certificate")); - break; - case "xauth_rsa_server": - case "rsasig": - $reqdfields = explode(" ", "caref certref"); - $reqdfieldsn = array(gettext("Certificate Authority"),gettext("Certificate")); - break; - case "pubkey": - $reqdfields = explode(" ", "local-kpref peer-kpref"); - $reqdfieldsn = array(gettext("Local Key Pair"),gettext("Peer Key Pair")); - break; - } - - if (empty($pconfig['mobile'])) { - $reqdfields[] = "remote-gateway"; - $reqdfieldsn[] = gettext("Remote gateway"); - } - - do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); - - if (!empty($pconfig['inactivity_timeout']) && !is_numericint($pconfig['inactivity_timeout'])) { - $input_errors[] = gettext("The inactivity timeout must be an integer."); - } - if (!empty($pconfig['keyingtries']) && !is_numericint($pconfig['keyingtries']) && $pconfig['keyingtries'] != "-1") { - $input_errors[] = gettext("The keyingtries must be an integer."); - } - - if ((!empty($pconfig['lifetime']) && !is_numeric($pconfig['lifetime']))) { - $input_errors[] = gettext("The P1 lifetime must be an integer."); - } - if (!empty($pconfig['margintime'])) { - if (!is_numericint($pconfig['margintime'])) { - $input_errors[] = gettext("The margintime must be an integer."); - } else { - $rekeyfuzz = empty($pconfig['rekeyfuzz']) || !is_numeric($pconfig['rekeyfuzz']) ? 100 : $pconfig['rekeyfuzz']; - if (((int)$pconfig['margintime'] * 2) * ($rekeyfuzz / 100.0) > (int)$pconfig['lifetime']) { - $input_errors[] = gettext("The value margin... + margin... * rekeyfuzz must not exceed the original lifetime limit."); - } - } - } - if (!empty($pconfig['rekeyfuzz']) && !is_numericint($pconfig['rekeyfuzz'])) { - $input_errors[] = gettext("Rekeyfuzz must be an integer."); - } - - if (!empty($pconfig['remote-gateway'])) { - if (!is_ipaddr($pconfig['remote-gateway']) && !is_domain($pconfig['remote-gateway'])) { - $input_errors[] = gettext("A valid remote gateway address or host name must be specified."); - } elseif (is_ipaddrv4($pconfig['remote-gateway']) && ($pconfig['protocol'] != "inet")) { - $input_errors[] = gettext("A valid remote gateway IPv4 address must be specified or you need to change protocol to IPv6"); - } elseif (is_ipaddrv6($pconfig['remote-gateway']) && ($pconfig['protocol'] != "inet6")) { - $input_errors[] = gettext("A valid remote gateway IPv6 address must be specified or you need to change protocol to IPv4"); - } - } - - if (!empty($pconfig['remote-gateway']) && is_ipaddr($pconfig['remote-gateway']) && !isset($pconfig['disabled']) && - (empty($pconfig['iketype']) || $pconfig['iketype'] == "ikev1")) { - $t = 0; - foreach ($a_phase1 as $ph1tmp) { - if ($p1index != $t) { - if (isset($ph1tmp['remote-gateway']) && $ph1tmp['remote-gateway'] == $pconfig['remote-gateway'] && !isset($ph1tmp['disabled'])) { - $input_errors[] = sprintf(gettext('The remote gateway "%s" is already used by phase1 "%s".'), $pconfig['remote-gateway'], $ph1tmp['descr']); - } - } - $t++; - } - } - - if ($pconfig['interface'] == 'any' && $pconfig['myid_type'] == "myaddress") { - $input_errors[] = gettext("Please select an identifier (My Identifier) other then 'any' when selecting 'Any' interface"); - } elseif ($pconfig['myid_type'] == "address" && $pconfig['myid_data'] == "") { - $input_errors[] = gettext("Please enter an address for 'My Identifier'"); - } elseif ($pconfig['myid_type'] == "keyid tag" && $pconfig['myid_data'] == "") { - $input_errors[] = gettext("Please enter a keyid tag for 'My Identifier'"); - } elseif ($pconfig['myid_type'] == "fqdn" && $pconfig['myid_data'] == "") { - $input_errors[] = gettext("Please enter a fully qualified domain name for 'My Identifier'"); - } elseif ($pconfig['myid_type'] == "user_fqdn" && $pconfig['myid_data'] == "") { - $input_errors[] = gettext("Please enter a user and fully qualified domain name for 'My Identifier'"); - } elseif ($pconfig['myid_type'] == "dyn_dns" && $pconfig['myid_data'] == "") { - $input_errors[] = gettext("Please enter a dynamic domain name for 'My Identifier'"); - } elseif ((($pconfig['myid_type'] == "address") && !is_ipaddr($pconfig['myid_data']))) { - $input_errors[] = gettext("A valid IP address for 'My identifier' must be specified."); - } elseif ((($pconfig['myid_type'] == "fqdn") && !is_domain($pconfig['myid_data']))) { - $input_errors[] = gettext("A valid domain name for 'My identifier' must be specified."); - } elseif ($pconfig['myid_type'] == "fqdn" && !is_domain($pconfig['myid_data'])) { - $input_errors[] = gettext("A valid FQDN for 'My identifier' must be specified."); - } elseif ($pconfig['myid_type'] == "user_fqdn") { - $user_fqdn = explode("@", $pconfig['myid_data']); - if (is_domain($user_fqdn[1]) == false) { - $input_errors[] = gettext("A valid User FQDN in the form of user@my.domain.com for 'My identifier' must be specified."); - } - } elseif ($pconfig['myid_type'] == "dyn_dns") { - if (is_domain($pconfig['myid_data']) == false) { - $input_errors[] = gettext("A valid Dynamic DNS address for 'My identifier' must be specified."); - } - } - - // Only enforce peer ID if we are not dealing with a pure-psk mobile config. - if (!(($pconfig['authentication_method'] == "pre_shared_key") && !empty($pconfig['mobile']))) { - if ($pconfig['peerid_type'] == "address" and $pconfig['peerid_data'] == "") { - $input_errors[] = gettext("Please enter an address for 'Peer Identifier'"); - } - if ($pconfig['peerid_type'] == "keyid tag" and $pconfig['peerid_data'] == "") { - $input_errors[] = gettext("Please enter a keyid tag for 'Peer Identifier'"); - } - if ($pconfig['peerid_type'] == "fqdn" and $pconfig['peerid_data'] == "") { - $input_errors[] = gettext("Please enter a fully qualified domain name for 'Peer Identifier'"); - } - if ($pconfig['peerid_type'] == "user_fqdn" and $pconfig['peerid_data'] == "") { - $input_errors[] = gettext("Please enter a user and fully qualified domain name for 'Peer Identifier'"); - } - if ((($pconfig['peerid_type'] == "address") && !is_ipaddr($pconfig['peerid_data']))) { - $input_errors[] = gettext("A valid IP address for 'Peer identifier' must be specified."); - } - if ((($pconfig['peerid_type'] == "fqdn") && !is_domain($pconfig['peerid_data']))) { - $input_errors[] = gettext("A valid domain name for 'Peer identifier' must be specified."); - } - if ($pconfig['peerid_type'] == "fqdn") { - if (is_domain($pconfig['peerid_data']) == false) { - $input_errors[] = gettext("A valid FQDN for 'Peer identifier' must be specified."); - } - } - if ($pconfig['peerid_type'] == "user_fqdn") { - $user_fqdn = explode("@", $pconfig['peerid_data']); - if (is_domain($user_fqdn[1]) == false) { - $input_errors[] = gettext("A valid User FQDN in the form of user@my.domain.com for 'Peer identifier' must be specified."); - } - } - } - - if (!empty($pconfig['closeaction']) && !in_array($pconfig['closeaction'], ['clear', 'hold', 'restart'])) { - $input_errors[] = gettext('Invalid argument for close action.'); - } - - if (!empty($pconfig['unique']) && !in_array($pconfig['unique'], ['no', 'replace', 'never', 'keep'])) { - $input_errors[] = gettext('Invalid argument for unique.'); - } - - if (!empty($pconfig['dpd_enable'])) { - if (!is_numeric($pconfig['dpd_delay'])) { - $input_errors[] = gettext("A numeric value must be specified for DPD delay."); - } - if (!is_numeric($pconfig['dpd_maxfail'])) { - $input_errors[] = gettext("A numeric value must be specified for DPD retries."); - } - if (!empty($pconfig['dpd_action']) && !in_array($pconfig['dpd_action'], array("restart", "clear"))) { - $input_errors[] = gettext('Invalid argument for DPD action.'); - } - } - - if (!empty($pconfig['iketype']) && !in_array($pconfig['iketype'], array("ike", "ikev1", "ikev2"))) { - $input_errors[] = gettext('Invalid argument for key exchange protocol version.'); - } - - /* build our encryption algorithms array */ - if (!isset($pconfig['encryption-algorithm']) || !is_array($pconfig['encryption-algorithm'])) { - $pconfig['encryption-algorithm'] = array(); - } - $pconfig['encryption-algorithm']['name'] = $pconfig['ealgo']; - if (!empty($pconfig['ealgo_keylen'])) { - $pconfig['encryption-algorithm']['keylen'] = $pconfig['ealgo_keylen']; - } - - if (empty($pconfig['hash-algorithm'])) { - $input_errors[] = gettext("At least one hashing algorithm needs to be selected."); - $pconfig['hash-algorithm'] = array(); - } - - if (empty($pconfig['dhgroup'])) { - $pconfig['dhgroup'] = array(); - } - - foreach (ipsec_p1_ealgos() as $algo => $algodata) { - if (!empty($pconfig['iketype']) && !empty($pconfig['encryption-algorithm']['name']) && !empty($algodata['iketype']) - && $pconfig['iketype'] != $algodata['iketype'] && $pconfig['encryption-algorithm']['name'] == $algo) { - $input_errors[] = sprintf(gettext("%s can only be used with IKEv2 type VPNs."), $algodata['name']); - } - } - - if (!empty($pconfig['ikeid']) && !empty($pconfig['installpolicy'])) { - foreach ($config['ipsec']['phase2'] as $phase2ent) { - if ($phase2ent['ikeid'] == $pconfig['ikeid'] && $phase2ent['mode'] == 'route-based') { - $input_errors[] = gettext( - "Install policy on phase1 is not a valid option when using Route-based phase 2 entries." - ); - break; - } - } - } - - if (count($input_errors) == 0) { - $copy_fields = "ikeid,iketype,interface,mode,protocol,myid_type,myid_data - ,peerid_type,peerid_data,encryption-algorithm,margintime,rekeyfuzz,inactivity_timeout,keyingtries - ,lifetime,pre-shared-key,certref,caref,authentication_method,descr,local-kpref,peer-kpref - ,nat_traversal,auto,mobike,closeaction,unique"; - - foreach (explode(",",$copy_fields) as $fieldname) { - $fieldname = trim($fieldname); - if(!empty($pconfig[$fieldname])) { - $ph1ent[$fieldname] = $pconfig[$fieldname]; - } - } - - foreach (array('authservers', 'dhgroup', 'hash-algorithm') as $fieldname) { - if (!empty($pconfig[$fieldname])) { - $ph1ent[$fieldname] = implode(',', $pconfig[$fieldname]); - } - } - - $ph1ent['disabled'] = !empty($pconfig['disabled']); - $ph1ent['sha256_96'] = !empty($pconfig['sha256_96']); - $ph1ent['noinstallpolicy'] = empty($pconfig['installpolicy']); // XXX: reversed - $ph1ent['private-key'] =isset($pconfig['privatekey']) ? base64_encode($pconfig['privatekey']) : null; - if (!empty($pconfig['mobile'])) { - $ph1ent['mobile'] = true; - } else { - $ph1ent['remote-gateway'] = $pconfig['remote-gateway']; - } - if (isset($pconfig['reauth_enable'])) { - $ph1ent['reauth_enable'] = true; - } - if (isset($pconfig['rekey_enable'])) { - $ph1ent['rekey_enable'] = true; - } - - if (isset($pconfig['tunnel_isolation'])) { - $ph1ent['tunnel_isolation'] = true; - } - - if (isset($pconfig['rightallowany'])) { - $ph1ent['rightallowany'] = true; - } - - if (isset($pconfig['dpd_enable'])) { - $ph1ent['dpd_delay'] = $pconfig['dpd_delay']; - $ph1ent['dpd_maxfail'] = $pconfig['dpd_maxfail']; - $ph1ent['dpd_action'] = $pconfig['dpd_action']; - } - - /* generate unique phase1 ikeid */ - if ($ph1ent['ikeid'] == 0) { - $ph1ent['ikeid'] = ipsec_ikeid_next(); - } - - if (isset($p1index) && isset($a_phase1[$p1index])) { - $a_phase1[$p1index] = $ph1ent; - } else { - if (!empty($pconfig['clone_phase2']) && !empty($a_phase1[$_GET['dup']]) - && !empty($config['ipsec']['phase2'])) { - // clone phase 2 entries in disabled state if requested. - $prev_ike_id = $a_phase1[$_GET['dup']]['ikeid']; - foreach ($config['ipsec']['phase2'] as $phase2ent) { - if ($phase2ent['ikeid'] == $prev_ike_id) { - $new_phase2 = $phase2ent; - $new_phase2['disabled'] = true; - $new_phase2['uniqid'] = uniqid(); - $new_phase2['ikeid'] = $ph1ent['ikeid']; - unset($new_phase2['reqid']); - $config['ipsec']['phase2'][] = $new_phase2; - } - } - } - $a_phase1[] = $ph1ent; - } - - write_config(); - mark_subsystem_dirty('ipsec'); - - header(url_safe('Location: /ui/ipsec/tunnels')); - exit; - } -} - -$service_hook = 'strongswan'; - -legacy_html_escape_form_data($pconfig); -include("head.inc"); -?> - - - - - -
-
-
- 0) { - print_input_errors($input_errors); - } -?> - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- /> - -
- /> - - -
- - - -
- - - -
- - -
- - -
- - -
- /> - - -
- - -
 
- - -
- - -
- -
- -
-
- - - - - -
- " /> - -
- - -
- - -
- - -
- - -
- - -
- - - - -
- - -
- - -
- /> - -
- /> - -
- /> - -
- /> - -
- /> - -
- - -
- /> - -
- - -
- - -
- /> - -
-
- - - -
- - - -
- - - -
-
- - -
- - -
- - -
- - -
- - -
  - - - - - - - - -
-
-
-
-
-
-
-
- - - * Copyright (C) 2003-2005 Manuel Kasper - * 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_once("guiconfig.inc"); -require_once("interfaces.inc"); -require_once("plugins.inc.d/ipsec.inc"); - -/** - * combine ealgos and keylen_* tags - */ -function pconfig_to_ealgos($pconfig) -{ - $ealgos = []; - if (isset($pconfig['ealgos'])) { - foreach (ipsec_p2_ealgos() as $algo_name => $algo_data) { - if (in_array($algo_name, $pconfig['ealgos'])) { - $ealgos[] = ['name' => $algo_name]; - } - } - } - return $ealgos; -} - -function ealgos_to_pconfig(& $ealgos, & $pconfig) -{ - $p2_ealgos = ipsec_p2_ealgos(); - $pconfig['ealgos'] = []; - foreach ($ealgos as $cnf_algo_data) { - foreach ($p2_ealgos as $algo_name => $algo_data) { - if ($algo_name == $cnf_algo_data['name']) { - $pconfig['ealgos'][] = $algo_name; - } elseif ($algo_data['name'] == $cnf_algo_data['name']) { - // XXX: extract and convert legacy encryption-algorithm-option setting - if ($cnf_algo_data['keylen'] == $algo_data['keylen'] || $cnf_algo_data['keylen'] == "auto") { - $pconfig['ealgos'][] = $algo_name; - } - } - } - } - - return $ealgos; -} - -/** - * convert id_address, id_netbits, id_type - * to type/address/netbits structure - */ -function pconfig_to_idinfo($prefix, $pconfig) -{ - $type = isset($pconfig[$prefix."id_type"]) ? $pconfig[$prefix."id_type"] : null; - $address = isset($pconfig[$prefix."id_address"]) ? $pconfig[$prefix."id_address"] : null; - $netbits = isset($pconfig[$prefix."id_netbits"]) ? $pconfig[$prefix."id_netbits"] : null; - - 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 ); - } -} - -/** - * reverse pconfig_to_idinfo from $idinfo array to $pconfig - */ -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; - } -} - -/** - * search phase 2 entries for record with uniqid - */ -function getIndexByUniqueId($uniqid) -{ - global $config; - $p2index = null; - if ($uniqid != null) { - foreach ($config['ipsec']['phase2'] as $idx => $ph2) { - if ($ph2['uniqid'] == $uniqid) { - $p2index = $idx; - break; - } - } - } - return $p2index; -} - -config_read_array('ipsec', 'client'); -config_read_array('ipsec', 'phase2'); - -if ($_SERVER['REQUEST_METHOD'] === 'GET') { - // lookup p2index - if (!empty($_GET['dup'])) { - $p2index = getIndexByUniqueId($_GET['dup']); - } elseif (!empty($_GET['p2index'])) { - $p2index = getIndexByUniqueId($_GET['p2index']); - } else { - $p2index = null; - } - // initialize form data - $pconfig = array(); - - $phase2_fields = "ikeid,mode,descr,uniqid,proto,hash-algorithm-option,pfsgroup,lifetime,pinghost,protocol,spd,"; - $phase2_fields .= "tunnel_local,tunnel_remote"; - if ($p2index !== null) { - // 1-on-1 copy - foreach (explode(",", $phase2_fields) as $fieldname) { - $fieldname = trim($fieldname); - if (isset($config['ipsec']['phase2'][$p2index][$fieldname])) { - $pconfig[$fieldname] = $config['ipsec']['phase2'][$p2index][$fieldname]; - } elseif (!isset($pconfig[$fieldname])) { - // initialize element - $pconfig[$fieldname] = null; - } - } - // fields with some kind of logic - $pconfig['disabled'] = isset($config['ipsec']['phase2'][$p2index]['disabled']); - - idinfo_to_pconfig("local", $config['ipsec']['phase2'][$p2index]['localid'], $pconfig); - idinfo_to_pconfig("remote", $config['ipsec']['phase2'][$p2index]['remoteid'], $pconfig); - if (!empty($config['ipsec']['phase2'][$p2index]['encryption-algorithm-option'])) { - ealgos_to_pconfig($config['ipsec']['phase2'][$p2index]['encryption-algorithm-option'], $pconfig); - } else { - $pconfig['ealgos'] = []; - } - - if (!empty($_GET['dup'])) { - $pconfig['uniqid'] = uniqid(); - } - } else { - if (isset($_GET['ikeid'])) { - $pconfig['ikeid'] = $_GET['ikeid']; - } - /* defaults */ - $pconfig['localid_type'] = "lan"; - $pconfig['remoteid_type'] = "network"; - $pconfig['protocol'] = "esp"; - $pconfig['ealgos'] = ['aes256gcm16']; - $pconfig['hash-algorithm-option'] = ['hmac_sha256']; - $pconfig['pfsgroup'] = "0"; - $pconfig['uniqid'] = uniqid(); - - // init empty - foreach (explode(",", $phase2_fields) as $fieldname) { - $fieldname = trim($fieldname); - if (!isset($pconfig[$fieldname])) { - $pconfig[$fieldname] = null; - } - } - } - /* mobile client */ - foreach ($config['ipsec']['phase1'] as $phase1ent) { - if ($phase1ent['ikeid'] == $pconfig['ikeid'] && isset($phase1ent['mobile'])) { - $pconfig['mobile'] = true; - break; - } - } -} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { - if (!empty($_POST['uniqid'])) { - $p2index = getIndexByUniqueId($_POST['uniqid']); - } else { - $p2index = null; - } - $input_errors = array(); - $pconfig = $_POST; - - /* input validation */ - if (!isset($_POST['ikeid'])) { - $input_errors[] = gettext("A valid ikeid must be specified."); - } - $reqdfields = explode(" ", "localid_type uniqid"); - $reqdfieldsn = array(gettext("Local network type"), gettext("Unique Identifier")); - if (!isset($pconfig['mobile'])) { - $reqdfields[] = "remoteid_type"; - $reqdfieldsn[] = gettext("Remote network type"); - } - - do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); - - if (($pconfig['mode'] == 'tunnel') || ($pconfig['mode'] == 'tunnel6')) { - switch ($pconfig['localid_type']) { - case 'network': - if (($pconfig['localid_netbits'] != 0 && !$pconfig['localid_netbits']) || !is_numeric($pconfig['localid_netbits'])) { - $input_errors[] = gettext('A valid local network bit count must be specified.'); - } - /* FALLTHROUGH */ - case 'address': - if (!$pconfig['localid_address'] || !is_ipaddr($pconfig['localid_address'])) { - $input_errors[] = gettext('A valid local network IP address must be specified.'); - } elseif (is_ipaddrv4($pconfig['localid_address']) && ($pconfig['mode'] != 'tunnel')) { - $input_errors[] = gettext('A valid local network IPv4 address must be specified or you need to change Mode to IPv6'); - } elseif (is_ipaddrv6($pconfig['localid_address']) && ($pconfig['mode'] != 'tunnel6')) { - $input_errors[] = gettext('A valid local network IPv6 address must be specified or you need to change Mode to IPv4'); - } - break; - default: - if ($pconfig['mode'] == 'tunnel') { - list (, $subnet) = interfaces_primary_address($pconfig['localid_type']); - if (!is_subnetv4($subnet)) { - $input_errors[] = sprintf( - gettext('Invalid local network: %s has no valid IPv4 network.'), - convert_friendly_interface_to_friendly_descr($pconfig['localid_type']) - ); - } - } elseif ($pconfig['mode'] == 'tunnel6') { - list (, $subnet) = interfaces_primary_address6($pconfig['localid_type']); - if (!is_subnetv6($subnet)) { - $input_errors[] = sprintf( - gettext('Invalid local network: %s has no valid IPv6 network.'), - convert_friendly_interface_to_friendly_descr($pconfig['localid_type']) - ); - } - } - break; - } - - switch ($pconfig['remoteid_type']) { - case "network": - if (($pconfig['remoteid_netbits'] != 0 && !$pconfig['remoteid_netbits']) || !is_numeric($pconfig['remoteid_netbits'])) { - $input_errors[] = gettext("A valid remote network bit count must be specified."); - } - // address rules also apply to network type (hence, no break) - case "address": - if (!$pconfig['remoteid_address'] || !is_ipaddr($pconfig['remoteid_address'])) { - $input_errors[] = gettext("A valid remote network IP address must be specified."); - } elseif (is_ipaddrv4($pconfig['remoteid_address']) && ($pconfig['mode'] != "tunnel")) { - $input_errors[] = gettext("A valid remote network IPv4 address must be specified or you need to change Mode to IPv6"); - } elseif (is_ipaddrv6($pconfig['remoteid_address']) && ($pconfig['mode'] != "tunnel6")) { - $input_errors[] = gettext("A valid remote network IPv6 address must be specified or you need to change Mode to IPv4"); - } - break; - } - } elseif ($pconfig['mode'] == 'route-based') { - // validate if both tunnel networks are using the correct address family - if (!is_ipaddr($pconfig['tunnel_local']) || !is_ipaddr($pconfig['tunnel_remote'])) { - if (!is_ipaddr($pconfig['tunnel_local'])) { - $input_errors[] = gettext('A valid local network IP address must be specified.'); - } - if (!is_ipaddr($pconfig['tunnel_remote'])) { - $input_errors[] = gettext("A valid remote network IP address must be specified."); - } - } elseif( - !(is_ipaddrv4($pconfig['tunnel_local']) && is_ipaddrv4($pconfig['tunnel_remote'])) && - !(is_ipaddrv6($pconfig['tunnel_local']) && is_ipaddrv6($pconfig['tunnel_remote'])) - ) { - $input_errors[] = gettext("A valid local network IP address must be specified."); - $input_errors[] = gettext("A valid remote network IP address must be specified."); - } - } - /* Validate enabled phase2's are not duplicates */ - if (isset($pconfig['mobile'])) { - /* User is adding phase 2 for mobile phase1 */ - foreach ($config['ipsec']['phase2'] as $key => $name) { - if (isset($name['mobile']) && $pconfig['ikeid'] == $name['ikeid'] && $name['uniqid'] != $pconfig['uniqid']) { - /* check duplicate localids only for mobile clients */ - $localid_data = ipsec_idinfo_to_cidr($name['localid'], false, $name['mode']); - $entered = array(); - $entered['type'] = $pconfig['localid_type']; - if (isset($pconfig['localid_address'])) { - $entered['address'] = $pconfig['localid_address']; - } - if (isset($pconfig['localid_netbits'])) { - $entered['netbits'] = $pconfig['localid_netbits']; - } - $entered_localid_data = ipsec_idinfo_to_cidr($entered, false, $pconfig['mode']); - if ($localid_data == $entered_localid_data) { - /* adding new p2 entry */ - $input_errors[] = gettext("Phase2 with this Local Network is already defined for mobile clients."); - break; - } - } - } - } else { - /* User is adding phase 2 for site-to-site phase1 */ - foreach ($config['ipsec']['phase2'] as $key => $name) { - if (!isset($name['mobile']) && $pconfig['mode'] != 'route-based' && - $pconfig['ikeid'] == $name['ikeid'] && $pconfig['uniqid'] != $name['uniqid']) { - /* check duplicate subnets only for given phase1 */ - $localid_data = ipsec_idinfo_to_cidr($name['localid'], false, $name['mode']); - $remoteid_data = ipsec_idinfo_to_cidr($name['remoteid'], false, $name['mode']); - $entered_local = array(); - $entered_local['type'] = $pconfig['localid_type']; - if (isset($pconfig['localid_address'])) { - $entered_local['address'] = $pconfig['localid_address']; - } - if (isset($pconfig['localid_netbits'])) { - $entered_local['netbits'] = $pconfig['localid_netbits']; - } - $entered_localid_data = ipsec_idinfo_to_cidr($entered_local, false, $pconfig['mode']); - $entered_remote = array(); - $entered_remote['type'] = $pconfig['remoteid_type']; - if (isset($pconfig['remoteid_address'])) { - $entered_remote['address'] = $pconfig['remoteid_address']; - } - if (isset($pconfig['remoteid_netbits'])) { - $entered_remote['netbits'] = $pconfig['remoteid_netbits']; - } - $entered_remoteid_data = ipsec_idinfo_to_cidr($entered_remote, false, $pconfig['mode']); - if ($localid_data == $entered_localid_data && $remoteid_data == $entered_remoteid_data) { - /* adding new p2 entry */ - $input_errors[] = gettext("Phase2 with this Local/Remote networks combination is already defined for this Phase1."); - break; - } - } - } - } - - if (!empty($pconfig['ikeid'])) { - foreach ($config['ipsec']['phase1'] as $phase1ent) { - if ($phase1ent['ikeid'] == $pconfig['ikeid'] && - $pconfig['mode'] == 'route-based' && - empty($phase1ent['noinstallpolicy']) - ) { - $input_errors[] = gettext( - "Install policy on phase1 is not a valid option when using Route-based phase 2 entries." - ); - break; - } - } - } - - /* For ESP protocol, handle encryption algorithms */ - if ($pconfig['protocol'] == "esp") { - $ealgos = pconfig_to_ealgos($pconfig); - - if (!count($ealgos)) { - $input_errors[] = gettext("At least one encryption algorithm must be selected."); - } else { - if (empty($pconfig['hash-algorithm-option'])) { - foreach ($ealgos as $ealgo) { - if (!strpos($ealgo['name'], "gcm")) { - $input_errors[] = gettext("At least one hashing algorithm needs to be selected."); - break; - } - } - $pconfig['hash-algorithm-option'] = array(); - } - } - } - if ((!empty($_POST['lifetime']) && !is_numeric($_POST['lifetime']))) { - $input_errors[] = gettext("The P2 lifetime must be an integer."); - } - - if (!empty($pconfig['spd'])) { - foreach (explode(',', $pconfig['spd']) as $spd_entry) { - if (($pconfig['mode'] == "tunnel" && !is_subnetv4(trim($spd_entry))) || - ($pconfig['mode'] == "tunnel6" && !is_subnetv6(trim($spd_entry)))) { - $input_errors[] = sprintf(gettext('SPD "%s" is not a valid network, it should match the tunnel type (IPv4/IPv6).'), $spd_entry) ; - } - } - } - - if (count($input_errors) == 0) { - $ph2ent = array(); - $copy_fields = "ikeid,uniqid,mode,pfsgroup,lifetime,pinghost,descr,protocol,spd"; - - // 1-on-1 copy - foreach (explode(",", $copy_fields) as $fieldname) { - $fieldname = trim($fieldname); - if (!empty($pconfig[$fieldname])) { - $ph2ent[$fieldname] = $pconfig[$fieldname]; - } - } - - // fields with some logic in them - $ph2ent['disabled'] = $pconfig['disabled'] ? true : false; - if (($ph2ent['mode'] == "tunnel") || ($ph2ent['mode'] == "tunnel6")) { - $ph2ent['localid'] = pconfig_to_idinfo("local", $pconfig); - $ph2ent['remoteid'] = pconfig_to_idinfo("remote", $pconfig); - } elseif ($ph2ent['mode'] == 'route-based') { - $ph2ent['tunnel_local'] = $pconfig['tunnel_local']; - $ph2ent['tunnel_remote'] = $pconfig['tunnel_remote']; - } - - $ph2ent['encryption-algorithm-option'] = pconfig_to_ealgos($pconfig); - - if (!empty($pconfig['hash-algorithm-option'])) { - $ph2ent['hash-algorithm-option'] = $pconfig['hash-algorithm-option']; - } else { - unset($ph2ent['hash-algorithm-option']); - } - - // attach or generate reqid - if ($p2index !== null && !empty($config['ipsec']['phase2'][$p2index]['reqid'])) { - $ph2ent['reqid'] = $config['ipsec']['phase2'][$p2index]['reqid']; - } else { - $reqids = []; - foreach ($config['ipsec']['phase2'] as $tmp) { - if (!empty($tmp['reqid'])) { - $reqids[] = $tmp['reqid']; - } - } - for ($i=1; $i < 65535; $i++) { - if (!in_array($i, $reqids)) { - $ph2ent['reqid'] = $i; - break; - } - } - } - // save to config - if ($p2index !== null) { - $config['ipsec']['phase2'][$p2index] = $ph2ent; - } else { - $config['ipsec']['phase2'][] = $ph2ent; - } - - - write_config(); - mark_subsystem_dirty('ipsec'); - - header(url_safe('Location: /ui/ipsec/tunnels')); - exit; - } -} - -$service_hook = 'strongswan'; - -legacy_html_escape_form_data($pconfig); - -include("head.inc"); - -?> - - - - - - 0) { - print_input_errors($input_errors); -} -?> -
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- /> - -
- -
- - -
- -
- -
- -
   - - - - - -
- - - -
-
:   - -
:   - - - - - -
- - - -
-
- -
- -
- -
- -
- - -
- - - - - -
- - -
- - -
- -
- - -
- - -
  - - - - - - - -
-
-
-
-
-
-
-
- -