diff options
Diffstat (limited to 'src/etc')
35 files changed, 1475 insertions, 320 deletions
diff --git a/src/etc/inc/auth.inc b/src/etc/inc/auth.inc index 563987b..9c48992 100644 --- a/src/etc/inc/auth.inc +++ b/src/etc/inc/auth.inc @@ -26,6 +26,7 @@ * NOTE : Portions of the mschapv2 support was based on the BSD licensed CHAP.php * file courtesy of Michael Retterklieber. */ +include_once('phpsessionmanager.inc'); if (!$do_not_include_config_gui_inc) { require_once("config.gui.inc"); } @@ -1580,9 +1581,11 @@ function get_user_settings($username) { $settings['webgui']['dashboardcolumns'] = $config['system']['webgui']['dashboardcolumns']; $settings['webgui']['webguihostnamemenu'] = $config['system']['webgui']['webguihostnamemenu']; $settings['webgui']['webguicss'] = $config['system']['webgui']['webguicss']; + $settings['webgui']['interfacessort'] = isset($config['system']['webgui']['interfacessort']); $settings['webgui']['dashboardavailablewidgetspanel'] = isset($config['system']['webgui']['dashboardavailablewidgetspanel']); $settings['webgui']['webguifixedmenu'] = isset($config['system']['webgui']['webguifixedmenu']); $settings['webgui']['webguileftcolumnhyper'] = isset($config['system']['webgui']['webguileftcolumnhyper']); + $settings['webgui']['disablealiaspopupdetail'] = isset($config['system']['webgui']['disablealiaspopupdetail']); $settings['webgui']['systemlogsfilterpanel'] = isset($config['system']['webgui']['systemlogsfilterpanel']); $settings['webgui']['systemlogsmanagelogpanel'] = isset($config['system']['webgui']['systemlogsmanagelogpanel']); $settings['webgui']['statusmonitoringsettingspanel'] = isset($config['system']['webgui']['statusmonitoringsettingspanel']); @@ -1603,9 +1606,11 @@ function get_user_settings($username) { if (isset($user['webguihostnamemenu'])) { $settings['webgui']['webguihostnamemenu'] = $user['webguihostnamemenu']; } + $settings['webgui']['interfacessort'] = isset($user['interfacessort']); $settings['webgui']['dashboardavailablewidgetspanel'] = isset($user['dashboardavailablewidgetspanel']); $settings['webgui']['webguifixedmenu'] = isset($user['webguifixedmenu']); $settings['webgui']['webguileftcolumnhyper'] = isset($user['webguileftcolumnhyper']); + $settings['webgui']['disablealiaspopupdetail'] = isset($user['disablealiaspopupdetail']); $settings['webgui']['systemlogsfilterpanel'] = isset($user['systemlogsfilterpanel']); $settings['webgui']['systemlogsmanagelogpanel'] = isset($user['systemlogsmanagelogpanel']); $settings['webgui']['statusmonitoringsettingspanel'] = isset($user['statusmonitoringsettingspanel']); @@ -1747,12 +1752,11 @@ function session_auth() { true ); - if (!session_id()) { - session_start(); - } + phpsession_begin(); // Detect protocol change if (!isset($_POST['login']) && !empty($_SESSION['Logged_In']) && $_SESSION['protocol'] != $config['system']['webgui']['protocol']) { + phpsession_end(); return false; } @@ -1770,6 +1774,7 @@ function session_auth() { $_SESSION['user_radius_attributes'] = $attributes; $_SESSION['last_access'] = time(); $_SESSION['protocol'] = $config['system']['webgui']['protocol']; + phpsession_end(true); if (!isset($config['system']['webgui']['quietlogin'])) { log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR'])); } @@ -1795,6 +1800,7 @@ function session_auth() { /* Show login page if they aren't logged in */ if (empty($_SESSION['Logged_In'])) { + phpsession_end(true); return false; } @@ -1842,7 +1848,7 @@ function session_auth() { } /* and destroy it */ - session_destroy(); + phpsession_destroy(); $scriptName = explode("/", $_SERVER["SCRIPT_FILENAME"]); $scriptElms = count($scriptName); @@ -1873,7 +1879,7 @@ function session_auth() { if ($_REQUEST['enable_ajax']) { unset($_SESSION['NO_AJAX']); } - + phpsession_end(true); return true; } diff --git a/src/etc/inc/authgui.inc b/src/etc/inc/authgui.inc index f0b7751..db76b88 100644 --- a/src/etc/inc/authgui.inc +++ b/src/etc/inc/authgui.inc @@ -27,13 +27,14 @@ include_once("priv.inc"); if (!function_exists('platform_booting')) { require_once('globals.inc'); } +require_once('pfsense-utils.inc'); /* Authenticate user - exit if failed */ if (!session_auth()) { display_login_form(); exit; } - +phpsession_begin(); /* * Once here, the user has authenticated with the web server. * We give them access only to the appropriate pages based on @@ -90,9 +91,9 @@ if (!$_SESSION['Post_Login']) { /* * Close session data to allow other scripts from same host to come in. - * A session can be reactivated from calling session_start again + * A session can be reactivated from calling phpsession_begin again */ -session_commit(); +phpsession_end(true); /* * determine if the user is allowed access to the requested page diff --git a/src/etc/inc/captiveportal.inc b/src/etc/inc/captiveportal.inc index e3c7b7b..22138fe 100644 --- a/src/etc/inc/captiveportal.inc +++ b/src/etc/inc/captiveportal.inc @@ -2301,7 +2301,7 @@ function portal_allow($clientip, $clientmac, $username, $password = null, $attri $safe_username = SQLite3::escapeString($username); /* encode password in Base64 just in case it contains commas */ - $bpassword = base64_encode($password); + $bpassword = (isset($config['captiveportal'][$cpzone]['reauthenticate'])) ? base64_encode($password) : ''; $insertquery = "INSERT INTO captiveportal (allow_time, pipeno, ip, mac, username, sessionid, bpassword, session_timeout, idle_timeout, session_terminate_time, interim_interval, radiusctx) "; $insertquery .= "VALUES ({$allow_time}, {$pipeno}, '{$clientip}', '{$clientmac}', '{$safe_username}', '{$sessionid}', '{$bpassword}', "; $insertquery .= "{$session_timeout}, {$idle_timeout}, {$session_terminate_time}, {$interim_interval}, '{$radiusctx}')"; diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index bb114c8..cb3d1b1 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -511,6 +511,18 @@ function cert_get_subject_hash($crt) { return $inf_crt['subject']; } +function cert_get_sans($str_crt, $decode = true) { + if ($decode) { + $str_crt = base64_decode($str_crt); + } + $sans = array(); + $crt_details = openssl_x509_parse($str_crt); + if (!empty($crt_details['extensions']['subjectAltName'])) { + $sans = explode(',', $crt_details['extensions']['subjectAltName']); + } + return $sans; +} + function cert_get_issuer($str_crt, $decode = true) { if ($decode) { @@ -541,39 +553,62 @@ function cert_get_issuer($str_crt, $decode = true) { return $issuer; } -/* this function works on x509 (crt), rsa key (prv), and req(csr) */ -function cert_get_modulus($str_crt, $decode = true, $type = "crt") { +/* Works for both RSA and ECC (crt) and key (prv) */ +function cert_get_publickey($str_crt, $decode = true, $type = "crt") { if ($decode) { $str_crt = base64_decode($str_crt); } - - $modulus = ""; - if (in_array($type, array("crt", "prv", "csr"))) { - $type = str_replace(array("crt", "prv", "csr"), array("x509", "rsa", "req"), $type); - $modulus = exec("echo \"{$str_crt}\" | openssl {$type} -noout -modulus"); + switch ($type) { + case 'prv': + exec("echo \"{$str_crt}\" | openssl pkey -pubout", $out); + break; + case 'crt': + exec("echo \"{$str_crt}\" | openssl x509 -inform pem -noout -pubkey", $out); + break; + case 'csr': + exec("echo \"{$str_crt}\" | openssl req -inform pem -noout -pubkey", $out); + break; + default: + $out = array(); + break; } - return $modulus; -} - -/* Same but returns modulus keysize not modulus itself */ -function cert_get_modulus_keysize($str_crt, $decode = true, $type = "crt") { - // modulus usually returned as "modulus=.....". Remove anything before an "=" and return 4 x (hex string length) - $raw_modulus = explode('=', cert_get_modulus($str_crt, $decode, $type)); - return strlen(array_pop($raw_modulus))*4; -} - -function csr_get_modulus($str_crt, $decode = true) { - return cert_get_modulus($str_crt, $decode, "csr"); + return implode("\n", $out); } function cert_get_purpose($str_crt, $decode = true) { + $extended_oids = array( + "1.3.6.1.5.5.8.2.2" => "IP Security IKE Intermediate", + ); if ($decode) { $str_crt = base64_decode($str_crt); } $crt_details = openssl_x509_parse($str_crt); $purpose = array(); + if (!empty($crt_details['extensions']['keyUsage'])) { + $purpose['ku'] = explode(',', $crt_details['extensions']['keyUsage']); + foreach ($purpose['ku'] as & $ku) { + $ku = trim($ku); + if (array_key_exists($ku, $extended_oids)) { + $ku = $extended_oids[$ku]; + } + } + } else { + $purpose['ku'] = array(); + } + if (!empty($crt_details['extensions']['extendedKeyUsage'])) { + $purpose['eku'] = explode(',', $crt_details['extensions']['extendedKeyUsage']); + foreach ($purpose['eku'] as & $eku) { + $eku = trim($eku); + if (array_key_exists($eku, $extended_oids)) { + $eku = $extended_oids[$eku]; + } + } + } else { + $purpose['eku'] = array(); + } $purpose['ca'] = (stristr($crt_details['extensions']['basicConstraints'], 'CA:TRUE') === false) ? 'No': 'Yes'; - $purpose['server'] = (strpos($crt_details['extensions']['nsCertType'], 'SSL Server') !== FALSE) ? 'Yes': 'No'; + $purpose['server'] = (in_array('TLS Web Server Authentication', $purpose['eku'])) ? 'Yes': 'No'; + return $purpose; } @@ -603,10 +638,6 @@ function cert_get_serial($str_crt, $decode = true) { } } -function prv_get_modulus($str_crt, $decode = true) { - return cert_get_modulus($str_crt, $decode, "prv"); -} - function is_openvpn_server_ca($caref) { global $config; if (!is_array($config['openvpn']['openvpn-server'])) { @@ -771,6 +802,27 @@ function cert_in_use($certref) { is_package_cert($certref)); } +function cert_usedby_description($refid, $certificates_used_by_packages) { + $result = ""; + if (is_array($certificates_used_by_packages)) { + foreach ($certificates_used_by_packages as $name => $package) { + if (isset($package['certificatelist'][$refid])) { + $hint = "" ; + if (is_array($package['certificatelist'][$refid])) { + foreach ($package['certificatelist'][$refid] as $cert_used) { + $hint = $hint . $cert_used['usedby']."\n"; + } + } + $count = count($package['certificatelist'][$refid]); + $result .= "<div title='".htmlspecialchars($hint)."'>"; + $result .= htmlspecialchars($package['pkgname'])." ($count)<br />"; + $result .= "</div>"; + } + } + } + return $result; +} + function crl_create(& $crl, $caref, $name, $serial = 0, $lifetime = 9999) { global $config; $ca =& lookup_ca($caref); @@ -861,7 +913,7 @@ function cert_compare($cert1, $cert2) { if ((cert_get_issuer($c1, false) == cert_get_issuer($c2, false)) && (cert_get_subject($c1, false) == cert_get_subject($c2, false)) && (cert_get_serial($c1, false) == cert_get_serial($c2, false)) && - (cert_get_modulus($c1, false) == cert_get_modulus($c2, false))) { + (cert_get_publickey($c1, false) == cert_get_publickey($c2, false))) { return true; } return false; diff --git a/src/etc/inc/config.console.inc b/src/etc/inc/config.console.inc index 1415e86..fac977d 100644 --- a/src/etc/inc/config.console.inc +++ b/src/etc/inc/config.console.inc @@ -71,7 +71,7 @@ EOD; else $status = "(down)"; $ifsmallist = $ifsmallist . $iface. " "; - echo sprintf("% -7s%s %s %s\n", $iface, $ifa['mac'], + echo sprintf("%-7s %s %s %s\n", $iface, $ifa['mac'], $status, substr($ifa['dmesg'], 0, 48)); } } @@ -519,6 +519,10 @@ function check_for_alternate_interfaces() { $config['interfaces']['lan']['if'] = 'igb1'; } break; + case 'Turbot Dual-E': + $config['interfaces']['wan']['if'] = 'igb0'; + $config['interfaces']['lan']['if'] = 'igb1'; + break; default: $default_device['wan'] = ""; $default_device['lan'] = ""; diff --git a/src/etc/inc/config.lib.inc b/src/etc/inc/config.lib.inc index 21aeb11..40c3150 100644 --- a/src/etc/inc/config.lib.inc +++ b/src/etc/inc/config.lib.inc @@ -443,20 +443,27 @@ function write_config($desc="Unknown", $backup = true, $write_config_only = fals global $config, $g; if (!empty($_SERVER['REMOTE_ADDR'])) { - if (!session_id()) { - @session_start(); - } + @phpsession_begin(); if (!empty($_SESSION['Username']) && ($_SESSION['Username'] != "admin")) { $user = getUserEntry($_SESSION['Username']); if (is_array($user) && userHasPrivilege($user, "user-config-readonly")) { - session_commit(); + phpsession_end(true); return false; } } + if (!isset($argc)) { + phpsession_end(true); + } } - if (!isset($argc)) { - session_commit(); + if (isset($config['reset_factory_defaults'])) { + /* + We have put a default config.xml on disk and are about to reboot + or reload it. Do not let any system or package code try to save + state to config because that would overwrite the default config + with the running config. + */ + return false; } if ($backup) { @@ -527,7 +534,7 @@ function write_config($desc="Unknown", $backup = true, $write_config_only = fals * integer - indicates completion ******/ function reset_factory_defaults($lock = false, $reboot_required = true) { - global $g; + global $config, $g; /* Remove all additional packages */ @@ -558,6 +565,17 @@ function reset_factory_defaults($lock = false, $reboot_required = true) { disable_security_checks(); + /* + Let write_config know that we are awaiting reload of the current config + to factory defaults. Either the system is about to reboot, throwing away + the current in-memory config as it shuts down, or the in-memory config + is about to be reloaded on-the-fly by parse_config. + + In both cases, we want to ensure that write_config does not flush the + in-memory config back to disk. + */ + $config['reset_factory_defaults'] = true; + /* call the wizard */ if ($reboot_required) { // If we need a reboot first then touch a different trigger file. diff --git a/src/etc/inc/dyndns.class b/src/etc/inc/dyndns.class index 7772bc7..ab3ba2d 100644 --- a/src/etc/inc/dyndns.class +++ b/src/etc/inc/dyndns.class @@ -60,6 +60,7 @@ * - All-Inkl (all-inkl.com) * - DuiaDNS (www.duiadns.net) * - DuiaDNS IPv6 (www.duiadns.net) + * - Hover (www.hover.com) * +----------------------------------------------------+ * Requirements: * - PHP version 4.0.2 or higher with the CURL Library and the PCRE Library @@ -113,6 +114,7 @@ * All-Inkl - Last Tested: 12 November 2016 * DuiaDNS - Last Tested: 25 November 2016 * DuiaDNS IPv6 - Last Tested: 25 November 2016 + * Hover - Last Tested: 15 February 2017 * +====================================================+ * * @author E.Kristensen @@ -210,6 +212,7 @@ case "cloudflare-v6": case "cloudflare": case "gratisdns": + case "hover": if (!$dnsUser) $this->_error(3); if (!$dnsPass) $this->_error(4); if (!$dnsHost) $this->_error(5); @@ -319,6 +322,7 @@ case 'spdyn': case 'spdyn-v6': case 'all-inkl': + case 'hover': $this->_update(); if ($this->_dnsDummyUpdateDone == true) { // If a dummy update was needed, then sleep a while and do the update again to put the proper address back. @@ -650,10 +654,9 @@ case 'route53': require_once("r53.class"); $r53 = new Route53($this->_dnsUser, $this->_dnsPass); - list($r53_regionId, $r53_zoneId) = split('/', $this->_dnsZoneID); - $apiurl = $r53->getApiUrl($r53_zoneId); + $apiurl = $r53->getApiUrl($this->_dnsZoneID); $xmlreq = $r53->getRequestBody($this->_dnsHost, $this->_dnsIP, $this->_dnsTTL); - $httphead = $r53->getHttpPostHeaders($r53_zoneId, $r53_regionId, hash("sha256",$xmlreq)); + $httphead = $r53->getHttpPostHeaders($this->_dnsZoneID, "us-east-1", hash("sha256",$xmlreq)); curl_setopt($ch, CURLOPT_HTTPHEADER, $httphead); if($this->_dnsVerboseLog){ log_error(sprintf("Sending reuquest to: %s", $apiurl)); @@ -820,6 +823,52 @@ curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass); curl_setopt($ch, CURLOPT_URL, $server . 'myip=' . $this->_dnsIP); break; + case 'hover': + $needsIP = FALSE; + $port = ""; + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); + + //step 1: login to API + $post_data['username'] = $this->_dnsUser; + $post_data['password'] = $this->_dnsPass; + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/login"); + curl_setopt($ch, CURLOPT_HEADER, 1); //return the full headers to extract the cookies + $output = curl_exec($ch); + + //extract the cookies + preg_match_all("/^Set-cookie: (.*?);/ism", $output, $cookies); + if( count($cookies[1]) > 0 ){ + $cookie_data = implode("; ",$cookies[1]); + } + + //step 2: find the id of the A record + $post_data = null; + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + curl_setopt($ch, CURLOPT_COOKIE, $cookie_data); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/dns"); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); + + $output = curl_exec($ch); + preg_match("/^{\"succeeded\":true.*?domain_name\":\"{$this->_dnsDomain}.*?entries.*?{\"id\":\"([^\"]*?)\",\"name\":\"{$this->_dnsHost}\".*?\$/", $output, $hostID); + $hostID = $hostID[1]; + preg_match("/^{\"succeeded\":true.*?domain_name\":\"{$this->_dnsDomain}.*?entries.*?{[^\}]*?\"name\":\"{$this->_dnsHost}\".*?content\":\"([^\"]*?)\".*?\$/", $output, $hostIP); + $hostIP = $hostIP[1]; + + //step 3: update the IP + if ($hostID) { + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); + curl_setopt($ch, CURLOPT_COOKIE, $cookie_data); + $post_data['content'] = $this->_dnsIP; + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/dns/{$hostID}"); + log_error("HostID:{$hostID}, OldIP:{$hostIP}"); + } + break; default: break; } @@ -1484,6 +1533,16 @@ $this->_debug($header); } break; + case 'hover': + if (preg_match('/succeeded":true/i', $data)) { + $status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")"; + $successful_update = true; + } else { + $status = $status_intro . "(" . gettext("Unknown Response") . ")"; + log_error($status_intro . gettext("PAYLOAD:") . " " . $data); + $this->_debug($data); + } + break; } if ($successful_update == true) { diff --git a/src/etc/inc/easyrule.inc b/src/etc/inc/easyrule.inc index 766eb2e..8984c45 100644 --- a/src/etc/inc/easyrule.inc +++ b/src/etc/inc/easyrule.inc @@ -30,7 +30,7 @@ require_once("config.inc"); function easyrule_find_rule_interface($int) { global $config; /* Borrowed from firewall_rules.php */ - $iflist = get_configured_interface_with_descr(false, true); + $iflist = get_configured_interface_with_descr(true); if ($config['pppoe']['mode'] == "server") { $iflist['pppoe'] = "PPPoE Server"; diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index ef46c72..d940442 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -587,7 +587,20 @@ function filter_generate_scrubing() { return $scrubrules; } -function filter_generate_nested_alias($name, $alias, &$aliasnesting, &$aliasaddrnesting, &$use_filterdns = false) { +function filter_generate_nested_alias($name) { + global $aliastable; + + $aliasnesting = array(); + $aliasaddrnesting = array(); + + if (($name == "") || !isset($aliastable[$name])) { + return ""; + } + + return filter_generate_nested_alias_recurse($name, $aliastable[$name], $aliasnesting, $aliasaddrnesting); +} + +function filter_generate_nested_alias_recurse($name, $alias, &$aliasnesting, &$aliasaddrnesting, &$use_filterdns = false) { global $aliastable, $filterdns; $addresses = explode(" ", $alias); @@ -604,7 +617,7 @@ function filter_generate_nested_alias($name, $alias, &$aliasnesting, &$aliasaddr $tmpline = ""; if (is_alias($address)) { if (alias_get_type($address) == 'urltable') { - // Feature#1603. For this type of alias we do not need to recursively call filter_generate_nested_alias. Just load IPs from the file. + // Feature#1603. For this type of alias we do not need to recursively call filter_generate_nested_alias_recurse. Just load IPs from the file. $urltable_nesting = alias_expand_urltable($address); if (!empty($urltable_nesting)) { $urlfile_as_arr = file($urltable_nesting); @@ -620,10 +633,10 @@ function filter_generate_nested_alias($name, $alias, &$aliasnesting, &$aliasaddr } /* We already expanded this alias so there is no necessity to do it again. */ else if (!isset($aliasnesting[$address])) { - $tmpline = filter_generate_nested_alias($name, $aliastable[$address], $aliasnesting, $aliasaddrnesting, $use_filterdns); + $tmpline = filter_generate_nested_alias_recurse($name, $aliastable[$address], $aliasnesting, $aliasaddrnesting, $use_filterdns); } } else if (!isset($aliasaddrnesting[$address])) { - if (!is_ipaddr($address) && !is_subnet($address) && !((($alias_type == 'port') || ($alias_type == 'url_ports')) && (is_port($address) || is_portrange($address))) && is_hostname($address)) { + if (!is_ipaddr($address) && !is_subnet($address) && !((($alias_type == 'port') || ($alias_type == 'url_ports')) && is_port_or_range($address)) && is_hostname($address)) { if (!isset($filterdns["{$address}{$name}"])) { $use_filterdns = true; $filterdns["{$address}{$name}"] = "pf {$address} {$name}\n"; @@ -664,9 +677,7 @@ function filter_expand_alias($alias_name) { if (isset($config['aliases']['alias'])) { foreach ($config['aliases']['alias'] as $aliased) { if ($aliased['name'] == $alias_name) { - $aliasnesting = array(); - $aliasaddrnesting = array(); - return filter_generate_nested_alias($aliased['name'], $aliased['address'], $aliasnesting, $aliasaddrnesting); + return filter_generate_nested_alias($aliased['name']); } } } @@ -750,14 +761,12 @@ function filter_generate_aliases() { /* Setup pf groups */ if (isset($config['aliases']['alias'])) { foreach ($config['aliases']['alias'] as $aliased) { - $aliasnesting = array(); - $aliasaddrnesting = array(); if (is_numericint($aliased['name'])) { // skip aliases with numeric-only names. redmine #4289 file_notice("Filter_Reload", sprintf(gettext("Aliases with numeric-only names are not valid. Skipping alias %s"), $aliased['name'])); continue; } - $addrlist = filter_generate_nested_alias($aliased['name'], $aliased['address'], $aliasnesting, $aliasaddrnesting); + $addrlist = filter_generate_nested_alias($aliased['name']); switch ($aliased['type']) { case "host": case "network": @@ -2700,6 +2709,38 @@ function filter_generate_user_rule($rule) { file_notice("Filter_Reload", $error_text); return "# {$error_text}"; } + if ($rule['source']['port'] + && !is_port_or_range(str_replace("-", ":", $rule['source']['port']))) { + $error_text = ""; + + // It is not a literal port or port range, so alias should exist, and expand to something non-empty + if (!alias_expand($rule['source']['port'])) { + $error_text = sprintf(gettext("Unresolvable source port alias '%1\$s' for rule '%2\$s'"), $rule['source']['port'], $rule['descr']); + } else if (trim(filter_generate_nested_alias($rule['source']['port'])) == "") { + $error_text = sprintf(gettext("Empty source port alias '%1\$s' for rule '%2\$s'"), $rule['source']['port'], $rule['descr']); + } + + if ($error_text) { + file_notice("Filter_Reload", $error_text); + return "# {$error_text}"; + } + } + if ($rule['destination']['port'] + && !is_port_or_range(str_replace("-", ":", $rule['destination']['port']))) { + $error_text = ""; + + // It is not a literal port or port range, so alias should exist, and expand to something non-empty + if (!alias_expand($rule['destination']['port'])) { + $error_text = sprintf(gettext("Unresolvable destination port alias '%1\$s' for rule '%2\$s'"), $rule['destination']['port'], $rule['descr']); + } else if (trim(filter_generate_nested_alias($rule['destination']['port'])) == "") { + $error_text = sprintf(gettext("Empty destination port alias '%1\$s' for rule '%2\$s'"), $rule['destination']['port'], $rule['descr']); + } + + if ($error_text) { + file_notice("Filter_Reload", $error_text); + return "# {$error_text}"; + } + } update_filter_reload_status(gettext("Setting up pass/block rules")); $type = $rule['type']; if ($type != "pass" && $type != "block" && $type != "reject" && $type != "match") { @@ -2793,7 +2834,9 @@ function filter_generate_user_rule($rule) { if ($rule['protocol'] == "icmp" && $rule['icmptype'] && ($rule['icmptype'] != 'any')) { $icmptype_key = ($rule['ipprotocol'] == 'inet6' ? 'icmp6-type' : 'icmp-type'); - $icmptype_text = (strpos($rule['icmptype'], ",") === false ? $rule['icmptype'] : '{ ' . $rule['icmptype'] . ' }'); + // XXX: Bug #7372 + $icmptype_text = replace_element_in_list($rule['icmptype'], ',', 'skip', '39'); + $icmptype_text = (strpos($icmptype_text, ",") === false ? $icmptype_text : '{ ' . $icmptype_text . ' }'); $aline[$icmptype_key] = "{$icmptype_key} {$icmptype_text} "; } diff --git a/src/etc/inc/functions.inc b/src/etc/inc/functions.inc index 085fab1..abb3578 100644 --- a/src/etc/inc/functions.inc +++ b/src/etc/inc/functions.inc @@ -23,47 +23,17 @@ * limitations under the License. */ -/* BEGIN compatibility goo with HEAD */ -if (!function_exists("pfSenseHeader")) { - /****f* pfsense-utils/pfSenseHeader - * NAME - * pfSenseHeader - * INPUTS - * none - * RESULT - * Javascript header change or browser Location: - ******/ - function pfSenseHeader($text) { - global $_SERVER; - if (isAjax()) { - if ($_SERVER['HTTPS'] == "on") { - $protocol = "https"; - } else { - $protocol = "http"; - } - - $port = ":{$_SERVER['SERVER_PORT']}"; - if ($_SERVER['SERVER_PORT'] == "80" && $protocol == "http") { - $port = ""; - } - if ($_SERVER['SERVER_PORT'] == "443" && $protocol == "https") { - $port = ""; - } - $complete_url = "{$protocol}://{$_SERVER['HTTP_HOST']}{$port}/{$text}"; - echo "\ndocument.location.href = '{$complete_url}';\n"; - } else { - header("Location: $text"); - } - } -} -/* END compatibility goo with HEAD */ +/* + * DEPRECATED! DO NOT INCLUDE THIS FILE! + * Use individual .inc files containing the required functions instead. + */ /* include all configuration functions */ -require_once("interfaces.inc"); +require_once("certs.inc"); require_once("gwlb.inc"); -require_once("services.inc"); +require_once("interfaces.inc"); require_once("pfsense-utils.inc"); -require_once("certs.inc"); +require_once("services.inc"); require_once("system.inc"); require_once("vslb.inc"); diff --git a/src/etc/inc/globals.inc b/src/etc/inc/globals.inc index 3a55902..9166421 100644 --- a/src/etc/inc/globals.inc +++ b/src/etc/inc/globals.inc @@ -70,7 +70,7 @@ $g = array( "disablecrashreporter" => false, "crashreporterurl" => "https://crashreporter.pfsense.org/crash_reporter.php", "debug" => false, - "latest_config" => "16.2", + "latest_config" => "16.5", "minimum_ram_warning" => "101", "minimum_ram_warning_text" => "128 MB", "wan_interface_name" => "wan", diff --git a/src/etc/inc/gwlb.inc b/src/etc/inc/gwlb.inc index f3e7904..1e927f5 100644 --- a/src/etc/inc/gwlb.inc +++ b/src/etc/inc/gwlb.inc @@ -521,8 +521,13 @@ function return_gateways_status_text($byname = false, $brief = false) { return $output; } -/* Return all configured gateways on the system */ -function return_gateways_array($disabled = false, $localhost = false, $inactive = false) { +/* Return all configured gateways on the system + $disabled = true - include gateways that are disabled + $localhost = true - include "Null" entries for localhost IP addresses + $inactive = true - include gateways on inactive interfaces + $integer_index = true - index the returned array by integers 0,1,2,... instead of by GW name +*/ +function return_gateways_array($disabled = false, $localhost = false, $inactive = false, $integer_index = false) { global $config, $g; $gateways_arr = array(); @@ -630,12 +635,15 @@ function return_gateways_array($disabled = false, $localhost = false, $inactive } } unset($gateway); + + //Sort the array by GW name before moving on. + ksort($gateways_arr, SORT_STRING | SORT_FLAG_CASE); /* Loop through all interfaces with a gateway and add it to a array */ if ($disabled == false) { $iflist = get_configured_interface_with_descr(); } else { - $iflist = get_configured_interface_with_descr(false, true); + $iflist = get_configured_interface_with_descr(true); } /* Process/add dynamic v4 gateways. */ @@ -861,6 +869,11 @@ function return_gateways_array($disabled = false, $localhost = false, $inactive $gateways_arr['Null4'] = $gwlo4; $gateways_arr['Null6'] = $gwlo6; } + + if ($integer_index) { + $gateways_arr = array_values($gateways_arr); + } + return($gateways_arr); } @@ -1320,4 +1333,465 @@ function gateway_is_gwgroup_member($name) { return $members; } +/* + Check the proposed gateway settings to see if they are valid. + $gateway_settings - the proposed array of proposed gateway settings + $id - the index of the gateway proposed to be modified (otherwise "" if adding a new gateway) + $parent_ip - the IP (v4 or v6) address about to be set on the corresponding interface (if any) + $parent_sn - the subnet about to be set on the corresponding interface (if any) + (Note: the above 2 parameters allow gateway parameters to be validated concurrently with saving + an interface, before the new interface parameters are actually saved in the config.) + Return completed $input_errors array if there is any problem. + Otherwise return an empty $input_errors array +*/ +function validate_gateway($gateway_settings, $id = "", $parent_ip = "", $parent_sn = "") { + global $config; + + $a_gateways = return_gateways_array(true, false, true, true); + $input_errors = array(); + + /* input validation */ + $reqdfields = explode(" ", "name interface"); + $reqdfieldsn = array(gettext("Name"), gettext("Interface")); + + do_input_validation($gateway_settings, $reqdfields, $reqdfieldsn, $input_errors); + + if (!isset($gateway_settings['name'])) { + $input_errors[] = "A valid gateway name must be specified."; + } + if (!is_validaliasname($gateway_settings['name'])) { + $input_errors[] = invalidaliasnamemsg($gateway_settings['name'], gettext("gateway")); + } else if (isset($gateway_settings['disabled'])) { + // We have a valid gateway name that the user wants to mark as disabled. + // Check if the gateway name is used in any gateway group. + if (is_array($config['gateways']['gateway_group'])) { + foreach ($config['gateways']['gateway_group'] as $group) { + foreach ($group['item'] as $item) { + $items = explode("|", $item); + if ($items[0] == $gateway_settings['name']) { + $input_errors[] = sprintf(gettext('Gateway "%1$s" cannot be disabled because it is in use on Gateway Group "%2$s"'), $gateway_settings['name'], $group['name']); + } + } + } + } + + // Check if the gateway name is used in any enabled Static Route. + if (is_array($config['staticroutes']['route'])) { + foreach ($config['staticroutes']['route'] as $route) { + if ($route['gateway'] == $gateway_settings['name']) { + if (!isset($route['disabled'])) { + // There is a static route that uses this gateway and is enabled (not disabled). + $input_errors[] = sprintf(gettext('Gateway "%1$s" cannot be disabled because it is in use on Static Route "%2$s"'), $gateway_settings['name'], $route['network']); + } + } + } + } + } + /* skip system gateways which have been automatically added */ + if (($gateway_settings['gateway'] && (!is_ipaddr($gateway_settings['gateway'])) && ($gateway_settings['attribute'] !== "system")) && ($gateway_settings['gateway'] != "dynamic")) { + $input_errors[] = gettext("A valid gateway IP address must be specified."); + } + + if ($gateway_settings['gateway'] && is_ipaddr($gateway_settings['gateway'])) { + if (is_ipaddrv4($gateway_settings['gateway'])) { + if ($parent_ip == '') { + $parent_ip = get_interface_ip($gateway_settings['interface']); + $parent_sn = get_interface_subnet($gateway_settings['interface']); + } + if (empty($parent_ip) || empty($parent_sn)) { + $input_errors[] = gettext("Cannot add IPv4 Gateway Address because no IPv4 address could be found on the interface."); + } elseif (!isset($gateway_settings["nonlocalgateway"])) { + $subnets = array(gen_subnet($parent_ip, $parent_sn) . "/" . $parent_sn); + $vips = link_interface_to_vips($gateway_settings['interface']); + if (is_array($vips)) { + foreach ($vips as $vip) { + if (!is_ipaddrv4($vip['subnet'])) { + continue; + } + $subnets[] = gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']; + } + } + + $found = false; + foreach ($subnets as $subnet) { + if (ip_in_subnet($gateway_settings['gateway'], $subnet)) { + $found = true; + break; + } + } + + if ($found === false) { + $input_errors[] = sprintf(gettext("The gateway address %s does not lie within one of the chosen interface's subnets."), $gateway_settings['gateway']); + } + } + } else if (is_ipaddrv6($gateway_settings['gateway'])) { + /* do not do a subnet match on a link local address, it's valid */ + if (!is_linklocal($gateway_settings['gateway'])) { + if ($parent_ip == '') { + $parent_ip = get_interface_ipv6($gateway_settings['interface']); + $parent_sn = get_interface_subnetv6($gateway_settings['interface']); + } + if (empty($parent_ip) || empty($parent_sn)) { + $input_errors[] = gettext("Cannot add IPv6 Gateway Address because no IPv6 address could be found on the interface."); + } elseif (!isset($gateway_settings["nonlocalgateway"])) { + $subnets = array(gen_subnetv6($parent_ip, $parent_sn) . "/" . $parent_sn); + $vips = link_interface_to_vips($gateway_settings['interface']); + if (is_array($vips)) { + foreach ($vips as $vip) { + if (!is_ipaddrv6($vip['subnet'])) { + continue; + } + $subnets[] = gen_subnetv6($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']; + } + } + + $found = false; + foreach ($subnets as $subnet) { + if (ip_in_subnet($gateway_settings['gateway'], $subnet)) { + $found = true; + break; + } + } + + if ($found === false) { + $input_errors[] = sprintf(gettext("The gateway address %s does not lie within one of the chosen interface's subnets."), $gateway_settings['gateway']); + } + } + } + } + + if (!empty($config['interfaces'][$gateway_settings['interface']]['ipaddr'])) { + if (is_ipaddr($config['interfaces'][$gateway_settings['interface']]['ipaddr']) && (empty($gateway_settings['gateway']) || $gateway_settings['gateway'] == "dynamic")) { + $input_errors[] = gettext("Dynamic gateway values cannot be specified for interfaces with a static IPv4 configuration."); + } + } + if (!empty($config['interfaces'][$gateway_settings['interface']]['ipaddrv6'])) { + if (is_ipaddr($config['interfaces'][$gateway_settings['interface']]['ipaddrv6']) && (empty($gateway_settings['gateway']) || $gateway_settings['gateway'] == "dynamic")) { + $input_errors[] = gettext("Dynamic gateway values cannot be specified for interfaces with a static IPv6 configuration."); + } + } + } + if (($gateway_settings['monitor'] != "") && ($gateway_settings['monitor'] != "dynamic")) { + validateipaddr($gateway_settings['monitor'], IPV4V6, "Monitor IP", $input_errors, false); + } + if (isset($gateway_settings['data_payload']) && is_numeric($gateway_settings['data_payload']) && $gateway_settings['data_payload'] < 0) { + $input_errors[] = gettext("A valid data payload must be specified."); + } + /* only allow correct IPv4 and IPv6 gateway addresses */ + if (($gateway_settings['gateway'] <> "") && is_ipaddr($gateway_settings['gateway']) && $gateway_settings['gateway'] != "dynamic") { + if (is_ipaddrv6($gateway_settings['gateway']) && ($gateway_settings['ipprotocol'] == "inet")) { + $input_errors[] = sprintf(gettext("The IPv6 gateway address '%s' can not be used as a IPv4 gateway."), $gateway_settings['gateway']); + } + if (is_ipaddrv4($gateway_settings['gateway']) && ($gateway_settings['ipprotocol'] == "inet6")) { + $input_errors[] = sprintf(gettext("The IPv4 gateway address '%s' can not be used as a IPv6 gateway."), $gateway_settings['gateway']); + } + } + /* only allow correct IPv4 and IPv6 monitor addresses */ + if (($gateway_settings['monitor'] <> "") && is_ipaddr($gateway_settings['monitor']) && $gateway_settings['monitor'] != "dynamic") { + if (is_ipaddrv6($gateway_settings['monitor']) && ($gateway_settings['ipprotocol'] == "inet")) { + $input_errors[] = sprintf(gettext("The IPv6 monitor address '%s' can not be used on a IPv4 gateway."), $gateway_settings['monitor']); + } + if (is_ipaddrv4($gateway_settings['monitor']) && ($gateway_settings['ipprotocol'] == "inet6")) { + $input_errors[] = sprintf(gettext("The IPv4 monitor address '%s' can not be used on a IPv6 gateway."), $gateway_settings['monitor']); + } + } + + if (isset($gateway_settings['name'])) { + /* check for overlaps */ + foreach ($a_gateways as $gateway) { + if (isset($id) && ($a_gateways[$id]) && ($a_gateways[$id] === $gateway)) { + if ($gateway['name'] != $gateway_settings['name']) { + $input_errors[] = gettext("Changing name on a gateway is not allowed."); + } + continue; + } + if ($gateway_settings['name'] <> "") { + if (($gateway['name'] <> "") && ($gateway_settings['name'] == $gateway['name']) && ($gateway['attribute'] !== "system")) { + $input_errors[] = sprintf(gettext('The gateway name "%s" already exists.'), $gateway_settings['name']); + break; + } + } + if (is_ipaddr($gateway_settings['gateway'])) { + if (($gateway['gateway'] <> "") && ($gateway_settings['gateway'] == $gateway['gateway']) && ($gateway['attribute'] !== "system")) { + $input_errors[] = sprintf(gettext('The gateway IP address "%s" already exists.'), $gateway_settings['gateway']); + break; + } + } + if (is_ipaddr($gateway_settings['monitor'])) { + if (($gateway['monitor'] <> "") && ($gateway_settings['monitor'] == $gateway['monitor']) && ($gateway['attribute'] !== "system")) { + $input_errors[] = sprintf(gettext('The monitor IP address "%s" is already in use. A different monitor IP must be chosen.'), $gateway_settings['monitor']); + break; + } + } + } + } + + /* input validation of dpinger advanced parameters */ + + $dpinger_default = return_dpinger_defaults(); + $latencylow = $dpinger_default['latencylow']; + if ($gateway_settings['latencylow']) { + if (!is_numeric($gateway_settings['latencylow'])) { + $input_errors[] = gettext("The low latency threshold needs to be a numeric value."); + } else if ($gateway_settings['latencylow'] < 1) { + $input_errors[] = gettext("The low latency threshold needs to be positive."); + } else { + $latencylow = $gateway_settings['latencylow']; + } + } + + $latencyhigh = $dpinger_default['latencyhigh']; + if ($gateway_settings['latencyhigh']) { + if (!is_numeric($gateway_settings['latencyhigh'])) { + $input_errors[] = gettext("The high latency threshold needs to be a numeric value."); + } else if ($gateway_settings['latencyhigh'] < 1) { + $input_errors[] = gettext("The high latency threshold needs to be positive."); + } else { + $latencyhigh = $gateway_settings['latencyhigh']; + } + } + + $losslow = $dpinger_default['losslow']; + if ($gateway_settings['losslow']) { + if (!is_numeric($gateway_settings['losslow'])) { + $input_errors[] = gettext("The low Packet Loss threshold needs to be a numeric value."); + } else if ($gateway_settings['losslow'] < 1) { + $input_errors[] = gettext("The low Packet Loss threshold needs to be positive."); + } else if ($gateway_settings['losslow'] >= 100) { + $input_errors[] = gettext("The low Packet Loss threshold needs to be less than 100."); + } else { + $losslow = $gateway_settings['losslow']; + } + } + + $losshigh = $dpinger_default['losshigh']; + if ($gateway_settings['losshigh']) { + if (!is_numeric($gateway_settings['losshigh'])) { + $input_errors[] = gettext("The high Packet Loss threshold needs to be a numeric value."); + } else if ($gateway_settings['losshigh'] < 1) { + $input_errors[] = gettext("The high Packet Loss threshold needs to be positive."); + } else if ($gateway_settings['losshigh'] > 100) { + $input_errors[] = gettext("The high Packet Loss threshold needs to be 100 or less."); + } else { + $losshigh = $gateway_settings['losshigh']; + } + } + + $time_period = $dpinger_default['time_period']; + if ($gateway_settings['time_period']) { + if (!is_numeric($gateway_settings['time_period'])) { + $input_errors[] = gettext("The time period over which results are averaged needs to be a numeric value."); + } else if ($gateway_settings['time_period'] < 1) { + $input_errors[] = gettext("The time period over which results are averaged needs to be positive."); + } else { + $time_period = $gateway_settings['time_period']; + } + } + + $interval = $dpinger_default['interval']; + if ($gateway_settings['interval']) { + if (!is_numeric($gateway_settings['interval'])) { + $input_errors[] = gettext("The probe interval needs to be a numeric value."); + } else if ($gateway_settings['interval'] < 1) { + $input_errors[] = gettext("The probe interval needs to be positive."); + } else { + $interval = $gateway_settings['interval']; + } + } + + $loss_interval = $dpinger_default['loss_interval']; + if ($gateway_settings['loss_interval']) { + if (!is_numeric($gateway_settings['loss_interval'])) { + $input_errors[] = gettext("The loss interval needs to be a numeric value."); + } else if ($gateway_settings['loss_interval'] < 1) { + $input_errors[] = gettext("The loss interval setting needs to be positive."); + } else { + $loss_interval = $gateway_settings['loss_interval']; + } + } + + $alert_interval = $dpinger_default['alert_interval']; + if ($gateway_settings['alert_interval']) { + if (!is_numeric($gateway_settings['alert_interval'])) { + $input_errors[] = gettext("The alert interval needs to be a numeric value."); + } else if ($gateway_settings['alert_interval'] < 1) { + $input_errors[] = gettext("The alert interval setting needs to be positive."); + } else { + $alert_interval = $gateway_settings['alert_interval']; + } + } + + if ($latencylow >= $latencyhigh) { + $input_errors[] = gettext( + "The high latency threshold needs to be greater than the low latency threshold"); + } + + if ($losslow >= $losshigh) { + $input_errors[] = gettext( + "The high packet loss threshold needs to be higher than the low packet loss threshold"); + } + + // If the loss interval is less than latencyhigh, then high latency could never be recorded + // because those high latency packets would be considered as lost. So do not allow that. + if ($latencyhigh > $loss_interval) { + $input_errors[] = gettext("The loss interval needs to be greater than or equal to the high latency threshold."); + } + + // Ensure that the time period is greater than 2 times the probe interval plus the loss interval. + if (($interval * 2 + $loss_interval) >= $time_period) { + $input_errors[] = gettext("The time period needs to be greater than twice the probe interval plus the loss interval."); + } + + // There is no point recalculating the average latency and loss more often than the probe interval. + // So the alert interval needs to be >= probe interval. + if ($interval > $alert_interval) { + $input_errors[] = gettext("The alert interval needs to be greater than or equal to the probe interval."); + } + + return $input_errors; +} + +// Save gateway settings. +// $gateway_settings - the array of gateway setting parameters +// $realid - the index of the gateway to be modified (otherwise "" if adding a new gateway) + +// This function is responsible to: +// Setup the gateway parameter structure from the gateway settings input parameter +// Save the structure into the config +// Remove any run-time settings from gateway parameters that are changed (e.g. remove routes to addresses that are changing) + +// A subsequent "apply" step will implement the added/changed gateway. + +function save_gateway($gateway_settings, $realid = "") { + global $config; + + $a_gateway_item = &$config['gateways']['gateway_item']; + $reloadif = ""; + $gateway = array(); + + if (empty($gateway_settings['interface'])) { + $gateway['interface'] = $gateway_settings['friendlyiface']; + } else { + $gateway['interface'] = $gateway_settings['interface']; + } + if (is_ipaddr($gateway_settings['gateway'])) { + $gateway['gateway'] = $gateway_settings['gateway']; + } else { + $gateway['gateway'] = "dynamic"; + } + $gateway['name'] = $gateway_settings['name']; + $gateway['weight'] = $gateway_settings['weight']; + $gateway['ipprotocol'] = $gateway_settings['ipprotocol']; + if ($gateway_settings['interval']) { + $gateway['interval'] = $gateway_settings['interval']; + } + + if ($gateway_settings['time_period']) { + $gateway['time_period'] = $gateway_settings['time_period']; + } + if ($gateway_settings['alert_interval']) { + $gateway['alert_interval'] = $gateway_settings['alert_interval']; + } + + $gateway['descr'] = $gateway_settings['descr']; + if ($gateway_settings['monitor_disable'] == "yes") { + $gateway['monitor_disable'] = true; + } + if ($gateway_settings['action_disable'] == "yes") { + $gateway['action_disable'] = true; + } + if ($gateway_settings['nonlocalgateway'] == "yes") { + $gateway['nonlocalgateway'] = true; + } + if ($gateway_settings['force_down'] == "yes") { + $gateway['force_down'] = true; + } + if (is_ipaddr($gateway_settings['monitor'])) { + $gateway['monitor'] = $gateway_settings['monitor']; + } + if (isset($gateway_settings['data_payload']) && $gateway_settings['data_payload'] > 0) { + $gateway['data_payload'] = $gateway_settings['data_payload']; + } + + /* NOTE: If gateway ip is changed need to cleanup the old static interface route */ + if ($gateway_settings['monitor'] != "dynamic" && !empty($a_gateway_item[$realid]) && is_ipaddr($a_gateway_item[$realid]['gateway']) && + $gateway['gateway'] != $a_gateway_item[$realid]['gateway'] && + isset($a_gateway_item[$realid]["nonlocalgateway"])) { + $realif = get_real_interface($a_gateway_item[$realid]['interface']); + $inet = (!is_ipaddrv4($a_gateway_item[$realid]['gateway']) ? "-inet6" : "-inet"); + $cmd = "/sbin/route delete $inet " . escapeshellarg($a_gateway_item[$realid]['gateway']) . " -iface " . escapeshellarg($realif); + mwexec($cmd); + } + + /* NOTE: If monitor ip is changed need to cleanup the old static route */ + if ($gateway_settings['monitor'] != "dynamic" && !empty($a_gateway_item[$realid]) && is_ipaddr($a_gateway_item[$realid]['monitor']) && + $gateway_settings['monitor'] != $a_gateway_item[$realid]['monitor'] && $gateway['gateway'] != $a_gateway_item[$realid]['monitor']) { + if (is_ipaddrv4($a_gateway_item[$realid]['monitor'])) { + mwexec("/sbin/route delete " . escapeshellarg($a_gateway_item[$realid]['monitor'])); + } else { + mwexec("/sbin/route delete -inet6 " . escapeshellarg($a_gateway_item[$realid]['monitor'])); + } + } + + if ($gateway_settings['defaultgw'] == "yes" || $gateway_settings['defaultgw'] == "on") { + $i = 0; + /* remove the default gateway bits for all gateways with the same address family */ + foreach ($a_gateway_item as $gw) { + if ($gateway['ipprotocol'] == $gw['ipprotocol']) { + unset($config['gateways']['gateway_item'][$i]['defaultgw']); + if ($gw['interface'] != $gateway_settings['interface'] && $gw['defaultgw']) { + $reloadif = $gw['interface']; + } + } + $i++; + } + $gateway['defaultgw'] = true; + } + + if ($gateway_settings['latencylow']) { + $gateway['latencylow'] = $gateway_settings['latencylow']; + } + if ($gateway_settings['latencyhigh']) { + $gateway['latencyhigh'] = $gateway_settings['latencyhigh']; + } + if ($gateway_settings['losslow']) { + $gateway['losslow'] = $gateway_settings['losslow']; + } + if ($gateway_settings['losshigh']) { + $gateway['losshigh'] = $gateway_settings['losshigh']; + } + if ($gateway_settings['loss_interval']) { + $gateway['loss_interval'] = $gateway_settings['loss_interval']; + } + + if (isset($gateway_settings['disabled'])) { + $gateway['disabled'] = true; + /* Check if the gateway was enabled but changed to disabled. */ + if ((isset($realid) && $a_gateway_item[$realid]) && ($a_gateway_item[$realid]['disabled'] == false)) { + /* If the disabled gateway was the default route, remove the default route */ + if (is_ipaddr($gateway['gateway']) && + isset($gateway['defaultgw'])) { + $inet = (!is_ipaddrv4($gateway['gateway']) ? '-inet6' : '-inet'); + mwexec("/sbin/route delete {$inet} default"); + } + } + } else { + unset($gateway['disabled']); + } + + /* when saving the manual gateway we use the attribute which has the corresponding id */ + if (isset($realid) && $a_gateway_item[$realid]) { + $a_gateway_item[$realid] = $gateway; + } else { + $a_gateway_item[] = $gateway; + } + + mark_subsystem_dirty('staticroutes'); + + write_config(); + + if (!empty($reloadif)) { + send_event("interface reconfigure {$reloadif}"); + } +} ?> diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index e91fbe0..8d7843f 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -38,6 +38,27 @@ function interfaces_bring_up($interface) { } /* + * Validate comma-separated list of IPv4 addresses + */ +function validate_ipv4_list($value) { + $value = trim($value); + + if (empty($value)) { + return false; + } + + $list = explode(',', $value); + + foreach ($list as $ip) { + if (!is_ipaddrv4($ip)) { + return false; + } + } + + return true; +} + +/* * Return the interface array */ function get_interface_arr($flush = false) { @@ -1300,7 +1321,7 @@ function interface_bring_down($interface = "wan", $destroy = false, $ifacecfg = switch ($ifcfg['ipaddrv6']) { case "slaac": case "dhcp6": - kill_dhcp6client_process($realif, isset($ifcfg['dhcp6norelease'])); + kill_dhcp6client_process($realif, $destroy, false); unlink_if_exists("{$g['varetc_path']}/dhcp6c_{$interface}.conf"); unlink_if_exists("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh"); unlink_if_exists("{$g['varetc_path']}/rtsold_{$realifv6}_script.sh"); @@ -2502,7 +2523,7 @@ function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) { $baseif = interface_get_wireless_base($ifcfg['if']); // Sync shared settings for assigned clones - $iflist = get_configured_interface_list(false, true); + $iflist = get_configured_interface_list(true); foreach ($iflist as $if) { if ($baseif == interface_get_wireless_base($config['interfaces'][$if]['if']) && $ifcfg['if'] != $config['interfaces'][$if]['if']) { if (isset($config['interfaces'][$if]['wireless']['standard']) || $sync_changes) { @@ -3043,36 +3064,72 @@ function find_dhcp6c_process($interface) { return intval($pid); } -function kill_dhcp6client_process($interface, $norelease) { +function kill_dhcp6client_process($interface, $force, $release = false) { global $g; + $i = 0; + + /* + Beware of the following: Reason, the interface may be down, but + dhcp6c may still be running, it just complains it cannot send + and carries on. Commented out as will stop the call to kill. + if (empty($interface) || !does_interface_exist($interface)) { return; } + */ - if (($pid = find_dhcp6c_process($interface)) != 0) { - /* - * Kill -9 caused the pid to get left behind, also if we need a - * relase sent then it needs to be -15, this then allows dhcp6c - * to send the release, it will also clean up after itself - */ - $sig = (isset($norelease) ? SIGKILL : SIGTERM); - posix_kill($pid, $sig); - if(!isset($norelease)) { - /* - * Allow dhcp6c to send release and exit gracefully if - * needed. - */ - sleep(2); - } + /*********** Notes on signals for dhcp6c and this function ************* + + If we have Taken the WAN interface down, then dhcp6c sits there sending + a release and waiting for the response that never comes. + So we need to tell it that the interface is down and to just die quickly + otherwise a new client may launch and we have duplicate proceses. + In this case use SIGUSR1. + + If we want to exit normally obeying the no release flag then use SIGTERM. + If we want to exit with a release overiding the no release flag then + use SIGUSR2. + + If $Force is true it will use SIGUSR1, thus forcing dhcp6c to + exit quickly without sending release signals. + + If $Force is set to false and $release is also set to false dhcp6c will + follow the no-release flag. + + If $Force is set to false and $release is true then dhcp6c will send a + release regardless of the no-release flag. + ***********************************************************************/ + + if ($force == true) { + $psig=SIGUSR1; + } else if ($release == false) { + $psig=SIGTERM; + } else { + $psig=SIGUSR2; } - /* Clear the RTSOLD script created lock & tidy up */ + + while ((($pid = find_dhcp6c_process($interface)) != 0) && ($i < 3)) { + /* 3rd time make it die for sure */ + $sig = ($i == 2 ? SIGKILL : $psig); + posix_kill($pid, $sig); + sleep(1); + $i++; + } + /* Clear the RTSOLD script created lock & tidy up */ unlink_if_exists("/tmp/dhcp6c_{$interface}_lock"); - /* just in case! */ - unlink_if_exists("{$g['varrun_path']}/dhcp6c_{$interface}.pid"); + unlink_if_exists("{$g['varrun_path']}/dhcp6c_{$interface}.pid"); // just in case! +} +function reset_dhcp6client_process($interface) { + + $pid = find_dhcp6c_process($interface); + + if($pid != 0) { + posix_kill($pid, SIGHUP); + } } -function run_dhcp6client_process($interface, $wancfg) { +function run_dhcp6client_process($interface, $interface_name, $wancfg) { global $g; $debugOption = isset($wancfg['dhcp6debug']) ? "-D" : "-d"; @@ -3086,20 +3143,19 @@ function run_dhcp6client_process($interface, $wancfg) { * It should not happen as the process should have been killed and the * lock deleted. */ + if (!file_exists("/tmp/dhcp6c_{$interface}_lock")) { - kill_dhcp6client_process($interface, - isset($wancfg['dhcp6norelease'])); - + kill_dhcp6client_process($interface, true); /* Lock it to avoid multiple runs */ touch("/tmp/dhcp6c_{$interface}_lock"); mwexec("/usr/local/sbin/dhcp6c {$debugOption} " . "{$noreleaseOption} " . - "-c {$g['varetc_path']}/dhcp6c_wan.conf " . + "-c {$g['varetc_path']}/dhcp6c_{$interface_name}.conf " . "-p {$g['varrun_path']}/dhcp6c_{$interface}.pid " . $interface); log_error(sprintf(gettext( "Starting dhcp6 client for interface wan %s in DHCP6 without RA mode"), - $wanif)); + $interface)); } } @@ -3269,8 +3325,10 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven if ($g['debug']) { log_error(sprintf(gettext("Deny router advertisements for interface %s"), $interface)); } - mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv", true); - + if (isset($wancfg['dhcp6usev4iface']) || $wancfg['ipaddr']==='ppp') + { + mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv", true); + } /* wireless configuration? */ if (is_array($wancfg['wireless'])) { interface_wireless_configure($realif, $wancfg, $wancfg['wireless']); @@ -3949,6 +4007,13 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { log_error(gettext("Failed to write user DUID file!")); } } + + /* accept router advertisements for this interface */ + /* Moved to early in the function as sometimes interface not ready */ + /* RTSOLD fails as interface does not accept ..... */ + + log_error("Accept router advertisements on interface {$wanif} "); + mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv"); if ($wancfg['adv_dhcp6_config_file_override']) { // DHCP6 Config File Override @@ -4026,6 +4091,9 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { } } + $debugOption = isset($wancfg['dhcp6debug']) ? "-D" : "-d"; + $noreleaseOption = isset($wancfg['dhcp6norelease']) ? "-n" : ""; + /* wide-dhcp6c works for now. */ if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}.conf", $dhcp6cconf)) { printf("Error: cannot open dhcp6c_{$interface}.conf in interface_dhcpv6_configure() for writing.\n"); @@ -4034,20 +4102,55 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { } unset($dhcp6cconf); - /* - * Script create for dhcp6withoutRA mode. - * dhcp6c will launch rtsold. rtsold will then run the wan ipv6 - * configure - */ - $dhcp6cscriptwithoutra = "#!/bin/sh\n"; + /*************** Script Debug Logging *************************** + Both dhcp6 scripts now have a logging message built in. + These logging messages ONLY appear if dhcp6c debug logging is set. + The logging messages appear in the dhcp section of the logs, + not in system. + + These scripts now also take advantage of the REASON= env vars + supplied by dhcp6c. + ****************************************************************/ + + /* Script create for dhcp6withoutRA mode */ + /* dhcp6c will launch rtsold. rtsold will then run the wan ipv6 configure */ + $dhcp6cscriptwithoutra = "#!/bin/sh\n"; $dhcp6cscriptwithoutra .= "# This shell script launches rtsold.\n"; $dhcp6cscriptwithoutra .= "dmips=\${new_domain_name_servers}\n"; $dhcp6cscriptwithoutra .= "dmnames=\${new_domain_name}\n"; + $dhcp6cscriptwithoutra .= "dreason=\${REASON}\n"; // Need to pass params to the final script $dhcp6cscriptwithoutra .= "echo \$dmips > /tmp/{$wanif}_domain_name_servers\n"; $dhcp6cscriptwithoutra .= "echo \$dmnames > /tmp/{$wanif}_new_domain_name\n"; + $dhcp6cscriptwithoutra .= "echo \$dreason > /tmp/{$wanif}_reason\n"; + $dhcp6cscriptwithoutra .= "case \$REASON in\n"; + $dhcp6cscriptwithoutra .= "REQUEST)\n"; + $dhcp6cscriptwithoutra .= "/bin/sleep 2\n"; $dhcp6cscriptwithoutra .= "/usr/sbin/rtsold -1 -p {$g['varrun_path']}/rtsold_{$wanif}.pid -O {$g['varetc_path']}/rtsold_{$wanif}_script.sh {$wanif}\n"; - + if ($debugOption == '-D') { + $dhcp6cscriptwithoutra .= "/usr/bin/logger -t dhcp6c \"dhcp6c REQUEST on {$wanif} - running rc.newwanipv6\"\n"; + } + $dhcp6cscriptwithoutra .= ";;\n"; + $dhcp6cscriptwithoutra .= "REBIND)\n"; + if ($debugOption == '-D') { + $dhcp6cscriptwithoutra .= "/usr/bin/logger -t dhcp6c \"dhcp6c rebind on {$wanif}\"\n"; + } + $dhcp6cscriptwithoutra .= ";;\n"; + if (isset($wancfg['dhcp6norelease'])) { + $dhcp6cscriptwithoutra .= "EXIT)\n"; + } else { + $dhcp6cscriptwithoutra .= "RELEASE)\n"; + } + if ($debugOption == '-D') { + $dhcp6cscriptwithoutra .= "/usr/bin/logger -t dhcp6c \"dhcp6c EXIT or RELEASE on {$wanif} running rc.newwanipv6\"\n"; + } + $dhcp6cscriptwithoutra .= "/usr/local/sbin/fcgicli -f /etc/rc.newwanipv6 -d \"interface={$wanif}&dmnames=\${dmnames}&dmips=\${dmips}\"\n"; + $dhcp6cscriptwithoutra .= ";;\n"; + $dhcp6cscriptwithoutra .= "RENEW|INFO)\n"; + if ($debugOption == '-D') { + $dhcp6cscriptwithoutra .= "/usr/bin/logger -t dhcp6c \"dhcp6c renew, no change - bypassing update on {$wanif}\"\n"; + } + $dhcp6cscriptwithoutra .= "esac\n"; if (!@file_put_contents( "{$g['varetc_path']}/dhcp6c_{$interface}_dhcp6withoutra_script.sh", $dhcp6cscriptwithoutra)) { @@ -4057,6 +4160,7 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { unset($dhcp6cscriptwithoutra); return 1; } + unset($dhcp6cscriptwithoutra); @chmod( "{$g['varetc_path']}/dhcp6c_{$interface}_dhcp6withoutra_script.sh", @@ -4071,12 +4175,41 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { if (!isset($wancfg['dhcp6withoutra'])) { $dhcp6cscript .= "dmips=\${new_domain_name_servers}\n"; $dhcp6cscript .= "dmnames=\${new_domain_name}\n"; + $dhcp6cscript .= "case \$REASON in\n"; + $dhcp6cscript .= "REQUEST)\n"; + $dhcp6cscript .= "/usr/local/sbin/fcgicli -f /etc/rc.newwanipv6 -d \"interface={$wanif}&dmnames=\${dmnames}&dmips=\${dmips}\"\n"; + if ($debugOption == '-D') { + $dhcp6cscript .= "/usr/bin/logger -t dhcp6c \"dhcp6c REQUEST on {$wanif} - running rc.newwanipv6\"\n"; + } + $dhcp6cscript .= ";;\n"; + $dhcp6cscript .= "REBIND)\n"; + if ($debugOption == '-D') { + $dhcp6cscript .= "/usr/bin/logger -t dhcp6c \"dhcp6c rebind on {$wanif}\"\n"; + } + $dhcp6cscript .= ";;\n"; + if (isset($wancfg['dhcp6norelease'])) { + $dhcp6cscript .= "EXIT)\n"; + } else { + $dhcp6cscript .= "RELEASE)\n"; + } + if ($debugOption == '-D') { + $dhcp6cscript .= "/usr/bin/logger -t dhcp6c \"dhcp6c EXIT or RELEASE on {$wanif} running rc.newwanipv6\"\n"; + } + $dhcp6cscript .= "/usr/local/sbin/fcgicli -f /etc/rc.newwanipv6 -d \"interface={$wanif}&dmnames=\${dmnames}&dmips=\${dmips}\"\n"; + $dhcp6cscript .= ";;\n"; + $dhcp6cscript .= "RENEW|INFO)\n"; + if ($debugOption == '-D') { + $dhcp6cscript .= "/usr/bin/logger -t dhcp6c \"dhcp6c renew, no change - bypassing update on {$wanif}\"\n"; + } + $dhcp6cscript .= "esac\n"; } else { // Need to get the paramaters from the dhcp6cwithoutRA run $dhcp6cscript .= "dmips=\$(cat \"/tmp/{$wanif}_domain_name_servers\")\n"; $dhcp6cscript .= "dmnames=\$(cat \"/tmp/{$wanif}_new_domain_name\")\n"; + $dhcp6cscript .= "/bin/sleep 1\n"; + $dhcp6cscript .= "/usr/local/sbin/fcgicli -f /etc/rc.newwanipv6 -d \"interface={$wanif}&dmnames=\${dmnames}&dmips=\${dmips}\"\n"; } - $dhcp6cscript .= "/usr/local/sbin/fcgicli -f /etc/rc.newwanipv6 -d \"interface={$wanif}&dmnames=\${dmnames}&dmips=\${dmips}\"\n"; + /* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */ if (!@file_put_contents("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", $dhcp6cscript)) { printf("Error: cannot open dhcp6c_{$interface}_script.sh in interface_dhcpv6_configure() for writing.\n"); @@ -4086,9 +4219,6 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { unset($dhcp6cscript); @chmod("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", 0755); - $debugOption = isset($wancfg['dhcp6debug']) ? "-D" : "-d"; - $noreleaseOption = isset($wancfg['dhcp6norelease']) ? "-n" : ""; - $rtsoldscript = "#!/bin/sh\n"; $rtsoldscript .= "# This shell script launches dhcp6c and configured gateways for this interface.\n"; $rtsoldscript .= "echo $2 > {$g['tmp_path']}/{$wanif}_routerv6\n"; @@ -4106,22 +4236,24 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { * of dhcp6c being launched */ $rtsoldscript .= "if [ ! -f /tmp/dhcp6c_{$wanif}_lock ]; then\n"; - $rtsoldscript .= "\tif [ -f {$g['varrun_path']}/dhcp6c_{$wanif}.pid ]; then\n"; - $rtsoldscript .= "\t\t/bin/pkill -F {$g['varrun_path']}/dhcp6c_{$wanif}.pid\n"; - $rtsoldscript .= "\t\t/bin/rm -f {$g['varrun_path']}/dhcp6c_{$wanif}.pid\n"; - $rtsoldscript .= "\t\t/bin/sleep 1\n"; - $rtsoldscript .= "\tfi\n"; /* * Create the lock file, trying to prevent multiple instances * of dhcp6c being launched */ $rtsoldscript .= "\t/usr/bin/touch /tmp/dhcp6c_{$wanif}_lock\n"; + $rtsoldscript .= "\tif [ -f {$g['varrun_path']}/dhcp6c_{$wanif}.pid ]; then\n"; + $rtsoldscript .= "\t\t/bin/pkill -F {$g['varrun_path']}/dhcp6c_{$wanif}.pid\n"; + $rtsoldscript .= "\t\t/bin/rm -f {$g['varrun_path']}/dhcp6c_{$wanif}.pid\n"; + $rtsoldscript .= "\t\t/bin/sleep 1\n"; + $rtsoldscript .= "\tfi\n"; $rtsoldscript .= "\t/usr/local/sbin/dhcp6c {$debugOption} " . "{$noreleaseOption} -c {$g['varetc_path']}/dhcp6c_{$interface}.conf " . "-p {$g['varrun_path']}/dhcp6c_{$wanif}.pid {$wanif}\n"; $rtsoldscript .= "\t/usr/bin/logger -t rtsold \"Starting dhcp6 client for interface {$interface}({$wanif})\"\n"; $rtsoldscript .= "else\n"; - $rtsoldscript .= "\t/usr/bin/logger -t rtsold \"RTSOLD Lock in place\"\n"; + $rtsoldscript .= "\t/usr/bin/logger -t rtsold \"RTSOLD Lock in place - sending SIGHUP to dhcp6c\"\n"; + $rtsoldscript .= "\tdhcp6c_pid=\$(cat \"{$g['varrun_path']}/dhcp6c_{$wanif}.pid\")\n"; + $rtsoldscript .= "\t/bin/kill -1 \${dhcp6c_pid}\n"; $rtsoldscript .= "fi\n"; } else { /* @@ -4141,12 +4273,9 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { unset($rtsoldscript); @chmod("{$g['varetc_path']}/rtsold_{$wanif}_script.sh", 0755); - /* accept router advertisements for this interface */ - log_error("Accept router advertisements on interface {$wanif} "); - mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv"); - if (isvalidpid("{$g['varrun_path']}/rtsold_{$wanif}.pid")) { killbypid("{$g['varrun_path']}/rtsold_{$wanif}.pid"); + log_error("Killing running rtsold process"); sleep(2); } @@ -4171,7 +4300,7 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { * Otherwise it is not ready to accept and will fail. */ sleep(3); - run_dhcp6client_process($wanif,$wancfg); + run_dhcp6client_process($wanif,$interface,$wancfg); } } else { /* @@ -4179,6 +4308,8 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { * ( it does not background, it exits! ) It will launch dhcp6c * if dhcpwihtoutra is not set */ + log_error("Starting rtsold process"); + sleep(2); mwexec("/usr/sbin/rtsold -1 " . "-p {$g['varrun_path']}/rtsold_{$wanif}.pid " . "-O {$g['varetc_path']}/rtsold_{$wanif}_script.sh " . @@ -4403,7 +4534,7 @@ initial-interval 1; script "/usr/local/sbin/pfSense-dhclient-script"; EOD; - if (is_ipaddrv4($wancfg['dhcprejectfrom'])) { + if (validate_ipv4_list($wancfg['dhcprejectfrom'])) { $dhclientconf .= <<<EOD reject {$wancfg['dhcprejectfrom']}; @@ -4675,7 +4806,7 @@ function convert_real_interface_to_friendly_interface_name($interface = "wan", $ /* XXX: For speed reasons reference directly the interface array */ $ifdescrs = &$config['interfaces']; - //$ifdescrs = get_configured_interface_list(false, true); + //$ifdescrs = get_configured_interface_list(true); foreach ($ifdescrs as $if => $ifname) { if ($if == $interface || $ifname['if'] == $interface) { @@ -4752,7 +4883,7 @@ function convert_friendly_interface_to_friendly_descr($interface) { return get_interface_linklocal($interface); } else { /* if list */ - $ifdescrs = get_configured_interface_with_descr(false, true); + $ifdescrs = get_configured_interface_with_descr(true); foreach ($ifdescrs as $if => $ifname) { if ($if == $interface || $ifname == $interface) { return $ifname; @@ -5854,12 +5985,13 @@ function is_altq_capable($int) { * 20150328 - removed wireless drivers - ath, awi, bwn, iwi, ipw, ral, rum, run, wi - for now. redmine #4406 */ $capable = array("ae", "age", "alc", "ale", "an", "aue", "axe", "bce", - "bfe", "bge", "bridge", "cas", "cpsw", "cxl", "dc", "de", "ed", "em", "ep", "epair", "et", "fxp", "gem", - "hme", "hn", "igb", "ix", "jme", "le", "lem", "msk", "mxge", "my", "nfe", - "nge", "npe", "nve", "re", "rl", "sf", "sge", "sis", "sk", - "ste", "stge", "ti", "txp", "udav", "ural", "vge", "vmx", "vr", "vte", "xl", - "ndis", "tun", "ovpns", "ovpnc", "vlan", "pppoe", "pptp", "ng", - "l2tp", "ppp", "vtnet"); + "bfe", "bge", "bridge", "cas", "cpsw", "cxl", "dc", "de", + "ed", "em", "ep", "epair", "et", "fxp", "gem", "hme", "hn", + "igb", "ix", "jme", "l2tp", "le", "lem", "msk", "mxge", "my", + "ndis", "nfe", "ng", "nge", "npe", "nve", "ovpnc", "ovpns", + "ppp", "pppoe", "pptp", "re", "rl", "sf", "sge", "sis", "sk", + "ste", "stge", "ti", "tun", "txp", "udav", "ural", "vge", + "vlan", "vmx", "vr", "vte", "vtnet", "xl"); $int_family = remove_ifindex($int); diff --git a/src/etc/inc/pfsense-utils.inc b/src/etc/inc/pfsense-utils.inc index 60507e8..e86e83d 100644 --- a/src/etc/inc/pfsense-utils.inc +++ b/src/etc/inc/pfsense-utils.inc @@ -130,6 +130,37 @@ function get_dns_servers() { return array_unique($dns_servers); } +/****f* pfsense-utils/pfSenseHeader + * NAME + * pfSenseHeader + * INPUTS + * none + * RESULT + * Javascript header change or browser Location: + ******/ +function pfSenseHeader($text) { + global $_SERVER; + if (isAjax()) { + if ($_SERVER['HTTPS'] == "on") { + $protocol = "https"; + } else { + $protocol = "http"; + } + + $port = ":{$_SERVER['SERVER_PORT']}"; + if ($_SERVER['SERVER_PORT'] == "80" && $protocol == "http") { + $port = ""; + } + if ($_SERVER['SERVER_PORT'] == "443" && $protocol == "https") { + $port = ""; + } + $complete_url = "{$protocol}://{$_SERVER['HTTP_HOST']}{$port}/{$text}"; + echo "\ndocument.location.href = '{$complete_url}';\n"; + } else { + header("Location: $text"); + } +} + /****f* pfsense-utils/get_css_files * NAME * get_css_files - get a list of the available CSS files (themes) @@ -255,6 +286,25 @@ function gen_dashboardcolumns_field(&$section, $value) { )); } +/****f* pfsense-utils/gen_interfacessort_field + * NAME + * gen_interfacessort_field + * INPUTS + * Pointer to section object + * Initial value for the field + * RESULT + * no return value, section object is updated + ******/ +function gen_interfacessort_field(&$section, $value) { + + $section->addInput(new Form_Checkbox( + 'interfacessort', + 'Interfaces Sort', + 'Sort Alphabetically', + $value + ))->setHelp('If selected, lists of interfaces will be sorted by description, otherwise they are listed wan,lan,optn...'); +} + /****f* pfsense-utils/gen_associatedpanels_fields * NAME * gen_associatedpanels_fields @@ -320,6 +370,25 @@ function gen_webguileftcolumnhyper_field(&$section, $value) { ))->setHelp('If selected, clicking a label in the left column will select/toggle the first item of the group.'); } +/****f* pfsense-utils/gen_disablealiaspopupdetail_field + * NAME + * gen_disablealiaspopupdetail_field + * INPUTS + * Pointer to section object + * Initial value for the field + * RESULT + * no return value, section object is updated + ******/ +function gen_disablealiaspopupdetail_field(&$section, $value) { + + $section->addInput(new Form_Checkbox( + 'disablealiaspopupdetail', + 'Alias Popups', + 'Disable details in alias popups', + $value + ))->setHelp('If selected, the details in alias popups will not be shown, just the alias description (e.g. in Firewall Rules).'); +} + /****f* pfsense-utils/gen_pagenamefirst_field * NAME * gen_pagenamefirst_field @@ -356,6 +425,7 @@ function gen_user_settings_fields(&$section, $pconfig) { gen_webguifixedmenu_field($section, $pconfig['webguifixedmenu']); gen_webguihostnamemenu_field($section, $pconfig['webguihostnamemenu']); gen_dashboardcolumns_field($section, $pconfig['dashboardcolumns']); + gen_interfacessort_field($section, $pconfig['interfacessort']); gen_associatedpanels_fields( $section, $pconfig['dashboardavailablewidgetspanel'], @@ -363,6 +433,7 @@ function gen_user_settings_fields(&$section, $pconfig) { $pconfig['systemlogsmanagelogpanel'], $pconfig['statusmonitoringsettingspanel']); gen_webguileftcolumnhyper_field($section, $pconfig['webguileftcolumnhyper']); + gen_disablealiaspopupdetail_field($section, $pconfig['disablealiaspopupdetail']); gen_pagenamefirst_field($section, $pconfig['pagenamefirst']); } @@ -565,7 +636,7 @@ function is_schedule_inuse($schedule) { function setup_microcode() { /* if list */ - $iflist = get_configured_interface_list(false, true); + $iflist = get_configured_interface_list(true); foreach ($iflist as $if => $ifdescr) { enable_hardware_offloading($if); } @@ -1012,7 +1083,8 @@ function setup_serial_port($when = "save", $path = "") { $vga_only = false; $specific_platform = system_identify_specific_platform(); - if ($specific_platform['name'] == 'XG-1540') { + if ($specific_platform['name'] == 'XG-1540' || + $specific_platform['name'] == 'Turbot Dual-E') { $vga_only = true; } elseif ($specific_platform['name'] == 'RCC-VE' || $specific_platform['name'] == 'RCC' || @@ -2038,6 +2110,37 @@ function update_progress_bar($percent, $first_time) { } } +function update_alias_name($new_alias_name, $orig_alias_name) { + if (!$orig_alias_name) { + return; + } + + // Firewall rules + update_alias_names_upon_change(array('filter', 'rule'), array('source', 'address'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'address'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('filter', 'rule'), array('source', 'port'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'port'), $new_alias_name, $orig_alias_name); + // NAT Rules + update_alias_names_upon_change(array('nat', 'rule'), array('source', 'address'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'rule'), array('source', 'port'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'address'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'port'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'rule'), array('target'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'rule'), array('local-port'), $new_alias_name, $orig_alias_name); + // NAT 1:1 Rules + //update_alias_names_upon_change(array('nat', 'onetoone'), array('external'), $new_alias_name, $orig_alias_name); + //update_alias_names_upon_change(array('nat', 'onetoone'), array('source', 'address'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'onetoone'), array('destination', 'address'), $new_alias_name, $orig_alias_name); + // NAT Outbound Rules + update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('source', 'network'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('sourceport'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('destination', 'address'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('dstport'), $new_alias_name, $orig_alias_name); + update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('target'), $new_alias_name, $orig_alias_name); + // Alias in an alias + update_alias_names_upon_change(array('aliases', 'alias'), array('address'), $new_alias_name, $orig_alias_name); +} + function update_alias_names_upon_change($section, $field, $new_alias_name, $origname) { global $g, $config, $pconfig, $debug; if (!$origname) { @@ -2133,7 +2236,7 @@ function parse_aliases_file($filename, $type = "url", $max_items = -1, $kflc = f $tmp = $tmp_str; } $valid = (($type == "url" || $type == "urltable") && (is_ipaddr($tmp) || is_subnet($tmp))) || - (($type == "url_ports" || $type == "urltable_ports") && (is_port($tmp) || is_portrange($tmp))); + (($type == "url_ports" || $type == "urltable_ports") && is_port_or_range($tmp)); if ($valid) { $items[] = $tmp; if (count($items) == $max_items) { @@ -2791,10 +2894,11 @@ function set_language() { function get_locale_list() { $locales = array( + "de_DE" => gettext("German (Germany)"), "en_US" => gettext("English"), "es" => gettext("Spanish"), - "pt_BR" => gettext("Portuguese (Brazil)"), - "tr" => gettext("Turkish"), + "nb" => gettext("Norwegian Bokmål"), + "ru" => gettext("Russian"), "zh_Hans_CN" => gettext("Chinese (Simplified, China)"), "zh_TW" => gettext("Chinese (Taiwan)"), ); @@ -3011,6 +3115,7 @@ function huawei_service_to_string($state) { $modes[2] = gettext("Valid Service"); $modes[3] = gettext("Restricted Regional Service"); $modes[4] = gettext("Powersaving Service"); + $modes[255] = gettext("Unknown Service"); $string = $modes[$state]; return $string; } @@ -3113,19 +3218,15 @@ function pkg_call_plugins($plugin_type, $plugin_params) { return $results; } foreach ($config['installedpackages']['package'] as $package) { - if (!file_exists("/usr/local/pkg/" . $package['configurationfile'])) { - continue; - } - $pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], 'packagegui'); - $pkgname = substr(reverse_strrchr($package['configurationfile'], "."), 0, -1); - if (is_array($pkg_config['plugins']['item'])) { - foreach ($pkg_config['plugins']['item'] as $plugin) { + if (is_array($package['plugins']['item'])) { + foreach ($package['plugins']['item'] as $plugin) { if ($plugin['type'] == $plugin_type) { - if (file_exists($pkg_config['include_file'])) { - require_once($pkg_config['include_file']); + if (file_exists($package['include_file'])) { + require_once($package['include_file']); } else { continue; } + $pkgname = substr(reverse_strrchr($package['configurationfile'], "."), 0, -1); $plugin_function = $pkgname . '_'. $plugin_type; $results[$pkgname] = call_user_func($plugin_function, $plugin_params); } diff --git a/src/etc/inc/phpsessionmanager.inc b/src/etc/inc/phpsessionmanager.inc new file mode 100644 index 0000000..8f1a00e --- /dev/null +++ b/src/etc/inc/phpsessionmanager.inc @@ -0,0 +1,78 @@ +<?php +/* + * phpsessionmanager.inc + * + * part of pfSense (https://www.pfsense.org) + * Copyright (c) 2016 Rubicon Communications, LLC (Netgate) + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +$session_opencounter = 0; +$session_write = false; +$session_action_list = array(); + +function simplestacktrace() { + $stack = debug_backtrace(); + $str = ""; + foreach($stack as $s) { + // $s['args'] + $str .= "\n{$s['function']}(..) - {$s['file']}:{$s['line']}"; + } + return $str; +} + +function phpsession_begin() { + global $session_opencounter, $session_action_list; + $session_action_list[] = "#### phpsession_begin ####" . simplestacktrace(); + if ($session_opencounter == 0) { + session_start(); + } + $session_opencounter++; +} + +function phpsession_destroy() { + global $session_opencounter, $session_action_list; + $session_action_list[] = "#### phpsession_destroy ####" . simplestacktrace(); + session_destroy(); + $session_opencounter = 0; +} + +function phpsession_end($write = false) { + global $session_opencounter, $session_write, $session_action_list; + $session_action_list[] = "#### phpsession_end ####" . simplestacktrace(); + $session_write |= $write; + $session_opencounter--; + if ($session_opencounter == 0) { + if ($session_write) { + session_commit(); + $session_write = false; + } else { + session_abort(); + } + } + if ($session_opencounter < 0) { + $session_opencounter = 0; + syslog(LOG_WARNING, "PHPSESSION closed more often than opened!" . simplestacktrace()); + } +} + +function phpsession_cleanupcheck() { + global $session_opencounter, $session_action_list; + if ($session_opencounter > 0) { + syslog(LOG_WARNING, "PHPSESSION {$session_opencounter} open sessions left at shutdown script!".print_r($session_action_list, true)); + } +} + +register_shutdown_function('phpsession_cleanupcheck'); diff --git a/src/etc/inc/pkg-utils.inc b/src/etc/inc/pkg-utils.inc index 199021a..df4ac49 100644 --- a/src/etc/inc/pkg-utils.inc +++ b/src/etc/inc/pkg-utils.inc @@ -337,8 +337,8 @@ function get_package_internal_name($package_data) { } // Get information about packages. -function get_pkg_info($pkgs = 'all', $remote_repo_usage_disabled = false, $installed_pkgs_only = false) { - +function get_pkg_info($pkgs = 'all', $remote_repo_usage_disabled = false, + $installed_pkgs_only = false) { global $g, $input_errors; $out = $err = $extra_param = ''; @@ -375,30 +375,47 @@ function get_pkg_info($pkgs = 'all', $remote_repo_usage_disabled = false, $insta } if (!$installed_pkgs_only) { - $rc = pkg_exec("search {$extra_param}-R --raw-format json-compact " . $pkgs, $out, $err); + $rc = pkg_exec( + "search {$extra_param}-R --raw-format json-compact " . + $pkgs, $out, $err); } - if (($installed_pkgs_only || ($rc != 0 && $remote_repo_usage_disabled)) && is_package_installed($pkgs)) { - /* Fall back on pkg info to return locally installed matching pkgs instead, if + if (($installed_pkgs_only || ($rc != 0 && $remote_repo_usage_disabled)) + && is_pkg_installed($pkgs)) { + /* + * Fall back on pkg info to return locally installed matching + * pkgs instead, if: * * (1) only installed pkgs needed, or - * we tried to check the local catalog copy (implying that we would have accepted incomplete/outdated pkg info) - * but it didn't have any contents, or for other reasons returned an error. + * we tried to check the local catalog copy (implying that + * we would have accepted incomplete/outdated pkg info) + * but it didn't have any contents, or for other reasons + * returned an error. * AND * (2) at least some pkgs matching <pattern> are installed * - * Following an unsuccessful attempt to access a remote repo catalog, the local copy is wiped clear. Thereafter any - * "pkg search" will return an error until online+updated again. If the calling code would have accepted local copy info - * (which could be incomplete/out of date), then it makes sense to fall back on pkg info to at least return the known - * info about installed pkgs (pkg info should still work), instead of failing and returning no info at all. - * For example, this at least enables offline view + management of installed pkgs in GUI/console. + * Following an unsuccessful attempt to access a remote repo + * catalog, the local copy is wiped clear. Thereafter any + * "pkg search" will return an error until online+updated again. + * If the calling code would have accepted local copy info + * (which could be incomplete/out of date), then it makes sense + * to fall back on pkg info to at least return the known + * info about installed pkgs (pkg info should still work), + * instead of failing and returning no info at all. + * For example, this at least enables offline view + management + * of installed pkgs in GUI/console. + * + * We skip this step if no matching pkgs are installed, because + * then pkg info would return a "no matching pkgs" RC code, + * even though this wouldn't be considered an "error" (and + * $out+$err would be correct empty strings if none match). * - * We skip this step if no matching pkgs are installed, because then pkg info would return a "no matching pkgs" - * RC code, even though this wouldn't be considered an "error" (and $out+$err would be correct empty strings if none match). - * Note that is_package_installed() is a wrapper for pkg info -e <pattern> which is what we need here. + * Note that is_pkg_installed() is a wrapper for pkg info -e + * <pattern> which is what we need here. */ // ok, 1 or more packages match, so pkg info can be safely called to get the pkg list - $rc = pkg_exec("info -R --raw-format json-compact " . $pkgs, $out, $err); + $rc = pkg_exec("info -R --raw-format json-compact " . $pkgs, + $out, $err); } if ($lock) { @@ -410,8 +427,10 @@ function get_pkg_info($pkgs = 'all', $remote_repo_usage_disabled = false, $insta "ERROR: Error trying to get packages list. Aborting...") . "\n"); update_status($err); - $input_errors[] = gettext("ERROR: Error trying to get packages list. Aborting...") . "\n"; - $input_errors[] = $err; + $input_errors[] = gettext( + "ERROR: Error trying to get packages list. Aborting...") . + "\n"; + $input_errors[] = $err; return array(); } @@ -423,7 +442,8 @@ function get_pkg_info($pkgs = 'all', $remote_repo_usage_disabled = false, $insta continue; } - if (isset($pkg_filter) && !in_array($pkg_info['name'], $pkg_filter)) { + if (isset($pkg_filter) && !in_array($pkg_info['name'], + $pkg_filter)) { continue; } @@ -438,24 +458,29 @@ function get_pkg_info($pkgs = 'all', $remote_repo_usage_disabled = false, $insta if (is_pkg_installed($pkg_info['name'])) { $pkg_info['installed'] = true; - $rc = pkg_exec("query %v {$pkg_info['name']}", $out, $err); + $rc = pkg_exec("query %v {$pkg_info['name']}", $out, + $err); if ($rc != 0) { update_status("\n" . gettext( "ERROR: Error trying to get package version. Aborting...") . "\n"); update_status($err); - $input_errors[] = gettext("ERROR: Error trying to get package version. Aborting...") . "\n"; - $input_errors[] = $err; + $input_errors[] = gettext( + "ERROR: Error trying to get package version. Aborting...") . + "\n"; + $input_errors[] = $err; return array(); } - $pkg_info['installed_version'] = str_replace("\n", "", $out); + $pkg_info['installed_version'] = str_replace("\n", "", + $out); } else if (is_package_installed($pkg_info['shortname'])) { $pkg_info['broken'] = true; } - $pkg_info['desc'] = preg_replace('/\n+WWW:.*$/', '', $pkg_info['desc']); + $pkg_info['desc'] = preg_replace('/\n+WWW:.*$/', '', + $pkg_info['desc']); $result[] = $pkg_info; unset($pkg_info); @@ -482,12 +507,7 @@ function register_all_installed_packages() { $pkg_info = get_pkg_info('all', true, true); - foreach ($pkg_info as $pkg) { - if (!isset($pkg['installed'])) { - continue; - } - pkg_remove_prefix($pkg['name']); if (is_package_installed($pkg['name'])) { @@ -812,6 +832,16 @@ function install_package_xml($package_name) { } update_status(gettext("done.") . "\n"); } + if (is_array($pkg_config['tabs'])) { + $config['installedpackages']['package'][$pkgid]['tabs'] = $pkg_config['tabs']; + } + /* plugins */ + if (isset($pkg_config['include_file'])) { + $config['installedpackages']['package'][$pkgid]['include_file'] = $pkg_config['include_file']; + } + if (is_array($pkg_config['plugins']['item'])) { + $config['installedpackages']['package'][$pkgid]['plugins']['item'] = $pkg_config['plugins']['item']; + } } else { pkg_debug("Unable to find config file\n"); update_status(gettext("Loading package configuration... failed!") . "\n\n" . gettext("Installation aborted.")); @@ -938,7 +968,7 @@ function delete_package_xml($package_name, $when = "post-deinstall") { } } /* deinstall commands */ - if ($when == "post-deinstall" && $pkg_config['custom_php_deinstall_command'] <> "") { + if ($when == "deinstall" && $pkg_config['custom_php_deinstall_command'] <> "") { update_status(gettext("Deinstall commands... ")); if ($missing_include == false) { eval_once($pkg_config['custom_php_deinstall_command']); diff --git a/src/etc/inc/priv.inc b/src/etc/inc/priv.inc index a2e2763..a80e383 100644 --- a/src/etc/inc/priv.inc +++ b/src/etc/inc/priv.inc @@ -275,6 +275,7 @@ function getAllowedPages($username, &$attributes = array()) { $allowed_pages = array(); $allowed_groups = array(); + phpsession_begin(); if ($_SESSION['remoteauth']) { $authcfg = auth_get_authserver($config['system']['webgui']['authmode']); // cache auth results for a short time to ease load on auth services & logs @@ -331,7 +332,7 @@ function getAllowedPages($username, &$attributes = array()) { // log_error("debug: user {$username} pages = {$dbg_pages}"); $_SESSION['page-match'] = $allowed_pages; - + phpsession_end(true); return $allowed_pages; } diff --git a/src/etc/inc/service-utils.inc b/src/etc/inc/service-utils.inc index a4d2559..5b5789a 100644 --- a/src/etc/inc/service-utils.inc +++ b/src/etc/inc/service-utils.inc @@ -20,13 +20,15 @@ * limitations under the License. */ -require_once("globals.inc"); require_once("captiveportal.inc"); -require_once("openvpn.inc"); +require_once("globals.inc"); +require_once("gwlb.inc"); require_once("ipsec.inc"); +require_once("openvpn.inc"); +require_once("system.inc"); +require_once("util.inc"); require_once("vpn.inc"); require_once("vslb.inc"); -require_once("gwlb.inc"); define("RCFILEPREFIX", "/usr/local/etc/rc.d/"); function write_rcfile($params) { @@ -261,6 +263,11 @@ function get_services() { $pconfig['description'] = gettext("NTP clock sync"); $services[] = $pconfig; + $pconfig = array(); + $pconfig['name'] = "syslogd"; + $pconfig['description'] = gettext("System Logger Daemon"); + $services[] = $pconfig; + if (is_array($config['captiveportal'])) { foreach ($config['captiveportal'] as $zone => $setting) { if (isset($setting['enable'])) { @@ -570,7 +577,6 @@ function service_control_start($name, $extras) { captiveportal_init_webgui_zonename($zone); break; case 'ntpd': - case 'openntpd': system_ntp_configure(); break; case 'dpinger': @@ -618,6 +624,10 @@ function service_control_start($name, $extras) { break; case 'relayd': relayd_configure(); + filter_configure(); + break; + case 'syslogd': + system_syslogd_start(); break; default: start_service($name); @@ -687,7 +697,17 @@ function service_control_stop($name, $extras) { } break; case 'relayd': - mwexec('pkill relayd'); + sigkillbyname("relayd", "TERM"); + break; + case 'syslogd': + if (isvalidpid("{$g['varrun_path']}/syslog.pid")) { + sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM"); + usleep(100000); + } + if (isvalidpid("{$g['varrun_path']}/syslog.pid")) { + sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL"); + usleep(100000); + } break; default: stop_service($name); @@ -757,6 +777,10 @@ function service_control_restart($name, $extras) { break; case 'relayd': relayd_configure(true); + filter_configure(); + break; + case 'syslogd': + system_syslogd_start(); break; default: restart_service($name); diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index a37a9a3..392ad7b 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -23,8 +23,8 @@ * limitations under the License. */ -define('DYNDNS_PROVIDER_VALUES', 'all-inkl citynetwork cloudflare cloudflare-v6 custom custom-v6 dnsexit dnsimple dnsmadeeasy dnsomatic duiadns duiadns-v6 dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns freedns-v6 glesys googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker loopia namecheap noip noip-free ods opendns ovh-dynhost route53 selfhost spdyn spdyn-v6 zoneedit'); -define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,City Network,CloudFlare,CloudFlare (v6),Custom,Custom (v6),DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DuiaDns.net,DuiaDns.net (v6),DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,freeDNS (v6),GleSYS,Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,SelfHost,SPDYN,SPDYN (v6),ZoneEdit'); +define('DYNDNS_PROVIDER_VALUES', 'all-inkl citynetwork cloudflare cloudflare-v6 custom custom-v6 dnsexit dnsimple dnsmadeeasy dnsomatic duiadns duiadns-v6 dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns freedns-v6 glesys googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker hover loopia namecheap noip noip-free ods opendns ovh-dynhost route53 selfhost spdyn spdyn-v6 zoneedit'); +define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,City Network,CloudFlare,CloudFlare (v6),Custom,Custom (v6),DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DuiaDns.net,DuiaDns.net (v6),DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,freeDNS (v6),GleSYS,Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Hover,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,SelfHost,SPDYN,SPDYN (v6),ZoneEdit'); /* implement ipv6 route advertising daemon */ function services_radvd_configure($blacklist = array()) { @@ -2524,8 +2524,10 @@ function services_dnsupdate_process($int = "", $updatehost = "", $forced = false if (isset($dnsupdate['usepublicip'])) { $wanip = dyndnsCheckIP($if); + $bindip = get_interface_ip($if); } else { $wanip = get_interface_ip($if); + $bindip = $wanip; } $wanipv6 = get_interface_ipv6($if); @@ -2620,6 +2622,7 @@ EOD; "{$dnsupdate['host']}. A\n"; $upinst .= "update add {$dnsupdate['host']}. " . "{$dnsupdate['ttl']} A {$wanip}\n"; + $upinst .= "local {$bindip}\n"; $need_update = true; } else { log_error(sprintf(gettext( @@ -2867,6 +2870,8 @@ function install_cron_job($command, $active = false, $minute = "0", $hour = "*", if ($is_installed == true) { unset($config['cron']['item'][$x]); $change_message = "Removed cron job for %s"; + } else { + $cron_changed = false; } } diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 61b6a77..a557fa0 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -327,13 +327,15 @@ function system_hosts_local_entries() { ); $hosts_if_found = true; } - $cfgipv6 = get_interface_ipv6($sysif); - if (is_ipaddrv6($cfgipv6)) { - $hosts[] = array( - 'ipaddr' => $cfgipv6, - 'fqdn' => $local_fqdn - ); - $hosts_if_found = true; + if (!isset($syscfg['ipv6dontcreatelocaldns'])) { + $cfgipv6 = get_interface_ipv6($sysif); + if (is_ipaddrv6($cfgipv6)) { + $hosts[] = array( + 'ipaddr' => $cfgipv6, + 'fqdn' => $local_fqdn + ); + $hosts_if_found = true; + } } if ($hosts_if_found == true) { break; @@ -1235,6 +1237,7 @@ function system_webgui_create_certificate() { $cert = array(); $cert['refid'] = uniqid(); $cert['descr'] = sprintf(gettext("webConfigurator default (%s)"), $cert['refid']); + $cert_hostname = "{$config['system']['hostname']}-{$cert['refid']}"; $dn = array( 'countryName' => "US", @@ -1242,7 +1245,8 @@ function system_webgui_create_certificate() { 'localityName' => "Locality", 'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate", 'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}", - 'commonName' => "{$config['system']['hostname']}-{$cert['refid']}"); + 'commonName' => $cert_hostname, + 'subjectAltName' => "DNS:{$cert_hostname}"); $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */ if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) { while ($ssl_err = openssl_error_string()) { @@ -1518,7 +1522,7 @@ EOD; printf(gettext("Error: cannot open certificate file in system_webgui_start().%s"), "\n"); return 1; } - chmod("{$g['varetc_path']}/{$cert_location}", 0600); + chmod("{$g['varetc_path']}/{$cert_location}", 0644); if ($ca <> "") { $cert_chain = $cert . "\n" . $ca; } else { @@ -2321,6 +2325,7 @@ function system_identify_specific_platform() { global $g; $hw_model = get_single_sysctl('hw.model'); + $hw_ncpu = get_single_sysctl('hw.ncpu'); /* Try to guess from smbios strings */ unset($product); @@ -2360,6 +2365,24 @@ function system_identify_specific_platform() { case 'RCC': return (array('name' => 'RCC', 'descr' => 'Netgate XG-2758')); break; + case 'Minnowboard Turbot D0 PLATFORM': + $result = array(); + $result['name'] = 'Turbot Dual-E'; + /* Detect specific model */ + switch ($hw_ncpu) { + case '4': + $result['model'] = 'SG-2340'; + break; + case '2': + $result['model'] = 'SG-2320'; + break; + default: + $result['model'] = $result['name']; + break; + } + $result['descr'] = 'Netgate ' . $result['model']; + return $result; + break; case 'SYS-5018A-FTN4': case 'A1SAi': return (array('name' => 'C2758', 'descr' => 'Super Micro C2758')); @@ -2368,6 +2391,7 @@ function system_identify_specific_platform() { return (array('name' => 'XG-1540', 'descr' => 'Super Micro XG-1540')); break; case 'apu2': + case 'APU2': return (array('name' => 'apu2', 'descr' => 'PC Engines APU2')); break; case 'Virtual Machine': diff --git a/src/etc/inc/upgrade_config.inc b/src/etc/inc/upgrade_config.inc index b350497..bc4e4a1 100644 --- a/src/etc/inc/upgrade_config.inc +++ b/src/etc/inc/upgrade_config.inc @@ -742,7 +742,7 @@ function upgrade_041_to_042() { function upgrade_042_to_043() { global $config; /* migrate old interface gateway to the new gateways config */ - $iflist = get_configured_interface_list(false, true); + $iflist = get_configured_interface_list(true); $gateways = array(); $i = 0; foreach ($iflist as $ifname => $interface) { @@ -837,7 +837,7 @@ function upgrade_043_to_044() { function upgrade_044_to_045() { global $config; - $iflist = get_configured_interface_list(false, true); + $iflist = get_configured_interface_list(true); if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) { $i = 0; foreach ($config['vlans']['vlan'] as $id => $vlan) { @@ -5157,4 +5157,151 @@ function upgrade_161_to_162() { $config['system']['crypto_hardware'] = "cryptodev"; } } + +/* Traffic graphs widget settings are now stored in a layout similar + * to other widgets. Migrate any old settings. + */ +function upgrade_162_to_163() { + require_once("ipsec.inc"); + global $config; + + foreach (array('refreshinterval', 'invert', 'size', 'backgroundupdate') as $setting) { + if (isset($config['widgets']['trafficgraphs'][$setting])) { + $config['widgets']['traffic_graphs'][$setting] = $config['widgets']['trafficgraphs'][$setting]; + unset($config['widgets']['trafficgraphs'][$setting]); + } + } + + if (isset($config['widgets']['trafficgraphs']['shown'])) { + if (is_array($config['widgets']['trafficgraphs']['shown']['item'])) { + $ifdescrs = get_configured_interface_with_descr(); + + if (ipsec_enabled()) { + $ifdescrs['enc0'] = "IPsec"; + } + + $validNames = array(); + + foreach ($ifdescrs as $ifdescr => $ifname) { + array_push($validNames, $ifdescr); + } + + $config['widgets']['traffic_graphs']['filter'] = implode(',', array_diff($validNames, $config['widgets']['trafficgraphs']['shown']['item'])); + } + + unset($config['widgets']['trafficgraphs']['shown']); + } +} + +/* Dashboard widget settings config format has changed to support having possibly multiple + * of a widget on the dashboard. Migrate any old settings. + */ +function convert_widget_164($oldname, $newname, $settings_keys) { + global $config; + + if ($newname == '') { + $newname = $oldname . '-0'; + } + + if ($oldname == '') { + // These settings were stored directly in $config['widgets'] + // Move them down under their new key. + // e.g. $config['widgets']['filterlogentries'] + // becomes $config['widgets']['log-0']['filterlogentries'] + foreach ($settings_keys as $oldkey => $newkey) { + if ($newkey == '') { + $newkey = $oldkey; + } + + // Modify the system-wide entry + if (isset($config['widgets'][$oldkey])) { + $config['widgets'][$newname][$newkey] = $config['widgets'][$oldkey]; + unset($config['widgets'][$oldkey]); + } + + // Modify any user-specific entries + foreach ($config['system']['user'] as & $user) { + if (isset($user['widgets'][$oldkey])) { + $user['widgets'][$newname][$newkey] = $user['widgets'][$oldkey]; + unset($user['widgets'][$oldkey]); + } + } + } + } else { + // These settings were stored in some key under 'widgets', + // e.g. $config['widgets']['gateways_widget']['display_type'] + // becomes $config['widgets']['gateways-0']['display_type'] + foreach ($settings_keys as $oldkey => $newkey) { + if ($newkey == '') { + $newkey = $oldkey; + } + + // Modify the system-wide entry + if (isset($config['widgets'][$oldname][$oldkey])) { + $config['widgets'][$newname][$newkey] = $config['widgets'][$oldname][$oldkey]; + unset($config['widgets'][$oldname][$oldkey]); + } + + // Modify any user-specific entries + foreach ($config['system']['user'] as & $user) { + if (isset($user['widgets'][$oldname][$oldkey])) { + $user['widgets'][$newname][$newkey] = $user['widgets'][$oldname][$oldkey]; + unset($user['widgets'][$oldname][$oldkey]); + } + + if (isset($user['widgets'][$oldname])) { + unset($user['widgets'][$oldname]); + } + } + } + + if (isset($config['widgets'][$oldname])) { + unset($config['widgets'][$oldname]); + } + } +} + +function upgrade_163_to_164() { + global $config; + + convert_widget_164('dyn_dns_status', '', array('filter' => '')); + convert_widget_164('gateways_widget', 'gateways-0', array('display_type' => '', 'gatewaysfilter' => '')); + convert_widget_164('interface_statistics', '', array('iffilter' => '')); + convert_widget_164('interfaces', '', array('iffilter' => '')); + convert_widget_164('', 'log-0', + array( + 'filterlogentries' => '', + 'filterlogentriesacts' => '', + 'filterlogentriesinterfaces' => '', + 'filterlogentriesinterval' => '')); + convert_widget_164('openvpn', '', array('filter' => '')); + convert_widget_164('', 'picture-0', array('picturewidget' => '', 'picturewidget_filename' => '')); + convert_widget_164('', 'rss-0', array('rssfeed' => '', 'rssmaxitems' => '', 'rsswidgetheight' => '', 'rsswidgettextlength' => '')); + convert_widget_164('', 'services_status-0', array('servicestatusfilter' => 'filter')); + convert_widget_164('smart_status', '', array('filter' => '')); + convert_widget_164('system_information', '', array('filter' => '')); + convert_widget_164('thermal_sensors_widget', 'thermal_sensors-0', + array( + 'thermal_sensors_widget_zone_warning_threshold' => '', + 'thermal_sensors_widget_zone_critical_threshold' => '', + 'thermal_sensors_widget_core_warning_threshold' => '', + 'thermal_sensors_widget_core_critical_threshold' => '', + 'thermal_sensors_widget_show_raw_output' => '', + 'thermal_sensors_widget_show_full_sensor_name' => '', + 'thermal_sensors_widget_pulsate_warning' => '', + 'thermal_sensors_widget_pulsate_critical' => '' + )); + convert_widget_164('wol', 'wake_on_lan-0', array('filter' => '')); +} + +/* Work around broken wizard rules. See https://redmine.pfsense.org/issues/7434 */ +function upgrade_164_to_165() { + global $config; + foreach ($config['filter']['rule'] as & $rule) { + if ($rule['destination']['port'] == "137-139-137-139") { + $rule['destination']['port'] = "137-139"; + } + } +} + ?> diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 604c557..db8ec73 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -105,13 +105,6 @@ function clear_subsystem_dirty($subsystem = "") { @unlink("{$g['varrun_path']}/{$subsystem}.dirty"); } -function config_lock() { - return; -} -function config_unlock() { - return; -} - /* lock configuration file */ function lock($lock, $op = LOCK_SH) { global $g; @@ -1124,8 +1117,13 @@ function is_portrange($portrange) { return (count($ports) == 2 && is_port($ports[0]) && is_port($ports[1])); } -/* returns true if $port is a valid port number or an alias thereof */ -function is_portoralias($port) { +/* returns true if $port is a valid TCP/UDP port number or range ("<port>:<port>") */ +function is_port_or_range($port) { + return (is_port($port) || is_portrange($port)); +} + +/* returns true if $port is an alias that is a port type */ +function is_portalias($port) { global $config; if (is_alias($port)) { @@ -1136,10 +1134,18 @@ function is_portoralias($port) { } } } - return false; - } else { - return is_port($port); } + return false; +} + +/* returns true if $port is a valid port number or an alias thereof */ +function is_port_or_alias($port) { + return (is_port($port) || is_portalias($port)); +} + +/* returns true if $port is a valid TCP/UDP port number or range ("<port>:<port>") or an alias thereof */ +function is_port_or_range_or_alias($port) { + return (is_port($port) || is_portrange($port) || is_portalias($port)); } /* create ranges of sequential port numbers (200:215) and remove duplicates */ @@ -1361,16 +1367,13 @@ function compare_interface_friendly_names($a, $b) { } /* return the configured interfaces list. */ -function get_configured_interface_list($only_opt = false, $withdisabled = false) { +function get_configured_interface_list($withdisabled = false) { global $config; $iflist = array(); /* if list */ foreach ($config['interfaces'] as $if => $ifdetail) { - if ($only_opt && ($if == "wan" || $if == "lan")) { - continue; - } if (isset($ifdetail['enable']) || $withdisabled == true) { $iflist[$if] = $if; } @@ -1380,16 +1383,13 @@ function get_configured_interface_list($only_opt = false, $withdisabled = false) } /* return the configured interfaces list. */ -function get_configured_interface_list_by_realif($only_opt = false, $withdisabled = false) { +function get_configured_interface_list_by_realif($withdisabled = false) { global $config; $iflist = array(); /* if list */ foreach ($config['interfaces'] as $if => $ifdetail) { - if ($only_opt && ($if == "wan" || $if == "lan")) { - continue; - } if (isset($ifdetail['enable']) || $withdisabled == true) { $tmpif = get_real_interface($if); if (!empty($tmpif)) { @@ -1402,16 +1402,13 @@ function get_configured_interface_list_by_realif($only_opt = false, $withdisable } /* return the configured interfaces list with their description. */ -function get_configured_interface_with_descr($only_opt = false, $withdisabled = false) { - global $config; +function get_configured_interface_with_descr($withdisabled = false) { + global $config, $user_settings; $iflist = array(); /* if list */ foreach ($config['interfaces'] as $if => $ifdetail) { - if ($only_opt && ($if == "wan" || $if == "lan")) { - continue; - } if (isset($ifdetail['enable']) || $withdisabled == true) { if (empty($ifdetail['descr'])) { $iflist[$if] = strtoupper($if); @@ -1421,6 +1418,10 @@ function get_configured_interface_with_descr($only_opt = false, $withdisabled = } } + if ($user_settings['webgui']['interfacessort']) { + asort($iflist); + } + return $iflist; } @@ -1780,7 +1781,7 @@ function alias_expand($name) { } } return "\${$name}"; - } else if (is_ipaddr($name) || is_subnet($name) || is_port($name) || is_portrange($name)) { + } else if (is_ipaddr($name) || is_subnet($name) || is_port_or_range($name)) { return "{$name}"; } else { return null; @@ -2152,7 +2153,7 @@ function is_interface_mismatch() { $missing_interfaces = array(); if (is_array($config['interfaces'])) { foreach ($config['interfaces'] as $ifname => $ifcfg) { - if (preg_match("/^enc|^cua|^tun|^tap|^l2tp|^pptp|^ppp|^ovpn|^gif|^gre|^lagg|^bridge|vlan|_wlan/i", $ifcfg['if'])) { + if (preg_match("/^enc|^cua|^tun|^tap|^l2tp|^pptp|^ppp|^ovpn|^gif|^gre|^lagg|^bridge|vlan|_wlan|_\d{0,4}_\d{0,4}$/i", $ifcfg['if'])) { // Do not check these interfaces. $i++; continue; @@ -2368,6 +2369,23 @@ function explode_assoc($delimiter, $string) { return $result; } +/* + * Given a string of text with some delimiter, look for occurrences + * of some string and replace all of those. + * $text - the text string (e.g. "abc,defg,x123,ipv4,xyz") + * $delimiter - the delimiter (e.g. ",") + * $element - the element to match (e.g. "defg") + * $replacement - the string to replace it with (e.g. "42") + * Returns the resulting delimited string (e.g. "abc,42,x123,ipv4,xyz") + */ +function replace_element_in_list($text, $delimiter, $element, $replacement) { + $textArray = explode($delimiter, $text); + while (($entry = array_search($element, $textArray)) !== false) { + $textArray[$entry] = $replacement; + } + return implode(',', $textArray); +} + /* Try to change a static route, if it doesn't exist, add it */ function route_add_or_change($args) { global $config; diff --git a/src/etc/inc/vslb.inc b/src/etc/inc/vslb.inc index 7d59cb1..da52adb 100644 --- a/src/etc/inc/vslb.inc +++ b/src/etc/inc/vslb.inc @@ -147,6 +147,7 @@ function relayd_configure($kill_first=false) { if (!function_exists('filter_expand_alias_array')) { require_once("filter.inc"); } + require_once("util.inc"); $vs_a = $config['load_balancer']['virtual_server']; $pool_a = $config['load_balancer']['lbpool']; @@ -350,7 +351,7 @@ function relayd_configure($kill_first=false) { if (is_process_running('relayd')) { if (!empty($vs_a)) { if ($kill_first) { - mwexec('pkill relayd'); + sigkillbyname("relayd", "TERM"); /* Remove all active relayd anchors now that relayd is no longer running. */ cleanup_lb_anchor("*"); mwexec("/usr/local/sbin/relayd -f {$g['varetc_path']}/relayd.conf"); @@ -366,7 +367,7 @@ function relayd_configure($kill_first=false) { * mwexec('/usr/local/sbin/relayctl stop'); * returns "command failed" */ - mwexec('pkill relayd'); + sigkillbyname("relayd", "TERM"); /* Remove all active relayd anchors now that relayd is no longer running. */ cleanup_lb_anchor("*"); } @@ -485,6 +486,10 @@ function get_lb_anchors() { function cleanup_lb_anchor($anchorname = "*") { $lbanchors = get_lb_anchors(); foreach ($lbanchors as $lba) { + /* Skip empty/blank results */ + if (empty($lba)) { + continue; + } if (($anchorname == "*") || ($lba == "relayd/{$anchorname}")) { /* Flush both the NAT and the Table for the anchor, so it will be completely removed by pf. */ mwexec("/sbin/pfctl -a " . escapeshellarg($lba) . " -F nat"); diff --git a/src/etc/inc/wizardapp.inc b/src/etc/inc/wizardapp.inc index 88143b5..7aabc57 100644 --- a/src/etc/inc/wizardapp.inc +++ b/src/etc/inc/wizardapp.inc @@ -644,7 +644,7 @@ $othersplist = array(); $othersplist['smb'] = array(); /* Microsoft SMB and friends */ $othersplist['smb'][] = array('SMB1', 'tcp', '445', '445', 'both'); - $othersplist['smb'][] = array('SMB2', 'tcp', '137-139', '137-139', 'both'); + $othersplist['smb'][] = array('SMB2', 'tcp', '137', '139', 'both'); $othersplist['snmp'] = array(); /* Simple network management protocol */ diff --git a/src/etc/inc/xmlparse.inc b/src/etc/inc/xmlparse.inc index 5632e98..5d00d29 100644 --- a/src/etc/inc/xmlparse.inc +++ b/src/etc/inc/xmlparse.inc @@ -247,7 +247,7 @@ function dump_xml_config_sub($arr, $indent) { (substr($ent, 0, 9) == "ldap_attr") || (substr($ent, 0, 9) == "ldap_bind") || (substr($ent, 0, 11) == "ldap_basedn") || - (substr($ent, 0, 18) == "ldap_authcn") || + (substr($ent, 0, 11) == "ldap_authcn") || (substr($ent, 0, 19) == "ldap_extended_query")) { $xmlconfig .= "<$ent><![CDATA[" . htmlentities($cval) . "]]></$ent>\n"; } else { @@ -278,9 +278,9 @@ function dump_xml_config_sub($arr, $indent) { (substr($ent, 0, 9) == "ldap_attr") || (substr($ent, 0, 9) == "ldap_bind") || (substr($ent, 0, 11) == "ldap_basedn") || - (substr($ent, 0, 18) == "ldap_authcn") || + (substr($ent, 0, 11) == "ldap_authcn") || (substr($ent, 0, 19) == "ldap_extended_query") || - (substr($ent, 0, 5) == "text")) { + (substr($ent, 0, 4) == "text")) { $xmlconfig .= "<$ent><![CDATA[" . htmlentities($val) . "]]></$ent>\n"; } else { $xmlconfig .= "<$ent>" . htmlentities($val) . "</$ent>\n"; diff --git a/src/etc/inc/xmlrpc_client.inc b/src/etc/inc/xmlrpc_client.inc index 26a93be..962265d 100644 --- a/src/etc/inc/xmlrpc_client.inc +++ b/src/etc/inc/xmlrpc_client.inc @@ -111,7 +111,8 @@ class pfsense_xmlrpc_client { if ($previouserror == null) { // CurlException doesnt get filled with PreviousError, // however we dont want to show the stacktrace included in the 'message' to non sysadmin users - $this->error = "CurlException calling XMLRPC method {$method} #" . $e->getMessage(); + preg_match("/HTTP_Request2_ConnectionException: (.*) in \/.*/", $e->getMessage(), $errormsg); + $this->error = "A communications error occurred while attempting to call XMLRPC method {$method}: " . $errormsg[1]; } else { $this->error = "CurlException calling XMLRPC method {$method} #" . $previouserror->getMessage(); } diff --git a/src/etc/pfSense-rc b/src/etc/pfSense-rc index 4b9990d..0bb0f2b 100755 --- a/src/etc/pfSense-rc +++ b/src/etc/pfSense-rc @@ -228,7 +228,12 @@ SWAPDEVICE=`/bin/cat /etc/fstab | /usr/bin/grep swap | /usr/bin/cut -f1` # make some directories in /var /bin/mkdir -p $varrunpath /var/log /var/etc /var/db/entropy /var/db/rrd /var/at/jobs/ /var/empty /var/log/nginx 2>/dev/null + +# turn off the immutable flag, set /var/empty to read-only, make it immutable again +chflags noschg /var/empty chmod 0555 /var/empty +chflags schg /var/empty + /bin/rm -rf $varrunpath/* # Cleanup configuration files from previous instance diff --git a/src/etc/pfSense.obsoletedfiles b/src/etc/pfSense.obsoletedfiles index a7004e1..f1e08da 100644 --- a/src/etc/pfSense.obsoletedfiles +++ b/src/etc/pfSense.obsoletedfiles @@ -808,61 +808,7 @@ /usr/local/share/emacs /usr/local/share/examples /usr/local/share/java -/usr/local/share/locale/af -/usr/local/share/locale/am -/usr/local/share/locale/ar -/usr/local/share/locale/az -/usr/local/share/locale/bg -/usr/local/share/locale/bn -/usr/local/share/locale/br -/usr/local/share/locale/bs -/usr/local/share/locale/cy -/usr/local/share/locale/da -/usr/local/share/locale/de -/usr/local/share/locale/dk -/usr/local/share/locale/ee -/usr/local/share/locale/en_CA -/usr/local/share/locale/en_GB -/usr/local/share/locale/es -/usr/local/share/locale/es_ES -/usr/local/share/locale/es_MX -/usr/local/share/locale/et -/usr/local/share/locale/eu -/usr/local/share/locale/fa -/usr/local/share/locale/fr -/usr/local/share/locale/ga -/usr/local/share/locale/gu -/usr/local/share/locale/he -/usr/local/share/locale/hi -/usr/local/share/locale/hr -/usr/local/share/locale/hu -/usr/local/share/locale/id -/usr/local/share/locale/is -/usr/local/share/locale/it -/usr/local/share/locale/ka -/usr/local/share/locale/kn -/usr/local/share/locale/lt -/usr/local/share/locale/lv -/usr/local/share/locale/mk -/usr/local/share/locale/ml -/usr/local/share/locale/mn -/usr/local/share/locale/ms -/usr/local/share/locale/mt -/usr/local/share/locale/nb -/usr/local/share/locale/nl -/usr/local/share/locale/or -/usr/local/share/locale/pa /usr/local/share/locale/pt_BR.ISO8858-1 -/usr/local/share/locale/pt_PT -/usr/local/share/locale/ru -/usr/local/share/locale/sq -/usr/local/share/locale/sr@Latn -/usr/local/share/locale/sv -/usr/local/share/locale/ta -/usr/local/share/locale/th -/usr/local/share/locale/vi -/usr/local/share/locale/wa -/usr/local/share/locale/zh /usr/local/share/locale/zh_CN.GB2312 /usr/local/share/locale/zh_TW.Big5 /usr/local/share/misc diff --git a/src/etc/phpshellsessions/gitsync b/src/etc/phpshellsessions/gitsync index 26874c7..0ac9479 100644 --- a/src/etc/phpshellsessions/gitsync +++ b/src/etc/phpshellsessions/gitsync @@ -512,8 +512,8 @@ if (!$upgrading) { echo "===> Checkout complete.\n"; echo "\n"; if (!$upgrading) { - echo "Your system is now sync'd and PHP and nginx will be restarted in 5 seconds.\n\n"; + echo "The system is now sync'd and PHP and nginx will be restarted in 5 seconds.\n\n"; } else { - echo "Your system is now sync'd.\n\n"; + echo "The system is now sync'd.\n\n"; } diff --git a/src/etc/rc.banner b/src/etc/rc.banner index 92d9e12..05f1e2c 100755 --- a/src/etc/rc.banner +++ b/src/etc/rc.banner @@ -32,7 +32,7 @@ $machine = trim(`uname -m`); print "*** Welcome to {$product} {$g['product_version_string']} ({$machine}) on {$hostname} ***\n"; -$iflist = get_configured_interface_with_descr(false, true); +$iflist = get_configured_interface_with_descr(true); foreach ($iflist as $ifname => $friendly) { /* point to this interface's config */ $ifconf = $config['interfaces'][$ifname]; diff --git a/src/etc/rc.bootup b/src/etc/rc.bootup index 60919e0..bfc555e 100755 --- a/src/etc/rc.bootup +++ b/src/etc/rc.bootup @@ -132,6 +132,7 @@ if (mwexec("/bin/kenv -q pfSense.boot 2>/dev/null") != 0) { @file_put_contents("{$g['vardb_path']}/vendor_mac", $vendor_mac_arr_json); } unset($ifs, $if, $vendor_mac_arr, $vendor_mac_arr_json); + mwexec("/usr/sbin/gnid > {$g['vardb_path']}/uniqueid 2>/dev/null"); mwexec("/bin/kenv pfSense.boot=1"); } diff --git a/src/etc/rc.filter_synchronize b/src/etc/rc.filter_synchronize index a6f6aa7..2eb9d6c 100755 --- a/src/etc/rc.filter_synchronize +++ b/src/etc/rc.filter_synchronize @@ -96,8 +96,11 @@ function carp_check_version() { $resp = $rpc_client->xmlrpc_method('host_firmware_version'); log_error(sprintf(gettext("XMLRPC versioncheck:").$resp['config_version'] ." -- ". $config['version'])); - if (!isset($resp['config_version']) || - ($resp['config_version'] != $config['version'])) { + if (!isset($resp['config_version'])) { + update_filter_reload_status("The {$g['product_name']} software configuration version of the other member could not be determined. Skipping synchronization to avoid causing a problem!"); + log_error("The {$g['product_name']} software configuration version of the other member could not be determined. Skipping synchronization to avoid causing a problem!"); + return false; + } elseif ($resp['config_version'] != $config['version']) { update_filter_reload_status("The other member is on a different configuration version of {$g['product_name']}. Sync will not be done to prevent problems!"); log_error("The other member is on a different configuration version of {$g['product_name']}. Sync will not be done to prevent problems!"); return false; diff --git a/src/etc/rc.initial.setlanip b/src/etc/rc.initial.setlanip index b0b7144..25ed88e 100755 --- a/src/etc/rc.initial.setlanip +++ b/src/etc/rc.initial.setlanip @@ -134,7 +134,7 @@ function get_interface_config_description($iface) { $fp = fopen('php://stdin', 'r'); /* build an interface collection */ -$ifdescrs = get_configured_interface_with_descr(false, true); +$ifdescrs = get_configured_interface_with_descr(true); $count = count($ifdescrs); /* grab interface that we will operate on, unless there is only one interface */ diff --git a/src/etc/rc.packages b/src/etc/rc.packages index b0f37b3..8a6f886 100755 --- a/src/etc/rc.packages +++ b/src/etc/rc.packages @@ -20,6 +20,11 @@ * limitations under the License. */ +/* If PHP is not running, silently abort and run registration during boot */ +if (!file_exists('/var/run/php-fpm.pid')) { + exit; +} + require_once("config.inc"); require_once("functions.inc"); require_once("filter.inc"); @@ -41,11 +46,6 @@ if ($argc == 1) { exit; } -/* If PHP is not running, silently abort and run registration during boot */ -if (!isvalidpid('/var/run/php-fpm.pid')) { - exit; -} - $pkg = ''; $when = ''; diff --git a/src/etc/rc.php-fpm_restart b/src/etc/rc.php-fpm_restart index 3af827e..c390c77 100755 --- a/src/etc/rc.php-fpm_restart +++ b/src/etc/rc.php-fpm_restart @@ -22,6 +22,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +echo ">>> Killing check_reload_status" +/bin/pkill -9 check_reload_status +sleep 2 + echo ">>> Killing php-fpm" /bin/pkill -F /var/run/php-fpm.pid sleep 2 @@ -40,3 +44,6 @@ echo ">>> Restarting php-fpm" | /usr/bin/logger -p daemon.info -i -t rc.php-fpm_ echo ">>> Starting php-fpm" /usr/local/sbin/php-fpm -c /usr/local/etc/php.ini -y /usr/local/lib/php-fpm.conf -RD 2>&1 >/dev/null +# restart check_reload_status +echo ">>> Starting check_reload_status" +/usr/bin/nice -n20 /usr/local/sbin/check_reload_status |