diff options
Diffstat (limited to 'src/etc')
31 files changed, 1031 insertions, 350 deletions
diff --git a/src/etc/inc/auth.inc b/src/etc/inc/auth.inc index 6e0824b..52a3dc3 100644 --- a/src/etc/inc/auth.inc +++ b/src/etc/inc/auth.inc @@ -36,6 +36,31 @@ $security_passed = true; /* If this function doesn't exist, we're being called from Captive Portal or another internal subsystem which does not include authgui.inc */ +if (function_exists("display_error_form")) { + /* Extra layer of lockout protection. Check if the user is in the GUI + * lockout table before processing a request */ + + /* Fetch the contents of the lockout table. */ + exec("/sbin/pfctl -t 'webConfiguratorlockout' -T show", $entries); + + /* If the client is in the lockout table, print an error, kill states, and exit */ + if (in_array($_SERVER['REMOTE_ADDR'], array_map('trim', $entries))) { + if (!security_checks_disabled()) { + /* They may never see the error since the connection will be cut off, but try to be nice anyhow. */ + display_error_form("501", gettext("Access Denied<br/><br/>Access attempt from a temporarily locked out client address.<br /><br />Try accessing the firewall again after the lockout expires.")); + /* If they are locked out, they shouldn't have a state. Disconnect their connections. */ + $retval = pfSense_kill_states($_SERVER['REMOTE_ADDR']); + if (is_ipaddrv4($_SERVER['REMOTE_ADDR'])) { + $retval = pfSense_kill_states("0.0.0.0/0", $_SERVER['REMOTE_ADDR']); + } elseif (is_ipaddrv6($_SERVER['REMOTE_ADDR'])) { + $retval = pfSense_kill_states("::", $_SERVER['REMOTE_ADDR']); + } + exit; + } + $security_passed = false; + } +} + if (function_exists("display_error_form") && !isset($config['system']['webgui']['nodnsrebindcheck'])) { /* DNS ReBinding attack prevention. https://redmine.pfsense.org/issues/708 */ $found_host = false; @@ -858,6 +883,8 @@ function ldap_setup_caenv($authcfg) { return; } else { $caref = lookup_ca($authcfg['ldap_caref']); + $param = array('caref' => $authcfg['ldap_caref']); + $cachain = ca_chain($param); if (!$caref) { log_error(sprintf(gettext("LDAP: Could not lookup CA by reference for host %s."), $authcfg['ldap_caref'])); /* XXX: Prevent for credential leaking since we cannot setup the CA env. Better way? */ @@ -870,7 +897,7 @@ function ldap_setup_caenv($authcfg) { if (file_exists("{$g['varrun_path']}/certs/{$caref['refid']}.ca")) { @unlink("{$g['varrun_path']}/certs/{$caref['refid']}.ca"); } - file_put_contents("{$g['varrun_path']}/certs/{$caref['refid']}.ca", base64_decode($caref['crt'])); + file_put_contents("{$g['varrun_path']}/certs/{$caref['refid']}.ca", $cachain); @chmod("{$g['varrun_path']}/certs/{$caref['refid']}.ca", 0600); putenv('LDAPTLS_REQCERT=hard'); /* XXX: Probably even the hashed link should be created for this? */ @@ -933,7 +960,7 @@ function ldap_test_bind($authcfg) { ldap_set_option($ldap, LDAP_OPT_NETWORK_TIMEOUT, (int)$ldaptimeout); if (strstr($authcfg['ldap_urltype'], "STARTTLS")) { - if (!(ldap_start_tls($ldap))) { + if (!(@ldap_start_tls($ldap))) { log_error(sprintf(gettext("ERROR! ldap_test_bind() could not STARTTLS to server %s."), $ldapname)); @ldap_close($ldap); return false; @@ -1023,7 +1050,7 @@ function ldap_get_user_ous($show_complete_ou=true, $authcfg) { ldap_set_option($ldap, LDAP_OPT_NETWORK_TIMEOUT, (int)$ldaptimeout); if (strstr($authcfg['ldap_urltype'], "STARTTLS")) { - if (!(ldap_start_tls($ldap))) { + if (!(@ldap_start_tls($ldap))) { log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not STARTTLS to server %s."), $ldapname)); @ldap_close($ldap); return false; @@ -1166,7 +1193,7 @@ function ldap_get_groups($username, $authcfg) { ldap_set_option($ldap, LDAP_OPT_NETWORK_TIMEOUT, (int)$ldaptimeout); if (strstr($authcfg['ldap_urltype'], "STARTTLS")) { - if (!(ldap_start_tls($ldap))) { + if (!(@ldap_start_tls($ldap))) { log_error(sprintf(gettext("ERROR! ldap_get_groups() could not STARTTLS to server %s."), $ldapname)); @ldap_close($ldap); return false; @@ -1314,7 +1341,7 @@ function ldap_backed($username, $passwd, $authcfg) { ldap_set_option($ldap, LDAP_OPT_NETWORK_TIMEOUT, (int)$ldaptimeout); if (strstr($authcfg['ldap_urltype'], "STARTTLS")) { - if (!(ldap_start_tls($ldap))) { + if (!(@ldap_start_tls($ldap))) { log_error(sprintf(gettext("ERROR! ldap_backed() could not STARTTLS to server %s."), $ldapname)); @ldap_close($ldap); return false; @@ -1790,7 +1817,7 @@ function session_auth() { exit; } else { /* give the user an error message */ - $_SESSION['Login_Error'] = "Username or Password incorrect"; + $_SESSION['Login_Error'] = gettext("Username or Password incorrect"); log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}"); if (isAjax()) { echo "showajaxmessage('{$_SESSION['Login_Error']}');"; diff --git a/src/etc/inc/authgui.inc b/src/etc/inc/authgui.inc index 65358d1..20d4039 100644 --- a/src/etc/inc/authgui.inc +++ b/src/etc/inc/authgui.inc @@ -34,7 +34,9 @@ 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 @@ -106,33 +108,77 @@ function display_error_form($http_code, $desc) { return; } - $cssfile = "/css/pfSense.css"; - - if (isset($user_settings['webgui']['webguicss'])) { - if (file_exists("/usr/local/www/css/" . $user_settings['webgui']['webguicss'])) { - $cssfile = "/css/" . $user_settings['webgui']['webguicss']; - } - } - + $logincssfile = "#770101"; ?> + <!DOCTYPE html> <html lang="en"> -<head> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" href="<?=$cssfile?>" /> - <title><?=gettext("Error: not allowed"); ?></title> -</head> -<body id="error" class="no-menu"> - <div id="jumbotron"> - <div class="container"> - <div class="col-sm-offset-3 col-sm-6 col-xs-12"> - <!-- FIXME: We really need to POST the logout action --> - <div class="alert alert-danger" role="alert"><a href="index.php?logout"><?=$desc;?></a></div> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css" type="text/css"> + <link rel="stylesheet" href="/css/login.css" type="text/css"> + <title><?=gettext("Error"); ?></title> + </head> + + <body id="error" > + <div id="total"> + <header> + <div id="headerrow"> + <div class="row"> + <div class="col-sm-4"> + <div id="logodiv" style="text-align:center" class="nowarning"> + <svg role="img" aria-labelledby="pfsense-logo" x="0px" y="0px" viewBox="0 0 282.8 84.2" width="240" height="100%"> + <title id="pfsense-logo-svg">pfSense Logo</title> + <style type="text/css"> + .logo-st0{fill:#2B40B5;} + .logo-st1{fill:#1475CF;} + .logo-st2{fill:#1C1275;} + </style> + <path class="logo-st0" d="M27.8,57.7c2.9,0,5.4-0.9,7.5-2.6c2.1-1.7,3.6-4,4.4-6.8c0.8-2.8,0.6-5.1-0.5-6.8c-1.1-1.7-3.2-2.6-6.1-2.6 c-2.9,0-5.4,0.9-7.5,2.6c-2.1,1.7-3.5,4-4.3,6.8c-0.8,2.8-0.7,5.1,0.5,6.8C22.8,56.9,24.8,57.7,27.8,57.7"/> + <path class="logo-st0" d="M115.1,46.6c-1.5-0.8-3-1.4-4.7-1.8c-1.7-0.4-3.2-0.7-4.7-1.1c-1.5-0.3-2.7-0.7-3.6-1.1c-0.9-0.4-1.4-1.1-1.4-2 c0-1.1,0.5-1.9,1.4-2.4c0.9-0.5,1.9-0.7,2.8-0.7c2.8,0,5,1,6.7,3.1l7-7c-1.7-1.8-3.9-3.1-6.4-3.8c-2.5-0.7-5-1.1-7.4-1.1 c-1.9,0-3.9,0.2-5.7,0.7c-1.9,0.5-3.6,1.2-5,2.3c-1.5,1-2.6,2.3-3.5,3.9c-0.9,1.6-1.3,3.5-1.3,5.7c0,2.3,0.5,4.2,1.4,5.6 c0.9,1.4,2.1,2.5,3.6,3.3c1.5,0.8,3,1.3,4.7,1.7c1.7,0.4,3.2,0.7,4.7,1.1c1.5,0.3,2.7,0.7,3.6,1.2c0.9,0.5,1.4,1.2,1.4,2.2 c0,1-0.5,1.7-1.6,2.1c-1.1,0.4-2.3,0.6-3.6,0.6c-1.7,0-3.3-0.3-4.6-1c-1.3-0.7-2.5-1.7-3.6-3l-7,7.7c1.8,1.9,4.1,3.2,6.7,3.9 c2.7,0.7,5.3,1.1,7.9,1.1c2,0,4-0.2,6.1-0.6c2-0.4,3.9-1,5.5-2c1.6-0.9,3-2.2,4-3.8c1-1.6,1.6-3.5,1.6-5.9c0-2.3-0.5-4.2-1.4-5.6 C117.7,48.6,116.5,47.4,115.1,46.6"/> + <path class="logo-st0" d="M156.3,34.1c-1.5-1.7-3.3-3-5.5-3.9c-2.2-0.9-4.6-1.4-7.2-1.4c-2.9,0-5.6,0.5-8.1,1.4c-2.5,0.9-4.7,2.2-6.6,3.9 c-1.9,1.7-3.3,3.8-4.4,6.2c-1.1,2.4-1.6,5.1-1.6,8c0,3,0.5,5.6,1.6,8c1.1,2.4,2.5,4.5,4.4,6.2c1.9,1.7,4.1,3,6.6,3.9 c2.5,0.9,5.2,1.4,8.1,1.4c3,0,5.9-0.6,8.7-1.9c2.8-1.3,5.1-3.1,7-5.4l-8-5.9c-1,1.3-2.1,2.4-3.4,3.3c-1.3,0.8-2.9,1.3-4.8,1.3 c-2.2,0-4.1-0.7-5.7-2c-1.5-1.3-2.5-3.1-3-5.2H161v-3.6c0-3-0.4-5.6-1.2-8C159,37.9,157.8,35.8,156.3,34.1 M134.3,44.1 c0.1-0.9,0.3-1.8,0.7-2.6c0.4-0.8,0.9-1.6,1.6-2.2c0.7-0.6,1.5-1.2,2.5-1.6c1-0.4,2.1-0.6,3.4-0.6c2.1,0,3.8,0.7,5.1,2.1 c1.3,1.4,2,3,1.9,5H134.3z"/> + <path class="logo-st0" d="M198.3,33.8c-1-1.6-2.4-2.8-4.2-3.7c-1.8-0.9-4.1-1.3-7-1.3c-1.4,0-2.7,0.2-3.8,0.5c-1.2,0.4-2.2,0.8-3.1,1.4 c-0.9,0.6-1.7,1.2-2.4,1.9c-0.7,0.7-1.2,1.4-1.5,2.1H176v-5.1h-11v37.2h11.5V48.4c0-1.2,0.1-2.4,0.2-3.5c0.2-1.1,0.5-2.1,1-3 c0.5-0.9,1.2-1.6,2.1-2.1c0.9-0.5,2.1-0.8,3.6-0.8c1.5,0,2.6,0.3,3.4,0.9c0.8,0.6,1.4,1.4,1.8,2.4c0.4,1,0.6,2,0.7,3.2 c0.1,1.1,0.1,2.3,0.1,3.3v18.2h11.5V46.4c0-2.5-0.2-4.8-0.5-7C199.9,37.3,199.3,35.4,198.3,33.8"/> + <path class="logo-st0" d="M231.5,46.6c-1.5-0.8-3-1.4-4.7-1.8c-1.7-0.4-3.2-0.7-4.7-1.1c-1.5-0.3-2.7-0.7-3.6-1.1c-0.9-0.4-1.4-1.1-1.4-2 c0-1.1,0.5-1.9,1.4-2.4c0.9-0.5,1.9-0.7,2.8-0.7c2.8,0,5,1,6.7,3.1l7-7c-1.7-1.8-3.9-3.1-6.4-3.8c-2.5-0.7-5-1.1-7.4-1.1 c-1.9,0-3.9,0.2-5.7,0.7c-1.9,0.5-3.6,1.2-5,2.3c-1.5,1-2.6,2.3-3.5,3.9c-0.9,1.6-1.3,3.5-1.3,5.7c0,2.3,0.5,4.2,1.4,5.6 c0.9,1.4,2.1,2.5,3.6,3.3c1.5,0.8,3,1.3,4.7,1.7c1.7,0.4,3.2,0.7,4.7,1.1c1.5,0.3,2.7,0.7,3.6,1.2c0.9,0.5,1.4,1.2,1.4,2.2 c0,1-0.5,1.7-1.6,2.1c-1.1,0.4-2.3,0.6-3.6,0.6c-1.7,0-3.3-0.3-4.6-1c-1.3-0.7-2.5-1.7-3.6-3l-7,7.7c1.8,1.9,4.1,3.2,6.7,3.9 c2.7,0.7,5.3,1.1,7.9,1.1c2,0,4-0.2,6.1-0.6c2-0.4,3.9-1,5.5-2c1.6-0.9,3-2.2,4-3.8c1-1.6,1.6-3.5,1.6-5.9c0-2.3-0.5-4.2-1.4-5.6 C234.1,48.6,232.9,47.4,231.5,46.6"/> + <path class="logo-st0" d="M277.4,51.9v-4.2c-0.1-2.7-0.5-5.2-1.2-7.4c-0.8-2.4-2-4.5-3.5-6.2c-1.5-1.7-3.3-3-5.5-3.9 c-2.2-0.9-4.6-1.4-7.2-1.4c-2.9,0-5.6,0.5-8.1,1.4c-2.5,0.9-4.7,2.2-6.6,3.9c-1.9,1.7-3.3,3.8-4.4,6.2c-1.1,2.4-1.6,5.1-1.6,8 c0,3,0.5,5.6,1.6,8c1.1,2.4,2.5,4.5,4.4,6.2c1.9,1.7,4.1,3,6.6,3.9c2.5,0.9,5.2,1.4,8.1,1.4c3,0,5.9-0.6,8.7-1.9 c2.8-1.3,5.1-3.1,7-5.4l-8-5.9c-1,1.3-2.1,2.4-3.4,3.3c-1.3,0.8-2.9,1.3-4.8,1.3c-2.2,0-4.1-0.7-5.7-2c-1.5-1.3-2.5-3.1-3-5.2H277.4 z M250.7,44.1c0.1-0.9,0.3-1.8,0.7-2.6c0.4-0.8,0.9-1.6,1.6-2.2c0.7-0.6,1.5-1.2,2.5-1.6c1-0.4,2.1-0.6,3.4-0.6 c2.1,0,3.8,0.7,5.1,2.1c1.3,1.4,2,3,1.9,5H250.7z"/> + <path class="logo-st1" d="M52.6,38.9l2.6-9.2h4.6l1.8-6.6c0.6-2,1.3-4,2.2-5.8c0.8-1.8,2-3.4,3.4-4.8c1.4-1.4,3.2-2.5,5.3-3.3 c2.1-0.8,4.8-1.2,7.9-1.2c0.8,0,1.5,0,2.3,0.1c-0.7-2.9-3.3-5-6.3-5.1H11.9c-3.6,0-6.5,3-6.5,6.6V67l10.5-37.3h10.6l-1.4,4.9h0.2 c0.6-0.7,1.4-1.3,2.4-2c1-0.7,2-1.3,3.1-1.9c1.1-0.6,2.3-1,3.6-1.4c1.3-0.4,2.6-0.5,3.9-0.5c2.8,0,5.1,0.5,7.1,1.4 c2,0.9,3.5,2.3,4.7,4c1,1.5,1.6,3.3,1.9,5.4l0.8-0.6H52.6z"/> + <path class="logo-st2" d="M82.1,17.9c-0.5-0.1-1.1-0.2-1.8-0.2c-1.8,0-3.3,0.4-4.5,1.2c-1.1,0.8-2.1,2.4-2.8,4.9l-1.7,5.9h6.5l1.6,5.1 l-4.2,4.1h-6.5l-7.9,28H49.4l7.9-28h-4.4L52,39.5c0,0.2,0.1,0.5,0.1,0.7c0.2,2.3-0.1,4.9-0.9,7.7c-0.7,2.6-1.8,5.1-3.3,7.5 c-1.5,2.4-3.2,4.5-5.1,6.3c-2,1.8-4.2,3.3-6.6,4.4c-2.4,1.1-4.9,1.6-7.6,1.6c-2.4,0-4.5-0.4-6.4-1.1c-1.9-0.7-3.2-2-4-3.8h-0.2 l-5,17.7h63.3c3.6,0,6.6-2.9,6.6-6.6V18.2C82.6,18.1,82.3,18,82.1,17.9"/> + <path class="logo-st0" d="M277.6,68.5h0.8c0.4,0,0.6-0.1,0.7-0.2c0.1-0.1,0.2-0.2,0.2-0.4c0-0.1,0-0.2-0.1-0.3c-0.1-0.1-0.1-0.2-0.3-0.2 c-0.1,0-0.3-0.1-0.6-0.1h-0.7V68.5z M277,70.6v-3.8h1.3c0.5,0,0.8,0,1,0.1c0.2,0.1,0.4,0.2,0.5,0.4c0.1,0.2,0.2,0.4,0.2,0.6 c0,0.3-0.1,0.5-0.3,0.7c-0.2,0.2-0.5,0.3-0.8,0.3c0.1,0.1,0.2,0.1,0.3,0.2c0.2,0.2,0.3,0.4,0.6,0.8l0.5,0.7h-0.8l-0.3-0.6 c-0.3-0.5-0.5-0.8-0.6-0.9c-0.1-0.1-0.3-0.1-0.5-0.1h-0.4v1.6H277z M278.6,65.7c-0.5,0-1,0.1-1.5,0.4c-0.5,0.3-0.8,0.6-1.1,1.1 c-0.3,0.5-0.4,1-0.4,1.5c0,0.5,0.1,1,0.4,1.5c0.3,0.5,0.6,0.8,1.1,1.1c0.5,0.3,1,0.4,1.5,0.4c0.5,0,1-0.1,1.5-0.4 c0.5-0.3,0.8-0.6,1.1-1.1c0.3-0.5,0.4-1,0.4-1.5c0-0.5-0.1-1-0.4-1.5c-0.3-0.5-0.6-0.8-1.1-1.1C279.6,65.8,279.1,65.7,278.6,65.7z M278.6,65.1c0.6,0,1.2,0.2,1.8,0.5c0.6,0.3,1,0.7,1.3,1.3c0.3,0.6,0.5,1.2,0.5,1.8c0,0.6-0.2,1.2-0.5,1.8c-0.3,0.6-0.8,1-1.3,1.3 c-0.6,0.3-1.2,0.5-1.8,0.5c-0.6,0-1.2-0.2-1.8-0.5c-0.6-0.3-1-0.8-1.3-1.3c-0.3-0.6-0.5-1.2-0.5-1.8c0-0.6,0.2-1.2,0.5-1.8 c0.3-0.6,0.8-1,1.3-1.3C277.4,65.2,278,65.1,278.6,65.1z"/> + </svg> + </div> + </div> + <div class="col-sm-8 nowarning msgbox text-center"> + <span id="hostspan"> + </span> + </div> + </div> + </div> + </header> + + <div style="background: <?=$logincssfile?>;" class="pagebody"> + <div class="col-sm-2"></div> + + <div class="col-sm-8 offset-md-4 logoCol"> + <div class="loginCont center-block error-panel"> + <a href="index.php?logout"><?=$desc;?></a> + </div> + </div> + + <div class="col-sm-2"></div> </div> + + <footer id="3"> + <div id="footertext"> + <p class="text-muted"> + <a target="_blank" href="https://www.pfsense.org/?gui=bootstrap">pfSense</a> is © + 2004 - 2017 by <a href="https://pfsense.org/license" class="tblnk">Rubicon Communications, LLC (Netgate)</a>. All Rights Reserved. + [<a href="/license.php" class="tblnk">view license</a>] + </p> + </div> + </footer> </div> - </div> -</body> + </body> </html> + <?php } // end function @@ -244,116 +290,138 @@ function display_login_form() { $loginautocomplete = isset($config['system']['webgui']['loginautocomplete']) ? '' : 'autocomplete="off"'; if (is_ipaddr($http_host) && !$local_ip && !isset($config['system']['webgui']['nohttpreferercheck'])) { - $warnclass = "bb2"; + $warnclass = "pagebodywarn"; // Make room for a warning display row } else { - $warnclass = "bb"; + $warnclass = "pagebody"; } ?> <!DOCTYPE html> <html lang="en"> -<head> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css" type="text/css"> - <link rel="stylesheet" href="css/login.css" type="text/css"> - <title><?=gettext("Login"); ?></title> - <script type="text/javascript"> - //<![CDATA{ - var events = events || []; - //]]> - </script> -</head> - -<body id="login" > - <div id="total"> - <header id="1"> - <div id="a"> - <div class="row"> - <div class="col-sm-4"> - <div id="logodiv" style="text-align:center" class="nowarning"> - <img src="pfsense-trans.png" height="100%"/> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css" type="text/css"> + <link rel="stylesheet" href="/css/login.css" type="text/css"> + <title><?=gettext("Login"); ?></title> + <script type="text/javascript"> + //<![CDATA{ + var events = events || []; + //]]> + </script> + </head> + + <body id="login" > + <div id="total"> + <header> + <div id="headerrow"> + <div class="row"> + <!-- Header left logo box --> + <div class="col-sm-4"> + <div id="logodiv" style="text-align:center" class="nowarning"> + <svg role="img" aria-labelledby="pfsense-logo" x="0px" y="0px" viewBox="0 0 282.8 84.2" width="240" height="100%"> + <title id="pfsense-logo-svg">pfSense Logo</title> + <style type="text/css"> + .logo-st0{fill:#2B40B5;} + .logo-st1{fill:#1475CF;} + .logo-st2{fill:#1C1275;} + </style> + <path class="logo-st0" d="M27.8,57.7c2.9,0,5.4-0.9,7.5-2.6c2.1-1.7,3.6-4,4.4-6.8c0.8-2.8,0.6-5.1-0.5-6.8c-1.1-1.7-3.2-2.6-6.1-2.6 c-2.9,0-5.4,0.9-7.5,2.6c-2.1,1.7-3.5,4-4.3,6.8c-0.8,2.8-0.7,5.1,0.5,6.8C22.8,56.9,24.8,57.7,27.8,57.7"/> + <path class="logo-st0" d="M115.1,46.6c-1.5-0.8-3-1.4-4.7-1.8c-1.7-0.4-3.2-0.7-4.7-1.1c-1.5-0.3-2.7-0.7-3.6-1.1c-0.9-0.4-1.4-1.1-1.4-2 c0-1.1,0.5-1.9,1.4-2.4c0.9-0.5,1.9-0.7,2.8-0.7c2.8,0,5,1,6.7,3.1l7-7c-1.7-1.8-3.9-3.1-6.4-3.8c-2.5-0.7-5-1.1-7.4-1.1 c-1.9,0-3.9,0.2-5.7,0.7c-1.9,0.5-3.6,1.2-5,2.3c-1.5,1-2.6,2.3-3.5,3.9c-0.9,1.6-1.3,3.5-1.3,5.7c0,2.3,0.5,4.2,1.4,5.6 c0.9,1.4,2.1,2.5,3.6,3.3c1.5,0.8,3,1.3,4.7,1.7c1.7,0.4,3.2,0.7,4.7,1.1c1.5,0.3,2.7,0.7,3.6,1.2c0.9,0.5,1.4,1.2,1.4,2.2 c0,1-0.5,1.7-1.6,2.1c-1.1,0.4-2.3,0.6-3.6,0.6c-1.7,0-3.3-0.3-4.6-1c-1.3-0.7-2.5-1.7-3.6-3l-7,7.7c1.8,1.9,4.1,3.2,6.7,3.9 c2.7,0.7,5.3,1.1,7.9,1.1c2,0,4-0.2,6.1-0.6c2-0.4,3.9-1,5.5-2c1.6-0.9,3-2.2,4-3.8c1-1.6,1.6-3.5,1.6-5.9c0-2.3-0.5-4.2-1.4-5.6 C117.7,48.6,116.5,47.4,115.1,46.6"/> + <path class="logo-st0" d="M156.3,34.1c-1.5-1.7-3.3-3-5.5-3.9c-2.2-0.9-4.6-1.4-7.2-1.4c-2.9,0-5.6,0.5-8.1,1.4c-2.5,0.9-4.7,2.2-6.6,3.9 c-1.9,1.7-3.3,3.8-4.4,6.2c-1.1,2.4-1.6,5.1-1.6,8c0,3,0.5,5.6,1.6,8c1.1,2.4,2.5,4.5,4.4,6.2c1.9,1.7,4.1,3,6.6,3.9 c2.5,0.9,5.2,1.4,8.1,1.4c3,0,5.9-0.6,8.7-1.9c2.8-1.3,5.1-3.1,7-5.4l-8-5.9c-1,1.3-2.1,2.4-3.4,3.3c-1.3,0.8-2.9,1.3-4.8,1.3 c-2.2,0-4.1-0.7-5.7-2c-1.5-1.3-2.5-3.1-3-5.2H161v-3.6c0-3-0.4-5.6-1.2-8C159,37.9,157.8,35.8,156.3,34.1 M134.3,44.1 c0.1-0.9,0.3-1.8,0.7-2.6c0.4-0.8,0.9-1.6,1.6-2.2c0.7-0.6,1.5-1.2,2.5-1.6c1-0.4,2.1-0.6,3.4-0.6c2.1,0,3.8,0.7,5.1,2.1 c1.3,1.4,2,3,1.9,5H134.3z"/> + <path class="logo-st0" d="M198.3,33.8c-1-1.6-2.4-2.8-4.2-3.7c-1.8-0.9-4.1-1.3-7-1.3c-1.4,0-2.7,0.2-3.8,0.5c-1.2,0.4-2.2,0.8-3.1,1.4 c-0.9,0.6-1.7,1.2-2.4,1.9c-0.7,0.7-1.2,1.4-1.5,2.1H176v-5.1h-11v37.2h11.5V48.4c0-1.2,0.1-2.4,0.2-3.5c0.2-1.1,0.5-2.1,1-3 c0.5-0.9,1.2-1.6,2.1-2.1c0.9-0.5,2.1-0.8,3.6-0.8c1.5,0,2.6,0.3,3.4,0.9c0.8,0.6,1.4,1.4,1.8,2.4c0.4,1,0.6,2,0.7,3.2 c0.1,1.1,0.1,2.3,0.1,3.3v18.2h11.5V46.4c0-2.5-0.2-4.8-0.5-7C199.9,37.3,199.3,35.4,198.3,33.8"/> + <path class="logo-st0" d="M231.5,46.6c-1.5-0.8-3-1.4-4.7-1.8c-1.7-0.4-3.2-0.7-4.7-1.1c-1.5-0.3-2.7-0.7-3.6-1.1c-0.9-0.4-1.4-1.1-1.4-2 c0-1.1,0.5-1.9,1.4-2.4c0.9-0.5,1.9-0.7,2.8-0.7c2.8,0,5,1,6.7,3.1l7-7c-1.7-1.8-3.9-3.1-6.4-3.8c-2.5-0.7-5-1.1-7.4-1.1 c-1.9,0-3.9,0.2-5.7,0.7c-1.9,0.5-3.6,1.2-5,2.3c-1.5,1-2.6,2.3-3.5,3.9c-0.9,1.6-1.3,3.5-1.3,5.7c0,2.3,0.5,4.2,1.4,5.6 c0.9,1.4,2.1,2.5,3.6,3.3c1.5,0.8,3,1.3,4.7,1.7c1.7,0.4,3.2,0.7,4.7,1.1c1.5,0.3,2.7,0.7,3.6,1.2c0.9,0.5,1.4,1.2,1.4,2.2 c0,1-0.5,1.7-1.6,2.1c-1.1,0.4-2.3,0.6-3.6,0.6c-1.7,0-3.3-0.3-4.6-1c-1.3-0.7-2.5-1.7-3.6-3l-7,7.7c1.8,1.9,4.1,3.2,6.7,3.9 c2.7,0.7,5.3,1.1,7.9,1.1c2,0,4-0.2,6.1-0.6c2-0.4,3.9-1,5.5-2c1.6-0.9,3-2.2,4-3.8c1-1.6,1.6-3.5,1.6-5.9c0-2.3-0.5-4.2-1.4-5.6 C234.1,48.6,232.9,47.4,231.5,46.6"/> + <path class="logo-st0" d="M277.4,51.9v-4.2c-0.1-2.7-0.5-5.2-1.2-7.4c-0.8-2.4-2-4.5-3.5-6.2c-1.5-1.7-3.3-3-5.5-3.9 c-2.2-0.9-4.6-1.4-7.2-1.4c-2.9,0-5.6,0.5-8.1,1.4c-2.5,0.9-4.7,2.2-6.6,3.9c-1.9,1.7-3.3,3.8-4.4,6.2c-1.1,2.4-1.6,5.1-1.6,8 c0,3,0.5,5.6,1.6,8c1.1,2.4,2.5,4.5,4.4,6.2c1.9,1.7,4.1,3,6.6,3.9c2.5,0.9,5.2,1.4,8.1,1.4c3,0,5.9-0.6,8.7-1.9 c2.8-1.3,5.1-3.1,7-5.4l-8-5.9c-1,1.3-2.1,2.4-3.4,3.3c-1.3,0.8-2.9,1.3-4.8,1.3c-2.2,0-4.1-0.7-5.7-2c-1.5-1.3-2.5-3.1-3-5.2H277.4 z M250.7,44.1c0.1-0.9,0.3-1.8,0.7-2.6c0.4-0.8,0.9-1.6,1.6-2.2c0.7-0.6,1.5-1.2,2.5-1.6c1-0.4,2.1-0.6,3.4-0.6 c2.1,0,3.8,0.7,5.1,2.1c1.3,1.4,2,3,1.9,5H250.7z"/> + <path class="logo-st1" d="M52.6,38.9l2.6-9.2h4.6l1.8-6.6c0.6-2,1.3-4,2.2-5.8c0.8-1.8,2-3.4,3.4-4.8c1.4-1.4,3.2-2.5,5.3-3.3 c2.1-0.8,4.8-1.2,7.9-1.2c0.8,0,1.5,0,2.3,0.1c-0.7-2.9-3.3-5-6.3-5.1H11.9c-3.6,0-6.5,3-6.5,6.6V67l10.5-37.3h10.6l-1.4,4.9h0.2 c0.6-0.7,1.4-1.3,2.4-2c1-0.7,2-1.3,3.1-1.9c1.1-0.6,2.3-1,3.6-1.4c1.3-0.4,2.6-0.5,3.9-0.5c2.8,0,5.1,0.5,7.1,1.4 c2,0.9,3.5,2.3,4.7,4c1,1.5,1.6,3.3,1.9,5.4l0.8-0.6H52.6z"/> + <path class="logo-st2" d="M82.1,17.9c-0.5-0.1-1.1-0.2-1.8-0.2c-1.8,0-3.3,0.4-4.5,1.2c-1.1,0.8-2.1,2.4-2.8,4.9l-1.7,5.9h6.5l1.6,5.1 l-4.2,4.1h-6.5l-7.9,28H49.4l7.9-28h-4.4L52,39.5c0,0.2,0.1,0.5,0.1,0.7c0.2,2.3-0.1,4.9-0.9,7.7c-0.7,2.6-1.8,5.1-3.3,7.5 c-1.5,2.4-3.2,4.5-5.1,6.3c-2,1.8-4.2,3.3-6.6,4.4c-2.4,1.1-4.9,1.6-7.6,1.6c-2.4,0-4.5-0.4-6.4-1.1c-1.9-0.7-3.2-2-4-3.8h-0.2 l-5,17.7h63.3c3.6,0,6.6-2.9,6.6-6.6V18.2C82.6,18.1,82.3,18,82.1,17.9"/> + <path class="logo-st0" d="M277.6,68.5h0.8c0.4,0,0.6-0.1,0.7-0.2c0.1-0.1,0.2-0.2,0.2-0.4c0-0.1,0-0.2-0.1-0.3c-0.1-0.1-0.1-0.2-0.3-0.2 c-0.1,0-0.3-0.1-0.6-0.1h-0.7V68.5z M277,70.6v-3.8h1.3c0.5,0,0.8,0,1,0.1c0.2,0.1,0.4,0.2,0.5,0.4c0.1,0.2,0.2,0.4,0.2,0.6 c0,0.3-0.1,0.5-0.3,0.7c-0.2,0.2-0.5,0.3-0.8,0.3c0.1,0.1,0.2,0.1,0.3,0.2c0.2,0.2,0.3,0.4,0.6,0.8l0.5,0.7h-0.8l-0.3-0.6 c-0.3-0.5-0.5-0.8-0.6-0.9c-0.1-0.1-0.3-0.1-0.5-0.1h-0.4v1.6H277z M278.6,65.7c-0.5,0-1,0.1-1.5,0.4c-0.5,0.3-0.8,0.6-1.1,1.1 c-0.3,0.5-0.4,1-0.4,1.5c0,0.5,0.1,1,0.4,1.5c0.3,0.5,0.6,0.8,1.1,1.1c0.5,0.3,1,0.4,1.5,0.4c0.5,0,1-0.1,1.5-0.4 c0.5-0.3,0.8-0.6,1.1-1.1c0.3-0.5,0.4-1,0.4-1.5c0-0.5-0.1-1-0.4-1.5c-0.3-0.5-0.6-0.8-1.1-1.1C279.6,65.8,279.1,65.7,278.6,65.7z M278.6,65.1c0.6,0,1.2,0.2,1.8,0.5c0.6,0.3,1,0.7,1.3,1.3c0.3,0.6,0.5,1.2,0.5,1.8c0,0.6-0.2,1.2-0.5,1.8c-0.3,0.6-0.8,1-1.3,1.3 c-0.6,0.3-1.2,0.5-1.8,0.5c-0.6,0-1.2-0.2-1.8-0.5c-0.6-0.3-1-0.8-1.3-1.3c-0.3-0.6-0.5-1.2-0.5-1.8c0-0.6,0.2-1.2,0.5-1.8 c0.3-0.6,0.8-1,1.3-1.3C277.4,65.2,278,65.1,278.6,65.1z"/> + </svg> + </div> </div> - </div> - <div class="col-sm-8 nowarning msgbox text-center"> - <span id="hostspan"> - <a><h4><?=$loginbannerstr?></h4></a> - </span - </div> - </div> + <!-- Header center message box --> + <div class="col-sm-4 nowarning msgbox text-center text-danger"> <?php - if ($warnclass == "bb2") { + if (!empty($_POST['usernamefld'])) { + print("<h4>" . $_SESSION['Login_Error'] . "</h4>"); + } ?> + </div> - <div class="row"> - <div class="col-sm-12"> - <div class="alert alert-warning" class="<?=$warnclass?>"> - <?=gettext("The IP address being used to access this router is not configured locally, which may be forwarded by NAT or other means. - If this forwarding is unexpected, it should be verified that a man-in-the-middle attack is not taking place.")?> + <!-- Header right message box (hostname or msg)--> + <div class="col-sm-4 nowarning msgbox text-center"> + <span id="hostspan"> + <a><h4><?=$loginbannerstr?></h4></a> + </span> </div> </div> - </div> <?php -} + if ($warnclass == "pagebodywarn") { ?> - </div> - </header> - - <div style="background: <?=$logincssfile?>;" class="<?=$warnclass?>"> - <div class="col-sm-4"> - </div> - - <div class="col-sm-4 logoCol"> - <div class="loginCont center-block"> - <p class="form-title"> - Sign In - </p> - - <form method="post" class="login"> - <input name="usernamefld" id="usernamefld" type="text" placeholder="Username" /> - <input name="passwordfld" id="passwordfld" type="password" placeholder="Password" /> - <input type="submit" name="login" value="Sign In" class="btn btn-success btn-sm" /> - </form> - </div> - </div> - - <div class="col-sm-4"> - </div> - </div> - <footer id="3"> - <div id="c"> - <p class="text-muted"> - <a target="_blank" href="https://www.pfsense.org/?gui=bootstrap">pfSense</a> is © - 2004 - 2017 by <a href="https://pfsense.org/license" class="tblnk">Rubicon Communications, LLC (Netgate)</a>. All Rights Reserved. - [<a href="/license.php" class="tblnk">view license</a>] - </p> - </div> - </footer> - </div> - - <script src="/vendor/jquery/jquery-1.12.0.min.js?v=<?=filemtime('/usr/local/www/vendor/jquery/jquery-1.12.0.min.js')?>"></script> - <script src="/vendor/bootstrap/js/bootstrap.min.js?v=<?=filemtime('/usr/local/www/vendor/bootstrap/js/bootstrap.min.js')?>"></script> - <script src="/js/pfSense.js?v=<?=filemtime('/usr/local/www/js/pfSense.js')?>"></script> - - <script type="text/javascript"> - //!<[CDATA[ - events.push(function() { - document.cookie= - "cookie_test=1" + - "<?php echo $config['system']['webgui']['protocol'] == 'https' ? '; secure' : '';?>"; - - if (document.cookie.indexOf("cookie_test") == -1) { - alert("<?=gettext('The browser must support cookies to login.')?>"); - } + <div class="row"> + <div class="col-sm-12"> + <div class="alert alert-warning <?=$warnclass?>"> + <?=gettext("The IP address being used to access this router is not configured locally, which may be forwarded by NAT or other means. + If this forwarding is unexpected, it should be verified that a man-in-the-middle attack is not taking place.")?> + </div> + </div> + </div> +<?php + } +?> + </div> + </header> + + <div style="background: <?=$logincssfile?>;" class="<?=$warnclass?>"> + <div class="col-sm-4"></div> + + <div class="col-sm-4 offset-md-4 logoCol"> + <div class="loginCont center-block"> + <form method="post" <?=$loginautocomplete?> class="login"> + <p class="form-title">Sign In</p> + <input name="usernamefld" id="usernamefld" type="text" placeholder="Username" autocorrect="off" autocapitalize="none"/> + <input name="passwordfld" id="passwordfld" type="password" placeholder="Password" /> + <input type="submit" name="login" value="Sign In" class="btn btn-success btn-sm" /> + </form> + </div> + </div> + + <div class="col-sm-4"></div> + </div> + + <footer id="3"> + <div id="footertext"> + <p class="text-muted"> + <a target="_blank" href="https://www.pfsense.org/?gui=bootstrap">pfSense</a> is © + 2004 - 2017 by <a href="https://pfsense.org/license" class="tblnk">Rubicon Communications, LLC (Netgate)</a>. All Rights Reserved. + [<a href="/license.php" class="tblnk">view license</a>] + </p> + </div> + </footer> + </div> + + <script src="/vendor/jquery/jquery-1.12.0.min.js?v=<?=filemtime('/usr/local/www/vendor/jquery/jquery-1.12.0.min.js')?>"></script> + <script src="/vendor/bootstrap/js/bootstrap.min.js?v=<?=filemtime('/usr/local/www/vendor/bootstrap/js/bootstrap.min.js')?>"></script> + <script src="/js/pfSense.js?v=<?=filemtime('/usr/local/www/js/pfSense.js')?>"></script> + + <script type="text/javascript"> + //!<[CDATA[ + events.push(function() { + document.cookie= + "cookie_test=1" + + "<?php echo $config['system']['webgui']['protocol'] == 'https' ? '; secure' : '';?>"; + + if (document.cookie.indexOf("cookie_test") == -1) { + alert("<?=gettext('The browser must support cookies to login.')?>"); + } - // Delete it - document.cookie = "cookie_test=1; expires=Thu, 01-Jan-1970 00:00:01 GMT"; - }); - //]]> - </script> + // Delete it + document.cookie = "cookie_test=1; expires=Thu, 01-Jan-1970 00:00:01 GMT"; + }); + //]]> + </script> -</body> + </body> </html> -<?php +<?php } // end function diff --git a/src/etc/inc/captiveportal.inc b/src/etc/inc/captiveportal.inc index 22138fe..1f232d7 100644 --- a/src/etc/inc/captiveportal.inc +++ b/src/etc/inc/captiveportal.inc @@ -630,9 +630,9 @@ function captiveportal_init_rules($reinit = false) { $cprules .= "table {$cpzone}_auth_up create type addr valtype pipe\n"; $cprules .= "table {$cpzone}_auth_down create type addr valtype pipe\n"; $cprules .= captiveportal_create_ipfw_rule("add", $rulenum, - "pipe tablearg ip from table({$cpzone}_auth_up) to any in"); + "pipe tablearg ip from table({$cpzone}_auth_up) to any layer2 in"); $cprules .= captiveportal_create_ipfw_rule("add", $rulenum, - "pipe tablearg ip from any to table({$cpzone}_auth_down) out"); + "pipe tablearg ip from any to table({$cpzone}_auth_down) layer2 out"); if (!empty($config['captiveportal'][$cpzone]['listenporthttp'])) { $listenporthttp = $config['captiveportal'][$cpzone]['listenporthttp']; @@ -663,7 +663,6 @@ function captiveportal_init_rules($reinit = false) { "skipto 65534 all from any to any"); /* generate passthru mac database */ - file_put_contents("/tmp/debug_antes", $cprules); $cprules .= captiveportal_passthrumac_configure(true); $cprules .= "\n"; @@ -801,7 +800,7 @@ function captiveportal_prune_old() { $uidletimeout = (is_numeric($cpentry[8])) ? $cpentry[8] : $idletimeout; /* if an idle timeout is specified, get last activity timestamp from ipfw */ if (!$timedout && $uidletimeout > 0) { - $lastact = captiveportal_get_last_activity($cpentry[2], $cpentry[3]); + $lastact = captiveportal_get_last_activity($cpentry[2]); /* If the user has logged on but not sent any traffic they will never be logged out. * We "fix" this by setting lastact to the login timestamp. */ @@ -861,10 +860,8 @@ function captiveportal_prune_old() { false, // Not an interim request $rastop_time); // Stop Time $clientsn = (is_ipaddrv6($cpentry[2])) ? 128 : 32; - /* XXX: Fix - $_gb = @pfSense_ipfw_table($cpzoneid, IP_FW_TABLE_XZEROENTRY, {$cpzone}_auth_up, $cpentry[2], $clientsn, $cpentry[3]); - $_gb = @pfSense_ipfw_table($cpzoneid, IP_FW_TABLE_XZEROENTRY, {$cpzone}_auth_down, $cpentry[2], $clientsn, $cpentry[3]); - */ + pfSense_ipfw_table_zerocnt("{$cpzone}_auth_up", "{$cpentry[2]}/{$clientsn}"); + pfSense_ipfw_table_zerocnt("{$cpzone}_auth_down", "{$cpentry[2]}/{$clientsn}"); if ($cpcfg['reauthenticateacct'] == "stopstartfreeradius") { /* Need to pause here or the FreeRADIUS server gets confused about packet ordering. */ sleep(1); @@ -1020,7 +1017,11 @@ function captiveportal_disconnect($dbent, $radiusservers, $term_cause = 1, $stop } if (is_ipaddr($dbent[2])) { - /* Delete client's ip entry from tables auth_up and auth_down. */ + /* + * Delete client's ip entry from tables auth_up and auth_down. + * + * It's not necessary to explicit specify mac address here + */ $clientsn = (is_ipaddrv6($dbent[2])) ? 128 : 32; pfSense_ipfw_table("{$cpzone}_auth_up", IP_FW_TABLE_XDEL, "{$dbent[2]}/{$clientsn}"); pfSense_ipfw_table("{$cpzone}_auth_down", IP_FW_TABLE_XDEL, "{$dbent[2]}/{$clientsn}"); @@ -1382,19 +1383,21 @@ function captiveportal_allowedip_configure() { } /* get last activity timestamp given client IP address */ -function captiveportal_get_last_activity($ip, $mac = NULL, $table = 1) { - global $cpzoneid; +function captiveportal_get_last_activity($ip) { + global $cpzone; - /* XXX Fix */ - return 0; - $ipfwoutput = pfSense_ipfw_getTablestats($cpzoneid, IP_FW_TABLE_XLISTENTRY, $table, $ip, $mac); /* Reading only from one of the tables is enough of approximation. */ - if (is_array($ipfwoutput)) { - /* Workaround for #46652 */ - if ($ipfwoutput['packets'] > 0) { - return $ipfwoutput['timestamp']; - } else { - return 0; + $tables = array("{$cpzone}_allowed_up", "{$cpzone}_auth_up"); + + foreach ($tables as $table) { + $ipfw = pfSense_ipfw_table_lookup($table, $ip); + if (is_array($ipfw)) { + /* Workaround for #46652 */ + if ($ipfw['packets'] > 0) { + return $ipfw['timestamp']; + } else { + return 0; + } } } @@ -1871,35 +1874,42 @@ function captiveportal_get_dn_passthru_ruleno($value) { * */ -function getVolume($ip, $mac = NULL) { - global $config, $cpzone, $cpzoneid; +function getVolume($ip) { + global $config, $cpzone; - $reverse = isset($config['captiveportal'][$cpzone]['reverseacct']) ? true : false; + $reverse = isset($config['captiveportal'][$cpzone]['reverseacct']) + ? true : false; $volume = array(); // Initialize vars properly, since we don't want NULL vars - $volume['input_pkts'] = $volume['input_bytes'] = $volume['output_pkts'] = $volume['output_bytes'] = 0 ; + $volume['input_pkts'] = $volume['input_bytes'] = 0; + $volume['output_pkts'] = $volume['output_bytes'] = 0; - /* XXX Fix */ - return $volume; - $ipfw = pfSense_ipfw_getTablestats($cpzoneid, IP_FW_TABLE_XLISTENTRY, 1, $ip, $mac); - if (is_array($ipfw)) { + $tables = array("allowed", "auth"); + + foreach($tables as $table) { + $ipfw = pfSense_ipfw_table_lookup("{$cpzone}_{$table}_up", $ip); + if (!is_array($ipfw)) { + continue; + } if ($reverse) { $volume['output_pkts'] = $ipfw['packets']; $volume['output_bytes'] = $ipfw['bytes']; - } - else { + } else { $volume['input_pkts'] = $ipfw['packets']; $volume['input_bytes'] = $ipfw['bytes']; } } - $ipfw = pfSense_ipfw_getTablestats($cpzoneid, IP_FW_TABLE_XLISTENTRY, 2, $ip, $mac); - if (is_array($ipfw)) { + foreach($tables as $table) { + $ipfw = pfSense_ipfw_table_lookup("{$cpzone}_{$table}_down", + $ip); + if (!is_array($ipfw)) { + continue; + } if ($reverse) { $volume['input_pkts'] = $ipfw['packets']; $volume['input_bytes'] = $ipfw['bytes']; - } - else { + } else { $volume['output_pkts'] = $ipfw['packets']; $volume['output_bytes'] = $ipfw['bytes']; } @@ -2283,9 +2293,12 @@ function portal_allow($clientip, $clientmac, $username, $password = null, $attri $_gb = @pfSense_ipfw_pipe("pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100 buckets 16"); $_gb = @pfSense_ipfw_pipe("pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100 buckets 16"); - $clientsn = (is_ipaddrv6($clientip)) ? 128 : 32; - $_gb = @pfSense_ipfw_table("{$cpzone}_auth_up", IP_FW_TABLE_XADD, "{$clientip}/{$clientsn}", $bw_up_pipeno); - $_gb = @pfSense_ipfw_table("{$cpzone}_auth_down", IP_FW_TABLE_XADD, "{$clientip}/{$clientsn}", $bw_down_pipeno); + $rule_entry = "{$clientip}/" . (is_ipaddrv6($clientip) ? "128" : "32"); + if (!isset($config['captiveportal'][$cpzone]['nomacfilter'])) { + $rule_entry .= ",{$clientmac}"; + } + $_gb = @pfSense_ipfw_table("{$cpzone}_auth_up", IP_FW_TABLE_XADD, "{$rule_entry}", $bw_up_pipeno); + $_gb = @pfSense_ipfw_table("{$cpzone}_auth_down", IP_FW_TABLE_XADD, "{$rule_entry}", $bw_down_pipeno); if ($attributes['voucher']) { $attributes['session_timeout'] = $remaining_time; diff --git a/src/etc/inc/certs.inc b/src/etc/inc/certs.inc index b30a607..53bebeb 100644 --- a/src/etc/inc/certs.inc +++ b/src/etc/inc/certs.inc @@ -39,6 +39,15 @@ $openssl_crl_status = array( OCSP_REVOKED_STATUS_CERTIFICATEHOLD => "Certificate Hold" ); +global $cert_altname_types; +$cert_altname_types = array( + 'DNS' => gettext('FQDN or Hostname'), + 'IP' => gettext('IP address'), + 'URI' => gettext('URI'), + 'email' => gettext('email address'), +); + + function & lookup_ca($refid) { global $config; @@ -323,18 +332,7 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type = "user", $ $ca_serial = ++$ca['serial']; } - switch ($type) { - case "ca": - $cert_type = "v3_ca"; - break; - case "server": - case "self-signed": - $cert_type = "server"; - break; - default: - $cert_type = "usr_cert"; - break; - } + $cert_type = cert_type_config_section($type); // in case of using Subject Alternative Names use other sections (with postfix '_san') // pass subjectAltName over environment variable 'SAN' @@ -392,10 +390,21 @@ function cert_create(& $cert, $caref, $keylen, $lifetime, $dn, $type = "user", $ return true; } -function csr_generate(& $cert, $keylen, $dn, $digest_alg = "sha256") { +function csr_generate(& $cert, $keylen, $dn, $type = "user", $digest_alg = "sha256") { + + $cert_type = cert_type_config_section($type); + + // in case of using Subject Alternative Names use other sections (with postfix '_san') + // pass subjectAltName over environment variable 'SAN' + if ($dn['subjectAltName']) { + putenv("SAN={$dn['subjectAltName']}"); // subjectAltName can be set _only_ via configuration file + $cert_type .= '_san'; + unset($dn['subjectAltName']); + } $args = array( - "x509_extensions" => "v3_req", + "x509_extensions" => $cert_type, + "req_extensions" => "req_{$cert_type}", "digest_alg" => $digest_alg, "private_key_bits" => (int)$keylen, "private_key_type" => OPENSSL_KEYTYPE_RSA, @@ -426,6 +435,42 @@ function csr_generate(& $cert, $keylen, $dn, $digest_alg = "sha256") { return true; } +function csr_sign($csr, & $ca, $duration, $type = "user", $altnames, $digest_alg = "sha256") { + global $config; + $old_err_level = error_reporting(0); + + // Gather the information required for signed cert + $ca_str_crt = base64_decode($ca['crt']); + $ca_str_key = base64_decode($ca['prv']); + $ca_res_key = openssl_pkey_get_private(array(0 => $ca_str_key, 1 => "")); + if (!$ca_res_key) { + return false; + } + if (empty($ca['serial'])) { + $ca['serial'] = 0; + } + $ca_serial = ++$ca['serial']; + + $cert_type = cert_type_config_section($type); + + if (!empty($altnames)) { + putenv("SAN={$altnames}"); // subjectAltName can be set _only_ via configuration file + $cert_type .= '_san'; + } + + $args = array( + "x509_extensions" => $cert_type, + "digest_alg" => $digest_alg, + "req_extensions" => "req_{$cert_type}" + ); + + // Sign the new cert and export it in x509 format + openssl_x509_export(openssl_csr_sign($csr, $ca_str_crt, $ca_str_key, $duration, $args, $ca_serial), $n509); + error_reporting($old_err_level); + + return $n509; +} + function csr_complete(& $cert, $str_crt) { $str_key = base64_decode($cert['prv']); cert_import($cert, $str_crt, $str_key); @@ -638,6 +683,26 @@ function cert_get_serial($str_crt, $decode = true) { } } +function cert_get_sigtype($str_crt, $decode = true) { + if ($decode) { + $str_crt = base64_decode($str_crt); + } + $crt_details = openssl_x509_parse($str_crt); + + $signature = array(); + if (isset($crt_details['signatureTypeSN']) && !empty($crt_details['signatureTypeSN'])) { + $signature['shortname'] = $crt_details['signatureTypeSN']; + } + if (isset($crt_details['signatureTypeLN']) && !empty($crt_details['signatureTypeLN'])) { + $signature['longname'] = $crt_details['signatureTypeLN']; + } + if (isset($crt_details['signatureTypeNID']) && !empty($crt_details['signatureTypeNID'])) { + $signature['nid'] = $crt_details['signatureTypeNID']; + } + + return $signature; +} + function is_openvpn_server_ca($caref) { global $config; if (!is_array($config['openvpn']['openvpn-server'])) { @@ -1011,4 +1076,38 @@ function cert_escape_x509_chars($str, $reverse = false) { } } +function cert_add_altname_type($str) { + $type = ""; + if (is_ipaddr($str)) { + $type = "IP"; + } elseif (is_hostname($str)) { + $type = "DNS"; + } elseif (is_URL($str)) { + $type = "URI"; + } elseif (filter_var($str, FILTER_VALIDATE_EMAIL)) { + $type = "email"; + } + if (!empty($type)) { + return "{$type}:" . cert_escape_x509_chars($str); + } else { + return ""; + } +} + +function cert_type_config_section($type) { + switch ($type) { + case "ca": + $cert_type = "v3_ca"; + break; + case "server": + case "self-signed": + $cert_type = "server"; + break; + default: + $cert_type = "usr_cert"; + break; + } + return $cert_type; +} + ?> diff --git a/src/etc/inc/config.console.inc b/src/etc/inc/config.console.inc index fac977d..e4488bb 100644 --- a/src/etc/inc/config.console.inc +++ b/src/etc/inc/config.console.inc @@ -23,6 +23,11 @@ * limitations under the License. */ +require_once("config.inc"); +require_once("globals.inc"); +require_once("interfaces.inc"); +require_once("util.inc"); + function set_networking_interfaces_ports() { global $noreboot; global $config; diff --git a/src/etc/inc/config.lib.inc b/src/etc/inc/config.lib.inc index 0ee64b9..988c9b8 100644 --- a/src/etc/inc/config.lib.inc +++ b/src/etc/inc/config.lib.inc @@ -337,9 +337,6 @@ function convert_config() { } } } - if ($config['version'] == $g['latest_config']) { - return; /* already at latest version */ - } // Save off config version $prev_version = $config['version']; @@ -349,17 +346,37 @@ function convert_config() { if (file_exists("/etc/inc/upgrade_config_custom.inc")) { include_once("upgrade_config_custom.inc"); } + + if ($config['version'] == $g['latest_config']) { + additional_config_upgrade(); + return; /* already at latest version */ + } + + if (!is_array($config['system']['already_run_config_upgrade'])) { + $config['system']['already_run_config_upgrade'] = array(); + } + $already_run = $config['system']['already_run_config_upgrade']; + /* Loop and run upgrade_VER_to_VER() until we're at current version */ while ($config['version'] < $g['latest_config']) { $cur = $config['version'] * 10; $next = $cur + 1; - $migration_function = sprintf('upgrade_%03d_to_%03d', $cur, $next); - if (function_exists($migration_function)) { - $migration_function(); - } - $migration_function = "{$migration_function}_custom"; - if (function_exists($migration_function)) { - $migration_function(); + $migration_function = sprintf('upgrade_%03d_to_%03d', $cur, + $next); + + foreach (array("", "_custom") as $suffix) { + $migration_function .= $suffix; + if (!function_exists($migration_function)) { + continue; + } + if (isset($already_run[$migration_function])) { + /* Already executed, skip now */ + unset($config['system'] + ['already_run_config_upgrade'] + [$migration_function]); + } else { + $migration_function(); + } } $config['version'] = sprintf('%.1f', $next / 10); if (platform_booting()) { @@ -367,12 +384,14 @@ function convert_config() { } } - $now = date("H:i:s"); - log_error(sprintf(gettext("Ended Configuration upgrade at %s"), $now)); - if ($prev_version != $config['version']) { + $now = date("H:i:s"); + log_error(sprintf(gettext("Ended Configuration upgrade at %s"), $now)); + write_config(sprintf(gettext('Upgraded config version level from %1$s to %2$s'), $prev_version, $config['version'])); } + + additional_config_upgrade(); } /****f* config/safe_write_file diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index d940442..3470642 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -90,6 +90,18 @@ $icmptypes = array( 'wrureq' => array('descrip' => gettext('Who are you request'), 'valid4' => false, 'valid6' => true) ); +global $vlanprio_values; +$vlanprio_values = array( + "bk" => 0, + "be" => 1, + "ee" => 2, + "ca" => 3, + "vi" => 4, + "vo" => 5, + "ic" => 6, + "nc" => 7 +); + /* * Fixed tracker values (used to group and track usage in GUI): * @@ -559,10 +571,7 @@ function filter_generate_scrubing() { } /* set up MSS clamping */ if (($scrubcfg['mss'] <> "") && - (is_numeric($scrubcfg['mss'])) && - ($scrubcfg['if'] != "pppoe") && - ($scrubcfg['if'] != "pptp") && - ($scrubif['if'] != "l2tp")) { + (is_numeric($scrubcfg['mss']))) { $mssclamp = "max-mss " . (intval($scrubcfg['mss'] - 40)); } else { $mssclamp = ""; @@ -2249,10 +2258,6 @@ function filter_nat_rules_generate() { $srcaddr = trim($srcaddr); $dstaddr = trim($dstaddr); - if (!$dstaddr) { - $dstaddr = $FilterIflist[$natif]['ip']; - } - $dstaddr_port = explode(" ", $dstaddr); if (empty($dstaddr_port[0]) || strtolower(trim($dstaddr_port[0])) == "port") { continue; // Skip port forward if no destination address found @@ -2635,7 +2640,7 @@ function filter_generate_address(& $rule, $target = "source", $isnat = false) { function filter_generate_user_rule($rule) { global $config, $g, $FilterIflist, $GatewaysList; - global $dummynet_name_list; + global $dummynet_name_list, $vlanprio_values; if (isset($config['system']['developerspew'])) { $mt = microtime(); @@ -2881,10 +2886,10 @@ function filter_generate_user_rule($rule) { } } if (!empty($rule['vlanprio']) && ($rule['vlanprio'] != "none")) { - $aline['vlanprio'] = " ieee8021q-pcp " . $rule['vlanprio'] . " "; + $aline['vlanprio'] = " prio " . $vlanprio_values[$rule['vlanprio']] . " "; } if (!empty($rule['vlanprioset']) && ($rule['vlanprioset'] != "none")) { - $aline['vlanprioset'] = " ieee8021q-setpcp " . $rule['vlanprioset'] . " "; + $aline['vlanprioset'] = " set prio " . $vlanprio_values[$rule['vlanprioset']] . " "; } if ($type == "pass") { if (isset($rule['allowopts'])) { diff --git a/src/etc/inc/globals.inc b/src/etc/inc/globals.inc index c4533d8..1e2cbdf 100644 --- a/src/etc/inc/globals.inc +++ b/src/etc/inc/globals.inc @@ -71,7 +71,7 @@ $g = array( "disablecrashreporter" => false, "crashreporterurl" => "https://crashreporter.pfsense.org/crash_reporter.php", "debug" => false, - "latest_config" => "16.5", + "latest_config" => "17.0", "minimum_ram_warning" => "101", "minimum_ram_warning_text" => "128 MB", "wan_interface_name" => "wan", @@ -172,6 +172,10 @@ if (file_exists("/etc/inc/globals_override.inc")) { /* Read all XML files in following dir and load menu entries */ $g["ext_menu_path"] = "/usr/local/share/{$g['product_name']}/menu"; +/* Cache file used to store pfSense version */ +$g["version_cache_file"] = "{$g['varrun_path']}/{$g['product_name']}_version"; +$g['version_cache_refresh'] = 2 * 60 * 60; /* 2h */ + function platform_booting($on_console = false) { global $g; diff --git a/src/etc/inc/gwlb.inc b/src/etc/inc/gwlb.inc index 55f3135..9f8ca94 100644 --- a/src/etc/inc/gwlb.inc +++ b/src/etc/inc/gwlb.inc @@ -92,7 +92,7 @@ function start_dpinger($gateway) { global $g; if (!isset($gateway['gwifip'])) { - return; + return (false); } $dpinger_defaults = return_dpinger_defaults(); @@ -166,8 +166,12 @@ function start_dpinger($gateway) { /* Do not try to bind IPv6 where interface is in tentative state */ if (is_ipaddrv6($gateway['gwifip'])) { - interface_wait_tentative(get_real_interface( + $err = interface_wait_tentative(get_real_interface( $gateway['interface'])); + if ($err == false) { + log_error(gettext("Timeout waiting for IPv6 address in tentative state. dpinger will not run.")); + return (false); + } } /* Redirect stdout to /dev/null to avoid exec() to wait for dpinger */ @@ -1754,14 +1758,16 @@ function save_gateway($gateway_settings, $realid = "") { 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']; + if (is_array($a_gateway_item)) { + 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++; } - $i++; } $gateway['defaultgw'] = true; } diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 5b375ec..e711f91 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -560,6 +560,8 @@ function interface_bridge_configure(&$bridge, $checkmember = 0) { interface_bridge_configure_advanced($bridge); + interface_bridge_configure_ip6linklocal($bridge); + if ($bridge['bridgeif']) { interfaces_bring_up($bridge['bridgeif']); } else { @@ -686,6 +688,25 @@ function interface_bridge_configure_advanced($bridge) { } } +function interface_bridge_configure_ip6linklocal($bridge) { + $bridgeif = $bridge['bridgeif']; + + $members = explode(',', $bridge['members']); + if (!count($members)) { + return; + } + + $auto_linklocal = isset($bridge['ip6linklocal']); + $bridgeop = $auto_linklocal ? '' : '-'; + $memberop = $auto_linklocal ? '-' : ''; + + mwexec("/usr/sbin/ndp -i {$bridgeif} -- {$bridgeop}auto_linklocal"); + foreach ($members as $member) { + $realif = get_real_interface($member); + mwexec("/usr/sbin/ndp -i {$realif} -- {$memberop}auto_linklocal"); + } +} + function interface_bridge_add_member($bridgeif, $interface, $flagsapplied = false) { global $config; @@ -3494,6 +3515,9 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven // N.B. PPP connections using PPP as the IPv6 parent interface are excluded because the ppp-ipv6 script // calls interface_dhcpv6_configure() for these connections after IPv6CP is up, whilst rc.newwanip // handles all non-PPP connections with 'dhcp6usev4iface' set + /* Remove the check file. Should not be there but just in case */ + unlink_if_exists("/tmp/{$wanif}_dhcp6_complete"); + log_error(gettext("calling interface_dhcpv6_configure.")); if (!(isset($wancfg['dhcp6usev4iface']) || $wancfg['ipaddr']==='ppp')) { interface_dhcpv6_configure($interface, $wancfg); } @@ -3849,9 +3873,6 @@ function interface_6rd_configure($interface = "wan", $wancfg) { /* XXX: need to extend to support variable prefix size for v4 */ - if (!is_module_loaded("if_stf")) { - mwexec("/sbin/kldload if_stf.ko"); - } $stfiface = "{$interface}_stf"; if (does_interface_exist($stfiface)) { pfSense_interface_destroy($stfiface); @@ -3859,7 +3880,7 @@ function interface_6rd_configure($interface = "wan", $wancfg) { $tmpstfiface = pfSense_interface_create("stf"); pfSense_interface_rename($tmpstfiface, $stfiface); pfSense_interface_flags($stfiface, IFF_LINK2); - mwexec("/sbin/ifconfig {$stfiface} inet6 {$rd6prefix}/{$rd6prefixlen}"); + mwexec("/sbin/ifconfig {$stfiface} inet6 no_dad {$rd6prefix}/{$rd6prefixlen}"); mwexec("/sbin/ifconfig {$stfiface} stfv4br " . escapeshellarg($wancfg['gateway-6rd'])); if ($wancfg['prefix-6rd-v4plen'] >= 0 && $wancfg['prefix-6rd-v4plen'] <= 32) { mwexec("/sbin/ifconfig {$stfiface} stfv4net {$ip4address}/" . escapeshellarg($wancfg['prefix-6rd-v4plen'])); @@ -4407,10 +4428,11 @@ function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif) { } $id_assoc_statement_prefix .= ";"; } - + + $realif = get_real_interface($wancfg['adv_dhcp6_prefix_selected_interface']); if (is_numeric($wancfg['adv_dhcp6_prefix_interface_statement_sla_id'])) { $id_assoc_statement_prefix .= "\n\tprefix-interface"; - $id_assoc_statement_prefix .= " {$wanif}"; + $id_assoc_statement_prefix .= " {$realif}"; $id_assoc_statement_prefix .= " {\n"; $id_assoc_statement_prefix .= "\t\tsla-id {$wancfg['adv_dhcp6_prefix_interface_statement_sla_id']};\n"; if (($wancfg['adv_dhcp6_prefix_interface_statement_sla_len'] >= 0) && @@ -5132,7 +5154,8 @@ function get_real_interface($interface = "wan", $family = "all", $realv6iface = case 'ppp': case 'l2tp': case 'pptp': - if (isset($cfg['dhcp6usev4iface']) && $realv6iface === false) { + // Added catch for static v6 but using v4 link. Sets things to use pppoe link + if ((isset($cfg['dhcp6usev4iface']) && $realv6iface === false) || isset($cfg['ipv6usev4iface'])) { $wanif = $cfg['if']; } else { $parents = get_parent_interface($interface); @@ -5980,7 +6003,7 @@ function interface_has_gatewayv6($friendly) { function is_altq_capable($int) { /* Per: - * http://www.freebsd.org/cgi/man.cgi?query=altq&apropos=0&sektion=0&manpath=FreeBSD+8.3-RELEASE&arch=default&format=html + * http://www.freebsd.org/cgi/man.cgi?query=altq&apropos=0&sektion=0&manpath=FreeBSD+11.0-RELEASE&arch=default&format=html * Only the following drivers have ALTQ support * 20150328 - removed wireless drivers - ath, awi, bwn, iwi, ipw, ral, rum, run, wi - for now. redmine #4406 */ diff --git a/src/etc/inc/openvpn.inc b/src/etc/inc/openvpn.inc index cce84bd..88faa5b 100644 --- a/src/etc/inc/openvpn.inc +++ b/src/etc/inc/openvpn.inc @@ -124,7 +124,7 @@ global $openvpn_compression_modes; $openvpn_compression_modes = array( '' => gettext("Omit Preference (Use OpenVPN Default)"), 'lz4' => gettext("LZ4 Compression [compress lz4]"), - 'lz4-v2' => gettext("LZ4 Comression v2 [compress lz4-v2]"), + 'lz4-v2' => gettext("LZ4 Compression v2 [compress lz4-v2]"), 'lzo' => gettext("LZO Compression [compress lzo, equivalent to comp-lzo yes for compatibility]"), 'stub' => gettext("Enable Compression (stub) [compress]"), 'noadapt' => gettext("Omit Preference, + Disable Adaptive LZO Compression [Legacy style, comp-noadapt]"), @@ -433,20 +433,55 @@ function openvpn_validate_curve($curve) { return array_key_exists($curve, $curves); } -function openvpn_get_digestlist() { +/* Obtain the list of digest algorithms supported by openssl and their alternate names */ +function openvpn_get_openssldigestmappings() { + $digests = array(); + $digest_out = shell_exec('/usr/bin/openssl list-message-digest-algorithms | /usr/bin/grep "=>"'); + $digest_lines = explode("\n", trim($digest_out)); + sort($digest_lines); + foreach ($digest_lines as $line) { + $words = explode(' => ', $line, 2); + $digests[$words[0]] = $words[1]; + } + return $digests; +} +/* Obtain the list of digest algorithms supported by openvpn */ +function openvpn_get_digestlist() { + /* Grab the list from OpenSSL to check for duplicates or aliases */ + $openssl_digest_mappings = openvpn_get_openssldigestmappings(); $digests = array(); $digest_out = shell_exec('/usr/local/sbin/openvpn --show-digests | /usr/bin/grep "digest size" | /usr/bin/awk \'{print $1, "(" $2 "-" $3 ")";}\''); $digest_lines = explode("\n", trim($digest_out)); sort($digest_lines); foreach ($digest_lines as $line) { $words = explode(' ', $line); - $digests[$words[0]] = "{$words[0]} {$words[1]}"; + /* Only add the entry if it is NOT also listed as being an alias/mapping by OpenSSL */ + if (!array_key_exists($words[0], $openssl_digest_mappings)) { + $digests[$words[0]] = "{$words[0]} {$words[1]}"; + } } $digests["none"] = gettext("None (No Authentication)"); return $digests; } +/* Check to see if a digest name is an alias and if so, find the actual digest + * algorithm instead. Useful for upgrade code that has to translate aliased + * algorithms to their actual names. + */ +function openvpn_remap_digest($digest) { + $openssl_digest_mappings = openvpn_get_openssldigestmappings(); + if (array_key_exists($digest, $openssl_digest_mappings)) { + /* Some mappings point to other mappings, keep going until we find the actual digest algorithm */ + if (array_key_exists($openssl_digest_mappings[$digest], $openssl_digest_mappings)) { + return openvpn_remap_digest($openssl_digest_mappings[$digest]); + } else { + return $openssl_digest_mappings[$digest]; + } + } + return $digest; +} + function openvpn_get_engines() { $openssl_engines = array('none' => gettext('No Hardware Crypto Acceleration')); exec("/usr/bin/openssl engine -t -c", $openssl_engine_output); diff --git a/src/etc/inc/pfsense-utils.inc b/src/etc/inc/pfsense-utils.inc index 04cbf60..ebf75c8 100644 --- a/src/etc/inc/pfsense-utils.inc +++ b/src/etc/inc/pfsense-utils.inc @@ -180,12 +180,14 @@ function get_css_files() { $usrcss = $pfscss = $betacss = array(); foreach ($cssfiles as $css) { - if (strpos($css, "BETA") != 0) { - array_push($betacss, $css); - } else if (strpos($css, "pfSense") != 0) { - array_push($pfscss, $css); - } else { - array_push($usrcss, $css); + if (strpos($css, "login") == 0) { // Don't display any login page related CSS files + if (strpos($css, "BETA") != 0) { + array_push($betacss, $css); + } else if (strpos($css, "pfSense") != 0) { + array_push($pfscss, $css); + } else { + array_push($usrcss, $css); + } } } @@ -723,7 +725,7 @@ function get_carp_interface_status($carpid) { $vhid = $vip['vhid']; $carp_query = ''; - $_gb = exec("/sbin/ifconfig $interface | /usr/bin/grep carp: | /usr/bin/grep \"vhid $vhid\"", $carp_query); + $_gb = exec("/sbin/ifconfig {$interface} | /usr/bin/grep \"carp:.* vhid {$vhid} \"", $carp_query); foreach ($carp_query as $int) { if (stripos($int, "MASTER")) return "MASTER"; @@ -1945,8 +1947,8 @@ function download_file($url, $destination, $verify_ssl = true, $connect_timeout curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - if (!isset($config['system']['do_not_send_host_uuid'])) { - curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version'] . ' : ' . get_single_sysctl('kern.hostuuid')); + if (!isset($config['system']['do_not_send_uniqueid'])) { + curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version'] . ':' . system_get_uniqueid()); } else { curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version']); } @@ -2001,8 +2003,8 @@ function download_file_with_progress_bar($url, $destination, $verify_ssl = true, curl_setopt($ch, CURLOPT_NOPROGRESS, '1'); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); - if (!isset($config['system']['do_not_send_host_uuid'])) { - curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version'] . ' : ' . get_single_sysctl('kern.hostuuid')); + if (!isset($config['system']['do_not_send_uniqueid'])) { + curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version'] . ':' . system_get_uniqueid()); } else { curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . $g['product_version']); } @@ -2936,14 +2938,18 @@ function set_language() { function get_locale_list() { $locales = array( "bs" => gettext("Bosnian"), - "de_DE" => gettext("German (Germany)"), + "zh_Hans_CN" => gettext("Chinese (Simplified, China)"), + "zh_TW" => gettext("Chinese (Taiwan)"), + "nl" => gettext("Dutch"), "en_US" => gettext("English"), - "es" => gettext("Spanish"), - "es_AR" => gettext("Spanish (Argentina)"), + "fr" => gettext("French"), + "de_DE" => gettext("German (Germany)"), "nb" => gettext("Norwegian BokmÃ¥l"), + "pl" => gettext("Polish"), + "pt_BR" => gettext("Portuguese (Brazil)"), "ru" => gettext("Russian"), - "zh_Hans_CN" => gettext("Chinese (Simplified, China)"), - "zh_TW" => gettext("Chinese (Taiwan)"), + "es" => gettext("Spanish"), + "es_AR" => gettext("Spanish (Argentina)"), ); // If the locales are sorted, the order changes depending on the language selected. If the user accidentally diff --git a/src/etc/inc/pkg-utils.inc b/src/etc/inc/pkg-utils.inc index a7e51f5..6c6d12b 100644 --- a/src/etc/inc/pkg-utils.inc +++ b/src/etc/inc/pkg-utils.inc @@ -77,6 +77,11 @@ function pkg_update($force = false) { function pkg_env($extra_env = array()) { global $config, $g; + $user_agent = $g['product_name'] . '/' . $g['product_version']; + if (!isset($config['system']['do_not_send_uniqueid'])) { + $user_agent .= ':' . system_get_uniqueid(); + } + $pkg_env_vars = array( "LANG" => "C", "HTTP_USER_AGENT" => $user_agent, @@ -117,11 +122,6 @@ function pkg_call($params, $mute = false, $extra_env = array()) { return false; } - $user_agent = $g['product_name'] . '/' . $g['product_version']; - if (!isset($config['system']['do_not_send_host_uuid'])) { - $user_agent .= ' : ' . get_single_sysctl('kern.hostuuid'); - } - $descriptorspec = array( 1 => array("pipe", "w"), /* stdout */ 2 => array("pipe", "w") /* stderr */ @@ -199,11 +199,6 @@ function pkg_exec($params, &$stdout, &$stderr, $extra_env = array()) { return -1; } - $user_agent = $g['product_name'] . '/' . $g['product_version']; - if (!isset($config['system']['do_not_send_host_uuid'])) { - $user_agent .= ' : ' . get_single_sysctl('kern.hostuuid'); - } - $descriptorspec = array( 1 => array("pipe", "w"), /* stdout */ 2 => array("pipe", "w") /* stderr */ @@ -1175,14 +1170,34 @@ function get_base_pkg_name() { } /* Verify if system needs upgrade (meta package or base) */ -function get_system_pkg_version($baseonly = false) { +function get_system_pkg_version($baseonly = false, $use_cache = true) { global $g; - $output = exec("/usr/local/sbin/{$g['product_name']}-upgrade -c", $_gc, - $rc); + $cache_file = $g['version_cache_file']; + $rc_file = $cache_file . '.rc'; + + $rc = ""; + if ($use_cache && file_exists($rc_file) && + (time()-filemtime($rc_file) < $g['version_cache_refresh'])) { + $rc = chop(@file_get_contents($rc_file)); + } + + if ($rc == "2") { + $output = @file_get_contents($cache_file); + } else if ($rc != "0") { + $output = exec( + "/usr/local/sbin/{$g['product_name']}-upgrade -c", $_gc, + $rc); + + /* Update cache if it succeeded */ + if ($rc == 0 || $rc == 2) { + @file_put_contents($cache_file, $output); + @file_put_contents($rc_file, $rc); + } + } /* pfSense-upgrade returns 2 when there is a new version */ - if ($rc == 2) { + if ($rc == "2") { $new_version = explode(' ', $output)[0]; } @@ -1193,7 +1208,7 @@ function get_system_pkg_version($baseonly = false) { return false; } - $info = get_pkg_info($base_pkg, true); + $info = get_pkg_info($base_pkg, true, true); $pkg_info = array(); foreach ($info as $item) { @@ -1205,7 +1220,7 @@ function get_system_pkg_version($baseonly = false) { if (empty($pkg_info) || (!$baseonly && ($pkg_info['version'] == $pkg_info['installed_version']))) { - $info = get_pkg_info($meta_pkg, true); + $info = get_pkg_info($meta_pkg, true, true); foreach ($info as $item) { if ($item['name'] == $meta_pkg) { @@ -1287,7 +1302,9 @@ function pkg_switch_repo($path) { file_put_contents("/usr/local/etc/pkg.conf", $pkg_conf); } - return pkg_update(true); + /* Update pfSense_version cache */ + mwexec_bg("/etc/rc.update_pkg_metadata now"); + return; } ?> diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index f7aadd8..79a12db 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -610,6 +610,7 @@ EOD; $type = "secondary"; $my_port = "520"; $peer_port = "519"; + $dhcpdconf_pri = ''; } else { $my_port = "519"; $peer_port = "520"; @@ -1522,6 +1523,10 @@ EOD; $dhhostname = str_replace(" ", "_", $sm['hostname']); $dhhostname = str_replace(".", "_", $dhhostname); $dhcpdv6conf .= " option host-name {$dhhostname};\n"; + if (isset($dhcpv6ifconf['ddnsupdate']) && + isset($dhcpv6ifconf['ddnsforcehostname'])) { + $dhcpdv6conf .= " ddns-hostname \"{$dhhostname}\";\n"; + } } if ($sm['filename']) { $dhcpdv6conf .= " filename \"{$sm['filename']}\";\n"; @@ -2234,12 +2239,21 @@ function services_unbound_configure($restart_dhcp = true) { echo "services_unbound_configure() being called $mt\n"; } - // kill any running Unbound instance - if (file_exists("{$g['varrun_path']}/unbound.pid")) { - sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM"); - } - if (isset($config['unbound']['enable'])) { + require_once('/etc/inc/unbound.inc'); + + /* Stop Unbound using TERM */ + if (file_exists("{$g['varrun_path']}/unbound.pid")) { + sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM"); + } + + /* If unbound is still running, wait up to 30 seconds for it to terminate. */ + for ($i=1; $i <= 30; $i++) { + if (is_process_running('unbound')) { + sleep(1); + } + } + if (platform_booting()) { echo gettext("Starting DNS Resolver..."); } else { @@ -2251,13 +2265,35 @@ function services_unbound_configure($restart_dhcp = true) { $return = 1; } - require_once('/etc/inc/unbound.inc'); + /* Check here for dhcp6 complete - wait upto 10 seconds */ + if($config['interfaces']["wan"]['ipaddrv6'] == 'dhcp6') { + $wanif = get_real_interface("wan", "inet6"); + if (platform_booting()) { + for ($i=1; $i <= 10; $i++) { + if (!file_exists("/tmp/{$wanif}_dhcp6_complete")) { + log_error(gettext("Unbound start waiting on dhcp6c.")); + sleep(1); + } else { + unlink_if_exists("/tmp/{$wanif}_dhcp6_complete"); + log_error(gettext("dhcp6 init complete. Continuing")); + break; + } + } + } + } + sync_unbound_service(); if (platform_booting()) { + log_error(gettext("sync unbound done.")); echo gettext("done.") . "\n"; } system_dhcpleases_configure(); + } else { + /* kill Unbound since it should not be enabled */ + if (file_exists("{$g['varrun_path']}/unbound.pid")) { + sigkillbypid("{$g['varrun_path']}/unbound.pid", "KILL"); + } } if (!platform_booting() && $restart_dhcp) { @@ -2868,7 +2904,7 @@ function install_cron_job($command, $active = false, $minute = "0", $hour = "*", } } else { if ($is_installed == true) { - unset($config['cron']['item'][$x]); + array_splice($config['cron']['item'], $x, 1); $change_message = "Removed cron job for %s"; } else { $cron_changed = false; diff --git a/src/etc/inc/shaper.inc b/src/etc/inc/shaper.inc index 01fddc5..cc4005f 100644 --- a/src/etc/inc/shaper.inc +++ b/src/etc/inc/shaper.inc @@ -1214,8 +1214,9 @@ class priq_queue { } if ($this->CheckBandwidth($data['bandwidth'], $data['bandwidthtype'])) $input_errors[] = "The sum of child bandwidth is higher than parent."; - if ($data['priority'] && (!is_numeric($data['priority']) || - ($data['priority'] < 1) || ($data['priority'] > 15))) { + + if (isset($data['priority']) && (!is_numeric($data['priority']) || + ($data['priority'] < 0) || ($data['priority'] > 15))) { $input_errors[] = gettext("The priority must be an integer between 1 and 15."); } if ($data['qlimit'] && (!is_numeric($data['qlimit']))) { @@ -1256,7 +1257,7 @@ class priq_queue { } else { $this->SetQlimit(""); // Default } - if (!empty($q['priority'])) { + if (is_numeric($q['priority'])) { $this->SetQPriority($q['priority']); } else { $this->SetQpriority(""); @@ -1331,7 +1332,7 @@ class priq_queue { $pfq_rule .= " on ".get_real_interface($this->GetInterface()); } $tmpvalue = $this->GetQpriority(); - if (!empty($tmpvalue)) { + if (is_numeric($tmpvalue)) { $pfq_rule .= " priority ".$this->GetQpriority(); } $tmpvalue = $this->GetQlimit(); @@ -1423,13 +1424,15 @@ class priq_queue { $this->GetQname() )); - $section->addInput(new Form_Input( - 'priority', - 'Priority', - 'number', - $this->GetQpriority(), - ['min' => '0', 'max'=> '7'] - ))->setHelp('For hfsc, the range is 0 to 7. The default is 1. Hfsc queues with a higher priority are preferred in the case of overload.'); + if (!is_a($this, "hfsc_queue")) { + $section->addInput(new Form_Input( + 'priority', + 'Priority', + 'number', + $this->GetQpriority(), + ['min' => '0', 'max'=> ''] + ))->setHelp('For cbq and fairq the range is 0 to 7. The default is 1. For priq the range is 0 to 15, queues with a higher priority are preferred in the case of overload.'); + } $section->addInput(new Form_Input( 'qlimit', @@ -1589,7 +1592,7 @@ class priq_queue { unset($cflink['qlimit']); } $cflink['priority'] = trim($this->GetQpriority()); - if (empty($cflink['priority'])) { + if (!is_numeric($cflink['priority'])) { unset($cflink['priority']); } $cflink['description'] = trim($this->GetDescription()); @@ -2410,7 +2413,7 @@ EOJS; unset($cflink['qlimit']); } $cflink['priority'] = $this->GetQpriority(); - if (empty($cflink['priority'])) { + if (!is_numericint($cflink['priority'])) { unset($cflink['priority']); } $cflink['description'] = $this->GetDescription(); @@ -2562,7 +2565,7 @@ class cbq_queue extends priq_queue { unset($cflink['qlimit']); } $cflink['priority'] = trim($this->GetQpriority()); - if (empty($cflink['priority'])) { + if (!is_numeric($cflink['priority'])) { unset($cflink['priority']); } $cflink['name'] = $this->GetQname(); @@ -2644,7 +2647,7 @@ class cbq_queue extends priq_queue { parent::validate_input($data, $input_errors); if ($data['priority'] > 7) { - $input_errors[] = gettext("Priority must be an integer between 1 and 7."); + $input_errors[] = gettext("Priority must be an integer between 0 and 7."); } $reqdfields[] = "bandwidth"; $reqdfieldsn[] = gettext("Bandwidth"); @@ -2696,7 +2699,7 @@ class cbq_queue extends priq_queue { $pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale(); } $tmpvalue = $this->GetQpriority(); - if (!empty($tmpvalue)) { + if (is_numeric($tmpvalue)) { $pfq_rule .= " priority " . $this->GetQpriority(); } $tmpvalue = trim($this->GetQlimit()); @@ -2826,7 +2829,7 @@ class cbq_queue extends priq_queue { unset($cflink['qlimit']); } $cflink['priority'] = $this->GetQpriority(); - if (empty($cflink['priority'])) { + if (!is_numeric($cflink['priority'])) { unset($cflink['priority']); } $cflink['name'] = $this->GetQname(); @@ -2925,8 +2928,8 @@ class fairq_queue extends priq_queue { function validate_input($data, &$input_errors) { parent::validate_input($data, $input_errors); - if ($data['priority'] > 255) { - $input_errors[] = gettext("Priority must be an integer between 1 and 255."); + if ($data['priority'] > 7) { + $input_errors[] = gettext("Priority must be an integer between 0 and 7."); } $reqdfields[] = "bandwidth"; $reqdfieldsn[] = gettext("Bandwidth"); @@ -2977,7 +2980,7 @@ class fairq_queue extends priq_queue { $pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale(); } $tmpvalue = trim($this->GetQpriority()); - if (!empty($tmpvalue)) { + if (is_numeric($tmpvalue)) { $pfq_rule .= " priority " . $this->GetQpriority(); } $tmpvalue = trim($this->GetQlimit()); @@ -3105,7 +3108,7 @@ class fairq_queue extends priq_queue { unset($cflink['qlimit']); } $cflink['priority'] = trim($this->GetQpriority()); - if (empty($cflink['priority'])) { + if (!is_numeric($cflink['priority'])) { unset($cflink['priority']); } $cflink['name'] = $this->GetQname(); diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index c7c6be2..295641d 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -298,13 +298,15 @@ function system_hosts_local_entries() { $hosts = array(); $hosts[] = array( 'ipaddr' => '127.0.0.1', - 'fqdn' => 'localhost', - 'name' => 'localhost.' . $syscfg['domain'] + 'fqdn' => 'localhost.' . $syscfg['domain'], + 'name' => 'localhost', + 'domain' => $syscfg['domain'] ); $hosts[] = array( 'ipaddr' => '::1', - 'fqdn' => 'localhost', - 'name' => 'localhost.' . $syscfg['domain'] + 'fqdn' => 'localhost.' . $syscfg['domain'], + 'name' => 'localhost', + 'domain' => $syscfg['domain'] ); if ($config['interfaces']['lan']) { @@ -323,7 +325,9 @@ function system_hosts_local_entries() { if (is_ipaddrv4($cfgip)) { $hosts[] = array( 'ipaddr' => $cfgip, - 'fqdn' => $local_fqdn + 'fqdn' => $local_fqdn, + 'name' => $syscfg['hostname'], + 'domain' => $syscfg['domain'] ); $hosts_if_found = true; } @@ -332,7 +336,9 @@ function system_hosts_local_entries() { if (is_ipaddrv6($cfgipv6)) { $hosts[] = array( 'ipaddr' => $cfgipv6, - 'fqdn' => $local_fqdn + 'fqdn' => $local_fqdn, + 'name' => $syscfg['hostname'], + 'domain' => $syscfg['domain'] ); $hosts_if_found = true; } @@ -364,7 +370,9 @@ function system_hosts_override_entries($dnscfg) { $hosts[] = array( 'ipaddr' => $host['ip'], - 'fqdn' => $fqdn + 'fqdn' => $fqdn, + 'name' => $host['host'], + 'domain' => $host['domain'] ); if (!is_array($host['aliases']) || @@ -381,7 +389,9 @@ function system_hosts_override_entries($dnscfg) { $hosts[] = array( 'ipaddr' => $host['ip'], - 'fqdn' => $fqdn + 'fqdn' => $fqdn, + 'name' => $alias['host'], + 'domain' => $alias['domain'] ); } } @@ -414,17 +424,20 @@ function system_hosts_dhcpd_entries() { } $fqdn = $host['hostname'] . "."; + $domain = ""; if ($host['domain']) { - $fqdn .= $host['domain']; + $domain = $host['domain']; } elseif ($dhcpifconf['domain']) { - $fqdn .= $dhcpifconf['domain']; + $domain = $dhcpifconf['domain']; } else { - $fqdn .= $syscfg['domain']; + $domain = $syscfg['domain']; } $hosts[] = array( 'ipaddr' => $host['ipaddr'], - 'fqdn' => $fqdn + 'fqdn' => $fqdn . $domain, + 'name' => $host['hostname'], + 'domain' => $domain ); } } @@ -468,17 +481,20 @@ function system_hosts_dhcpd_entries() { } $fqdn = $host['hostname'] . "."; + $domain = ""; if ($host['domain']) { - $fqdn .= $host['domain']; - } else if ($dhcpifconf['domain']) { - $fqdn .= $dhcpifconf['domain']; + $domain = $host['domain']; + } elseif ($dhcpifconf['domain']) { + $domain = $dhcpifconf['domain']; } else { - $fqdn .= $syscfg['domain']; + $domain = $syscfg['domain']; } $hosts[] = array( 'ipaddr' => $ipaddrv6, - 'fqdn' => $fqdn + 'fqdn' => $fqdn . $domain, + 'name' => $host['hostname'], + 'domain' => $domain ); } } @@ -532,9 +548,11 @@ function system_hosts_generate() { $hosts_array = system_hosts_entries($dnsmasqcfg); foreach ($hosts_array as $host) { - $hosts .= "{$host['ipaddr']}\t{$host['fqdn']}"; - if (!empty($host['name'])) { - $hosts .= " {$host['name']}"; + $hosts .= "{$host['ipaddr']}\t"; + if ($host['name'] == "localhost") { + $hosts .= "{$host['name']} {$host['fqdn']}"; + } else { + $hosts .= "{$host['fqdn']} {$host['name']}"; } $hosts .= "\n"; } @@ -2345,6 +2363,24 @@ function system_get_serial() { return get_single_sysctl('kern.hostuuid'); } +function system_get_uniqueid() { + global $g; + + $uniqueid_file="{$g['vardb_path']}/uniqueid"; + + if (empty($g['uniqueid'])) { + if (!file_exists($uniqueid_file)) { + mwexec("/usr/sbin/gnid > {$g['vardb_path']}/uniqueid " . + "2>/dev/null"); + } + if (file_exists($uniqueid_file)) { + $g['uniqueid'] = @file_get_contents($uniqueid_file); + } + } + + return ($g['uniqueid'] ?: ''); +} + /* * attempt to identify the specific platform (for embedded systems) * Returns an array with two elements: diff --git a/src/etc/inc/unbound.inc b/src/etc/inc/unbound.inc index 428a523..d9a745c 100644 --- a/src/etc/inc/unbound.inc +++ b/src/etc/inc/unbound.inc @@ -465,10 +465,10 @@ function do_as_unbound_user($cmd, $param1 = "") { mwexec("/usr/local/sbin/unbound -c {$g['unbound_chroot_path']}/unbound.conf"); break; case "stop": - mwexec("echo '/usr/local/sbin/unbound-control stop' | /usr/bin/su -m unbound", true); + mwexec("echo '/usr/local/sbin/unbound-control -c {$g['unbound_chroot_path']}/unbound.conf stop' | /usr/bin/su -m unbound", true); break; case "reload": - mwexec("echo '/usr/local/sbin/unbound-control reload' | /usr/bin/su -m unbound", true); + mwexec("echo '/usr/local/sbin/unbound-control -c {$g['unbound_chroot_path']}/unbound.conf reload' | /usr/bin/su -m unbound", true); break; case "unbound-anchor": $root_key_file = "{$g['unbound_chroot_path']}{$param1}/root.key"; @@ -536,23 +536,13 @@ function unbound_add_domain_overrides($pvt_rev="", $cfgsubdir = "") { } } -function unbound_add_host_entries($cfgsubdir = "") { - global $config, $g; - - // Check if auto add host entries is not set - if (!isset($config['unbound']['disable_auto_added_host_entries'])) { - // Make sure the config setting is a valid unbound local zone type. If not use "transparent". - if (array_key_exists($config['unbound']['system_domain_local_zone_type'], unbound_local_zone_types())) { - $system_domain_local_zone_type = $config['unbound']['system_domain_local_zone_type']; - } else { - $system_domain_local_zone_type = "transparent"; - } - - $unbound_entries = "local-zone: \"{$config['system']['domain']}\" {$system_domain_local_zone_type}\n"; +function unbound_generate_zone_data($domain, $hosts, &$added_ptr, $zone_type = "transparent", $write_domain_zone_declaration = false, $always_add_short_names = false) { + global $config; + if ($write_domain_zone_declaration) { + $zone_data = "local-zone: \"{$domain}.\" {$zone_type}\n"; + } else { + $zone_data = ""; } - - $hosts = system_hosts_entries($config['unbound']); - $added_ptr = array(); foreach ($hosts as $host) { if (is_ipaddrv4($host['ipaddr'])) { $type = 'A'; @@ -561,12 +551,69 @@ function unbound_add_host_entries($cfgsubdir = "") { } else { continue; } - if (!$added_ptr[$host['ipaddr']]) { - $unbound_entries .= "local-data-ptr: \"{$host['ipaddr']} {$host['fqdn']}\"\n"; + $zone_data .= "local-data-ptr: \"{$host['ipaddr']} {$host['fqdn']}\"\n"; $added_ptr[$host['ipaddr']] = true; } - $unbound_entries .= "local-data: \"{$host['fqdn']} {$type} {$host['ipaddr']}\"\n"; + /* For the system localhost entry, write an entry for just the hostname. */ + if ((($host['name'] == "localhost") && ($domain == $config['system']['domain'])) || $always_add_short_names) { + $zone_data .= "local-data: \"{$host['name']}. {$type} {$host['ipaddr']}\"\n"; + } + /* Redirect zones must have a zone declaration that matches the + * local-data record exactly, it cannot have entries "under" the + * domain. + */ + if ($zone_type == "redirect") { + $zone_data .= "local-zone: \"{$host['fqdn']}.\" {$zone_type}\n";; + } + $zone_data .= "local-data: \"{$host['fqdn']}. {$type} {$host['ipaddr']}\"\n"; + } + return $zone_data; +} + +function unbound_add_host_entries($cfgsubdir = "") { + global $config, $g; + + $hosts = system_hosts_entries($config['unbound']); + + /* Pass 1: Build domain list and hosts inside domains */ + $hosts_by_domain = array(); + foreach ($hosts as $host) { + if (!array_key_exists($host['domain'], $hosts_by_domain)) { + $hosts_by_domain[$host['domain']] = array(); + } + $hosts_by_domain[$host['domain']][] = $host; + } + + $added_ptr = array(); + /* Build local zone data */ + // Check if auto add host entries is not set + $system_domain_local_zone_type = "transparent"; + if (!isset($config['unbound']['disable_auto_added_host_entries'])) { + // Make sure the config setting is a valid unbound local zone type. If not use "transparent". + if (array_key_exists($config['unbound']['system_domain_local_zone_type'], unbound_local_zone_types())) { + $system_domain_local_zone_type = $config['unbound']['system_domain_local_zone_type']; + } + } + /* Add entries for the system domain before all others */ + if (array_key_exists($config['system']['domain'], $hosts_by_domain)) { + $unbound_entries .= unbound_generate_zone_data($config['system']['domain'], + $hosts_by_domain[$config['system']['domain']], + $added_ptr, + $system_domain_local_zone_type, + true); + /* Unset this so it isn't processed again by the loop below. */ + unset($hosts_by_domain[$config['system']['domain']]); + } + + /* Build zone data for other domain */ + foreach ($hosts_by_domain as $domain => $hosts) { + $unbound_entries .= unbound_generate_zone_data($domain, + $hosts, + $added_ptr, + "transparent", + false, + isset($config['unbound']['always_add_short_names'])); } // Write out entries diff --git a/src/etc/inc/upgrade_config.inc b/src/etc/inc/upgrade_config.inc index 512d7de..dc69685 100644 --- a/src/etc/inc/upgrade_config.inc +++ b/src/etc/inc/upgrade_config.inc @@ -4746,7 +4746,7 @@ function upgrade_147_to_148() { } // if there was a space in a group name, there may be multiple - // groups with the same name in the group file. To prevent pw + // groups with the same name in the group file. To prevent pw // from getting into a neverending loop, delete all user-defined // groups here. local_sync_accounts will run shortly after this // and add them back. redmine #6012 @@ -5091,7 +5091,7 @@ function upgrade_160_to_161() { } else { foreach ($rrdrestore as $xml_file) { $rrd_file = '/' . substr($xml_file, 0, -4) . '.rrd'; - unlink_if_exists("{$rrd_file}"); + unlink_if_exists("{$rrd_file}"); file_put_contents("{$g['tmp_path']}/rrd_restore", $xml_file); $_gb = exec("LANG=C /usr/bin/tar -xf {$g['cf_conf_path']}/rrd.tgz -C / -T {$g['tmp_path']}/rrd_restore"); @@ -5304,4 +5304,132 @@ function upgrade_164_to_165() { } } +/* Fixup digest algorithm selection for OpenVPN clients and servers so they do not use aliased names. */ +function upgrade_165_to_166() { + require_once('openvpn.inc'); + global $config; + + if (isset($config['openvpn']) && is_array($config['openvpn'])) { + if (is_array($config['openvpn']['openvpn-server'])) { + foreach ($config['openvpn']['openvpn-server'] as &$vpn) { + $vpn['digest'] = openvpn_remap_digest($vpn['digest']); + } + } + if (is_array($config['openvpn']['openvpn-client'])) { + foreach ($config['openvpn']['openvpn-client'] as &$vpn) { + $vpn['digest'] = openvpn_remap_digest($vpn['digest']); + } + } + } +} + +/* Force the Netgate Services and Support widget to be active on upgrade. + New widget is added at the top of column 2 */ +function upgrade_166_to_167() { + global $config; + + if (strpos($config['widgets']['sequence'], + 'netgate_services_and_support') === false) { + $widgets = explode(",", $config['widgets']['sequence']); + $cnt = count($widgets); + $col2 = $cnt; + $newsequence = array(); + + // Locate the firt column 2 widget + for ($idx=0;$idx<$cnt;$idx++) { + if (strpos($widgets[$idx], 'col2') !== false) { + $col2 = $idx; + break; + } + } + + /* + * Loop through the widgets inserting the new widget before + * the first col2 widget + */ + for ($old=0,$new=0;$old<$cnt;$old++,$new++) { + $newsequence[$new] = $widgets[$old]; + + if ($old != ($col2 - 1)) { + continue; + } + $new++; + $newsequence[$new] = + "netgate_services_and_support:col2:open:0"; + } + + $config['widgets']['sequence'] = implode(",", $newsequence); + } +} + +function upgrade_167_to_168() { + upgrade_166_to_167(); +} + +function upgrade_168_to_169() { + global $config; + + /* Remove workaround added in 2.3 */ + unset($config['cron']['rc_update_pkg_metadata']); + + $command = '/usr/bin/nice -n20 /etc/rc.update_pkg_metadata'; + if (is_array($config['cron']['item'])) { + foreach ($config['cron']['item'] as $entry) { + if ($entry['command'] == $command) { + return; + } + } + } + + $config['cron']['item'][] = array( + 'minute' => '1', + 'hour' => '0', + 'mday' => '*', + 'month' => '*', + 'wday' => '*', + 'who' => 'root', + 'command' => $command + ); +} + +/* Upgrade wireless interfaces to the format required for 2.4 + * Each wireless interface now needs to be a cloned instance, the card itself + * Can no longer be assigned. https://redmine.pfsense.org/issues/6770 */ +function upgrade_169_to_170() { + global $config; + foreach ($config['interfaces'] as $friendly => & $iface) { + if (is_array($iface['wireless']) && !empty($iface['wireless']['mode'])) { + /* This test can only be true for one instance per card, so it is safe. */ + if (stristr($iface['if'], '_wlan') === false) { + $wlan = array(); + $wlan['if'] = $iface['if']; + $wlan['mode'] = $iface['wireless']['mode']; + $wlan['descr'] = "Wireless interface {$friendly}"; + /* It was not possible to create clones of _wlan0 before, so this is safe. */ + $wlan['cloneif'] = "{$iface['if']}_wlan0"; + /* Make sure this entry is placed in the list of wireless interface clones. */ + if (!is_array($config['wireless'])) { + $config['wireless'] = array(); + $config['wireless']['clone'] = array(); + } + $config['wireless']['clone'][] = $wlan; + /* The interface assignment must now be the cloned interface name. */ + $iface['if'] = $wlan['cloneif']; + } + } + } +} + +/* + * Special function that is called independent of current config version. It's + * a workaround to have config_upgrade running on older versions after next + * config version was already taken by newer pfSense. + * + * XXX Change the way we handle config version to make it based on product + * version + */ +function additional_config_upgrade() { + global $config; +} + ?> diff --git a/src/etc/inc/vpn.inc b/src/etc/inc/vpn.inc index 1398135..8eb2c3c 100644 --- a/src/etc/inc/vpn.inc +++ b/src/etc/inc/vpn.inc @@ -489,12 +489,19 @@ EOD; } } + /* Activate RADIUS accounting if it was selected on the auth server view */ + $radius_accounting = ""; + if($auth_server && isset($auth_server['radius_acct_port'])){ + $radius_accounting = 'accounting = yes'; + } + /* write an eap-radius config section if appropriate */ if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) { $strongswan .= <<<EOD eap-radius { class_group = yes eap_start = no + {$radius_accounting} servers { {$radius_server_txt} } @@ -855,7 +862,7 @@ EOD; if (is_ipaddr($right_spec)) { $sourcehost = $right_spec; } else { - $sourcehost = $rgmap['remote-gateway']; + $sourcehost = $rgmap[$right_spec]; } if (substr($ph1ent['interface'], 0, 4) == "_vip") { @@ -881,7 +888,8 @@ EOD; $subnet_bits = get_interface_subnet($vpninterface); $subnet_ip = gen_subnetv4($interfaceip, $subnet_bits); /* if the remote gateway is in the local subnet, then don't add a route */ - if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) { + if (is_ipaddrv4($sourcehost) && + !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) { if (is_ipaddrv4($gatewayip)) { // log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}"); route_add_or_change("-host {$sourcehost} {$gatewayip}"); @@ -895,7 +903,8 @@ EOD; $subnet_bits = get_interface_subnetv6($vpninterface); $subnet_ip = gen_subnetv6($interfaceip, $subnet_bits); /* if the remote gateway is in the local subnet, then don't add a route */ - if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) { + if (is_ipaddrv6($sourcehost) && + !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) { if (is_ipaddrv6($gatewayip)) { // log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}"); route_add_or_change("-inet6 -host {$sourcehost} {$gatewayip}"); @@ -1101,10 +1110,14 @@ EOD; } else { $reauth = "reauth = yes"; } + if (isset($ph1ent['rekey_enable'])) { - $rekey = "rekey = no"; + $rekeyline = "rekey = no"; } else { - $rekey = "rekey = yes"; + $rekeyline = "rekey = yes"; + if(!empty($ph1ent['margintime'])){ + $rekeyline .= "\n\tmargintime = {$ph1ent['margintime']}s"; + } } if ($ph1ent['nat_traversal'] == 'off') { @@ -1303,7 +1316,7 @@ EOD; {$forceencaps} {$mobike} {$tfc} - {$rekey} + {$rekeyline} installpolicy = yes {$tunneltype} {$dpdline} diff --git a/src/etc/pfSense-rc b/src/etc/pfSense-rc index 0bb0f2b..d5eca8a 100755 --- a/src/etc/pfSense-rc +++ b/src/etc/pfSense-rc @@ -191,6 +191,7 @@ fi || mkdir /home /bin/rm -f /root/force_fsck +/bin/rm -f /root/force_growfs /bin/rm -f /root/TRIM_set /bin/rm -f /root/TRIM_unset @@ -412,6 +413,9 @@ fi /usr/local/sbin/${product}-upgrade -y -b 3 +# Update pkg metadata +/etc/rc.update_pkg_metadata now + # Log product version to syslog get_version BUILDTIME=`cat /etc/version.buildtime` diff --git a/src/etc/pfSense.obsoletedfiles b/src/etc/pfSense.obsoletedfiles index 1714f53..49ae203 100644 --- a/src/etc/pfSense.obsoletedfiles +++ b/src/etc/pfSense.obsoletedfiles @@ -814,6 +814,8 @@ /usr/local/share/mobile-broadband-provider-info/iso_3166-1_list_en.xml /usr/local/share/nls /usr/local/share/pbi-keys +/usr/local/share/pfSense/keys/pkg/revoked/.empty +/usr/local/share/pfSense/keys/pkg/trusted/.empty /usr/local/share/pfSense/pfSense-repo-devel.conf /usr/local/share/pfSense/post_upgrade_command /usr/local/share/pfSense/post_upgrade_command.php @@ -1013,7 +1015,9 @@ /usr/local/www/vpn_pppoe_edit.php /usr/local/www/vpn_pppoe_users.php /usr/local/www/vpn_pppoe_users_edit.php +/usr/local/www/widgets/include/thermal_sensors.inc /usr/local/www/widgets/widgets/deactivated +/usr/local/www/widgets/widgets/support.widget.php /usr/local/www/wizards/traffic_shaper_wizard.inc /usr/local/www/wizards/traffic_shaper_wizard.xml /usr/local/www/wizards/traffic_shaper_wizard_multi_lan.inc diff --git a/src/etc/phpshellsessions/gitsync b/src/etc/phpshellsessions/gitsync index 0ac9479..a5618f7 100644 --- a/src/etc/phpshellsessions/gitsync +++ b/src/etc/phpshellsessions/gitsync @@ -34,7 +34,7 @@ $GITSYNC_MERGE = "/root/.gitsync_merge"; /* NOTE: Set branches here */ $branches = array( - "master" => "2.4 development branch", + "master" => "2.4.1 development branch", "build_commit" => "The commit originally used to build the image" ); diff --git a/src/etc/rc.bootup b/src/etc/rc.bootup index 8924efe..cc0f500 100755 --- a/src/etc/rc.bootup +++ b/src/etc/rc.bootup @@ -121,6 +121,13 @@ if (file_exists("/conf/trigger_initial_wizard") && !file_exists("/conf/assign_co check_for_alternate_interfaces(); } +/* Convert configuration + * This must happen before the interface mismatch test, see + * https://redmine.pfsense.org/issues/7809 */ +echo "Updating configuration..."; +convert_config(); +echo "done.\n"; + /* * Determine if we need to throw a interface exception * and ask the user to reassign interfaces. This will @@ -146,12 +153,7 @@ while (is_interface_mismatch() == true) { led_kitt(); } -/* convert config and clean backups */ -echo "Updating configuration..."; -convert_config(); -echo "done.\n"; - -echo "Cleaning backup cache..."; +echo "Checking config backups consistency..."; cleanup_backupcache(true); echo "done.\n"; diff --git a/src/etc/rc.gateway_alarm b/src/etc/rc.gateway_alarm index 2ac516e..96bffed 100755 --- a/src/etc/rc.gateway_alarm +++ b/src/etc/rc.gateway_alarm @@ -17,15 +17,28 @@ # limitations under the License. GW="$1" +alarm_addr="$2" +alarm_flag="$3" +alarm_rtt="$4" +alarm_rttsd="$5" +alarm_loss="$6" if [ -z "$GW" ]; then exit 1 fi +echo ">>> Gateway alarm: ${GW} (Addr:${alarm_addr} Alarm:${alarm_flag} RTT:${alarm_rtt}ms RTTsd:${alarm_rttsd}ms Loss:${alarm_loss}%)" | /usr/bin/logger -p daemon.info -i -t rc.gateway_alarm + /usr/local/sbin/pfSctl \ -c "service reload dyndns ${GW}" \ -c "service reload ipsecdns" \ -c "service reload openvpn ${GW}" \ -c "filter reload" >/dev/null 2>&1 +# after above signal the check_reload_status process calls the following scripts simultaneously.: +# - "/etc/rc.dyndns.update", "dyndns=%s" +# - "/etc/rc.newipsecdns" +# - "/etc/rc.openvpn", "interface=%s" +# - "/etc/rc.filter_configure_sync" + exit $? diff --git a/src/etc/rc.newipsecdns b/src/etc/rc.newipsecdns index 4670b37..387e731 100755 --- a/src/etc/rc.newipsecdns +++ b/src/etc/rc.newipsecdns @@ -25,8 +25,21 @@ * limitations under the License. */ -/* parse the configuration and include all functions used below */ require_once("util.inc"); +require_once("globals.inc"); + +/* make sure to wait until the boot scripts have finished */ +if (file_exists("{$g['varrun_path']}/booting")) { + return; +} + +$ipseclck_pending = try_lock('ipsecdns_pending', 0); +if (!$ipseclck_pending) { + /* if a vpn_ipsec_configure() is still pending no need to stack up another one */ + return; +} + +/* parse the configuration and include all functions used below */ require_once("config.inc"); require_once("gwlb.inc"); require_once("functions.inc"); @@ -36,21 +49,20 @@ require_once("auth.inc"); require_once("ipsec.inc"); require_once("vpn.inc"); -/* make sure to wait until the boot scripts have finished */ -if (file_exists("{$g['varrun_path']}/booting")) { - return; -} - -if (ipsec_enabled()) { - sleep(15); - log_error("IPSEC: One or more IPsec tunnel endpoints has changed its IP. Refreshing."); -} else { +if (!ipsec_enabled()) { + unlock($ipseclck_pending); return; } $ipseclck = lock('ipsecdns', LOCK_EX); +sleep(12); +unlock($ipseclck_pending); +sleep(3); +log_error("IPSEC: One or more IPsec tunnel endpoints has changed its IP. Refreshing."); + +/* make sure we have the latest configuration changes loaded. */ +$config = parse_config(); vpn_ipsec_configure(); unlock($ipseclck); -?> diff --git a/src/etc/rc.newwanip b/src/etc/rc.newwanip index 920c1e5..76b5f6f 100755 --- a/src/etc/rc.newwanip +++ b/src/etc/rc.newwanip @@ -200,12 +200,13 @@ if (platform_booting()) { if (!is_ipaddr($oldip) || $curwanip != $oldip || !is_ipaddrv4($config['interfaces'][$interface]['ipaddr'])) { /* IP changed, kill states accordingly */ if ($curwanip != $oldip) { - log_error("IP has changed, killing states on former IP $oldip."); - pfSense_kill_states($oldip); if (isset($config['system']['ip_change_kill_states'])) { - /* hidden config option to wipe all states if needed */ - log_error("Killing all states post-IP change."); + log_error("IP Address has changed, killing all states (ip_change_kill_states is set)."); + pfSense_kill_states($oldip); filter_flush_state_table(); + } else { + log_error("IP Address has changed, killing states on former IP Address $oldip."); + pfSense_kill_states($oldip); } } diff --git a/src/etc/rc.newwanipv6 b/src/etc/rc.newwanipv6 index f669f5b..f41a91d 100755 --- a/src/etc/rc.newwanipv6 +++ b/src/etc/rc.newwanipv6 @@ -140,6 +140,7 @@ setup_gateways_monitor(); if (platform_booting()) { // avoid race conditions in many of the below functions that occur during boot + touch("/tmp/{$interface_real}_dhcp6_complete"); exit; } diff --git a/src/etc/rc.php_ini_setup b/src/etc/rc.php_ini_setup index f54dcdb..561f113 100755 --- a/src/etc/rc.php_ini_setup +++ b/src/etc/rc.php_ini_setup @@ -110,8 +110,6 @@ PHPMODULES="$PHPMODULES sqlite3" PHPMODULES="$PHPMODULES radius" # ZeroMQ PHPMODULES="$PHPMODULES zmq" -# SSH2 -PHPMODULES="$PHPMODULES ssh2" # pfSense extensions PHPMODULES="$PHPMODULES pfSense" # json diff --git a/src/etc/rc.update_bogons.sh b/src/etc/rc.update_bogons.sh index bcb8654..d8df393 100755 --- a/src/etc/rc.update_bogons.sh +++ b/src/etc/rc.update_bogons.sh @@ -23,6 +23,14 @@ # Global variables proc_error="" +do_not_send_uniqueid=$(/usr/local/sbin/read_xml_tag.sh boolean system/do_not_send_uniqueid) +if [ "${do_not_send_uniqueid}" != "true" ]; then + uniqueid=$(/usr/sbin/gnid) + export HTTP_USER_AGENT="${product}/${product_version}:${uniqueid}" +else + export HTTP_USER_AGENT="${product}/${product_version}" +fi + # Download and extract if necessary process_url() { local file=$1 diff --git a/src/etc/rc.update_pkg_metadata b/src/etc/rc.update_pkg_metadata new file mode 100755 index 0000000..f22c1af --- /dev/null +++ b/src/etc/rc.update_pkg_metadata @@ -0,0 +1,48 @@ +#!/bin/sh +# +# rc.update_pkg_metadata +# +# Copyright (c) 2017 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. + +if [ "$1" = "now" ]; then + sleep_time=0 +else + sleep_time=$(jot -r 1 1 86399) +fi + +# Read product_name from $g, defaults to pfSense +product=$(/usr/local/sbin/read_global_var product_name pfSense) + +tmp_version=$(mktemp -q /tmp/${product}_version.XXXXXXXX) \ + || exit 1 + +( \ + sleep $sleep_time \ + && /usr/local/sbin/${product}-upgrade -uf \ + && ( \ + /usr/local/sbin/${product}-upgrade -Uc > ${tmp_version}.tmp \ + ; rc=$? \ + ; tail -n 1 ${tmp_version}.tmp > $tmp_version \ + ; rm -f ${tmp_version}.tmp \ + ; echo $rc > ${tmp_version}.rc \ + ; test $rc -eq 2 && return 0 || return $rc \ + ) \ + && ( \ + mv $tmp_version /var/run/${product}_version \ + && mv ${tmp_version}.rc /var/run/${product}_version.rc \ + ) || rm -f $tmp_version ${tmp_version}.rc +) >/dev/null 2>&1 & + +exit 0 diff --git a/src/etc/version b/src/etc/version index f8fd14e..86150d0 100644 --- a/src/etc/version +++ b/src/etc/version @@ -1 +1 @@ -2.4.0-BETA +2.4.1-DEVELOPMENT |