Commit cee1af97 authored by Franco Fichtner's avatar Franco Fichtner

vpn: merge nine IPsec changes from master

Same same, but different. (See previous commit for details.)

o Human-readable format of authentication method in overview
o Refine behaviour of enable / apply on main IPsec page
o Dedup leftsubnet/rightsubnet for meshed IKEv2
o More elegant interface and service plugging
o Tunnel isolation mode for IKEv2 (unmashed)
o Cleanup pass over backend code
o Allow Camellia for IKEv2
o Allow %any in phase 1
o Allow EAP-MSCHAPV2
parent efb06220
......@@ -1552,7 +1552,7 @@ function filter_nat_rules_generate(&$FilterIflist)
}
/* ipsec nat */
if (isset($config['ipsec']) && is_array($config['ipsec']) && isset($config['ipsec']['enable'])) {
if (isset($config['ipsec']['enable'])) {
if (isset($config['ipsec']['phase2'])) {
foreach ($config['ipsec']['phase2'] as $ph2ent) {
if ($ph2ent['mode'] != 'transport' && !empty($ph2ent['natlocalid']) && !isset($ph2ent['disabled'])) {
......@@ -2784,6 +2784,7 @@ pass in {$log['pass']} on \$loopback inet all label "pass IPv4 loopback"
pass out {$log['pass']} on \$loopback inet all label "pass IPv4 loopback"
pass in {$log['pass']} on \$loopback inet6 all label "pass IPv6 loopback"
pass out {$log['pass']} on \$loopback inet6 all label "pass IPv6 loopback"
# let out anything from the firewall host itself and decrypted IPsec traffic
pass out {$log['pass']} inet all keep state allow-opts label "let out anything IPv4 from firewall host itself"
pass out {$log['pass']} inet6 all keep state allow-opts label "let out anything IPv6 from firewall host itself"
......@@ -2821,10 +2822,9 @@ EOD;
}
}
/* add ipsec interfaces */
if (isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) {
$ipfrules .= "pass out {$log['pass']} on \$IPsec all keep state label \"IPsec internal host to host\"\n";
if (!empty($FilterIflist['enc0']['descr'])) {
$ipfrules .= "pass out {$log['pass']} on \${$FilterIflist['enc0']['descr']} all keep state label \"IPsec internal host to host\"\n";
}
if (is_array($config['system']['webgui']) && !isset($config['system']['webgui']['noantilockout'])) {
......@@ -2836,6 +2836,7 @@ EOD;
*/
$lanif = $FilterIflist['lan']['if'];
$ipfrules .= <<<EOD
# make sure the user cannot lock himself out of the webConfigurator or SSH
pass in {$log['pass']} quick on {$lanif} proto tcp from any to ({$lanif}) port { {$alports} } keep state label "anti-lockout rule"
......@@ -2844,6 +2845,7 @@ EOD;
/* single-interface deployment, add to WAN */
$wanif = $FilterIflist["wan"]['if'];
$ipfrules .= <<<EOD
# make sure the user cannot lock himself out of the webConfigurator or SSH
pass in {$log['pass']} quick on {$wanif} proto tcp from any to ({$wanif}) port { {$alports} } keep state label "anti-lockout rule"
......@@ -3189,10 +3191,8 @@ function filter_generate_ipsec_rules(&$FilterIflist, $log = array())
return "\n# VPN Rules not added disabled in System->Advanced.\n";
}
$ipfrules = "\n# VPN Rules\n";
if (isset($config['ipsec']['enable']) &&
is_array($config['ipsec']['phase1'])) {
if (isset($config['ipsec']['enable']) && isset($config['ipsec']['phase1'])) {
/* step through all phase1 entries */
foreach ($config['ipsec']['phase1'] as $ph1ent) {
if (isset ($ph1ent['disabled'])) {
......
......@@ -29,7 +29,6 @@
POSSIBILITY OF SUCH DAMAGE.
*/
/* IPsec defines */
$ipsec_loglevels = array("dmn" => "Daemon", "mgr" => "SA Manager", "ike" => "IKE SA", "chd" => "IKE Child SA",
"job" => "Job Processing", "cfg" => "Configuration backend", "knl" => "Kernel Interface",
"net" => "Networking", "asn" => "ASN encoding", "enc" => "Message encoding",
......@@ -38,11 +37,22 @@ $ipsec_loglevels = array("dmn" => "Daemon", "mgr" => "SA Manager", "ike" => "IKE
);
$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' => 64 ) ),
'3des' => array( 'name' => '3DES' ),
'cast128' => array( 'name' => 'CAST128' ),
'des' => array( 'name' => 'DES' )
'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ), 'iketype' => null ),
'camellia' => array( 'name' => 'Camellia', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ), 'iketype' => 'ikev2' ),
'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ), 'iketype' => null ),
'3des' => array( 'name' => '3DES', 'iketype' => null ),
'cast128' => array( 'name' => 'CAST128', 'iketype' => null ),
'des' => array( 'name' => 'DES', 'iketype' => null )
);
$p1_authentication_methods = array(
'hybrid_rsa_server' => array( 'name' => 'Hybrid RSA + Xauth', 'mobile' => true ),
'xauth_rsa_server' => array( 'name' => 'Mutual RSA + Xauth', 'mobile' => true ),
'xauth_psk_server' => array( 'name' => 'Mutual PSK + Xauth', 'mobile' => true ),
'eap-tls' => array( 'name' => 'EAP-TLS', 'mobile' => true),
'eap-mschapv2' => array( 'name' => 'EAP-MSCHAPV2', 'mobile' => true),
'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ),
);
$p2_ealgos = array(
......@@ -63,7 +73,6 @@ $p2_halgos = array(
'aesxcbc' => 'AES-XCBC'
);
$p2_protos = array(
'esp' => 'ESP',
'ah' => 'AH'
......@@ -84,9 +93,12 @@ $p2_pfskeygroups = array(
/*
* Return phase1 local address
*/
function ipsec_get_phase1_src(& $ph1ent) {
function ipsec_get_phase1_src(&$ph1ent)
{
if (!empty($ph1ent['interface'])) {
if (!is_ipaddr($ph1ent['interface'])) {
if ($ph1ent['interface'] == 'any') {
return '%any';
} elseif (!is_ipaddr($ph1ent['interface'])) {
if (strpos($ph1ent['interface'],'_vip') !== false) {
// if this is a vip, set the interface to $ph1ent['interface']
$if = $ph1ent['interface'];
......@@ -112,11 +124,11 @@ function ipsec_get_phase1_src(& $ph1ent) {
}
}
/*
* Return phase2 idinfo in cidr format
*/
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
function ipsec_idinfo_to_cidr(&$idinfo, $addrbits = false, $mode = '')
{
global $config;
switch ($idinfo['type']) {
......@@ -158,7 +170,6 @@ function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
}
}
/*
* Return phase1 association for phase2
*/
......@@ -189,7 +200,8 @@ function ipsec_lookup_phase1(&$ph2ent, &$ph1ent)
/*
* Check phase1 communications status
*/
function ipsec_phase1_status($ipsec_status, $ikeid) {
function ipsec_phase1_status($ipsec_status, $ikeid)
{
foreach ($ipsec_status as $ike) {
if ($ike['id'] != $ikeid) {
continue;
......@@ -312,7 +324,8 @@ function ipsec_dump_sad()
return $sad;
}
function ipsec_mobilekey_sort() {
function ipsec_mobilekey_sort()
{
global $config;
function mobilekeycmp($a, $b) {
......@@ -322,7 +335,8 @@ function ipsec_mobilekey_sort() {
usort($config['ipsec']['mobilekey'], "mobilekeycmp");
}
function ipsec_get_number_of_phase2($ikeid) {
function ipsec_get_number_of_phase2($ikeid)
{
global $config;
$a_phase2 = $config['ipsec']['phase2'];
$nbph2=0;
......@@ -336,62 +350,39 @@ function ipsec_get_number_of_phase2($ikeid) {
return $nbph2;
}
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
function ipsec_find_id(&$ph1ent, $side = 'local', $rgmap = array())
{
$id_data = null;
if ($side == "local") {
$id_type = $ph1ent['myid_type'];
if (isset($ph1ent['myid_data'])) {
$id_data = $ph1ent['myid_data'];
}
$addr = ipsec_get_phase1_src($ph1ent);
if (!$addr) {
return array();
}
$id_data = isset($ph1ent['myid_data']) ? $ph1ent['myid_data'] : null;
} elseif ($side == "peer") {
$id_type = $ph1ent['peerid_type'];
if (isset($ph1ent['peerid_data'])) {
$id_data = $ph1ent['peerid_data'];
}
$id_data = isset($ph1ent['peerid_data']) ? $ph1ent['peerid_data'] : null;
/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
if (isset($ph1ent['mobile'])) {
$addr = "%any";
} else {
$addr = $ph1ent['remote-gateway'];
return null;
}
} else {
return array();
}
$thisid_type = $id_type;
switch ($thisid_type) {
switch ($id_type) {
case "myaddress":
$thisid_type = "address";
$thisid_data = $addr;
$thisid_data = ipsec_get_phase1_src($ph1ent);
break;
case "dyn_dns":
$thisid_type = "address";
$thisid_data = resolve_retry($id_data);
break;
case "peeraddress":
$thisid_type = "address";
$thisid_data = $rgmap[$ph1ent['remote-gateway']];
break;
case "address";
case "address":
$thisid_data = $id_data;
break;
case "fqdn";
case "keyid tag";
case "user_fqdn";
case "asn1dn";
$thisid_data = $id_data;
if( $thisid_data ) {
$thisid_data = "{$thisid_data}";
}
default:
$thisid_data = !empty($id_data) ? "{$id_data}" : null;
break;
}
return array($thisid_type, $thisid_data);
return $thisid_data;
}
/* include all configuration functions */
......@@ -448,7 +439,7 @@ function ipsec_configure()
$a_phase1 = isset($config['ipsec']['phase1']) ? $config['ipsec']['phase1'] : array();
$a_phase2 = isset($config['ipsec']['phase2']) ? $config['ipsec']['phase2'] : array();
$a_client = isset($config['ipsec']['client']) ? $config['ipsec']['client'] : array();
$aggressive_psk = false ; // if one of the phase 1 entries has aggressive/psk combination, this will be set true
$aggressive_psk = false; // if one of the phase 1 entries has aggressive/psk combination, this will be set true
if (!isset($ipseccfg['enable'])) {
/* try to stop charon */
......@@ -491,7 +482,6 @@ function ipsec_configure()
set_single_sysctl("net.inet.ip.fastforwarding", "0");
/* resolve all local, peer addresses and setup pings */
$ipmap = array();
$rgmap = array();
$filterdns_list = array();
$ipsecpinghosts = "";
......@@ -505,14 +495,6 @@ function ipsec_configure()
$aggressive_psk = true;
}
$ep = ipsec_get_phase1_src($ph1ent);
if (!is_ipaddr($ep)) {
continue;
}
if(!in_array($ep,$ipmap)) {
$ipmap[] = $ep;
}
/* 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 filterdns */
......@@ -532,7 +514,7 @@ function ipsec_configure()
continue;
}
}
if(array_search($rg, $rgmap)) {
if (array_search($rg, $rgmap)) {
log_error("The remote gateway {$rg} already exists on another phase 1 entry");
continue;
}
......@@ -797,18 +779,13 @@ EOD;
/* XXX" Traffic selectors? */
$pskconf .= " : RSA {$ph1keyfile}\n";
} else {
list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
if (empty($peerid_data)) {
continue;
}
} elseif (!empty($ph1ent['pre-shared-key'])) {
$myid_data = ipsec_find_id($ph1ent, "local");
$peerid_data = ipsec_find_id($ph1ent, "peer", $rgmap);
$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
if (!empty($ph1ent['pre-shared-key'])) {
$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
if (!empty($peerid_data)) {
$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
$pskconf .= $myid . trim($peerid_data) . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
}
}
}
......@@ -826,9 +803,6 @@ EOD;
/* add PSKs for mobile clients */
if (isset($ipseccfg['mobilekey'])) {
foreach ($ipseccfg['mobilekey'] as $key) {
if ($key['ident'] == "allusers") {
$key['ident'] = '';
}
$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
}
unset($key);
......@@ -850,7 +824,7 @@ EOD;
foreach ($ipsec_loglevels as $lkey => $ldescr) {
if (isset($config['ipsec']["ipsec_{$lkey}"]) && is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
intval($config['ipsec']["ipsec_{$lkey}"]) >= 1 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 5) {
$cfg_loglevels[] = "${lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) ;
$cfg_loglevels[] = "${lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1);
}
}
}
......@@ -891,14 +865,8 @@ EOD;
$conn_auto = 'route';
}
list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
$peerid_spec = '';
if (!isset($ph1ent['mobile'])) {
$peerid_spec = $peerid_data;
}
$myid_data = ipsec_find_id($ph1ent, "local");
$peerid_spec = ipsec_find_id($ph1ent, "peer", $rgmap);
if (!empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
$ealg_id = $ph1ent['encryption-algorithm']['name'];
......@@ -943,6 +911,10 @@ EOD;
case 'eap-tls':
$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
break;
case 'eap-mschapv2':
$authentication = "leftauth = pubkey\n\trightauth = eap-mschapv2";
$authentication .= "\n\teap_identity=%any";
break;
case 'xauth_rsa_server':
$authentication = "leftauth = pubkey\n\trightauth = pubkey";
$authentication .= "\n\trightauth2 = xauth-generic";
......@@ -989,7 +961,7 @@ EOD;
$rekey = "rekey = yes";
}
$forceencaps = 'forceencaps = no' ;
$forceencaps = 'forceencaps = no';
if (!empty($ph1ent['nat_traversal']) && $ph1ent['nat_traversal'] == 'force') {
$forceencaps = 'forceencaps = yes';
}
......@@ -1000,7 +972,6 @@ EOD;
$ealgoAHsp2arr = array();
$ealgoESPsp2arr = array();
if (count($a_phase2)) {
foreach ($a_phase2 as $ph2ent) {
if ($ph1ent['ikeid'] != $ph2ent['ikeid'] || isset($ph2ent['disabled'])) {
......@@ -1154,7 +1125,6 @@ conn con<<connectionId>>
installpolicy = yes
{$tunneltype}
{$dpdline}
auto = {$conn_auto}
left = {$left_spec}
right = {$right_spec}
leftid = {$myid_data}
......@@ -1181,14 +1151,14 @@ EOD;
// append ipsec connections
if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
// ikev1 not mobile
for ($idx = 0 ; $idx < count($leftsubnet_spec) ; ++$idx) {
for ($idx = 0; $idx < count($leftsubnet_spec); ++$idx) {
if (count($leftsubnet_spec) == 1) {
$tmpconf = str_replace('<<connectionId>>', "{$ph1ent['ikeid']}", $connEntry);
$tmpconf = str_replace('<<connectionId>>', "{$ph1ent['ikeid']}", $connEntry);
} else {
// suffix connection with sequence number
$tmpconf = str_replace('<<connectionId>>', "{$ph1ent['ikeid']}-00{$idx}", $connEntry);
$tmpconf = str_replace('<<connectionId>>', sprintf('%s-%03d', $ph1ent['ikeid'], $idx), $connEntry);
}
$tmpconf .= "\trightsubnet =" . $rightsubnet_spec[$idx]. "\n" ;
$tmpconf .= "\trightsubnet = " . $rightsubnet_spec[$idx]. "\n";
$tmpconf .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
if (!empty($ealgoESPsp2arr[$idx])) {
$tmpconf .= "\tesp = " . join(',', $ealgoESPsp2arr[$idx]) . "!\n";
......@@ -1196,42 +1166,69 @@ EOD;
if (!empty($ealgoAHsp2arr[$idx])) {
$tmpconf .= "\tah = " . join(',', $ealgoAHsp2arr[$idx]) . "!\n";
}
$tmpconf .= "\tauto = {$conn_auto}\n";
$ipsecconf .= $tmpconf;
}
} else {
// mobile and ikev2
$tmpconf = str_replace('<<connectionId>>', "{$ph1ent['ikeid']}", $connEntry);
if (!empty($rightsubnet_spec)) {
$tmpconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
}
if (!empty($leftsubnet_spec)) {
$tmpconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
}
// merge esp phase 2 arrays.
$esp_content = array();
foreach ($ealgoESPsp2arr as $ealgoESPsp2arr_details) {
foreach ($ealgoESPsp2arr_details as $esp_item) {
if (!in_array($esp_item, $esp_content)) {
$esp_content[] = $esp_item;
if (isset($ph1ent['tunnel_isolation'])) {
$ipsecconf .= str_replace('<<connectionId>>', "{$ph1ent['ikeid']}-000", $connEntry);
for ($idx = 0; $idx < count($leftsubnet_spec); ++$idx) {
// requires leading empty line:
$tmpconf = array('');
// fix for strongSwan to pick up the correct connection
// name from the first configured tunnel ($idx == 0):
$conn_suffix = $idx ? sprintf('-%03d', $idx) : '';
$tmpconf[] = "conn con{$ph1ent['ikeid']}{$conn_suffix}";
$tmpconf[] = "\trightsubnet = {$rightsubnet_spec[$idx]}";
$tmpconf[] = "\tleftsubnet = {$leftsubnet_spec[$idx]}";
if (!empty($ealgoESPsp2arr[$idx])) {
$tmpconf[] = "\tesp = " . join(',', $ealgoESPsp2arr[$idx]) . '!';
}
if (!empty($ealgoAHsp2arr[$idx])) {
$tmpconf[] = "\tah = " . join(',', $ealgoAHsp2arr[$idx]) . '!';
}
$tmpconf[] = "\talso = con{$ph1ent['ikeid']}-000";
$tmpconf[] = "\tauto = {$conn_auto}";
// requires trailing empty line:
$tmpconf[] = '';
$ipsecconf .= join("\n", $tmpconf);
}
}
// merge ah phase 2 arrays.
$ah_content = array();
foreach ($ealgoAHsp2arr as $ealgoAHsp2arr_details) {
foreach ($ealgoAHsp2arr_details as $ah_item) {
if (!in_array($ah_item, $ah_content)) {
$ah_content[] = $ah_item;
} else {
$tmpconf = str_replace('<<connectionId>>', "{$ph1ent['ikeid']}", $connEntry);
if (!empty($rightsubnet_spec)) {
$tmpconf .= "\trightsubnet = " . join(',', array_unique($rightsubnet_spec)) . "\n";
}
if (!empty($leftsubnet_spec)) {
$tmpconf .= "\tleftsubnet = " . join(',', array_unique($leftsubnet_spec)) . "\n";
}
// merge esp phase 2 arrays.
$esp_content = array();
foreach ($ealgoESPsp2arr as $ealgoESPsp2arr_details) {
foreach ($ealgoESPsp2arr_details as $esp_item) {
if (!in_array($esp_item, $esp_content)) {
$esp_content[] = $esp_item;
}
}
}
// merge ah phase 2 arrays.
$ah_content = array();
foreach ($ealgoAHsp2arr as $ealgoAHsp2arr_details) {
foreach ($ealgoAHsp2arr_details as $ah_item) {
if (!in_array($ah_item, $ah_content)) {
$ah_content[] = $ah_item;
}
}
}
if (!empty($esp_content)) {
$tmpconf .= "\tesp = " . join(',', $esp_content) . "!\n";
}
if (!empty($ah_content)) {
$tmpconf .= "\tah = " . join(',', $ah_content) . "!\n";
}
$tmpconf .= "\tauto = {$conn_auto}\n";
$ipsecconf .= $tmpconf;
}
if (!empty($esp_content)) {
$tmpconf .= "\tesp = " . join(',', $esp_content) . "!\n";
}
if (!empty($ah_content)) {
$tmpconf .= "\tah = " . join(',', $ah_content) . "!\n";
}
$ipsecconf .= $tmpconf;
}
}
}
......
......@@ -44,7 +44,7 @@ function if_ipsec_services()
$services = array();
if (isset($config['ipsec']['enable'])) {
if (isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) {
$pconfig = array();
$pconfig['name'] = 'ipsec';
$pconfig['description'] = gettext('IPsec VPN');
......@@ -64,15 +64,33 @@ function if_ipsec_interfaces()
$interfaces = array();
/* add ipsec interfaces */
if (isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) {
$oic = array("enable" => true);
$oic['if'] = 'enc0';
$oic['descr'] = 'IPsec';
$oic['type'] = "none";
$oic['virtual'] = true;
$oic['networks'] = array();
$interfaces['enc0'] = $oic;
if (isset($config['ipsec']['phase1']) && isset($config['ipsec']['phase2'])) {
foreach ($config['ipsec']['phase1'] as $ph1ent) {
if (isset($ph1ent['disabled'])) {
continue;
}
foreach ($config['ipsec']['phase2'] as $ph2ent) {
if (isset($ph2ent['disabled']) || $ph1ent['ikeid'] != $ph2ent['ikeid']) {
continue;
}
if ((isset($ph2ent['mobile']) && !isset($config['ipsec']['client']['enable'])) ||
!isset($config['ipsec']['enable'])) {
continue;
}
$oic = array('enable' => true);
$oic['if'] = 'enc0';
$oic['descr'] = 'IPsec';
$oic['type'] = 'none';
$oic['virtual'] = true;
$oic['networks'] = array();
$interfaces['enc0'] = $oic;
break 2;
}
}
}
return $interfaces;
......
......@@ -79,14 +79,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$a_phase2 = &$config['ipsec']['phase2'];
if (isset($_POST['apply'])) {
ipsec_configure();
/* reload the filter in the background */
filter_configure();
$savemsg = get_std_save_message();
clear_subsystem_dirty('ipsec');
} elseif (isset($_POST['save'])) {
$config['ipsec']['enable'] = !empty($_POST['enable']) ? true : false;
if (!empty($_POST['enable'])) {
$config['ipsec']['enable'] = true;
} elseif (isset($config['ipsec']['enable'])) {
unset($config['ipsec']['enable']);
}
write_config();
ipsec_configure();
filter_configure();
clear_subsystem_dirty('ipsec');
header("Location: vpn_ipsec.php");
exit;
} elseif (!empty($_POST['act']) && $_POST['act'] == "delphase1" ) {
......@@ -311,7 +316,7 @@ $( document ).ready(function() {
if (isset($savemsg)) {
print_info_box($savemsg);
}
if ($pconfig['enable'] && is_subsystem_dirty('ipsec')) {
if (is_subsystem_dirty('ipsec')) {
print_info_box_apply(gettext("The IPsec tunnel configuration has been changed.") . "<br />" . gettext("You must apply the changes in order for them to take effect."));
}?>
<section class="col-xs-12">
......@@ -423,7 +428,7 @@ $( document ).ready(function() {
<?=gettext("DH Group"); ?>&nbsp;<?=$p1_dhgroups[$ph1ent['dhgroup']];?>
</td>
<td class="hidden-xs">
<?=str_replace('_', ' ', $ph1ent['authentication_method']);?>
<?= html_safe($p1_authentication_methods[$ph1ent['authentication_method']]['name']) ?>
</td>
<td>
<?=$ph1ent['descr'];?>&nbsp;
......
......@@ -132,14 +132,13 @@ if (is_subsystem_dirty('ipsec')) {
foreach ($config['system']['user'] as $id => $user) {
if (!empty($user['ipsecpsk'])) {
$userkeys[] = array('ident' => $user['name'], 'pre-shared-key' => $user['ipsecpsk'], 'id' => $id);
;
}
}
foreach ($userkeys as $secretent) :
?>
<tr>
<td>
<?=$secretent['ident'] == 'allusers' ? gettext("ANY USER") : htmlspecialchars($secretent['ident']) ;?>
<?=htmlspecialchars($secretent['ident']) ;?>
</td>
<td>
<?=htmlspecialchars($secretent['pre-shared-key']);?>
......
......@@ -172,7 +172,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
write_config();
mark_subsystem_dirty('ipsec');
header(url_safe('Location: vpn_ipsec_mobile.php'));
exit;
}
......
......@@ -87,7 +87,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$phase1_fields = "mode,protocol,myid_type,myid_data,peerid_type,peerid_data
,encryption-algorithm,hash-algorithm,dhgroup,lifetime,authentication_method,descr,nat_traversal
,interface,iketype,dpd_delay,dpd_maxfail,remote-gateway,pre-shared-key,certref
,caref,reauth_enable,rekey_enable, auto";
,caref,reauth_enable,rekey_enable,auto,tunnel_isolation";
if (isset($p1index) && isset($config['ipsec']['phase1'][$p1index])) {
// 1-on-1 copy
foreach (explode(",", $phase1_fields) as $fieldname) {
......@@ -178,6 +178,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// For RSA methods, require the CA/Cert.
switch ($method) {
case "eap-tls":
case "eap-mschapv2":
if ($pconfig['iketype'] != 'ikev2') {
$input_errors[] = sprintf(gettext("%s can only be used with IKEv2 type VPNs."), strtoupper($method));
}
......@@ -199,6 +200,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$reqdfieldsn = array(gettext("Certificate Authority"),gettext("Certificate"));
break;
}
if (empty($pconfig['mobile'])) {
$reqdfields[] = "remote-gateway";
$reqdfieldsn[] = gettext("Remote gateway");
......@@ -247,48 +249,30 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
}
if ($pconfig['myid_type'] == "address" and $pconfig['myid_data'] == "") {
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'");
}
if ($pconfig['myid_type'] == "keyid tag" and $pconfig['myid_data'] == "") {
} elseif ($pconfig['myid_type'] == "keyid tag" && $pconfig['myid_data'] == "") {
$input_errors[] = gettext("Please enter a keyid tag for 'My Identifier'");
}
if ($pconfig['myid_type'] == "fqdn" and $pconfig['myid_data'] == "") {
} elseif ($pconfig['myid_type'] == "fqdn" && $pconfig['myid_data'] == "") {
$input_errors[] = gettext("Please enter a fully qualified domain name for 'My Identifier'");
}
if ($pconfig['myid_type'] == "user_fqdn" and $pconfig['myid_data'] == "") {
} elseif ($pconfig['myid_type'] == "user_fqdn" && $pconfig['myid_data'] == "") {
$input_errors[] = gettext("Please enter a user and fully qualified domain name for 'My Identifier'");
}
if ($pconfig['myid_type'] == "dyn_dns" and $pconfig['myid_data'] == "") {
} elseif ($pconfig['myid_type'] == "dyn_dns" && $pconfig['myid_data'] == "") {
$input_errors[] = gettext("Please enter a dynamic domain name for 'My Identifier'");
}
if ((($pconfig['myid_type'] == "address") && !is_ipaddr($pconfig['myid_data']))) {
} elseif ((($pconfig['myid_type'] == "address") && !is_ipaddr($pconfig['myid_data']))) {
$input_errors[] = gettext("A valid IP address for 'My identifier' must be specified.");
}
if ((($pconfig['myid_type'] == "fqdn") && !is_domain($pconfig['myid_data']))) {
} elseif ((($pconfig['myid_type'] == "fqdn") && !is_domain($pconfig['myid_data']))) {
$input_errors[] = gettext("A valid domain name for 'My identifier' must be specified.");
}
if ($pconfig['myid_type'] == "fqdn") {
if (is_domain($pconfig['myid_data']) == false) {
$input_errors[] = gettext("A valid FQDN for 'My identifier' must be specified.");
}
}
if ($pconfig['myid_type'] == "user_fqdn") {
} 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.");
}
}
if ($pconfig['myid_type'] == "dyn_dns") {
} 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.");
}
......@@ -349,6 +333,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$pconfig['encryption-algorithm']['keylen'] = $pconfig['ealgo_keylen'];
}
foreach ($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 (count($input_errors) == 0) {
$copy_fields = "ikeid,iketype,interface,mode,protocol,myid_type,myid_data
,peerid_type,peerid_data,encryption-algorithm,hash-algorithm,dhgroup
......@@ -376,6 +367,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$ph1ent['rekey_enable'] = true;
}
if (isset($pconfig['tunnel_isolation'])) {
$ph1ent['tunnel_isolation'] = true;
}
if (isset($pconfig['dpd_enable'])) {
$ph1ent['dpd_delay'] = $pconfig['dpd_delay'];
$ph1ent['dpd_maxfail'] = $pconfig['dpd_maxfail'];
......@@ -402,7 +397,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
write_config();
mark_subsystem_dirty('ipsec');
header("Location: vpn_ipsec.php");
exit;
}
......@@ -448,6 +442,7 @@ include("head.inc");
case 'hybrid_rsa_server':
case 'xauth_rsa_server':
case 'rsasig':
case 'eap-mschapv2':
$(".auth_eap_tls").show();
$(".auth_eap_tls :input").prop( "disabled", false );
$(".auth_eap_tls_caref").show();
......@@ -620,6 +615,9 @@ include("head.inc");
</option>
<?php endforeach;
?>
<option value="any" <?= $pconfig['interface'] == "any" ? "selected=\"selected\"" : "" ?>>
<?=gettext("Any");?>
</option>
</select>
<div class="hidden" for="help_for_interface">
<?=gettext("Select the interface for the local endpoint of this phase1 entry."); ?>
......@@ -661,13 +659,6 @@ include("head.inc");
<td>
<select name="authentication_method" id="authentication_method" class="formselect">
<?php
$p1_authentication_methods = array(
'hybrid_rsa_server' => array( 'name' => 'Hybrid RSA + Xauth', 'mobile' => true ),
'xauth_rsa_server' => array( 'name' => 'Mutual RSA + Xauth', 'mobile' => true ),
'xauth_psk_server' => array( 'name' => 'Mutual PSK + Xauth', 'mobile' => true ),
'eap-tls' => array( 'name' => 'EAP-TLS', 'mobile' => true),
'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) );
foreach ($p1_authentication_methods as $method_type => $method_params) :
if (empty($pconfig['mobile']) && $method_params['mobile']) {
continue;
......@@ -731,6 +722,8 @@ endforeach; ?>
</div>
</td>
</tr>
<?php
if (empty($pconfig['mobile'])):?>
<tr class="auth_opt auth_eap_tls auth_psk">
<td ><i class="fa fa-info-circle text-muted"></i> <?=gettext("Peer identifier"); ?></td>
<td>
......@@ -762,6 +755,8 @@ endforeach; ?>
} ?>
</td>
</tr>
<?php
endif;?>
<tr class="auth_opt auth_psk">
<td ><a id="help_for_psk" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Pre-Shared Key"); ?></td>
<td>
......@@ -928,6 +923,15 @@ endforeach; ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_tunnel_isolation" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Tunnel Isolation') ?></td>
<td>
<input name="tunnel_isolation" type="checkbox" id="tunnel_isolation" value="yes" <?= !empty($pconfig['tunnel_isolation']) ? 'checked="checked"' : '' ?>/>
<div class="hidden" for="help_for_tunnel_isolation">
<?= gettext('This option will create a tunnel for each phase 2 entry for IKEv2 interoperability with e.g. FortiGate devices.') ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_nat_traversal" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("NAT Traversal"); ?></td>
<td>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment