diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 9d93ad2ab..63559950d 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -1183,7 +1183,7 @@ function interfaces_configure() system_routing_configure(); /* reload IPsec tunnels */ - vpn_ipsec_configure(); + ipsec_configure(); /* reload dhcpd (interface enabled/disabled status may have changed) */ services_dhcpd_configure(); @@ -3164,7 +3164,7 @@ function interface_configure($interface = 'wan', $reloadall = false, $linkupeven system_routing_configure($interface); /* reload ipsec tunnels */ - vpn_ipsec_configure(); + ipsec_configure(); /* restart dnsmasq or unbound */ if (isset($config['dnsmasq']['enable'])) { diff --git a/src/etc/inc/ipsec.inc b/src/etc/inc/ipsec.inc index 3ad24d69e..50631a195 100644 --- a/src/etc/inc/ipsec.inc +++ b/src/etc/inc/ipsec.inc @@ -1,8 +1,9 @@ + +/* include all configuration functions */ +function ipsec_convert_to_modp($index) +{ + $convertion = ""; + switch ($index) { + case '1': + $convertion = "modp768"; + break; + case '2': + $convertion = "modp1024"; + break; + case '5': + $convertion = "modp1536"; + break; + case '14': + $convertion = "modp2048"; + break; + case '15': + $convertion = "modp3072"; + break; + case '16': + $convertion = "modp4096"; + break; + case '17': + $convertion = "modp6144"; + break; + case '18': + $convertion = "modp8192"; + break; + } + + return $convertion; +} + +function ipsec_configure() +{ + global $config, $p2_ealgos, $ipsec_loglevels; + + /* get the automatic ping_hosts.sh ready */ + @unlink('/var/db/ipsecpinghosts'); + touch('/var/db/ipsecpinghosts'); + + // Prefer older IPsec SAs (advanced setting) + if (isset($config['ipsec']['preferoldsa'])) { + set_single_sysctl("net.key.preferred_oldsa", "-30"); + } else { + set_single_sysctl("net.key.preferred_oldsa", "0"); + } + + $syscfg = $config['system']; + $ipseccfg = $config['ipsec']; + $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 + + if (!isset($ipseccfg['enable'])) { + /* try to stop charon */ + mwexec('/usr/local/sbin/ipsec stop'); + /* Stop dynamic monitoring */ + killbypid('/var/run/filterdns-ipsec.pid'); + + /* wait for process to die */ + sleep(2); + + /* disallow IPSEC, it is off */ + mwexec("/sbin/ifconfig enc0 down"); + set_single_sysctl("net.inet.ip.ipsec_in_use", "0"); + + return 0; + } else { + $certpath = "/usr/local/etc/ipsec.d/certs"; + $capath = "/usr/local/etc/ipsec.d/cacerts"; + $keypath = "/usr/local/etc/ipsec.d/private"; + + mwexec("/sbin/ifconfig enc0 up"); + set_single_sysctl("net.inet.ip.ipsec_in_use", "1"); + + /* needed directories for config files */ + @mkdir($capath); + @mkdir($keypath); + @mkdir($certpath); + @mkdir('/usr/local/etc/ipsec.d'); + @mkdir('/usr/local/etc/ipsec.d/crls'); + @mkdir('/usr/local/etc/ipsec.d/aacerts'); + @mkdir('/usr/local/etc/ipsec.d/acerts'); + @mkdir('/usr/local/etc/ipsec.d/ocspcerts'); + @mkdir('/usr/local/etc/ipsec.d/reqs'); + + if (file_exists("/var/run/booting")) { + echo gettext("Configuring IPsec VPN... "); + } + + /* fastforwarding is not compatible with ipsec tunnels */ + set_single_sysctl("net.inet.ip.fastforwarding", "0"); + + /* resolve all local, peer addresses and setup pings */ + $ipmap = array(); + $rgmap = array(); + $filterdns_list = array(); + $ipsecpinghosts = ""; + /* step through each phase1 entry */ + foreach ($a_phase1 as $ph1ent) { + if (isset($ph1ent['disabled'])) { + continue; + } + + if ($ph1ent['mode'] == "aggressive" && in_array($ph1ent['authentication_method'], array("pre_shared_key", "xauth_psk_server"))) { + $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 */ + + if (isset ($ph1ent['mobile'])) { + continue; + } + + $rg = $ph1ent['remote-gateway']; + + if (!is_ipaddr($rg)) { + $filterdns_list[] = "{$rg}"; + add_hostname_to_watch($rg); + if(! file_exists("/var/run/booting")) { + $rg = resolve_retry($rg); + } + if (!is_ipaddr($rg)) { + continue; + } + } + if(array_search($rg, $rgmap)) { + log_error("The remote gateway {$rg} already exists on another phase 1 entry"); + continue; + } + $rgmap[$ph1ent['remote-gateway']] = $rg; + + /* step through each phase2 entry */ + foreach ($a_phase2 as $ph2ent) { + if (isset($ph2ent['disabled'])) { + continue; + } + + if ($ph1ent['ikeid'] != $ph2ent['ikeid']) { + continue; + } + + /* add an ipsec pinghosts entry */ + if ($ph2ent['pinghost']) { + if (!isset($iflist) || !is_array($iflist)) { + $iflist = get_configured_interface_list(); + } + $viplist = get_configured_vips_list(); + $srcip = null; + $local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']); + if(is_ipaddrv6($ph2ent['pinghost'])) { + foreach ($iflist as $ifent => $ifname) { + $interface_ip = get_interface_ipv6($ifent); + if (!is_ipaddrv6($interface_ip)) { + continue; + } + if (ip_in_subnet($interface_ip, $local_subnet)) { + $srcip = $interface_ip; + break; + } + } + } else { + foreach ($iflist as $ifent => $ifname) { + $interface_ip = get_interface_ip($ifent); + if (!is_ipaddrv4($interface_ip)) { + continue; + } + if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) { + $srcip = $interface_ip; + break; + } + } + } + /* if no valid src IP was found in configured interfaces, try the vips */ + if (is_null($srcip)) { + foreach ($viplist as $vip) { + if (ip_in_subnet($vip['ipaddr'], $local_subnet)) { + $srcip = $vip['ipaddr']; + break; + } + } + } + $dstip = $ph2ent['pinghost']; + if(is_ipaddrv6($dstip)) { + $family = "inet6"; + } else { + $family = "inet"; + } + if (is_ipaddr($srcip)) { + $ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n"; + } + } + } + } + @file_put_contents('/var/db/ipsecpinghosts', $ipsecpinghosts); + + $cnf_add_to_charon_section = ""; + $cnf_add_to_charon_section .= $aggressive_psk ? "\ti_dont_care_about_security_and_use_aggressive_mode_psk=yes\n":""; + if (isset($a_client['enable']) && isset($a_client['net_list'])) { + $cnf_add_to_charon_section .= "\tcisco_unity = yes\n"; + } + + $strongswan = << 0) { + $strongswan .= ","; + } + if ($authcfg == "system") { + $authcfg = "Local Database"; + } + $strongswan .= $authcfg; + $firstsed = 1; + } + $strongswan .= "\n"; + $strongswan .= "\t}\n"; + } + } + + $strongswan .= "\t}\n}\n"; + @file_put_contents("/usr/local/etc/strongswan.conf", $strongswan); + unset($strongswan); + + /* generate CA certificates files */ + if (isset($config['ca'])) { + foreach ($config['ca'] as $ca) { + if (!isset($ca['crt'])) { + log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr'])); + continue; + } + $cert = base64_decode($ca['crt']); + $x509cert = openssl_x509_parse(openssl_x509_read($cert)); + if (!is_array($x509cert) || !isset($x509cert['hash'])) { + log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr'])); + continue; + } + $fname = "{$capath}/{$x509cert['hash']}.0.crt"; + if (!@file_put_contents($fname, $cert)) { + log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr'])); + continue; + } + unset($cert); + } + } + + $pskconf = ""; + + foreach ($a_phase1 as $ph1ent) { + if (isset($ph1ent['disabled'])) { + continue; + } + + if (!empty($ph1ent['certref'])) { + $cert = lookup_cert($ph1ent['certref']); + + if (empty($cert)) { + log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name'])); + continue; + } + + @chmod($certpath, 0600); + + $ph1keyfile = "{$keypath}/cert-{$ph1ent['ikeid']}.key"; + if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) { + log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name'])); + continue; + } + @chmod($ph1keyfile, 0600); + + $ph1certfile = "{$certpath}/cert-{$ph1ent['ikeid']}.crt"; + if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) { + log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name'])); + @unlink($ph1keyfile); + continue; + } + @chmod($ph1certfile, 0600); + + /* 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; + } + + $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"; + } + } + } + + /* Add user PSKs */ + if (isset($config['system']['user']) && is_array($config['system']['user'])) { + foreach ($config['system']['user'] as $user) { + if (!empty($user['ipsecpsk'])) { + $pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n"; + } + } + unset($user); + } + + /* 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); + } + + @file_put_contents("/usr/local/etc/ipsec.secrets", $pskconf); + chmod("/usr/local/etc/ipsec.secrets", 0600); + unset($pskconf); + + $natfilterrules = false; + /* begin ipsec.conf */ + $ipsecconf = ""; + if (count($a_phase1)) { + $ipsecconf .= "# This file is automatically generated. Do not edit\n"; + $ipsecconf .= "config setup\n\tuniqueids = yes\n"; + // parse debug tags + $cfg_loglevels = array(); + if (isset($ipsec_loglevels)) { + 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) ; + } + } + } + $ipsecconf .= "\tcharondebug=\"" .implode(',', $cfg_loglevels) . "\"\n"; + + foreach ($a_phase1 as $ph1ent) { + if (isset($ph1ent['disabled'])) { + continue; + } + + if ($ph1ent['mode'] == "aggressive") { + $aggressive = "yes"; + } else { + $aggressive = "no"; + } + + $ep = ipsec_get_phase1_src($ph1ent); + if (empty($ep)) { + continue; + } + + $keyexchange = "ikev1"; + if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") { + $keyexchange = "ikev2"; + } + + if (isset($ph1ent['mobile'])) { + $right_spec = "%any"; + } else { + $right_spec = $ph1ent['remote-gateway']; + } + + if (!empty($ph1ent['auto'])) { + $conn_auto = $ph1ent['auto']; + } elseif (isset($ph1ent['mobile'])) { + $conn_auto = 'add'; + } else { + $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; + } + + if (!empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) { + $ealg_id = $ph1ent['encryption-algorithm']['name']; + if (isset($ph1ent['encryption-algorithm']['keylen'])){ + $ealgosp1 = "ike = {$ealg_id}{$ph1ent['encryption-algorithm']['keylen']}-{$ph1ent['hash-algorithm']}"; + } else { + $ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}"; + } + $modp = ipsec_convert_to_modp($ph1ent['dhgroup']); + if (!empty($modp)) { + $ealgosp1 .= "-{$modp}"; + } + $ealgosp1 .= "!"; + } + + if (!empty($ph1ent['dpd_delay']) && !empty($ph1ent['dpd_maxfail'])) { + if ($conn_auto == "route") { + $dpdline = "dpdaction = restart"; + } else { + $dpdline = "dpdaction = clear"; + } + $dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s"; + $dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1); + $dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s"; + } else { + $dpdline = "dpdaction = none"; + } + + if (!empty($ph1ent['lifetime'])) { + $ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s"; + } else { + $ikelifeline = ''; + } + + $rightsourceip = NULL; + if (!empty($a_client['pool_address']) && isset($ph1ent['mobile']) ) { + $rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n"; + } + + $authentication = ""; + switch ($ph1ent['authentication_method']) { + case 'eap-tls': + $authentication = "leftauth=eap-tls\n\trightauth=eap-tls"; + break; + case 'xauth_rsa_server': + $authentication = "leftauth = pubkey\n\trightauth = pubkey"; + $authentication .= "\n\trightauth2 = xauth-generic"; + break; + case 'xauth_psk_server': + $authentication = "leftauth = psk\n\trightauth = psk"; + $authentication .= "\n\trightauth2 = xauth-generic"; + break; + case 'pre_shared_key': + $authentication = "leftauth = psk\n\trightauth = psk"; + break; + case 'rsasig': + $authentication = "leftauth = pubkey\n\trightauth = pubkey"; + break; + case 'hybrid_rsa_server': + $authentication = "leftauth = xauth-generic\n\trightauth = pubkey"; + $authentication .= "\n\trightauth2 = xauth"; + break; + } + if (!empty($ph1ent['certref'])) { + $authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt"; + } + if (!empty($ph1ent['caref'])) { + $ca = lookup_ca($ph1ent['caref']);; + if (!empty($ca)) { + $rightca = ""; + foreach (cert_get_subject_array($ca['crt']) as $ca_field) { + $rightca .= "{$ca_field['a']}={$ca_field['v']}/"; + } + $authentication .= "\n\trightca=\"/$rightca\""; + } + } + $left_spec = $ep; + + if (isset($ph1ent['reauth_enable'])) { + $reauth = "reauth = no"; + } else { + $reauth = "reauth = yes"; + } + + if (isset($ph1ent['rekey_enable'])) { + $rekey = "rekey = no"; + } else { + $rekey = "rekey = yes"; + } + + $forceencaps = 'forceencaps = no' ; + if (!empty($ph1ent['nat_traversal']) && $ph1ent['nat_traversal'] == 'force') { + $forceencaps = 'forceencaps = yes'; + } + + $ipseclifetime = 0; + $rightsubnet_spec = array(); + $leftsubnet_spec = array(); + $ealgoAHsp2arr = array(); + $ealgoESPsp2arr = array(); + + + if (count($a_phase2)) { + foreach ($a_phase2 as $ph2ent) { + if ($ph1ent['ikeid'] != $ph2ent['ikeid'] || isset($ph2ent['disabled'])) { + continue; + } + if (isset($ph2ent['mobile']) && !isset($a_client['enable'])){ + continue; + } + + if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) { + $tunneltype = "type = tunnel"; + $localid_type = $ph2ent['localid']['type']; + $leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']); + /* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */ + if (($localid_type == "none" || $localid_type == "mobile") + && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ph1ent['ikeid'])==1)) { + $left_spec = '%any'; + } else { + if ($localid_type != "address") { + $localid_type = "subnet"; + } + // Don't let an empty subnet into config, it can cause parse errors. Ticket #2201. + if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) { + log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet."); + continue; + } + if (!empty($ph2ent['natlocalid'])) { + $natfilterrules = true; + } + } + + $leftsubnet_spec[] = $leftsubnet_data; + + if (!isset($ph2ent['mobile'])) { + $tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']); + $rightsubnet_spec[] = $tmpsubnet; + } else if (!empty($a_client['pool_address'])) { + $rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}"; + } + } else { + $tunneltype = "type = transport"; + if ((($ph1ent['authentication_method'] == "xauth_psk_server") || + ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) { + $left_spec = "%any"; + } else { + $tmpsubnet = ipsec_get_phase1_src($ph1ent); + $leftsubnet_spec[] = $tmpsubnet; + } + if (!isset($ph2ent['mobile'])) { + $rightsubnet_spec[] = $right_spec; + } + } + if (isset($a_client['pfs_group'])) { + $ph2ent['pfsgroup'] = $a_client['pfs_group']; + } + if (isset($ph2ent['protocol']) && $ph2ent['protocol'] == 'esp') { + $ealgoESPsp2arr_details = array(); + if (is_array($ph2ent['encryption-algorithm-option'])) { + foreach ($ph2ent['encryption-algorithm-option'] as $ealg) { + $ealg_id = $ealg['name']; + if (isset($ealg['keylen'])) { + $ealg_kl = $ealg['keylen']; + } else { + $ealg_kl = null; + } + + 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']; + /* XXX: in some cases where include ordering is suspect these variables + * are somehow 0 and we enter this loop forever and timeout after 900 + * seconds wrecking bootup */ + if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) { + for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) { + if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) { + foreach ($ph2ent['hash-algorithm-option'] as $halgo) { + $halgo = str_replace('hmac_', '', $halgo); + $tmpealgo = "{$ealg_id}{$keylen}-{$halgo}"; + $modp = ipsec_convert_to_modp($ph2ent['pfsgroup']); + if (!empty($modp)) { + $tmpealgo .= "-{$modp}"; + } + $ealgoESPsp2arr_details[] = $tmpealgo; + } + } else { + $tmpealgo = "{$ealg_id}{$keylen}"; + $modp = ipsec_convert_to_modp($ph2ent['pfsgroup']); + if (!empty($modp)) { + $tmpealgo .= "-{$modp}"; + } + $ealgoESPsp2arr_details[] = $tmpealgo; + } + } + } + } else { + if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) { + foreach ($ph2ent['hash-algorithm-option'] as $halgo) { + $halgo = str_replace('hmac_', '', $halgo); + $tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}"; + $modp = ipsec_convert_to_modp($ph2ent['pfsgroup']); + if (!empty($modp)) { + $tmpealgo .= "-{$modp}"; + } + $ealgoESPsp2arr_details[] = $tmpealgo; + } + } else { + $tmpealgo = "{$ealg_id}{$ealg_kl}"; + $modp = ipsec_convert_to_modp($ph2ent['pfsgroup']); + if (!empty($modp)) { + $tmpealgo .= "-{$modp}"; + } + $ealgoESPsp2arr_details[] = $tmpealgo; + } + } + } + } + $ealgoESPsp2arr[] = $ealgoESPsp2arr_details; + } else if (isset($ph2ent['protocol']) && $ph2ent['protocol'] == 'ah') { + $ealgoAHsp2arr_details = array(); + if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) { + $modp = ipsec_convert_to_modp($ph2ent['pfsgroup']); + foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) { + $tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo); + if (!empty($modp)) { + $tmpAHalgo = "-{$modp}"; + } + $ealgoAHsp2arr_details[] = $tmpAHalgo; + } + } + $ealgoAHsp2arr[] = $ealgoAHsp2arr_details; + } + + if (!empty($ph2ent['lifetime'])) { + if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) { + $ipseclifetime = intval($ph2ent['lifetime']); + } + } + } + } + + $connEntry =<<> + aggressive = {$aggressive} + fragmentation = yes + keyexchange = {$keyexchange} + {$reauth} + {$rekey} + {$forceencaps} + installpolicy = yes + {$tunneltype} + {$dpdline} + auto = {$conn_auto} + left = {$left_spec} + right = {$right_spec} + leftid = {$myid_data} + {$ikelifeline} + +EOD; + + if ($ipseclifetime > 0) { + $connEntry .= "\tlifetime = {$ipseclifetime}s\n"; + } + if (!empty($rightsourceip)) { + $connEntry .= "{$rightsourceip}"; + } + if (!empty($ealgosp1)) { + $connEntry .= "\t{$ealgosp1}\n"; + } + if (!empty($authentication)) { + $connEntry .= "\t{$authentication}\n"; + } + if (!empty($peerid_spec)) { + $connEntry .= "\trightid = {$peerid_spec}\n"; + } + + // append ipsec connections + if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') { + // ikev1 not mobile + for ($idx = 0 ; $idx < count($leftsubnet_spec) ; ++$idx) { + if (count($leftsubnet_spec) == 1) { + $tmpconf = str_replace('<>', "{$ph1ent['ikeid']}", $connEntry); + } else { + // suffix connection with sequence number + $tmpconf = str_replace('<>', "{$ph1ent['ikeid']}-00{$idx}", $connEntry); + } + $tmpconf .= "\trightsubnet =" . $rightsubnet_spec[$idx]. "\n" ; + $tmpconf .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n"; + if (!empty($ealgoESPsp2arr[$idx])) { + $tmpconf .= "\tesp = " . join(',', $ealgoESPsp2arr[$idx]) . "!\n"; + } + if (!empty($ealgoAHsp2arr[$idx])) { + $connEntry .= "\tah = " . join(',', $ealgoAHsp2arr[$idx]) . "!\n"; + } + $ipsecconf .= $tmpconf; + } + } else { + // mobile and ikev2 + $tmpconf = str_replace('<>', "{$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; + } + } + } + // 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"; + } + $ipsecconf .= $tmpconf; + } + } + } + } + // dump file, replace tabs for 2 spaces + @file_put_contents("/usr/local/etc/ipsec.conf", str_replace("\t",' ', $ipsecconf)); + unset($ipsecconf); + /* end ipsec.conf */ + + /* mange process */ + if (isvalidpid('/var/run/charon.pid')) { + /* Read secrets */ + mwexec('/usr/local/sbin/ipsec rereadall', false); + /* Update configuration changes */ + mwexec('/usr/local/sbin/ipsec reload', false); + } else { + mwexec("/usr/local/sbin/ipsec start", false); + } + + if ($natfilterrules == true) { + filter_configure(); + } + + /* start filterdns, if necessary */ + if (count($filterdns_list) > 0) { + $interval = 60; + if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) { + $interval = $ipseccfg['dns-interval']; + } + + $hostnames = ""; + array_unique($filterdns_list); + foreach ($filterdns_list as $hostname) { + $hostnames .= "cmd {$hostname} '/usr/local/opnsense/service/configd_ctl.py ipsecdns reload'\n"; + } + file_put_contents("/usr/local/etc/filterdns-ipsec.hosts", $hostnames); + unset($hostnames); + + if (isvalidpid('/var/run/filterdns-ipsec.pid')) { + killbypid('/var/run/filterdns-ipsec.pid', 'HUP'); + } else { + mwexec("/usr/local/sbin/filterdns -p /var/run/filterdns-ipsec.pid -i {$interval} -c /usr/local/etc/filterdns-ipsec.hosts -d 1"); + } + } else { + killbypid('/var/run/filterdns-ipsec.pid'); + } + + if (file_exists("/var/run/booting")) { + echo "done\n"; + } + + return count($filterdns_list); +} + +/* + * Forcefully restart IPsec + * This is required for when dynamic interfaces reload + * For all other occasions the normal ipsec_configure() + * will gracefully reload the settings without restarting + */ +function ipsec_force_reload($interface = '') +{ + global $config; + + $ipseccfg = $config['ipsec']; + + if (!empty($interface) && isset($ipseccfg['phase1']) && is_array($ipseccfg['phase1'])) { + $found = false; + foreach ($ipseccfg['phase1'] as $ipsec) { + if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) { + $found = true; + break; + } + } + if (!$found) { + log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface)); + return; + } + } + + /* if ipsec is enabled, start up again */ + if (isset($ipseccfg['enable'])) { + log_error(gettext("Forcefully reloading IPsec")); + ipsec_configure(); + } +} diff --git a/src/etc/inc/plugins.inc b/src/etc/inc/plugins.inc new file mode 100644 index 000000000..48505c3aa --- /dev/null +++ b/src/etc/inc/plugins.inc @@ -0,0 +1,82 @@ + + * 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. + */ + +function plugin_scan() +{ + $path = '/usr/local/etc/inc/plugins.inc.d/'; + $ext = '.inc'; + + $ret = array(); + + $plugins = glob($path . '*' . $ext); + if (!is_array($plugins)) { + return $ret; + } + + sort($plugins); + + foreach ($plugins as $plugin) { + $name = preg_replace('/' . preg_quote($path, '/') . '/', '', $plugin); + $name = preg_replace('/' . preg_quote($ext, '/') . '/', '', $name); + $ret[$name] = $plugin; + } + + return $ret; +} + +function plugins_services() +{ + $services = array(); + + foreach (plugin_scan() as $name => $path) { + require_once $path; + $func = sprintf('%s_services', $name); + if (function_exists($func)) { + $workers = $func(); + foreach ($workers as $work) { + $services[] = $work; + } + } + } + + return $services; +} + +function plugins_configure() +{ + foreach (plugin_scan() as $name => $path) { + require_once $path; + $func = sprintf('%s_configure', $name); + if (function_exists($func)) { + $workers = $func(); + foreach ($workers as $worker) { + $worker(); + } + } + } +} diff --git a/src/etc/inc/plugins.inc.d/vpn.inc b/src/etc/inc/plugins.inc.d/vpn.inc new file mode 100644 index 000000000..557b0c145 --- /dev/null +++ b/src/etc/inc/plugins.inc.d/vpn.inc @@ -0,0 +1,765 @@ + + * Copyright (C) 2008 Shrew Soft Inc + * Copyright (C) 2008 Ermal Luçi + * Copyright (C) 2004 Scott Ullrich + * Copyright (C) 2003-2004 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. + */ + +function vpn_configure() +{ + return array( + 'vpn_pptpd_configure', + 'vpn_pppoes_configure', + 'vpn_l2tp_configure' + ); +} + +function vpn_services() +{ + global $config; + + $services = array(); + + if (isset($config['pptpd']['mode']) && $config['pptpd']['mode'] != 'off') { + $services[] = array( + 'description' => gettext('PPTP Server'), + 'pidfile' => '/var/run/pptp-vpn.pid', + 'php' => array( + 'restart' => array('vpn_pptpd_configure'), + 'start' => array('vpn_pptpd_configure'), + ), + 'name' => 'pptpd', + ); + } + + if (isset($config['l2tp']['mode']) && $config['l2tp']['mode'] != 'off') { + $services[] = array( + 'description' => gettext('L2TP Server'), + 'pidfile' => '/var/run/l2tp-vpn.pid', + 'php' => array( + 'restart' => array('vpn_l2tp_configure'), + 'start' => array('vpn_l2tp_configure'), + ), + 'name' => 'l2tpd', + ); + } + + if (isset($config['pppoes']['pppoe'])) { + foreach ($config['pppoes']['pppoe'] as $pppoecfg) { + if (isset($pppoecfg['mode']) || $pppoecfg['mode'] != 'off') { + $services[] = array( + 'description' => gettext('PPPoE Server') . ': ' . htmlspecialchars($pppoecfg['descr']), + 'php' => array( + 'restart' => array('vpn_pppoe_configure_by_id'), + 'start' => array('vpn_pppoe_configure_by_id'), + 'args' => array('pppoeid'), + ), + 'pidfile' => "/var/run/pppoe{$pppoecfg['pppoeid']}-vpn.pid", + 'pppoeid' => $pppoecfg['pppoeid'], + 'name' => 'pppoed', + ); + } + } + } + + return $services; +} + +function vpn_netgraph_support() { + $iflist = get_configured_interface_list(); + foreach ($iflist as $iface) { + $realif = get_real_interface($iface); + /* Get support for netgraph(4) from the nic */ + $ifinfo = pfSense_get_interface_addresses($realif); + if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) { + pfSense_ngctl_attach(".", $realif); + } + } +} + +function vpn_pptpd_configure() { + global $config; + + $syscfg = $config['system']; + $pptpdcfg = $config['pptpd']; + + if (file_exists("/var/run/booting")) { + if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) + return 0; + + echo gettext("Configuring PPTP VPN service... "); + } else { + /* kill mpd */ + killbypid('/var/run/pptp-vpn.pid'); + + /* wait for process to die */ + sleep(3); + + if (is_process_running("mpd -b")) { + killbypid('/var/run/pptp-vpn.pid'); + log_error(gettext("Could not kill mpd within 3 seconds. Trying again.")); + } + + /* remove mpd.conf, if it exists */ + @unlink('/var/etc/pptp-vpn/mpd.conf'); + @unlink('/var/etc/pptp-vpn/mpd.links'); + @unlink('/var/etc/pptp-vpn/mpd.secret'); + } + + if (empty($pptpdcfg['n_pptp_units'])) { + log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise."); + return; + } + + /* make sure pptp-vpn directory exists */ + @mkdir('/var/etc/pptp-vpn'); + + switch ($pptpdcfg['mode']) { + case 'server' : + /* write mpd.conf */ + $fd = fopen('/var/etc/pptp-vpn/mpd.conf', 'w'); + if (!$fd) { + printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n"); + return 1; + } + + $mpdconf = << 1) ? $pptpdcfg['radius']['server']['port'] : 1812; + $acctport = $authport + 1; + $mpdconf .=<< 1) ? $pptpdcfg['radius']['server2']['port'] : 1812; + $acctport = $authport + 1; + $mpdconf .=<< 'configd', ); + if (function_exists('plugins_services')) { + /* only pull plugins if plugins.inc was included before */ + foreach (plugins_services() as $service) { + $services[] = $service; + } + } + return $services; } diff --git a/src/etc/inc/vpn.inc b/src/etc/inc/vpn.inc deleted file mode 100644 index 3729d264a..000000000 --- a/src/etc/inc/vpn.inc +++ /dev/null @@ -1,1618 +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("ipsec.inc"); - - -/* include all configuration functions */ -function vpn_ipsec_convert_to_modp($index) -{ - $convertion = ""; - switch ($index) { - case '1': - $convertion = "modp768"; - break; - case '2': - $convertion = "modp1024"; - break; - case '5': - $convertion = "modp1536"; - break; - case '14': - $convertion = "modp2048"; - break; - case '15': - $convertion = "modp3072"; - break; - case '16': - $convertion = "modp4096"; - break; - case '17': - $convertion = "modp6144"; - break; - case '18': - $convertion = "modp8192"; - break; - } - - return $convertion; -} - -function vpn_ipsec_configure() -{ - global $config, $p2_ealgos, $ipsec_loglevels; - - /* get the automatic ping_hosts.sh ready */ - @unlink('/var/db/ipsecpinghosts'); - touch('/var/db/ipsecpinghosts'); - - // Prefer older IPsec SAs (advanced setting) - if (isset($config['ipsec']['preferoldsa'])) { - set_single_sysctl("net.key.preferred_oldsa", "-30"); - } else { - set_single_sysctl("net.key.preferred_oldsa", "0"); - } - - $syscfg = $config['system']; - $ipseccfg = $config['ipsec']; - $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 - - if (!isset($ipseccfg['enable'])) { - /* try to stop charon */ - mwexec('/usr/local/sbin/ipsec stop'); - /* Stop dynamic monitoring */ - killbypid('/var/run/filterdns-ipsec.pid'); - - /* wait for process to die */ - sleep(2); - - /* disallow IPSEC, it is off */ - mwexec("/sbin/ifconfig enc0 down"); - set_single_sysctl("net.inet.ip.ipsec_in_use", "0"); - - return 0; - } else { - $certpath = "/usr/local/etc/ipsec.d/certs"; - $capath = "/usr/local/etc/ipsec.d/cacerts"; - $keypath = "/usr/local/etc/ipsec.d/private"; - - mwexec("/sbin/ifconfig enc0 up"); - set_single_sysctl("net.inet.ip.ipsec_in_use", "1"); - - /* needed directories for config files */ - @mkdir($capath); - @mkdir($keypath); - @mkdir($certpath); - @mkdir('/usr/local/etc/ipsec.d'); - @mkdir('/usr/local/etc/ipsec.d/crls'); - @mkdir('/usr/local/etc/ipsec.d/aacerts'); - @mkdir('/usr/local/etc/ipsec.d/acerts'); - @mkdir('/usr/local/etc/ipsec.d/ocspcerts'); - @mkdir('/usr/local/etc/ipsec.d/reqs'); - - if (file_exists("/var/run/booting")) { - echo gettext("Configuring IPsec VPN... "); - } - - /* fastforwarding is not compatible with ipsec tunnels */ - set_single_sysctl("net.inet.ip.fastforwarding", "0"); - - /* resolve all local, peer addresses and setup pings */ - $ipmap = array(); - $rgmap = array(); - $filterdns_list = array(); - $ipsecpinghosts = ""; - /* step through each phase1 entry */ - foreach ($a_phase1 as $ph1ent) { - if (isset($ph1ent['disabled'])) { - continue; - } - - if ($ph1ent['mode'] == "aggressive" && in_array($ph1ent['authentication_method'], array("pre_shared_key", "xauth_psk_server"))) { - $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 */ - - if (isset ($ph1ent['mobile'])) { - continue; - } - - $rg = $ph1ent['remote-gateway']; - - if (!is_ipaddr($rg)) { - $filterdns_list[] = "{$rg}"; - add_hostname_to_watch($rg); - if(! file_exists("/var/run/booting")) { - $rg = resolve_retry($rg); - } - if (!is_ipaddr($rg)) { - continue; - } - } - if(array_search($rg, $rgmap)) { - log_error("The remote gateway {$rg} already exists on another phase 1 entry"); - continue; - } - $rgmap[$ph1ent['remote-gateway']] = $rg; - - /* step through each phase2 entry */ - foreach ($a_phase2 as $ph2ent) { - if (isset($ph2ent['disabled'])) { - continue; - } - - if ($ph1ent['ikeid'] != $ph2ent['ikeid']) { - continue; - } - - /* add an ipsec pinghosts entry */ - if ($ph2ent['pinghost']) { - if (!isset($iflist) || !is_array($iflist)) { - $iflist = get_configured_interface_list(); - } - $viplist = get_configured_vips_list(); - $srcip = null; - $local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']); - if(is_ipaddrv6($ph2ent['pinghost'])) { - foreach ($iflist as $ifent => $ifname) { - $interface_ip = get_interface_ipv6($ifent); - if (!is_ipaddrv6($interface_ip)) { - continue; - } - if (ip_in_subnet($interface_ip, $local_subnet)) { - $srcip = $interface_ip; - break; - } - } - } else { - foreach ($iflist as $ifent => $ifname) { - $interface_ip = get_interface_ip($ifent); - if (!is_ipaddrv4($interface_ip)) { - continue; - } - if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) { - $srcip = $interface_ip; - break; - } - } - } - /* if no valid src IP was found in configured interfaces, try the vips */ - if (is_null($srcip)) { - foreach ($viplist as $vip) { - if (ip_in_subnet($vip['ipaddr'], $local_subnet)) { - $srcip = $vip['ipaddr']; - break; - } - } - } - $dstip = $ph2ent['pinghost']; - if(is_ipaddrv6($dstip)) { - $family = "inet6"; - } else { - $family = "inet"; - } - if (is_ipaddr($srcip)) { - $ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n"; - } - } - } - } - @file_put_contents('/var/db/ipsecpinghosts', $ipsecpinghosts); - - $cnf_add_to_charon_section = ""; - $cnf_add_to_charon_section .= $aggressive_psk ? "\ti_dont_care_about_security_and_use_aggressive_mode_psk=yes\n":""; - if (isset($a_client['enable']) && isset($a_client['net_list'])) { - $cnf_add_to_charon_section .= "\tcisco_unity = yes\n"; - } - - $strongswan = << 0) { - $strongswan .= ","; - } - if ($authcfg == "system") { - $authcfg = "Local Database"; - } - $strongswan .= $authcfg; - $firstsed = 1; - } - $strongswan .= "\n"; - $strongswan .= "\t}\n"; - } - } - - $strongswan .= "\t}\n}\n"; - @file_put_contents("/usr/local/etc/strongswan.conf", $strongswan); - unset($strongswan); - - /* generate CA certificates files */ - if (isset($config['ca'])) { - foreach ($config['ca'] as $ca) { - if (!isset($ca['crt'])) { - log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr'])); - continue; - } - $cert = base64_decode($ca['crt']); - $x509cert = openssl_x509_parse(openssl_x509_read($cert)); - if (!is_array($x509cert) || !isset($x509cert['hash'])) { - log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr'])); - continue; - } - $fname = "{$capath}/{$x509cert['hash']}.0.crt"; - if (!@file_put_contents($fname, $cert)) { - log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr'])); - continue; - } - unset($cert); - } - } - - $pskconf = ""; - - foreach ($a_phase1 as $ph1ent) { - if (isset($ph1ent['disabled'])) { - continue; - } - - if (!empty($ph1ent['certref'])) { - $cert = lookup_cert($ph1ent['certref']); - - if (empty($cert)) { - log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name'])); - continue; - } - - @chmod($certpath, 0600); - - $ph1keyfile = "{$keypath}/cert-{$ph1ent['ikeid']}.key"; - if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) { - log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name'])); - continue; - } - @chmod($ph1keyfile, 0600); - - $ph1certfile = "{$certpath}/cert-{$ph1ent['ikeid']}.crt"; - if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) { - log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name'])); - @unlink($ph1keyfile); - continue; - } - @chmod($ph1certfile, 0600); - - /* 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; - } - - $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"; - } - } - } - - /* Add user PSKs */ - if (isset($config['system']['user']) && is_array($config['system']['user'])) { - foreach ($config['system']['user'] as $user) { - if (!empty($user['ipsecpsk'])) { - $pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n"; - } - } - unset($user); - } - - /* 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); - } - - @file_put_contents("/usr/local/etc/ipsec.secrets", $pskconf); - chmod("/usr/local/etc/ipsec.secrets", 0600); - unset($pskconf); - - $natfilterrules = false; - /* begin ipsec.conf */ - $ipsecconf = ""; - if (count($a_phase1)) { - $ipsecconf .= "# This file is automatically generated. Do not edit\n"; - $ipsecconf .= "config setup\n\tuniqueids = yes\n"; - // parse debug tags - $cfg_loglevels = array(); - if (isset($ipsec_loglevels)) { - 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) ; - } - } - } - $ipsecconf .= "\tcharondebug=\"" .implode(',', $cfg_loglevels) . "\"\n"; - - foreach ($a_phase1 as $ph1ent) { - if (isset($ph1ent['disabled'])) { - continue; - } - - if ($ph1ent['mode'] == "aggressive") { - $aggressive = "yes"; - } else { - $aggressive = "no"; - } - - $ep = ipsec_get_phase1_src($ph1ent); - if (empty($ep)) { - continue; - } - - $keyexchange = "ikev1"; - if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") { - $keyexchange = "ikev2"; - } - - if (isset($ph1ent['mobile'])) { - $right_spec = "%any"; - } else { - $right_spec = $ph1ent['remote-gateway']; - } - - if (!empty($ph1ent['auto'])) { - $conn_auto = $ph1ent['auto']; - } elseif (isset($ph1ent['mobile'])) { - $conn_auto = 'add'; - } else { - $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; - } - - if (!empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) { - $ealg_id = $ph1ent['encryption-algorithm']['name']; - if (isset($ph1ent['encryption-algorithm']['keylen'])){ - $ealgosp1 = "ike = {$ealg_id}{$ph1ent['encryption-algorithm']['keylen']}-{$ph1ent['hash-algorithm']}"; - } else { - $ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}"; - } - $modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']); - if (!empty($modp)) { - $ealgosp1 .= "-{$modp}"; - } - $ealgosp1 .= "!"; - } - - if (!empty($ph1ent['dpd_delay']) && !empty($ph1ent['dpd_maxfail'])) { - if ($conn_auto == "route") { - $dpdline = "dpdaction = restart"; - } else { - $dpdline = "dpdaction = clear"; - } - $dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s"; - $dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1); - $dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s"; - } else { - $dpdline = "dpdaction = none"; - } - - if (!empty($ph1ent['lifetime'])) { - $ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s"; - } else { - $ikelifeline = ''; - } - - $rightsourceip = NULL; - if (!empty($a_client['pool_address']) && isset($ph1ent['mobile']) ) { - $rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n"; - } - - $authentication = ""; - switch ($ph1ent['authentication_method']) { - case 'eap-tls': - $authentication = "leftauth=eap-tls\n\trightauth=eap-tls"; - break; - case 'xauth_rsa_server': - $authentication = "leftauth = pubkey\n\trightauth = pubkey"; - $authentication .= "\n\trightauth2 = xauth-generic"; - break; - case 'xauth_psk_server': - $authentication = "leftauth = psk\n\trightauth = psk"; - $authentication .= "\n\trightauth2 = xauth-generic"; - break; - case 'pre_shared_key': - $authentication = "leftauth = psk\n\trightauth = psk"; - break; - case 'rsasig': - $authentication = "leftauth = pubkey\n\trightauth = pubkey"; - break; - case 'hybrid_rsa_server': - $authentication = "leftauth = xauth-generic\n\trightauth = pubkey"; - $authentication .= "\n\trightauth2 = xauth"; - break; - } - if (!empty($ph1ent['certref'])) { - $authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt"; - } - if (!empty($ph1ent['caref'])) { - $ca = lookup_ca($ph1ent['caref']);; - if (!empty($ca)) { - $rightca = ""; - foreach (cert_get_subject_array($ca['crt']) as $ca_field) { - $rightca .= "{$ca_field['a']}={$ca_field['v']}/"; - } - $authentication .= "\n\trightca=\"/$rightca\""; - } - } - $left_spec = $ep; - - if (isset($ph1ent['reauth_enable'])) { - $reauth = "reauth = no"; - } else { - $reauth = "reauth = yes"; - } - - if (isset($ph1ent['rekey_enable'])) { - $rekey = "rekey = no"; - } else { - $rekey = "rekey = yes"; - } - - $forceencaps = 'forceencaps = no' ; - if (!empty($ph1ent['nat_traversal']) && $ph1ent['nat_traversal'] == 'force') { - $forceencaps = 'forceencaps = yes'; - } - - $ipseclifetime = 0; - $rightsubnet_spec = array(); - $leftsubnet_spec = array(); - $ealgoAHsp2arr = array(); - $ealgoESPsp2arr = array(); - - - if (count($a_phase2)) { - foreach ($a_phase2 as $ph2ent) { - if ($ph1ent['ikeid'] != $ph2ent['ikeid'] || isset($ph2ent['disabled'])) { - continue; - } - if (isset($ph2ent['mobile']) && !isset($a_client['enable'])){ - continue; - } - - if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) { - $tunneltype = "type = tunnel"; - $localid_type = $ph2ent['localid']['type']; - $leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']); - /* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */ - if (($localid_type == "none" || $localid_type == "mobile") - && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ph1ent['ikeid'])==1)) { - $left_spec = '%any'; - } else { - if ($localid_type != "address") { - $localid_type = "subnet"; - } - // Don't let an empty subnet into config, it can cause parse errors. Ticket #2201. - if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) { - log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet."); - continue; - } - if (!empty($ph2ent['natlocalid'])) { - $natfilterrules = true; - } - } - - $leftsubnet_spec[] = $leftsubnet_data; - - if (!isset($ph2ent['mobile'])) { - $tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']); - $rightsubnet_spec[] = $tmpsubnet; - } else if (!empty($a_client['pool_address'])) { - $rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}"; - } - } else { - $tunneltype = "type = transport"; - if ((($ph1ent['authentication_method'] == "xauth_psk_server") || - ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) { - $left_spec = "%any"; - } else { - $tmpsubnet = ipsec_get_phase1_src($ph1ent); - $leftsubnet_spec[] = $tmpsubnet; - } - if (!isset($ph2ent['mobile'])) { - $rightsubnet_spec[] = $right_spec; - } - } - if (isset($a_client['pfs_group'])) { - $ph2ent['pfsgroup'] = $a_client['pfs_group']; - } - if (isset($ph2ent['protocol']) && $ph2ent['protocol'] == 'esp') { - $ealgoESPsp2arr_details = array(); - if (is_array($ph2ent['encryption-algorithm-option'])) { - foreach ($ph2ent['encryption-algorithm-option'] as $ealg) { - $ealg_id = $ealg['name']; - if (isset($ealg['keylen'])) { - $ealg_kl = $ealg['keylen']; - } else { - $ealg_kl = null; - } - - 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']; - /* XXX: in some cases where include ordering is suspect these variables - * are somehow 0 and we enter this loop forever and timeout after 900 - * seconds wrecking bootup */ - if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) { - for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) { - if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) { - foreach ($ph2ent['hash-algorithm-option'] as $halgo) { - $halgo = str_replace('hmac_', '', $halgo); - $tmpealgo = "{$ealg_id}{$keylen}-{$halgo}"; - $modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']); - if (!empty($modp)) { - $tmpealgo .= "-{$modp}"; - } - $ealgoESPsp2arr_details[] = $tmpealgo; - } - } else { - $tmpealgo = "{$ealg_id}{$keylen}"; - $modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']); - if (!empty($modp)) { - $tmpealgo .= "-{$modp}"; - } - $ealgoESPsp2arr_details[] = $tmpealgo; - } - } - } - } else { - if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) { - foreach ($ph2ent['hash-algorithm-option'] as $halgo) { - $halgo = str_replace('hmac_', '', $halgo); - $tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}"; - $modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']); - if (!empty($modp)) { - $tmpealgo .= "-{$modp}"; - } - $ealgoESPsp2arr_details[] = $tmpealgo; - } - } else { - $tmpealgo = "{$ealg_id}{$ealg_kl}"; - $modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']); - if (!empty($modp)) { - $tmpealgo .= "-{$modp}"; - } - $ealgoESPsp2arr_details[] = $tmpealgo; - } - } - } - } - $ealgoESPsp2arr[] = $ealgoESPsp2arr_details; - } else if (isset($ph2ent['protocol']) && $ph2ent['protocol'] == 'ah') { - $ealgoAHsp2arr_details = array(); - if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) { - $modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']); - foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) { - $tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo); - if (!empty($modp)) { - $tmpAHalgo = "-{$modp}"; - } - $ealgoAHsp2arr_details[] = $tmpAHalgo; - } - } - $ealgoAHsp2arr[] = $ealgoAHsp2arr_details; - } - - if (!empty($ph2ent['lifetime'])) { - if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) { - $ipseclifetime = intval($ph2ent['lifetime']); - } - } - } - } - - $connEntry =<<> - aggressive = {$aggressive} - fragmentation = yes - keyexchange = {$keyexchange} - {$reauth} - {$rekey} - {$forceencaps} - installpolicy = yes - {$tunneltype} - {$dpdline} - auto = {$conn_auto} - left = {$left_spec} - right = {$right_spec} - leftid = {$myid_data} - {$ikelifeline} - -EOD; - - if ($ipseclifetime > 0) { - $connEntry .= "\tlifetime = {$ipseclifetime}s\n"; - } - if (!empty($rightsourceip)) { - $connEntry .= "{$rightsourceip}"; - } - if (!empty($ealgosp1)) { - $connEntry .= "\t{$ealgosp1}\n"; - } - if (!empty($authentication)) { - $connEntry .= "\t{$authentication}\n"; - } - if (!empty($peerid_spec)) { - $connEntry .= "\trightid = {$peerid_spec}\n"; - } - - // append ipsec connections - if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') { - // ikev1 not mobile - for ($idx = 0 ; $idx < count($leftsubnet_spec) ; ++$idx) { - if (count($leftsubnet_spec) == 1) { - $tmpconf = str_replace('<>', "{$ph1ent['ikeid']}", $connEntry); - } else { - // suffix connection with sequence number - $tmpconf = str_replace('<>', "{$ph1ent['ikeid']}-00{$idx}", $connEntry); - } - $tmpconf .= "\trightsubnet =" . $rightsubnet_spec[$idx]. "\n" ; - $tmpconf .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n"; - if (!empty($ealgoESPsp2arr[$idx])) { - $tmpconf .= "\tesp = " . join(',', $ealgoESPsp2arr[$idx]) . "!\n"; - } - if (!empty($ealgoAHsp2arr[$idx])) { - $connEntry .= "\tah = " . join(',', $ealgoAHsp2arr[$idx]) . "!\n"; - } - $ipsecconf .= $tmpconf; - } - } else { - // mobile and ikev2 - $tmpconf = str_replace('<>', "{$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; - } - } - } - // 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"; - } - $ipsecconf .= $tmpconf; - } - } - } - } - // dump file, replace tabs for 2 spaces - @file_put_contents("/usr/local/etc/ipsec.conf", str_replace("\t",' ', $ipsecconf)); - unset($ipsecconf); - /* end ipsec.conf */ - - /* mange process */ - if (isvalidpid('/var/run/charon.pid')) { - /* Read secrets */ - mwexec('/usr/local/sbin/ipsec rereadall', false); - /* Update configuration changes */ - mwexec('/usr/local/sbin/ipsec reload', false); - } else { - mwexec("/usr/local/sbin/ipsec start", false); - } - - if ($natfilterrules == true) { - filter_configure(); - } - - /* start filterdns, if necessary */ - if (count($filterdns_list) > 0) { - $interval = 60; - if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) { - $interval = $ipseccfg['dns-interval']; - } - - $hostnames = ""; - array_unique($filterdns_list); - foreach ($filterdns_list as $hostname) { - $hostnames .= "cmd {$hostname} '/usr/local/opnsense/service/configd_ctl.py ipsecdns reload'\n"; - } - file_put_contents("/usr/local/etc/filterdns-ipsec.hosts", $hostnames); - unset($hostnames); - - if (isvalidpid('/var/run/filterdns-ipsec.pid')) { - killbypid('/var/run/filterdns-ipsec.pid', 'HUP'); - } else { - mwexec("/usr/local/sbin/filterdns -p /var/run/filterdns-ipsec.pid -i {$interval} -c /usr/local/etc/filterdns-ipsec.hosts -d 1"); - } - } else { - killbypid('/var/run/filterdns-ipsec.pid'); - } - - if (file_exists("/var/run/booting")) { - echo "done\n"; - } - - return count($filterdns_list); -} - -/* - * Forcefully restart IPsec - * This is required for when dynamic interfaces reload - * For all other occasions the normal vpn_ipsec_configure() - * will gracefully reload the settings without restarting - */ -function vpn_ipsec_force_reload($interface = '') -{ - global $config; - - $ipseccfg = $config['ipsec']; - - if (!empty($interface) && isset($ipseccfg['phase1']) && is_array($ipseccfg['phase1'])) { - $found = false; - foreach ($ipseccfg['phase1'] as $ipsec) { - if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) { - $found = true; - break; - } - } - if (!$found) { - log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface)); - return; - } - } - - /* if ipsec is enabled, start up again */ - if (isset($ipseccfg['enable'])) { - log_error(gettext("Forcefully reloading IPsec")); - vpn_ipsec_configure(); - } -} - -/* master setup for vpn (mpd) */ -function vpn_setup() -{ - /* start pptpd */ - vpn_pptpd_configure(); - - /* start pppoe server */ - vpn_pppoes_configure(); - - /* setup l2tp */ - vpn_l2tp_configure(); -} - -function vpn_netgraph_support() { - $iflist = get_configured_interface_list(); - foreach ($iflist as $iface) { - $realif = get_real_interface($iface); - /* Get support for netgraph(4) from the nic */ - $ifinfo = pfSense_get_interface_addresses($realif); - if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) { - pfSense_ngctl_attach(".", $realif); - } - } -} - -function vpn_pptpd_configure() { - global $config; - - $syscfg = $config['system']; - $pptpdcfg = $config['pptpd']; - - if (file_exists("/var/run/booting")) { - if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) - return 0; - - echo gettext("Configuring PPTP VPN service... "); - } else { - /* kill mpd */ - killbypid('/var/run/pptp-vpn.pid'); - - /* wait for process to die */ - sleep(3); - - if (is_process_running("mpd -b")) { - killbypid('/var/run/pptp-vpn.pid'); - log_error(gettext("Could not kill mpd within 3 seconds. Trying again.")); - } - - /* remove mpd.conf, if it exists */ - @unlink('/var/etc/pptp-vpn/mpd.conf'); - @unlink('/var/etc/pptp-vpn/mpd.links'); - @unlink('/var/etc/pptp-vpn/mpd.secret'); - } - - if (empty($pptpdcfg['n_pptp_units'])) { - log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise."); - return; - } - - /* make sure pptp-vpn directory exists */ - @mkdir('/var/etc/pptp-vpn'); - - switch ($pptpdcfg['mode']) { - case 'server' : - /* write mpd.conf */ - $fd = fopen('/var/etc/pptp-vpn/mpd.conf', 'w'); - if (!$fd) { - printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n"); - return 1; - } - - $mpdconf = << 1) ? $pptpdcfg['radius']['server']['port'] : 1812; - $acctport = $authport + 1; - $mpdconf .=<< 1) ? $pptpdcfg['radius']['server2']['port'] : 1812; - $acctport = $authport + 1; - $mpdconf .=<< gettext("AMD Geode LX Security Block"), 'aesni' => gettext("AES-NI CPU-based Acceleration") ); diff --git a/src/www/system_gateway_groups_edit.php b/src/www/system_gateway_groups_edit.php index f255242cb..075d93959 100644 --- a/src/www/system_gateway_groups_edit.php +++ b/src/www/system_gateway_groups_edit.php @@ -28,7 +28,7 @@ */ require_once("guiconfig.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("services.inc"); require_once("interfaces.inc"); diff --git a/src/www/vpn_ipsec.php b/src/www/vpn_ipsec.php index cb28b940f..500d6bc1f 100644 --- a/src/www/vpn_ipsec.php +++ b/src/www/vpn_ipsec.php @@ -30,7 +30,7 @@ require_once("guiconfig.inc"); require_once("filter.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("services.inc"); require_once("pfsense-utils.inc"); require_once("interfaces.inc"); @@ -78,7 +78,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $a_phase1 = &$config['ipsec']['phase1']; $a_phase2 = &$config['ipsec']['phase2']; if (isset($_POST['apply'])) { - $retval = vpn_ipsec_configure(); + $retval = ipsec_configure(); /* reload the filter in the background */ filter_configure(); $savemsg = get_std_save_message(); @@ -90,7 +90,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } elseif (isset($_POST['save'])) { $config['ipsec']['enable'] = !empty($_POST['enable']) ? true : false; write_config(); - vpn_ipsec_configure(); + ipsec_configure(); header("Location: vpn_ipsec.php"); exit; } elseif (!empty($_POST['act']) && $_POST['act'] == "delphase1" ) { diff --git a/src/www/vpn_ipsec_keys.php b/src/www/vpn_ipsec_keys.php index f508932c9..5a93b7351 100644 --- a/src/www/vpn_ipsec_keys.php +++ b/src/www/vpn_ipsec_keys.php @@ -28,7 +28,7 @@ */ require_once("guiconfig.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("filter.inc"); require_once("services.inc"); require_once("pfsense-utils.inc"); @@ -56,13 +56,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } } elseif (isset($_POST['apply'])) { // apply changes - $retval = vpn_ipsec_configure(); - /* reload the filter in the background */ + ipsec_configure(); filter_configure(); $savemsg = get_std_save_message(); - if (is_subsystem_dirty('ipsec')) { - clear_subsystem_dirty('ipsec'); - } + clear_subsystem_dirty('ipsec'); } else { // nothing to post, redirect header("Location: vpn_ipsec_keys.php"); diff --git a/src/www/vpn_ipsec_keys_edit.php b/src/www/vpn_ipsec_keys_edit.php index 40c9496c7..2d3d6be53 100644 --- a/src/www/vpn_ipsec_keys_edit.php +++ b/src/www/vpn_ipsec_keys_edit.php @@ -29,7 +29,7 @@ require_once("interfaces.inc"); require_once("guiconfig.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("services.inc"); if (!isset($config['ipsec']) || !is_array($config['ipsec'])) { diff --git a/src/www/vpn_ipsec_mobile.php b/src/www/vpn_ipsec_mobile.php index 2c0a678d8..4014a424a 100644 --- a/src/www/vpn_ipsec_mobile.php +++ b/src/www/vpn_ipsec_mobile.php @@ -30,7 +30,7 @@ require_once("interfaces.inc"); require_once("guiconfig.inc"); require_once("filter.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("services.inc"); require_once("pfsense-utils.inc"); @@ -89,14 +89,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { exit; } elseif (isset($_POST['apply'])) { // apply changes - $retval = 0; - $retval = vpn_ipsec_configure(); + ipsec_configure(); $savemsg = get_std_save_message(); - if ($retval >= 0) { - if (is_subsystem_dirty('ipsec')) { - clear_subsystem_dirty('ipsec'); - } - } + clear_subsystem_dirty('ipsec'); header("Location: vpn_ipsec_mobile.php?savemsg=".$savemsg); exit; } elseif (isset($_POST['submit'])) { diff --git a/src/www/vpn_ipsec_phase1.php b/src/www/vpn_ipsec_phase1.php index 1cca9b144..00c075499 100644 --- a/src/www/vpn_ipsec_phase1.php +++ b/src/www/vpn_ipsec_phase1.php @@ -31,7 +31,7 @@ require_once("guiconfig.inc"); require_once("filter.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("services.inc"); require_once("pfsense-utils.inc"); require_once("interfaces.inc"); @@ -399,7 +399,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } /* if the remote gateway changed and the interface is not WAN then remove route */ - /* the vpn_ipsec_configure() handles adding the route */ + /* the ipsec_configure() handles adding the route */ if ($pconfig['interface'] <> "wan") { if ($old_ph1ent['remote-gateway'] <> $pconfig['remote-gateway']) { mwexec("/sbin/route delete -host {$old_ph1ent['remote-gateway']}"); diff --git a/src/www/vpn_ipsec_phase2.php b/src/www/vpn_ipsec_phase2.php index 9cc42fbb3..c3b3a1dd9 100644 --- a/src/www/vpn_ipsec_phase2.php +++ b/src/www/vpn_ipsec_phase2.php @@ -30,7 +30,7 @@ require_once("guiconfig.inc"); require_once("interfaces.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("services.inc"); /** diff --git a/src/www/vpn_ipsec_settings.php b/src/www/vpn_ipsec_settings.php index 0f7a50750..126594cc0 100644 --- a/src/www/vpn_ipsec_settings.php +++ b/src/www/vpn_ipsec_settings.php @@ -29,7 +29,7 @@ require_once("guiconfig.inc"); require_once("filter.inc"); -require_once("vpn.inc"); +require_once("ipsec.inc"); require_once("services.inc"); require_once("pfsense-utils.inc"); require_once("interfaces.inc"); @@ -99,9 +99,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { write_config(); $savemsg = get_std_save_message(); - filter_configure(); - vpn_ipsec_configure(); + ipsec_configure(); } $service_hook = 'ipsec'; diff --git a/src/www/vpn_l2tp.php b/src/www/vpn_l2tp.php index a5c3f920b..66abff2e9 100644 --- a/src/www/vpn_l2tp.php +++ b/src/www/vpn_l2tp.php @@ -28,9 +28,11 @@ */ require_once("guiconfig.inc"); -require_once("vpn.inc"); require_once("pfsense-utils.inc"); require_once("interfaces.inc"); +require_once("services.inc"); +require_once("plugins.inc"); +require_once("plugins.inc.d/vpn.inc"); if (!isset($config['l2tp']['radius']) || !is_array($config['l2tp']['radius'])) { $config['l2tp']['radius'] = array(); @@ -164,6 +166,8 @@ if ($_POST) { } } +$service_hook = 'l2tpd'; + include("head.inc"); ?> diff --git a/src/www/vpn_l2tp_users.php b/src/www/vpn_l2tp_users.php index fc6cb5bd8..b7e82f99c 100644 --- a/src/www/vpn_l2tp_users.php +++ b/src/www/vpn_l2tp_users.php @@ -28,7 +28,9 @@ */ require_once("guiconfig.inc"); -require_once("vpn.inc"); +require_once("services.inc"); +require_once("plugins.inc"); +require_once("plugins.inc.d/vpn.inc"); if (!isset($config['l2tp']['user'])) { $config['l2tp']['user'] = array(); @@ -39,16 +41,9 @@ if ($_POST) { $pconfig = $_POST; if ($_POST['apply']) { - $retval = 0; - if (!is_subsystem_dirty('rebootreq')) { - $retval = vpn_l2tp_configure(); - } + vpn_l2tp_configure(); $savemsg = get_std_save_message(); - if ($retval == 0) { - if (is_subsystem_dirty('l2tpusers')) { - clear_subsystem_dirty('l2tpusers'); - } - } + clear_subsystem_dirty('l2tpusers'); } } @@ -62,6 +57,8 @@ if ($_GET['act'] == "del") { } } +$service_hook = 'l2tpd'; + include("head.inc"); diff --git a/src/www/vpn_l2tp_users_edit.php b/src/www/vpn_l2tp_users_edit.php index 7307b0435..55832e66d 100644 --- a/src/www/vpn_l2tp_users_edit.php +++ b/src/www/vpn_l2tp_users_edit.php @@ -44,7 +44,9 @@ function l2tp_users_sort() } require_once("guiconfig.inc"); -require_once("vpn.inc"); +require_once("services.inc"); +require_once("plugins.inc"); +require_once("plugins.inc.d/vpn.inc"); $referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/vpn_l2tp_users.php'); @@ -122,18 +124,18 @@ if ($_POST) { } else { $a_secret[] = $secretent; } + l2tp_users_sort(); - write_config(); - - $retval = vpn_l2tp_configure(); + vpn_l2tp_configure(); header("Location: vpn_l2tp_users.php"); - exit; } } +$service_hook = 'l2tpd'; + include("head.inc"); ?> diff --git a/src/www/vpn_pppoe.php b/src/www/vpn_pppoe.php index 826bff3cb..93230268d 100644 --- a/src/www/vpn_pppoe.php +++ b/src/www/vpn_pppoe.php @@ -29,7 +29,7 @@ require_once("guiconfig.inc"); require_once("filter.inc"); -require_once("vpn.inc"); +require_once("plugins.inc.d/vpn.inc"); require_once("interfaces.inc"); if (!is_array($config['pppoes'])) { diff --git a/src/www/vpn_pppoe_edit.php b/src/www/vpn_pppoe_edit.php index dc75e2416..b543cb93c 100644 --- a/src/www/vpn_pppoe_edit.php +++ b/src/www/vpn_pppoe_edit.php @@ -29,7 +29,6 @@ */ require_once("guiconfig.inc"); -require_once("vpn.inc"); require_once("interfaces.inc"); function vpn_pppoe_get_id() diff --git a/src/www/vpn_pptp.php b/src/www/vpn_pptp.php index c81d0625f..fa9edcf3a 100644 --- a/src/www/vpn_pptp.php +++ b/src/www/vpn_pptp.php @@ -30,8 +30,10 @@ require_once('guiconfig.inc'); require_once('interfaces.inc'); require_once('filter.inc'); -require_once('vpn.inc'); +require_once('services.inc'); +require_once("plugins.inc"); require_once("pfsense-utils.inc"); +require_once('plugins.inc.d/vpn.inc'); if (!is_array($config['pptpd']['radius'])) { $config['pptpd']['radius'] = array(); @@ -187,15 +189,14 @@ if ($_POST) { } write_config(); - - $retval = 0; - $retval = vpn_pptpd_configure(); $savemsg = get_std_save_message(); - + vpn_pptpd_configure(); filter_configure(); } } +$service_hook = 'pptpd'; + include("head.inc"); ?> diff --git a/src/www/vpn_pptp_users.php b/src/www/vpn_pptp_users.php index 3950dae07..d7a0bd97e 100644 --- a/src/www/vpn_pptp_users.php +++ b/src/www/vpn_pptp_users.php @@ -28,7 +28,9 @@ */ require_once('guiconfig.inc'); -require_once('vpn.inc'); +require_once('services.inc'); +require_once("plugins.inc"); +require_once('plugins.inc.d/vpn.inc'); if (!is_array($config['pptpd']['user'])) { $config['pptpd']['user'] = array(); @@ -39,14 +41,9 @@ if ($_POST) { $pconfig = $_POST; if ($_POST['apply']) { - $retval = 0; - $retval = vpn_setup(); + vpn_pptpd_configure(); $savemsg = get_std_save_message(); - if ($retval == 0) { - if (is_subsystem_dirty('pptpusers')) { - clear_subsystem_dirty('pptpusers'); - } - } + clear_subsystem_dirty('pptpusers'); } } @@ -60,6 +57,8 @@ if ($_GET['act'] == "del") { } } +$service_hook = 'pptpd'; + include("head.inc"); $main_buttons = array( diff --git a/src/www/vpn_pptp_users_edit.php b/src/www/vpn_pptp_users_edit.php index 2355df0d4..24e60bd85 100644 --- a/src/www/vpn_pptp_users_edit.php +++ b/src/www/vpn_pptp_users_edit.php @@ -34,17 +34,19 @@ function pptpusercmp($a, $b) function pptpd_users_sort() { - global $config; + global $config; if (!is_array($config['ppptpd']['user'])) { return; } - usort($config['pptpd']['user'], "pptpusercmp"); + usort($config['pptpd']['user'], "pptpusercmp"); } require_once('guiconfig.inc'); -require_once('vpn.inc'); +require_once('services.inc'); +require_once("plugins.inc"); +require_once('plugins.inc.d/vpn.inc'); if (!is_array($config['pptpd']['user'])) { $config['pptpd']['user'] = array(); @@ -124,16 +126,18 @@ if ($_POST) { } else { $a_secret[] = $secretent; } - pptpd_users_sort(); + pptpd_users_sort(); write_config(); - mark_subsystem_dirty('pptpusers'); + vpn_pptpd_configure(); header("Location: vpn_pptp_users.php"); exit; } } +$service_hook = 'pptpd'; + include("head.inc"); ?> diff --git a/src/www/widgets/widgets/services_status.widget.php b/src/www/widgets/widgets/services_status.widget.php index 126cd2b11..cd4325c69 100644 --- a/src/www/widgets/widgets/services_status.widget.php +++ b/src/www/widgets/widgets/services_status.widget.php @@ -33,9 +33,10 @@ $nocsrf = true; require_once("guiconfig.inc"); require_once("services.inc"); -require_once("vpn.inc"); -require_once("widgets/include/services_status.inc"); +require_once('plugins.inc'); +require_once("ipsec.inc"); require_once("interfaces.inc"); +require_once("widgets/include/services_status.inc"); $services = services_get();