diff options
Diffstat (limited to 'etc/inc')
-rw-r--r-- | etc/inc/captiveportal.inc | 290 | ||||
-rw-r--r-- | etc/inc/config.inc | 43 | ||||
-rw-r--r-- | etc/inc/filter.inc | 357 | ||||
-rw-r--r-- | etc/inc/functions.inc | 1 | ||||
-rw-r--r-- | etc/inc/globals.inc | 38 | ||||
-rw-r--r-- | etc/inc/interfaces.inc | 22 | ||||
-rw-r--r-- | etc/inc/itemid.inc | 85 | ||||
-rw-r--r-- | etc/inc/notices.inc | 38 | ||||
-rw-r--r-- | etc/inc/pfsense-utils.inc | 165 | ||||
-rw-r--r-- | etc/inc/rrd.inc | 5 | ||||
-rw-r--r-- | etc/inc/services.inc | 39 | ||||
-rw-r--r-- | etc/inc/shaper.inc | 8 | ||||
-rw-r--r-- | etc/inc/system.inc | 27 | ||||
-rw-r--r-- | etc/inc/upgrade_config.inc | 4 | ||||
-rw-r--r-- | etc/inc/util.inc | 64 | ||||
-rw-r--r-- | etc/inc/vpn.inc | 3 | ||||
-rw-r--r-- | etc/inc/xmlparse.inc | 148 |
17 files changed, 749 insertions, 588 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc index eed86c6..59c39ee 100644 --- a/etc/inc/captiveportal.inc +++ b/etc/inc/captiveportal.inc @@ -3,6 +3,7 @@ captiveportal.inc part of m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2009 Ermal Luçi Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. All rights reserved. @@ -58,13 +59,16 @@ function captiveportal_configure() { continue; $tmpif = get_real_interface($cpifgrp); if (!empty($tmpif)) { + mwexec("/sbin/ifconfig {$tmpif} -ipfwfilter"); if ($firsttime > 0) $cpinterface .= " or "; $cpinterface .= "via {$tmpif}"; $firsttime = 1; $cpipm = get_interface_ip($cpifgrp); - if (is_ipaddr($cpipm)) + if (is_ipaddr($cpipm)) { $cpips[] = $cpipm; + mwexec("/sbin/ifconfig {$tmpif} ipfwfilter"); + } } } if (count($cpips) > 0) { @@ -168,7 +172,7 @@ EOD; <b> Username and/or password invalid. <br><br> -<a href="javascript:history.back()">Go back</a> +<a href="javascript:history.back(); ">Go back</a> </b> </body> </html> @@ -244,8 +248,8 @@ EOD; /* generate passthru mac database */ captiveportal_passthrumac_configure(true); - /* create allowed ip database and insert ipfw rules to make it so */ - captiveportal_allowedip_configure(true); + /* allowed ipfw rules to make allowed ip work */ + captiveportal_allowedip_configure(); /* generate radius server database */ if ($config['captiveportal']['radiusip'] && (!isset($config['captiveportal']['auth_method']) || @@ -297,6 +301,9 @@ EOD; /* unload ipfw */ mwexec("/sbin/kldunload ipfw.ko"); + $listifs = get_configured_interface_list_by_realif(); + foreach ($listifs as $listrealif => $listif) + mwexec("/sbin/ifconfig {$listrealif} -ipfwfilter"); } unlock($captiveportallck); @@ -316,18 +323,6 @@ function captiveportal_rules_generate($cpif, &$cpiparray) { $cprules = "add 500 set 1 allow pfsync from any to any\n"; $cprules .= "add 500 set 1 allow carp from any to any\n"; - /* allow nat redirects to work see - http://cvstrac.pfsense.com/tktview?tn=651 - */ - /* if list */ - $iflist = get_configured_interface_list(); - foreach ($iflist as $ifent => $ifname) { - if(stristr($cpifn, $ifname)) - continue; - $int = get_real_interface($ifname); - $cprules .= "add 30 set 1 skipto 50000 all from any to any in via {$int} keep-state\n"; - } - /* captive portal on LAN interface? */ if (stristr($cpifn, "lan")) { /* add anti-lockout rules */ @@ -339,13 +334,7 @@ EOD; } $cprules .= <<<EOD -add 1000 set 1 skipto 1200 all from any to any not layer2 $cpif -# skip to traffic shaper if not on captive portal interface -add 1001 set 1 skipto 50000 all from any to any not layer2 -add 1003 set 1 skipto 1100 layer2 $cpif -# pass all layer2 traffic on other interfaces -add 1004 set 1 pass layer2 - +add 1000 set 1 skipto 1150 all from any to any not layer2 # layer 2: pass ARP add 1100 set 1 pass layer2 mac-type arp # pfsense requires for WPA @@ -362,11 +351,11 @@ add 1100 set 1 pass layer2 mac-type 0x888e # layer 2: block anything else non-IP add 1101 set 1 deny layer2 not mac-type ip # layer 2: check if MAC addresses of authenticated clients are correct -add 1102 set 1 skipto 20000 layer2 +add 1102 set 1 skipto 2000 layer2 EOD; - $rulenum = 1200; + $rulenum = 1150; foreach ($cpiparray as $cpip) { //# allow access to our DHCP server (which needs to be able to ping clients as well) $cprules .= "add {$rulenum} set 1 pass udp from any 68 to 255.255.255.255 67 in \n"; @@ -396,33 +385,33 @@ EOD; $cprules .= "add {$rulenum} set 1 pass tcp from {$cpip} 8001 to any out \n"; } } - $rulenum++; - //# allow access to our DNS forwarder if it incorrectly resolves the hostname to $lanip - $cprules .= "add {$rulenum} set 1 pass udp from any to {$lanip} 53 in \n"; - $rulenum++; - $cprules .= "add {$rulenum} set 1 pass udp from {$lanip} 53 to any out \n"; - //# allow access to lan web server incase the dns name resolves incorrectly to $lanip - $rulenum++; - $cprules .= "add {$rulenum} set 1 pass tcp from any to {$lanip} 8000 in \n"; - $rulenum++; - $cprules .= "add {$rulenum} set 1 pass tcp from {$lanip} 8000 to any out \n"; - - $cprules .= <<<EOD -# ... 10000-19899: rules per authenticated client go here... + if (isset($config['captiveportal']['peruserbw'])) { + $cprules .= "add {$rulenum} set 2 pipe tablearg ip from table(3) to any in\n"; + $rulenum++; + $cprules .= "add {$rulenum} set 2 pipe tablearg ip from any to table(4) out\n"; + $rulenum++; + } else { + $cprules .= "add {$rulenum} set 2 skipto 50000 ip from table(3) to any in\n"; + $rulenum++; + $cprules .= "add {$rulenum} set 2 skipto 50000 ip from any to table(4) out\n"; + $rulenum++; + } + + $cprules .= <<<EOD # redirect non-authenticated clients to captive portal -add 19902 set 1 fwd 127.0.0.1,8000 tcp from any to any 80 in +add 1990 set 1 fwd 127.0.0.1,8000 tcp from any to any 80 in # let the responses from the captive portal web server back out -add 19903 set 1 pass tcp from any 80 to any out +add 1991 set 1 pass tcp from any 80 to any out # block everything else -add 19904 set 1 deny all from any to any +add 1992 set 1 deny all from any to any -# ... 20000-29899: layer2 block rules per authenticated client go here... +# ... 2000-49899: layer2 block rules per authenticated client go here... # pass everything else on layer2 -add 29900 set 1 pass all from any to any layer2 +add 49900 set 1 pass all from any to any layer2 EOD; @@ -464,6 +453,7 @@ function captiveportal_prune_old() { * the loop would evalate 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++) { @@ -494,7 +484,7 @@ function captiveportal_prune_old() { $idletimeout = (is_numeric($cpdb[$i][8])) ? $cpdb[$i][8] : $idletimeout; /* if an idle timeout is specified, get last activity timestamp from ipfw */ if (!$timedout && $idletimeout) { - $lastact = captiveportal_get_last_activity($cpdb[$i][1]); + $lastact = captiveportal_get_last_activity($cpdb[$i][2]); /* if the user has logged on but not sent any trafic they will never be logged out. * We "fix" this by setting lastact to the login timestamp */ @@ -525,7 +515,7 @@ function captiveportal_prune_old() { if ($timedout) { captiveportal_disconnect($cpdb[$i], $radiusservers,$term_cause,$stop_time); captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "TIMEOUT"); - unset($cpdb[$i]); + $unsetindexes[$i] = $i; } /* do periodic RADIUS reauthentication? */ @@ -545,7 +535,8 @@ function captiveportal_prune_old() { $cpdb[$i][2], // clientip $cpdb[$i][3], // clientmac 10); // NAS Request - exec("/sbin/ipfw zero {$cpdb[$i][1]}"); + exec("/sbin/ipfw table 3 entryzerostats {$cpdb[$i][2]}"); + exec("/sbin/ipfw table 4 entryzerostats {$cpdb[$i][2]}"); RADIUS_ACCOUNTING_START($cpdb[$i][1], // ruleno $cpdb[$i][4], // username $cpdb[$i][5], // sessionid @@ -580,10 +571,13 @@ function captiveportal_prune_old() { 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']); - unset($cpdb[$i]); + $unsetindexes[$i] = $i; } } } + /* This is a kludge to overcome some php weirdness */ + foreach($unsetindexes as $unsetindex) + unset($cpdb[$unsetindex]); /* write database */ captiveportal_write_db($cpdb); @@ -614,18 +608,20 @@ function captiveportal_disconnect($dbent, $radiusservers,$term_cause = 1,$stop_t $stop_time); } - mwexec("/sbin/ipfw delete " . $dbent[1] . " " . ($dbent[1]+10000)); - - /* We need to delete +40500 and +45500 as well... - * these are the pipe numbers we use to control traffic shaping for each logged in user via captive portal - * We could get an error if the pipe doesn't exist but everything should still be fine - */ - if (isset($config['captiveportal']['peruserbw'])) { - mwexec("/sbin/ipfw pipe " . ($dbent[1]+40500) . " delete"); - mwexec("/sbin/ipfw pipe " . ($dbent[1]+45500) . " delete"); - } + mwexec("/sbin/ipfw table 4 delete {$dbent[2]}"); + mwexec("/sbin/ipfw table 4 delete {$dbent[2]}"); + mwexec("/sbin/ipfw delete {$dbent[1]}"); + + /* + * These are the pipe numbers we use to control traffic shaping for each logged in user via captive portal + * We could get an error if the pipe doesn't exist but everything should still be fine + */ + if (isset($config['captiveportal']['peruserbw'])) { + mwexec("/sbin/ipfw pipe " . ($dbent[1]+20000) . " delete"); + mwexec("/sbin/ipfw pipe " . ($dbent[1]+20001) . " delete"); + } - /* pfSense: ensure all pf states are killed (pfSense) */ + /* Ensure all pf(4) states are killed. */ mwexec("pfctl -k {$dbent[2]}"); mwexec("pfctl -K {$dbent[2]}"); @@ -643,14 +639,17 @@ function captiveportal_disconnect_client($id,$term_cause = 1) { $radiusservers = captiveportal_get_radius_servers(); /* find entry */ + $tmpindex = 0; for ($i = 0; $i < count($cpdb); $i++) { if ($cpdb[$i][1] == $id) { captiveportal_disconnect($cpdb[$i], $radiusservers, $term_cause); captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "DISCONNECT"); - unset($cpdb[$i]); + $tmpindex = $i; break; } } + if ($tmpindex > 0) + unset($cpdb[$tmpindex]); /* write database */ captiveportal_write_db($cpdb); @@ -728,8 +727,8 @@ function captiveportal_passthrumac_configure($lock = false) { foreach($config['captiveportal']['passthrumac'] as $ptm) { /* create the pass through mac entry */ //system("echo /sbin/ipfw add 50 skipto 65535 ip from any to any MAC {$ptm['mac']} any > /tmp/cp"); - mwexec("/sbin/ipfw add 50 skipto 29900 ip from any to any MAC {$ptm['mac']} any keep-state"); - mwexec("/sbin/ipfw add 50 skipto 29900 ip from any to any MAC any {$ptm['mac']} keep-state"); + mwexec("/sbin/ipfw add 50 skipto 49900 ip from any to any MAC {$ptm['mac']} any keep-state"); + mwexec("/sbin/ipfw add 50 skipto 49900 ip from any to any MAC any {$ptm['mac']} keep-state"); } } @@ -739,89 +738,50 @@ function captiveportal_passthrumac_configure($lock = false) { return 0; } -function captiveportal_allowedip_configure($lock = false) { +function captiveportal_allowedip_configure() { global $config, $g; - if (!$lock) - $captiveportallck = lock('captiveportal'); - /* clear out existing allowed ips, if necessary */ - if (file_exists("{$g['vardb_path']}/captiveportal_ip.db")) { - $fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "r"); - if ($fd) { - while (!feof($fd)) { - $line = trim(fgets($fd)); - if ($line) { - list($ip,$rule) = explode(",",$line); - mwexec("/sbin/ipfw delete $rule"); - } - } - } - fclose($fd); - unlink("{$g['vardb_path']}/captiveportal_ip.db"); - } - - /* get next ipfw rule number */ - if (file_exists("{$g['vardb_path']}/captiveportal.nextrule")) - $ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule")); - if (!$ruleno) - $ruleno = 10000; /* first rule number */ + mwexec("/sbin/ipfw table 1 flush"); + mwexec("/sbin/ipfw table 2 flush"); if (is_array($config['captiveportal']['allowedip'])) { - - $fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "w"); - if (!$fd) { - printf("Error: cannot open allowed ip DB file in captiveportal_allowedip_configure().\n"); - unlock($captiveportallck); - return 1; - } - + $tableone = false; + $tabletwo = false; foreach ($config['captiveportal']['allowedip'] as $ipent) { - /* get next ipfw rule number */ - $ruleno = captiveportal_get_next_ipfw_ruleno(); - - /* if the pool is empty, return apprioriate message and fail */ - if (is_null($ruleno)) { - printf("Error: system reached maximum login capacity, no free FW rulenos in captiveportal_allowedip_configure().\n"); - fclose($fd); - unlock($captiveportallck); - return 1; - } - - /* record allowed ip so it can be recognized and removed later */ - fwrite($fd, $ipent['ip'] . "," . $ruleno ."\n"); - - /* insert ipfw rule to allow ip thru */ - if ($ipent['dir'] == "from") { - mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from " . $ipent['ip'] . " to any in"); - mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to " . $ipent['ip'] . " out"); - } else { - mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to " . $ipent['ip'] . " in"); - mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from " . $ipent['ip'] . " to any out"); - } - - } - - fclose($fd); - } + /* insert address in ipfw table */ + if ($ipent['dir'] == "from") { + mwexec("/sbin/ipfw table 1 add {$ipent['ip']}"); + $tableone = true; + } else { + mwexec("/sbin/ipfw table 2 add {$ipent['ip']}"); + $tabletwo = true; + } + } + if ($tableone == true) { + mwexec("/sbin/ipfw add 1890 set 2 skipto 50000 ip from table\(1\) to any in"); + mwexec("/sbin/ipfw add 1891 set 2 skipto 50000 ip from any to table\(1\) out"); + } + if ($tabletwo == true) { + mwexec("/sbin/ipfw add 1892 set 2 skipto 50000 ip from any to table\(2\) in"); + mwexec("/sbin/ipfw add 1893 set 2 skipto 50000 ip from table\(2\) to any out"); + } + } - if (!$lock) - unlock($captiveportallck); return 0; } /* get last activity timestamp given ipfw rule number */ -function captiveportal_get_last_activity($ruleno) { +function captiveportal_get_last_activity($ip) { $ipfwoutput = ""; - exec("/sbin/ipfw -T list {$ruleno} 2>/dev/null", $ipfwoutput); - - /* in */ + exec("/sbin/ipfw table 3 entrystats {$ip} 2>/dev/null", $ipfwoutput); + /* Reading only from one of the tables is enough of approximation. */ if ($ipfwoutput[0]) { $ri = explode(" ", $ipfwoutput[0]); - if ($ri[1]) - return $ri[1]; + if ($ri[4]) + return $ri[4]; } return 0; @@ -996,28 +956,31 @@ function captiveportal_write_elements() { /* * This function will calculate the lowest free firewall ruleno - * within the range specified based on the actual installed rules + * within the range specified based on the actual logged on users * */ -function captiveportal_get_next_ipfw_ruleno($rulenos_start = 10000, $rulenos_range_max = 9899) { - - $fwrules = ""; - $matches = ""; - exec("/sbin/ipfw show", $fwrules); - foreach ($fwrules as $fwrule) { - preg_match("/^(\d+)\s+/", $fwrule, $matches); - $rulenos_used[] = $matches[1]; - } - $rulenos_used = array_unique($rulenos_used); - $rulenos_range = count($rulenos_used); - if ($rulenos_range > $rulenos_range_max) { - return NULL; - } - $rulenos_pool = range($rulenos_start, ($rulenos_start + $rulenos_range)); - $rulenos_free = array_diff($rulenos_pool, $rulenos_used); - $ruleno = array_shift($rulenos_free); +function captiveportal_get_next_ipfw_ruleno($rulenos_start = 2000, $rulenos_range_max = 49899) { + global $config, $g; - return $ruleno; + $ruleno = 0; + if (file_exists("{$g['vardb_path']}/captiveportal.nextrule")) + $ruleno = intval(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule")); + else + $ruleno = 1; + if ($ruleno > 0 && (($rulenos_start + $ruleno) < $rulenos_range_max)) { + /* + * This allows our traffic shaping pipes to be the in pipe the same as ruleno + * and the out pipe ruleno + 1. This removes limitation that where present in + * previous version of the peruserbw. + */ + if (isset($config['captiveportal']['peruserbw'])) + $ruleno += 2; + else + $ruleno++; + file_put_contents("{$g['vardb_path']}/captiveportal.nextrule", $ruleno); + return $rulenos_start + $ruleno; + } + return NULL; } /** @@ -1031,7 +994,7 @@ function captiveportal_get_next_ipfw_ruleno($rulenos_start = 10000, $rulenos_ran * */ -function getVolume($ruleno) { +function getVolume($ip) { $volume = array(); @@ -1039,20 +1002,23 @@ function getVolume($ruleno) { $volume['input_pkts'] = $volume['input_bytes'] = $volume['output_pkts'] = $volume['output_bytes'] = 0 ; // Ingress - $ipfw = ""; - $matches = ""; - exec("/sbin/ipfw show {$ruleno}", $ipfw); - preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+.*/", $ipfw[0], $matches); - $volume['input_pkts'] = $matches[2]; - $volume['input_bytes'] = $matches[3]; - - // Flush internal buffer - unset($matches); - - // Outgress - preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+.*/", $ipfw[1], $matches); - $volume['output_pkts'] = $matches[2]; - $volume['output_bytes'] = $matches[3]; + $ipfwin = ""; + $ipfwout = ""; + $matchesin = ""; + $matchesout = ""; + exec("/sbin/ipfw table 3 entrystats {$ip}", $ipfwin); + if ($ipfwin[0]) { + $ipfwin = split(" ", $ipfwin[0]); + $volume['input_pkts'] = $ipfwin[2]; + $volume['input_bytes'] = $ipfwin[3]; + } + + exec("/sbin/ipfw table 4 entrystats {$ip}", $ipfwout); + if ($ipfwout[0]) { + $ipfwout = split(" ", $ipfwout[0]); + $volume['output_pkts'] = $ipfwout[2]; + $volume['output_bytes'] = $ipfwout[3]; + } return $volume; } diff --git a/etc/inc/config.inc b/etc/inc/config.inc index f6e17a8..8a48d23 100644 --- a/etc/inc/config.inc +++ b/etc/inc/config.inc @@ -240,10 +240,11 @@ function encrypted_configxml() { * $config - array containing all configuration variables ******/ function parse_config($parse = false) { - global $g; + global $g, $config_parsed; $lockkey = lock('config'); - if (filesize("{$g['conf_path']}/config.xml") == 0) { + $config_parsed == false; + if (!file_exists("{$g['conf_path']}/config.xml") || filesize("{$g['conf_path']}/config.xml") == 0) { $last_backup = discover_last_backup(); if($last_backup) { log_error("No config.xml found, attempting last known config restore."); @@ -302,14 +303,9 @@ function parse_config($parse = false) { } if($g['booting']) echo "."; alias_make_table($config); + $config_parsed = true; unlock($lockkey); - /* process packager manager custom rules */ - if(is_dir("/usr/local/pkg/parse_config")) { - update_filter_reload_status("Running plugins (parse_config)"); - run_plugins("/usr/local/pkg/parse_config/"); - update_filter_reload_status("Plugins completed."); - } return $config; } @@ -341,10 +337,12 @@ function discover_last_backup() { } function restore_backup($file) { + global $g; + if (file_exists($file)) { conf_mount_rw(); copy("$file","/cf/conf/config.xml"); - unlink_if_exists("/tmp/config.cache"); + unlink_if_exists("{$g['tmp_path']}/config.cache"); log_error("{$g['product_name']} is restoring the configuration $file"); file_notice("config.xml", "{$g['product_name']} is restoring the configuration $file", "pfSenseConfigurator", ""); conf_mount_ro(); @@ -647,9 +645,7 @@ function write_config($desc="Unknown", $backup = true) { if(is_dir("/usr/local/pkg/write_config")) { /* process packager manager custom rules */ - update_filter_reload_status("Running plugins"); run_plugins("/usr/local/pkg/write_config/"); - update_filter_reload_status("Plugins completed."); } return $config; @@ -698,18 +694,22 @@ function config_restore($conffile) { if (!file_exists($conffile)) return 1; - $lockkey = lock('config'); conf_mount_rw(); backup_config(); + + $lockkey = lock('config'); + copy($conffile, "{$g['cf_conf_path']}/config.xml"); + unlink_if_exists("{$g['tmp_path']}/config.cache"); + unlock($lockkey); + $config = parse_config(true); - $lockkey = lock('config'); + write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false); conf_mount_ro(); - unlock($lockkey); return 0; } @@ -720,14 +720,16 @@ function config_install($conffile) { if (!file_exists($conffile)) return 1; - if (!config_validate("{$g['conf_path']}/config.xml")) + if (!config_validate("{$conffile}")) return 1; if($g['booting'] == true) echo "Installing configuration...\n"; + else + log_error("Installing configuration ...."); - $lockkey = lock('config'); conf_mount_rw(); + $lockkey = lock('config'); copy($conffile, "{$g['conf_path']}/config.xml"); @@ -735,8 +737,8 @@ function config_install($conffile) { if(file_exists("{$g['tmp_path']}/config.cache")) unlink("{$g['tmp_path']}/config.cache"); - conf_mount_ro(); unlock($lockkey); + conf_mount_ro(); return 0; } @@ -1397,4 +1399,11 @@ function set_device_perms() { if($g['booting']) echo "."; $config = parse_config(); +if($config_parsed == true) { + /* process packager manager custom rules */ + if(is_dir("/usr/local/pkg/parse_config")) { + run_plugins("/usr/local/pkg/parse_config/"); + } +} + ?> diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc index d93d857..f783255 100644 --- a/etc/inc/filter.inc +++ b/etc/inc/filter.inc @@ -292,20 +292,27 @@ function filter_configure_sync() { layer7_start_l7daemon(); /* run items scheduled for after filter configure run */ - $fda = fopen("/tmp/commands.txt", "w"); - foreach($after_filter_configure_run as $afcr) - fwrite($fda, $afcr . "\n"); - /* - * we need a way to let a user run a shell cmd after each - * filter_configure() call. run this xml command after - * each change. - */ - if($config['system']['afterfilterchangeshellcmd'] <> "") - fwrite($fda, $config['system']['afterfilterchangeshellcmd'] . "\n"); - fclose($fda); - if (file_exists("/tmp/commands.txt")) { - mwexec("sh /tmp/commands.txt &"); - unlink("/tmp/commands.txt"); + $fda = fopen("{$g['tmp_path']}/commands.txt", "w"); + if ($fda) { + if($after_filter_configure_run) + foreach($after_filter_configure_run as $afcr) + fwrite($fda, $afcr . "\n"); + /* + * we need a way to let a user run a shell cmd after each + * filter_configure() call. run this xml command after + * each change. + */ + if($config['system']['afterfilterchangeshellcmd'] <> "") + fwrite($fda, $config['system']['afterfilterchangeshellcmd'] . "\n"); + + fclose($fda); + } + + unlock($filterlck); + + if (file_exists("{$g['tmp_path']}/commands.txt")) { + mwexec("sh {$g['tmp_path']}/commands.txt &"); + unlink("{$g['tmp_path']}/commands.txt"); } /* if time based rules are enabled then swap in the set */ if ($time_based_rules == true) @@ -313,8 +320,6 @@ function filter_configure_sync() { else filter_tdr_install_cron(false); - unlock($filterlck); - if ($g['booting'] == true) echo "."; find_dns_aliases(); @@ -356,17 +361,23 @@ function filter_generate_scrubing() return $scrubrules; } -function filter_generate_nested_alias($alias) { +function filter_generate_nested_alias($name, $alias, &$aliasnesting, &$aliasaddrnesting) { global $aliastable; $addresses = split(" ", $alias); $finallist = ""; + $aliasnesting[$name] = $name; foreach ($addresses as $address) { $linelength = strlen($finallist); - if (isset($aliastable[$address])) - $tmpline = filter_generate_nested_alias($aliastable[$address]); - else + $tmpline = ""; + if (is_alias($address)) { + /* We already expanded this alias so there is no neccessity to do it again. */ + if (!isset($aliasnesting[$address])) + $tmpline = filter_generate_nested_alias($address, $aliastable[$address], $aliasnesting, $aliasaddrnesting); + } else if (!isset($aliasaddrnesting[$address])) { + $aliasaddrnesting[$address] = $address; $tmpline = " $address"; + } if ((strlen($tmpline)+ $linelength) > 4036) $finallist .= "\n"; $finallist .= " {$tmpline}"; @@ -375,7 +386,7 @@ function filter_generate_nested_alias($alias) { } function filter_generate_aliases() { - global $config, $FilterIflist, $aliastable; + global $config, $FilterIflist; if(isset($config['system']['developerspew'])) { $mt = microtime(); echo "filter_generate_aliases() being called $mt\n"; @@ -394,10 +405,32 @@ function filter_generate_aliases() { $extraalias = ""; $ip = find_interface_ip($aliased['address']); $extraalias = " " . link_ip_to_carp_interface($ip); - $addrlist = filter_generate_nested_alias($aliased['address']); + $aliasnesting = array(); + $aliasaddrnesting = array(); + $addrlist = filter_generate_nested_alias($aliased['name'], $aliased['address'], $aliasnesting, $aliasaddrnesting); if ($aliased['type'] == "host" || $aliased['type'] == "network") { $aliases .= "table <{$aliased['name']}> { {$addrlist}{$extralias} } \n"; $aliases .= "{$aliased['name']} = \"<{$aliased['name']}>\"\n"; + } else if ($aliased['type'] == "openvpn") { + $openvpncfg = array(); + if($config['openvpn']['user']) { + /* XXX: Check if we have a correct ip? */ + foreach ($config['openvpn']['user'] as $openvpn) + $openvpncfg[$openvpn['name']] = $openvpn['ip']; + } + $vpn_lines = split("\n", $addrlist); + foreach ($vpn_lines as $vpn_line) { + $vpn_address_split = split(" ", $vpn_line); + foreach($vpn_address_split as $vpnsplit) { + if(isset($openvpncfg[$vpnsplit])) { + $newaddress .= " "; + $newaddress .= $openvpn[$vpnsplit]; + break; + } + } + } + $aliases .= "table <{$aliased['name']}> { {$newaddress}{$extralias} } \n"; + $aliases .= "{$aliased['name']} = \"<{$aliased['name']}>\"\n"; } else $aliases .= "{$aliased['name']} = \"{ {$aliased['address']}{$extralias} }\"\n"; } @@ -570,6 +603,109 @@ function filter_flush_state_table() return mwexec("/sbin/pfctl -F state"); } +function filter_generate_reflection($rule, $extport, &$starting_localhost_port) { + global $FilterIflist, $config; + + $natrules = ""; + if(!isset($config['system']['disablenatreflection'])) { + $inetd_fd = fopen("/var/etc/inetd.conf","w"); + /* add tftp protocol helper */ + fwrite($inetd_fd, "tftp\tdgram\tudp\twait\t\troot\t/usr/local/sbin/tftp-proxy -v\n"); + + update_filter_reload_status("Setting up reflection"); + $natrules .= "\n# Reflection redirects\n"; + foreach ($FilterIflist as $ifent => $ifname) { + /* do not process interfaces with gateways*/ + if (interface_has_gateway($ifent)) + continue; + if($extport[1]) + $range_end = ($extport[1]); + else + $range_end = ($extport[0]); + $range_end++; + if($rule['local-port']) + $lrange_start = $rule['local-port']; + if($range_end - $extport[0] > 500) { + $range_end = $extport[0]+1; + log_error("Not installing nat reflection rules for a port range > 500"); + } else { + /* only install reflection rules for < 19991 items */ + if($starting_localhost_port < 19991) { + $loc_pt = $lrange_start; + for($x=$extport[0]; $x<$range_end; $x++) { + $xxx = $x; + update_filter_reload_status("Creating reflection rule for {$rule['descr']}..."); + if($config['system']['reflectiontimeout']) + $reflectiontimeout = $config['system']['reflectiontimeout']; + else + $reflectiontimeout = "2000"; + $toadd_array = array(); + if(is_alias($loc_pt)) { + $loc_pt_translated = alias_expand($loc_pt); + add_hostname_to_watch($loc_pt_translated); + if(stristr($loc_pt_translated, " ")) { + /* XXX: we should deal with multiple ports */ + $loc_pt_translated_split = split(" ", $loc_pt_translated); + foreach($loc_pt_translated_split as $lpts) + $toadd_array[] = $lpts; + } else { + $toadd_array[] = $loc_pt_translated; + } + } else { + $loc_pt_translated = $loc_pt; + $toadd_array[] = $loc_pt_translated; + } + + switch($rule['protocol']) { + case "tcp/udp": + $protocol = "{ tcp udp }"; + foreach($toadd_array as $tda){ + fwrite($inetd_fd, "{$starting_localhost_port}\tstream\ttcp/udp\tnowait/0\tnobody\t/usr/bin/nc nc -w {$reflectiontimeout}{$target} {$tda}\n"); + $natrules .= "rdr on {$ifname['if']} proto tcp from any to {$extaddr} port {$xxx} tag PFREFLECT -> 127.0.0.1 port {$starting_localhost_port}\n"; + $starting_localhost_port++; + fwrite($inetd_fd, "{$starting_localhost_port}\tstream\ttcp/udp\tnowait/0\tnobody\t/usr/bin/nc nc -u -w {$reflectiontimeout} {$target} {$tda}\n"); + $natrules .= "rdr on { {$ifname['if']} } proto udp from any to {$extaddr} port {$xxx} tag PFREFLECT -> 127.0.0.1 port {$starting_localhost_port}\n"; + $xxx++; + $starting_localhost_port++; + } + break; + case "tcp": + case "udp": + $protocol = $rule['protocol']; + foreach($toadd_array as $tda){ + if($protocol == "udp") { + $socktype = "dgram"; + $dash_u = "-u "; + } else { + $socktype = "stream"; + $dash_u = ""; + } + if($config['system']['reflectiontimeout']) + $reflectiontimeout = $config['system']['reflectiontimeout']; + else + $reflectiontimeout = "20"; + fwrite($inetd_fd, "{$starting_localhost_port}\t{$socktype}\t{$protocol}\tnowait/0\tnobody\t/usr/bin/nc nc {$dash_u}-w {$reflectiontimeout} {$target} {$tda}\n"); + $natrules .= "rdr on { {$ifname['if']} } proto {$protocol} from any to {$extaddr} port {$xxx} tag PFREFLECT -> 127.0.0.1 port {$starting_localhost_port}\n"; + $xxx++; + $starting_localhost_port++; + } + break; + default: + break; + } + $loc_pt++; + if($starting_localhost_port > 19990) { + log_error("Not installing nat reflection rules. Maximum 1,000 reached."); + $x = $range_end+1; + } + } + } + } + } + } + return $natrules; +} + /* Generate a 'nat on' or 'no nat on' rule for given interface */ function filter_nat_rules_generate_if($if, $src = "any", $srcport = "", $dst = "any", $dstport = "", $natip = "", $natport = "", $nonat = false, $staticnatport = false) { @@ -809,21 +945,17 @@ function filter_nat_rules_generate() fwrite($inetd_fd, "tftp\tdgram\tudp\twait\t\troot\t/usr/local/sbin/tftp-proxy -v\n"); if (isset($config['nat']['rule'])) { - $natrules .= "# NAT Inbound Redirects\n"; - $inetd_fd = fopen("/var/etc/inetd.conf","w"); - /* add tftp protocol helper */ - fwrite($inetd_fd, "tftp\tdgram\tudp\twait\t\troot\t/usr/local/sbin/tftp-proxy -v\n"); if(!isset($config['system']['disablenatreflection'])) { /* start redirects on port 19000 of localhost */ $starting_localhost_port = 19000; } + $natrules .= "# NAT Inbound Redirects\n"; foreach ($config['nat']['rule'] as $rule) { update_filter_reload_status("Creating NAT rule {$rule['descr']}"); /* if item is an alias, expand */ $extport = ""; - unset($extport); if(alias_expand($rule['external-port'])) - $extport[0] = alias_expand_value($rule['external-port']); + $extport[0] = alias_expand($rule['external-port']); else $extport = explode("-", $rule['external-port']); /* if item is an alias, expand */ @@ -831,48 +963,34 @@ function filter_nat_rules_generate() $localport = ""; else $localport = " port {$rule['local-port']}"; - $target = alias_expand_host($rule['target']); + $target = alias_expand($rule['target']); if (!$target) { $natrules .= "# Unresolvable alias {$rule['target']}\n"; continue; /* unresolvable alias */ } - # use tables for aliases in rdr - if (!is_ipaddr($target)) { - $natrules .= "table <{$rule['target']}> { $target }\n"; - $target = "<{$rule['target']}>"; - } - if ($rule['external-address']) - if($rule['external-address'] <> "any") - $extaddr = $rule['external-address'] . "/32"; - else - $extaddr = $rule['external-address']; + if (!$rule['interface']) + $natif = "wan"; + else + $natif = $rule['interface']; + if (alias_expand($rule['external-address'])) + $extaddr = alias_expand($extaddr); + else if ($rule['external-address'] <> "") + $extaddr = $rule['external-address']; else $extaddr = $FilterIflist[$rule['interface']]['ip']; - if (!$rule['interface']) - $natif = "wan"; - else - $natif = $rule['interface']; $natif = $FilterIflist[$natif]['if']; - /* - * Expand aliases - * XXX: may want to integrate this into pf macros - */ - if(alias_expand($target)) - $target = alias_expand($target); - if(alias_expand($extaddr)) - $extaddr = alias_expand($extaddr); - if($extaddr == "") - $dontinstallrdr = true; - if($dontinstallrdr == false) { + + if ($extaddr <> "") { /* is rule a port range? */ if ((!$extport[1]) || ($extport[0] == $extport[1])) { + switch ($rule['protocol']) { case "tcp/udp": if($natif) { if($rule['external-port'] <> $rule['local-port']) - $natrules .= "{$nordr} rdr on $natif proto { tcp udp } from any to {$extaddr} port { {$extport[0]} } -> {$target}{$localport}"; + $natrules .= "{$nordr} rdr on $natif proto { tcp udp } from any to {$extaddr} port {$extport[0]} -> {$target}{$localport}"; else - $natrules .= "{$nordr} rdr on $natif proto { tcp udp } from any to {$extaddr} port { {$extport[0]} } -> {$target}"; + $natrules .= "{$nordr} rdr on $natif proto { tcp udp } from any to {$extaddr} port {$extport[0]} -> {$target}"; } break; case "udp": @@ -880,9 +998,9 @@ function filter_nat_rules_generate() if($extport[0]) if($natif) { if($rule['external-port'] <> $rule['local-port']) - $natrules .= "rdr on $natif proto {$rule['protocol']} from any to {$extaddr} port { {$extport[0]} } -> {$target}{$localport}"; + $natrules .= "rdr on $natif proto {$rule['protocol']} from any to {$extaddr} port {$extport[0]} -> {$target}{$localport}"; else - $natrules .= "rdr on $natif proto {$rule['protocol']} from any to {$extaddr} port { {$extport[0]} } -> {$target}"; + $natrules .= "rdr on $natif proto {$rule['protocol']} from any to {$extaddr} port {$extport[0]} -> {$target}"; } else if($natif) @@ -922,115 +1040,7 @@ function filter_nat_rules_generate() $natrules .= "nat on {$natif} proto tcp from {$rule_subnet}/{$rule_interface_subnet} to {$target} port {$extport[0]} -> ({$natif})\n"; } } - if(!isset($config['system']['disablenatreflection'])) { - update_filter_reload_status("Setting up reflection"); - $natrules .= "\n# Reflection redirects\n"; - foreach ($FilterIflist as $ifent => $ifname) { - /* do not process interfaces with gateways*/ - if (interface_has_gateway($ifent)) - continue; - if($extport[1]) - $range_end = ($extport[1]); - else - $range_end = ($extport[0]); - $range_end++; - if($rule['local-port']) - $lrange_start = $rule['local-port']; - if($range_end - $extport[0] > 500) { - $range_end = $extport[0]+1; - log_error("Not installing nat reflection rules for a port range > 500"); - } else { - /* only install reflection rules for < 19991 items */ - if($starting_localhost_port < 19991) { - $loc_pt = $lrange_start; - for($x=$extport[0]; $x<$range_end; $x++) { - $xxx = $x; - /* do not install reflection rules for FTP. This simply - * opens up pandoras box. - */ - if($xxx == "21") - continue; - update_filter_reload_status("Creating reflection rule for {$rule['descr']}..."); - if($config['system']['reflectiontimeout']) - $reflectiontimeout = $config['system']['reflectiontimeout']; - else - $reflectiontimeout = "2000"; - switch($rule['protocol']) { - case "tcp/udp": - $protocol = "{ tcp udp }"; - $toadd_array = array(); - if(is_alias($loc_pt)) { - $loc_pt_translated = alias_expand_value($loc_pt); - add_hostname_to_watch($loc_pt_translated); - if(stristr($loc_pt_translated, " ")) { - /* XXX: we should deal with multiple ports */ - $loc_pt_translated_split = split(" ", $loc_pt_translated); - foreach($loc_pt_translated_split as $lpts) - $toadd_array[] = $lpts; - } else { - $toadd_array[] = $loc_pt_translated; - } - } else { - $loc_pt_translated = $loc_pt; - $toadd_array[] = $loc_pt_translated; - } - foreach($toadd_array as $tda){ - fwrite($inetd_fd, "{$starting_localhost_port}\tstream\ttcp/udp\tnowait/0\tnobody\t/usr/bin/nc nc -w {$reflectiontimeout} {$target} {$tda}\n"); - $natrules .= "rdr on {$ifname['if']} proto tcp from any to {$extaddr} port { {$xxx} } tag PFREFLECT -> 127.0.0.1 port {$starting_localhost_port}\n"; - $starting_localhost_port++; - fwrite($inetd_fd, "{$starting_localhost_port}\tstream\ttcp/udp\tnowait/0\tnobody\t/usr/bin/nc nc -u -w {$reflectiontimeout} {$target} {$tda}\n"); - $natrules .= "rdr on { {$ifname['if']} } proto udp from any to {$extaddr} port { {$xxx} } tag PFREFLECT -> 127.0.0.1 port {$starting_localhost_port}\n"; - $xxx++; - $starting_localhost_port++; - } - break; - case "tcp": - case "udp": - $protocol = $rule['protocol']; - $toadd_array = array(); - if(is_alias($loc_pt)) { - $loc_pt_translated = alias_expand_value($loc_pt); - add_hostname_to_watch($loc_pt_translated); - if(stristr($loc_pt_translated, " ")) { - /* XXX: we should deal with multiple ports */ - $loc_pt_translated_split = split(" ", $loc_pt_translated); - foreach($loc_pt_translated_split as $lpts) - $toadd_array[] = $lpts; - } else { - $toadd_array[] = $loc_pt_translated; - } - } else { - $loc_pt_translated = $loc_pt; - $toadd_array[] = $loc_pt_translated; - } - foreach($toadd_array as $tda){ - if($protocol == "udp") - $dash_u = "-u "; - else - $dash_u = ""; - if($config['system']['reflectiontimeout']) - $reflectiontimeout = $config['system']['reflectiontimeout']; - else - $reflectiontimeout = "20"; - fwrite($inetd_fd, "{$starting_localhost_port}\tstream\t{$protocol}\tnowait/0\tnobody\t/usr/bin/nc nc {$dash_u}-w {$reflectiontimeout} {$target} {$tda}\n"); - $natrules .= "rdr on { {$ifname['if']} } proto {$protocol} from any to {$extaddr} port { {$xxx} } tag PFREFLECT -> 127.0.0.1 port {$starting_localhost_port}\n"; - $xxx++; - $starting_localhost_port++; - } - break; - default: - break; - } - $loc_pt++; - if($starting_localhost_port > 19990) { - log_error("Not installing nat reflection rules. Maximum 1,000 reached."); - $x = $range_end+1; - } - } - } - } - } - } + $natrules .= filter_generate_reflection($rule, $extport, $starting_localhost_port); $natrules .= "\n"; } } @@ -1483,8 +1493,9 @@ function filter_generate_user_rule($rule) foreach ($config['schedules']['schedule'] as $sched) { if ($sched['name'] == $rule['sched']) { if (!filter_get_time_based_rule_status($sched)) { - mwexec("/sbin/pfctl -y \"{$sched['schedlabel']}\""); - $line = "# schedule finished - {$rule}"; + if (!isset($config['system']['schedule_states'])) + mwexec("/sbin/pfctl -y {$sched['schedlabel']}"); + return "# schedule finished - {$rule['descr']}"; } else if ($g['debug']) log_error("[TDR DEBUG] status true -- rule type '$type'"); @@ -1739,7 +1750,7 @@ EOD; * interface in question to avoid problems with complicated routing * topologies */ - if (isset($config['system']['bypassstaticroutes']) && is_array($config['staticroutes']['route']) && count($config['staticroutes']['route'])) { + if (isset($config['filter']['bypassstaticroutes']) && is_array($config['staticroutes']['route']) && count($config['staticroutes']['route'])) { $ipfrules .= "anchor \"staticrouted\" \n"; foreach ($config['staticroutes']['route'] as $route) { $realif = guess_interface_from_ip(lookup_gateway_ip_by_name($route['gateway'])); @@ -1884,6 +1895,12 @@ function filter_rules_spoofcheck_generate($ifname, $if, $sa, $sn, $log) return $ipfrules; } +/* COMPAT Function */ +function tdr_install_cron($should_install) { + log_error("Please use filter_tdr_install_cron() function tdr_install_cron will be deprecated!"); + filter_tdr_install_cron($should_install); +} + /****f* filter/filter_tdr_install_cron * NAME * filter_tdr_install_cron diff --git a/etc/inc/functions.inc b/etc/inc/functions.inc index c7189b5..79aa19d 100644 --- a/etc/inc/functions.inc +++ b/etc/inc/functions.inc @@ -83,5 +83,6 @@ require_once("vpn.inc"); require_once("vslb.inc"); require_once("cmd_chain.inc"); require_once("rrd.inc"); +require_once("itemid.inc"); ?> diff --git a/etc/inc/globals.inc b/etc/inc/globals.inc index 6a032b6..666f759 100644 --- a/etc/inc/globals.inc +++ b/etc/inc/globals.inc @@ -31,6 +31,26 @@ POSSIBILITY OF SUCH DAMAGE. */ +function remove_numbers($string) { + $nums = array("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", " "); + $string = str_replace($nums, '', $string); + return $string; +} + +function get_nics_with_capabilities($CAPABILITIES) { + $if_list = get_interface_list(); + $vlan_native_supp = array(); + foreach($if_list as $if => $iface) { + $capable = `ifconfig -m | grep -a1 $if | grep $CAPABILITIES`; + if($capable) { + $interfacenonum = remove_numbers($if); + if(!in_array($interfacenonum, $vlan_native_supp)) + $vlan_native_supp[] = $interfacenonum; + } + } + return $vlan_native_supp; +} + $g = array( "base_packages" => "AutoConfigBackup, siproxd", "factory_shipped_username" => "admin", @@ -76,11 +96,23 @@ $g = array( "embeddedbootupslice" => "/dev/ad0a", "services_dhcp_server_enable" => true, "firmware_update_text" => "(pfSense-*.tgz)", - "wireless_regex" => "/^(ndis|wi|ath|an|ral|ural|wai|iwi|awi|wlan|rum)/", - "vlan_native_supp" => array("bce", "bge", "bfe", "cxgb", "dc", "em", "fxp", "gem", "hme", "ixgb", "msk", "nge", "re", "rl", "sis", "ste", "stge", "ti", "tl", "tx", "txp", "vge", "vr", "xl", "lagg"), - "vlan_long_frame" => array("vge", "bfe", "bge", "dc", "em", "fxp", "gem", "hme", "ixgb", "le", "nge", "re", "rl", "sis", "sk", "ste", "ti", "tl", "tx", "txp", "vr", "xl", "lagg") + "wireless_regex" => "/^(ndis|wi|ath|an|ral|ural|wai|iwi|awi|wlan|rum)/" ); +// Loop through and set vlan_native_supp (native vlan tagging) +$vlan_native_supp = get_nics_with_capabilities("HWTAGGING"); +if(count($vlan_native_supp) > 0) + $g['vlan_native_supp'] = $vlan_native_supp; +else + $g['vlan_native_supp'] = array("bce", "bge", "bfe", "cxgb", "dc", "em", "fxp", "gem", "hme", "ixgb", "msk", "nge", "re", "rl", "sis", "ste", "stge", "ti", "tl", "tx", "txp", "vge", "vr", "xl", "lagg"); + +// Loop through and set vlan_long_frame VLAN_MTU +$vlan_native_supp = get_nics_with_capabilities("VLAN_MTU"); +if(count($vlan_native_supp) > 0) + $g['vlan_long_frame'] = $vlan_native_supp; +else + $g['vlan_long_frame'] = array("vge", "bfe", "bge", "dc", "em", "fxp", "gem", "hme", "ixgb", "le", "nge", "re", "rl", "sis", "sk", "ste", "ti", "tl", "tx", "txp", "vr", "xl", "lagg"); + /* IP TOS flags */ $iptos = array("lowdelay", "throughput", "reliability"); diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index c7eab73..9e6ffee 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -1979,18 +1979,17 @@ function interface_group_setup($groupname /* The parameter is an array */) { return; } -/* XXX: stub for code that references the old functions(mostly packages) */ -/* - * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0 - */ +/* COMPAT Function */ function convert_friendly_interface_to_real_interface_name($interface) { return get_real_interface($interface); } +/* COMPAT Function */ function get_real_wan_interface($interface = "wan") { return get_real_interface($interface); } +/* COMPAT Function */ function get_current_wan_address($interface = "wan") { return get_interface_ip($interface); } @@ -2185,7 +2184,7 @@ function get_real_interface($interface = "wan") { } function guess_interface_from_ip($ipaddress) { - $ret = `/usr/bin/netstat -rn | /usr/bin/awk '/^{$ipaddress}/ {print \$6}'`; + $ret = `/usr/bin/netstat -rn | /usr/bin/awk '/^{$ipaddress}/ {printf "%s", \$6}'`; if (empty($ret)) return false; @@ -2369,14 +2368,15 @@ function interface_has_gateway($friendly) { function is_altq_capable($int) { /* Per: - * http://www.freebsd.org/cgi/man.cgi?query=altq&manpath=FreeBSD+6.0-current&format=html + * 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("an", "ath", "awi", "bfe", "bge", "dc", "de", "ed", - "em", "fxp", "hme", "le", "nve", "re", "rl", "ndis", "sf", "sis", "sk", - "tun", "vr", "wi", "xl", "vlan", "ste", "aue", "bce", "ep", "gem", "ipw", - "iwi", "msk", "mxge", "my", "nfe", "npe", "ral", "rum", "stge", "udav", - "ural", "pppoe", "pptp", "ng", "ppp"); + $capable = array("age", "ale", "an", "ath", "aue", "awi", "bce", + "bfe", "bge", "dc", "de", "ed", "em", "ep", "fxp", "gem", + "hme", "ipw", "iwi", "jme", "le", "msk", "mxge", "my", "nfe", + "npe", "nve", "ral", "re", "rl", "rum", "sf", "sis", "sk", + "ste", "stge", "txp", "udav", "ural", "vge", "vr", "wi", "xl", + "ndis", "tun", "vlan", "pppoe", "pptp", "ng", "ppp"); $int_family = preg_split("/[0-9]+/", $int); diff --git a/etc/inc/itemid.inc b/etc/inc/itemid.inc new file mode 100644 index 0000000..3a48e51 --- /dev/null +++ b/etc/inc/itemid.inc @@ -0,0 +1,85 @@ +<?php +/* $Id$ */ +/* + Copyright (C) 2009 Janne Enberg <janne.enberg@lietu.net> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + DISABLE_PHP_LINT_CHECKING +*/ + +/****f* itemid/delete_id + * NAME + * delete_id - delete an item with ['id'] = $id from $array + * INPUTS + * $id - int: The ID to delete + * $array - array to delete the item from + * RESULT + * boolean - true if item was found and deleted + ******/ +function delete_id($id, &$array){ + // Index to delete + $delete_index = NULL; + + // Search for the item in the array + foreach ($array as $key => $item){ + // If this item is the one we want to delete + if(isset($item['id']) && $item['id']==$id ){ + $delete_index = $key; + break; + } + } + + // If we found the item, unset it + if( $delete_index!==NULL ){ + unset($array[$delete_index]); + return true; + } else { + return false; + } + +} + +/****f* itemid/get_next_id + * NAME + * get_next_id - find the next available id from an item list + * INPUTS + * $array - array of items to get the id for + * RESULT + * integer - the next available id + ******/ +function get_next_id($array){ + // Default value + $next_id = 1; + + // Search for IDs + foreach ($array as $item){ + // If this item has an ID, and it's higher or equal to the current "next ID", use that + 1 as the next ID + if(isset($item['id']) && $item['id']>=$next_id ){ + $next_id = $item['id'] + 1; + } + } + return $next_id; +} + +?>
\ No newline at end of file diff --git a/etc/inc/notices.inc b/etc/inc/notices.inc index c2722b2..2f8e5fa 100644 --- a/etc/inc/notices.inc +++ b/etc/inc/notices.inc @@ -190,4 +190,42 @@ function are_notices_pending($category = "all") { return false; } +/****f* pfsense-utils/notify_via_growl + * NAME + * notify_via_growl + * INPUTS + * notification string to send + * RESULT + * returns true if message was sent + ******/ +function notify_via_growl($message) { + require_once("growl.class"); + global $config; + $growl_ip = $config['notifications']['growl']['ipaddress']; + $growl_password = $config['notifications']['growl']['password']; + if($growl_ip) { + $growl = new Growl($growl_ip, $growl_password); + $growl->notify("pfSense growl alert", "pfSense", "{$message}"); + } +} + +/****f* pfsense-utils/register_via_growl + * NAME + * register_via_growl + * INPUTS + * none + * RESULT + * none + ******/ +function register_via_growl() { + require_once("growl.class"); + global $config; + $growl_ip = $config['notifications']['growl']['ipaddress']; + $growl_password = $config['notifications']['growl']['password']; + if($growl_ip) { + $growl = new Growl($growl_ip, $growl_password); + $growl->register(); + } +} + ?>
\ No newline at end of file diff --git a/etc/inc/pfsense-utils.inc b/etc/inc/pfsense-utils.inc index 42781d8..69e65bc 100644 --- a/etc/inc/pfsense-utils.inc +++ b/etc/inc/pfsense-utils.inc @@ -128,7 +128,8 @@ function is_private_ip($iptocheck) { * returns a temporary filename ******/ function get_tmp_file() { - return "/tmp/tmp-" . time(); + global $g; + return "{$g['tmp_path']}/tmp-" . time(); } /****f* pfsense-utils/find_number_of_needed_carp_interfaces @@ -893,9 +894,10 @@ Content-Length: $content_length * php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors */ if (!function_exists('php_check_syntax')){ + global $g; function php_check_syntax($code_to_check, &$errormessage){ return false; - $fout = fopen("/tmp/codetocheck.php","w"); + $fout = fopen("{$g['tmp_path']}/codetocheck.php","w"); $code = $_POST['content']; $code = str_replace("<?php", "", $code); $code = str_replace("?>", "", $code); @@ -903,7 +905,7 @@ if (!function_exists('php_check_syntax')){ fwrite($fout, $code_to_check); fwrite($fout, "\n\n?>\n"); fclose($fout); - $command = "/usr/local/bin/php -l /tmp/codetocheck.php"; + $command = "/usr/local/bin/php -l {$g['tmp_path']}/codetocheck.php"; $output = exec_command($command); if (stristr($output, "Errors parsing") == false) { echo "false\n"; @@ -1084,7 +1086,7 @@ function reload_interfaces_sync() { log_error("Removing {$g['tmp_path']}/reloading_all"); /* start devd back up */ - mwexec("/bin/rm /tmp/reload*"); + mwexec("/bin/rm {$g['tmp_path']}/reload*"); } /****f* pfsense-utils/reload_all @@ -1096,7 +1098,8 @@ function reload_interfaces_sync() { * none ******/ function reload_all() { - touch("/tmp/reload_all"); + global $g; + touch("{$g['tmp_path']}/reload_all"); } /****f* pfsense-utils/reload_interfaces @@ -1108,7 +1111,8 @@ function reload_all() { * none ******/ function reload_interfaces() { - touch("/tmp/reload_interfaces"); + global $g; + touch("{$g['tmp_path']}/reload_interfaces"); } /****f* pfsense-utils/reload_all_sync @@ -1167,12 +1171,12 @@ function reload_all_sync() { conf_mount_ro(); /* restart sshd */ - @touch("/tmp/start_sshd"); + @touch("{$g['tmp_path']}/start_sshd"); /* restart webConfigurator if needed */ - touch("/tmp/restart_webgui"); + touch("{$g['tmp_path']}/restart_webgui"); - mwexec("/bin/rm /tmp/reload*"); + mwexec("/bin/rm {$g['tmp_path']}/reload*"); } function auto_login($status) { @@ -1668,47 +1672,116 @@ function isvm() { return false; } -/****f* pfsense-utils/notify_via_growl - * NAME - * notify_via_growl - * INPUTS - * notification string to send - * RESULT - * returns true if message was sent - ******/ -function notify_via_growl($message) { - require_once("growl.class"); - global $config; - $growl_ip = $config['notifications']['growl']['ipaddress']; - $growl_password = $config['notifications']['growl']['password']; - if($growl_ip) { - $growl = new Growl($growl_ip, $growl_password); - $growl->notify("pfSense growl alert", "pfSense", "{$message}"); - } +function get_freebsd_version() { + $version = trim(`/usr/bin/uname -r | /usr/bin/cut -d'.' -f1`); + return $version; } -/****f* pfsense-utils/register_via_growl - * NAME - * register_via_growl - * INPUTS - * none - * RESULT - * none - ******/ -function register_via_growl() { - require_once("growl.class"); - global $config; - $growl_ip = $config['notifications']['growl']['ipaddress']; - $growl_password = $config['notifications']['growl']['password']; - if($growl_ip) { - $growl = new Growl($growl_ip, $growl_password); - $growl->register(); - } +function download_file_with_progress_bar($url_file, $destination_file, $readbody = 'read_body') { + global $ch, $fout, $file_size, $downloaded; + $file_size = 1; + $downloaded = 1; + /* open destination file */ + $fout = fopen($destination_file, "wb"); + + /* + * Originally by Author: Keyvan Minoukadeh + * Modified by Scott Ullrich to return Content-Length size + */ + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url_file); + curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header'); + curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody); + curl_setopt($ch, CURLOPT_NOPROGRESS, '1'); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, '5'); + curl_setopt($ch, CURLOPT_TIMEOUT, 0); + + curl_exec($ch); + $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if($fout) + fclose($fout); + curl_close($ch); + return ($http_code == 200) ? true : $http_code; +} + +function read_header($ch, $string) { + global $file_size, $fout; + $length = strlen($string); + $regs = ""; + ereg("(Content-Length:) (.*)", $string, $regs); + if($regs[2] <> "") { + $file_size = intval($regs[2]); + } + ob_flush(); + return $length; +} + +function read_body($ch, $string) { + global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen; + $length = strlen($string); + $downloaded += intval($length); + $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0); + $downloadProgress = 100 - $downloadProgress; + if($lastseen <> $downloadProgress and $downloadProgress < 101) { + if($sendto == "status") { + $tostatus = $static_status . $downloadProgress . "%"; + update_status($tostatus); + } else { + $tooutput = $static_output . $downloadProgress . "%"; + update_output_window($tooutput); + } + update_progress_bar($downloadProgress); + $lastseen = $downloadProgress; + } + if($fout) + fwrite($fout, $string); + ob_flush(); + return $length; } -function get_freebsd_version() { - $version = trim(`/usr/bin/uname -r | /usr/bin/cut -d'.' -f1`); - return $version; +/* + * update_output_window: update bottom textarea dynamically. + */ +function update_output_window($text) { + global $pkg_interface; + $log = ereg_replace("\n", "\\n", $text); + if($pkg_interface == "console") { + /* too chatty */ + } else { + echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>"; + } + /* ensure that contents are written out */ + ob_flush(); +} + +/* + * update_output_window: update top textarea dynamically. + */ +function update_status($status) { + global $pkg_interface; + if($pkg_interface == "console") { + echo $status . "\n"; + } else { + echo "\n<script type=\"text/javascript\">this.document.forms[0].status.value=\"" . $status . "\";</script>"; + } + /* ensure that contents are written out */ + ob_flush(); +} + +/* + * update_progress_bar($percent): updates the javascript driven progress bar. + */ +function update_progress_bar($percent) { + global $pkg_interface; + if($percent > 100) $percent = 1; + if($pkg_interface <> "console") { + echo "\n<script type=\"text/javascript\" language=\"javascript\">"; + echo "\ndocument.progressbar.style.width='" . $percent . "%';"; + echo "\n</script>"; + } else { + echo " {$percent}%"; + } } ?> diff --git a/etc/inc/rrd.inc b/etc/inc/rrd.inc index 78f42c6..721316e 100644 --- a/etc/inc/rrd.inc +++ b/etc/inc/rrd.inc @@ -55,7 +55,10 @@ function create_new_rrd($rrdcreatecmd) { } function migrate_rrd_format($rrdoldxml, $rrdnewxml) { - exec("echo 'Converting RRD configuration to new format. This might take a bit...' | wall"); + if(!file_exists("/tmp/rrd_notice_sent.txt")) { + exec("echo 'Converting RRD configuration to new format. This might take a bit...' | wall"); + touch("/tmp/rrd_notice_sent.txt"); + } $numrraold = count($rrdoldxml['rra']); $numdsold = count($rrdoldxml['ds']); $numrranew = count($rrdnewxml['rra']); diff --git a/etc/inc/services.inc b/etc/inc/services.inc index 4310283..ce3d3c7 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -2,8 +2,9 @@ /* $Id$ */ /* services.inc - part of m0n0wall (http://m0n0.ch/wall) + part of the pfSense project (http://www.pfsense.com) + originally part of m0n0wall (http://m0n0.ch/wall) Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. All rights reserved. @@ -94,13 +95,23 @@ function services_dhcpd_configure() { return 1; } - + $optcounter = 0; + $custoptions = ""; + foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) { + if($dhcpifconf['numberoptions']['item']) { + foreach($dhcpifconf['numberoptions']['item'] as $item) { + $custoptions .= "option custom-opt-$optcounter code {$item['number']} = text;\n"; + $optcounter++; + } + } + } $dhcpdconf = <<<EOD option domain-name "{$syscfg['domain']}"; option ldap-server code 95 = text; option domain-search-list code 119 = text; +{$custoptions} default-lease-time 7200; max-lease-time 86400; log-facility local7; @@ -256,25 +267,43 @@ $dnscfg EOD; - if ($dhcpifconf['defaultleasetime']) + // default-lease-time + if ($dhcpifconf['defaultleasetime']) $dhcpdconf .= " default-lease-time {$dhcpifconf['defaultleasetime']};\n"; + + // max-lease-time if ($dhcpifconf['maxleasetime']) $dhcpdconf .= " max-lease-time {$dhcpifconf['maxleasetime']};\n"; + // netbios-name* if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) { $dhcpdconf .= " option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n"; $dhcpdconf .= " option netbios-node-type 8;\n"; } + // ntp-servers if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0]) $dhcpdconf .= " option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n"; + // tftp-server-name if ($dhcpifconf['tftp'] <> "") $dhcpdconf .= " option tftp-server-name \"{$dhcpifconf['tftp']}\";\n"; - if ($dhcpifconf['ldap'] <> "") + // Handle option, number rowhelper values + $optcounter = 0; + $dhcpdconf .= "\n"; + if($dhcpifconf['numberoptions']['item']) { + foreach($dhcpifconf['numberoptions']['item'] as $item) { + $dhcpdconf .= " option custom-opt-$optcounter \"{$item['value']}\";\n"; + $optcounter++; + } + } + + // ldap-server + if ($dhcpifconf['ldap'] <> "") $dhcpdconf .= " option ldap-server \"{$dhcpifconf['ldap']}\";\n"; + // net boot information if(isset($dhcpifconf['netboot'])) { if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) { $dhcpdconf .= " next-server {$dhcpifconf['next-server']};\n"; @@ -282,7 +311,7 @@ EOD; } if ($dhcpifconf['rootpath'] <> "") { $dhcpdconf .= " option root-path \"{$dhcpifconf['rootpath']}\";\n"; - } + } } $dhcpdconf .= <<<EOD diff --git a/etc/inc/shaper.inc b/etc/inc/shaper.inc index 7ce0bee..f97ec20 100644 --- a/etc/inc/shaper.inc +++ b/etc/inc/shaper.inc @@ -3549,6 +3549,10 @@ function read_altq_config() { global $altq_list_queues, $config; $path = array(); + if (!is_array($config['shaper'])) + $config['shaper'] = array(); + if (!is_array($config['shaper']['queue'])) + $config['shaper']['queue'] = array(); $a_int = &$config['shaper']['queue']; $altq_list_queues = array(); @@ -3585,6 +3589,10 @@ function read_dummynet_config() { $dnqueuenumber = 1; $dnpipenumber = 1; + if (!is_array($config['dnshaper'])) + $config['dnshaper'] = array(); + if (!is_array($config['dnshaper']['queue'])) + $config['dnshaper']['queue'] = array(); $a_int = &$config['dnshaper']['queue']; $dummynet_pipe_list = array(); diff --git a/etc/inc/system.inc b/etc/inc/system.inc index 9217bd5..3939471 100644 --- a/etc/inc/system.inc +++ b/etc/inc/system.inc @@ -42,9 +42,9 @@ function activate_powerd() { function activate_sysctls() { global $config, $g; - exec("/sbin/sysctl net.enc.out.ipsec_bpf_mask=0x00000000"); + exec("/sbin/sysctl net.enc.out.ipsec_bpf_mask=0x00000001"); exec("/sbin/sysctl net.enc.out.ipsec_filter_mask=0x00000001"); - exec("/sbin/sysctl net.enc.in.ipsec_bpf_mask=0x00000000"); + exec("/sbin/sysctl net.enc.in.ipsec_bpf_mask=0x00000002"); exec("/sbin/sysctl net.enc.in.ipsec_filter_mask=0x00000002"); if (is_array($config['sysctl'])) @@ -455,16 +455,22 @@ auth.info;authpriv.info;daemon.info @{$syslogcfg['remoteserver']} *.emerg @{$syslogcfg['remoteserver']} EOD; + if (isset($syslogcfg['logall'])) { + $syslogconf .= <<<EOD +*.* @{$syslogcfg['remoteserver']} + +EOD; + } fwrite($fd, $syslogconf); fclose($fd); // Are we logging to a least one remote server ? if(strpos($syslogconf, "@") != false) - $retval = system("/usr/sbin/syslogd -f {$g['varetc_path']}/syslog.conf"); + $retval = system("/usr/sbin/syslogd -c -f {$g['varetc_path']}/syslog.conf"); else - $retval = system("/usr/sbin/syslogd -f {$g['varetc_path']}/syslog.conf"); + $retval = system("/usr/sbin/syslogd -c -f {$g['varetc_path']}/syslog.conf"); } else { - $retval = mwexec("/usr/sbin/syslogd"); + $retval = mwexec("/usr/sbin/syslogd -c"); } if ($g['booting']) @@ -519,7 +525,7 @@ function system_webgui_start() { $key = ""; /* non-standard port? */ - if ($config['system']['webgui']['port']) + if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") $portarg = "{$config['system']['webgui']['port']}"; if ($config['system']['webgui']['protocol'] == "https") { @@ -598,7 +604,11 @@ function system_generate_lighty_config($filename, $memory = get_memory(); $avail = $memory[0]; - if($avail > 0 and $avail < 98) { + if($avail > 0 and $avail < 65) { + $fast_cgi_enable = false; + } + + if($avail > 65 and $avail < 98) { $max_procs = 1; $max_requests = 1; } @@ -959,6 +969,9 @@ function system_ntp_configure() { /* start opentpd, set time now and use /var/etc/ntpd.conf */ exec("/usr/local/sbin/ntpd -s -f {$g['varetc_path']}/ntpd.conf"); + + // Note that we are starting up + exec("echo 'OpenNTPD is starting up' >> {$g['varlog_path']}/ntpd.log"); } diff --git a/etc/inc/upgrade_config.inc b/etc/inc/upgrade_config.inc index 8191d89..7d05575 100644 --- a/etc/inc/upgrade_config.inc +++ b/etc/inc/upgrade_config.inc @@ -1,10 +1,10 @@ <?php /* - Copyright (C) 2004-2006 Scott Ullrich + Copyright (C) 2004-2009 Scott Ullrich <sullrich@gmail.com> All rights reserved. originally part of m0n0wall (http://m0n0.ch/wall) -Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. + Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/etc/inc/util.inc b/etc/inc/util.inc index 4304801..c289d62 100644 --- a/etc/inc/util.inc +++ b/etc/inc/util.inc @@ -1,7 +1,9 @@ -<?php /* $Id$ */ /* +<?php +/* util.inc - part of m0n0wall (http://m0n0.ch/wall) + part of the pfSense project (http://www.pfsense.com) + originally part of m0n0wall (http://m0n0.ch/wall) Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. All rights reserved. @@ -648,34 +650,6 @@ function is_alias($name) { return isset($aliastable[$name]); } -function alias_expand_value($name) { - - global $aliastable, $config; - $newaddress = ""; - $firstentry = true; - if($config['aliases']['alias']) - foreach($config['aliases']['alias'] as $alias) { - if($alias['name'] == $name) { - if($alias['type'] == "openvpn") { - $vpn_address_split = split(" ", $alias['address']); - foreach($vpn_address_split as $vpnsplit) { - foreach($config['openvpn']['user'] as $openvpn) { - if($openvpn['name'] == $vpnsplit) { - if($firstentry == false) - $newaddress .= " "; - $newaddress .= $openvpn['ip']; - $firstentry = false; - } - } - } - } else { - $newaddress = $alias['address']; - } - } - } - return $newaddress; -} - /* expand a host or network alias, if necessary */ function alias_expand($name) { @@ -689,36 +663,6 @@ function alias_expand($name) { return null; } -/* expand a host alias, if necessary */ -function alias_expand_host($name) { - global $aliastable; - - if (isset($aliastable[$name])) { - $ip_arr = explode(" ", $aliastable[$name]); - foreach($ip_arr as $ip) { - if (!is_ipaddr($ip)) - return null; - } - return $aliastable[$name]; - } else if (is_ipaddr($name)) - return $name; - else - return null; -} - -/* expand a network alias, if necessary */ -function alias_expand_net($name) { - - global $aliastable; - - if (isset($aliastable[$name]) && is_subnet($aliastable[$name])) - return $aliastable[$name]; - else if (is_subnet($name)) - return $name; - else - return null; -} - /* find out whether two subnets overlap */ function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) { diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc index b1620c4..51fd673 100644 --- a/etc/inc/vpn.inc +++ b/etc/inc/vpn.inc @@ -38,6 +38,7 @@ require_once ("functions.inc"); function vpn_ipsec_failover_configure() { global $config, $g; + require_once ("ipsec.inc"); $sasyncd_text = ""; @@ -91,6 +92,7 @@ function find_last_gif_device() { function vpn_ipsec_configure($ipchg = false) { global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos; + require_once ("ipsec.inc"); mwexec("/sbin/ifconfig enc0 up"); @@ -871,6 +873,7 @@ EOD; function vpn_ipsec_force_reload() { global $config; global $g; + require_once ("ipsec.inc"); $ipseccfg = $config['ipsec']; diff --git a/etc/inc/xmlparse.inc b/etc/inc/xmlparse.inc index cb55117..78178b8 100644 --- a/etc/inc/xmlparse.inc +++ b/etc/inc/xmlparse.inc @@ -49,87 +49,47 @@ function listtags() { "serversdisabled earlyshellcmd shellcmd staticmap subqueue timerange ". "tunnel user vip virtual_server vlan winsserver wolentry widget " ); - return $ret; + return array_flip($ret); } /* Package XML tags that should be treat as a list not as a traditional array */ function listtags_pkg() { $ret = array("depends_on_package", "onetoone", "queue", "rule", "servernat", "alias", "additional_files_needed", "tab", "template", "menu", "rowhelperfield", "service", "step", "package", "columnitem", "option", "item", "field", "package", "file"); - return $ret; + return array_flip($ret); } -function startElement($parser, $name, $attrs) { - global $parsedcfg, $depth, $curpath, $havedata, $listtags; +function add_elements(&$cfgarray, &$parser) { + global $listtags; + while ($parser->read()) { + switch ($parser->nodeType) { + case XMLReader::WHITESPACE: + //$type = "WHITESPACE"; + break; + case XMLReader::SIGNIFICANT_WHITESPACE: + //$type = "SIGNIFICANT_WHITESPACE"; + break; + case XMLReader::ELEMENT: + if ($parser->isEmptyElement) { + $cfgarray[$parser->name] = ""; + } else { + if (isset($listtags[$parser->name])) + add_elements($cfgarray[$parser->name][], $parser); + else + add_elements($cfgarray[$parser->name], $parser); + } + break; + case XMLReader::TEXT: + $cfgarray = $parser->value; + break; + case XMLReader::END_ELEMENT: + return; + break; + default: + break; + } - array_push($curpath, strtolower($name)); - - $ptr =& $parsedcfg; - foreach ($curpath as $path) { - $ptr =& $ptr[$path]; - } - - /* is it an element that belongs to a list? */ - if (in_array(strtolower($name), $listtags)) { - - /* is there an array already? */ - if (!is_array($ptr)) { - /* make an array */ - $ptr = array(); - } - - array_push($curpath, count($ptr)); - - } else if (isset($ptr)) { - /* multiple entries not allowed for this element, bail out */ - die(sprintf("XML error: %s at line %d cannot occur more than once\n", - $name, - xml_get_current_line_number($parser))); - } - - $depth++; - $havedata = $depth; -} - -function endElement($parser, $name) { - global $depth, $curpath, $parsedcfg, $havedata, $listtags; - - if ($havedata == $depth) { - $ptr =& $parsedcfg; - foreach ($curpath as $path) { - $ptr =& $ptr[$path]; - } - $ptr = ""; - } - - array_pop($curpath); - - if (in_array(strtolower($name), $listtags)) - array_pop($curpath); - - $depth--; -} - -function cData($parser, $data) { - global $depth, $curpath, $parsedcfg, $havedata; - - $data = trim($data, "\t\n\r"); - - if ($data != "") { - $ptr =& $parsedcfg; - foreach ($curpath as $path) { - $ptr =& $ptr[$path]; - } - - if (is_string($ptr)) { - $ptr .= $data; - } else { - if (trim($data, " ") != "") { - $ptr = $data; - $havedata++; - } - } - } + } } function parse_xml_config($cffile, $rootobj, $isstring = "false") { @@ -137,10 +97,10 @@ function parse_xml_config($cffile, $rootobj, $isstring = "false") { $listtags = listtags(); if (isset($GLOBALS['custom_listtags'])) { foreach($GLOBALS['custom_listtags'] as $tag) { - $listtags[] = $tag; + $listtags[$tag] = $tag; } } - return parse_xml_config_raw($cffile, $rootobj, $isstring); + return parse_xml_config_raw($cffile, $rootobj); } function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") { @@ -148,7 +108,7 @@ function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") { $listtags = listtags_pkg(); if (isset($GLOBALS['custom_listtags_pkg'])) { foreach($GLOBALS['custom_listtags_pkg'] as $tag) { - $listtags[] = $tag; + $listtags[$tag] = $tag; } } return parse_xml_config_raw($cffile, $rootobj, $isstring); @@ -156,34 +116,14 @@ function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") { function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") { - global $depth, $curpath, $parsedcfg, $havedata, $listtags; $parsedcfg = array(); - $curpath = array(); - $depth = 0; - $havedata = 0; - - $xml_parser = xml_parser_create(); - - xml_set_element_handler($xml_parser, "startElement", "endElement"); - xml_set_character_data_handler($xml_parser, "cdata"); - - if (!($fp = fopen($cffile, "r"))) { - die("Error: could not open XML input\n"); - } - while ($data = fread($fp, 4096)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - log_error(sprintf("XML error: %s at line %d\n", - xml_error_string(xml_get_error_code($xml_parser)), - xml_get_current_line_number($xml_parser))); - return -1; - } - } - xml_parser_free($xml_parser); - - if (!$parsedcfg[$rootobj]) { - die("XML error: no $rootobj object found!\n"); - } + $par = new XMLReader(); + if ($par->open($cffile)) { + add_elements($parsedcfg, $par); + $par->close(); + } else + log_error("Error returned while trying to parse {$cffile}"); return $parsedcfg[$rootobj]; } @@ -197,7 +137,7 @@ function dump_xml_config_sub($arr, $indent) { foreach ($arr as $ent => $val) { if (is_array($val)) { /* is it just a list of multiple values? */ - if (in_array(strtolower($ent), $listtags)) { + if (isset($listtags[strtolower($ent)])) { foreach ($val as $cval) { if (is_array($cval)) { $xmlconfig .= str_repeat("\t", $indent); @@ -242,7 +182,7 @@ function dump_xml_config($arr, $rootobj) { $listtags = listtags(); if (isset($GLOBALS['custom_listtags'])) { foreach($GLOBALS['custom_listtags'] as $tag) { - $listtags[] = $tag; + $listtags[$tag] = $tag; } } return dump_xml_config_raw($arr, $rootobj); @@ -253,7 +193,7 @@ function dump_xml_config_pkg($arr, $rootobj) { $listtags = listtags_pkg(); if (isset($GLOBALS['custom_listtags_pkg'])) { foreach($GLOBALS['custom_listtags_pkg'] as $tag) { - $listtags[] = $tag; + $listtags[$tag] = $tag; } } return dump_xml_config_raw($arr, $rootobj); |