diff options
author | Vinicius Coque <vinicius.coque@bluepex.com> | 2011-03-25 08:49:04 -0300 |
---|---|---|
committer | Vinicius Coque <vinicius.coque@bluepex.com> | 2011-03-25 08:49:04 -0300 |
commit | 54bdff758f68e2e1b1ebd42b8b0b629b68ed1a3d (patch) | |
tree | 27b7d45e582e3d84cdf8d0fa0f3bc93b65f3c986 /etc/inc | |
parent | b845290619244e8cfe3bc2aa6271c6629eeb86b5 (diff) | |
parent | 401fb0ad8fa7ad06743435808dac8e913b3c16bb (diff) | |
download | pfsense-54bdff758f68e2e1b1ebd42b8b0b629b68ed1a3d.zip pfsense-54bdff758f68e2e1b1ebd42b8b0b629b68ed1a3d.tar.gz |
Merge remote-tracking branch 'mainline/master' into inc
Conflicts:
etc/inc/auth.inc
etc/inc/config.lib.inc
etc/inc/filter.inc
etc/inc/pfsense-utils.inc
etc/inc/pkg-utils.inc
etc/inc/priv.defs.inc
etc/inc/services.inc
etc/inc/shaper.inc
etc/inc/voucher.inc
etc/inc/vpn.inc
usr/local/www/fbegin.inc
Diffstat (limited to 'etc/inc')
-rw-r--r-- | etc/inc/auth.inc | 4 | ||||
-rw-r--r-- | etc/inc/authgui.inc | 2 | ||||
-rw-r--r-- | etc/inc/captiveportal.inc | 611 | ||||
-rw-r--r-- | etc/inc/certs.inc | 7 | ||||
-rw-r--r-- | etc/inc/config.console.inc | 2 | ||||
-rw-r--r-- | etc/inc/config.gui.inc | 6 | ||||
-rw-r--r-- | etc/inc/config.lib.inc | 62 | ||||
-rw-r--r-- | etc/inc/dyndns.class | 4 | ||||
-rw-r--r-- | etc/inc/easyrule.inc | 7 | ||||
-rw-r--r-- | etc/inc/filter.inc | 108 | ||||
-rw-r--r-- | etc/inc/globals.inc | 6 | ||||
-rw-r--r-- | etc/inc/interfaces.inc | 30 | ||||
-rw-r--r-- | etc/inc/ipsec.inc | 8 | ||||
-rw-r--r-- | etc/inc/openvpn.inc | 4 | ||||
-rw-r--r-- | etc/inc/pfsense-utils.inc | 70 | ||||
-rw-r--r-- | etc/inc/pkg-utils.inc | 19 | ||||
-rw-r--r-- | etc/inc/priv.defs.inc | 12 | ||||
-rw-r--r-- | etc/inc/rrd.inc | 19 | ||||
-rw-r--r-- | etc/inc/service-utils.inc | 4 | ||||
-rw-r--r-- | etc/inc/services.inc | 19 | ||||
-rw-r--r-- | etc/inc/shaper.inc | 47 | ||||
-rw-r--r-- | etc/inc/upgrade_config.inc | 44 | ||||
-rw-r--r-- | etc/inc/util.inc | 4 | ||||
-rw-r--r-- | etc/inc/voucher.inc | 26 | ||||
-rw-r--r-- | etc/inc/vpn.inc | 63 |
25 files changed, 863 insertions, 325 deletions
diff --git a/etc/inc/auth.inc b/etc/inc/auth.inc index 6942223..8f1cde8 100644 --- a/etc/inc/auth.inc +++ b/etc/inc/auth.inc @@ -1216,7 +1216,9 @@ function session_auth() { $_SESSION['Logged_In'] = "True"; $_SESSION['Username'] = $_POST['usernamefld']; $_SESSION['last_access'] = time(); - log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR'])); + if(! isset($config['system']['webgui']['quietlogin'])) { + log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR'])); + } $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username']; if (isset($_POST['postafterlogin'])) return true; diff --git a/etc/inc/authgui.inc b/etc/inc/authgui.inc index 44fcb1c..110765c 100644 --- a/etc/inc/authgui.inc +++ b/etc/inc/authgui.inc @@ -227,7 +227,7 @@ if($config['virtualip']) print_info_box(gettext("You are accessing this router by an IP address not configured locally, which may be forwarded by NAT or other means. <br/><br/>If you did not setup this forwarding, you may be the target of a man-in-the-middle attack.")); } ?> - <form id="iform" name="login_iform" method="post" autocomplete="off" action="<?=$_SERVER['SCRIPT_NAME'];?>"> + <form id="iform" name="login_iform" method="post" action="<?=$_SERVER['SCRIPT_NAME'];?>"> <h1></h1> <div id="inputerrors"><?=$_SESSION['Login_Error'];?></div> <p> diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc index 4a3b80d..6535f54 100644 --- a/etc/inc/captiveportal.inc +++ b/etc/inc/captiveportal.inc @@ -211,6 +211,8 @@ function captiveportal_configure() { if ($g['booting']) echo "Starting captive portal... "; + else + captiveportal_syslog("Restarting captive portal."); /* kill any running mini_httpd */ killbypid("{$g['varrun_path']}/lighty-CaptivePortal.pid"); @@ -226,7 +228,7 @@ function captiveportal_configure() { touch("{$g['vardb_path']}/captiveportal.db"); /* kill any running minicron */ - killbypid("{$g['varrun_path']}/minicron.pid"); + killbypid("{$g['varrun_path']}/cp_prunedb.pid"); /* init ipfw rules */ captiveportal_init_rules(true); @@ -417,8 +419,12 @@ EOD; /* start up the webserving daemon */ captiveportal_init_webgui(); + /* Kill any existing prunecaptiveportal processes */ + if(file_exists("{$g['varrun_path']}/cp_prunedb.pid")) + killbypid("{$g['varrun_path']}/cp_prunedb.pid"); + /* start pruning process (interval defaults to 60 seconds) */ - mwexec("/usr/local/bin/minicron $croninterval {$g['varrun_path']}/minicron.pid " . + mwexec("/usr/local/bin/minicron $croninterval {$g['varrun_path']}/cp_prunedb.pid " . "/etc/rc.prunecaptiveportal"); /* generate radius server database */ @@ -429,7 +435,7 @@ EOD; } else { killbypid("{$g['varrun_path']}/lighty-CaptivePortal.pid"); - killbypid("{$g['varrun_path']}/minicron.pid"); + killbypid("{$g['varrun_path']}/cp_prunedb.pid"); captiveportal_radius_stop_all(); @@ -498,6 +504,7 @@ function captiveportal_init_webgui() { $res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-CaptivePortal-SSL.conf"); } +/* reinit will disconnect all users, be careful! */ function captiveportal_init_rules($reinit = false) { global $config, $g; @@ -708,48 +715,47 @@ function captiveportal_prune_old() { !isset($config['captiveportal']['radiussession_timeout']) && !isset($config['voucher']['enable'])) return; + $radiusservers = captiveportal_get_radius_servers(); + /* read database */ $cpdb = captiveportal_read_db(); - $radiusservers = captiveportal_get_radius_servers(); - /* To make sure we iterate over ALL accounts on every run the count($cpdb) is moved * outside of the loop. Otherwise the loop would evaluate count() on every iteration * and since $i would increase and count() would decrement they would meet before we * had a chance to iterate over all accounts. */ $unsetindexes = array(); - $no_users = count($cpdb); - for ($i = 0; $i < $no_users; $i++) { + foreach ($cpdb as $cpentry) { $timedout = false; $term_cause = 1; /* hard timeout? */ if ($timeout) { - if ((time() - $cpdb[$i][0]) >= $timeout) { + if ((time() - $cpentry[0]) >= $timeout) { $timedout = true; $term_cause = 5; // Session-Timeout } } /* Session-Terminate-Time */ - if (!$timedout && !empty($cpdb[$i][9])) { - if (time() >= $cpdb[$i][9]) { + if (!$timedout && !empty($cpentry[9])) { + if (time() >= $cpentry[9]) { $timedout = true; $term_cause = 5; // Session-Timeout } } /* check if the radius idle_timeout attribute has been set and if its set change the idletimeout to this value */ - $uidletimeout = (is_numeric($cpdb[$i][8])) ? $cpdb[$i][8] : $idletimeout; + $uidletimeout = (is_numeric($cpentry[8])) ? $cpentry[8] : $idletimeout; /* if an idle timeout is specified, get last activity timestamp from ipfw */ if (!$timedout && $uidletimeout) { - $lastact = captiveportal_get_last_activity($cpdb[$i][2]); + $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. */ - $lastact = $lastact ? $lastact : $cpdb[$i][0]; + $lastact = $lastact ? $lastact : $cpentry[0]; if ($lastact && ((time() - $lastact) >= $uidletimeout)) { $timedout = true; $term_cause = 4; // Idle-Timeout @@ -758,25 +764,25 @@ function captiveportal_prune_old() { } /* if vouchers are configured, activate session timeouts */ - if (!$timedout && isset($config['voucher']['enable']) && !empty($cpdb[$i][7])) { - if (time() >= ($cpdb[$i][0] + $cpdb[$i][7])) { + if (!$timedout && isset($config['voucher']['enable']) && !empty($cpentry[7])) { + if (time() >= ($cpentry[0] + $cpentry[7])) { $timedout = true; $term_cause = 5; // Session-Timeout } } /* if radius session_timeout is enabled and the session_timeout is not null, then check if the user should be logged out */ - if (!$timedout && isset($config['captiveportal']['radiussession_timeout']) && !empty($cpdb[$i][7])) { - if (time() >= ($cpdb[$i][0] + $cpdb[$i][7])) { + if (!$timedout && isset($config['captiveportal']['radiussession_timeout']) && !empty($cpentry[7])) { + if (time() >= ($cpentry[0] + $cpentry[7])) { $timedout = true; $term_cause = 5; // Session-Timeout } } if ($timedout) { - captiveportal_disconnect($cpdb[$i], $radiusservers,$term_cause,$stop_time); - captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "TIMEOUT"); - $unsetindexes[$i] = $i; + captiveportal_disconnect($cpentry, $radiusservers,$term_cause,$stop_time); + captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "TIMEOUT"); + $unsetindexes[] = $cpentry[5]; } /* do periodic RADIUS reauthentication? */ @@ -784,30 +790,30 @@ function captiveportal_prune_old() { if (isset($config['captiveportal']['radacct_enable'])) { if ($config['captiveportal']['reauthenticateacct'] == "stopstart") { /* stop and restart accounting */ - RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno - $cpdb[$i][4], // username - $cpdb[$i][5], // sessionid - $cpdb[$i][0], // start time + RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno + $cpentry[4], // username + $cpentry[5], // sessionid + $cpentry[0], // start time $radiusservers, - $cpdb[$i][2], // clientip - $cpdb[$i][3], // clientmac + $cpentry[2], // clientip + $cpentry[3], // clientmac 10); // NAS Request - exec("/sbin/ipfw table 1 entryzerostats {$cpdb[$i][2]}"); - exec("/sbin/ipfw table 2 entryzerostats {$cpdb[$i][2]}"); - RADIUS_ACCOUNTING_START($cpdb[$i][1], // ruleno - $cpdb[$i][4], // username - $cpdb[$i][5], // sessionid + exec("/sbin/ipfw table 1 entryzerostats {$cpentry[2]}"); + exec("/sbin/ipfw table 2 entryzerostats {$cpentry[2]}"); + RADIUS_ACCOUNTING_START($cpentry[1], // ruleno + $cpentry[4], // username + $cpentry[5], // sessionid $radiusservers, - $cpdb[$i][2], // clientip - $cpdb[$i][3]); // clientmac + $cpentry[2], // clientip + $cpentry[3]); // clientmac } else if ($config['captiveportal']['reauthenticateacct'] == "interimupdate") { - RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno - $cpdb[$i][4], // username - $cpdb[$i][5], // sessionid - $cpdb[$i][0], // start time + RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno + $cpentry[4], // username + $cpentry[5], // sessionid + $cpentry[0], // start time $radiusservers, - $cpdb[$i][2], // clientip - $cpdb[$i][3], // clientmac + $cpentry[2], // clientip + $cpentry[3], // clientmac 10, // NAS Request true); // Interim Updates } @@ -815,26 +821,24 @@ function captiveportal_prune_old() { /* check this user against RADIUS again */ if (isset($config['captiveportal']['reauthenticate'])) { - $auth_list = RADIUS_AUTHENTICATION($cpdb[$i][4], // username - base64_decode($cpdb[$i][6]), // password + $auth_list = RADIUS_AUTHENTICATION($cpentry[4], // username + base64_decode($cpentry[6]), // password $radiusservers, - $cpdb[$i][2], // clientip - $cpdb[$i][3], // clientmac - $cpdb[$i][1]); // ruleno + $cpentry[2], // clientip + $cpentry[3], // clientmac + $cpentry[1]); // ruleno if ($auth_list['auth_val'] == 3) { - captiveportal_disconnect($cpdb[$i], $radiusservers, 17); - captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "RADIUS_DISCONNECT", $auth_list['reply_message']); - $unsetindexes[$i] = $i; + captiveportal_disconnect($cpentry, $radiusservers, 17); + captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "RADIUS_DISCONNECT", $auth_list['reply_message']); + $unsetindexes[] = $cpentry[5]; } } } } - /* This is a kludge to overcome some php weirdness */ - foreach($unsetindexes as $unsetindex) - unset($cpdb[$unsetindex]); /* write database */ - captiveportal_write_db($cpdb); + if (!empty($unsetindexes)) + captiveportal_write_db($cpdb, false, $unsetindexes); } /* remove a single client according to the DB entry */ @@ -856,12 +860,15 @@ function captiveportal_disconnect($dbent, $radiusservers,$term_cause = 1,$stop_t false, $stop_time); } - /* Delete client's ip entry from tables 3 and 4. */ - mwexec("/sbin/ipfw table 1 delete {$dbent[2]}"); - mwexec("/sbin/ipfw table 2 delete {$dbent[2]}"); - - /* Release the ruleno so it can be reallocated to new clients. */ - captiveportal_free_ipfw_ruleno($dbent[1]); + + if (is_ipaddr($dbent[2])) { + /* Delete client's ip entry from tables 3 and 4. */ + mwexec("/sbin/ipfw table 1 delete {$dbent[2]}"); + mwexec("/sbin/ipfw table 2 delete {$dbent[2]}"); + /* XXX: Redundant?! Ensure all pf(4) states are killed. */ + mwexec("pfctl -k {$dbent[2]}"); + mwexec("pfctl -K {$dbent[2]}"); + } /* * These are the pipe numbers we use to control traffic shaping for each logged in user via captive portal @@ -872,32 +879,33 @@ function captiveportal_disconnect($dbent, $radiusservers,$term_cause = 1,$stop_t mwexec("/sbin/ipfw pipe " . ($dbent[1]+20001) . " delete"); } - /* XXX: Redundant?! Ensure all pf(4) states are killed. */ - mwexec("pfctl -k {$dbent[2]}"); - mwexec("pfctl -K {$dbent[2]}"); - + /* Release the ruleno so it can be reallocated to new clients. */ + captiveportal_free_ipfw_ruleno($dbent[1]); } -/* remove a single client by ipfw rule number */ -function captiveportal_disconnect_client($id,$term_cause = 1) { +/* remove a single client by sessionid */ +function captiveportal_disconnect_client($sessionid, $term_cause = 1, $logoutReason = "LOGOUT") { global $g, $config; - /* read database */ - $cpdb = captiveportal_read_db(); $radiusservers = captiveportal_get_radius_servers(); + $unsetindex = array(); + + $cpdblck = lock('captiveportaldb', LOCK_EX); + + /* read database */ + $cpdb = captiveportal_read_db(true); /* find entry */ - foreach ($cpdb as $i => $cpentry) { - if ($cpentry[1] == $id) { - captiveportal_disconnect($cpentry, $radiusservers, $term_cause); - captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "DISCONNECT"); - unset($cpdb[$i]); - break; - } - } + if (isset($cpdb[$sessionid])) { + $cpentry = $cpdb[$sessionid]; + /* write database */ + $unsetindex[] = $sessionid; + captiveportal_write_db($cpdb, true, $unsetindex); + unlock($cpdblck); - /* write database */ - captiveportal_write_db($cpdb); + captiveportal_disconnect($cpentry, $radiusservers, $term_cause); + captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "DISCONNECT"); + } } /* send RADIUS acct stop for all current clients */ @@ -1077,10 +1085,10 @@ function setup_dnsfilter_entries() { $cp_filterdns_conf = ""; if (is_array($config['captiveportal']['allowedhostname'])) { foreach ($config['captiveportal']['allowedhostname'] as $hostnameent) { - $cp_filterdns_conf .= "ipfw $hostnameent 3 '/etc/rc.captiveportal_configure'\n"; - $cp_filterdns_conf .= "ipfw $hostnameent 4 '/etc/rc.captiveportal_configure'\n"; - $cp_filterdns_conf .= "ipfw $hostnameent 7 '/etc/rc.captiveportal_configure'\n"; - $cp_filterdns_conf .= "ipfw $hostnameent 8 '/etc/rc.captiveportal_configure'\n"; + $cp_filterdns_conf .= "ipfw {$hostnameent['hostname']} 3\n"; + $cp_filterdns_conf .= "ipfw {$hostnameent['hostname']} 4\n"; + $cp_filterdns_conf .= "ipfw {$hostnameent['hostname']} 7\n"; + $cp_filterdns_conf .= "ipfw {$hostnameent['hostname']} 8\n"; } } file_put_contents($cp_filterdns_filename, $cp_filterdns_conf); @@ -1254,38 +1262,54 @@ function radius($username,$password,$clientip,$clientmac,$type) { } /* read captive portal DB into array */ -function captiveportal_read_db() { - global $g; +function captiveportal_read_db($locked = false) { + global $g; - $cpdb = array(); + $cpdb = array(); + if ($locked == false) $cpdblck = lock('captiveportaldb'); - $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r"); - if ($fd) { - while (!feof($fd)) { - $line = trim(fgets($fd)); - if ($line) - $cpdb[] = explode(",", $line); + $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r"); + if ($fd) { + while (!feof($fd)) { + $line = trim(fgets($fd)); + if ($line) { + $cpe = explode(",", $line); + /* Hash by session id */ + $cpdb[$cpe[5]] = $cpe; } - fclose($fd); } + fclose($fd); + } + if ($locked == false) unlock($cpdblck); - return $cpdb; + return $cpdb; } /* write captive portal DB */ -function captiveportal_write_db($cpdb) { - global $g; +function captiveportal_write_db($cpdb, $locked = false, $remove = false) { + global $g; + if ($locked == false) $cpdblck = lock('captiveportaldb', LOCK_EX); - $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w"); - if ($fd) { - foreach ($cpdb as $cpent) { - fwrite($fd, join(",", $cpent) . "\n"); - } - fclose($fd); + + if (is_array($remove)) { + if (!empty($remove)) { + $cpdb = captiveportal_read_db(true); + foreach ($remove as $key) + unset($cpdb[$key]); + } else + return; //This makes sure no record removal calls + } + $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w"); + if ($fd) { + foreach ($cpdb as $cpent) { + fwrite($fd, join(",", $cpent) . "\n"); } - unlock($cpdblck); + fclose($fd); + } + if ($locked == false) + unlock($cpdblck); } function captiveportal_write_elements() { @@ -1515,4 +1539,393 @@ function portal_ip_from_client_ip($cliip) { return false; } +/* functions move from index.php */ + +function portal_reply_page($redirurl, $type = null, $message = null, $clientmac = null, $clientip = null, $username = null, $password = null) { + global $g, $config; + + /* Get captive portal layout */ + if ($type == "redir") { + header("Location: {$redirurl}"); + return; + } else if ($type == "login") + $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal.html"); + else + $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal-error.html"); + + /* substitute the PORTAL_REDIRURL variable */ + if ($config['captiveportal']['preauthurl']) { + $htmltext = str_replace("\$PORTAL_REDIRURL\$", "{$config['captiveportal']['preauthurl']}", $htmltext); + $htmltext = str_replace("#PORTAL_REDIRURL#", "{$config['captiveportal']['preauthurl']}", $htmltext); + } + + /* substitute other variables */ + if (isset($config['captiveportal']['httpslogin'])) { + $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext); + $htmltext = str_replace("#PORTAL_ACTION#", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext); + } else { + $ifip = portal_ip_from_client_ip($clientip); + if (!$ifip) + $ourhostname = $config['system']['hostname'] . ":8000"; + else + $ourhostname = "{$ifip}:8000"; + $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$ourhostname}/", $htmltext); + $htmltext = str_replace("#PORTAL_ACTION#", "http://{$ourhostname}/", $htmltext); + } + + $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext); + $htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext); + $htmltext = str_replace("\$CLIENT_MAC\$", htmlspecialchars($clientmac), $htmltext); + $htmltext = str_replace("\$CLIENT_IP\$", htmlspecialchars($clientip), $htmltext); + + // Special handling case for captive portal master page so that it can be ran + // through the PHP interpreter using the include method above. We convert the + // $VARIABLE$ case to #VARIABLE# in /etc/inc/captiveportal.inc before writing out. + $htmltext = str_replace("#PORTAL_REDIRURL#", htmlspecialchars($redirurl), $htmltext); + $htmltext = str_replace("#PORTAL_MESSAGE#", htmlspecialchars($message), $htmltext); + $htmltext = str_replace("#CLIENT_MAC#", htmlspecialchars($clientmac), $htmltext); + $htmltext = str_replace("#CLIENT_IP#", htmlspecialchars($clientip), $htmltext); + $htmltext = str_replace("#USERNAME#", htmlspecialchars($username), $htmltext); + $htmltext = str_replace("#PASSWORD#", htmlspecialchars($password), $htmltext); + + echo $htmltext; +} + +function portal_mac_radius($clientmac,$clientip) { + global $config ; + + $radmac_secret = $config['captiveportal']['radmac_secret']; + + /* authentication against the radius server */ + $username = mac_format($clientmac); + $auth_list = radius($username,$radmac_secret,$clientip,$clientmac,"MACHINE LOGIN"); + if ($auth_list['auth_val'] == 2) + return TRUE; + if (!empty($auth_list['url_redirection'])) + portal_reply_page($auth_list['url_redirection'], "redir"); + + return FALSE; +} + +function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null) { + + global $redirurl, $g, $config, $type, $passthrumac, $_POST; + + /* See if a ruleno is passed, if not start sessions because this means there isn't one atm */ + if ($ruleno == null) + $ruleno = captiveportal_get_next_ipfw_ruleno(); + + /* if the pool is empty, return appropriate message and exit */ + if (is_null($ruleno)) { + portal_reply_page($redirurl, "error", "System reached maximum login capacity"); + log_error("WARNING! Captive portal has reached maximum login capacity"); + exit; + } + + // Ensure we create an array if we are missing attributes + if (!is_array($attributes)) + $attributes = array(); + + $radiusservers = captiveportal_get_radius_servers(); + + /* Do not allow concurrent login execution. */ + $cpdblck = lock('captiveportaldb', LOCK_EX); + + unset($sessionid); + + /* read in client database */ + $cpdb = captiveportal_read_db(true); + + if ($attributes['voucher']) + $remaining_time = $attributes['session_timeout']; + + $writecfg = false; + /* Find an existing session */ + if ((isset($config['captiveportal']['noconcurrentlogins'])) && $passthrumac) { + if (isset($config['captiveportal']['passthrumacadd'])) { + $mac = captiveportal_passthrumac_findbyname($username); + if (!empty($mac)) { + if ($_POST['replacemacpassthru']) { + foreach ($config['captiveportal']['passthrumac'] as $idx => $macent) { + if ($macent['mac'] == $mac['mac']) { + $macrules = ""; + $ruleno = captiveportal_get_ipfw_passthru_ruleno($mac['mac']); + if ($ruleno) { + captiveportal_free_ipfw_ruleno($ruleno, true); + $macrules .= "delete {$ruleno}\n"; + ++$ruleno; + $macrules .= "delete {$ruleno}\n"; + } + unset($config['captiveportal']['passthrumac'][$idx]); + $mac['mac'] = $clientmac; + $config['captiveportal']['passthrumac'][] = $mac; + $macrules .= captiveportal_passthrumac_configure_entry($mac); + file_put_contents("{$g['tmp_path']}/macentry.rules.tmp", $macrules); + mwexec("/sbin/ipfw -q {$g['tmp_path']}/macentry.rules.tmp"); + $writecfg = true; + $sessionid = true; + break; + } + } + } else { + portal_reply_page($redirurl, "error", "Username: {$username} is already authenticated using another MAC address.", + $clientmac, $clientip, $username, $password); + exit; + } + } + } + } + + foreach ($cpdb as $sid => $cpentry) { + /* on the same ip */ + if($cpentry[2] == $clientip) { + captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - REUSING OLD SESSION"); + $sessionid = $sid; + break; + } + elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) { + // user logged in with an active voucher. Check for how long and calculate + // how much time we can give him (voucher credit - used time) + $remaining_time = $cpentry[0] + $cpentry[7] - time(); + if ($remaining_time < 0) // just in case. + $remaining_time = 0; + + /* This user was already logged in so we disconnect the old one */ + captiveportal_disconnect($cpentry,$radiusservers,13); + captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - TERMINATING OLD SESSION"); + unset($cpdb[$sid]); + break; + } + elseif ((isset($config['captiveportal']['noconcurrentlogins'])) && ($username != 'unauthenticated')) { + /* on the same username */ + if (strcasecmp($cpentry[4], $username) == 0) { + /* This user was already logged in so we disconnect the old one */ + captiveportal_disconnect($cpentry,$radiusservers,13); + captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - TERMINATING OLD SESSION"); + unset($cpdb[$sid]); + break; + } + } + } + + if ($attributes['voucher'] && $remaining_time <= 0) + return 0; // voucher already used and no time left + + if (!isset($sessionid)) { + /* generate unique session ID */ + $tod = gettimeofday(); + $sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16); + + /* Add rules for traffic shaping + * We don't need to add extra rules since traffic will pass due to the following kernel option + * net.inet.ip.fw.one_pass: 1 + */ + $peruserbw = isset($config['captiveportal']['peruserbw']); + + $bw_up = isset($attributes['bw_up']) ? trim($attributes['bw_up']) : $config['captiveportal']['bwdefaultup']; + $bw_down = isset($attributes['bw_down']) ? trim($attributes['bw_down']) : $config['captiveportal']['bwdefaultdn']; + + if ($passthrumac) { + $mac = array(); + $mac['mac'] = $clientmac; + if (isset($config['captiveportal']['passthrumacaddusername'])) + $mac['username'] = $username; + $mac['descr'] = "Auto added pass-through MAC for user {$username}"; + if (!empty($bw_up)) + $mac['bw_up'] = $bw_up; + if (!empty($bw_down)) + $mac['bw_down'] = $bw_down; + if (!is_array($config['captiveportal']['passthrumac'])) + $config['captiveportal']['passthrumac'] = array(); + $config['captiveportal']['passthrumac'][] = $mac; + unlock($cpdblck); + $macrules = captiveportal_passthrumac_configure_entry($mac); + file_put_contents("{$g['tmp_path']}/macentry.rules.tmp", $macrules); + mwexec("/sbin/ipfw -q {$g['tmp_path']}/macentry.rules.tmp"); + $writecfg = true; + } else { + if ($peruserbw && !empty($bw_up) && is_numeric($bw_up)) { + $bw_up_pipeno = $ruleno + 20000; + //$bw_up /= 1000; // Scale to Kbit/s + mwexec("/sbin/ipfw pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100"); + + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac} {$bw_up_pipeno}"); + else + mwexec("/sbin/ipfw table 1 add {$clientip} {$bw_up_pipeno}"); + } else { + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac}"); + else + mwexec("/sbin/ipfw table 1 add {$clientip}"); + } + if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) { + $bw_down_pipeno = $ruleno + 20001; + //$bw_down /= 1000; // Scale to Kbit/s + mwexec("/sbin/ipfw pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100"); + + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac} {$bw_down_pipeno}"); + else + mwexec("/sbin/ipfw table 2 add {$clientip} {$bw_down_pipeno}"); + } else { + if (!isset($config['captiveportal']['nomacfilter'])) + mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac}"); + else + mwexec("/sbin/ipfw table 2 add {$clientip}"); + } + + if ($attributes['voucher']) + $attributes['session_timeout'] = $remaining_time; + + /* encode password in Base64 just in case it contains commas */ + $bpassword = base64_encode($password); + $cpdb[] = array(time(), $ruleno, $clientip, $clientmac, $username, $sessionid, $bpassword, + $attributes['session_timeout'], $attributes['idle_timeout'], $attributes['session_terminate_time']); + + /* rewrite information to database */ + captiveportal_write_db($cpdb, true); + unlock($cpdblck); + + if (isset($config['captiveportal']['radacct_enable']) && !empty($radiusservers)) { + $acct_val = RADIUS_ACCOUNTING_START($ruleno, + $username, $sessionid, $radiusservers, $clientip, $clientmac); + if ($acct_val == 1) + captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED"); + } + } + } else + unlock($cpdblck); + + if ($writecfg == true) + write_config(); + + /* redirect user to desired destination */ + if (!empty($attributes['url_redirection'])) + $my_redirurl = $attributes['url_redirection']; + else if ($config['captiveportal']['redirurl']) + $my_redirurl = $config['captiveportal']['redirurl']; + else + $my_redirurl = $redirurl; + + if(isset($config['captiveportal']['logoutwin_enable']) && !$passthrumac) { + + if (isset($config['captiveportal']['httpslogin'])) + $logouturl = "https://{$config['captiveportal']['httpsname']}:8001/"; + else { + $ifip = portal_ip_from_client_ip($clientip); + if (!$ifip) + $ourhostname = $config['system']['hostname'] . ":8000"; + else + $ourhostname = "{$ifip}:8000"; + $logouturl = "http://{$ourhostname}/"; + } + + if (isset($attributes['reply_message'])) + $message = $attributes['reply_message']; + else + $message = 0; + + include("{$g['varetc_path']}/captiveportal-logout.html"); + + } else { + header("Location: " . $my_redirurl); + } + + return $sessionid; +} + + +/* + * Used for when pass-through credits are enabled. + * Returns true when there was at least one free login to deduct for the MAC. + * Expired entries are removed as they are seen. + * Active entries are updated according to the configuration. + */ +function portal_consume_passthrough_credit($clientmac) { + global $config; + + if (!empty($config['captiveportal']['freelogins_count']) && is_numeric($config['captiveportal']['freelogins_count'])) + $freeloginscount = $config['captiveportal']['freelogins_count']; + else + return false; + + if (!empty($config['captiveportal']['freelogins_resettimeout']) && is_numeric($config['captiveportal']['freelogins_resettimeout'])) + $resettimeout = $config['captiveportal']['freelogins_resettimeout']; + else + return false; + + if ($freeloginscount < 1 || $resettimeout <= 0 || !$clientmac) + return false; + + $updatetimeouts = isset($config['captiveportal']['freelogins_updatetimeouts']); + + /* + * Read database of used MACs. Lines are a comma-separated list + * of the time, MAC, then the count of pass-through credits remaining. + */ + $usedmacs = captiveportal_read_usedmacs_db(); + + $currenttime = time(); + $found = false; + foreach ($usedmacs as $key => $usedmac) { + $usedmac = explode(",", $usedmac); + + if ($usedmac[1] == $clientmac) { + if ($usedmac[0] + ($resettimeout * 3600) > $currenttime) { + if ($usedmac[2] < 1) { + if ($updatetimeouts) { + $usedmac[0] = $currenttime; + unset($usedmacs[$key]); + $usedmacs[] = implode(",", $usedmac); + captiveportal_write_usedmacs_db($usedmacs); + } + + return false; + } else { + $usedmac[2] -= 1; + $usedmacs[$key] = implode(",", $usedmac); + } + + $found = true; + } else + unset($usedmacs[$key]); + + break; + } else if ($usedmac[0] + ($resettimeout * 3600) <= $currenttime) + unset($usedmacs[$key]); + } + + if (!$found) { + $usedmac = array($currenttime, $clientmac, $freeloginscount - 1); + $usedmacs[] = implode(",", $usedmac); + } + + captiveportal_write_usedmacs_db($usedmacs); + return true; +} + +function captiveportal_read_usedmacs_db() { + global $g; + + $cpumaclck = lock('captiveusedmacs'); + if (file_exists("{$g['vardb_path']}/captiveportal_usedmacs.db")) { + $usedmacs = file("{$g['vardb_path']}/captiveportal_usedmacs.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (!$usedmacs) + $usedmacs = array(); + } else + $usedmacs = array(); + + unlock($cpumaclck); + return $usedmacs; +} + +function captiveportal_write_usedmacs_db($usedmacs) { + global $g; + + $cpumaclck = lock('captiveusedmacs', LOCK_EX); + @file_put_contents("{$g['vardb_path']}/captiveportal_usedmacs.db", implode("\n", $usedmacs)); + unlock($cpumaclck); +} + ?> diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc index 7d19045..8d5604f 100644 --- a/etc/inc/certs.inc +++ b/etc/inc/certs.inc @@ -90,12 +90,12 @@ function & lookup_crl($refid) { function ca_chain_array(& $cert) { if($cert['caref']) { $chain = array(); - $crt =& lookup_ca($cert['caref']); + $crt = lookup_ca($cert['caref']); $chain[] = $crt; while ($crt) { $caref = $crt['caref']; if($caref) - $crt =& lookup_ca($caref); + $crt = lookup_ca($caref); else $crt = false; if($crt) @@ -417,7 +417,8 @@ function is_ipsec_cert($certref) { function is_webgui_cert($certref) { global $config; - if ($config['system']['webgui']['ssl-certref'] == $certref) + if (($config['system']['webgui']['ssl-certref'] == $certref) + && ($config['system']['webgui']['protocol'] != "http")) return true; } diff --git a/etc/inc/config.console.inc b/etc/inc/config.console.inc index 7b2cab7..75eb013 100644 --- a/etc/inc/config.console.inc +++ b/etc/inc/config.console.inc @@ -303,9 +303,9 @@ EOD; echo "\n" . gettext("The interfaces will be assigned as follows:") . "\n\n"; + echo "WAN -> " . $wanif . "\n"; if ($lanif != "") echo "LAN -> " . $lanif . "\n"; - echo "WAN -> " . $wanif . "\n"; for ($i = 0; $i < count($optif); $i++) { echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n"; } diff --git a/etc/inc/config.gui.inc b/etc/inc/config.gui.inc index 1a7e397..bfceb5a 100644 --- a/etc/inc/config.gui.inc +++ b/etc/inc/config.gui.inc @@ -41,10 +41,6 @@ pfSense_BUILDER_BINARIES: /sbin/mount /sbin/sysctl /sbin/umount /sbin/halt /sbin/fsck pfSense_MODULE: config */ -/* - * XXX: Hack around the cvs syntax checks. - * DISABLE_PHP_LINT_CHECKING - */ require_once("globals.inc"); @@ -87,4 +83,4 @@ if($config_parsed == true) { } } -?>
\ No newline at end of file +?> diff --git a/etc/inc/config.lib.inc b/etc/inc/config.lib.inc index 9f0b736..c0b568d 100644 --- a/etc/inc/config.lib.inc +++ b/etc/inc/config.lib.inc @@ -120,35 +120,6 @@ function parse_config($parse = false) { if(!$parse) { if (file_exists($g['tmp_path'] . '/config.cache')) { $config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache')); -<<<<<<< HEAD - if(is_null($config)) { - unlock($lockkey); - parse_config(true); - $lockkey = lock('config'); - } - } else { - if(!file_exists($g['conf_path'] . "/config.xml")) { - log_error(gettext("No config.xml found, attempting last known config restore.")); - file_notice("config.xml", gettext("No config.xml found, attempting last known config restore."), "pfSenseConfigurator", ""); - $last_backup = discover_last_backup(); - if ($last_backup) - restore_backup("/cf/conf/backup/{$last_backup}"); - else { - log_error(gettext("Could not restore config.xml.")); - unlock($lockkey); - die(gettext("Config.xml is corrupted and is 0 bytes. Could not restore a previous backup.")); - } - } - unlock($lockkey); - $config = parse_config(true); - $lockkey = lock('config'); - } - } else { - if(!file_exists($g['conf_path'] . "/config.xml")) { - if($g['booting']) echo "."; - log_error(gettext("No config.xml found, attempting last known config restore.")); - file_notice("config.xml", gettext("No config.xml found, attempting last known config restore."), "pfSenseConfigurator", ""); -======= if (is_null($config)) $parse = true; } else @@ -160,7 +131,6 @@ function parse_config($parse = false) { echo "."; log_error("No config.xml found, attempting last known config restore."); file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", ""); ->>>>>>> master $last_backup = discover_last_backup(); if ($last_backup) restore_backup("/cf/conf/backup/{$last_backup}"); @@ -276,12 +246,8 @@ function parse_config_bootup() { restore_backup("/cf/conf/backup/{$last_backup}"); } if(!file_exists("{$g['conf_path']}/config.xml")) { -<<<<<<< HEAD echo sprintf(gettext("XML configuration file not found. %s cannot continue booting."), $g['product_name']) . "\n"; -======= - echo "XML configuration file not found. {$g['product_name']} cannot continue booting.\n"; unlock($lockkey); ->>>>>>> master mwexec("/sbin/halt"); exit; } @@ -345,23 +311,23 @@ function conf_mount_rw() { if (refcount_reference(1000) > 1) return; - $status = mwexec("/sbin/mount -u -w {$g['cf_path']}"); + $status = mwexec("/sbin/mount -u -w -o sync,noatime {$g['cf_path']}"); if($status <> 0) { if($g['booting']) echo gettext("Disk is dirty. Running fsck -y") . "\n"; mwexec("/sbin/fsck -y {$g['cf_path']}"); - $status = mwexec("/sbin/mount -u -w {$g['cf_path']}"); + $status = mwexec("/sbin/mount -u -w -o sync,noatime {$g['cf_path']}"); } /* if the platform is soekris or wrap or pfSense, lets mount the * compact flash cards root. */ - $status = mwexec("/sbin/mount -u -w /"); + $status = mwexec("/sbin/mount -u -w -o sync,noatime /"); /* we could not mount this correctly. kick off fsck */ if($status <> 0) { log_error(gettext("File system is dirty. Launching FSCK for /")); mwexec("/sbin/fsck -y /"); - $status = mwexec("/sbin/mount -u -w /"); + $status = mwexec("/sbin/mount -u -w -o sync,noatime /"); } mark_subsystem_dirty('mount'); @@ -389,8 +355,8 @@ function conf_mount_ro() { clear_subsystem_dirty('mount'); /* sync data, then force a remount of /cf */ pfSense_sync(); - mwexec("/sbin/mount -u -r -f {$g['cf_path']}"); - mwexec("/sbin/mount -u -r -f /"); + mwexec("/sbin/mount -u -r -f -o sync,noatime {$g['cf_path']}"); + mwexec("/sbin/mount -u -r -f -o sync,noatime /"); } /****f* config/convert_config @@ -446,14 +412,7 @@ function convert_config() { log_error(sprintf(gettext("Ended Configuration upgrade at %s"), $now)); if ($prev_version != $config['version']) -<<<<<<< HEAD write_config(sprintf(gettext('Upgraded config version level from %1$s to %2$s'), $prev_version, $config['version'])); - - if($g['booting']) - echo gettext("Loading new configuration..."); -======= - write_config("Upgraded config version level from {$prev_version} to {$config['version']}"); ->>>>>>> master } /****f* config/safe_write_file @@ -520,13 +479,12 @@ function write_config($desc="Unknown", $backup = true) { * for now, since it was preventing config saving. */ // $config = parse_config(true, false, false); -<<<<<<< HEAD - if($g['bootup']) - log_error(gettext("WARNING! Configuration written on bootup. This can cause stray openvpn and load balancing items in config.xml")); -======= + /* Comment this check out for now. There aren't any current issues that + * make this problematic, and it makes users think there is a problem + * when one doesn't really exist. if($g['booting']) log_error("WARNING! Configuration written on bootup. This can cause stray openvpn and load balancing items in config.xml"); ->>>>>>> master + */ $username = empty($_SESSION["Username"]) ? "(system)" : $_SESSION['Username']; diff --git a/etc/inc/dyndns.class b/etc/inc/dyndns.class index da8844e..dcde894 100644 --- a/etc/inc/dyndns.class +++ b/etc/inc/dyndns.class @@ -43,7 +43,7 @@ * ZoneEdit - Last Tested: NEVER * Dyns - Last Tested: NEVER * ODS - Last Tested: 02 August 2005 - * FreeDNS - Last Tested: NEVER + * FreeDNS - Last Tested: 23 Feb 2011 * Loopia - Last Tested: NEVER * StaticCling - Last Tested: 27 April 2006 * DNSexit - Last Tested: 20 July 2008 @@ -350,7 +350,7 @@ break; case 'freedns': $needIP = FALSE; - curl_setopt($ch, CURLOPT_URL, 'http://freedns.afraid.org/dynamic/update.php?' . $this->_dnsHost); + curl_setopt($ch, CURLOPT_URL, 'http://freedns.afraid.org/dynamic/update.php?' . $this->_dnsPass); $data = curl_exec($ch); if (@curl_error($ch)) log_error("Curl error occurred: " . curl_error($ch)); curl_close($ch); diff --git a/etc/inc/easyrule.inc b/etc/inc/easyrule.inc index 96864b1..0a6c703 100644 --- a/etc/inc/easyrule.inc +++ b/etc/inc/easyrule.inc @@ -46,7 +46,7 @@ function easyrule_find_rule_interface($int) { if ($config['pptpd']['mode'] == "server") $iflist['pptp'] = "PPTP VPN"; - if ($config['pppoe']['mode'] == "server") + if (is_pppoe_server_enabled() && have_ruleint_access("pppoe")) $iflist['pppoe'] = "PPPoE VPN"; if ($config['l2tp']['mode'] == "server") @@ -79,11 +79,12 @@ function easyrule_block_rule_exists($int = 'wan') { } /* Search through the rules for one referencing our alias */ - foreach ($config['filter']['rule'] as $rule) + foreach ($config['filter']['rule'] as $rule) { if (!is_array($rule) || !is_array($rule['source'])) continue; if ($rule['source']['address'] == $blockaliasname . strtoupper($int) && ($rule['interface'] == $int)) return true; + } return false; } @@ -114,7 +115,7 @@ function easyrule_block_rule_create($int = 'wan') { $filterent['destination']['any'] = ''; $filterent['descr'] = gettext("Easy Rule: Blocked from Firewall Log View"); - $a_filter[] = $filterent; + array_splice($a_filter, 0, 0, array($filterent)); return true; } diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc index 6de6425..64528e7 100644 --- a/etc/inc/filter.inc +++ b/etc/inc/filter.inc @@ -124,7 +124,7 @@ function filter_pflog_start() { } mute_kernel_msgs(); $output = 0; - exec("/bin/pgrep -f 'tcpdump -s 256 -v -l -n -e -ttt -i pflog0'", $output, $retval); + exec("/bin/pgrep -af 'tcpdump -s 256 -v -l -n -e -ttt -i pflog0'", $output, $retval); if($retval != 0) mwexec_bg("/usr/sbin/tcpdump -s 256 -v -l -n -e -ttt -i pflog0 | logger -t pf -p local0.info"); unmute_kernel_msgs(); @@ -522,8 +522,10 @@ function filter_generate_aliases() { $aliases .= "table <sshlockout> persist\n"; $aliases .= "table <webConfiguratorlockout> persist\n"; - $aliases .= "#Snort2C table\n"; + $aliases .= "#pfSnortSam tables\n"; $aliases .= "table <snort2c>\n"; + $aliases .= "table <pfSnortSamout>\n"; + $aliases .= "table <pfSnortSamin>\n"; $aliases .= "\ntable <virusprot>\n"; @@ -1122,14 +1124,22 @@ function filter_nat_rules_generate_if($if, $src = "any", $srcport = "", $dst = " if($src == "") $src = "any"; /* Match on this source port */ - if($srcport != "") - $src .= " port {$srcport}"; + if($srcport != "") { + $srcportexpand = alias_expand($srcport); + if(!$srcportexpand) + $srcportexpand = $srcport; + $src .= " port {$srcportexpand}"; + } /* sometimes this gets called with "" instead of a value */ if($dst == "") $dst = "any"; /* Match on this dest port */ - if($dstport != "") - $dst .= " port {$dstport}"; + if($dstport != "") { + $dstportexpand = alias_expand($dstport); + if(!$dstportexpand) + $dstportexpand = $dstport; + $dst .= " port {$dstportexpand}"; + } /* outgoing static-port option, hamachi, Grandstream, VOIP, etc */ $staticnatport_txt = ""; if($staticnatport) @@ -1232,11 +1242,14 @@ function filter_nat_rules_generate() { if(is_array($config['nat']['advancedoutbound']['rule'])) { foreach ($config['nat']['advancedoutbound']['rule'] as $obent) { update_filter_reload_status(sprintf(gettext("Creating advanced outbound rule %s"), $obent['descr'])); - $src = $obent['source']['network']; - if(isset($obent['destination']['not']) && !isset($obent['destination']['any'])) - $dst = "!" . $obent['destination']['address']; - else + $src = alias_expand($obent['source']['network']); + if(!$src) + $src = $obent['source']['network']; + $dst = alias_expand($obent['destination']['address']); + if(!$dst) $dst = $obent['destination']['address']; + if(isset($obent['destination']['not']) && !isset($obent['destination']['any'])) + $dst = "!" . $dst; if(!$obent['interface']) $natif = "wan"; else @@ -1339,6 +1352,7 @@ function filter_nat_rules_generate() { } } $natrules .= "\n# Subnets to NAT \n"; + $tonathosts .= "127.0.0.0/8 "; if($numberofnathosts > 4) { $natrules .= "table <tonatsubnets> { {$tonathosts} }\n"; $macroortable = "<tonatsubnets>"; @@ -1527,6 +1541,16 @@ function filter_nat_rules_generate() { else sigkillbypid("/var/run/inetd.pid", "HUP"); } + + if (isset($config['pptpd']['mode']) && ($config['pptpd']['mode'] != "off")) { + if ($config['pptpd']['mode'] == "redir") { + $pptpdtarget = $config['pptpd']['redir']; + $natrules .= "# PPTP\n"; + $natrules .= "rdr on \${$FilterIflist['wan']['descr']} proto gre from any to any -> {$pptpdtarget}\n"; + $natrules .= "rdr on \${$FilterIflist['wan']['descr']} proto tcp from any to any port 1723 -> {$pptpdtarget}\n"; + } + } + $natrules .= discover_pkg_rules("nat"); $natrules .= filter_process_carp_nat_rules(); @@ -1619,6 +1643,7 @@ function filter_generate_address(& $rule, $target = "source", $isnat = false) { $src = " {$not} {$expsrc}"; } + $rule['protocol'] = strtolower($rule['protocol']); if(in_array($rule['protocol'], array("tcp","udp","tcp/udp"))) { if($rule[$target]['port']) { $srcport = explode("-", $rule[$target]['port']); @@ -1704,7 +1729,7 @@ function filter_generate_user_rule($rule) { } update_filter_reload_status("Setting up pass/block rules"); $type = $rule['type']; - if($type != "pass" && $type != "block" && $type != "reject") { + if($type != "pass" && $type != "block" && $type != "reject" && $type != "match") { /* default (for older rules) is pass */ $type = "pass "; } @@ -1728,7 +1753,7 @@ function filter_generate_user_rule($rule) { update_filter_reload_status(sprintf(gettext("Setting up pass/block rules %s"), $rule['descr'])); /* do not process reply-to for gateway'd rules */ - if($rule['gateway'] == "" && $aline['direction'] <> "" && interface_has_gateway($rule['interface']) && !isset($rule['disablereplyto'])) { + if($rule['gateway'] == "" && $aline['direction'] <> "" && interface_has_gateway($rule['interface']) && !isset($config['system']['disablereplyto'])) { $rg = get_interface_gateway($rule['interface']); if(is_ipaddr($rg)) { $aline['reply'] = "reply-to ( {$ifcfg['if']} {$rg} ) "; @@ -1744,10 +1769,10 @@ function filter_generate_user_rule($rule) { /* Add the load balanced gateways */ $aline['route'] = " \$GW{$rule['gateway']} "; else - log_error(sprintf(gettext("The gateway: %s is invalid/unkown not using it."), $rule['gateway'])); + log_error("The gateway: {$rule['gateway']} is invalid or unknown, not using it."); } - if(isset($rule['protocol'])) { + if (isset($rule['protocol']) && !empty($rule['protocol'])) { if($rule['protocol'] == "tcp/udp") $aline['prot'] = " proto { tcp udp } "; elseif($rule['protocol'] == "icmp") @@ -2006,9 +2031,11 @@ EOD; $ipfrules .= <<<EOD -# snort2c +# pfSnortSam block quick from <snort2c> to any label "Block snort2c hosts" block quick from any to <snort2c> label "Block snort2c hosts" +block quick from <pfSnortSamout> to any label "Block pfSnortSamOut hosts" +block quick from any to <pfSnortSamin> label "Block pfSnortSamIn hosts" EOD; @@ -2157,6 +2184,15 @@ pass in on \${$oc['descr']} proto udp from any port = 68 to {$oc['ip']} port = 6 pass out on \${$oc['descr']} proto udp from {$oc['ip']} port = 67 to any port = 68 label "allow access to DHCP server" EOD; + if($config['dhcpd'][$on]['failover_peerip'] <> "") { + $ipfrules .= <<<EOD +# allow access to DHCP failover on {$oc['descr']} from {$config['dhcpd'][$on]['failover_peerip']} +pass in on \${$oc['descr']} proto udp from {$config['dhcpd'][$on]['failover_peerip']} to {$oc['ip']} port = 519 label "allow access to DHCP failover" +pass in on \${$oc['descr']} proto udp from {$config['dhcpd'][$on]['failover_peerip']} to {$oc['ip']} port = 520 label "allow access to DHCP failover" + +EOD; + } + } break; } @@ -2327,10 +2363,37 @@ EOD; $ipfrules .= <<<EOD anchor "tftp-proxy/*" +EOD; + + update_filter_reload_status("Creating uPNP rules..."); + if(isset($config['installedpackages']['miniupnpd']['config'][0]['enable'])) { + + $ipfrules .= <<<EOD # uPnPd anchor "miniupnpd" EOD; + + $upnp_interfaces = explode(",", $config['installedpackages']['miniupnpd'][0]['config']['iface_array']); + foreach($upnp_interfaces as $upnp_if) { + if(is_array($FilterIflist[$upnp_if])) { + $oc = $FilterIflist[$upnp_if]; + if($oc['ip']) { + $sa = $oc['sa']; + $sn = $oc['sn']; + $if = $oc['if']; + } + if($sa) { + $ipfrules .= <<<EOD + +pass in on \${$oc['descr']} proto tcp from {$sa}/{$sn} to 239.255.255.250/32 port 1900 keep state label "pass multicast traffic to miniupnpd" + +EOD; + } + } + } + } + return $ipfrules; } @@ -2570,16 +2633,11 @@ function filter_setup_logging_interfaces() { echo "filter_setup_logging_interfaces() being called $mt\n"; } $rules = ""; - foreach ($FilterIflist as $ifdescr => $ifcfg) { - /* - * XXX: This should be cleared out after a discussion - * between pf(4) devs is cleared out. This breaks - * compatibility with OpenBSD. - */ - if(isset($ifcfg['virtual'])) - continue; - $rules .= "set loginterface {$ifcfg['if']}\n"; - } + if (isset($FilterIflist['lan'])) + $rules .= "set loginterface {$FilterIflist['lan']['if']}\n"; + else if (isset($FilterIflist['wan'])) + $rules .= "set loginterface {$FilterIflist['wan']['if']}\n"; + return $rules; } diff --git a/etc/inc/globals.inc b/etc/inc/globals.inc index 6f64478..21460c5 100644 --- a/etc/inc/globals.inc +++ b/etc/inc/globals.inc @@ -88,10 +88,12 @@ $g = array( "disablethemeselection" => false, "disablehelpmenu" => false, "disablehelpicon" => false, + "disablecrashreporter" => false, + "crashreporterurl" => "http://crashreporter.pfsense.org/crash_reporter.php", "debug" => false, - "latest_config" => "7.6", + "latest_config" => "7.7", "nopkg_platforms" => array("cdrom"), - "minimum_ram_warning" => "105", + "minimum_ram_warning" => "101", "minimum_ram_warning_text" => "128 MB", "minimum_nic_count" => "1", "minimum_nic_count_text" => "*AT LEAST* 1", diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index 60201bd..e678b3b 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -1143,7 +1143,14 @@ function handle_pppoe_reset($post_array) { function interface_ppps_configure($interface) { global $config, $g; - + + /* Return for unassigned interfaces. This is a minimum requirement. */ + if (empty($config['interfaces'][$interface])) + return 0; + $ifcfg = $config['interfaces'][$interface]; + if (!isset($ifcfg['enable'])) + return 0; + // mpd5 requires a /var/spool/lock directory for PPP modem links. if(!is_dir("/var/spool/lock")) { exec("/bin/mkdir -p /var/spool/lock"); @@ -1152,10 +1159,7 @@ function interface_ppps_configure($interface) { // mpd5 modem chat script expected in the same directory as the mpd_xxx.conf files if (!file_exists("{$g['varetc_path']}/mpd.script")) mwexec("/bin/ln -s /usr/local/sbin/mpd.script {$g['varetc_path']}/."); - - $ifcfg = $config['interfaces'][$interface]; - if (!isset($ifcfg['enable'])) - return 0; + if (is_array($config['ppps']['ppp']) && count($config['ppps']['ppp'])) { foreach ($config['ppps']['ppp'] as $pppid => $ppp) { if ($ifcfg['if'] == $ppp['if']) @@ -1172,7 +1176,7 @@ function interface_ppps_configure($interface) { else $type = $ppp['type']; $upper_type = strtoupper($ppp['type']); - + if($g['booting']) { $descr = isset($ifcfg['descr']) ? $ifcfg['descr'] : strtoupper($interface); echo "starting {$pppif} link..."; @@ -1180,7 +1184,7 @@ function interface_ppps_configure($interface) { if(file_exists("{$g['varrun_path']}/{$ppp['type']}_{$interface}.pid")) return 0; } - + $ports = explode(',',$ppp['ports']); if ($type != "modem") { foreach ($ports as $pid => $port) @@ -1189,10 +1193,10 @@ function interface_ppps_configure($interface) { $localips = explode(',',$ppp['localip']); $gateways = explode(',',$ppp['gateway']); $subnets = explode(',',$ppp['subnet']); - + /* We bring up the parent interface first because if DHCP is configured on the parent we need - to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs - */ + * to obtain an address first so we can write it in the mpd .conf file for PPTP and L2TP configs + */ foreach($ports as $pid => $port){ switch ($ppp['type']) { case "pppoe": @@ -2469,7 +2473,7 @@ function kill_wpasupplicant($interface) { function find_dhclient_process($interface) { if ($interface) - $pid = `/bin/pgrep -xf "dhclient: {$interface}"`; + $pid = `/bin/pgrep -axf "dhclient: {$interface}"`; else $pid = 0; @@ -3480,8 +3484,8 @@ function is_altq_capable($int) { * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+7.2-current&format=html * Only the following drivers have ALTQ support */ - $capable = array("age", "ale", "an", "ath", "aue", "awi", "bce", - "bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem", + $capable = array("age", "alc", "ale", "an", "ath", "aue", "awi", "bce", + "bfe", "bge", "bridge", "cas", "dc", "de", "ed", "em", "ep", "fxp", "gem", "hme", "igb", "ipw", "iwi", "jme", "le", "lem", "msk", "mxge", "my", "nfe", "npe", "nve", "ral", "re", "rl", "rum", "run", "bwn", "sf", "sis", "sk", "ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl", diff --git a/etc/inc/ipsec.inc b/etc/inc/ipsec.inc index 109bf18..6040de6 100644 --- a/etc/inc/ipsec.inc +++ b/etc/inc/ipsec.inc @@ -143,11 +143,13 @@ function ipsec_get_phase1_src(& $ph1ent) { * Return phase1 local address */ function ipsec_get_phase1_dst(& $ph1ent) { + global $g; $rg = $ph1ent['remote-gateway']; - if (!is_ipaddr($rg)) - return resolve_retry($rg); - + if (!is_ipaddr($rg)) { + if(! $g['booting']) + return resolve_retry($rg); + } if(!is_ipaddr($rg)) return false; diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc index 9101c04..1d9b9b0 100644 --- a/etc/inc/openvpn.inc +++ b/etc/inc/openvpn.inc @@ -228,9 +228,9 @@ function openvpn_add_dhcpopts(& $settings, & $conf) { $conf .= "push \"dhcp-option DNS {$settings['dns_server4']}\"\n"; if (!empty($settings['ntp_server1'])) - $conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n"; + $conf .= "push \"dhcp-option NTP {$settings['ntp_server1']}\"\n"; if (!empty($settings['ntp_server2'])) - $conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n"; + $conf .= "push \"dhcp-option NTP {$settings['ntp_server2']}\"\n"; if ($settings['netbios_enable']) { diff --git a/etc/inc/pfsense-utils.inc b/etc/inc/pfsense-utils.inc index b6755c8..a352cf2 100644 --- a/etc/inc/pfsense-utils.inc +++ b/etc/inc/pfsense-utils.inc @@ -1039,6 +1039,22 @@ function is_dhcp_server_enabled() return $dhcpdenable; } +/* Any PPPoE servers enabled? */ +function is_pppoe_server_enabled() { + global $config; + + $pppoeenable = false; + + if (!is_array($config['pppoes']) || !is_array($config['pppoes']['pppoe'])) + return false; + + foreach ($config['pppoes']['pppoe'] as $pppoes) + if ($pppoes['mode'] == 'server') + $pppoeenable = true; + + return $pppoeenable; +} + function convert_seconds_to_hms($sec){ $min=$hrs=0; if ($sec != 0){ @@ -1413,7 +1429,7 @@ function get_freebsd_version() { return $version[0]; } -function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') { +function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body', $connect_timeout=60, $timeout=0) { global $ch, $fout, $file_size, $downloaded; $file_size = 1; $downloaded = 1; @@ -1433,10 +1449,10 @@ function download_file_with_progress_bar($url_file, $destination_file, $readbody curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody); curl_setopt($ch, CURLOPT_NOPROGRESS, '1'); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '60'); - curl_setopt($ch, CURLOPT_TIMEOUT, 0); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout); + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); - curl_exec($ch); + @curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if($fout) fclose($fout); @@ -1548,29 +1564,39 @@ if(!function_exists("split")) { } } -function update_alias_names_upon_change($section, $subsection, $fielda, $fieldb, $new_alias_name, $origname) { +function update_alias_names_upon_change($section, $field, $new_alias_name, $origname) { global $g, $config, $pconfig, $debug; if(!$origname) return; + $sectionref = &$config; + foreach($section as $sectionname) { + if(is_array($sectionref) && isset($sectionref[$sectionname])) + $sectionref = &$sectionref[$sectionname]; + else + return; + } + if($debug) $fd = fopen("{$g['tmp_path']}/print_r", "a"); if($debug) fwrite($fd, print_r($pconfig, true)); - if($fieldb) { - if($debug) fwrite($fd, sprintf(gettext("fieldb exists%s"), "\n")); - for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) { - if($debug) fwrite($fd, "$i\n"); - if($config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] == $origname) { - if($debug) fwrite($fd, sprintf(gettext('Setting old alias value %1$s to %2$s%3$s'), $origname, $new_alias_name, "\n")); - $config["$section"]["$subsection"][$i]["$fielda"]["$fieldb"] = $new_alias_name; + if(is_array($sectionref)) { + foreach($sectionref as $itemkey => $item) { + if($debug) fwrite($fd, "$itemkey\n"); + + $fieldfound = true; + $fieldref = &$sectionref[$itemkey]; + foreach($field as $fieldname) { + if(is_array($fieldref) && isset($fieldref[$fieldname])) + $fieldref = &$fieldref[$fieldname]; + else { + $fieldfound = false; + break; + } } - } - } else { - if($debug) fwrite($fd, "fieldb does not exist\n"); - for ($i = 0; isset($config["$section"]["$subsection"][$i]["$fielda"]); $i++) { - if($config["$section"]["$subsection"][$i]["$fielda"] == $origname) { - $config["$section"]["$subsection"][$i]["$fielda"] = $new_alias_name; - if($debug) fwrite($fd, sprintf(gettext('Setting old alias value %1$s to %2$s%3$s'), $origname, $new_alias_name, "\n")); + if($fieldfound && $fieldref == $origname) { + if($debug) fwrite($fd, "Setting old alias value $origname to $new_alias_name\n"); + $fieldref = $new_alias_name; } } } @@ -1674,9 +1700,9 @@ function version_compare_dates($a, $b) { if ((!$a_time) || (!$b_time)) { return FALSE; } else { - if ($a < $b) + if ($a_time < $b_time) return -1; - elseif ($a == $b) + elseif ($$a_time == $b_time) return 0; else return 1; @@ -1735,7 +1761,7 @@ function version_compare_numeric($a, $b) { } function pfs_version_compare($cur_time, $cur_text, $remote) { // First try date compare - $v = version_compare_dates($cur_time, $b); + $v = version_compare_dates($cur_time, $remote); if ($v === FALSE) { // If that fails, try to compare by string // Before anything else, simply test if the strings are equal diff --git a/etc/inc/pkg-utils.inc b/etc/inc/pkg-utils.inc index eb54b6d..1535e8a 100644 --- a/etc/inc/pkg-utils.inc +++ b/etc/inc/pkg-utils.inc @@ -451,6 +451,17 @@ function sync_package($pkg_name, $sync_depends = true, $show_message = false) { function pkg_fetch_recursive($pkgname, $filename, $dependlevel = 0, $base_url = "") { global $static_output, $g; + if (($g['platform'] == "nanobsd") || ($g['platform'] == "embedded")) { + $pkgtmpdir = "/usr/bin/env PKG_TMPDIR=/root/ "; + $pkgstagingdir = "/root/tmp"; + if (!is_dir($pkgstagingdir)) + mkdir($pkgstagingdir); + $pkgstaging = "-t {$pkgstagingdir}/instmp.XXXXXX"; + $fetchdir = $pkgstagingdir; + } else { + $fetchdir = $g['tmp_path']; + } + $osname = php_uname("s"); $arch = php_uname("m"); $rel = strtolower(php_uname("r")); @@ -461,7 +472,7 @@ function pkg_fetch_recursive($pkgname, $filename, $dependlevel = 0, $base_url = $base_url = $priv_url; if (substr($base_url, -1) == "/") $base_url = substr($base_url, 0, -1); - $fetchto = "{$g['tmp_path']}/apkg_{$filename}"; + $fetchto = "{$fetchdir}/apkg_{$filename}"; $static_output .= "\n" . str_repeat(" ", $dependlevel * 2 + 1) . "Downloading {$base_url}/{$filename} ... "; if (download_file_with_progress_bar("{$base_url}/{$filename}", $fetchto) !== true) { if ($base_url != $priv_url && download_file_with_progress_bar("{$priv_url}/{$filename}", $fetchto) !== true) { @@ -498,8 +509,9 @@ function pkg_fetch_recursive($pkgname, $filename, $dependlevel = 0, $base_url = } } } + $pkgaddout = ""; - exec("/usr/sbin/pkg_add -fv {$fetchto} 2>&1", $pkgaddout); + exec("{$pkgtmpdir}/usr/sbin/pkg_add {$pkgstaging} -fv {$fetchto} 2>&1", $pkgaddout); pkg_debug($pkgname . " " . print_r($pkgaddout, true) . "\npkg_add successfully completed.\n"); return true; @@ -580,7 +592,6 @@ function install_package($package, $pkg_info = "") { write_config($changedesc); $static_output .= gettext("done.") . "\n"; update_output_window($static_output); - $static_output .= gettext("Starting service.") . "\n"; update_output_window($static_output); if($pkg_info['after_install_info']) update_output_window($pkg_info['after_install_info']); @@ -1140,6 +1151,8 @@ function squash_from_bytes($size, $round = "") { function pkg_reinstall_all() { global $g, $config; + + @unlink('/conf/needs_package_sync'); $pkg_id = 0; $todo = array(); if (is_array($config['installedpackages']['package'])) diff --git a/etc/inc/priv.defs.inc b/etc/inc/priv.defs.inc index f16603f..81eda0d 100644 --- a/etc/inc/priv.defs.inc +++ b/etc/inc/priv.defs.inc @@ -325,6 +325,12 @@ $priv_list['page-status-systemlogs-ppp']['match'] = array(); $priv_list['page-status-systemlogs-ppp']['match'][] = "diag_logs_ppp.php*"; $priv_list['page-diagnostics-nanobsd'] = array(); +$priv_list['page-diagnostics-nanobsd']['name'] = gettext("WebCfg - Diagnostics: Edit file"); +$priv_list['page-diagnostics-nanobsd']['descr'] = gettext("Allow access to the 'Diagnostics: Edit File' page."); +$priv_list['page-diagnostics-nanobsd']['match'] = array(); +$priv_list['page-diagnostics-nanobsd']['match'][] = "edit.php*"; + +$priv_list['page-diagnostics-nanobsd'] = array(); $priv_list['page-diagnostics-nanobsd']['name'] = gettext("WebCfg - Diagnostics: NanoBSD"); $priv_list['page-diagnostics-nanobsd']['descr'] = gettext("Allow access to the 'Diagnostics: NanoBSD' page."); $priv_list['page-diagnostics-nanobsd']['match'] = array(); @@ -342,6 +348,12 @@ $priv_list['page-diagnostics-cpuutilization']['descr'] = gettext("Allow access t $priv_list['page-diagnostics-cpuutilization']['match'] = array(); $priv_list['page-diagnostics-cpuutilization']['match'][] = "graph_cpu.php*"; +$priv_list['page-diagnostics-cpuutilization'] = array(); +$priv_list['page-diagnostics-cpuutilization']['name'] = "WebCfg - XMLRPC CPU Utilization page"; +$priv_list['page-diagnostics-cpuutilization']['descr'] = "Allow access to the 'XMLRPC CPU Utilization' page."; +$priv_list['page-diagnostics-cpuutilization']['match'] = array(); +$priv_list['page-diagnostics-cpuutilization']['match'][] = "stats.php*"; + $priv_list['page-diagnostics-haltsystem'] = array(); $priv_list['page-diagnostics-haltsystem']['name'] = gettext("WebCfg - Diagnostics: Halt system page"); $priv_list['page-diagnostics-haltsystem']['descr'] = gettext("Allow access to the 'Diagnostics: Halt system' page."); diff --git a/etc/inc/rrd.inc b/etc/inc/rrd.inc index e928fc8..35c461c 100644 --- a/etc/inc/rrd.inc +++ b/etc/inc/rrd.inc @@ -298,9 +298,12 @@ function enable_rrd_graphing() { $rrdupdatesh .= "\n"; $rrdupdatesh .= "# polling traffic for interface $ifname $realif \n"; - $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\\\n"; - $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$6 \":\"}'`\\\n"; - $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n"; + $rrdupdatesh .= "TMPFILE=`mktemp -q /tmp/STATS_{$realif}.XXXXXX` \n"; + $rrdupdatesh .= "$pfctl -vvsI -i {$realif} > \$TMPFILE \n"; + $rrdupdatesh .= "unset BYTES \n"; + $rrdupdatesh .= "BYTES=`cat \$TMPFILE | awk '/In4\/Pass|Out4\/Pass/ {printf \$6 \":\"}'`\\\n"; + $rrdupdatesh .= "`cat \$TMPFILE | awk '/In4\/Block|Out4\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n"; + $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\$BYTES\n"; /* PACKETS, set up the rrd file */ if (!file_exists("$rrddbpath$ifname$packets")) { @@ -324,9 +327,11 @@ function enable_rrd_graphing() { $rrdupdatesh .= "\n"; $rrdupdatesh .= "# polling packets for interface $ifname $realif \n"; - $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n"; - $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$4 \":\"}'`\\\n"; - $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n"; + $rrdupdatesh .= "unset PACKETS \n"; + $rrdupdatesh .= "PACKETS=`cat \$TMPFILE | awk '/In4\/Pass|Out4\/Pass/ {printf \$4 \":\"}'`\\\n"; + $rrdupdatesh .= "`cat \$TMPFILE | awk '/In4\/Block|Out4\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n"; + $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\$PACKETS\n"; + $rrdupdatesh .= "rm \$TMPFILE \n"; /* WIRELESS, set up the rrd file */ if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") { @@ -769,6 +774,8 @@ function enable_rrd_graphing() { } function kill_traffic_collector() { + mwexec("killall top", true); + mwexec("killall rrdtool", true); mwexec("/bin/pkill -f updaterrd.sh", true); } diff --git a/etc/inc/service-utils.inc b/etc/inc/service-utils.inc index 3588953..895eb57 100644 --- a/etc/inc/service-utils.inc +++ b/etc/inc/service-utils.inc @@ -34,7 +34,7 @@ */ /* - pfSense_BUILDER_BINARIES: /bin/pkill /bin/pgrep /bin/sh /usr/bin/killall + pfSense_BUILDER_BINARIES: /bin/pgrep /bin/sh /usr/bin/killall pfSense_MODULE: utils */ @@ -207,4 +207,4 @@ function is_service_running($service, $ps = "") { return false; } -?>
\ No newline at end of file +?> diff --git a/etc/inc/services.inc b/etc/inc/services.inc index 3c23ece..77846d7 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -32,7 +32,7 @@ */ /* - pfSense_BUILDER_BINARIES: /usr/bin/killall /bin/sh /usr/local/sbin/dhcpd /usr/local/sbin/igmpproxy + pfSense_BUILDER_BINARIES: /usr/bin/killall /bin/pgrep /bin/sh /usr/local/sbin/dhcpd /usr/local/sbin/igmpproxy pfSense_BUILDER_BINARIES: /sbin/ifconfig /usr/sbin/arp /sbin/ifconfig /usr/local/sbin/dnsmasq pfSense_BUILDER_BINARIES: /usr/sbin/bsnmpd /sbin/route /usr/local/sbin/olsrd pfSense_BUILDER_BINARIES: /usr/local/sbin/miniupnpd @@ -1308,7 +1308,7 @@ function upnp_action ($action) { mwexec_bg('/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf'); break; case "stop": - while((int)exec("pgrep miniupnpd | wc -l") > 0) + while((int)exec("/bin/pgrep -a miniupnpd | wc -l") > 0) mwexec('killall miniupnpd 2>/dev/null', true); mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null'); mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null'); @@ -1321,21 +1321,16 @@ function upnp_action ($action) { } function upnp_start() { - global $config, $g; + global $config; if(!isset($config['installedpackages']['miniupnpd']['config'])) return; if($config['installedpackages']['miniupnpd']['config'][0]['enable']) { - if($g['booting']) { - echo gettext("Starting UPnP service... "); - require_once('/usr/local/pkg/miniupnpd.inc'); - sync_package_miniupnpd(); - echo gettext("done.") . "\n"; - } - else { - upnp_action('start'); - } + echo gettext("Starting UPnP service... "); + require_once('/usr/local/pkg/miniupnpd.inc'); + sync_package_miniupnpd(); + echo "done.\n"; } } diff --git a/etc/inc/shaper.inc b/etc/inc/shaper.inc index bc4a0c2..c410495 100644 --- a/etc/inc/shaper.inc +++ b/etc/inc/shaper.inc @@ -560,16 +560,16 @@ class altq_root_queue { function build_javascript() { $javascript = "<script type=\"text/javascript\">"; $javascript .= "function mySuspend() {"; - $javascript .= "if (document.layers && document.layers['shaperarea'] != null);"; - $javascript .= "document.layers['shaperarea'].visibility = 'hidden';"; + $javascript .= "if (document.layers && document.layers['shaperarea'] != null) "; + $javascript .= "document.layers['shaperarea'].visibility = 'hidden'; "; $javascript .= "else if (document.all)"; $javascript .= "document.all['shaperarea'].style.visibility = 'hidden';"; $javascript .= "}"; $javascript .= "function myResume() {"; - $javascript .= "if (document.layers && document.layers['shaperarea'] != null)"; + $javascript .= "if (document.layers && document.layers['shaperarea'] != null) "; $javascript .= "document.layers['shaperarea'].visibility = 'visible';"; - $javascript .= "else if (document.all)"; + $javascript .= "else if (document.all) "; $javascript .= "document.all['shaperarea'].style.visibility = 'visible';"; $javascript .= "}"; $javascript .= "</script>"; @@ -858,7 +858,7 @@ class priq_queue { function build_javascript() { $javascript = "<script type=\"text/javascript\">"; $javascript .= "function mySuspend() { \n"; - $javascript .= "if (document.layers && document.layers['shaperarea'] != null);\n"; + $javascript .= "if (document.layers && document.layers['shaperarea'] != null)\n"; $javascript .= "document.layers['shaperarea'].visibility = 'hidden';\n"; $javascript .= "else if (document.all)\n"; $javascript .= "document.all['shaperarea'].style.visibility = 'hidden';\n"; @@ -967,8 +967,12 @@ class priq_queue { } function ReadConfig(&$q) { - if (isset($q['name'])) - $this->SetQname($q['name']); + if (!empty($q['name']) && !empty($q['newname']) && $q['name'] != $q['newname']) { + $this->SetQname($q['newname']); + } else if (!empty($q['newname'])) { + $this->SetQname($q['newname']); + } else if (isset($q['name'])) + $this->SetQname($q['name']); if (isset($q['interface'])) $this->SetInterface($q['interface']); $this->SetBandwidth($q['bandwidth']); @@ -1100,7 +1104,10 @@ class priq_queue { $form .= "<tr>"; $form .= "<td width=\"22%\" valign=\"center\" class=\"vncellreq\">"; $form .= gettext("Queue Name") . "</td><td width=\"78%\" class=\"vtable\">"; - $form .= "<input name=\"name\" type=\"text\" id=\"name\" class=\"formfld unknown\" size=\"15\" maxlength=\"15\" value=\""; + $form .= "<input name=\"newname\" type=\"text\" id=\"newname\" class=\"formfld unknown\" size=\"15\" maxlength=\"15\" value=\""; + $form .= htmlspecialchars($this->GetQname()); + $form .= "\">"; + $form .= "<input name=\"name\" type=\"hidden\" id=\"name\" class=\"formfld unknown\" size=\"15\" maxlength=\"15\" value=\""; $form .= htmlspecialchars($this->GetQname()); $form .= "\">"; $form .= "<br /> <span class=\"vexpl\">" . gettext("Enter the name of the queue here. Do not use spaces and limit the size to 15 characters."); @@ -2877,7 +2884,13 @@ class dnpipe_class extends dummynet_class { } function ReadConfig(&$q) { - $this->SetQname($q['name']); + if (!empty($q['name']) && !empty($q['newname']) && $q['name'] != $q['newname']) { + $this->SetQname($q['newname']); + } else if (!empty($q['newname'])) { + $this->SetQname($q['newname']); + } else { + $this->SetQname($q['name']); + } $this->SetNumber($q['number']); if (isset($q['bandwidth']) && $q['bandwidth'] <> "") { $this->SetBandwidth($q['bandwidth']); @@ -2983,7 +2996,9 @@ class dnpipe_class extends dummynet_class { $form .= "</td></tr>"; $form .= "<tr><td valign=\"center\" class=\"vncellreq\"><br><span class=\"vexpl\">" . gettext("Name") . "</span></td>"; $form .= "<td class=\"vncellreq\">"; - $form .= "<input type=\"text\" id=\"name\" name=\"name\" value=\""; + $form .= "<input type=\"text\" id=\"newname\" name=\"newname\" value=\""; + $form .= $this->GetQname()."\">"; + $form .= "<input type=\"hidden\" id=\"name\" name=\"name\" value=\""; $form .= $this->GetQname()."\">"; $form .= "</td></tr>"; $form .= "<tr><td valign=\"center\" class=\"vncellreq\">" . gettext("Bandwidth"); @@ -3163,7 +3178,13 @@ class dnqueue_class extends dummynet_class { } function ReadConfig(&$q) { - $this->SetQname($q['name']); + if (!empty($q['name']) && !empty($q['newname']) && $q['name'] != $q['newname']) { + $this->SetQname($q['newname']); + } else if (!empty($q['newname'])) { + $this->SetQname($q['newname']); + } else { + $this->SetQname($q['name']); + } $this->SetNumber($q['number']); if (isset($q['qlimit']) && $q['qlimit'] <> "") $this->SetQlimit($q['qlimit']); @@ -3235,7 +3256,9 @@ class dnqueue_class extends dummynet_class { $form .= "</td></tr>"; $form .= "<tr><td valign=\"center\" class=\"vncellreq\"><br><span class=\"vexpl\">" . gettext("Name") . "</span></td>"; $form .= "<td class=\"vncellreq\">"; - $form .= "<input type=\"text\" id=\"name\" name=\"name\" value=\""; + $form .= "<input type=\"text\" id=\"newname\" name=\"newname\" value=\""; + $form .= $this->GetQname()."\">"; + $form .= "<input type=\"hidden\" id=\"name\" name=\"name\" value=\""; $form .= $this->GetQname()."\">"; $form .= "</td></tr>"; $form .= "<tr><td valign=\"center\" class=\"vncellreq\">" . gettext("Mask") . "</td>"; diff --git a/etc/inc/upgrade_config.inc b/etc/inc/upgrade_config.inc index c7c29c8..7536f8c 100644 --- a/etc/inc/upgrade_config.inc +++ b/etc/inc/upgrade_config.inc @@ -584,7 +584,7 @@ function upgrade_039_to_040() { $config['system']['group'][0]['name'] = "admins"; $config['system']['group'][0]['description'] = gettext("System Administrators"); $config['system']['group'][0]['scope'] = "system"; - $config['system']['group'][0]['pages'] = "ANY"; + $config['system']['group'][0]['priv'] = "page-all"; $config['system']['group'][0]['home'] = "index.php"; $config['system']['group'][0]['gid'] = "110"; @@ -820,15 +820,18 @@ function upgrade_044_to_045() { global $config; $iflist = get_configured_interface_list(false, true); if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) { + $i = 0; foreach ($config['vlans']['vlan'] as $id => $vlan) { - $config['vlans']['vlan'][$id]['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}"; /* Make sure to update the interfaces section with the right name */ + $vlan_name = "{$vlan['if']}_vlan{$vlan['tag']}"; foreach($iflist as $ifname) { - if($config['interfaces'][$ifname]['if'] == "vlan{$id}") { - $config['interfaces'][$ifname]['if'] = $vlan['vlanif']; + if($config['interfaces'][$ifname]['if'] == "vlan{$i}") { + $config['interfaces'][$ifname]['if'] = $vlan_name; + continue; } } - + $config['vlans']['vlan'][$i]['vlanif'] = "{$vlan_name}"; + $i++; } } } @@ -869,6 +872,8 @@ function upgrade_045_to_046() { if(count($config['load_balancer']) == 0) { unset($config['load_balancer']); } + mwexec('/usr/sbin/pw groupadd -n _relayd -g 913'); + mwexec('/usr/sbin/pw useradd -n _relayd -c "Relay Daemon" -d /var/empty -s /usr/sbin/nologin -u 913 -g 913'); } @@ -917,6 +922,11 @@ function upgrade_046_to_047() { if (isset($tunnel['disabled'])) $ph1ent['disabled'] = $tunnel['disabled']; + /* convert to the new vip[$vhid] name */ + if(preg_match("/^carp/", $tunnel['interface'])) { + $carpid = str_replace("carp", "", $tunnel['interface']); + $tunnel['interface'] = "vip" . $config['virtualip']['vip'][$carpid]['vhid']; + } $ph1ent['interface'] = $tunnel['interface']; $ph1ent['remote-gateway'] = $tunnel['remote-gateway']; $ph1ent['descr'] = $tunnel['descr']; @@ -1681,7 +1691,7 @@ function upgrade_053_to_054() { } else { $i = 1; } - $gateway_group['item'][] = "$interface|$i"; + $gateway_group['item'][] = "$static_name|$i"; } $gateway_group_arr[] = $gateway_group; } else { @@ -2206,18 +2216,16 @@ function upgrade_069_to_070() { /* Convert NAT 1:1 rules */ if (is_array($config['nat']['onetoone'])) { - $a_nat = &$config['nat']['onetoone']; - - foreach ($a_nat as &$natent) { + foreach ($config['nat']['onetoone'] as $nidx => $natent) { if ($natent['subnet'] == 32) - $natent['source'] = array("address" => $natent['internal']); + $config['nat']['onetoone'][$nidx]['source'] = array("address" => $natent['internal']); else - $natent['source'] = array("address" => $natent['internal'] . "/" . $natent['subnet']); + $config['nat']['onetoone'][$nidx]['source'] = array("address" => $natent['internal'] . "/" . $natent['subnet']); - $natent['destination'] = array("any" => true); + $config['nat']['onetoone'][$nidx]['destination'] = array("any" => true); - unset($natent['internal']); - unset($natent['subnet']); + unset($config['nat']['onetoone'][$nidx]['internal']); + unset($config['nat']['onetoone'][$nidx]['subnet']); } unset($natent); @@ -2298,4 +2306,12 @@ function upgrade_075_to_076() { $config['cron']['item'][] = $cron_item; } +function upgrade_076_to_077() { + global $config; + foreach($config['filter']['rule'] as & $rule) { + if (isset($rule['protocol']) && !empty($rule['protocol'])) + $rule['protocol'] = strtolower($rule['protocol']); + } +} + ?> diff --git a/etc/inc/util.inc b/etc/inc/util.inc index 507e32c..c1a57cf 100644 --- a/etc/inc/util.inc +++ b/etc/inc/util.inc @@ -50,7 +50,7 @@ function isvalidpid($pid) { function is_process_running($process) { $output = ""; - exec("/bin/pgrep -x {$process}", $output, $retval); + exec("/bin/pgrep -ax {$process}", $output, $retval); return (intval($retval) == 0); } @@ -463,7 +463,7 @@ function is_domain($domain) { /* returns true if $macaddr is a valid MAC address */ function is_macaddr($macaddr) { - return preg_match('/^[0-9A-F]{2}(?=([:]?))(?:\\1[0-9A-F]{2}){5}$/i', $macaddr) == 1 ? true : false; + return preg_match('/^[0-9A-F]{2}(?:[:][0-9A-F]{2}){5}$/i', $macaddr) == 1 ? true : false; } /* returns true if $name is a valid name for an alias */ diff --git a/etc/inc/voucher.inc b/etc/inc/voucher.inc index 74d83d9..cb13770 100644 --- a/etc/inc/voucher.inc +++ b/etc/inc/voucher.inc @@ -100,11 +100,11 @@ EOF; function voucher_auth($voucher_received, $test = 0) { global $g, $config; - $voucherlck = lock('voucher'); + $voucherlck = lock('voucher', LOCK_EX); // XMLRPC Call over to the master Voucher node $a_voucher = &$config['voucher']; - if($a_voucher['vouchersyncdbip']) { + if(!empty($a_voucher['vouchersyncdbip'])) { $syncip = $a_voucher['vouchersyncdbip']; $syncport = $a_voucher['vouchersyncport']; $syncpass = $a_voucher['vouchersyncpass']; @@ -154,10 +154,10 @@ function voucher_auth($voucher_received, $test = 0) { if (!isset($active_vouchers[$roll])) $active_vouchers[$roll] = voucher_read_active_db($roll); // valid voucher. Store roll# and ticket# - if ($line = $active_vouchers[$roll][$voucher]) { - list($timestamp,$minutes) = explode(",", $line); + if (!empty($active_vouchers[$roll][$voucher])) { + list($timestamp,$minutes) = explode(",", $active_vouchers[$roll][$voucher]); // we have an already active voucher here. - $remaining = intval((($timestamp + 60*$minutes) - time())/60); + $remaining = intval((($timestamp + (60*$minutes)) - time())/60); $test_result[] = sprintf(gettext('%1$s (%2$s/%3$s) active and good for %4$d Minutes'), $voucher, $roll, $nr, $remaining); $total_minutes += $remaining; } else { @@ -215,7 +215,7 @@ function voucher_auth($voucher_received, $test = 0) { } // If we did a XMLRPC sync earlier check the timeleft - if($a_voucher['vouchersyncdbip']) + if(!empty($a_voucher['vouchersyncdbip'])) if($remote_time_used['timeleft'] < $total_minutes) $total_minutes = $remote_time_used['timeleft']; @@ -238,8 +238,8 @@ function voucher_auth($voucher_received, $test = 0) { // log in later using just the first voucher. It also keeps username limited // to one voucher and that voucher shows the correct time credit in 'active vouchers' - if ($line = $active_vouchers[$first_voucher_roll][$first_voucher]) { - list($timestamp, $minutes) = explode(",", $line); + if (!empty($active_vouchers[$first_voucher_roll][$first_voucher])) { + list($timestamp, $minutes) = explode(",", $active_vouchers[$first_voucher_roll][$first_voucher]); } else { $timestamp = time(); // new voucher $minutes = $total_minutes; @@ -298,13 +298,13 @@ function voucher_configure() { fwrite($fd, "{$config['voucher']['rollbits']},{$config['voucher']['ticketbits']},{$config['voucher']['checksumbits']},{$config['voucher']['magic']},{$config['voucher']['charset']}\n"); fclose($fd); @chmod("{$g['varetc_path']}/voucher.cfg", 0600); - unlock($voucherlck); + unlock($voucherlck); if ($g['booting'] && is_array($config['voucher']['roll'])) { // create active and used DB per roll on ramdisk from config $a_roll = &$config['voucher']['roll']; - $voucherlck = lock('voucher'); + $voucherlck = lock('voucher', LOCK_EX); foreach ($a_roll as $rollent) { @@ -325,8 +325,8 @@ function voucher_configure() { } voucher_write_active_db($roll, $active_vouchers); } - - unlock($voucherlck); + + unlock($voucherlck); echo gettext("done") . "\n"; } @@ -363,7 +363,7 @@ function voucher_read_active_db($roll) { $line = trim(fgets($fd)); if ($line) { list($voucher,$timestamp,$minutes) = explode(",", $line); // voucher,timestamp - if ((($timestamp + 60*$minutes) - time()) > 0) + if ((($timestamp + (60*$minutes)) - time()) > 0) $active[$voucher] = "$timestamp,$minutes"; else $dirty=1; diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc index 906fcdd..1c0a1c9 100644 --- a/etc/inc/vpn.inc +++ b/etc/inc/vpn.inc @@ -159,11 +159,15 @@ function vpn_ipsec_configure($ipchg = false) if (!is_ipaddr($rg)) { $filterdns_list[] = "{$rg}"; add_hostname_to_watch($rg); - $rg = resolve_retry($rg); - if (!$rg) + if(! $g['booting']) + $rg = resolve_retry($rg); + if (!is_ipaddr($rg)) continue; } - + if(array_search($rg, $rgmap)) { + log_error("The remote gateway {$rg} already exists on another phase 1 entry"); + continue; + } $rgmap[$ph1ent['remote-gateway']] = $rg; /* step through each phase2 entry */ @@ -813,6 +817,8 @@ EOD; continue; $rgip = $rgmap[$ph1ent['remote-gateway']]; + if(!is_ipaddr($rgip)) + continue; $localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true); $remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true); @@ -844,7 +850,7 @@ EOD; else $parentinterface = $ph1ent['interface']; - if ($parentinterface <> "wan") { + if (($parentinterface <> "wan") && (is_ipaddr($rgip))) { /* add endpoint routes to correct gateway on interface */ if (interface_has_gateway($parentinterface)) { $gatewayip = get_interface_gateway("$parentinterface"); @@ -862,7 +868,7 @@ EOD; } } } - } else { + } elseif(is_ipaddr($rgip)) { if(stristr($route_str, "{$rgip}")) { mwexec("/sbin/route delete -host {$rgip}", true); } @@ -880,9 +886,7 @@ EOD; /* mange racoon process */ if (is_process_running("racoon")) { sleep("0.1"); - /* XXX: This seems to not work in ipsec-tools 0.7.3 but a HUP signal is equivalent. */ - //mwexec("/usr/local/sbin/racoonctl -s /var/db/racoon/racoon.sock reload-config", false); - sigkillbypid("{$g['varrun_path']}/racoon.pid", "HUP"); + mwexec("/usr/local/sbin/racoonctl -s /var/db/racoon/racoon.sock reload-config", false); /* load SPD without flushing to be safe on config additions or changes. */ mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false); } else { @@ -897,21 +901,21 @@ EOD; /* load SPD */ mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false); - /* start filterdns, if necessary */ - if (count($filterdns_list) > 0) { - $interval = 60; - if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) - $interval = $ipseccfg['dns-interval']; - - $hostnames = ""; - array_unique($filterdns_list); - foreach ($hostname as $filterdns_list) - $hostnames .= "cmd {$hostname} '/etc/rc.newipsecdns'\n"; - file_put_contents("{$g['varetc_path']}/filternds-ipsec.hosts", $hostnames); - - killbypid("{$g['varrun_path']}/filterdns-ipsec.pid"); - mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/filterdns_ipsec.hosts -d 1"); - } + } + /* start filterdns, if necessary */ + if (count($filterdns_list) > 0) { + $interval = 60; + if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) + $interval = $ipseccfg['dns-interval']; + + $hostnames = ""; + array_unique($filterdns_list); + foreach ($filterdns_list as $hostname) + $hostnames .= "cmd {$hostname} '/etc/rc.newipsecdns'\n"; + file_put_contents("{$g['varetc_path']}/filterdns-ipsec.hosts", $hostnames); + + killbypid("{$g['varrun_path']}/filterdns-ipsec.pid"); + mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/filterdns-ipsec.hosts -d 1"); } vpn_ipsec_failover_configure(); @@ -1676,11 +1680,16 @@ function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) { /* see if this tunnel has a hostname for the remote-gateway, and if so, * try to resolve it now and add it to the list for filterdns */ + $rgip = ""; if (!is_ipaddr($phase1['remote-gateway'])) { - $rgip = resolve_retry($phase1['remote-gateway']); - add_hostname_to_watch($phase1['remote-gateway']); - if (!$rgip) { - log_error(sprintf(gettext("Could not determine VPN endpoint for '%s'"), $phase1['descr'])); + if(! $g['booting']) { + $rgip = resolve_retry($phase1['remote-gateway']); + add_hostname_to_watch($phase1['remote-gateway']); + } else { + add_hostname_to_watch($phase1['remote-gateway']); + } + if (!is_ipaddr($rgip)) { + log_error("Could not determine VPN endpoint for '{$phase1['descr']}'"); return false; } } else { |