diff options
Diffstat (limited to 'config')
77 files changed, 3752 insertions, 1358 deletions
diff --git a/config/apache_mod_security-dev/apache_balancer.template b/config/apache_mod_security-dev/apache_balancer.template index 361a5ed4..06422125 100644 --- a/config/apache_mod_security-dev/apache_balancer.template +++ b/config/apache_mod_security-dev/apache_balancer.template @@ -6,7 +6,7 @@ $balancer_config= <<<EOF # then edit /usr/local/pkg/apache_* files. # # # # And don't forget to submit your changes to: # -# https://github.com/bsdperimeter/pfsense-packages # +# https://github.com/pfsense/pfsense-packages # ################################################################################## SetOutputFilter DEFLATE SetInputFilter DEFLATE @@ -37,4 +37,4 @@ Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ EOF; -?>
\ No newline at end of file +?> diff --git a/config/apache_mod_security-dev/apache_mod_security.inc b/config/apache_mod_security-dev/apache_mod_security.inc index cdee4f6b..57f5407b 100644 --- a/config/apache_mod_security-dev/apache_mod_security.inc +++ b/config/apache_mod_security-dev/apache_mod_security.inc @@ -321,7 +321,7 @@ function generate_apache_configuration() { # then edit /usr/local/pkg/apache_* files. # # # # And don't forget to submit your changes to: # -# https://github.com/bsdperimeter/pfsense-packages # +# https://github.com/pfsense/pfsense-packages # ################################################################################## diff --git a/config/bandwidthd/bandwidthd.inc b/config/bandwidthd/bandwidthd.inc index 8821ac76..829cdf59 100644 --- a/config/bandwidthd/bandwidthd.inc +++ b/config/bandwidthd/bandwidthd.inc @@ -46,6 +46,8 @@ function bandwidthd_install_deinstall() { exec("rm -f /usr/local/etc/rc.d/bandwidthd*"); exec("rm -rf " . PKG_BANDWIDTHD_BASE . "/htdocs"); exec("rm -f /usr/local/www/bandwidthd"); + // Remove the cron job, if it is there + install_cron_job("/bin/kill -HUP `cat /var/run/bandwidthd.pid`", false); conf_mount_ro(); config_unlock(); } @@ -62,44 +64,47 @@ function bandwidthd_install_config() { config_lock(); /* user defined values */ - $meta_refresh = $config['installedpackages']['bandwidthd']['config'][0]['meta_refresh']; + $bandwidthd_config = $config['installedpackages']['bandwidthd']['config'][0]; + $meta_refresh = $bandwidthd_config['meta_refresh']; if($meta_refresh) $meta_refresh = "meta_refresh $meta_refresh\n"; - $graph = $config['installedpackages']['bandwidthd']['config'][0]['drawgraphs']; + $graph = $bandwidthd_config['drawgraphs']; if($graph) $graph = "graph true\n"; else $graph = "graph false\n"; - $filter_text = $config['installedpackages']['bandwidthd']['config'][0]['filter']; + $filter_text = $bandwidthd_config['filter']; if($filter_text) $filter_text = "filter $filter_text\n"; - $recover_cdf = $config['installedpackages']['bandwidthd']['config'][0]['recovercdf']; + $recover_cdf = $bandwidthd_config['recovercdf']; if($recover_cdf) $recover_cdf = "recover_cdf true\n"; - $output_cdf = $config['installedpackages']['bandwidthd']['config'][0]['outputcdf']; + $output_cdf = $bandwidthd_config['outputcdf']; if($output_cdf) - $output_cdf = "output_cdf true\n"; - $promiscuous = $config['installedpackages']['bandwidthd']['config'][0]['promiscuous']; + $output_cdf_string = "output_cdf true\n"; + else + $output_cdf_string = ""; + $promiscuous = $bandwidthd_config['promiscuous']; if($promiscuous) $promiscuous = "promiscuous true\n"; else $promiscuous = "promiscuous false\n"; - $graph_cutoff = $config['installedpackages']['bandwidthd']['config'][0]['graphcutoff']; + $graph_cutoff = $bandwidthd_config['graphcutoff']; if($graph_cutoff) $graph_cutoff = "graph_cutoff $graph_cutoff\n"; - $skip_intervals = $config['installedpackages']['bandwidthd']['config'][0]['skipintervals']; + $skip_intervals = $bandwidthd_config['skipintervals']; if($skip_intervals) $skip_intervals = "skip_intervals $skip_intervals\n"; - if($config['installedpackages']['bandwidthd']['config'][0]['active_interface']){ - $ifdescrs = array($config['installedpackages']['bandwidthd']['config'][0]['active_interface']); + if($bandwidthd_config['active_interface']){ + $ifdescrs = array($bandwidthd_config['active_interface']); } else { log_error("You should specify an interface for bandwidthd to listen on. Exiting."); } - $subnets_custom = explode(';',str_replace(' ','',$config['installedpackages']['bandwidthd']['config'][0]['subnets_custom'])); + $subnets_custom = explode(';',str_replace(' ','',$bandwidthd_config['subnets_custom'])); /* initialize to "" */ $subnets = ""; @@ -180,7 +185,7 @@ $graph_cutoff $promiscuous #Log data to cdf file htdocs/log.cdf -$output_cdf +$output_cdf_string #Read back the cdf file on startup $recover_cdf @@ -208,26 +213,40 @@ EOF; fwrite($fd, $config_file); fclose($fd); + if ($g['platform'] == 'nanobsd') { + $bandwidthd_nano_dir = "/var/bandwidthd"; + $bandwidthd_htdocs_dir = $bandwidthd_nano_dir . "/htdocs"; + if (!is_dir($bandwidthd_nano_dir)) { + if (file_exists($bandwidthd_nano_dir)) { + unlink($bandwidthd_nano_dir); + } + mkdir($bandwidthd_nano_dir); + } + } else { + $bandwidthd_htdocs_dir = $bandwidthd_base_dir . "/htdocs"; + } + $rc = array(); $rc['file'] = 'bandwidthd.sh'; $rc['stop'] = <<<EOD /usr/bin/killall bandwidthd EOD; - if ($g['platform'] == 'nanobsd') { - // On nanobsd, /var/bandwidthd is created. - // In that is a real /var/bandwidth/htdocs, where the graph data is written - // A soft link to the real bandwidth program is made - /var/bandwidthd/bandwidthd - // A soft link to the etc folder with the conf file is made - /var/bandwidthd/etc - // bandwidthd is started from /var/bandwidthd with the current dir /var/bandwidth - // This way, it: - // looks in ./etc for the conf file - // writes graph files in ./htdocs - // writes cdf log files (if selected in the config) to ./ - // All of this is on the /var filesystem, which is a read-write memory disk on nanobsd - $bandwidthd_nano_dir = "/var/bandwidthd"; - $bandwidthd_htdocs_dir = $bandwidthd_nano_dir . "/htdocs"; - $rc['start'] = <<<EOD + // If this is an old config before the enable checkbox was added, then enable by default + $bandwidthd_enable = (!isset($bandwidthd_config['enable']) || ($bandwidthd_config['enable'])); + if ($bandwidthd_enable) { + if ($g['platform'] == 'nanobsd') { + // On nanobsd, /var/bandwidthd is created. + // In that is a real /var/bandwidth/htdocs, where the graph data is written + // A soft link to the real bandwidth program is made - /var/bandwidthd/bandwidthd + // A soft link to the etc folder with the conf file is made - /var/bandwidthd/etc + // bandwidthd is started from /var/bandwidthd with the current dir /var/bandwidth + // This way, it: + // looks in ./etc for the conf file + // writes graph files in ./htdocs + // writes cdf log files (if selected in the config) to ./ + // All of this is on the /var filesystem, which is a read-write memory disk on nanobsd + $rc['start'] = <<<EOD if [ ! -d "{$bandwidthd_nano_dir}" ] ; then if [ -e "{$bandwidthd_nano_dir}" ] ; then /bin/rm -f {$bandwidthd_nano_dir} @@ -252,22 +271,25 @@ if [ ! -L "{$bandwidthd_nano_dir}/etc" ] ; then fi /bin/ln -s {$bandwidthd_config_dir} {$bandwidthd_nano_dir}/etc fi - +if [ ! -f "{$bandwidthd_htdocs_dir}/legend.gif" ] ; then + /bin/cp {$bandwidthd_base_dir}/htdocs/legend.gif {$bandwidthd_htdocs_dir} +fi +if [ ! -f "{$bandwidthd_htdocs_dir}/logo.gif" ] ; then + /bin/cp {$bandwidthd_base_dir}/htdocs/logo.gif {$bandwidthd_htdocs_dir} +fi cd {$bandwidthd_nano_dir} {$bandwidthd_nano_dir}/bandwidthd cd - EOD; - if (!is_dir($bandwidthd_nano_dir)) { - if (file_exists($bandwidthd_nano_dir)) { - unlink($bandwidthd_nano_dir); - } - mkdir($bandwidthd_nano_dir); - } - } else { - $bandwidthd_htdocs_dir = $bandwidthd_base_dir . "/htdocs"; - $rc['start'] = <<<EOD + } else { + $rc['start'] = <<<EOD /usr/local/bandwidthd/bandwidthd EOD; + } + } else { + // bandwidthd is disabled, so do not put any real start commands in the script. + // This effectively disables it but keeps all the files in place (e.g. saved logs) ready to reload when it is enabled. + $rc['start'] = "return"; } /* write out rc.d start/stop file */ @@ -292,10 +314,22 @@ EOD; if (!file_exists($bandwidthd_index_file)) { exec("echo \"Please start bandwidthd to populate this directory.\" > " . $bandwidthd_index_file); } + + if (($bandwidthd_enable) && ($output_cdf)) { + // Use cron job to rotate logs every day at 00:01 + install_cron_job("/bin/kill -HUP `cat /var/run/bandwidthd.pid`", true, "1", "0"); + } + else + { + // Remove the cron job, if it is there + install_cron_job("/bin/kill -HUP `cat /var/run/bandwidthd.pid`", false); + } conf_mount_ro(); config_unlock(); stop_service("bandwidthd"); - start_service("bandwidthd"); + if ($bandwidthd_enable) { + start_service("bandwidthd"); + } } ?> diff --git a/config/bandwidthd/bandwidthd.xml b/config/bandwidthd/bandwidthd.xml index f82ac69d..f306546a 100644 --- a/config/bandwidthd/bandwidthd.xml +++ b/config/bandwidthd/bandwidthd.xml @@ -7,7 +7,7 @@ /* $Id$ */ /* ========================================================================== */ /* - authng.xml + bandwidthd.xml part of pfSense (http://www.pfSense.com) Copyright (C) 2007 to whom it may belong All rights reserved. @@ -41,10 +41,10 @@ */ /* ========================================================================== */ ]]> - </copyright> - <description>Describe your package here</description> - <requirements>Describe your package requirements here</requirements> - <faq>Currently there are no FAQ items provided.</faq> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> <name>bandwidthd</name> <version>2.0.1.4</version> <title>Bandwidthd</title> @@ -60,7 +60,7 @@ <name>bandwidthd</name> <rcfile>bandwidthd.sh</rcfile> <executable>bandwidthd</executable> - </service> + </service> <tabs> <tab> <text>BandwidthD</text> @@ -80,6 +80,12 @@ </additional_files_needed> <fields> <field> + <fielddescr>Enable bandwidthd</fielddescr> + <fieldname>enable</fieldname> + <type>checkbox</type> + <description></description> + </field> + <field> <fielddescr>Interface</fielddescr> <fieldname>active_interface</fieldname> <description>The interface that bandwidthd will bind to.</description> @@ -96,7 +102,7 @@ <field> <fielddescr>Skip intervals</fielddescr> <fieldname>skipintervals</fieldname> - <description>Number of intervals (2.5 minute) to skip between graphing. Default 0.</description> + <description>Number of intervals to skip between graphing. Default 0. Each interval is 200 seconds = 3 min 20 sec.</description> <type>input</type> </field> <field> @@ -108,19 +114,20 @@ <field> <fielddescr>Promiscuous</fielddescr> <fieldname>promiscuous</fieldname> - <description>Put interface in promiscuous mode to score to traffic that may not be routing through the host machine.</description> + <description>Put interface in promiscuous mode to see traffic that may not be routing through the host machine.<br> + Note: If the interface is connected to a switch then the interface will only see the traffic on its port.</description> <type>checkbox</type> </field> <field> <fielddescr>output_cdf</fielddescr> <fieldname>outputcdf</fieldname> - <description>Log data to cdf file htdocs/log.cdf</description> + <description>Log data to cdf files log*.cdf</description> <type>checkbox</type> </field> <field> <fielddescr>recover_cdf</fielddescr> <fieldname>recovercdf</fieldname> - <description>Read back the cdf file on startup</description> + <description>Read back the cdf files on startup</description> <type>checkbox</type> </field> <field> @@ -139,9 +146,24 @@ <field> <fielddescr>Meta Refresh</fielddescr> <fieldname>meta_refresh</fieldname> - <description>Set META REFRESH seconds (default 150, use 0 to disable).</description> + <description>Sets the interval (seconds) at which the browser graph display refreshes (default 150, use 0 to disable).</description> <type>input</type> </field> + <field> + <fielddescr>Graph and Log Info</fielddescr> + <fieldname>graph_log_info</fieldname> + <description>If draw graphs is on, then the daily report and graph html data is regenerated every (skip intervals + 1) * 200 seconds. The data volumes in the report are for the same period as the span of the graph.<br> + If output_cdf is on, then a cron job is added to rotate the log files at 00:01 each day. 6 log files are kept for each log frequency (daily, weekly, monthly, yearly). At the respective rotation intervals, the oldest log is deleted, the others are shuffled back and a new log is created.<br> + <table cellpadding=1 cellspacing=0 style="text-align: left;"> <tbody> + <tr><th> </th><th> Data Interval </th><th> Graph Span </th><th> Log Rotation </th><th> Log File Name </th></tr> + <tr><th> Daily </th><td> 200 seconds </td><td> 2 days </td><td> 1 day </td><td> log.1.[0-5].cdf </td></tr> + <tr><th> Weekly </th><td> 10 minutes </td><td> 7 days </td><td> 7 days </td><td> log.2.[0-5].cdf </td></tr> + <tr><th> Monthly </th><td> 1 hour </td><td> 35 days </td><td> 35 days </td><td> log.3.[0-5].cdf </td></tr> + <tr><th> Yearly </th><td> 12 hours </td><td> 412.5 days </td><td> 412.5 days </td><td> log.4.[0-5].cdf </td></tr> + </tbody> </table> + </description> + <type>info</type> + </field> </fields> <custom_php_resync_config_command> bandwidthd_install_config(); diff --git a/config/dansguardian/dansguardian.inc b/config/dansguardian/dansguardian.inc index 8177fe3f..b1c79a97 100755 --- a/config/dansguardian/dansguardian.inc +++ b/config/dansguardian/dansguardian.inc @@ -101,8 +101,13 @@ function sync_package_dansguardian($via_rpc=false,$install_process=false) { $boot_process="on"; } - if (is_process_running('dansguardian') && isset($boot_process) && $via_rpc==false) + if (is_process_running('dansguardian') && isset($boot_process) && $via_rpc==false){ + log_error("[Dansguardian] - Detected boot process pr:".is_process_running('dansguardian')." bp:".isset($boot_process)." rpc:".$via_rpc); return; + } + else{ + log_error("[Dansguardian] - Save settings package call pr:".is_process_running('dansguardian')." bp:".isset($boot_process)." rpc:".$via_rpc); + } #assign xml arrays if (!is_array($config['installedpackages']['dansguardian'])) @@ -921,7 +926,8 @@ EOF; #check blacklist download files if ($install_process == true){ require_once("/usr/local/www/dansguardian.php"); - fetch_blacklist(false); + fetch_blacklist(false,true); + update_output_window("Blacklist check done, continuing package config sync."); } else{ if ($dansguardian_blacklist['cron']=="force_download"){ @@ -956,7 +962,6 @@ EOF; $daemongroup = 'nobody'; } $filtergroups=($count > 1?($count -1):1); - $filterip=""; $filterports=""; foreach (explode(",", $dansguardian['interface']) as $i => $iface) { @@ -1084,7 +1089,6 @@ EOF; conf_mount_rw(); write_config(); - #update cron if ($cron_found > 0){ $config['cron']=$new_cron; @@ -1108,19 +1112,15 @@ EOF; #check virus_scanner options $libexec_dir= DANSGUARDIAN_DIR."/libexec/dansguardian/"; - if (preg_match("/clamd/",$dansguardian_config['content_scanners'])){ + if ($install_process==true) + update_output_window("Skipping clamav check during package install."); + if (preg_match("/clamd/",$dansguardian_config['content_scanners']) && $install_process==false){ if (!(file_exists('/var/db/clamav/main.cvd')||file_exists('/var/db/clamav/main.cld'))){ file_notice("Dansguardian - No antivirus database found for clamav, running freshclam in background.",""); log_error('No antivirus database found for clamav, running freshclam in background. Content-scanner may not work until freshclam finishes.'); mwexec_bg(DANSGUARDIAN_DIR.'/bin/freshclam && /usr/local/etc/rc.d/clamav-clamd'); } - - $match=array(); - $match[0]='/NO/'; - $replace=array(); - $replace[0]='YES'; - #clamdscan.conf dansguardian file $cconf=DANSGUARDIAN_DIR . "/etc/dansguardian/contentscanners/clamdscan.conf"; $cconf_file=file_get_contents($cconf); @@ -1128,7 +1128,6 @@ EOF; $cconf_file=preg_replace('/#clamdudsfile/','clamdudsfile',$cconf_file); file_put_contents($cconf, $cconf_file, LOCK_EX); } - #clamd conf file $cconf=DANSGUARDIAN_DIR."/etc/clamd.conf"; $cconf_file=file_get_contents($cconf); @@ -1136,6 +1135,11 @@ EOF; #clamd script file $script='/usr/local/etc/rc.d/clamav-clamd'; $script_file=file($script); + $new_clamav_startup=""; + $cpreg_m[0]="@NO@"; + $cpreg_m[1]="@/usr/local@"; + $cpreg_r[0]="YES"; + $cpreg_r[1]=DANSGUARDIAN_DIR; foreach ($script_file as $script_line){ if(preg_match("/command=/",$script_line)){ $new_clamav_startup.= 'if [ ! -d /var/run/clamav ];then /bin/mkdir /var/run/clamav;fi'."\n"; @@ -1147,12 +1151,12 @@ EOF; $new_clamav_startup.=$script_line; } elseif(!preg_match("/(mkdir|chown|sleep|mailscanner)/",$script_line)) { - $new_clamav_startup.=preg_replace("/NO/","YES",$script_line); - $new_clamav_startup.=preg_replace("@/usr/local@",DANSGUARDIAN_DIR,$script_line); + $new_clamav_startup.=preg_replace($cpreg_m,$cpreg_r,$script_line); } } file_put_contents($script, $new_clamav_startup, LOCK_EX); chmod ($script,0755); + if (file_exists('/var/run/dansguardian.pid') && is_process_running('clamd')){ log_error('Stopping clamav-clamd'); mwexec("$script stop"); @@ -1164,8 +1168,7 @@ EOF; mwexec_bg("$script start"); } } - } - + } #check certificate hashed $script='/usr/local/etc/rc.d/dansguardian.sh'; @@ -1200,23 +1203,58 @@ EOF; #mount read only conf_mount_ro(); + #avoid sync during boot process if (!isset($boot_process)){ - $synconchanges = $config['installedpackages']['dansguardiansync']['config'][0]['synconchanges']; - if(!$synconchanges && !$syncondbchanges) - return; - log_error("[dansguardian] dansguardian_xmlrpc_sync.php is starting."); - foreach ($config['installedpackages']['dansguardiansync']['config'] as $rs ){ - foreach($rs['row'] as $sh){ + /* Uses XMLRPC to synchronize the changes to a remote node */ + if (is_array($config['installedpackages']['dansguardiansync']['config'])){ + $dans_sync=$config['installedpackages']['dansguardiansync']['config'][0]; + $synconchanges = $dans_sync['synconchanges']; + $synctimeout = $dans_sync['synctimeout']; + switch ($synconchanges){ + case "manual": + if (is_array($dans_sync[row])){ + $rs=$dans_sync[row]; + } + else{ + log_error("[Dansguardian] xmlrpc sync is enabled but there is no hosts to push on dansguardian config."); + return; + } + break; + case "auto": + if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){ + $system_carp=$config['installedpackages']['carpsettings']['config'][0]; + $rs[0]['ipaddress']=$system_carp['synchronizetoip']; + $rs[0]['username']=$system_carp['username']; + $rs[0]['password']=$system_carp['password']; + if (! is_ipaddr($system_carp['synchronizetoip'])){ + log_error("[Dansguardian] xmlrpc sync is enabled but there is no system backup hosts to push squid config."); + return; + } + } + else{ + log_error("[Dansguardian] xmlrpc sync is enabled but there is no system backup hosts to push squid config."); + return; + } + break; + default: + return; + break; + } + if (is_array($rs)){ + log_error("[Dansguardian] xmlrpc sync is starting."); + foreach($rs as $sh){ $sync_to_ip = $sh['ipaddress']; - $password = $sh['password']; - $sync_type = $sh['sync_type']; + $password = $sh['password']; + $username = ($sh['username']?$sh['username']:"admin"); if($password && $sync_to_ip) - dansguardian_do_xmlrpc_sync($sync_to_ip, $password,$sync_type); + dansguardian_do_xmlrpc_sync($sync_to_ip,$username,$password,$sync_type,$synctimeout); } + log_error("[Dansguardian] xmlrpc sync is ending."); } - log_error("[dansguardian] dansguardian_xmlrpc_sync.php is ending."); - } + } + } + } function dansguardian_validate_input($post, &$input_errors) { @@ -1260,15 +1298,21 @@ function dansguardian_php_deinstall_command() { } } -function dansguardian_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { +function dansguardian_do_xmlrpc_sync($sync_to_ip,$username,$password,$sync_type,$synctimeout) { global $config, $g; + if(!$username) + return; + if(!$password) return; if(!$sync_to_ip) return; + if(!$synctimeout) + $synctimeout=30; + $xmlrpc_sync_neighbor = $sync_to_ip; if($config['system']['webgui']['protocol'] != "") { $synchronizetoip = $config['system']['webgui']['protocol']; @@ -1286,28 +1330,26 @@ function dansguardian_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { /* xml will hold the sections to sync */ $xml = array(); - $sync_xml=$config['installedpackages']['dansguardiansync']['config'][0]['synconchanges']; - if ($sync_xml){ - log_error("Include dansguardian config"); - $xml['dansguardian'] = $config['installedpackages']['dansguardian']; - $xml['dansguardianantivirusacl'] = $config['installedpackages']['dansguardianantivirusacl']; - $xml['dansguardianconfig'] = $config['installedpackages']['dansguardianconfig']; - $xml['dansguardianblacklist'] = $config['installedpackages']['dansguardianblacklist']; - $xml['dansguardianldap'] = $config['installedpackages']['dansguardianldap']; - $xml['dansguardiancontentacl'] = $config['installedpackages']['dansguardiancontentacl']; - $xml['dansguardianfileacl'] = $config['installedpackages']['dansguardianfileacl']; - $xml['dansguardiangroups'] = $config['installedpackages']['dansguardiangroups']; - $xml['dansguardianheaderacl'] = $config['installedpackages']['dansguardianheaderacl']; - $xml['dansguardianlimits'] = $config['installedpackages']['dansguardianlimits']; - $xml['dansguardianlog'] = $config['installedpackages']['dansguardianlog']; - $xml['dansguardianphraseacl'] = $config['installedpackages']['dansguardianphraseacl']; - $xml['dansguardianpicsacl'] = $config['installedpackages']['dansguardianpicsacl']; - $xml['dansguardiansearchacl'] = $config['installedpackages']['dansguardiansearchacl']; - $xml['dansguardiansiteacl'] = $config['installedpackages']['dansguardiansiteacl']; - $xml['dansguardianurlacl'] = $config['installedpackages']['dansguardianurlacl']; - $xml['dansguardianusers'] = $config['installedpackages']['dansguardianusers']; + log_error("Include dansguardian config"); + $xml['dansguardian'] = $config['installedpackages']['dansguardian']; + $xml['dansguardianantivirusacl'] = $config['installedpackages']['dansguardianantivirusacl']; + $xml['dansguardianconfig'] = $config['installedpackages']['dansguardianconfig']; + $xml['dansguardianblacklist'] = $config['installedpackages']['dansguardianblacklist']; + $xml['dansguardianldap'] = $config['installedpackages']['dansguardianldap']; + $xml['dansguardiancontentacl'] = $config['installedpackages']['dansguardiancontentacl']; + $xml['dansguardianfileacl'] = $config['installedpackages']['dansguardianfileacl']; + $xml['dansguardiangroups'] = $config['installedpackages']['dansguardiangroups']; + $xml['dansguardianheaderacl'] = $config['installedpackages']['dansguardianheaderacl']; + $xml['dansguardianlimits'] = $config['installedpackages']['dansguardianlimits']; + $xml['dansguardianlog'] = $config['installedpackages']['dansguardianlog']; + $xml['dansguardianphraseacl'] = $config['installedpackages']['dansguardianphraseacl']; + $xml['dansguardianpicsacl'] = $config['installedpackages']['dansguardianpicsacl']; + $xml['dansguardiansearchacl'] = $config['installedpackages']['dansguardiansearchacl']; + $xml['dansguardiansiteacl'] = $config['installedpackages']['dansguardiansiteacl']; + $xml['dansguardianurlacl'] = $config['installedpackages']['dansguardianurlacl']; + $xml['dansguardianusers'] = $config['installedpackages']['dansguardianusers']; + $xml['dansguardianips'] = $config['installedpackages']['dansguardianips']; - } if (count($xml) > 0){ /* assemble xmlrpc payload */ $params = array( @@ -1321,18 +1363,18 @@ function dansguardian_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { $method = 'pfsense.merge_installedpackages_section_xmlrpc'; $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); - $cli->setCredentials('admin', $password); + $cli->setCredentials($username, $password); if($g['debug']) $cli->setDebug(1); - /* send our XMLRPC message and timeout after 30 seconds */ - $resp = $cli->send($msg, "30"); + /* send our XMLRPC message and timeout after $synctimeout seconds */ + $resp = $cli->send($msg, $synctimeout); if(!$resp) { $error = "A communications error occurred while attempting dansguardian XMLRPC sync with {$url}:{$port}."; log_error($error); file_notice("sync_settings", $error, "dansguardian Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); - $resp = $cli->send($msg, "30"); + $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting dansguardian XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "dansguardian Settings Sync", ""); @@ -1354,15 +1396,15 @@ function dansguardian_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { log_error("dansguardian XMLRPC reload data {$url}:{$port}."); $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); - $cli->setCredentials('admin', $password); - $resp = $cli->send($msg, "30"); + $cli->setCredentials($username, $password); + $resp = $cli->send($msg, $synctimeout); if(!$resp) { $error = "A communications error occurred while attempting dansguardian XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; log_error($error); file_notice("sync_settings", $error, "dansguardian Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); - $resp = $cli->send($msg, "30"); + $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting dansguardian XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "dansguardian Settings Sync", ""); @@ -1372,4 +1414,4 @@ function dansguardian_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { } } -?> +?>
\ No newline at end of file diff --git a/config/dansguardian/dansguardian.php b/config/dansguardian/dansguardian.php index d4dcf46c..b9c972a1 100644 --- a/config/dansguardian/dansguardian.php +++ b/config/dansguardian/dansguardian.php @@ -39,11 +39,19 @@ require_once("/etc/inc/pkg-utils.inc"); require_once("/etc/inc/globals.inc"); require_once("/usr/local/pkg/dansguardian.inc"); -function fetch_blacklist($log_notice=true) { +function fetch_blacklist($log_notice=true,$install_process=false) { global $config,$g; - $url=$config['installedpackages']['dansguardianblacklist']['config'][0]['url']; - if (is_url($url)) { - conf_mount_rw(); + if (is_array($config['installedpackages']['dansguardianblacklist']) && is_array($config['installedpackages']['dansguardianblacklist']['config'])){ + $url=$config['installedpackages']['dansguardianblacklist']['config'][0]['url']; + $uw="Found a previouns install, checking Blacklist config..."; + } + else{ + $uw="Found a clean install, reading default access lists..."; + } + conf_mount_rw(); + if ($install_process == true) + update_output_window($uw); + if (isset($url) && is_url($url)) { if ($log_notice==true){ print "file download start.."; unlink_if_exists("/usr/local/pkg/blacklist.tgz"); @@ -82,11 +90,13 @@ function fetch_blacklist($log_notice=true) { } } else { - if (!empty($url)) + if ($install_process==true) + read_lists(false,$uw); + elseif (!empty($url)) file_notice("Dansguardian - Blacklist url is invalid.",""); } } -function read_lists($log_notice=true){ +function read_lists($log_notice=true,$uw=""){ global $config,$g; $group_type=array(); $dir=DANSGUARDIAN_DIR . "/etc/dansguardian/lists"; @@ -152,12 +162,14 @@ function read_lists($log_notice=true){ $edit_file=preg_replace('/size.19/','size>5',$edit_file); file_put_contents("/usr/local/pkg/dansguardian_".$edit_xml."_acl.xml",$edit_file,LOCK_EX); } - if($log_notice==true) - file_notice("Dansguardian - Blacklist applied, check site and URL access lists for categories",""); - #foreach($config['installedpackages'] as $key => $values) - # if (preg_match("/dansguardian(phrase|black|white)lists/",$key)) - # print "$key\n"; write_config(); + if($log_notice==true && $uw==""){ + file_notice("Dansguardian - Blacklist applied, check site and URL access lists for categories",""); + } + else{ + $uw.="done\n"; + update_output_window($uw); + } } if ($argv[1]=="update_lists") diff --git a/config/dansguardian/dansguardian_sync.xml b/config/dansguardian/dansguardian_sync.xml index 7f714051..9401253c 100755 --- a/config/dansguardian/dansguardian_sync.xml +++ b/config/dansguardian/dansguardian_sync.xml @@ -104,8 +104,30 @@ <field> <fielddescr>Automatically sync dansguardian configuration changes</fielddescr> <fieldname>synconchanges</fieldname> - <description>pfSense will automatically sync changes to the hosts defined below.</description> - <type>checkbox</type> + <description>Select a sync method for dansguardian.</description> + <type>select</type> + <required/> + <default_value>auto</default_value> + <options> + <option><name>Sync to configured system backup server</name><value>auto</value></option> + <option><name>Sync to host(s) defined below</name><value>manual</value></option> + <option><name>Do not sync this package configuration</name><value>disabled</value></option> + </options> + </field> + <field> + <fielddescr>Sync timeout</fielddescr> + <fieldname>synctimeout</fieldname> + <description>Select sync max wait time</description> + <type>select</type> + <required/> + <default_value>250</default_value> + <options> + <option><name>250 seconds(Default)</name><value>250</value></option> + <option><name>120 seconds</name><value>120</value></option> + <option><name>90 seconds</name><value>90</value></option> + <option><name>60 seconds</name><value>60</value></option> + <option><name>30 seconds</name><value>30</value></option> + </options> </field> <field> <fielddescr>Remote Server</fielddescr> diff --git a/config/filemgr/file_manager.tmp b/config/filemgr/file_manager.tmp index 9699ec22..8c5ee1c5 100644 --- a/config/filemgr/file_manager.tmp +++ b/config/filemgr/file_manager.tmp @@ -477,8 +477,8 @@ if('ok' == 'ok'){ </div> <form id="path" name="path" method="get" action="" class="path"> - <input type="text" name="p" id="location" value="<?php echo $current_folder; ?>" /> - <img src="rbfmimg/go.png" name="go" width="35" height="18" id="go" alt="go" title="go" /> + <input name="p" type="text" id="location" value="<?php echo $current_folder; ?>" /> + <input name="go" type="image" id="go" value="Go" src="rbfmimg/go.png" style="width:35;height:18" /> </form> <div class="url_path"><br />URL path: <a href="/<?php echo $url_path; ?>" target="_blank"><?php echo $url_path; ?></a></div> <div class="container"> <?php echo $container; ?> <?php echo $error; ?> </div> diff --git a/config/freeradius2/freeradius.inc b/config/freeradius2/freeradius.inc index 38093780..eecfec84 100644 --- a/config/freeradius2/freeradius.inc +++ b/config/freeradius2/freeradius.inc @@ -5,6 +5,7 @@ freeradius.inc part of pfSense (http://www.pfSense.com) Copyright (C) 2011 - 2012 Alexander Wilke <nachtfalkeaw@web.de> + Copyright (C) 2013 Marcello Coutinho All rights reserved. Based on m0n0wall (http://m0n0.ch/wall) @@ -47,16 +48,24 @@ require_once("services.inc"); // Check pfSense version $pfs_version = substr(trim(file_get_contents("/etc/version")),0,3); -switch ($pfs_version) { - case "1.2": - case "2.0": - define('FREERADIUS_BASE', '/usr/local'); - break; - default: - define('FREERADIUS_BASE', '/usr/pbi/freeradius-' . php_uname("m")); +if ($pfs_version > 2.0){ + define('FREERADIUS_BASE', '/usr/pbi/freeradius-' . php_uname("m")); +} +else{ + define('FREERADIUS_BASE', '/usr/local'); } -// End: Check pfSense version +// Check freeradius lib version + $frlib=""; + $libfiles = scandir(FREERADIUS_BASE . "/lib/"); + foreach ($libfiles as $libfile){ + if (preg_match("/freeradius-/",$libfile)) + $frlib=FREERADIUS_BASE . "/lib/{$libfile}"; + } + if ($frlib == ""){ + log_error("freeRADIUS - No freeradius lib found on ".FREERADIUS_BASE."/lib"); + } + function freeradius_deinstall_command() { if (substr(trim(file_get_contents("/etc/version")),0,3) == "2.0") { exec("cd /var/db/pkg && pkg_delete `ls | grep freeradius`"); @@ -68,7 +77,7 @@ function freeradius_deinstall_command() { function freeradius_install_command() { global $config; conf_mount_rw(); - + // put the constant to a variable $varFREERADIUS_BASE = FREERADIUS_BASE; @@ -79,7 +88,7 @@ function freeradius_install_command() { exec("mkdir " . FREERADIUS_BASE . "/etc/raddb/scripts"); if (!file_exists("/var/log/radutmp")) { exec("touch /var/log/radutmp"); } if (!file_exists("/var/log/radwtmp")) { exec("touch /var/log/radwtmp"); } - exec("chown -R root:wheel " . FREERADIUS_BASE . "/etc/raddb && chown -R root:wheel " . FREERADIUS_BASE . "/lib/freeradius-2.1.12 && chown -R root:wheel /var/log/radacct"); + exec("chown -R root:wheel " . FREERADIUS_BASE . "/etc/raddb && chown -R root:wheel {$frlib} && chown -R root:wheel /var/log/radacct"); // creating a backup file of the original policy.conf no matter if user checked this or not if (!file_exists(FREERADIUS_BASE . "/etc/raddb/policy.conf.backup")) { @@ -213,7 +222,7 @@ raddbdir = \${sysconfdir}/raddb radacctdir = \${logdir}/radacct confdir = \${raddbdir} run_dir = \${localstatedir}/run -libdir = \${exec_prefix}/lib/freeradius-2.1.12 +libdir = {$frlib} pidfile = \${run_dir}/radiusd.pid db_dir = \${raddbdir} name = radiusd @@ -948,12 +957,18 @@ if ($eapconf['vareapconfchoosecertmanager'] == 'on') { if(base64_decode($ca_cert['crt'])) { + $crl_cert = lookup_crl($eapconf["ssl_ca_crl"]); + if ($crl_cert != false){ + $crl=base64_decode($crl_cert['text']); + $check_crl="check_crl = yes"; + } + else{ + $check_crl="check_crl = no"; + } file_put_contents(FREERADIUS_BASE . "/etc/raddb/certs/ca_cert.pem", - base64_decode($ca_cert['crt'])); + base64_decode($ca_cert['crt']). $crl); $conf['ssl_ca_cert'] = FREERADIUS_BASE . "/etc/raddb/certs/ca_cert.pem"; } - - $svr_cert = lookup_cert($eapconf["ssl_server_cert"]); if ($svr_cert != false) { if(base64_decode($svr_cert['prv'])) { @@ -970,7 +985,7 @@ if ($eapconf['vareapconfchoosecertmanager'] == 'on') { $conf['ssl_server_cert'] = FREERADIUS_BASE . "/etc/raddb/certs/server_cert.pem"; } - + /* Not needed anymore because pfsense can do this by default if ($eapconf['vareapconfenableclientp12'] == 'on') { $svr_cert = lookup_cert($eapconf["ssl_client_cert"]); if ($svr_cert != false) { @@ -990,7 +1005,7 @@ if ($eapconf['vareapconfchoosecertmanager'] == 'on') { exec("openssl pkcs12 -export -in " . FREERADIUS_BASE . "/etc/raddb/certs/client_cert.pem -inkey " . FREERADIUS_BASE . "/etc/raddb/certs/client_key.pem -out " . FREERADIUS_BASE . "/etc/raddb/certs/client_cert.p12 -passout pass\:"); } - + */ $conf['ssl_cert_dir'] = FREERADIUS_BASE . '/etc/raddb/certs'; } @@ -1055,7 +1070,7 @@ else { random_file = \${certdir}/random fragment_size = $vareapconffragmentsize include_length = $vareapconfincludelength - # check_crl = yes + {$check_crl} CA_path = \${cadir} $vareapconfcheckcertissuer $vareapconfcheckcertcn @@ -1120,6 +1135,18 @@ function freeradius_get_ca_certs() { } // Gets started from freeradiuseapconf.xml +function freeradius_get_ca_crl() { + global $config; + $crl_arr = array(); + $crl_arr[] = array('refid' => 'none', 'descr' => 'none'); + + foreach ($config['crl'] as $crl) { + $crl_arr[] = array('refid' => $crl['refid'], 'descr' => $crl['descr']); + } + return $crl_arr; +} + +// Gets started from freeradiuseapconf.xml function freeradius_get_server_certs() { global $config; $cert_arr = array(); diff --git a/config/freeradius2/freeradiuseapconf.xml b/config/freeradius2/freeradiuseapconf.xml index ac761523..a2dd2b99 100644 --- a/config/freeradius2/freeradiuseapconf.xml +++ b/config/freeradius2/freeradiuseapconf.xml @@ -10,6 +10,7 @@ freeradiuseapconf.xml part of pfSense (http://www.pfSense.com) Copyright (C) 2011 - 2012 Alexander Wilke <nachtfalkeaw@web.de> + Copyright (C) 2013 Marcello Coutinho (revocation list code) All rights reserved. Based on m0n0wall (http://m0n0.ch/wall) @@ -171,7 +172,7 @@ <b>uncheked</b>: FreeRADIUS Cert-Manager (not recommended) (Default: unchecked)<br> <b>cheked</b>: Firewall Cert-Manager (recommended)]]></description> <type>checkbox</type> - <enablefields>ssl_ca_cert,ssl_server_cert,vareapconfenableclientp12</enablefields> + <enablefields>ssl_ca_cert,ssl_ca_crl,ssl_server_cert</enablefields> </field> <field> <fielddescr>Private Key Password</fielddescr> @@ -191,6 +192,18 @@ <source_value>refid</source_value> </field> <field> + <fielddescr>SSL Revocation List</fielddescr> + <fieldname>ssl_ca_crl</fieldname> + <description><![CDATA[Choose the SSL CA Certficate revocation list here which you created with the firewall's Cert Manager.<br> + <b>HINT:</b> You need to restart freeradius service after adding a certificate to the CRL.<br> + Choose "none" if you do not use any kind of certificates or the freeradius Cert Manager. (Default: none)]]></description> + <type>select_source</type> + <source><![CDATA[freeradius_get_ca_crl()]]></source> + <source_name>descr</source_name> + <source_value>refid</source_value> + </field> + + <field> <fielddescr>SSL Server Certificate</fielddescr> <fieldname>ssl_server_cert</fieldname> <description><![CDATA[Choose the SSL Server Certficate here which you created with the firewall's Cert Manager.<br> @@ -200,6 +213,7 @@ <source_name>descr</source_name> <source_value>refid</source_value> </field> + <!-- Not needed anymore because pfsense itself can do this now> <field> <fielddescr>Create client.p12 for export</fielddescr> <fieldname>vareapconfenableclientp12</fieldname> @@ -217,6 +231,7 @@ <source_name>descr</source_name> <source_value>refid</source_value> </field> + --> <field> <name>EAP-TLS</name> <type>listtopic</type> @@ -470,4 +485,4 @@ <custom_php_resync_config_command> freeradius_eapconf_resync(); </custom_php_resync_config_command> -</packagegui>
\ No newline at end of file +</packagegui> diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc index 0f6de3de..735ab196 100644 --- a/config/haproxy-devel/haproxy.inc +++ b/config/haproxy-devel/haproxy.inc @@ -599,7 +599,7 @@ function haproxy_writeconf($configfile) { //ssl crt ./server.pem ca-file ./ca.crt verify optional crt-ignore-err all crl-file ./ca_crl.pem $ssl_crt=" crt /var/etc/{$backend['name']}.{$backend['port']}.crt"; $cert = lookup_cert($backend['ssloffloadcert']); - $certcontent = base64_decode($cert['crt']).base64_decode($cert['prv']); + $certcontent = base64_decode($cert['crt'])."\r\n".base64_decode($cert['prv']); file_put_contents("/var/etc/{$backend['name']}.{$backend['port']}.crt", $certcontent); unset($certcontent); }else{ diff --git a/config/lightsquid/sqstat.php b/config/lightsquid/sqstat.php index a56b604a..7b12b970 100644 --- a/config/lightsquid/sqstat.php +++ b/config/lightsquid/sqstat.php @@ -61,7 +61,7 @@ if ($_REQUEST['getactivity']) $pgtitle = "Proxy Squid: Realtime stat (sqstat)"; require_once("head.inc"); - +$csrf_token= csrf_get_tokens(); ?> <link href="sqstat.css" rel="stylesheet" type="text/css"/> @@ -79,7 +79,7 @@ function el(id) { function getactivity(action) { var url = "<?php echo ($_SERVER["PHP_SELF"]); ?>"; - var pars = "getactivity=yes"; + var pars = "getactivity=yes" + "<? echo '&__csrf_magic='.$csrf_token ?>"; var myAjax = new Ajax.Request( url, { @@ -414,4 +414,4 @@ function sqstat_get_real_interface_address($iface) return array($ip, long2ip(hexdec($netmask))); } -?>
\ No newline at end of file +?> diff --git a/config/mailreport/mail_reports.inc b/config/mailreport/mail_reports.inc index 8ab31301..85b67ddf 100644 --- a/config/mailreport/mail_reports.inc +++ b/config/mailreport/mail_reports.inc @@ -29,6 +29,7 @@ POSSIBILITY OF SUCH DAMAGE. */ +require_once("globals.inc"); require_once("config.inc"); require_once("filter.inc"); require_once("rrd.inc"); @@ -42,6 +43,28 @@ $graph_length = array( "year" => 31622400, "4year" => 126489600); +$logfile_friendly = array( + "dhcpd" => "DHCP", + "filter" => "Firewall (raw)", + "gateways" => "Gateway Events", + "installer" => "Installation", + "ipsec" => "IPsec VPN", + "l2tps" => "L2TP Server (raw)", + "lighttpd" => "Web Server (lighttpd)", + "ntpd" => "NTP", + "openvpn" => "OpenVPN", + "poes" => "PPPoE Server (raw)", + "portalauth" => "Captive Portal Authentication", + "ppp" => "PPP", + "pptps" => "PPTP Server (raw)", + "relayd" => "Load Balancer (relayd)", + "resolver" => "DNS Resolver", + "routing" => "Routing", + "system" => "System", + "vpn" => "PPTP/L2TP/PPPoE Server Login Events", + "wireless" => "Wireless" +); + function get_dates($curperiod, $graph) { global $graph_length; $now = time(); @@ -162,7 +185,7 @@ function set_mail_report_cron_jobs($a_mailreports) { include('phpmailer/class.phpmailer.php'); -function mail_report_send($headertext, $attachments) { +function mail_report_send($headertext, $cmdtext, $logtext, $attachments) { global $config, $g; if (empty($config['notifications']['smtp']['ipaddress'])) @@ -191,7 +214,11 @@ function mail_report_send($headertext, $attachments) { $address = $config['notifications']['smtp']['notifyemailaddress']; $mail->AddAddress($address, "Report Recipient"); $mail->Subject = "{$config['system']['hostname']}.{$config['system']['domain']} Graph Report: {$headertext}"; - $mail->Body .= "This is a periodic graph report from your firewall, {$config['system']['hostname']}.{$config['system']['domain']}.<br/><br/>Current report: {$headertext}\n"; + $mail->Body .= "This is a periodic report from your firewall, {$config['system']['hostname']}.{$config['system']['domain']}.<br /><br />Current report: {$headertext}<br />\n<br />\n"; + if (!empty($cmdtext)) + $mail->Body .= $cmdtext; + if (!empty($logtext)) + $mail->Body .= $logtext; if(is_array($attachments)) { foreach($attachments as $filename) { $shortname = basename($filename); @@ -203,7 +230,7 @@ function mail_report_send($headertext, $attachments) { if(!$mail->Send()) { echo "Mailer Error: " . $mail->ErrorInfo; } else { - echo "<strong>Message sent to {$userid}!</strong>\n"; + echo "<strong>Message sent to {$address}!</strong>\n"; } } @@ -1201,4 +1228,32 @@ function timeDiff($time, $opt = array()) { return $str; } +function mail_report_get_log($logfile, $tail, $grepfor) { + global $g, $config; + $logfile = "{$g['varlog_path']}/{$logfile}"; + $logarr = ""; + $grepline = " "; + if(is_array($grepfor)) + foreach($grepfor as $agrep) + $grepline .= " | grep \"$agrep\""; + if($config['system']['disablesyslogclog']) { + exec("cat {$logfile}{$grepline} | /usr/bin/tail -n {$tail}", $logarr); + } else { + if(isset($config['system']['usefifolog'])) { + exec("/usr/sbin/fifolog_reader {$logfile}{$grepline} | /usr/bin/tail -n {$tail}", $logarr); + } else { + exec("/usr/sbin/clog {$logfile}{$grepline}| grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/tail -n {$tail}", $logarr); + } + } + return($logarr); +} + +function get_friendly_log_name($logfile) { + global $logfile_friendly; + $friendly = str_replace(".log", "", $logfile); + if (!empty($logfile_friendly[$friendly])) + $friendly = $logfile_friendly[$friendly]; + return $friendly; +} + ?> diff --git a/config/mailreport/mail_reports_generate.php b/config/mailreport/mail_reports_generate.php index 7ff7b71e..a784c596 100644 --- a/config/mailreport/mail_reports_generate.php +++ b/config/mailreport/mail_reports_generate.php @@ -53,17 +53,42 @@ if (!$config['mailreports']['schedule'][$id]) exit; $thisreport = $config['mailreports']['schedule'][$id]; +$cmds = $thisreport['cmd']['row']; +$logs = $thisreport['log']['row']; $graphs = $thisreport['row']; -// No graphs on the report, bail! -if (!is_array($graphs) || !(count($graphs) > 0)) - exit; +// If there is nothing to do, bail! +if ((!is_array($cmds) || !(count($cmds) > 0)) + && (!is_array($logs) || !(count($logs) > 0)) + && (!is_array($graphs) || !(count($graphs) > 0))) + return; // Print report header +// Print command output +$cmdtext = ""; +foreach ($cmds as $cmd) { + $output = ""; + $cmdtext .= "Command output: {$cmd['descr']} (" . htmlspecialchars($cmd['detail']) . ")<br />\n"; + exec($cmd['detail'], $output); + $cmdtext .= "<pre>\n"; + $cmdtext .= implode("\n", $output); + $cmdtext .= "\n</pre>"; +} + +// Print log output +$logtext = ""; +foreach ($logs as $log) { + $lines = empty($log['lines']) ? 50 : $log['lines']; + $filter = empty($log['detail']) ? null : array($log['detail']); + $logtext .= "Log output: " . get_friendly_log_name($log['logfile']) . " ({$log['logfile']})<br />\n"; + $logtext .= "<pre>\n"; + $logtext .= implode("\n", mail_report_get_log($log['logfile'], $lines, $filter)); + $logtext .= "\n</pre>"; +} + // For each graph, print a header and the graph $attach = array(); -$idx=0; foreach ($graphs as $thisgraph) { $dates = get_dates($thisgraph['period'], $thisgraph['timespan']); $start = $dates['start']; @@ -71,6 +96,6 @@ foreach ($graphs as $thisgraph) { $attach[] = mail_report_generate_graph($thisgraph['graph'], $thisgraph['style'], $thisgraph['timespan'], $start, $end); } -mail_report_send($thisreport['descr'], $attach); +mail_report_send($thisreport['descr'], $cmdtext, $logtext, $attach); ?>
\ No newline at end of file diff --git a/config/mailreport/mailreport.xml b/config/mailreport/mailreport.xml index 613ac42f..d27d3a28 100644 --- a/config/mailreport/mailreport.xml +++ b/config/mailreport/mailreport.xml @@ -37,7 +37,7 @@ ]]> </copyright> <name>mailreport</name> - <version>1.0</version> + <version>2.0.4</version> <title>Status: Mail Reports</title> <additional_files_needed> <prefix>/usr/local/bin/</prefix> @@ -70,11 +70,19 @@ </additional_files_needed> <additional_files_needed> <prefix>/usr/local/www/</prefix> + <item>http://www.pfsense.com/packages/config/mailreport/status_mail_report_add_cmd.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <item>http://www.pfsense.com/packages/config/mailreport/status_mail_report_add_log.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> <item>http://www.pfsense.com/packages/config/mailreport/status_mail_report_add_graph.php</item> </additional_files_needed> <menu> - <name>RRD E-Mail Reports</name> - <tooltiptext>Setup periodic e-mail reports with RRD graphs.</tooltiptext> + <name>E-Mail Reports</name> + <tooltiptext>Setup periodic e-mail reports.</tooltiptext> <section>Status</section> <url>/status_mail_report.php</url> </menu> diff --git a/config/mailreport/status_mail_report.php b/config/mailreport/status_mail_report.php index 4dc195bc..b1705fac 100644 --- a/config/mailreport/status_mail_report.php +++ b/config/mailreport/status_mail_report.php @@ -74,11 +74,13 @@ include("head.inc"); <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td><div id="mainarea"> <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr><td colspan="4">Here you can define a list of reports, containing multiple RRD graphs, to be sent by e-mail. </td></tr> + <tr><td colspan="4">Here you can define a list of reports to be sent by e-mail. </td></tr> <tr><td> </td></tr> <tr> - <td width="45%" class="listhdr"><?=gettext("Description");?></td> - <td width="35%" class="listhdr"><?=gettext("Schedule");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="25%" class="listhdr"><?=gettext("Schedule");?></td> + <td width="10%" class="listhdr"><?=gettext("Cmds");?></td> + <td width="10%" class="listhdr"><?=gettext("Logs");?></td> <td width="10%" class="listhdr"><?=gettext("Graphs");?></td> <td width="10%" class="list"><a href="status_mail_report_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> </tr> @@ -86,6 +88,8 @@ include("head.inc"); <tr ondblclick="document.location='status_mail_report_edit.php?id=<?=$i;?>'"> <td class="listlr"><?php echo $mailreport['descr']; ?></td> <td class="listlr"><?php echo $mailreport['schedule_friendly']; ?></td> + <td class="listlr"><?php echo count($mailreport['cmd']['row']); ?></td> + <td class="listlr"><?php echo count($mailreport['log']['row']); ?></td> <td class="listlr"><?php echo count($mailreport['row']); ?></td> <td valign="middle" nowrap class="list"> <a href="status_mail_report_edit.php?id=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a> @@ -95,7 +99,7 @@ include("head.inc"); </tr> <?php $i++; endforeach; ?> <tr> - <td class="list" colspan="3"></td> + <td class="list" colspan="5"></td> <td class="list"><a href="status_mail_report_edit.php"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> </tr> <tr> diff --git a/config/mailreport/status_mail_report_add_cmd.php b/config/mailreport/status_mail_report_add_cmd.php new file mode 100644 index 00000000..7693f7a4 --- /dev/null +++ b/config/mailreport/status_mail_report_add_cmd.php @@ -0,0 +1,146 @@ +<?php +/* $Id$ */ +/* + status_rrd_graph.php + Part of pfSense + Copyright (C) 2011 Jim Pingle <jimp@pfsense.org> + Portions Copyright (C) 2007-2011 Seth Mos <seth.mos@dds.nl> + 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. +*/ +/* + pfSense_MODULE: system +*/ + +##|+PRIV +##|*IDENT=page-status-rrdgraphs +##|*NAME=Status: RRD Graphs page +##|*DESCR=Allow access to the 'Status: RRD Graphs' page. +##|*MATCH=status_rrd_graph.php* +##|-PRIV + +require("guiconfig.inc"); +require_once("mail_reports.inc"); + +$reportid = $_REQUEST['reportid']; +$id = $_REQUEST['id']; + +if (!is_array($config['mailreports']['schedule'])) + $config['mailreports']['schedule'] = array(); + +$a_mailreports = &$config['mailreports']['schedule']; + +if (!isset($reportid) || !isset($a_mailreports[$reportid])) { + header("Location: status_mail_report.php"); + return; +} + +if (!is_array($a_mailreports[$reportid]['cmd']['row'])) { + $a_mailreports[$reportid]['cmd'] = array(); + $a_mailreports[$reportid]['cmd']['row'] = array(); +} +$a_cmds = $a_mailreports[$reportid]['cmd']['row']; + +if (isset($id) && $a_cmds[$id]) { + $pconfig = $a_cmds[$id]; +} else { + $pconfig = array(); +} + +if (isset($id) && !($a_cmds[$id])) { + header("Location: status_mail_report_edit.php?id={$reportid}"); + return; +} + +if ($_POST) { + unset($_POST['__csrf_magic']); + $pconfig = $_POST; + + if (isset($id) && $a_cmds[$id]) + $a_cmds[$id] = $pconfig; + else + $a_cmds[] = $pconfig; + + $a_mailreports[$reportid]['cmd']['row'] = $a_cmds; + + write_config(); + header("Location: status_mail_report_edit.php?id={$reportid}"); + return; +} + + +$pgtitle = array(gettext("Status"),gettext("Add Mail Report Command")); +include("head.inc"); +?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td><div id="mainarea"> + <form action="status_mail_report_add_cmd.php" method="post" name="iform" id="iform"> + <table class="tabcont" width="100%" border="0" cellpadding="1" cellspacing="1"> + <tr> + <td class="listtopic" colspan="2">Command Settings</td> + </tr> + <tr> + <td width="20%" class="listhdr"> + <?=gettext("Name:");?> + </td> + <td width="80%" class="listhdr"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="20" value="<?=htmlspecialchars($pconfig['descr']);?>"> + </td> + </tr> + <tr> + <td class="listhdr"> + <?=gettext("Command:");?> + </td> + <td class="listhdr"> + <input name="detail" type="text" class="formfld unknown" id="detail" size="60" value="<?=htmlspecialchars($pconfig['detail']);?>"> + </td> + </tr> + <tr> + <td> </td> + <td> + <br/>NOTE: Use full paths to commands to ensure they run properly. The command will be run during the report and its stdout output will be included in the report body. Be extremely careful what commands you choose to run, the same warnings apply as those when using Diagnostics > Command. + <br/> + <br/>Do not use this solely as a way to run a command on a schedule, use the Cron package for that purpose instead. + </td> + </tr> + <tr> + <td colspan="2" align="center"> + <input name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> + <a href="status_mail_report_edit.php?id=<?php echo $reportid;?>"><input name="cancel" type="button" class="formbtn" value="<?=gettext("Cancel");?>"></a> + <input name="reportid" type="hidden" value="<?=htmlspecialchars($reportid);?>"> + <?php if (isset($id) && $a_graphs[$id]): ?> + <input name="id" type="hidden" value="<?=htmlspecialchars($id);?>"> + <?php endif; ?> + </td> + <td></td> + </tr> + </table> + </form> + </div></td></tr> +</table> + +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/mailreport/status_mail_report_add_graph.php b/config/mailreport/status_mail_report_add_graph.php index c0287367..165124f3 100644 --- a/config/mailreport/status_mail_report_add_graph.php +++ b/config/mailreport/status_mail_report_add_graph.php @@ -50,13 +50,8 @@ if(! isset($config['rrd']['enable'])) { header("Location: status_rrd_graph_settings.php"); } -$reportid = $_GET['reportid']; -if (isset($_POST['reportid'])) - $reportid = $_POST['reportid']; - -$id = $_GET['id']; -if (isset($_POST['id'])) - $id = $_POST['id']; +$reportid = $_REQUEST['reportid']; +$id = $_REQUEST['id']; if (!is_array($config['mailreports']['schedule'])) $config['mailreports']['schedule'] = array(); @@ -65,7 +60,7 @@ $a_mailreports = &$config['mailreports']['schedule']; if (!isset($reportid) || !isset($a_mailreports[$reportid])) { header("Location: status_mail_report.php"); - exit; + return; } if (!is_array($a_mailreports[$reportid]['row'])) @@ -80,7 +75,7 @@ if (isset($id) && $a_graphs[$id]) { if (isset($id) && !($a_graphs[$id])) { header("Location: status_mail_report_edit.php?id={$reportid}"); - exit; + return; } @@ -159,7 +154,7 @@ if ($_POST) { write_config(); header("Location: status_mail_report_edit.php?id={$reportid}"); - exit; + return; } diff --git a/config/mailreport/status_mail_report_add_log.php b/config/mailreport/status_mail_report_add_log.php new file mode 100644 index 00000000..75d092b5 --- /dev/null +++ b/config/mailreport/status_mail_report_add_log.php @@ -0,0 +1,162 @@ +<?php +/* $Id$ */ +/* + status_rrd_graph.php + Part of pfSense + Copyright (C) 2011 Jim Pingle <jimp@pfsense.org> + Portions Copyright (C) 2007-2011 Seth Mos <seth.mos@dds.nl> + 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. +*/ +/* + pfSense_MODULE: system +*/ + +##|+PRIV +##|*IDENT=page-status-rrdgraphs +##|*NAME=Status: RRD Graphs page +##|*DESCR=Allow access to the 'Status: RRD Graphs' page. +##|*MATCH=status_rrd_graph.php* +##|-PRIV + +require("guiconfig.inc"); +require_once("mail_reports.inc"); + +$reportid = $_REQUEST['reportid']; +$id = $_REQUEST['id']; + +if (!is_array($config['mailreports']['schedule'])) + $config['mailreports']['schedule'] = array(); + +$a_mailreports = &$config['mailreports']['schedule']; + +if (!isset($reportid) || !isset($a_mailreports[$reportid])) { + header("Location: status_mail_report.php"); + return; +} + +if (!is_array($a_mailreports[$reportid]['log']['row'])) { + $a_mailreports[$reportid]['log'] = array(); + $a_mailreports[$reportid]['log']['row'] = array(); +} +$a_logs = $a_mailreports[$reportid]['log']['row']; + +if (isset($id) && $a_logs[$id]) { + $pconfig = $a_logs[$id]; +} else { + $pconfig = array(); +} + +if (isset($id) && !($a_logs[$id])) { + header("Location: status_mail_report_edit.php?id={$reportid}"); + return; +} + +$logpath = "/var/log/"; +chdir($logpath); +$logfiles = glob("*.log"); + +sort($logfiles); + +if ($_POST) { + unset($_POST['__csrf_magic']); + $pconfig = $_POST; + + if (isset($id) && $a_logs[$id]) + $a_logs[$id] = $pconfig; + else + $a_logs[] = $pconfig; + + $a_mailreports[$reportid]['log']['row'] = $a_logs; + + write_config(); + header("Location: status_mail_report_edit.php?id={$reportid}"); + return; +} + + +$pgtitle = array(gettext("Status"),gettext("Add Mail Report Log")); +include("head.inc"); +?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td><div id="mainarea"> + <form action="status_mail_report_add_log.php" method="post" name="iform" id="iform"> + <table class="tabcont" width="100%" border="0" cellpadding="1" cellspacing="1"> + <tr> + <td class="listtopic" colspan="2">Log Settings</td> + </tr> + <tr> + <td width="20%" class="listhdr"> + <?=gettext("Logs:");?> + </td> + <td width="80%" class="listhdr"> + <select name="logfile" class="formselect" style="z-index: -10;"> + <?php + foreach ($logfiles as $logfile) { + echo "<option value=\"{$logfile}\""; + if ($pconfig['logfile'] == $logfile) { + echo " selected"; + } + echo ">" . htmlspecialchars(get_friendly_log_name($logfile)) . "</option>\n"; + } + ?> + </select> + </td> + </tr> + <tr> + <td width="20%" class="listhdr"> + <?=gettext("# Rows:");?> + </td> + <td width="80%" class="listhdr"> + <input name="lines" type="text" class="formfld unknown" id="lines" size="10" value="<?=htmlspecialchars($pconfig['lines']);?>"> + </td> + </tr> + <tr> + <td class="listhdr"> + <?=gettext("Filter:");?> + </td> + <td class="listhdr"> + <input name="detail" type="text" class="formfld unknown" id="detail" size="60" value="<?=htmlspecialchars($pconfig['detail']);?>"> + </td> + </tr> + <tr> + <td colspan="2" align="center"> + <input name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> + <a href="status_mail_report_edit.php?id=<?php echo $reportid;?>"><input name="cancel" type="button" class="formbtn" value="<?=gettext("Cancel");?>"></a> + <input name="reportid" type="hidden" value="<?=htmlspecialchars($reportid);?>"> + <?php if (isset($id) && $a_logs[$id]): ?> + <input name="id" type="hidden" value="<?=htmlspecialchars($id);?>"> + <?php endif; ?> + </td> + <td></td> + </tr> + </table> + </form> + </div></td></tr> +</table> + +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/mailreport/status_mail_report_edit.php b/config/mailreport/status_mail_report_edit.php index 3102e958..7ddb4c36 100644 --- a/config/mailreport/status_mail_report_edit.php +++ b/config/mailreport/status_mail_report_edit.php @@ -44,16 +44,13 @@ require_once("mail_reports.inc"); /* if the rrd graphs are not enabled redirect to settings page */ if(! isset($config['rrd']['enable'])) { header("Location: status_rrd_graph_settings.php"); - exit; + return; } -$graphid = $_GET['graphid']; -if (isset($_POST['graphid'])) - $graphid = $_POST['graphid']; - -$id = $_GET['id']; -if (isset($_POST['id'])) - $id = $_POST['id']; +$cmdid = $_REQUEST['cmdid']; +$logid = $_REQUEST['logid']; +$graphid = $_REQUEST['graphid']; +$id = $_REQUEST['id']; if (!is_array($config['mailreports']['schedule'])) $config['mailreports']['schedule'] = array(); @@ -63,19 +60,40 @@ if (isset($id) && $a_mailreports[$id]) { if (!is_array($a_mailreports[$id]['row'])) $a_mailreports[$id]['row'] = array(); $pconfig = $a_mailreports[$id]; + $a_cmds = $a_mailreports[$id]['cmd']['row']; + $a_logs = $a_mailreports[$id]['log']['row']; $a_graphs = $a_mailreports[$id]['row']; -} else { +} + +if (!is_array($pconfig)) $pconfig = array(); +if (!is_array($a_cmds)) + $a_cmds = array(); +if (!is_array($a_logs)) + $a_logs = array(); +if (!is_array($a_graphs)) $a_graphs = array(); -} + if ($_GET['act'] == "del") { - if ($a_graphs[$graphid]) { + if (is_numeric($cmdid) && $a_cmds[$cmdid]) { + unset($a_cmds[$cmdid]); + $a_mailreports[$id]['cmd']['row'] = $a_cmds; + write_config(); + header("Location: status_mail_report_edit.php?id={$id}"); + return; + } elseif (is_numeric($logid) && $a_logs[$logid]) { + unset($a_logs[$logid]); + $a_mailreports[$id]['log']['row'] = $a_logs; + write_config(); + header("Location: status_mail_report_edit.php?id={$id}"); + return; + } elseif (is_numeric($graphid) && $a_graphs[$graphid]) { unset($a_graphs[$graphid]); $a_mailreports[$id]['row'] = $a_graphs; write_config(); header("Location: status_mail_report_edit.php?id={$id}"); - exit; + return; } } @@ -97,7 +115,7 @@ if ($_POST) { if ($_POST['Submit'] == "Send Now") { mwexec_bg("/usr/local/bin/mail_reports_generate.php {$id}"); header("Location: status_mail_report_edit.php?id={$id}"); - exit; + return; } $friendly = ""; @@ -124,7 +142,9 @@ if ($_POST) { unset($pconfig['dayofmonth']); } - // Copy graphs back into the schedule. + // Copy back into the schedule. + $pconfig['cmd']["row"] = $a_cmds; + $pconfig['log']["row"] = $a_logs; $pconfig["row"] = $a_graphs; $pconfig['schedule_friendly'] = $friendly; @@ -139,7 +159,7 @@ if ($_POST) { write_config(); configure_cron(); header("Location: status_mail_report.php"); - exit; + return; } $pgtitle = array(gettext("Status"),gettext("Edit Mail Reports")); @@ -220,6 +240,78 @@ include("head.inc"); <td></td> </tr> <tr> + <td class="listtopic" colspan="4">Report Commands</td> + <td></td> + </tr> + <tr> + <td width="30%" class="listhdr"><?=gettext("Name");?></td> + <td width="60%" colspan="3" class="listhdr"><?=gettext("Command");?></td> + <td width="10%" class="list"> + <?php if (isset($id) && $a_mailreports[$id]): ?> + <a href="status_mail_report_add_cmd.php?reportid=<?php echo $id ;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a> + </td> + <?php else: ?> + </td> + <tr><td colspan="5" align="center"><br/>Save the report first, then items may be added.<br/></td></tr> + <?php endif; ?> + </tr> + <?php $i = 0; foreach ($a_cmds as $cmd): ?> + <tr ondblclick="document.location='status_mail_report_add_cmd.php?reportid=<?php echo $id ;?>&id=<?=$i;?>'"> + <td class="listlr"><?php echo htmlspecialchars($cmd['descr']); ?></td> + <td colspan="3" class="listlr"><?php echo htmlspecialchars($cmd['detail']); ?></td> + <td valign="middle" nowrap class="list"> + <a href="status_mail_report_add_cmd.php?reportid=<?php echo $id ;?>&id=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a> + + <a href="status_mail_report_edit.php?act=del&id=<?php echo $id ;?>&cmdid=<?=$i;?>" onclick="return confirm('<?=gettext("Do you really want to delete this entry?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a> + </td> + </tr> + <?php $i++; endforeach; ?> + <tr> + <td class="list" colspan="4"></td> + <td class="list"> + <?php if (isset($id) && $a_mailreports[$id]): ?> + <a href="status_mail_report_add_cmd.php?reportid=<?php echo $id ;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a> + <?php endif; ?> + </td> + </tr> + <tr> + <td class="listtopic" colspan="4">Report Logs</td> + <td></td> + </tr> + <tr> + <td width="30%" class="listhdr"><?=gettext("Log");?></td> + <td width="20%" class="listhdr"><?=gettext("# Rows");?></td> + <td width="40%" colspan="2" class="listhdr"><?=gettext("Filter");?></td> + <td width="10%" class="list"> + <?php if (isset($id) && $a_mailreports[$id]): ?> + <a href="status_mail_report_add_log.php?reportid=<?php echo $id ;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a> + </td> + <?php else: ?> + </td> + <tr><td colspan="5" align="center"><br/>Save the report first, then items may be added.<br/></td></tr> + <?php endif; ?> + </tr> + <?php $i = 0; foreach ($a_logs as $log): ?> + <tr ondblclick="document.location='status_mail_report_add_log.php?reportid=<?php echo $id ;?>&id=<?=$i;?>'"> + <td class="listlr"><?php echo get_friendly_log_name($log['logfile']); ?></td> + <td class="listlr"><?php echo $log['lines']; ?></td> + <td colspan="2" class="listlr"><?php echo $log['detail']; ?></td> + <td valign="middle" nowrap class="list"> + <a href="status_mail_report_add_cmd.php?reportid=<?php echo $id ;?>&id=<?=$i;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a> + + <a href="status_mail_report_edit.php?act=del&id=<?php echo $id ;?>&logid=<?=$i;?>" onclick="return confirm('<?=gettext("Do you really want to delete this entry?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a> + </td> + </tr> + <?php $i++; endforeach; ?> + <tr> + <td class="list" colspan="4"></td> + <td class="list"> + <?php if (isset($id) && $a_mailreports[$id]): ?> + <a href="status_mail_report_add_log.php?reportid=<?php echo $id ;?>"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a> + <?php endif; ?> + </td> + </tr> + <tr> <td class="listtopic" colspan="4">Report Graphs</td> <td></td> </tr> @@ -234,7 +326,7 @@ include("head.inc"); </td> <?php else: ?> </td> - <tr><td colspan="5" align="center"><br/>Save the report first, then you may add graphs.<br/></td></tr> + <tr><td colspan="5" align="center"><br/>Save the report first, then items may be added.<br/></td></tr> <?php endif; ?> </tr> <?php $i = 0; foreach ($a_graphs as $graph): @@ -246,7 +338,7 @@ include("head.inc"); } $prettyprint = ucwords(implode(" :: ", $optionc)); ?> - <tr ondblclick="document.location='status_mail_report_edit.php?id=<?=$i;?>'"> + <tr ondblclick="document.location='status_mail_report_add_graph.php?reportid=<?php echo $id ;?>&id=<?=$i;?>'"> <td class="listlr"><?php echo $prettyprint; ?></td> <td class="listlr"><?php echo $graph['style']; ?></td> <td class="listlr"><?php echo $graph['timespan']; ?></td> diff --git a/config/openbgpd/openbgpd.inc b/config/openbgpd/openbgpd.inc index eff2855b..e1619a55 100644 --- a/config/openbgpd/openbgpd.inc +++ b/config/openbgpd/openbgpd.inc @@ -3,7 +3,7 @@ /* $Id$ */ /* openbgpd.inc - Copyright (C) 2007 Scott Ullrich (sullrich@gmail.com) + Copyright (C) 2007 Scott Ullrich (sullrich@gmail.com) part of pfSense All rights reserved. @@ -63,127 +63,127 @@ function openbgpd_install_conf() { // Since we need to embed this in a string, copy to a var. Can't embed constnats. $bgpd_config_base = PKG_BGPD_CONFIG_BASE; - if ($config['installedpackages']['openbgpd']['rawconfig'] && $config['installedpackages']['openbgpd']['rawconfig']['item']) { - // if there is a raw config specified in the config.xml use that instead of the assisted config - $conffile = implode("\n",$config['installedpackages']['openbgpd']['rawconfig']['item']); - //$conffile = $config['installedpackages']['openbgpd']['rawconfig']; - } else { - // generate bgpd.conf based on the assistant - if($config['installedpackages']['openbgpd']['config']) - $openbgpd_conf = &$config['installedpackages']['openbgpd']['config'][0]; - if($config['installedpackages']['openbgpd']['config'][0]['row']) - $openbgpd_rows = &$config['installedpackages']['openbgpd']['config'][0]['row']; - if($config['installedpackages']['openbgpdgroups']['config']) - $openbgpd_groups = &$config['installedpackages']['openbgpdgroups']['config']; - if($config['installedpackages']['openbgpdneighbors']['config']) - $openbgpd_neighbors = &$config['installedpackages']['openbgpdneighbors']['config']; - - $conffile = "# This file was created by the package manager. Do not edit!\n\n"; - $setkeycf = ""; - - // Setup AS # - if($openbgpd_conf['asnum']) - $conffile .= "AS {$openbgpd_conf['asnum']}\n"; - - if($openbgpd_conf['fibupdate']) - $conffile .= "fib-update {$openbgpd_conf['fibupdate']}\n"; - - // Setup holdtime if defined. Default is 90. - if($openbgpd_conf['holdtime']) - $conffile .= "holdtime {$openbgpd_conf['holdtime']}\n"; - - // Specify listen ip - if($openbgpd_conf['listenip']) - $conffile .= "listen on {$openbgpd_conf['listenip']}\n"; - - // Specify router id - if($openbgpd_conf['routerid']) - $conffile .= "router-id {$openbgpd_conf['routerid']}\n"; - - // Handle advertised networks - if($config['installedpackages']['openbgpd']['config'][0]['row']) - if(is_array($openbgpd_rows)) - foreach($openbgpd_rows as $row) - $conffile .= "network {$row['networks']}\n"; - - // Attach neighbors to their respective group owner - if(is_array($openbgpd_groups)) { - foreach($openbgpd_groups as $group) { - $conffile .= "group \"{$group['name']}\" {\n"; - $conffile .= " remote-as {$group['remoteas']}\n"; - if(is_array($openbgpd_neighbors)) { - foreach($openbgpd_neighbors as $neighbor) { - if($neighbor['groupname'] == $group['name']) { - $conffile .= " neighbor {$neighbor['neighbor']} {\n"; - $conffile .= " descr \"{$neighbor['descr']}\"\n"; - $setkeycf .= "delete {$openbgpd_conf['listenip']} {$neighbor['neighbor']} tcp 0x1000;\n"; - if($neighbor['md5sigpass']) { - $setkeycf .= "add {$openbgpd_conf['listenip']} {$neighbor['neighbor']} tcp 0x1000 -A tcp-md5 \"{$neighbor['md5sigpass']}\";\n"; - $conffile .= " tcp md5sig password {$neighbor['md5sigpass']}\n"; - } - if($neighbor['md5sigkey']) { - $setkeycf .= "add {$openbgpd_conf['listenip']} {$neighbor['neighbor']} tcp 0x1000 -A tcp-md5 0x{$neighbor['md5sigkey']};\n"; - $conffile .= " tcp md5sig key {$neighbor['md5sigkey']}\n"; - } - foreach($neighbor['row'] as $row) { - $conffile .= " {$row['parameters']} {$row['parmvalue']} \n"; - } - $conffile .= "}\n"; - } - } - } - $conffile .= "}\n"; - } - } - - // Handle neighbors that do not have a group assigned to them - if(is_array($openbgpd_neighbors)) { - foreach($openbgpd_neighbors as $neighbor) { - $used_this_item = false; - if($neighbor['groupname'] == "") { - $conffile .= "neighbor {$neighbor['neighbor']} {\n"; - $conffile .= " descr \"{$neighbor['descr']}\"\n"; - $setkeycf .= "delete {$openbgpd_conf['listenip']} {$neighbor['neighbor']} tcp 0x1000;\n"; - if ($neighbor['md5sigpass']) { - $setkeycf .= "add {$openbgpd_conf['listenip']} {$neighbor['neighbor']} tcp 0x1000 -A tcp-md5 \"{$neighbor['md5sigpass']}\";\n"; - $conffile .= " tcp md5sig password {$neighbor['md5sigpass']}\n"; - } - if ($neighbor['md5sigkey']) { - $setkeycf .= "add {$openbgpd_conf['listenip']} {$neighbor['neighbor']} tcp 0x1000 -A tcp-md5 0x{$neighbor['md5sigkey']};\n"; - $conffile .= " tcp md5sig key {$neighbor['md5sigkey']}\n"; - } - $used_this_item = true; - foreach($neighbor['row'] as $row) { - $conffile .= " {$row['parameters']} {$row['parmvalue']} \n"; - } - } - if($used_this_item) - $conffile .= "}\n"; - } - } - - // OpenBGPD filters - $conffile .= "deny from any\n"; - $conffile .= "deny to any\n"; - if(is_array($openbgpd_neighbors)) { - foreach($openbgpd_neighbors as $neighbor) { - $conffile .= "allow from {$neighbor['neighbor']}\n"; - $conffile .= "allow to {$neighbor['neighbor']}\n"; - } - } - } - safe_mkdir($bgpd_config_base); - $fd = fopen("{$bgpd_config_base}/bgpd.conf", "w"); + if ($config['installedpackages']['openbgpd']['rawconfig'] && $config['installedpackages']['openbgpd']['rawconfig']['item']) { + // if there is a raw config specified in the config.xml use that instead of the assisted config + $conffile = implode("\n",$config['installedpackages']['openbgpd']['rawconfig']['item']); + //$conffile = $config['installedpackages']['openbgpd']['rawconfig']; + } else { + // generate bgpd.conf based on the assistant + if($config['installedpackages']['openbgpd']['config']) + $openbgpd_conf = &$config['installedpackages']['openbgpd']['config'][0]; + if($config['installedpackages']['openbgpd']['config'][0]['row']) + $openbgpd_rows = &$config['installedpackages']['openbgpd']['config'][0]['row']; + if($config['installedpackages']['openbgpdgroups']['config']) + $openbgpd_groups = &$config['installedpackages']['openbgpdgroups']['config']; + if($config['installedpackages']['openbgpdneighbors']['config']) + $openbgpd_neighbors = &$config['installedpackages']['openbgpdneighbors']['config']; + + $conffile = "# This file was created by the package manager. Do not edit!\n\n"; + + // Setup AS # + if($openbgpd_conf['asnum']) + $conffile .= "AS {$openbgpd_conf['asnum']}\n"; + + if($openbgpd_conf['fibupdate']) + $conffile .= "fib-update {$openbgpd_conf['fibupdate']}\n"; + + // Setup holdtime if defined. Default is 90. + if($openbgpd_conf['holdtime']) + $conffile .= "holdtime {$openbgpd_conf['holdtime']}\n"; + + // Specify listen ip + if($openbgpd_conf['listenip']) + $conffile .= "listen on {$openbgpd_conf['listenip']}\n"; + + // Specify router id + if($openbgpd_conf['routerid']) + $conffile .= "router-id {$openbgpd_conf['routerid']}\n"; + + // Handle advertised networks + if($config['installedpackages']['openbgpd']['config'][0]['row']) + if(is_array($openbgpd_rows)) + foreach($openbgpd_rows as $row) + $conffile .= "network {$row['networks']}\n"; + + // Attach neighbors to their respective group owner + if(is_array($openbgpd_groups)) { + foreach($openbgpd_groups as $group) { + $conffile .= "group \"{$group['name']}\" {\n"; + $conffile .= " remote-as {$group['remoteas']}\n"; + if(is_array($openbgpd_neighbors)) { + foreach($openbgpd_neighbors as $neighbor) { + if($neighbor['groupname'] == $group['name']) { + $conffile .= "\tneighbor {$neighbor['neighbor']} {\n"; + $conffile .= "\t\tdescr \"{$neighbor['descr']}\"\n"; + if($neighbor['md5sigpass']) { + $conffile .= "\t\ttcp md5sig password {$neighbor['md5sigpass']}\n"; + } + if($neighbor['md5sigkey']) { + $conffile .= "\t\ttcp md5sig key {$neighbor['md5sigkey']}\n"; + } + $setlocaladdr = true; + if (is_array($neighbor['row'])) { + foreach($neighbor['row'] as $row) { + if ($row['parameters'] == "local-address") + $setlocaladdr = false; + $conffile .= "\t\t{$row['parameters']} {$row['parmvalue']} \n"; + } + } + if ($setlocaladdr == true) + $conffile .= "\t\tlocal-address {$openbgpd_conf['listenip']}\n"; + $conffile .= "}\n"; + } + } + } + $conffile .= "}\n"; + } + } - // Write out the configuration file - fwrite($fd, $conffile); + // Handle neighbors that do not have a group assigned to them + if(is_array($openbgpd_neighbors)) { + foreach($openbgpd_neighbors as $neighbor) { + if($neighbor['groupname'] == "") { + $conffile .= "neighbor {$neighbor['neighbor']} {\n"; + $conffile .= "\tdescr \"{$neighbor['descr']}\"\n"; + if ($neighbor['md5sigpass']) { + $conffile .= "\ttcp md5sig password {$neighbor['md5sigpass']}\n"; + } + if ($neighbor['md5sigkey']) { + $conffile .= "\ttcp md5sig key {$neighbor['md5sigkey']}\n"; + } + $setlocaladdr = true; + if (is_array($neighbor['row'])) { + foreach($neighbor['row'] as $row) { + if ($row['parameters'] == "local-address") + $setlocaladdr = false; + $conffile .= "\t{$row['parameters']} {$row['parmvalue']} \n"; + } + } + if ($setlocaladdr == true) + $conffile .= "\tlocal-address {$openbgpd_conf['listenip']}\n"; + $conffile .= "}\n"; + } + } + } - // Close file handle - fclose($fd); + // OpenBGPD filters + $conffile .= "deny from any\n"; + $conffile .= "deny to any\n"; + if(is_array($openbgpd_neighbors)) { + foreach($openbgpd_neighbors as $neighbor) { + $conffile .= "allow from {$neighbor['neighbor']}\n"; + $conffile .= "allow to {$neighbor['neighbor']}\n"; + } + } + } + safe_mkdir($bgpd_config_base); + // Write out the configuration file + @file_put_contents("{$bgpd_config_base}/bgpd.conf", $conffile); + @chmod("{$bgpd_config_base}/bgpd.conf", 0600); // Create rc.d file $rc_file_stop = <<<EOF -killall -9 bgpd +killall -TERM bgpd EOF; $rc_file_start = <<<EOF @@ -195,12 +195,14 @@ if [ `pw usershow {$pkg_login} 2>&1 | grep -c "pw: no such user"` -gt 0 ]; then fi /bin/mkdir -p {$bgpd_config_base} -chmod u+rw,go-rw {$bgpd_config_base}/bgpd.conf /usr/sbin/chown -R root:wheel {$bgpd_config_base} +/bin/chmod 0600 {$bgpd_config_base}/bgpd.conf NUMBGPD=`ps auxw | grep -c '[b]gpd.*parent'` if [ \${NUMBGPD} -lt 1 ] ; then {$pkg_bin}/bgpd -f {$bgpd_config_base}/bgpd.conf +else + {$pkg_bin}/bgpctl reload fi EOF; write_rcfile(array( @@ -210,17 +212,11 @@ EOF; ) ); - // TCP-MD5 support on freebsd. See tcp(5) for more - $fd = fopen("{$g['tmp_path']}/bgpdsetkey.conf", "w"); - fwrite($fd, $setkeycf ); - fclose($fd); - exec("setkey -f {$g['tmp_path']}/bgpdsetkey.conf"); - // bgpd process running? if so reload, else start. if(is_openbgpd_running() == true) { - exec("bgpctl reload"); + exec("{$pkg_bin}/bgpctl reload"); } else { - exec("bgpd"); + exec("{$pkg_bin}/bgpd -f {$bgpd_config_base}/bgpd.conf"); } conf_mount_ro(); @@ -237,34 +233,19 @@ function openbgpd_get_raw_config() { // serialize the raw openbgpd config file to config.xml function openbgpd_put_raw_config($conffile) { - global $config; - if ($conffile == "") - unset($config['installedpackages']['openbgpd']['rawconfig']); - else { - $config['installedpackages']['openbgpd']['rawconfig'] = array(); - $config['installedpackages']['openbgpd']['rawconfig']['item'] = explode("\n",$_POST['openbgpd_raw']); - //$config['installedpackages']['openbgpd']['rawconfig'] = $conffile; - } + global $config; + if ($conffile == "") + unset($config['installedpackages']['openbgpd']['rawconfig']); + else { + $config['installedpackages']['openbgpd']['rawconfig'] = array(); + $config['installedpackages']['openbgpd']['rawconfig']['item'] = explode("\n",$_POST['openbgpd_raw']); + //$config['installedpackages']['openbgpd']['rawconfig'] = $conffile; + } } function deinstall_openbgpd() { global $config, $g; - if($config['installedpackages']['openbgpd']['config']) - $openbgpd_conf = &$config['installedpackages']['openbgpd']['config'][0]; - if($config['installedpackages']['openbgpdneighbors']['config']) - $openbgpd_neighbors = &$config['installedpackages']['openbgpdneighbors']['config']; - $setkeycf = ""; - if(is_array($openbgpd_neighbors)) { - foreach($openbgpd_neighbors as $neighbor) - $setkeycf .= "delete {$openbgpd_conf['listenip']} {$neighbor['neighbor']} tcp 0x1000;\n"; - } - // Clear all SADB entries used. - $fd = fopen("{$g['tmp_path']}/bgpdsetkey.conf", "w"); - fwrite($fd, $setkeycf ); - fclose($fd); - exec("setkey -f {$g['tmp_path']}/bgpdsetkey.conf"); - exec("rm /usr/local/etc/rc.d/bgpd.sh"); exec("rm /usr/local/www/openbgpd_status.php"); exec("killall bgpd"); @@ -369,4 +350,4 @@ function is_openbgpd_running() { return false; } -?>
\ No newline at end of file +?> diff --git a/config/openbgpd/openbgpd_neighbors.xml b/config/openbgpd/openbgpd_neighbors.xml index efa82384..5553c022 100644 --- a/config/openbgpd/openbgpd_neighbors.xml +++ b/config/openbgpd/openbgpd_neighbors.xml @@ -100,13 +100,13 @@ <field> <fielddescr>TCP-MD5 key</fielddescr> <fieldname>md5sigkey</fieldname> - <description>The md5 key to communicate with the peer. Does not work with Cisco BGP routers.</description> + <description>The md5 key to communicate with the peer. Does not work with Cisco BGP routers. If the Local Addr option is not set listening ip will be used.</description> <type>input</type> </field> <field> <fielddescr>TCP-MD5 password</fielddescr> <fieldname>md5sigpass</fieldname> - <description>The md5 password to communicate with the peer. Use this when communicating with a Cisco BGP router.</description> + <description>The md5 password to communicate with the peer. Use this when communicating with a Cisco BGP router. If the Local Addr option is not set listenning ip will be used.</description> <type>input</type> </field> <field> diff --git a/config/openbgpd/openbgpd_status.php b/config/openbgpd/openbgpd_status.php index 3db2781a..6b27b4de 100644 --- a/config/openbgpd/openbgpd_status.php +++ b/config/openbgpd/openbgpd_status.php @@ -60,8 +60,13 @@ function doCmdT($title, $command) { fclose($fd); } else { $fd = popen("{$command} 2>&1", "r"); + $ct = 0; while (($line = fgets($fd)) !== FALSE) { echo htmlspecialchars($line, ENT_NOQUOTES); + if ($ct++ > 1000) { + ob_flush(); + $ct = 0; + } } pclose($fd); } diff --git a/config/openvpn-client-export/openvpn-client-export.xml b/config/openvpn-client-export/openvpn-client-export.xml index 7eeebb0c..e70139a7 100755 --- a/config/openvpn-client-export/openvpn-client-export.xml +++ b/config/openvpn-client-export/openvpn-client-export.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" ?> <packagegui> <name>OpenVPN Client Export</name> - <version>1.0.3</version> + <version>1.0.6</version> <title>OpenVPN Client Export</title> <include_file>/usr/local/pkg/openvpn-client-export.inc</include_file> <backup_file></backup_file> diff --git a/config/openvpn-client-export/vpn_openvpn_export.php b/config/openvpn-client-export/vpn_openvpn_export.php index fd2060ad..cfec87f7 100755 --- a/config/openvpn-client-export/vpn_openvpn_export.php +++ b/config/openvpn-client-export/vpn_openvpn_export.php @@ -542,7 +542,7 @@ function usepass_changed() { function useproxy_changed(obj) { if ((obj.id == "useproxy" && obj.checked) || - $(obj.id + 'pass').value != 'none') { + (obj.id == "useproxypass" && (obj.value != 'none'))) { $(obj.id + '_opts').show(); } else { $(obj.id + '_opts').hide(); @@ -781,7 +781,7 @@ function useproxy_changed(obj) { <span class="vexpl"> This will change the generated .ovpn configuration to allow for usage of the management interface. And include the OpenVPNManager program in the "Windows Installers". With this OpenVPN can be used also by non-administrator users. - This is also usefull for Windows7/Vista systems where elevated permissions are needed to add routes to the system. + This is also useful for Windows Vista/7/8 systems where elevated permissions are needed to add routes to the system. </span> </td> </tr> diff --git a/config/openvpn_tapfix_20x/openvpn_tapfix_203.patch b/config/openvpn_tapfix_20x/openvpn_tapfix_203.patch new file mode 100644 index 00000000..897a1199 --- /dev/null +++ b/config/openvpn_tapfix_20x/openvpn_tapfix_203.patch @@ -0,0 +1,290 @@ +diff --git /etc/inc/openvpn.inc.orig /etc/inc/openvpn.inc +index 777b395..701a032 100644 +--- a/etc/inc/openvpn.inc ++++ b/etc/inc/openvpn.inc +@@ -394,19 +394,37 @@ function openvpn_reconfigure($mode, $settings) { + // If the CIDR is less than a /30, OpenVPN will complain if you try to + // use the server directive. It works for a single client without it. + // See ticket #1417 +- if ($cidr < 30) { ++ if (!empty($ip) && !empty($mask) && ($cidr < 30)) { + $conf .= "server {$ip} {$mask}\n"; + $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; + } + case 'p2p_shared_key': +- list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask); +- $conf .= "ifconfig $ip1 $ip2\n"; ++ if (!empty($ip) && !empty($mask)) { ++ list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask); ++ $conf .= "ifconfig $ip1 $ip2\n"; ++ } + break; + case 'server_tls': + case 'server_user': + case 'server_tls_user': +- $conf .= "server {$ip} {$mask}\n"; +- $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; ++ if (!empty($ip) && !empty($mask)) { ++ $conf .= "server {$ip} {$mask}\n"; ++ $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; ++ } else { ++ if ($settings['serverbridge_dhcp']) { ++ if ((!empty($settings['serverbridge_interface'])) && (strcmp($settings['serverbridge_interface'], "none"))) { ++ $biface_ip=get_interface_ip($settings['serverbridge_interface']); ++ $biface_sm=gen_subnet_mask(get_interface_subnet($settings['serverbridge_interface'])); ++ if (is_ipaddr($biface_ip) && is_ipaddr($settings['serverbridge_dhcp_start']) && is_ipaddr($settings['serverbridge_dhcp_end'])) { ++ $conf .= "server-bridge {$biface_ip} {$biface_sm} {$settings['serverbridge_dhcp_start']} {$settings['serverbridge_dhcp_end']}\n"; ++ } else { ++ $conf .= "mode server\n"; ++ } ++ } else { ++ $conf .= "mode server\n"; ++ } ++ } ++ } + break; + } + +@@ -452,7 +452,9 @@ function openvpn_reconfigure($mode, $settings) { + case 'server_user': + $conf .= "client-cert-not-required\n"; + case 'server_tls_user': +- $conf .= "username-as-common-name\n"; ++ /* username-as-common-name is not compatible with server-bridge */ ++ if (stristr($conf, "server-bridge") === false) ++ $conf .= "username-as-common-name\n"; + if (!empty($settings['authmode'])) { + $authcfgs = explode(",", $settings['authmode']); + $sed = "\$authmodes=array("; + +diff --git /usr/local/www/vpn_openvpn_server.php.orig /usr/local/www/vpn_openvpn_server.php +index 0ef67a7..bd9f527 100644 +--- a/usr/local/www/vpn_openvpn_server.php ++++ b/usr/local/www/vpn_openvpn_server.php +@@ -147,6 +147,11 @@ if($_GET['act']=="edit"){ + $pconfig['dynamic_ip'] = $a_server[$id]['dynamic_ip']; + $pconfig['pool_enable'] = $a_server[$id]['pool_enable']; + ++ $pconfig['serverbridge_dhcp'] = $a_server[$id]['serverbridge_dhcp']; ++ $pconfig['serverbridge_interface'] = $a_server[$id]['serverbridge_interface']; ++ $pconfig['serverbridge_dhcp_start'] = $a_server[$id]['serverbridge_dhcp_start']; ++ $pconfig['serverbridge_dhcp_end'] = $a_server[$id]['serverbridge_dhcp_end']; ++ + $pconfig['dns_domain'] = $a_server[$id]['dns_domain']; + if ($pconfig['dns_domain']) + $pconfig['dns_domain_enable'] = true; +@@ -188,7 +193,6 @@ if($_GET['act']=="edit"){ + $pconfig['duplicate_cn'] = isset($a_server[$id]['duplicate_cn']); + } + } +- + if ($_POST) { + + unset($input_errors); +@@ -284,9 +288,22 @@ if ($_POST) { + $reqdfieldsn = array(gettext('Shared key')); + } + +- $reqdfields[] = 'tunnel_network'; +- $reqdfieldsn[] = gettext('Tunnel network'); +- ++ if ($pconfig['dev_mode'] != "tap") { ++ $reqdfields[] = 'tunnel_network'; ++ $reqdfieldsn[] = gettext('Tunnel network'); ++ } else { ++ if ($pconfig['serverbridge_dhcp'] && $pconfig['tunnel_network']) ++ $input_errors[] = gettext("Using a tunnel network and server bridge settings together is not allowed."); ++ if (($pconfig['serverbridge_dhcp_start'] && !$pconfig['serverbridge_dhcp_end']) ++ || (!$pconfig['serverbridge_dhcp_start'] && $pconfig['serverbridge_dhcp_end'])) ++ $input_errors[] = gettext("Server Bridge DHCP Start and End must both be empty, or defined."); ++ if (($pconfig['serverbridge_dhcp_start'] && !is_ipaddr($pconfig['serverbridge_dhcp_start']))) ++ $input_errors[] = gettext("Server Bridge DHCP Start must be an IPv4 address."); ++ if (($pconfig['serverbridge_dhcp_end'] && !is_ipaddr($pconfig['serverbridge_dhcp_end']))) ++ $input_errors[] = gettext("Server Bridge DHCP End must be an IPv4 address."); ++ if (ip2ulong($pconfig['serverbridge_dhcp_start']) > ip2ulong($pconfig['serverbridge_dhcp_end'])) ++ $input_errors[] = gettext("The Server Bridge DHCP range is invalid (start higher than end)."); ++ } + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if (!$input_errors) { +@@ -341,6 +358,11 @@ if ($_POST) { + $server['dynamic_ip'] = $pconfig['dynamic_ip']; + $server['pool_enable'] = $pconfig['pool_enable']; + ++ $server['serverbridge_dhcp'] = $pconfig['serverbridge_dhcp']; ++ $server['serverbridge_interface'] = $pconfig['serverbridge_interface']; ++ $server['serverbridge_dhcp_start'] = $pconfig['serverbridge_dhcp_start']; ++ $server['serverbridge_dhcp_end'] = $pconfig['serverbridge_dhcp_end']; ++ + if ($pconfig['dns_domain_enable']) + $server['dns_domain'] = $pconfig['dns_domain']; + +@@ -559,6 +581,56 @@ function netbios_change() { + } + } + ++function tuntap_change() { ++ ++ mindex = document.iform.mode.selectedIndex; ++ mvalue = document.iform.mode.options[mindex].value; ++ ++ switch(mvalue) { ++ case "p2p_tls": ++ case "p2p_shared_key": ++ p2p = true; ++ break; ++ default: ++ p2p = false; ++ break; ++ } ++ ++ index = document.iform.dev_mode.selectedIndex; ++ value = document.iform.dev_mode.options[index].value; ++ switch(value) { ++ case "tun": ++ document.getElementById("ipv4_tunnel_network").className="vncellreq"; ++ document.getElementById("serverbridge_dhcp").style.display="none"; ++ document.getElementById("serverbridge_interface").style.display="none"; ++ document.getElementById("serverbridge_dhcp_start").style.display="none"; ++ document.getElementById("serverbridge_dhcp_end").style.display="none"; ++ break; ++ case "tap": ++ document.getElementById("ipv4_tunnel_network").className="vncell"; ++ if (!p2p) { ++ document.getElementById("serverbridge_dhcp").style.display=""; ++ document.getElementById("serverbridge_interface").style.display=""; ++ document.getElementById("serverbridge_dhcp_start").style.display=""; ++ document.getElementById("serverbridge_dhcp_end").style.display=""; ++ if (document.iform.serverbridge_dhcp.checked) { ++ document.iform.serverbridge_interface.disabled = false; ++ document.iform.serverbridge_dhcp_start.disabled = false; ++ document.iform.serverbridge_dhcp_end.disabled = false; ++ } else { ++ document.iform.serverbridge_interface.disabled = true; ++ document.iform.serverbridge_dhcp_start.disabled = true; ++ document.iform.serverbridge_dhcp_end.disabled = true; ++ } ++ } else { ++ document.iform.serverbridge_dhcp.disabled = true; ++ document.iform.serverbridge_interface.disabled = true; ++ document.iform.serverbridge_dhcp_start.disabled = true; ++ document.iform.serverbridge_dhcp_end.disabled = true; ++ } ++ break; ++ } ++} + //--> + </script> + <?php +@@ -619,7 +691,7 @@ if ($savemsg) + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Server Mode");?></td> + <td width="78%" class="vtable"> +- <select name='mode' id='mode' class="formselect" onchange='mode_change()'> ++ <select name='mode' id='mode' class="formselect" onchange='mode_change(); tuntap_change()'> + <?php + foreach ($openvpn_server_modes as $name => $desc): + $selected = ""; +@@ -666,7 +738,7 @@ if ($savemsg) + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Device Mode"); ?></td> + <td width="78%" class="vtable"> +- <select name="dev_mode" class="formselect"> ++ <select name="dev_mode" class="formselect" onchange='tuntap_change()'> + <?php + foreach ($openvpn_dev_mode as $device): + $selected = ""; +@@ -976,7 +1048,7 @@ if ($savemsg) + <td colspan="2" valign="top" class="listtopic"><?=gettext("Tunnel Settings"); ?></td> + </tr> + <tr> +- <td width="22%" valign="top" class="vncellreq"><?=gettext("Tunnel Network"); ?></td> ++ <td width="22%" valign="top" class="vncellreq" id="ipv4_tunnel_network"><?=gettext("Tunnel Network"); ?></td> + <td width="78%" class="vtable"> + <input name="tunnel_network" type="text" class="formfld unknown" size="20" value="<?=htmlspecialchars($pconfig['tunnel_network']);?>"> + <br> +@@ -989,6 +1061,76 @@ if ($savemsg) + "to connecting clients. (see Address Pool)"); ?> + </td> + </tr> ++ <tr id="serverbridge_dhcp"> ++ <td width="22%" valign="top" class="vncell"><?=gettext("Bridge DHCP"); ?></td> ++ <td width="78%" class="vtable"> ++ <table border="0" cellpadding="2" cellspacing="0"> ++ <tr> ++ <td> ++ <?php set_checked($pconfig['serverbridge_dhcp'],$chk); ?> ++ <input name="serverbridge_dhcp" type="checkbox" value="yes" <?=$chk;?> onchange='tuntap_change()' /> ++ </td> ++ <td> ++ <span class="vexpl"> ++ <?=gettext("Allow clients on the bridge to obtain DHCP."); ?><br> ++ </span> ++ </td> ++ </tr> ++ </table> ++ </td> ++ </tr> ++ <tr id="serverbridge_interface"> ++ <td width="22%" valign="top" class="vncell"><?=gettext("Bridge Interface"); ?></td> ++ <td width="78%" class="vtable"> ++ <select name="serverbridge_interface" class="formselect"> ++ <?php ++ $serverbridge_interface['none'] = "none"; ++ $serverbridge_interface = array_merge($serverbridge_interface, get_configured_interface_with_descr()); ++ $carplist = get_configured_carp_interface_list(); ++ foreach ($carplist as $cif => $carpip) ++ $serverbridge_interface[$cif.'|'.$carpip] = $carpip." (".get_vip_descr($carpip).")"; ++ $aliaslist = get_configured_ip_aliases_list(); ++ foreach ($aliaslist as $aliasip => $aliasif) ++ $serverbridge_interface[$aliasif.'|'.$aliasip] = $aliasip." (".get_vip_descr($aliasip).")"; ++ foreach ($serverbridge_interface as $iface => $ifacename): ++ $selected = ""; ++ if ($iface == $pconfig['serverbridge_interface']) ++ $selected = "selected"; ++ ?> ++ <option value="<?=$iface;?>" <?=$selected;?>> ++ <?=htmlspecialchars($ifacename);?> ++ </option> ++ <?php endforeach; ?> ++ </select> <br> ++ <?=gettext("The interface to which this tap instance will be, " . ++ "bridged. This is not done automatically. You must assign this " . ++ "interface and create the bridge separately. " . ++ "This setting controls which existing IP address and subnet " . ++ "mask are used by OpenVPN for the bridge. Setting this to " . ++ "'none' will cause the Server Bridge DHCP settings below to be ignored."); ?> ++ </td> ++ </tr> ++ <tr id="serverbridge_dhcp_start"> ++ <td width="22%" valign="top" class="vncell"><?=gettext("Server Bridge DHCP Start"); ?></td> ++ <td width="78%" class="vtable"> ++ <input name="serverbridge_dhcp_start" type="text" class="formfld unknown" size="20" value="<?=htmlspecialchars($pconfig['serverbridge_dhcp_start']);?>"> ++ <br> ++ <?=gettext("When using tap mode as multi-point server, " . ++ "you may optionally supply a DHCP range to use on the " . ++ "interface to which this tap instance is bridged. " . ++ "If these settings are left blank, DHCP will be passed " . ++ "through to the LAN, and the interface setting above " . ++ "will be ignored."); ?> ++ </td> ++ </tr> ++ <tr id="serverbridge_dhcp_end"> ++ <td width="22%" valign="top" class="vncell"><?=gettext("Server Bridge DHCP End"); ?></td> ++ <td width="78%" class="vtable"> ++ <input name="serverbridge_dhcp_end" type="text" class="formfld unknown" size="20" value="<?=htmlspecialchars($pconfig['serverbridge_dhcp_end']);?>"> ++ <br> ++ <?=gettext(""); ?> ++ </td> ++ </tr> + <tr id="gwredir_opts"> + <td width="22%" valign="top" class="vncell"><?=gettext("Redirect Gateway"); ?></td> + <td width="78%" class="vtable"> +@@ -1486,6 +1628,7 @@ dns_server_change(); + wins_server_change(); + ntp_server_change(); + netbios_change(); ++tuntap_change(); + //--> + </script> + </body> diff --git a/config/openvpn_tapfix_20x/openvpn_tapfix_20x.inc b/config/openvpn_tapfix_20x/openvpn_tapfix_20x.inc index 197a5e25..8f574212 100644 --- a/config/openvpn_tapfix_20x/openvpn_tapfix_20x.inc +++ b/config/openvpn_tapfix_20x/openvpn_tapfix_20x.inc @@ -2,15 +2,22 @@ function openvpn_tapfix_20x_install() { global $g, $config; - + $pfs_version = substr(trim(file_get_contents("/etc/version")),0,5); + switch ($pfs_version) { + case "2.0.3": + $patch_file = "openvpn_tapfix_203.patch"; + break; + default: + $patch_file = "openvpn_tapfix_20x.patch"; + } // Test to make sure the patch is not already applied. - $out = `patch -fslC --reverse -p1 -b .before_openvpn_tapfix_20x -d / -i /usr/local/pkg/openvpn_tapfix_20x.patch |& grep -ci reject`; + $out = `patch -fslC --reverse -p1 -b .before_openvpn_tapfix_20x -d / -i /usr/local/pkg/{$patch_file} |& grep -ci reject`; if ($out == 0) { // If the patch has not already been applied, test to see if it will apply cleanly. - $out = `patch -fsNlC -p1 -b .before_openvpn_tapfix_20x -d / -i /usr/local/pkg/openvpn_tapfix_20x.patch |& grep -ci reject`; + $out = `patch -fsNlC -p1 -b .before_openvpn_tapfix_20x -d / -i /usr/local/pkg/{$patch_file} |& grep -ci reject`; if ($out == 0) { // The patch should apply cleanly, let 'er rip. - mwexec("patch -fsNl -p1 -b .before_openvpn_tapfix_20x -d / -i /usr/local/pkg/openvpn_tapfix_20x.patch "); + mwexec("patch -fsNl -p1 -b .before_openvpn_tapfix_20x -d / -i /usr/local/pkg/{$patch_file} "); } } } diff --git a/config/openvpn_tapfix_20x/openvpn_tapfix_20x.patch b/config/openvpn_tapfix_20x/openvpn_tapfix_20x.patch index 35925ea8..ed4232bb 100644 --- a/config/openvpn_tapfix_20x/openvpn_tapfix_20x.patch +++ b/config/openvpn_tapfix_20x/openvpn_tapfix_20x.patch @@ -281,7 +281,7 @@ index 0ef67a7..bd9f527 100644 + </td> + </tr> + <tr id="serverbridge_dhcp_end"> -+ <td width="22%" valign="top" class="vncell"><?=gettext("Server Bridge DHCP Start"); ?></td> ++ <td width="22%" valign="top" class="vncell"><?=gettext("Server Bridge DHCP End"); ?></td> + <td width="78%" class="vtable"> + <input name="serverbridge_dhcp_end" type="text" class="formfld unknown" size="20" value="<?=htmlspecialchars($pconfig['serverbridge_dhcp_end']);?>"> + <br> diff --git a/config/openvpn_tapfix_20x/openvpn_tapfix_20x.xml b/config/openvpn_tapfix_20x/openvpn_tapfix_20x.xml index 17a59947..a9754610 100644 --- a/config/openvpn_tapfix_20x/openvpn_tapfix_20x.xml +++ b/config/openvpn_tapfix_20x/openvpn_tapfix_20x.xml @@ -46,7 +46,7 @@ <requirements>pfSense 2.0.x</requirements> <faq>None</faq> <name>OpenVPN tap Bridging Fix</name> - <version>0.1</version> + <version>0.4</version> <title>OpenVPN tap Bridging Fix</title> <include_file>/usr/local/pkg/openvpn_tapfix_20x.inc</include_file> <additional_files_needed> @@ -59,6 +59,11 @@ <chmod>077</chmod> <item>http://www.pfsense.com/packages/config/openvpn_tapfix_20x/openvpn_tapfix_20x.patch</item> </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/openvpn_tapfix_20x/openvpn_tapfix_203.patch</item> + </additional_files_needed> <custom_php_install_command> openvpn_tapfix_20x_install(); </custom_php_install_command> diff --git a/config/pf-blocker/pfblocker.inc b/config/pf-blocker/pfblocker.inc index 58b93bb5..c40d742e 100755 --- a/config/pf-blocker/pfblocker.inc +++ b/config/pf-blocker/pfblocker.inc @@ -52,29 +52,6 @@ function cb_get_real_interface_address($iface) { return array($ip, long2ip(hexdec($netmask))); } -function pfblocker_Range2CIDR($ip_min, $ip_max) { - #function called without any args - if ($ip_min == "" || $ip_max == "") - return ""; - #function called with same ip in min and max - if ($ip_min == $ip_max) - return $ip_min. "/32"; - #convert ip to decimal numbers - $ip_min_long=ip2long($ip_min); - $ip_max_long=ip2long($ip_max); - #check long results - if ($ip_min_long == -1 || $ip_max_long == -1) - return ""; - #identify bits mask - $bits=(32 -strlen(decbin($ip_max_long - $ip_min_long))); - if ($bits < 0) - return ""; - #identify first ip on range network - $network=long2ip( $ip_min_long & ((1<<32)-(1<<(32-$bits))-1) ); - #print decbin($ip_min_long)."\n".$network."\n"; - return $network . "/". $bits; -} - function sync_package_pfblocker($cron="") { global $g,$config; @@ -290,10 +267,12 @@ function sync_package_pfblocker($cron="") { foreach ($url_list as $line){ # Network range 192.168.0.0-192.168.0.254 if (preg_match("/(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)/",$line,$matches)){ - $cidr= pfblocker_Range2CIDR($matches[1],$matches[2]); - if ($cidr != ""){ - ${$alias}.= $cidr."\n"; - $new_file.= $cidr."\n"; + $a_cidr = ip_range_to_subnet_array($matches[1],$matches[2]); + if (is_array($a_cidr)) { + foreach ($a_cidr as $cidr) { + ${$alias}.= $cidr."\n"; + $new_file.= $cidr."\n"; + } } } # CIDR format 192.168.0.0/16 diff --git a/config/postfix/postfix.inc b/config/postfix/postfix.inc index e64f8cca..83fc46e2 100644 --- a/config/postfix/postfix.inc +++ b/config/postfix/postfix.inc @@ -3,14 +3,14 @@ postfix.inc part of the Postfix package for pfSense Copyright (C) 2010 Erik Fonnesbeck - Copyright (C) 2012 Marcello Coutinho + Copyright (C) 2011-2013 Marcello Coutinho 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, + 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 @@ -34,6 +34,13 @@ require_once("functions.inc"); require_once("pkg-utils.inc"); require_once("globals.inc"); +$pf_version=substr(trim(file_get_contents("/etc/version")),0,3); +if ($pf_version > 2.0) + define('POSTFIX_LOCALBASE', '/usr/pbi/postfix-' . php_uname("m")); +else + define('POSTFIX_LOCALBASE','/usr/local'); + + $uname=posix_uname(); if ($uname['machine']=='amd64') ini_set('memory_limit', '250M'); @@ -57,7 +64,7 @@ function sync_relay_recipients($via_cron="cron"){ if ($config['installedpackages']['postfixrecipients']['config']) { $relay_recipients=""; $relay_ldap_recipients=""; - $ad_export="/usr/local/etc/postfix/adexport.pl"; + $ad_export= "/usr/local/bin/adexport.pl"; $postfix_enabled=$config['installedpackages']['postfix']['config'][0]['enable_postfix']; if (is_array($config['installedpackages']['postfixrecipients']['config'])) { $relay_ldap_recipients=""; @@ -73,7 +80,7 @@ function sync_relay_recipients($via_cron="cron"){ #validate cront job if ($via_cron == "gui"){ #running via pfsense gui, not time for ldap fetch. - $ldap_recipients='/usr/local/etc/postfix/relay_ldap_recipients.txt'; + $ldap_recipients= POSTFIX_LOCALBASE. '/etc/postfix/relay_ldap_recipients.txt'; if (!file_exists($ldap_recipients)) system('/usr/bin/touch '. $ldap_recipients); $relay_ldap_recipients=file_get_contents($ldap_recipients); @@ -83,7 +90,7 @@ function sync_relay_recipients($via_cron="cron"){ $ldap_temp=array(); foreach ($postfix_recipients_config['row'] as $postfix_ldap) { print "extracting from ".$postfix_ldap['dc']."..."; - $filename="/usr/local/etc/postfix/relay_ldap_recipients.".$postfix_ldap['dc'].".txt"; + $filename=POSTFIX_LOCALBASE."/etc/postfix/relay_ldap_recipients.".$postfix_ldap['dc'].".txt"; exec($ad_export." ".$postfix_ldap['dc']." ".$postfix_ldap['cn']." ".$postfix_ldap['username']." ".$postfix_ldap['password'],$ldap_fetch,$status); if ($status == 0){ #write backup conf for ldap server @@ -115,20 +122,20 @@ function sync_relay_recipients($via_cron="cron"){ $relay_ldap_recipients.=($recipient != ""?preg_replace("/\s+/","",$recipient)." OK\n":""); #save ldap relay recipients - file_put_contents("/usr/local/etc/postfix/relay_ldap_recipients.txt",$relay_ldap_recipients, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/relay_ldap_recipients.txt",$relay_ldap_recipients, LOCK_EX); } } } #save all relay recipients, remove duplicates and reload postfix - $recipients_file="/usr/local/etc/postfix/relay_recipients"; + $recipients_file=POSTFIX_LOCALBASE."/etc/postfix/relay_recipients"; file_put_contents($recipients_file.".unsort",$relay_ldap_recipients."\n".$relay_recipients, LOCK_EX); exec('/usr/bin/sort -u '.$recipients_file.'.unsort > '.$recipients_file); unlink_if_exists($recipients_file.'.unsort'); - exec("/usr/local/sbin/postmap /usr/local/etc/postfix/relay_recipients"); + exec(POSTFIX_LOCALBASE."/sbin/postmap ".POSTFIX_LOCALBASE."/etc/postfix/relay_recipients"); mwexec("/usr/local/sbin/postfix reload"); } if($relay_recipients !="" || $relay_ldap_recipients!="") - return("relay_recipient_maps = hash:/usr/local/etc/postfix/relay_recipients\n"); + return("relay_recipient_maps = hash:".POSTFIX_LOCALBASE."/etc/postfix/relay_recipients\n"); } function check_cron(){ @@ -137,7 +144,7 @@ function check_cron(){ $new_cron=array(); $cron_cmd_sqlite = ""; $cron_postfix_sqlite=""; - $cron_cmd="/usr/local/bin/php -q /usr/local/www/postfix_recipients.php"; + $cron_cmd= "/usr/local/bin/php -q /usr/local/www/postfix_recipients.php"; $postfix_enabled=$config['installedpackages']['postfix']['config'][0]['enable_postfix']; #check ldap update if (is_array($config['installedpackages']['postfixrecipients']['config'])) @@ -359,10 +366,11 @@ function sync_package_postfix() { ABOUT; +$pf_dir=POSTFIX_LOCALBASE; $postfix_main=<<<EOF #main.cf\ {$copyright} -mynetworks = /usr/local/etc/postfix/mynetwork_table +mynetworks = {$pf_dir}/etc/postfix/mynetwork_table mynetworks_style = host EOF; @@ -373,7 +381,7 @@ EOF; } #Header Maps if ($config['installedpackages']['postfixacl']['config'][0]['header_maps']){ - $postfix_main .= "header_checks = pcre:/usr/local/etc/postfix/header_check\n"; + $postfix_main .= "header_checks = pcre:".POSTFIX_LOCALBASE."/etc/postfix/header_check\n"; $postfix_main .= "header_size_limit = 1024000\n"; $header_check = px_text_area_decode($config['installedpackages']['postfixacl']['config'][0]['header_maps']); } @@ -383,12 +391,12 @@ EOF; } #MIME Maps if ($config['installedpackages']['postfixacl']['config'][0]['mime_maps']){ - $postfix_main .= "mime_header_checks = pcre:/usr/local/etc/postfix/mime_check\n"; + $postfix_main .= "mime_header_checks = pcre:".POSTFIX_LOCALBASE."/etc/postfix/mime_check\n"; $mime_check = px_text_area_decode($config['installedpackages']['postfixacl']['config'][0]['mime_maps']); } #Body Maps if ($config['installedpackages']['postfixacl']['config'][0]['body_maps']){ - $postfix_main .= "body_checks = pcre:/usr/local/etc/postfix/body_check\n"; + $postfix_main .= "body_checks = pcre:".POSTFIX_LOCALBASE."/etc/postfix/body_check\n"; $body_check = px_text_area_decode($config['installedpackages']['postfixacl']['config'][0]['body_maps']); } #Client CIDR @@ -406,7 +414,7 @@ EOF; } $postfix_main .= px_text_area_decode($postfix_config['maincf'])."\n". "relay_domains ={$relay_domains}\n" . - "transport_maps = hash:/usr/local/etc/postfix/transport\n" . + "transport_maps = hash:".POSTFIX_LOCALBASE."/etc/postfix/transport\n" . "local_recipient_maps =\n" . $all_relay_recipients. "mydestination =\n" . @@ -467,8 +475,8 @@ smtpd_sender_restrictions = reject_non_fqdn_sender, # Allow connections from specified local clients and strong check everybody else. smtpd_client_restrictions = permit_mynetworks, reject_unauth_destination, - check_client_access pcre:/usr/local/etc/postfix/cal_pcre, - check_client_access cidr:/usr/local/etc/postfix/cal_cidr, + check_client_access pcre:{$pf_dir}/etc/postfix/cal_pcre, + check_client_access cidr:{$pf_dir}/etc/postfix/cal_cidr, reject_unknown_client_hostname, reject_unauth_pipelining, reject_multi_recipient_bounce, @@ -477,9 +485,9 @@ smtpd_client_restrictions = permit_mynetworks, smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, reject_unauth_pipelining, - check_client_access pcre:/usr/local/etc/postfix/cal_pcre, - check_client_access cidr:/usr/local/etc/postfix/cal_cidr, - check_sender_access hash:/usr/local/etc/postfix/sender_access, + check_client_access pcre:{$pf_dir}/etc/postfix/cal_pcre, + check_client_access cidr:{$pf_dir}/etc/postfix/cal_cidr, + check_sender_access hash:{$pf_dir}/etc/postfix/sender_access, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_recipient_domain, @@ -505,18 +513,18 @@ smtpd_sender_restrictions = reject_unknown_sender_domain, # Allow connections from specified local clients and rbl check everybody else if rbl check are set. smtpd_client_restrictions = permit_mynetworks, reject_unauth_destination, - check_sender_access hash:/usr/local/etc/postfix/sender_access, - check_client_access pcre:/usr/local/etc/postfix/cal_pcre, - check_client_access cidr:/usr/local/etc/postfix/cal_cidr + check_sender_access hash:{$pf_dir}/etc/postfix/sender_access, + check_client_access pcre:{$pf_dir}/etc/postfix/cal_pcre, + check_client_access cidr:{$pf_dir}/etc/postfix/cal_cidr RBLRBLRBL # Whitelisting: local clients may specify any destination domain. #, smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, - check_sender_access hash:/usr/local/etc/postfix/sender_access, - check_client_access pcre:/usr/local/etc/postfix/cal_pcre, - check_client_access cidr:/usr/local/etc/postfix/cal_cidr, + check_sender_access hash:{$pf_dir}/etc/postfix/sender_access, + check_client_access pcre:{$pf_dir}/etc/postfix/cal_pcre, + check_client_access cidr:{$pf_dir}/etc/postfix/cal_cidr, SPFSPFSPFRBLRBLRBL EOF; @@ -578,7 +586,7 @@ switch ($antispam['zombie_blocker']) $postfix_main.="postscreen_greet_action = ".$antispam['zombie_blocker']."\n"; } - $postfix_main.="postscreen_access_list = permit_mynetworks,\n\t\t\tcidr:/usr/local/etc/postfix/cal_cidr\n"; + $postfix_main.="postscreen_access_list = permit_mynetworks,\n\t\t\tcidr:".POSTFIX_LOCALBASE."/etc/postfix/cal_cidr\n"; $postfix_main.="postscreen_dnsbl_action= ".$antispam['zombie_blocker']."\n"; $postfix_main.="postscreen_blacklist_action= ".$antispam['zombie_blocker']."\n"; @@ -670,20 +678,20 @@ MASTEREOF2; conf_mount_rw(); log_error("Writing out configuration"); - file_put_contents("/usr/local/etc/postfix/main.cf", $postfix_main, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/master.cf", $postfix_master, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/transport", $transport, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/sender_access", $sender_access, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/cal_cidr", $cal_cidr, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/cal_pcre", $cal_pcre, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/header_check", $header_check, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/mime_check", $mime_check, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/body_check", $body_check, LOCK_EX); - file_put_contents("/usr/local/etc/postfix/mynetwork_table", $mynetworks, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/main.cf", $postfix_main, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/master.cf", $postfix_master, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/transport", $transport, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/sender_access", $sender_access, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/cal_cidr", $cal_cidr, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/cal_pcre", $cal_pcre, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/header_check", $header_check, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/mime_check", $mime_check, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/body_check", $body_check, LOCK_EX); + file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/mynetwork_table", $mynetworks, LOCK_EX); $FILES=array("transport","sender_access"); foreach ($FILES as $file) { - mwexec("/usr/local/sbin/postmap /usr/local/etc/postfix/".$file); + mwexec(POSTFIX_LOCALBASE."/sbin/postmap ".POSTFIX_LOCALBASE."/etc/postfix/".$file); } #check postix dirs @@ -710,6 +718,7 @@ MASTEREOF2; } function postfix_start(){ global $config; + $pf_dir=POSTFIX_LOCALBASE; $start=<<<EOF sysctl kern.ipc.nmbclusters=65536 @@ -717,10 +726,10 @@ function postfix_start(){ sysctl kern.maxfiles=131072 sysctl kern.maxfilesperproc=104856 sysctl kern.threads.max_threads_per_proc=4096 - /usr/local/sbin/postfix start + {$pf_dir}/sbin/postfix start EOF; - $stop = "/usr/local/sbin/postfix stop\n"; + $stop = POSTFIX_LOCALBASE."/sbin/postfix stop\n"; log_error("Writing rc_file"); write_rcfile(array("file" => "postfix.sh", "start" => $start, "stop" => $stop)); @@ -730,7 +739,7 @@ EOF; if ($config['installedpackages']['postfix']['config'][0]['enable_postfix']){ log_error("Reloading/starting postfix"); system('/bin/chmod +x /usr/local/etc/rc.d/postfix.sh'); - mwexec_bg("/usr/local/sbin/postfix reload || /usr/local/etc/rc.d/postfix.sh start"); + mwexec_bg(POSTFIX_LOCALBASE."/sbin/postfix reload || /usr/local/etc/rc.d/postfix.sh start"); log_error("Postfix setup completed"); } else{ @@ -783,33 +792,75 @@ function postfix_php_deinstall_command() { /* Uses XMLRPC to synchronize the changes to a remote node */ function postfix_sync_on_changes() { - global $config, $g; - $synconchanges = $config['installedpackages']['postfixsync']['config'][0]['synconchanges']; - $syncondbchanges= $config['installedpackages']['postfixsync']['config'][0]['rsync']; - if(!$synconchanges && !$syncondbchanges) - return; - log_error("[postfix] postfix_xmlrpc_sync.php is starting."); - foreach ($config['installedpackages']['postfixsync']['config'] as $rs ){ - foreach($rs['row'] as $sh){ - $sync_to_ip = $sh['ipaddress']; - $password = $sh['password']; - $sync_type = $sh['sync_type']; - if($password && $sync_to_ip) - postfix_do_xmlrpc_sync($sync_to_ip, $password,$sync_type); + global $config, $g; + if (is_array($config['installedpackages']['postfixsync']['config'])){ + $postfix_sync=$config['installedpackages']['postfixsync']['config'][0]; + $synctimeout = $postfix_sync['synctimeout']; + $synconchanges = $postfix_sync['synconchanges']; + switch ($synconchanges){ + case "manual": + if (is_array($postfix_sync[row])){ + $rs=$postfix_sync[row]; + } + else{ + log_error("[postfix] xmlrpc sync is enabled but there is no hosts to push postfix config."); + return; + } + break; + case "auto": + if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){ + $system_carp=$config['installedpackages']['carpsettings']['config'][0]; + $rs[0]['ipaddress']=$system_carp['synchronizetoip']; + $rs[0]['username']=$system_carp['username']; + $rs[0]['password']=$system_carp['password']; + $rs[0]['enabless']=true; + $rs[0]['sync_type']="xmlrpc"; + if (! is_ipaddr($system_carp['synchronizetoip'])){ + log_error("[postfix] xmlrpc sync is enabled but there is no system backup hosts to push postfix config."); + return; + } + } + else{ + log_error("[postfix] xmlrpc sync is enabled but there is no system backup hosts to push postfix config."); + return; + } + break; + default: + return; + break; } - } - log_error("[postfix] postfix_xmlrpc_sync.php is ending."); + if (is_array($rs)){ + log_error("[postfix] xmlrpc sync is starting."); + foreach($rs as $sh){ + $sync_to_ip = $sh['ipaddress']; + if($sh['username']) + $username = $sh['username']; + else + $username = 'admin'; + if($sh['password'] && $sh['ipaddress'] && $sh['enabless']) + postfix_do_xmlrpc_sync($sh['ipaddress'], $username, $sh['password'],$sh['sync_type'],$synctimeout); + } + log_error("[postfix] xmlrpc sync is ending."); + } + } } + /* Do the actual XMLRPC sync */ -function postfix_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { +function postfix_do_xmlrpc_sync($sync_to_ip,$username,$password,$sync_type,$synctimeout) { global $config, $g; + if(!$username) + $username="admin"; + if(!$password) return; if(!$sync_to_ip) return; + + if(!$synctimeout) + $synctimeout=120; $xmlrpc_sync_neighbor = $sync_to_ip; if($config['system']['webgui']['protocol'] != "") { @@ -851,18 +902,18 @@ function postfix_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { $method = 'pfsense.merge_installedpackages_section_xmlrpc'; $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); - $cli->setCredentials('admin', $password); + $cli->setCredentials($username, $password); if($g['debug']) $cli->setDebug(1); - /* send our XMLRPC message and timeout after 250 seconds */ - $resp = $cli->send($msg, "250"); + /* send our XMLRPC message and timeout after $sync_timeout seconds */ + $resp = $cli->send($msg, $synctimeout); if(!$resp) { $error = "A communications error occurred while attempting postfix XMLRPC sync with {$url}:{$port}."; log_error($error); file_notice("sync_settings", $error, "Postfix Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); - $resp = $cli->send($msg, "250"); + $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting postfix XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "Postfix Settings Sync", ""); @@ -884,15 +935,15 @@ function postfix_do_xmlrpc_sync($sync_to_ip, $password,$sync_type) { log_error("postfix XMLRPC reload data {$url}:{$port}."); $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); - $cli->setCredentials('admin', $password); - $resp = $cli->send($msg, "250"); + $cli->setCredentials($username, $password); + $resp = $cli->send($msg, $synctimeout); if(!$resp) { $error = "A communications error occurred while attempting postfix XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; log_error($error); file_notice("sync_settings", $error, "postfix Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); - $resp = $cli->send($msg, "250"); + $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting postfix XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "postfix Settings Sync", ""); diff --git a/config/postfix/postfix.php b/config/postfix/postfix.php index ff42918c..a11af2dd 100644 --- a/config/postfix/postfix.php +++ b/config/postfix/postfix.php @@ -2,14 +2,14 @@ /* postfix.php part of pfSense (http://www.pfsense.com/) - Copyright (C) 2011 Marcello Coutinho <marcellocoutinho@gmail.com> + Copyright (C) 2011-2013 Marcello Coutinho <marcellocoutinho@gmail.com> based on varnish_view_config. 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, + 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 diff --git a/config/postfix/postfix.xml b/config/postfix/postfix.xml index 51ddf601..25f7a81d 100644 --- a/config/postfix/postfix.xml +++ b/config/postfix/postfix.xml @@ -10,7 +10,7 @@ postfix.xml part of the Postfix package for pfSense Copyright (C) 2010 Erik Fonnesbeck - Copyright (C) 2011 Marcello Coutinho + Copyright (C) 2011-2013 Marcello Coutinho All rights reserved. */ @@ -19,7 +19,7 @@ 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, + 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 @@ -142,7 +142,7 @@ </additional_files_needed> <additional_files_needed> <item>http://www.pfsense.org/packages/config/postfix/adexport.pl</item> - <prefix>/usr/local/etc/postfix/</prefix> + <prefix>/usr/local/bin/</prefix> <chmod>0755</chmod> </additional_files_needed> <tabs> diff --git a/config/postfix/postfix_queue.php b/config/postfix/postfix_queue.php index 914ad88e..76bed31f 100755 --- a/config/postfix/postfix_queue.php +++ b/config/postfix/postfix_queue.php @@ -2,14 +2,14 @@ /* postfix_view_config.php part of pfSense (http://www.pfsense.com/) - Copyright (C) 2011 Marcello Coutinho <marcellocoutinho@gmail.com> + Copyright (C) 2011-2013 Marcello Coutinho <marcellocoutinho@gmail.com> based on varnish_view_config. 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, + 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 @@ -33,11 +33,17 @@ require("guiconfig.inc"); $uname=posix_uname(); if ($uname['machine']=='amd64') ini_set('memory_limit', '250M'); - + +$pf_version=substr(trim(file_get_contents("/etc/version")),0,3); +if ($pf_version > 2.0) + define('POSTFIX_LOCALBASE', '/usr/pbi/postfix-' . php_uname("m")); +else + define('POSTFIX_LOCALBASE','/usr/local'); + function get_cmd(){ if ($_REQUEST['cmd'] =='mailq'){ #exec("/usr/local/bin/mailq" . escapeshellarg('^'.$m.$j." ".$hour.".*".$grep)." /var/log/maillog", $lists); - exec("/usr/local/bin/mailq", $mailq); + exec(POSTFIX_LOCALBASE."/bin/mailq", $mailq); print '<table class="tabcont" width="100%" border="0" cellpadding="8" cellspacing="0">'; print '<tr><td colspan="6" valign="top" class="listtopic">'.gettext($_REQUEST['cmd']." Results").'</td></tr>'; print '<tr><td class="listlr"><strong>SID</strong></td>'; @@ -67,9 +73,9 @@ function get_cmd(){ } if ($_REQUEST['cmd'] =='qshape'){ if ($_REQUEST['qshape']!="") - exec("/usr/local/bin/qshape -".preg_replace("/\W/","",$_REQUEST['type'])." ". preg_replace("/\W/","",$_REQUEST['qshape']), $qshape); + exec(POSTFIX_LOCALBASE."/bin/qshape -".preg_replace("/\W/","",$_REQUEST['type'])." ". preg_replace("/\W/","",$_REQUEST['qshape']), $qshape); else - exec("/usr/local/bin/qshape", $qshape); + exec(POSTFIX_LOCALBASE."/bin/qshape", $qshape); print '<table class="tabcont" width="100%" border="0" cellpadding="8" cellspacing="0">'; print '<tr><td colspan="12" valign="top" class="listtopic">'.gettext($_REQUEST['cmd']." Results").'</td></tr>'; $td='<td valign="top" class="listlr">'; diff --git a/config/postfix/postfix_search.php b/config/postfix/postfix_search.php index 2b831f72..a1cf6b3f 100755 --- a/config/postfix/postfix_search.php +++ b/config/postfix/postfix_search.php @@ -2,14 +2,14 @@ /* postfix_search.php part of pfSense (http://www.pfsense.com/) - Copyright (C) 2011 Marcello Coutinho <marcellocoutinho@gmail.com> + Copyright (C) 2011-2013 Marcello Coutinho <marcellocoutinho@gmail.com> based on varnish_view_config. 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, + 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 diff --git a/config/postfix/postfix_sync.xml b/config/postfix/postfix_sync.xml index 08a62d87..88617fbf 100644 --- a/config/postfix/postfix_sync.xml +++ b/config/postfix/postfix_sync.xml @@ -9,7 +9,7 @@ /* postfix_sync.xml part of the Postfix package for pfSense - Copyright (C) 2010 Marcello Coutinho + Copyright (C) 2011-2013 Marcello Coutinho All rights reserved. */ /* ========================================================================== */ @@ -20,7 +20,7 @@ 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 + 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. @@ -100,23 +100,46 @@ <type>listtopic</type> </field> <field> - <fielddescr>Automatically sync Postfix configuration changes</fielddescr> + <fielddescr>Sync method</fielddescr> <fieldname>synconchanges</fieldname> - <description><![CDATA[pfSense will automatically sync changes to the hosts defined below.<br><br> - Remote server options are:<br> - <strong>XMLRPC Sync</strong> - Forward postfix settings to other pfsense boxes. Remote password required<br> - <strong>Share Database To</strong> - Allow other pfsense boxes to fetch maillog data via xml. Remote password NOT required.<br> - <strong>Fetch Database From</strong> - Merge logs from other pfsense boxes to this local database. Remote password required.<br> - <strong>Disabled</strong> - Ignore this host while sync.<br><br> - While sharing databases, you must setup 'Share Database To' in one box and 'Fetch Database From' on other box.]]></description> - <type>checkbox</type> + <description>Automatically sync postfix configuration changes.</description> + <type>select</type> + <required/> + <default_value>auto</default_value> + <options> + <option><name>Sync to configured system backup server</name><value>auto</value></option> + <option><name>Sync to host(s) defined below</name><value>manual</value></option> + <option><name>Do not sync this package configuration</name><value>disabled</value></option> + </options> + </field> + <field> + <fielddescr>Sync timeout</fielddescr> + <fieldname>synctimeout</fieldname> + <description>Select sync max wait time</description> + <type>select</type> + <required/> + <default_value>250</default_value> + <options> + <option><name>250 seconds(Default)</name><value>250</value></option> + <option><name>120 seconds</name><value>120</value></option> + <option><name>90 seconds</name><value>90</value></option> + <option><name>60 seconds</name><value>60</value></option> + <option><name>30 seconds</name><value>30</value></option> + </options> </field> <field> <fielddescr><![CDATA[Remote Server]]></fielddescr> <fieldname>none</fieldname> <type>rowhelper</type> + <dontdisplayname/> + <usecolspan2/> <rowhelper> <rowhelperfield> + <fielddescr>Enable</fielddescr> + <fieldname>enabless</fieldname> + <type>checkbox</type> + </rowhelperfield> + <rowhelperfield> <fielddescr>Sync Type </fielddescr> <fieldname>sync_type</fieldname> <type>select</type> @@ -126,18 +149,22 @@ <option><name>Fetch Database From</name><value>fetch</value></option> <option><name>Disabled</name><value>disabled</value></option> </options> - <description><![CDATA[<strong>Default: Strong</strong><br> - Enable sender, client, recipients and rfc verification.<br>]]></description> </rowhelperfield> - <rowhelperfield> - <fielddescr>IP Address</fielddescr> + <fielddescr>Remote Server IP</fielddescr> <fieldname>ipaddress</fieldname> <description>IP Address of remote server</description> <type>input</type> <size>10</size> </rowhelperfield> <rowhelperfield> + <fielddescr>Username</fielddescr> + <fieldname>username</fieldname> + <description>Username for remote server.</description> + <type>input</type> + <size>10</size> + </rowhelperfield> + <rowhelperfield> <fielddescr>Password</fielddescr> <fieldname>password</fieldname> <description>Password for remote server.</description> @@ -148,9 +175,15 @@ <fielddescr>Description</fielddescr> <fieldname>description</fieldname> <type>input</type> - <size>25</size> + <size>27</size> </rowhelperfield> </rowhelper> + <description><![CDATA[<br>Sync types Description:<br><br> + <strong>XMLRPC Sync</strong> - Forward postfix settings to other pfsense boxes. Remote password required<br> + <strong>Share Database To</strong> - Allow other pfsense boxes to fetch maillog data via xml. Remote password NOT required.<br> + <strong>Fetch Database From</strong> - Merge logs from other pfsense boxes to this local database. Remote password required.<br> + <strong>Disabled</strong> - Ignore this host while sync.<br><br> + While sharing databases works only when you select 'Sync to host(s) defined below' on sync method and you must setup 'Share Database To' in source box and 'Fetch Database From' on destination box.]]></description> </field> </fields> <custom_php_install_command> diff --git a/config/postfix/postfix_view_config.php b/config/postfix/postfix_view_config.php index 2c0b973e..5e1f6271 100644 --- a/config/postfix/postfix_view_config.php +++ b/config/postfix/postfix_view_config.php @@ -2,14 +2,14 @@ /* postfix_view_config.php part of pfSense (http://www.pfsense.com/) - Copyright (C) 2011 Marcello Coutinho <marcellocoutinho@gmail.com> + Copyright (C) 2011-2013 Marcello Coutinho <marcellocoutinho@gmail.com> based on varnish_view_config. 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, + 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 @@ -29,15 +29,21 @@ */ require("guiconfig.inc"); +$pf_version=substr(trim(file_get_contents("/etc/version")),0,3); +if ($pf_version > 2.0) + define('POSTFIX_LOCALBASE', '/usr/pbi/postfix-' . php_uname("m")); +else + define('POSTFIX_LOCALBASE','/usr/local'); + function get_file($file){ - $files['main']="/usr/local/etc/postfix/main.cf"; - $files['master']="/usr/local/etc/postfix/master.cf"; - $files['recipients']="/usr/local/etc/postfix/relay_recipients"; - $files['header']="/usr/local/etc/postfix/header_check"; - $files['mime']="/usr/local/etc/postfix/mime_check"; - $files['body']="/usr/local/etc/postfix/body_check"; - $files['cidr']="/usr/local/etc/postfix/cal_cidr"; - $files['pcre']="/usr/local/etc/postfix/cal_pcre"; + $files['main']=POSTFIX_LOCALBASE."/etc/postfix/main.cf"; + $files['master']=POSTFIX_LOCALBASE."/etc/postfix/master.cf"; + $files['recipients']=POSTFIX_LOCALBASE."/etc/postfix/relay_recipients"; + $files['header']=POSTFIX_LOCALBASE."/etc/postfix/header_check"; + $files['mime']=POSTFIX_LOCALBASE."/etc/postfix/mime_check"; + $files['body']=POSTFIX_LOCALBASE."/etc/postfix/body_check"; + $files['cidr']=POSTFIX_LOCALBASE."/etc/postfix/cal_cidr"; + $files['pcre']=POSTFIX_LOCALBASE."/etc/postfix/cal_pcre"; if ($files[$file]!="" && file_exists($files[$file])){ print '<textarea rows="50" cols="100%">'; diff --git a/config/quagga_ospfd/quagga_ospfd.inc b/config/quagga_ospfd/quagga_ospfd.inc index 598d3c00..46037bd9 100644 --- a/config/quagga_ospfd/quagga_ospfd.inc +++ b/config/quagga_ospfd/quagga_ospfd.inc @@ -290,7 +290,24 @@ EOF; exec("chmod u+rw,go-rw {$quagga_config_base}/zebra.conf"); // Kick off newly created rc.d script - exec("/usr/local/etc/rc.d/quagga.sh restart"); + if (is_ipaddr($ospfd_conf['carpstatusip'])) { + $status = quagga_get_carp_status_by_ip($ospfd_conf['carpstatusip']); + switch (strtoupper($status)) { + // Stop the service if the VIP is in BACKUP or INIT state. + case "BACKUP": + case "INIT": + exec("/usr/local/etc/rc.d/quagga.sh stop"); + break; + // Start the service if the VIP is MASTER state. + case "MASTER": + // Assume it's up if the status can't be determined. + default: + exec("/usr/local/etc/rc.d/quagga.sh restart"); + break; + } + } else { + exec("/usr/local/etc/rc.d/quagga.sh restart"); + } // Back to RO mount for NanoBSD and friends conf_mount_ro(); @@ -345,4 +362,18 @@ function quagga_ospfd_put_raw_config($conffile) { } } +function quagga_get_carp_status_by_ip($ipaddr) { + $iface = find_carp_interface($ipaddr); + if ($iface) { + $status = get_carp_interface_status($iface); + // If there is no status for that interface, return null. + if (!$status) + $status = null; + } else { + // If there is no VIP by that IP, return null. + $status = null; + } + return $status; +} + ?> diff --git a/config/quagga_ospfd/quagga_ospfd.xml b/config/quagga_ospfd/quagga_ospfd.xml index 3348dff3..c48d0f47 100644 --- a/config/quagga_ospfd/quagga_ospfd.xml +++ b/config/quagga_ospfd/quagga_ospfd.xml @@ -1,6 +1,6 @@ <packagegui> <name>quagga_ospfd</name> - <version>0.5.2</version> + <version>0.5.3</version> <title>Services: Quagga OSPFd</title> <include_file>/usr/local/pkg/quagga_ospfd.inc</include_file> <aftersaveredirect>pkg_edit.php?xml=quagga_ospfd.xml&id=0</aftersaveredirect> @@ -176,6 +176,13 @@ </rowhelperfield> </rowhelper> </field> + <field> + <fielddescr>CARP Status IP</fielddescr> + <fieldname>carpstatusip</fieldname> + <description>IP address used to determine the CARP status. When the VIP is in BACKUP status, quagga will not be started. <br/>NOTE: Requires changes to /etc/rc.carpmaster to start quagga and /etc/rc.carpbackup to stop quagga or it will not be fully effective.</description> + <type>input</type> + <size>25</size> + </field> </fields> <custom_php_resync_config_command> quagga_ospfd_install_conf(); diff --git a/config/snort/snort.inc b/config/snort/snort.inc index c36fc873..8062834f 100755 --- a/config/snort/snort.inc +++ b/config/snort/snort.inc @@ -33,21 +33,54 @@ require_once("pfsense-utils.inc"); require_once("config.inc"); require_once("functions.inc"); +require_once("service-utils.inc"); // Needed on 2.0 because of filter_get_vpns_list() require_once("filter.inc"); +// Explicitly declare these as global so they work through function call includes +global $snort_rules_file, $snort_version, $emerging_threats_version, $snort_rules_upd_log; +global $flowbit_rules_file, $snort_enforcing_rules_file, $rebuild_rules, $is_postinstall; +global $snort_community_rules_filename, $snort_community_rules_url, $emergingthreats_filename; + /* package version */ -$snort_version = "2.9.2.3"; -$pfSense_snort_version = "2.5.4"; +$snort_version = "2.9.4.1"; +$pfSense_snort_version = "2.5.7"; $snort_package_version = "Snort {$snort_version} pkg v. {$pfSense_snort_version}"; -$snort_rules_file = "snortrules-snapshot-2923.tar.gz"; -$emerging_threats_version = "2.9.3"; + +// Define SNORTDIR and SNORTLIBDIR constants according to FreeBSD version (PBI support or no PBI) +if (floatval(php_uname("r")) >= 8.3) { + exec("/usr/local/sbin/pbi_info | grep 'snort-{$snort_version}' | xargs /usr/local/sbin/pbi_info | awk '/Prefix/ {print $2}'",$pbidirarray); + $snort_pbidir = "{$pbidirarray[0]}"; + /* In case this is an initial Snort install and pbi_info() above returned null, set a sane default value */ + if (empty($snort_pbidir)) + $snort_pbidir = "/usr/pbi/snort-" . php_uname("m"); + define("SNORTDIR", "{$snort_pbidir}/etc/snort"); + define("SNORTLIBDIR", "{$snort_pbidir}/lib/snort"); +} +else { + define("SNORTDIR", "/usr/local/etc/snort"); + define("SNORTLIBDIR", "/usr/local/lib/snort"); +} + +define("SNORTLOGDIR", "/var/log/snort"); + +/* Important file definitions */ +$snort_rules_file = "snortrules-snapshot-2941.tar.gz"; +$emerging_threats_version = "2.9.0"; +$emergingthreats_filename = "emerging.rules.tar.gz"; +$snort_community_rules_url = "https://s3.amazonaws.com/snort-org/www/rules/community/"; +$snort_community_rules_filename = "community-rules.tar.gz"; $flowbit_rules_file = "flowbit-required.rules"; $snort_enforcing_rules_file = "snort.rules"; +$snort_rules_upd_log = SNORTLOGDIR; +$snort_rules_upd_log .= "/snort_rules_update.log"; -define("SNORTDIR", "/usr/local/etc/snort"); -define("SNORTLOGDIR", "/var/log/snort"); +/* Rebuild Rules Flag -- if "on", rebuild enforcing rules and flowbit-rules files */ +$rebuild_rules = "off"; + +/* Post-install Flag -- normally "false" except during post-install of package */ +$is_postinstall = false; if (!is_array($config['installedpackages']['snortglobal'])) $config['installedpackages']['snortglobal'] = array(); @@ -296,7 +329,6 @@ function snort_barnyard_stop($snortcfg, $if_real) { $snort_uuid = $snortcfg['uuid']; if (file_exists("{$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid") && isvalidpid("{$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid")) { killbypid("{$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid"); - @unlink("{$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid"); } } @@ -306,12 +338,11 @@ function snort_stop($snortcfg, $if_real) { $snort_uuid = $snortcfg['uuid']; if (file_exists("{$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid") && isvalidpid("{$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid")) { killbypid("{$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid"); - exec("/bin/rm {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid"); } snort_barnyard_stop($snortcfg, $if_real); - log_error("Interface Rule STOP for {$snortcfg['descr']}({$if_real})..."); + log_error("Snort STOP for {$snortcfg['descr']}({$if_real})..."); } function snort_barnyard_start($snortcfg, $if_real) { @@ -339,7 +370,7 @@ function snort_start($snortcfg, $if_real) { snort_barnyard_start($snortcfg, $if_real); - log_error("Interface Rule START for {$snortcfg['descr']}({$if_real})..."); + log_error("Snort START for {$snortcfg['descr']}({$if_real})..."); } function snort_get_friendly_interface($interface) { @@ -427,9 +458,15 @@ function snort_post_delete_logs($snort_uuid = 0) { } function snort_postinstall() { - global $config, $g; + global $config, $g, $snort_rules_file, $emerging_threats_version; + global $snort_version, $rebuild_rules, $is_postinstall; $snortdir = SNORTDIR; + $snortlibdir = SNORTLIBDIR; + $rcdir = RCFILEPREFIX; + + /* Set flag for post-install in progress */ + $is_postinstall = true; /* cleanup default files */ @rename("{$snortdir}/snort.conf-sample", "{$snortdir}/snort.conf"); @@ -440,25 +477,48 @@ function snort_postinstall() { @rename("{$snortdir}/generators-sample", "{$snortdir}/generators"); @rename("{$snortdir}/reference.config-sample", "{$snortdir}/reference.config"); @rename("{$snortdir}/gen-msg.map-sample", "{$snortdir}/gen-msg.map"); - @unlink("{$snortdir}/sid"); - @unlink("/usr/local/etc/rc.d/snort"); - @unlink("/usr/local/etc/rc.d/barnyard2"); - /* remove example files */ - if (file_exists('/usr/local/lib/snort/dynamicrules/lib_sfdynamic_example_rule.so.0')) - exec('rm /usr/local/lib/snort/dynamicrules/lib_sfdynamic_example*'); + /* fix up the preprocessor rules filenames from a PBI package install */ + $preproc_rules = array("decoder.rules", "preprocessor.rules", "sensitive-data.rules"); + foreach ($preproc_rules as $file) { + if (file_exists("{$snortdir}/preproc_rules/{$file}-sample")) + @rename("{$snortdir}/preproc_rules/{$file}-sample", "{$snortdir}/preproc_rules/{$file}"); + } + + /* Remove any previously installed scripts since we rebuild them */ + @unlink("{$snortdir}/sid"); + @unlink("{$rcdir}/snort.sh"); + @unlink("{$rcdir}/barnyard2"); - if (file_exists('/usr/local/lib/snort/dynamicpreprocessor/lib_sfdynamic_preprocessor_example.so')) - exec('/bin/rm /usr/local/lib/snort/dynamicpreprocessor/lib_sfdynamic_preprocessor_example*'); + /* remove example library files */ + $files = glob("{$snortlibdir}/dynamicrules/*_example*"); + foreach ($files as $f) + @unlink($f); + $files = glob("{$snortlibdir}/dynamicpreprocessor/*_example*"); + foreach ($files as $f) + @unlink($f); /* remake saved settings */ if ($config['installedpackages']['snortglobal']['forcekeepsettings'] == 'on') { + log_error(gettext("[Snort] Saved settings detected... rebuilding installation with saved settings...")); update_status(gettext("Saved settings detected...")); - update_output_window(gettext("Please wait... rebuilding files...")); + update_output_window(gettext("Please wait... rebuilding installation with saved settings...")); + log_error(gettext("[Snort] Downloading and updating configured rule types...")); @include_once("/usr/local/pkg/snort/snort_check_for_rule_updates.php"); + update_status(gettext("Generating snort.conf configuration file from saved settings...")); + $rebuild_rules = "on"; sync_snort_package_config(); - update_output_window(gettext("Finnished Rebuilding files...")); + $rebuild_rules = "off"; + update_output_window(gettext("Finished rebuilding files...")); + log_error(gettext("[Snort] Finished rebuilding installation from saved settings...")); + update_status(gettext("Starting Snort using rebuilt configuration...")); + log_error(gettext("[Snort] Starting Snort using rebuilt configuration...")); + start_service("snort"); } + + /* Done with post-install, so clear flag */ + $is_postinstall = false; + log_error(gettext("[Snort] Package post-installation tasks completed...")); } function snort_Getdirsize($node) { @@ -592,17 +652,20 @@ function snort_rm_blocked_install_cron($should_install) { } switch($should_install) { case true: - if(!$is_installed) { - $cron_item = array(); - $cron_item['minute'] = "$snort_rm_blocked_min"; - $cron_item['hour'] = "$snort_rm_blocked_hr"; - $cron_item['mday'] = "$snort_rm_blocked_mday"; - $cron_item['month'] = "$snort_rm_blocked_month"; - $cron_item['wday'] = "$snort_rm_blocked_wday"; - $cron_item['who'] = "root"; - $cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -t $snort_rm_blocked_expire snort2c"; + $cron_item = array(); + $cron_item['minute'] = "$snort_rm_blocked_min"; + $cron_item['hour'] = "$snort_rm_blocked_hr"; + $cron_item['mday'] = "$snort_rm_blocked_mday"; + $cron_item['month'] = "$snort_rm_blocked_month"; + $cron_item['wday'] = "$snort_rm_blocked_wday"; + $cron_item['who'] = "root"; + $cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -t $snort_rm_blocked_expire snort2c"; + + /* Add cron job if not already installed, else just update the existing one */ + if (!$is_installed) $config['cron']['item'][] = $cron_item; - } + elseif ($is_installed) + $config['cron']['item'][$x] = $cron_item; break; case false: if ($is_installed == true) @@ -672,17 +735,20 @@ function snort_rules_up_install_cron($should_install) { } switch($should_install) { case true: - if(!$is_installed) { - $cron_item = array(); - $cron_item['minute'] = "$snort_rules_up_min"; - $cron_item['hour'] = "$snort_rules_up_hr"; - $cron_item['mday'] = "$snort_rules_up_mday"; - $cron_item['month'] = "$snort_rules_up_month"; - $cron_item['wday'] = "$snort_rules_up_wday"; - $cron_item['who'] = "root"; - $cron_item['command'] = "/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/snort/snort_check_for_rule_updates.php >> /tmp/snort_update.log"; + $cron_item = array(); + $cron_item['minute'] = "$snort_rules_up_min"; + $cron_item['hour'] = "$snort_rules_up_hr"; + $cron_item['mday'] = "$snort_rules_up_mday"; + $cron_item['month'] = "$snort_rules_up_month"; + $cron_item['wday'] = "$snort_rules_up_wday"; + $cron_item['who'] = "root"; + $cron_item['command'] = "/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/snort/snort_check_for_rule_updates.php >> /tmp/snort_update.log"; + + /* Add cron job if not already installed, else just update the existing one */ + if (!$is_installed) $config['cron']['item'][] = $cron_item; - } + elseif ($is_installed) + $config['cron']['item'][$x] = $cron_item; break; case false: if($is_installed == true) @@ -693,12 +759,15 @@ function snort_rules_up_install_cron($should_install) { /* Only run when all ifaces needed to sync. Expects filesystem rw */ function sync_snort_package_config() { - global $config, $g; + global $config, $g, $flowbit_rules_file, $snort_enforcing_rules_file; + global $snort_version, $rebuild_rules; + + $snortdir = SNORTDIR; conf_mount_rw(); - /* do not start config build if rules is empty */ - if (!is_array($config['installedpackages']['snortglobal']) && !is_array($config['installedpackages']['snortglobal']['rule'])) { + /* do not start config build if rules is empty or there are no Snort settings */ + if (!is_array($config['installedpackages']['snortglobal']) || !is_array($config['installedpackages']['snortglobal']['rule'])) { exec('/bin/rm /usr/local/etc/rc.d/snort.sh'); conf_mount_ro(); return; @@ -708,10 +777,10 @@ function sync_snort_package_config() { foreach ($snortconf as $value) { $if_real = snort_get_real_interface($value['interface']); - /* create snort configuration file */ + /* create a snort.conf file for interface */ snort_generate_conf($value); - /* create barnyard2 configuration file */ + /* create barnyard2.conf file for interface */ if ($value['barnyard_enable'] == 'on') snort_create_barnyard2_conf($value, $if_real); } @@ -748,7 +817,7 @@ function snort_build_sid_msg_map($rules_path, $sid_file) { /* First check if we were passed a directory, a single file */ /* or an array of filenames to read. Set our $rule_files */ /* variable accordingly. If we can't figure it out, return */ - /* an empty rules map array. */ + /* and don't write a sid_msg_map file. */ if (is_string($rules_path)) { if (is_dir($rules_path)) $rule_files = glob($rules_path . "*.rules"); @@ -858,11 +927,19 @@ function snort_merge_reference_configs($cfg_in, $cfg_out) { /* Sort the new reference map. */ uksort($outMap,'strnatcasecmp'); + /**********************************************************/ + /* Do NOT write an empty references.config file, just */ + /* exit instead. */ + /**********************************************************/ + if (empty($outMap)) + return false; + /* Format and write it to the supplied output file. */ $format = "config reference: %-12s %s\n"; foreach ($outMap as $key=>$value) $outMap[$key] = sprintf($format, $key, $value); @file_put_contents($cfg_out, array_values($outMap)); + return true; } function snort_merge_classification_configs($cfg_in, $cfg_out) { @@ -895,11 +972,19 @@ function snort_merge_classification_configs($cfg_in, $cfg_out) { /* Sort the new classification map. */ uksort($outMap,'strnatcasecmp'); + /**********************************************************/ + /* Do NOT write an empty classification.config file, just */ + /* exit instead. */ + /**********************************************************/ + if (empty($outMap)) + return false; + /* Format and write it to the supplied output file. */ $format = "config classification: %s,%s\n"; foreach ($outMap as $key=>$value) $outMap[$key] = sprintf($format, $key, $value); @file_put_contents($cfg_out, array_values($outMap)); + return true; } function snort_load_rules_map($rules_path) { @@ -1272,11 +1357,13 @@ function snort_write_flowbit_rules_file($flowbit_rules, $rule_file) { /* given. */ /************************************************/ + global $flowbit_rules_file; + /* See if we were passed a directory or full */ /* filename to write the rules to, and adjust */ /* the destination argument accordingly. */ if (is_dir($rule_file)) - $rule_file = rtrim($rule_file, '/').'/flowbit-required.rules'; + $rule_file = rtrim($rule_file, '/')."/{$flowbit_rules_file}"; if (empty($flowbit_rules)) { @file_put_contents($rule_file, ""); @@ -1363,7 +1450,7 @@ function snort_write_enforcing_rules_file($rule_map, $rule_path) { global $snort_enforcing_rules_file; - $rule_file = "/snort.rules"; + $rule_file = "/{$snort_enforcing_rules_file}"; /* See if we were passed a directory or full */ /* filename to write the rules to, and adjust */ @@ -1402,9 +1489,17 @@ function snort_load_sid_mods($sids, $value) { /* This function parses the string of */ /* SID values in $sids and returns an */ /* array with the SID as the key and */ - /* passed $value as the value. The SID */ - /* values in $sids are assumed to be */ - /* delimited by "||". */ + /* value. The SID values in $sids are */ + /* assumed to be delimited by "||". */ + /* */ + /* $sids ==> string of SID values from */ + /* saved config file. */ + /* */ + /* $value ==> type of mod (enable or */ + /* disable). Not currently */ + /* utilized, but maintained */ + /* so as not to break legacy */ + /* code elsewhere. */ /*****************************************/ $result = array(); @@ -1413,7 +1508,7 @@ function snort_load_sid_mods($sids, $value) { $tmp = explode("||", $sids); foreach ($tmp as $v) { if (preg_match('/\s\d+/', $v, $match)) - $result[trim($match[0])] = $value; + $result[trim($match[0])] = trim($match[0]); } unset($tmp); @@ -1458,14 +1553,13 @@ function snort_modify_sids(&$rule_map, $snortcfg) { if (!empty($disablesid)) { foreach ($rule_map as $k1 => $rulem) { foreach ($rulem as $k2 => $v) { - if (in_array($k2, $disablesid) && $v['disabled'] == 0) { + if (in_array($k2, $disablesid) && $v['disabled'] == 0) { $rule_map[$k1][$k2]['rule'] = "# " . $v['rule']; $rule_map[$k1][$k2]['disabled'] = 1; } } } } - unset($enablesid, $disablesid); } @@ -1475,6 +1569,7 @@ function snort_create_rc() { global $config, $g; $snortdir = SNORTDIR; + $rcdir = RCFILEPREFIX; if (!is_array($config['installedpackages']['snortglobal']['rule'])) return; @@ -1494,8 +1589,9 @@ function snort_create_rc() { if [ ! -f {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid ]; then /bin/pgrep -xf '/usr/local/bin/barnyard2 -r {$snort_uuid} -f snort_{$snort_uuid}_{$if_real}.u2 --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d /var/log/snort/snort_{$if_real}{$snort_uuid} -D -q' > {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid + else + /bin/pgrep -F {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid fi - /bin/pgrep -F {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid if [ $? = 0 ]; then /bin/pkill -HUP -F {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid -a else @@ -1506,10 +1602,30 @@ EOE; $stop_barnyard2 = <<<EOE if [ -f {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid ]; then + pid=`/bin/pgrep -F {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid` /bin/pkill -F {$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid -a - /bin/rm /var/run/barnyard2_{$if_real}{$snort_uuid}.pid + time=0 timeout=30 + while kill -0 \$pid 2>/dev/null; do + sleep 1 + time=\$((time+1)) + if [ \$time -gt \$timeout ]; then + break + fi + done + if [ -f /var/run/barnyard2_{$if_real}{$snort_uuid}.pid ]; then + /bin/rm /var/run/barnyard2_{$if_real}{$snort_uuid}.pid + fi else + pid=`/bin/pgrep -xf '/usr/local/bin/barnyard2 -r {$snort_uuid} -f snort_{$snort_uuid}_{$if_real}.u2 --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d /var/log/snort/snort_{$if_real}{$snort_uuid} -D -q'` /bin/pkill -xf '/usr/local/bin/barnyard2 -r {$snort_uuid} -f snort_{$snort_uuid}_{$if_real}.u2 --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d /var/log/snort/snort_{$if_real}{$snort_uuid} -D -q' + time=0 timeout=30 + while kill -0 \$pid 2>/dev/null; do + sleep 1 + time=\$((time+1)) + if [ \$time -gt \$timeout ]; then + break + fi + done fi EOE; @@ -1521,19 +1637,18 @@ EOE; $start_snort_iface_start[] = <<<EOE ###### For Each Iface -#### Only try to restart if snort is running on Iface + # Start snort and barnyard2 if [ ! -f {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid ]; then - /bin/pgrep -xf '/usr/local/bin/snort -R {$snort_uuid} -D -q -l /var/log/snort/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}' > {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid + pid=`/bin/pgrep -xf '/usr/local/bin/snort -R {$snort_uuid} -D -q -l /var/log/snort/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}'` + else + pid=`/bin/pgrep -F {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid` fi - /bin/pgrep -nF {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid if [ $? = 0 ]; then - /bin/pkill -HUP -F {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid -a - /usr/bin/logger -p daemon.info -i -t SnortStartup "Snort SOFT START For {$value['descr']}({$snort_uuid}_{$if_real})..." + /bin/pkill -HUP \$pid + /usr/bin/logger -p daemon.info -i -t SnortStartup "Snort SOFT RESTART for {$value['descr']}({$snort_uuid}_{$if_real})..." else - # Start snort and barnyard2 - /bin/rm {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid /usr/local/bin/snort -R {$snort_uuid} -D -q -l /var/log/snort/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real} - /usr/bin/logger -p daemon.info -i -t SnortStartup "Snort START For {$value['descr']}({$snort_uuid}_{$if_real})..." + /usr/bin/logger -p daemon.info -i -t SnortStartup "Snort START for {$value['descr']}({$snort_uuid}_{$if_real})..." fi sleep 2 @@ -1543,12 +1658,32 @@ EOE; $start_snort_iface_stop[] = <<<EOE - /usr/bin/logger -p daemon.info -i -t SnortStartup "Snort STOP For {$value['descr']}({$snort_uuid}_{$if_real})..." + /usr/bin/logger -p daemon.info -i -t SnortStartup "Snort STOP for {$value['descr']}({$snort_uuid}_{$if_real})..." if [ -f {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid ]; then + pid=`/bin/pgrep -F {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid` /bin/pkill -F {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid -a - /bin/rm /var/run/snort_{$if_real}{$snort_uuid}.pid - else + time=0 timeout=30 + while kill -0 \$pid 2>/dev/null; do + sleep 1 + time=\$((time+1)) + if [ \$time -gt \$timeout ]; then + break + fi + done + if [ -f /var/run/snort_{$if_real}{$snort_uuid}.pid ]; then + /bin/rm /var/run/snort_{$if_real}{$snort_uuid}.pid + fi + else + pid=`/bin/pgrep -xf '/usr/local/bin/snort -R {$snort_uuid} -D -q -l /var/log/snort/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}'` /bin/pkill -xf '/usr/local/bin/snort -R {$snort_uuid} -D -q -l /var/log/snort/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}' + time=0 timeout=30 + while kill -0 \$pid 2>/dev/null; do + sleep 1 + time=\$((time+1)) + if [ \$time -gt \$timeout ]; then + break + fi + done fi sleep 2 @@ -1584,6 +1719,7 @@ case $1 in rc_stop ;; restart) + rc_stop rc_start ;; esac @@ -1591,11 +1727,11 @@ esac EOD; /* write out snort.sh */ - if (!@file_put_contents("/usr/local/etc/rc.d/snort.sh", $snort_sh_text)) { - log_error("Could not open /usr/local/etc/rc.d/snort.sh for writing."); + if (!@file_put_contents("{$rcdir}/snort.sh", $snort_sh_text)) { + log_error("Could not open {$rcdir}/snort.sh for writing."); return; } - @chmod("/usr/local/etc/rc.d/snort.sh", 0755); + @chmod("{$rcdir}/snort.sh", 0755); } /* open barnyard2.conf for writing */ @@ -1642,13 +1778,16 @@ function snort_generate_barnyard2_conf($snortcfg, $if_real) { config reference_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/reference.config config classification_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/classification.config config gen_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/gen-msg.map -config sid_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/sid-msg.map +config sid_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/sid-msg.map config hostname: $snortbarnyardlog_hostname_info_chk config interface: {$if_real} config decode_data_link config waldo_file: /var/log/snort/snort_{$if_real}{$snort_uuid}/barnyard2/{$snort_uuid}_{$if_real}.waldo +# Show year in timestamps +config show_year + ## START user pass through ## {$snortbarnyardlog_config_pass_thru} @@ -1671,12 +1810,15 @@ EOD; } function snort_deinstall() { - global $config, $g; + + global $config, $g, $snort_rules_upd_log; $snortdir = SNORTDIR; + $snortlibdir = SNORTLIBDIR; $snortlogdir = SNORTLOGDIR; + $rcdir = RCFILEPREFIX; - /* decrease bpf buffers back to 4096, from 20480 */ + /* Make sure all active Snort processes are terminated */ mwexec('/usr/bin/killall snort', true); sleep(2); mwexec('/usr/bin/killall -9 snort', true); @@ -1685,9 +1827,11 @@ function snort_deinstall() { sleep(2); mwexec('/usr/bin/killall -9 barnyard2', true); sleep(2); + + /* Remove the snort user and group */ mwexec('/usr/sbin/pw userdel snort; /usr/sbin/pw groupdel snort', true); - /* Remove snort cron entries Ugly code needs smoothness*/ + /* Remove snort cron entries Ugly code needs smoothness */ if (!function_exists('snort_deinstall_cron')) { function snort_deinstall_cron($crontask) { global $config, $g; @@ -1709,25 +1853,62 @@ function snort_deinstall() { } } - mwexec("/bin/rm {$snortdir}/*.md5; /bin/rm -r {$snortdir}/snort_*"); + /* Remove all the Snort cron jobs. */ snort_deinstall_cron("snort2c"); snort_deinstall_cron("snort_check_for_rule_updates.php"); snort_deinstall_cron("snort_check_cron_misc.inc"); configure_cron(); + /**********************************************************/ + /* Test for existence of library backup tarballs in /tmp. */ + /* If these are present, then a package "delete" */ + /* operation is in progress and we need to wipe out the */ + /* configuration files. Otherwise we leave the binary- */ + /* side configuration intact since only a GUI files */ + /* deinstall and reinstall operation is in progress. */ + /* */ + /* XXX: hopefully a better method presents itself in */ + /* future versions of pfSense. */ + /**********************************************************/ + if (file_exists("/tmp/pkg_libs.tgz") || file_exists("/tmp/pkg_bins.tgz")) { + log_error(gettext("[Snort] Package deletion requested... removing all files...")); + mwexec("/bin/rm -rf {$snortdir}"); + mwexec("/bin/rm -rf {$snortlibdir}/dynamicrules"); + mwexec("/bin/rm -f {$rcdir}/snort.sh"); + mwexec("/bin/rm -rf /usr/local/pkg/snort"); + mwexec("/bin/rm -rf /usr/local/www/snort"); + mwexec("/bin/rm -rf /usr/local/etc/snort"); + } + /* Keep this as a last step */ - if ($config['installedpackages']['snortglobal']['forcekeepsettings'] != 'on') + if ($config['installedpackages']['snortglobal']['forcekeepsettings'] != 'on') { + log_error(gettext("Not saving settings... all Snort configuration info and logs deleted...")); unset($config['installedpackages']['snortglobal']); + @unlink("{$snort_rules_upd_log}"); + mwexec("/bin/rm -rf {$snortlogdir}"); + log_error(gettext("[Snort] The package has been removed from this system...")); + } } function snort_prepare_rule_files($snortcfg, $snortcfgdir) { - global $snort_enforcing_rules_file, $flowbit_rules_file; + + global $snort_enforcing_rules_file, $flowbit_rules_file, $rebuild_rules; $snortdir = SNORTDIR; + $no_rules_defined = true; + + /* If there is no reason to rebuild the rules, exit to save time. */ + if ($rebuild_rules == "off") + return; + + /* Log a message for rules rebuild in progress */ + log_error(gettext("[Snort] Updating rules configuration for: " . snort_get_friendly_interface($snortcfg['interface']) . " ...")); + /* Only rebuild rules if some are selected or an IPS Policy is enabled */ if (!empty($snortcfg['rulesets']) || $snortcfg['ips_policy_enable'] == 'on') { $enabled_rules = array(); $enabled_files = array(); + $no_rules_defined = false; /* Create an array with the full path filenames of the enabled */ /* rule category files if we have any. */ @@ -1741,16 +1922,6 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { $enabled_rules = snort_load_rules_map($enabled_files); } - /* Remove any existing rules files (except custom rules) prior to building a new set. */ - foreach (glob("{$snortcfgdir}/rules/*.rules") as $file) { - $tmpfile = basename($file); - if (in_array("{$snortdir}/rules/{$tmpfile}", $enabled_files)) - continue; - if ($tmpfile != "custom.rules" && $tmpfile != $flowbit_rules_file && - $tmpfile != $snort_enforcing_rules_file) - @unlink($file); - } - /* Check if a pre-defined Snort VRT policy is selected. If so, */ /* add all the VRT policy rules to our enforcing rule set. */ if (!empty($snortcfg['ips_policy'])) { @@ -1773,9 +1944,12 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { /* Process any enablesid or disablesid modifications for the selected rules. */ snort_modify_sids($enabled_rules, $snortcfg); - /* Check for and disable any rules dependent upon disabled preprocessors. */ - log_error('Checking for and disabling any rules dependent upon disabled preprocessors for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); - snort_filter_preproc_rules($snortcfg, $enabled_rules); + /* Check for and disable any rules dependent upon disabled preprocessors if */ + /* this option is enabled for the interface. */ + if ($snortcfg['preproc_auto_rule_disable'] == "on") { + log_error('[Snort] Checking for rules dependent on disabled preprocessors for: ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); + snort_filter_preproc_rules($snortcfg, $enabled_rules); + } /* Write the enforcing rules file to the Snort interface's "rules" directory. */ snort_write_enforcing_rules_file($enabled_rules, "{$snortcfgdir}/rules/{$snort_enforcing_rules_file}"); @@ -1783,9 +1957,19 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { /* If auto-flowbit resolution is enabled, generate the dependent flowbits rules file. */ if ($snortcfg['autoflowbitrules'] == 'on') { - log_error('Resolving and auto-enabling flowbit required rules for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); + log_error('[Snort] Enabling any flowbit-required rules for: ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); $enabled_files[] = "{$snortcfgdir}/rules/{$snort_enforcing_rules_file}"; - snort_write_flowbit_rules_file(snort_resolve_flowbits($enabled_files), "{$snortcfgdir}/rules/{$flowbit_rules_file}"); + $fbits = snort_resolve_flowbits($enabled_files); + + /* Check for and disable any flowbit-required rules dependent upon */ + /* disabled preprocessors if this option is enabled for the interface. */ + if ($snortcfg['preproc_auto_rule_disable'] == "on") { + log_error('[Snort] Checking flowbit rules dependent on disabled preprocessors for: ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); + snort_filter_preproc_rules($snortcfg, $fbits, true); + } + snort_filter_preproc_rules($snortcfg, $fbits, true); + snort_write_flowbit_rules_file($fbits, "{$snortcfgdir}/rules/{$flowbit_rules_file}"); + unset($fbits); } else /* Just put an empty file to always have the file present */ snort_write_flowbit_rules_file(array(), "{$snortcfgdir}/rules/{$flowbit_rules_file}"); @@ -1796,17 +1980,24 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { snort_write_flowbit_rules_file(array(), "{$snortcfgdir}/rules/{$flowbit_rules_file}"); } - if (!empty($snortcfg['customrules'])) + if (!empty($snortcfg['customrules'])) { @file_put_contents("{$snortcfgdir}/rules/custom.rules", base64_decode($snortcfg['customrules'])); + $no_rules_defined = false; + } else @file_put_contents("{$snortcfgdir}/rules/custom.rules", ""); + /* Log a warning if the interface has no rules defined or enabled */ + if ($no_rules_defined) + log_error(gettext("[Snort] Warning - no text rules selected for: " . snort_get_friendly_interface($snortcfg['interface']) . " ...")); + /* Build a new sid-msg.map file from the enabled */ /* rules and copy it to the interface directory. */ + log_error(gettext("[Snort] Building new sig-msg.map file for " . snort_get_friendly_interface($snortcfg['interface']) . "...")); snort_build_sid_msg_map("{$snortcfgdir}/rules/", "{$snortcfgdir}/sid-msg.map"); } -function snort_filter_preproc_rules($snortcfg, &$active_rules) { +function snort_filter_preproc_rules($snortcfg, &$active_rules, $persist_log = false) { /**************************************************/ /* This function checks the $active_rules array */ @@ -1819,11 +2010,22 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { /* the interface */ /* $active_rules -> rules_map array of enabled */ /* rules for the interface */ + /* */ + /* NOTE: This feature must be enabled in the GUI */ + /* by the user. Use of this feature can */ + /* severely degrade Snort's ability to */ + /* detect threats by disabling potentially */ + /* crucial detection rules. */ /**************************************************/ global $config; - if (empty($active_rules)) + $snortlogdir = SNORTLOGDIR; + $disabled_count = 0; + $log_msg = array(); + + /* Check if no rules or if this option is disabled */ + if (empty($active_rules) || $snortcfg['preproc_auto_rule_disable'] <> 'on') return; /*************************************************** @@ -1833,8 +2035,20 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { * IMPORTANT -- Keep this part of the code current * * with changes to preprocessor rule options in * * Snort VRT rules. * + * * + * * + * Format of array is: * + * "rule_option" => "dependent_preprocessor" * + * * + * Last Update: 04/05/2013 * + * * + * Added: http_inspect content modifiers and * + * various "service" metadata values. * + * * ***************************************************/ $rule_opts_preprocs = array("ssl_version:" => "ssl_preproc","ssl_state:" => "ssl_preproc", + "service ssl" => "ssl_preproc", "service ftp" => "ftp_preprocessor", + "service telnet" => "ftp_preprocessor", "service dns" => "dns_preprocessor", "dce_iface:" => "dce_rpc_2", "dce_opnum:" => "dce_rpc_2", "dce_stub_data;" => "dce_rpc_2", "sd_pattern:" => "sensitive_data", "sip_method:" => "sip_preproc", "sip_stat_code:" => "sip_preproc", @@ -1843,7 +2057,16 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { "gtp_version:" => "gtp_preproc", "modbus_func:" => "modbus_preproc", "modbus_unit:" => "modbus_preproc", "modbus_data;" => "modbus_preproc", "dnp3_func:" => "dnp3_preproc", "dnp3_obj:" => "dnp3_preproc", - "dnp3_ind:" => "dnp3_preproc", "dnp3_data;" => "dnp3_preproc"); + "dnp3_ind:" => "dnp3_preproc", "dnp3_data;" => "dnp3_preproc", + "http_client_body;" => "http_inspect", "http_cookie;" => "http_inspect", + "http_raw_cookie;" => "http_inspect", "http_header;" => "http_inspect", + "http_raw_header;" => "http_inspect", "http_method;" => "http_inspect", + "http_uri;" => "http_inspect", "http_raw_uri;" => "http_inspect", + "http_stat_code;" => "http_inspect", "http_stat_msg;" => "http_inspect", + "uricontent:" => "http_inspect", "urilen:" => "http_inspect", + "http_encode;" => "http_inspect", "service http" => "http_inspect", + "service imap" => "imap_preproc", "service pop2" => "pop_preproc", + "service pop3" => "pop_preproc", "service smtp" => "smtp_preprocessor"); /*************************************************** * Iterate the enabled rules, and check for rule * @@ -1855,31 +2078,99 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { ***************************************************/ foreach ($active_rules as $k1 => $rulem) { foreach ($rulem as $k2 => $v) { - if ($v['disabled'] == 0) + + /* If rule is already disabled, skip it. */ + if ($v['disabled'] == 1) continue; + foreach ($rule_opts_preprocs as $opt => $preproc) { - $pcre = "/\s*\b" . $opt . "/i"; + $pcre = "/\s*\b" . preg_quote($opt) . "/i"; if (($snortcfg[$preproc] != 'on') && preg_match($pcre, $v['rule'])) { $active_rules[$k1][$k2]['rule'] = "# " . $v['rule']; $active_rules[$k1][$k2]['disabled'] = 1; + $disabled_count++; + + /* Accumulate auto-disabled rules for logging */ + $tmp = $active_rules[$k1][$k2]['category'] . ","; + $tmp .= "{$k1}:{$k2},{$preproc},{$opt}"; + $log_msg[] = $tmp; break; } } } } + + /***************************************************************/ + /* If we are persisting the log from the last pass, then open */ + /* the log file in append mode. Otherwise open in overwrite */ + /* to clear the log in case we have zero disabled rules. */ + /* */ + /* Typically "persist log" mode is used on the second pass */ + /* when flowbit-required rules are being assessed after the */ + /* primary enforcing rules have been evaluated. */ + /***************************************************************/ + $iface = snort_get_friendly_interface($snortcfg['interface']); + $file = "{$snortlogdir}/{$iface}_disabled_preproc_rules.log"; + if ($persist_log) + $fp = fopen($file, 'a'); + else + $fp = fopen($file, 'w'); + + /***************************************************/ + /* Log a warning if we auto-disabled any rules */ + /* just so the user is aware protection is less */ + /* than optimal with the preprocessors disabled. */ + /***************************************************/ + if ($disabled_count > 0) { + log_error(gettext("[Snort] Warning: auto-disabled {$disabled_count} rules due to disabled preprocessor dependencies.")); + natcasesort($log_msg); + if ($fp) { + /* Only write the header when not persisting the log */ + if (!$persist_log) { + @fwrite($fp, "#\n# Run Time: " . date("Y-m-d H:i:s") . "\n#\n"); + @fwrite($fp, "#\n# These rules were auto-disabled because they contain options or operators\n"); + @fwrite($fp, "# dependent on preprocessors that are currently NOT ENABLED on the Preprocessors\n"); + @fwrite($fp, "# tab. Without these dependent preprocessors enabled, Snort would fail to start\n"); + @fwrite($fp, "# if the rules listed below were enabled. Therefore the listed rules have been\n"); + @fwrite($fp, "# automatically disabled. This behavior is controlled by the Auto-Rule Disable\n"); + @fwrite($fp, "# feature on the Preprocessors tab.\n#\n"); + @fwrite($fp, "# WARNING: Using the auto-disable rule feature is not recommended because it can\n"); + @fwrite($fp, "# significantly reduce the threat detection capabilities of Snort!\n#"); + @fwrite($fp, "\n# In the list below, the PREPROCESSOR column is the disabled preprocessor that\n"); + @fwrite($fp, "# triggered the auto-disable of the rule represented by GID:SID. The RULE OPTION\n"); + @fwrite($fp, "# column shows the specific rule option or content modifier contained within\n"); + @fwrite($fp, "# the rule text that requires the preprocessor be enabled in order to execute.\n#"); + @fwrite($fp, "\n# RULE CATEGORY GID:SID PREPROCESSOR RULE OPTION\n"); + } + foreach ($log_msg as $m) { + $tmp = explode(",", $m); + @fwrite($fp, sprintf("%-30s %-10s %-20s %s", $tmp[0], $tmp[1], $tmp[2], $tmp[3]) . "\n"); + } + } + log_error(gettext("[Snort] See '{$file}' for list of auto-disabled rules.")); + unset($log_msg); + } + if ($fp) + fclose($fp); } function snort_generate_conf($snortcfg) { - global $config, $g; + + global $config, $g, $flowbit_rules_file, $snort_enforcing_rules_file, $rebuild_rules; $snortdir = SNORTDIR; + $snortlibdir = SNORTLIBDIR; $snortlogdir = SNORTLOGDIR; - $flowbit_rules_file = "flowbit-required.rules"; - $snort_enforcing_rules_file = "snort.rules"; if (!is_array($config['installedpackages']['snortglobal']['rule'])) return; + /* See if we should protect and not modify the preprocessor rules files */ + if (!empty($snortcfg['protect_preproc_rules'])) + $protect_preproc_rules = $snortcfg['protect_preproc_rules']; + else + $protect_preproc_rules = "off"; + $if_real = snort_get_real_interface($snortcfg['interface']); $snort_uuid = $snortcfg['uuid']; $snortcfgdir = "{$snortdir}/snort_{$snort_uuid}_{$if_real}"; @@ -1902,8 +2193,8 @@ function snort_generate_conf($snortcfg) { "{$snortlogdir}/snort_{$if_real}{$snort_uuid}", "{$snortlogdir}/snort_{$if_real}{$snort_uuid}/barnyard2", "{$snortcfgdir}/preproc_rules", - "dynamicrules" => "/usr/local/lib/snort/dynamicrules", - "dynamicengine" => "/usr/local/lib/snort/dynamicengine", + "dynamicrules" => "{$snortlibdir}/dynamicrules", + "dynamicengine" => "{$snortlibdir}/dynamicengine", "dynamicpreprocessor" => "{$snortcfgdir}/dynamicpreprocessor" ); foreach ($snort_dirs as $dir) { @@ -1911,13 +2202,24 @@ function snort_generate_conf($snortcfg) { safe_mkdir($dir); } + /********************************************************************/ + /* For fail-safe on an initial startup following installation, and */ + /* before a rules update has occurred, copy the default config */ + /* files to the interface directory. If files already exist in */ + /* the interface directory, or they are newer, that means a rule */ + /* update has been done and we should leave the customized files */ + /* put in place by the rules update process. */ + /********************************************************************/ $snort_files = array("gen-msg.map", "classification.config", "reference.config", "sid-msg.map", "unicode.map", "threshold.conf", "preproc_rules/preprocessor.rules", "preproc_rules/decoder.rules", "preproc_rules/sensitive-data.rules" ); foreach ($snort_files as $file) { - if (file_exists("{$snortdir}/{$file}")) - @copy("{$snortdir}/{$file}", "{$snortcfgdir}/{$file}"); + if (file_exists("{$snortdir}/{$file}")) { + $ftime = filemtime("{$snortdir}/{$file}"); + if (!file_exists("{$snortcfgdir}/{$file}") || ($ftime > filemtime("{$snortcfgdir}/{$file}"))) + @copy("{$snortdir}/{$file}", "{$snortcfgdir}/{$file}"); + } } /* define alertsystemlog */ @@ -2011,7 +2313,7 @@ EOD; if ((!empty($snortcfg['client_flow_depth'])) || ($snortcfg['client_flow_depth'] == '0')) $def_client_flow_depth_type = $snortcfg['client_flow_depth']; - if ($snortcfg['noalert_http_inspect'] == 'on') + if ($snortcfg['noalert_http_inspect'] == 'on' || empty($snortcfg['noalert_http_inspect'])) $noalert_http_inspect = "no_alerts "; else $noalert_http_inspect = ""; @@ -2256,6 +2558,16 @@ EOD; if (!empty($snortcfg['stream5_mem_cap'])) $def_stream5_mem_cap = ", memcap {$snortcfg['stream5_mem_cap']}"; + /* Default the HTTP_INSPECT preprocessor to "on" if not set. */ + /* The preprocessor is required by hundreds of Snort rules, */ + /* and without it Snort may not start and/or the number of */ + /* rules required to be disabled reduces Snort's capability. */ + /* Alerts from the HTTP_INSPECT preprocessor default to "off" */ + /* unless a specific value has been set by the user. */ + /**************************************************************/ + if (empty($snortcfg['http_inspect'])) + $snortcfg['http_inspect'] = 'on'; + /* define servers and ports snortdefservers */ $snort_servers = array ( "dns_servers" => "\$HOME_NET", "smtp_servers" => "\$HOME_NET", "http_servers" => "\$HOME_NET", @@ -2294,8 +2606,8 @@ EOD; if (!empty($snort_preproc_libs[$preproc])) { $preproclib = "libsf_" . $snort_preproc_libs[$preproc]; if (!file_exists($snort_dirs['dynamicpreprocessor'] . "{$preproclib}.so")) { - if (file_exists("/usr/local/lib/snort/dynamicpreprocessor/{$preproclib}.so")) { - @copy("/usr/local/lib/snort/dynamicpreprocessor/{$preproclib}.so", "{$snort_dirs['dynamicpreprocessor']}/{$preproclib}.so"); + if (file_exists("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so")) { + @copy("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so", "{$snort_dirs['dynamicpreprocessor']}/{$preproclib}.so"); $snort_preprocessors .= $$preproc; $snort_preprocessors .= "\n"; } else @@ -2317,28 +2629,32 @@ EOD; if (file_exists("{$snortcfgdir}/classification.config")) $snort_misc_include_rules .= "include {$snortcfgdir}/classification.config\n"; if (is_dir("{$snortcfgdir}/preproc_rules")) { - if ($snortcfg['sensitive_data'] == 'on') { + if ($snortcfg['sensitive_data'] == 'on' && $protect_preproc_rules == "off") { $sedcmd = '/^#alert.*classtype:sdf/s/^#//'; if (file_exists("{$snortcfgdir}/preproc_rules/sensitive-data.rules")) $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/sensitive-data.rules\n"; } else $sedcmd = '/^alert.*classtype:sdf/s/^/#/'; if (file_exists("{$snortcfgdir}/preproc_rules/decoder.rules") && - file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules")) { + file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules") && $protect_preproc_rules == "off") { @file_put_contents("{$g['tmp_path']}/sedcmd", $sedcmd); mwexec("/usr/bin/sed -I '' -f {$g['tmp_path']}/sedcmd {$snortcfgdir}/preproc_rules/preprocessor.rules"); mwexec("/usr/bin/sed -I '' -f {$g['tmp_path']}/sedcmd {$snortcfgdir}/preproc_rules/decoder.rules"); @unlink("{$g['tmp_path']}/sedcmd"); - $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/decoder.rules\n"; $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/preprocessor.rules\n"; - } else { + } else if (file_exists("{$snortcfgdir}/preproc_rules/decoder.rules") && + file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules") && $protect_preproc_rules == "on") { + $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/decoder.rules\n"; + $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/preprocessor.rules\n"; + } + else { $snort_misc_include_rules .= "config autogenerate_preprocessor_decoder_rules\n"; - log_error("Seems preprocessor/decoder rules are missing, enabling autogeneration of them"); + log_error("[Snort] Seems preprocessor/decoder rules are missing, enabling autogeneration of them"); } } else { $snort_misc_include_rules .= "config autogenerate_preprocessor_decoder_rules\n"; - log_error("Seems preprocessor/decoder rules are missing, enabling autogeneration of them"); + log_error("[Snort] Seems preprocessor/decoder rules are missing, enabling autogeneration of them"); } /* generate rule sections to load */ @@ -2346,6 +2662,8 @@ EOD; $selected_rules_sections = "include \$RULE_PATH/{$snort_enforcing_rules_file}\n"; $selected_rules_sections .= "include \$RULE_PATH/{$flowbit_rules_file}\n"; $selected_rules_sections .= "include \$RULE_PATH/custom.rules\n"; + + /* Create the actual rules file and save in the interface directory */ snort_prepare_rule_files($snortcfg, $snortcfgdir); $cksumcheck = "all"; @@ -2393,6 +2711,9 @@ config pcre_match_limit_recursion: 1500 config detection: search-method {$snort_performance} search-optimize max-pattern-len 20 max_queue_events 5 config event_queue: max_queue 8 log 5 order_events content_length +# Configure to show year in timestamps +config show_year + # Configure protocol aware flushing # # For more information see README.stream5 # config paf_max: 16000 diff --git a/config/snort/snort.xml b/config/snort/snort.xml index b18e66e1..2f60b7ae 100755 --- a/config/snort/snort.xml +++ b/config/snort/snort.xml @@ -46,8 +46,8 @@ <requirements>Describe your package requirements here</requirements> <faq>Currently there are no FAQ items provided.</faq> <name>Snort</name> - <version>2.9.2.3</version> - <title>Services:2.9.2.3 pkg v. 2.5.3</title> + <version>2.9.4.1</version> + <title>Services:2.9.4.1 pkg v. 2.5.7</title> <include_file>/usr/local/pkg/snort/snort.inc</include_file> <menu> <name>Snort</name> @@ -163,6 +163,11 @@ <chmod>077</chmod> <item>http://www.pfsense.com/packages/config/snort/snort_interfaces_suppress_edit.php</item> </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/snort/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/snort/snort_log_view.php</item> + </additional_files_needed> <fields> </fields> <custom_add_php_command> @@ -177,3 +182,4 @@ snort_deinstall(); </custom_php_deinstall_command> </packagegui> + diff --git a/config/snort/snort_alerts.php b/config/snort/snort_alerts.php index e6ebefeb..3fcbe6b7 100755 --- a/config/snort/snort_alerts.php +++ b/config/snort/snort_alerts.php @@ -219,7 +219,7 @@ if ($pconfig['arefresh'] == 'on') <td width="78%" class="vtable"> <input name="download" type="submit" class="formbtn" value="Download"> <?php echo gettext('All ' . 'log files will be saved.'); ?> <a href="/snort/snort_alerts.php?action=clear&instance=<?=$instanceid;?>"> - <input name="delete" type="button" class="formbtn" value="Clear" + <input name="delete" type="submit" class="formbtn" value="Clear" onclick="return confirm('Do you really want to remove all instance logs?')"></a> <span class="red"><strong><?php echo gettext('Warning:'); ?></strong></span> <?php echo ' ' . gettext('all log files will be deleted.'); ?> </td> diff --git a/config/snort/snort_barnyard.php b/config/snort/snort_barnyard.php index ccbe3c26..e1de3efd 100644 --- a/config/snort/snort_barnyard.php +++ b/config/snort/snort_barnyard.php @@ -32,7 +32,7 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $rebuild_rules; $id = $_GET['id']; if (isset($_POST['id'])) @@ -87,6 +87,9 @@ if ($_POST) { } write_config(); + + /* No need to rebuild rules if just toggling Barnyard2 on or off */ + $rebuild_rules = "off"; sync_snort_package_config(); /* after click go to this page */ @@ -173,10 +176,10 @@ function enable_change(enable_change) { <?php echo gettext("This will enable barnyard2 for this interface. You will also have to set the database credentials."); ?></td> </tr> <tr> - <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Mysql Settings"); ?></td> + <td colspan="2" valign="top" class="listtopic"><?php echo gettext("MySQL Settings"); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Log to a Mysql Database"); ?></td> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Log to a MySQL Database"); ?></td> <td width="78%" class="vtable"><input name="barnyard_mysql" type="text" class="formfld" id="barnyard_mysql" size="100" value="<?=htmlspecialchars($pconfig['barnyard_mysql']);?>"> <br> @@ -207,7 +210,7 @@ function enable_change(enable_change) { <td width="22%" valign="top"> </td> <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> <br> - <?php echo gettext("Please save your settings befor you click start."); ?> </td> + <?php echo gettext("Please save your settings before you click start."); ?> </td> </tr> </table> diff --git a/config/snort/snort_blocked.php b/config/snort/snort_blocked.php index def5dd22..295218f6 100644 --- a/config/snort/snort_blocked.php +++ b/config/snort/snort_blocked.php @@ -135,21 +135,23 @@ if ($pconfig['brefresh'] == 'on') <?php if ($savemsg) print_info_box($savemsg); ?> <form action="/snort/snort_blocked.php" method="post"> <table width="99%" border="0" cellpadding="0" cellspacing="0"> -<tr><td> -<?php - $tab_array = array(); - $tab_array[0] = array(gettext("Snort Interfaces"), false, "/snort/snort_interfaces.php"); - $tab_array[1] = array(gettext("Global Settings"), false, "/snort/snort_interfaces_global.php"); - $tab_array[2] = array(gettext("Updates"), false, "/snort/snort_download_updates.php"); - $tab_array[3] = array(gettext("Alerts"), false, "/snort/snort_alerts.php"); - $tab_array[4] = array(gettext("Blocked"), true, "/snort/snort_blocked.php"); - $tab_array[5] = array(gettext("Whitelists"), false, "/snort/snort_interfaces_whitelist.php"); - $tab_array[6] = array(gettext("Suppress"), false, "/snort/snort_interfaces_suppress.php"); - display_top_tabs($tab_array); -?> -</td></tr> - <tr> - <td> +<tr> + <td> + <?php + $tab_array = array(); + $tab_array[0] = array(gettext("Snort Interfaces"), false, "/snort/snort_interfaces.php"); + $tab_array[1] = array(gettext("Global Settings"), false, "/snort/snort_interfaces_global.php"); + $tab_array[2] = array(gettext("Updates"), false, "/snort/snort_download_updates.php"); + $tab_array[3] = array(gettext("Alerts"), false, "/snort/snort_alerts.php"); + $tab_array[4] = array(gettext("Blocked"), true, "/snort/snort_blocked.php"); + $tab_array[5] = array(gettext("Whitelists"), false, "/snort/snort_interfaces_whitelist.php"); + $tab_array[6] = array(gettext("Suppress"), false, "/snort/snort_interfaces_suppress.php"); + display_top_tabs($tab_array); + ?> + </td> +</tr> +<tr> + <td> <table id="maintable" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> @@ -164,7 +166,7 @@ if ($pconfig['brefresh'] == 'on') <input name="download" type="submit" class="formbtn" value="Download"> <?php echo gettext("All " . "blocked hosts will be saved."); ?> <input name="remove" type="submit" class="formbtn" value="Clear"> <span class="red"><strong><?php echo gettext("Warning:"); ?></strong></span> - <?php echo gettext("all hosts will be removed."); ?></form> + <?php echo gettext("all hosts will be removed."); ?> </td> </tr> <tr> @@ -179,17 +181,16 @@ if ($pconfig['brefresh'] == 'on') "number of blocked entries to view. %sDefault%s is %s500%s."), '<strong>', '</strong>', '<strong>', '</strong>'); ?> </td> </tr> - <tr> - <td colspan="2"> - <table id="sortabletable1" class="sortable" width="100%" border="0" - cellpadding="0" cellspacing="0"> - <tr id="frheader"> - <td width="5%" class="listhdrr">#</td> - <td width="15%" class="listhdrr"><?php echo gettext("IP"); ?></td> - <td width="70%" class="listhdrr"><?php echo gettext("Alert Description"); ?></td> - <td width="5%" class="listhdrr"><?php echo gettext("Remove"); ?></td> - </tr> - <?php + <tr> + <td colspan="2"> + <table id="sortabletable1" class="sortable" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr id="frheader"> + <td width="5%" class="listhdrr">#</td> + <td width="15%" class="listhdrr"><?php echo gettext("IP"); ?></td> + <td width="70%" class="listhdrr"><?php echo gettext("Alert Description"); ?></td> + <td width="5%" class="listhdrr"><?php echo gettext("Remove"); ?></td> + </tr> + <?php /* set the arrays */ $blocked_ips_array = array(); if (is_array($blocked_ips)) { @@ -242,27 +243,25 @@ if ($pconfig['brefresh'] == 'on') $counter++; /* use one echo to do the magic*/ - echo "<tr> - <td width='5%' > {$counter}</td> - <td width='15%' > {$blocked_ip}</td> - <td width='70%' > {$blocked_desc}</td> - <td width='5%' align=\"center\" valign=\"top\"'><a href='snort_blocked.php?todelete=" . trim(urlencode($blocked_ip)) . "'> - <img title=\"" . gettext("Delete") . "\" border=\"0\" name='todelete' id='todelete' alt=\"Delete\" src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"></a></td> - </tr>\n"; - + echo "<tr> + <td width='5%' > {$counter}</td> + <td width='15%' > {$blocked_ip}</td> + <td width='70%' > {$blocked_desc}</td> + <td width='5%' align=\"center\" valign=\"top\"'><a href='snort_blocked.php?todelete=" . trim(urlencode($blocked_ip)) . "'> + <img title=\"" . gettext("Delete") . "\" border=\"0\" name='todelete' id='todelete' alt=\"Delete\" src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"></a></td> + </tr>\n"; } - echo "\n<tr><td colspan='3' align=\"center\" valign=\"top\">{$counter} items listed.</td></tr>"; - } else - echo "\n<tr><td colspan='3' align=\"center\" valign=\"top\"><br><strong>There are currently no items being blocked by snort.</strong></td></tr>"; - - ?> + echo "\n<tr><td colspan='4' align=\"center\" valign=\"top\">{$counter} items listed.</td></tr>"; + } else + echo "\n<tr><td colspan='4' align=\"center\" valign=\"top\"><br><strong>There are currently no items being blocked by snort.</strong></td></tr>"; + ?> + </table> + </td> + </tr> </table> - </td> - </tr> -</table> - </td> - </tr> + </td> +</tr> </table> </form> <?php diff --git a/config/snort/snort_check_for_rule_updates.php b/config/snort/snort_check_for_rule_updates.php index af5d378c..f69c3b98 100755 --- a/config/snort/snort_check_for_rule_updates.php +++ b/config/snort/snort_check_for_rule_updates.php @@ -31,54 +31,73 @@ require_once("functions.inc"); require_once("service-utils.inc"); -require_once("/usr/local/pkg/snort/snort.inc"); +require_once "/usr/local/pkg/snort/snort.inc"; +require_once("service-utils.inc"); -global $snort_gui_include; +global $snort_gui_include, $vrt_enabled, $et_enabled, $rebuild_rules, $snort_rules_upd_log; +global $protect_preproc_rules, $is_postinstall, $snort_community_rules_filename; +global $snort_community_rules_url, $snort_rules_file, $emergingthreats_filename; $snortdir = SNORTDIR; +$snortlibdir = SNORTLIBDIR; +$snortlogdir = SNORTLOGDIR; if (!isset($snort_gui_include)) $pkg_interface = "console"; -$tmpfname = "{$snortdir}/tmp/snort_rules_up"; -$snort_filename_md5 = "{$snort_rules_file}.md5"; -$snort_filename = "{$snort_rules_file}"; -$emergingthreats_filename_md5 = "emerging.rules.tar.gz.md5"; -$emergingthreats_filename = "emerging.rules.tar.gz"; - /* define checks */ $oinkid = $config['installedpackages']['snortglobal']['oinkmastercode']; $snortdownload = $config['installedpackages']['snortglobal']['snortdownload']; $emergingthreats = $config['installedpackages']['snortglobal']['emergingthreats']; +$snortcommunityrules = $config['installedpackages']['snortglobal']['snortcommunityrules']; $vrt_enabled = $config['installedpackages']['snortglobal']['snortdownload']; $et_enabled = $config['installedpackages']['snortglobal']['emergingthreats']; -/* Start of code */ -conf_mount_rw(); +/* Directory where we download rule tarballs */ +$tmpfname = "{$snortdir}/tmp/snort_rules_up"; + +/* Snort VRT rules files and URL */ +$snort_filename_md5 = "{$snort_rules_file}.md5"; +$snort_filename = "{$snort_rules_file}"; +$snort_rule_url = "http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/"; -if (!is_dir($tmpfname)) - exec("/bin/mkdir -p {$tmpfname}"); +/* Emerging Threats rules MD5 file */ +$emergingthreats_filename_md5 = "{$emergingthreats_filename}.md5"; -/* Set user agent to Mozilla */ -ini_set('user_agent','Mozilla/4.0 (compatible; MSIE 6.0)'); -ini_set("memory_limit","150M"); +/* Snort GPLv2 Community Rules MD5 file */ +$snort_community_rules_filename_md5 = "{$snort_community_rules_filename}.md5"; + +/* Start of code */ +conf_mount_rw(); /* remove old $tmpfname files */ if (is_dir("{$tmpfname}")) exec("/bin/rm -r {$tmpfname}"); -/* Make sure snortdir exits */ +/* Make sure required snortdirs exsist */ exec("/bin/mkdir -p {$snortdir}/rules"); exec("/bin/mkdir -p {$snortdir}/signatures"); +exec("/bin/mkdir -p {$snortdir}/preproc_rules"); exec("/bin/mkdir -p {$tmpfname}"); -exec("/bin/mkdir -p /usr/local/lib/snort/dynamicrules"); +exec("/bin/mkdir -p {$snortlibdir}/dynamicrules"); +exec("/bin/mkdir -p {$snortlogdir}"); + +/* See if we need to automatically clear the Update Log based on 1024K size limit */ +if (file_exists($snort_rules_upd_log)) { + if (1048576 < filesize($snort_rules_upd_log)) + exec("/bin/rm -r {$snort_rules_upd_log}"); +} + +/* Log start time for this rules update */ +error_log(gettext("Starting rules update... Time: " . date("Y-m-d H:i:s") . "\n"), 3, $snort_rules_upd_log); /* download md5 sig from snort.org */ if ($snortdownload == 'on') { - update_status(gettext("Downloading snort.org md5 file...")); + update_status(gettext("Downloading Snort VRT md5 file...")); + error_log(gettext("\tDownloading Snort VRT md5 file...\n"), 3, $snort_rules_upd_log); $max_tries = 4; while ($max_tries > 0) { - $image = @file_get_contents("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename_md5}"); + $image = @file_get_contents("{$snort_rule_url}{$snort_filename_md5}"); if (false === $image) { $max_tries--; if ($max_tries > 0) @@ -87,15 +106,17 @@ if ($snortdownload == 'on') { } else break; } - log_error("Snort MD5 Attempts: " . (4 - $max_tries + 1)); + log_error("[Snort] Snort MD5 Attempts: " . (4 - $max_tries + 1)); + error_log("\tChecking Snort VRT md5 file...\n", 3, $snort_rules_upd_log); @file_put_contents("{$tmpfname}/{$snort_filename_md5}", $image); if (0 == filesize("{$tmpfname}/{$snort_filename_md5}")) { update_status(gettext("Please wait... You may only check for New Rules every 15 minutes...")); - log_error(gettext("Please wait... You may only check for New Rules every 15 minutes...")); + log_error(gettext("[Snort] Please wait... You may only check for New Rules every 15 minutes...")); update_output_window(gettext("Rules are released every month from snort.org. You may download the Rules at any time.")); $snortdownload = 'off'; + error_log(gettext("\tSnort VRT md5 download failed. Site may be offline or Oinkcode is not authorized for this level or version.\n"), 3, $snort_rules_upd_log); } else - update_status(gettext("Done downloading snort.org md5")); + update_status(gettext("Done downloading snort.org md5.")); } /* Check if were up to date snort.org */ @@ -104,8 +125,9 @@ if ($snortdownload == 'on') { $md5_check_new = file_get_contents("{$tmpfname}/{$snort_filename_md5}"); $md5_check_old = file_get_contents("{$snortdir}/{$snort_filename_md5}"); if ($md5_check_new == $md5_check_old) { - update_status(gettext("Snort rules are up to date...")); - log_error("Snort rules are up to date..."); + update_status(gettext("Snort VRT rules are up to date...")); + log_error(gettext("[Snort] Snort VRT rules are up to date...")); + error_log(gettext("\tSnort VRT rules are up to date.\n"), 3, $snort_rules_upd_log); $snortdownload = 'off'; } } @@ -113,50 +135,159 @@ if ($snortdownload == 'on') { /* download snortrules file */ if ($snortdownload == 'on') { - update_status(gettext("There is a new set of Snort.org rules posted. Downloading...")); - log_error(gettext("There is a new set of Snort.org rules posted. Downloading...")); + update_status(gettext("There is a new set of Snort VRT rules posted. Downloading...")); + log_error(gettext("[Snort] There is a new set of Snort VRT rules posted. Downloading...")); + error_log(gettext("\tThere is a new set of Snort VRT rules posted. Downloading...\n"), 3, $snort_rules_upd_log); $max_tries = 4; while ($max_tries > 0) { - download_file_with_progress_bar("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename}", "{$tmpfname}/{$snort_filename}"); - if (300000 > filesize("{$tmpfname}/$snort_filename")){ + download_file_with_progress_bar("{$snort_rule_url}{$snort_filename}", "{$tmpfname}/{$snort_filename}"); + if (5000 > filesize("{$tmpfname}/{$snort_filename}")){ $max_tries--; if ($max_tries > 0) sleep(30); continue; } else break; - } - update_status(gettext("Done downloading rules file.")); - log_error("Snort Rules Attempts: " . (4 - $max_tries + 1)); - if (300000 > filesize("{$tmpfname}/$snort_filename")){ - update_output_window(gettext("Snort rules file download failed...")); - log_error(gettext("Snort rules file download failed...")); - log_error("Failed Rules Filesize: " . filesize("{$tmpfname}/$snort_filename")); + } + if (filesize("{$tmpfname}/{$snort_filename}") == 0) { + update_output_window(gettext("Snort VRT rules file download failed...")); + log_error(gettext("[Snort] Snort VRT rules file download failed...")); + error_log(gettext("\tSnort VRT rules file download failed. Snort VRT rules will not be updated.\n"), 3, $snort_rules_upd_log); $snortdownload = 'off'; } + else { + update_status(gettext("Done downloading Snort VRT rules file.")); + log_error("[Snort] Snort VRT Rules Attempts: " . (4 - $max_tries + 1)); + error_log(gettext("\tDone downloading rules file.\n"),3, $snort_rules_upd_log); + if (trim(file_get_contents("{$tmpfname}/{$snort_filename_md5}")) != trim(md5_file("{$tmpfname}/{$snort_filename}"))){ + update_output_window(gettext("Snort VRT rules file download failed...")); + log_error(gettext("[Snort] Snort VRT rules file download failed...")); + log_error(gettext("[Snort] Failed File MD5: " . md5_file("{$tmpfname}/{$snort_filename}"))); + log_error(gettext("[Snort] Expected File MD5: " . file_get_contents("{$tmpfname}/{$snort_filename_md5}"))); + error_log(gettext("\tSnort VRT rules file download failed. Snort VRT rules will not be updated.\n"), 3, $snort_rules_upd_log); + error_log(gettext("\tDownloaded Snort VRT file MD5: " . md5_file("{$tmpfname}/{$snort_filename}") . "\n"), 3, $snort_rules_upd_log); + error_log(gettext("\tExpected Snort VRT file MD5: " . file_get_contents("{$tmpfname}/{$snort_filename_md5}") . "\n"), 3, $snort_rules_upd_log); + $snortdownload = 'off'; + } + } +} + +/* download md5 sig from Snort GPLv2 Community Rules */ +if ($snortcommunityrules == 'on') { + update_status(gettext("Downloading Snort GPLv2 Community Rules md5 file...")); + error_log(gettext("\tDownloading Snort GPLv2 Community Rules md5 file...\n"), 3, $snort_rules_upd_log); + $image = file_get_contents("{$snort_community_rules_url}{$snort_community_rules_filename_md5}"); + update_status(gettext("Done downloading Snort GPLv2 Community Rules md5")); + error_log(gettext("\tChecking Snort GPLv2 Community Rules md5.\n"), 3, $snort_rules_upd_log); + @file_put_contents("{$tmpfname}/{$snort_community_rules_filename_md5}", $image); + + /* See if the file download was successful, and turn off Snort GPLv2 update if it failed. */ + if (0 == filesize("{$tmpfname}/{$snort_community_rules_filename_md5}")){ + update_output_window(gettext("Snort GPLv2 Community Rules md5 file download failed. Community Rules will not be updated.")); + log_error(gettext("[Snort] Snort GPLv2 Community Rules md5 file download failed. Community Rules will not be updated.")); + error_log(gettext("\tSnort GPLv2 Community Rules md5 file download failed. Community Rules will not be updated.\n"), 3, $snort_rules_upd_log); + $snortcommunityrules = 'off'; + } + + if (file_exists("{$snortdir}/{$snort_community_rules_filename_md5}") && $snortcommunityrules == "on") { + /* Check if were up to date Snort GPLv2 Community Rules */ + $snort_comm_md5_check_new = file_get_contents("{$tmpfname}/{$snort_community_rules_filename_md5}"); + $snort_comm_md5_check_old = file_get_contents("{$snortdir}/{$snort_community_rules_filename_md5}"); + if ($snort_comm_md5_check_new == $snort_comm_md5_check_old) { + update_status(gettext("Snort GPLv2 Community Rules are up to date...")); + log_error(gettext("[Snort] Snort GPLv2 Community Rules are up to date...")); + error_log(gettext("\tSnort GPLv2 Community Rules are up to date.\n"), 3, $snort_rules_upd_log); + $snortcommunityrules = 'off'; + } + } +} + +/* download Snort GPLv2 Community rules file */ +if ($snortcommunityrules == "on") { + update_status(gettext("There is a new set of Snort GPLv2 Community Rules posted. Downloading...")); + log_error(gettext("[Snort] There is a new set of Snort GPLv2 Community Rules posted. Downloading...")); + error_log(gettext("\tThere is a new set of Snort GPLv2 Community Rules posted. Downloading...\n"), 3, $snort_rules_upd_log); + download_file_with_progress_bar("{$snort_community_rules_url}{$snort_community_rules_filename}", "{$tmpfname}/{$snort_community_rules_filename}"); + + /* Test for a valid rules file download. Turn off Snort Community update if download failed. */ + if (trim(file_get_contents("{$tmpfname}/{$snort_community_rules_filename_md5}")) != trim(md5_file("{$tmpfname}/{$snort_community_rules_filename}"))){ + update_output_window(gettext("Snort GPLv2 Community Rules file download failed...")); + log_error(gettext("[Snort] Snort GPLv2 Community Rules file download failed...")); + log_error(gettext("[Snort] Failed File MD5: " . md5_file("{$tmpfname}/{$snort_community_rules_filename}"))); + log_error(gettext("[Snort] Expected File MD5: " . file_get_contents("{$tmpfname}/{$snort_community_rules_filename_md5}"))); + error_log(gettext("\tSnort GPLv2 Community Rules file download failed. Community Rules will not be updated.\n"), 3, $snort_rules_upd_log); + error_log(gettext("\tDownloaded Snort GPLv2 file MD5: " . md5_file("{$tmpfname}/{$snort_community_rules_filename}") . "\n"), 3, $snort_rules_upd_log); + error_log(gettext("\tExpected Snort GPLv2 file MD5: " . file_get_contents("{$tmpfname}/{$snort_community_rules_filename_md5}") . "\n"), 3, $snort_rules_upd_log); + $snortcommunityrules = 'off'; + } + else { + update_status(gettext('Done downloading Snort GPLv2 Community Rules file.')); + log_error("[Snort] Snort GPLv2 Community Rules file update downloaded successfully"); + error_log(gettext("\tDone downloading Snort GPLv2 Community Rules file.\n"), 3, $snort_rules_upd_log); + } +} + +/* Untar Snort GPLv2 Community rules to tmp */ +if ($snortcommunityrules == 'on') { + safe_mkdir("{$snortdir}/tmp/community"); + if (file_exists("{$tmpfname}/{$snort_community_rules_filename}")) { + update_status(gettext("Extracting Snort GPLv2 Community Rules...")); + error_log(gettext("\tExtracting and installing Snort GPLv2 Community Rules...\n"), 3, $snort_rules_upd_log); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_community_rules_filename} -C {$snortdir}/tmp/community/"); + + $files = glob("{$snortdir}/tmp/community/community-rules/*.rules"); + foreach ($files as $file) { + $newfile = basename($file); + @copy($file, "{$snortdir}/rules/GPLv2_{$newfile}"); + } + /* base etc files for Snort GPLv2 Community rules */ + foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { + if (file_exists("{$snortdir}/tmp/community/community-rules/{$file}")) + @copy("{$snortdir}/tmp/community/community-rules/{$file}", "{$snortdir}/tmp/GPLv2_{$file}"); + } + + /* Copy snort community md5 sig to snort dir */ + if (file_exists("{$tmpfname}/{$snort_community_rules_filename_md5}")) { + update_status(gettext("Copying md5 signature to snort directory...")); + @copy("{$tmpfname}/{$snort_community_rules_filename_md5}", "{$snortdir}/{$snort_community_rules_filename_md5}"); + } + update_status(gettext("Extraction of Snort GPLv2 Community Rules completed...")); + error_log(gettext("\tInstallation of Snort GPLv2 Community Rules completed.\n"), 3, $snort_rules_upd_log); + exec("rm -r {$snortdir}/tmp/community"); + } } /* download md5 sig from emergingthreats.net */ if ($emergingthreats == 'on') { - update_status(gettext("Downloading emergingthreats md5 file...")); + update_status(gettext("Downloading EmergingThreats md5 file...")); + error_log(gettext("\tDownloading EmergingThreats md5 file...\n"), 3, $snort_rules_upd_log); /* If using Sourcefire VRT rules with ET, then we should use the open-nogpl ET rules. */ if ($vrt_enabled == "on") - $image = @file_get_contents("http://rules.emergingthreats.net/open-nogpl/snort-{$emerging_threats_version}/emerging.rules.tar.gz.md5"); + $image = @file_get_contents("http://rules.emergingthreats.net/open-nogpl/snort-{$emerging_threats_version}/{$emergingthreats_filename_md5}"); else - $image = @file_get_contents("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz.md5"); + $image = @file_get_contents("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/{$emergingthreats_filename_md5}"); - /* XXX: error checking */ + update_status(gettext("Done downloading EmergingThreats md5")); + error_log(gettext("\tChecking EmergingThreats md5.\n"), 3, $snort_rules_upd_log); @file_put_contents("{$tmpfname}/{$emergingthreats_filename_md5}", $image); - update_status(gettext("Done downloading emergingthreats md5")); - if (file_exists("{$snortdir}/{$emergingthreats_filename_md5}")) { + /* See if the file download was successful, and turn off ET update if it failed. */ + if (0 == filesize("{$tmpfname}/{$emergingthreats_filename_md5}")){ + update_output_window(gettext("EmergingThreats md5 file download failed. EmergingThreats rules will not be updated.")); + log_error(gettext("[Snort] EmergingThreats md5 file download failed. EmergingThreats rules will not be updated.")); + error_log(gettext("\tEmergingThreats md5 file download failed. EmergingThreats rules will not be updated.\n"), 3, $snort_rules_upd_log); + $emergingthreats = 'off'; + } + + if (file_exists("{$snortdir}/{$emergingthreats_filename_md5}") && $emergingthreats == "on") { /* Check if were up to date emergingthreats.net */ $emerg_md5_check_new = file_get_contents("{$tmpfname}/{$emergingthreats_filename_md5}"); $emerg_md5_check_old = file_get_contents("{$snortdir}/{$emergingthreats_filename_md5}"); if ($emerg_md5_check_new == $emerg_md5_check_old) { - update_status(gettext("Emerging threat rules are up to date...")); - log_error(gettext("Emerging threat rules are up to date...")); + update_status(gettext("Emerging Threats rules are up to date...")); + log_error(gettext("[Snort] Emerging Threat rules are up to date...")); + error_log(gettext("\tEmerging Threats rules are up to date.\n"), 3, $snort_rules_upd_log); $emergingthreats = 'off'; } } @@ -164,8 +295,9 @@ if ($emergingthreats == 'on') { /* download emergingthreats rules file */ if ($emergingthreats == "on") { - update_status(gettext("There is a new set of Emergingthreats rules posted. Downloading...")); - log_error(gettext("There is a new set of Emergingthreats rules posted. Downloading...")); + update_status(gettext("There is a new set of EmergingThreats rules posted. Downloading...")); + log_error(gettext("[Snort] There is a new set of EmergingThreats rules posted. Downloading...")); + error_log(gettext("\tThere is a new set of EmergingThreats rules posted. Downloading...\n"), 3, $snort_rules_upd_log); /* If using Sourcefire VRT rules with ET, then we should use the open-nogpl ET rules. */ if ($vrt_enabled == "on") @@ -173,24 +305,31 @@ if ($emergingthreats == "on") { else download_file_with_progress_bar("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz", "{$tmpfname}/{$emergingthreats_filename}"); - update_status(gettext('Done downloading Emergingthreats rules file.')); - log_error("Emergingthreats rules file update downloaded succsesfully"); + /* Test for a valid rules file download. Turn off ET update if download failed. */ + + if (trim(file_get_contents("{$tmpfname}/{$emergingthreats_filename_md5}")) != trim(md5_file("{$tmpfname}/{$emergingthreats_filename}"))){ + update_output_window(gettext("EmergingThreats rules file download failed...")); + log_error(gettext("[Snort] EmergingThreats rules file download failed...")); + log_error(gettext("[Snort] Failed File MD5: " . md5_file("{$tmpfname}/{$emergingthreats_filename}"))); + log_error(gettext("[Snort] Expected File MD5: " . file_get_contents("{$tmpfname}/{$emergingthreats_filename_md5}"))); + error_log(gettext("\tEmergingThreats rules file download failed. EmergingThreats rules will not be updated.\n"), 3, $snort_rules_upd_log); + error_log(gettext("\tDownloaded ET file MD5: " . md5_file("{$tmpfname}/{$emergingthreats_filename}") . "\n"), 3, $snort_rules_upd_log); + error_log(gettext("\tExpected ET file MD5: " . file_get_contents("{$tmpfname}/{$emergingthreats_filename_md5}") . "\n"), 3, $snort_rules_upd_log); + $emergingthreats = 'off'; + } + else { + update_status(gettext('Done downloading EmergingThreats rules file.')); + log_error("[Snort] EmergingThreats rules file update downloaded successfully"); + error_log(gettext("\tDone downloading EmergingThreats rules file.\n"), 3, $snort_rules_upd_log); + } } -/* Normalize rulesets */ -$sedcmd = "s/^#alert/# alert/g\n"; -$sedcmd .= "s/^##alert/# alert/g\n"; -$sedcmd .= "s/^#[ \\t#]*alert/# alert/g\n"; -$sedcmd .= "s/^##\\talert/# alert/g\n"; -$sedcmd .= "s/^\\talert/alert/g\n"; -$sedcmd .= "s/^[ \\t]*alert/alert/g\n"; -@file_put_contents("{$snortdir}/tmp/sedcmd", $sedcmd); - /* Untar emergingthreats rules to tmp */ if ($emergingthreats == 'on') { safe_mkdir("{$snortdir}/tmp/emerging"); if (file_exists("{$tmpfname}/{$emergingthreats_filename}")) { update_status(gettext("Extracting EmergingThreats.org rules...")); + error_log(gettext("\tExtracting and installing EmergingThreats.org rules...\n"), 3, $snort_rules_upd_log); exec("/usr/bin/tar xzf {$tmpfname}/{$emergingthreats_filename} -C {$snortdir}/tmp/emerging rules/"); $files = glob("{$snortdir}/tmp/emerging/rules/*.rules"); @@ -199,7 +338,7 @@ if ($emergingthreats == 'on') { @copy($file, "{$snortdir}/rules/{$newfile}"); } /* IP lists for Emerging Threats rules */ - $files = glob("{$snortdir}/tmp/emerging/rules/*.txt"); + $files = glob("{$snortdir}/tmp/emerging/rules/*ips.txt"); foreach ($files as $file) { $newfile = basename($file); @copy($file, "{$snortdir}/rules/{$newfile}"); @@ -207,31 +346,33 @@ if ($emergingthreats == 'on') { /* base etc files for Emerging Threats rules */ foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { if (file_exists("{$snortdir}/tmp/emerging/rules/{$file}")) - @copy("{$snortdir}/tmp/emerging/rules/{$file}", "{$snortdir}/ET_{$file}"); + @copy("{$snortdir}/tmp/emerging/rules/{$file}", "{$snortdir}/tmp/ET_{$file}"); } -// /* make sure default rules are in the right format */ -// exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/emerging*.rules"); - /* Copy emergingthreats md5 sig to snort dir */ - if (file_exists("{$tmpfname}/$emergingthreats_filename_md5")) { - update_status(gettext("Copying md5 sig to snort directory...")); - @copy("{$tmpfname}/$emergingthreats_filename_md5", "{$snortdir}/$emergingthreats_filename_md5"); + if (file_exists("{$tmpfname}/{$emergingthreats_filename_md5}")) { + update_status(gettext("Copying md5 signature to snort directory...")); + @copy("{$tmpfname}/{$emergingthreats_filename_md5}", "{$snortdir}/{$emergingthreats_filename_md5}"); } update_status(gettext("Extraction of EmergingThreats.org rules completed...")); + error_log(gettext("\tInstallation of EmergingThreats.org rules completed.\n"), 3, $snort_rules_upd_log); + exec("rm -r {$snortdir}/tmp/emerging"); } } /* Untar snort rules file individually to help people with low system specs */ if ($snortdownload == 'on') { if (file_exists("{$tmpfname}/{$snort_filename}")) { - if ($pfsense_stable == 'yes') - $freebsd_version_so = 'FreeBSD-7-2'; - else - $freebsd_version_so = 'FreeBSD-8-1'; + + /* Currently, only FreeBSD-8-1 and FreeBSD-9-0 precompiled SO rules exist from Snort.org */ + /* Default to FreeBSD 8.1, and then test for FreeBSD 9.x */ + $freebsd_version_so = 'FreeBSD-8-1'; + if (substr(php_uname("r"), 0, 1) == '9') + $freebsd_version_so = 'FreeBSD-9-0'; update_status(gettext("Extracting Snort VRT rules...")); - /* extract snort.org rules and add prefix to all snort.org files*/ + error_log(gettext("\tExtracting and installing Snort VRT rules...\n"), 3, $snort_rules_upd_log); + /* extract snort.org rules and add prefix to all snort.org files */ safe_mkdir("{$snortdir}/tmp/snortrules"); exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp/snortrules rules/"); $files = glob("{$snortdir}/tmp/snortrules/rules/*.rules"); @@ -249,151 +390,188 @@ if ($snortdownload == 'on') { /* extract so rules */ update_status(gettext("Extracting Snort VRT Shared Objects rules...")); - exec('/bin/mkdir -p /usr/local/lib/snort/dynamicrules/'); + exec("/bin/mkdir -p {$snortlibdir}/dynamicrules/"); + error_log(gettext("\tUsing Snort VRT precompiled SO rules for {$freebsd_version_so} ...\n"), 3, $snort_rules_upd_log); $snort_arch = php_uname("m"); $nosorules = false; if ($snort_arch == 'i386'){ - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/$freebsd_version_so/i386/{$snort_version}/"); - exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/i386/{$snort_version}/* /usr/local/lib/snort/dynamicrules/"); - } else if ($snort_arch == 'amd64') { - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/$freebsd_version_so/x86-64/{$snort_version}/"); - exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/x86-64/{$snort_version}/* /usr/local/lib/snort/dynamicrules/"); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/{$freebsd_version_so}/i386/{$snort_version}/"); + exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/{$freebsd_version_so}/i386/{$snort_version}/* {$snortlibdir}/dynamicrules/"); + } elseif ($snort_arch == 'amd64') { + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/{$freebsd_version_so}/x86-64/{$snort_version}/"); + exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/{$freebsd_version_so}/x86-64/{$snort_version}/* {$snortlibdir}/dynamicrules/"); } else $nosorules = true; exec("rm -r {$snortdir}/tmp/so_rules"); if ($nosorules == false) { - /* extract so rules none bin and rename */ + /* extract so stub rules, rename and copy to the rules folder. */ update_status(gettext("Copying Snort VRT Shared Objects rules...")); - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/"); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp --exclude precompiled/ --exclude src/ so_rules/"); $files = glob("{$snortdir}/tmp/so_rules/*.rules"); foreach ($files as $file) { $newfile = basename($file, ".rules"); @copy($file, "{$snortdir}/rules/snort_{$newfile}.so.rules"); } exec("rm -r {$snortdir}/tmp/so_rules"); - - /* extract base etc files */ - update_status(gettext("Extracting Snort VRT base config files...")); - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp etc/"); - foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { - if (file_exists("{$snortdir}/tmp/etc/{$file}")) - @copy("{$snortdir}/tmp/etc/{$file}", "{$snortdir}/VRT_{$file}"); - } - exec("rm -r {$snortdir}/tmp/etc"); - - /* Untar snort signatures */ - $signature_info_chk = $config['installedpackages']['snortglobal']['signatureinfo']; - if ($premium_url_chk == 'on') { - update_status(gettext("Extracting Snort VRT Signatures...")); - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} doc/signatures/"); - update_status(gettext("Done extracting Signatures.")); - - if (is_dir("{$snortdir}/doc/signatures")) { - update_status(gettext("Copying Snort VRT signatures...")); - exec("/bin/cp -r {$snortdir}/doc/signatures {$snortdir}/signatures"); - update_status(gettext("Done copying signatures.")); - } + } + + /* extract base etc files */ + update_status(gettext("Extracting Snort VRT config and map files...")); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp etc/"); + foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { + if (file_exists("{$snortdir}/tmp/etc/{$file}")) + @copy("{$snortdir}/tmp/etc/{$file}", "{$snortdir}/tmp/VRT_{$file}"); + } + exec("rm -r {$snortdir}/tmp/etc"); + + /* Untar snort signatures */ + $signature_info_chk = $config['installedpackages']['snortglobal']['signatureinfo']; + if ($premium_url_chk == 'on') { + update_status(gettext("Extracting Snort VRT Signatures...")); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} doc/signatures/"); + update_status(gettext("Done extracting Signatures.")); + + if (is_dir("{$snortdir}/doc/signatures")) { + update_status(gettext("Copying Snort VRT signatures...")); + exec("/bin/cp -r {$snortdir}/doc/signatures {$snortdir}/signatures"); + update_status(gettext("Done copying signatures.")); } + } - foreach (glob("/usr/local/lib/snort/dynamicrules/*example*") as $file) - @unlink($file); - - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} preproc_rules/"); - -// /* make sure default rules are in the right format */ -// exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/snort_*.rules"); + /* Extract the Snort preprocessor rules */ + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp preproc_rules/"); - if (file_exists("{$tmpfname}/{$snort_filename_md5}")) { - update_status(gettext("Copying md5 sig to snort directory...")); - @copy("{$tmpfname}/$snort_filename_md5", "{$snortdir}/$snort_filename_md5"); - } + if (file_exists("{$tmpfname}/{$snort_filename_md5}")) { + update_status(gettext("Copying md5 signature to snort directory...")); + @copy("{$tmpfname}/{$snort_filename_md5}", "{$snortdir}/{$snort_filename_md5}"); } - update_status(gettext("Extraction of Snort VRT rules completed...")); + update_status(gettext("Extraction of Snort VRT rules completed...")); + error_log(gettext("\tInstallation of Snort VRT rules completed.\n"), 3, $snort_rules_upd_log); } } -/* remove old $tmpfname files */ -if (is_dir("{$snortdir}/tmp")) { - update_status(gettext("Cleaning up after rules extraction...")); - exec("/bin/rm -r {$snortdir}/tmp"); -} - function snort_apply_customizations($snortcfg, $if_real) { + global $vrt_enabled; $snortdir = SNORTDIR; + + /* Update the Preprocessor rules for the master configuration and for the interface if Snort VRT rules are in use. */ + if ($vrt_enabled == 'on') { + exec("/bin/mkdir -p {$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/preproc_rules"); + $preproc_files = glob("{$snortdir}/tmp/preproc_rules/*.rules"); + foreach ($preproc_files as $file) { + $newfile = basename($file); + @copy($file, "{$snortdir}/preproc_rules/{$newfile}"); + /* Check if customized preprocessor rule protection is enabled for interface before overwriting them. */ + if ($snortcfg['protect_preproc_rules'] <> 'on') + @copy($file, "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/preproc_rules/{$newfile}"); + } + } + else { + exec("/bin/mkdir -p {$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/preproc_rules"); + } + snort_prepare_rule_files($snortcfg, "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}"); - /* Copy the master *.config and other *.map files to the interface's directory */ + /* Copy the master config and map files to the interface directory */ @copy("{$snortdir}/classification.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/classification.config"); @copy("{$snortdir}/gen-msg.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/gen-msg.map"); @copy("{$snortdir}/reference.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/reference.config"); @copy("{$snortdir}/unicode.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/unicode.map"); } -if ($snortdownload == 'on' || $emergingthreats == 'on') { +if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules == 'on') { update_status(gettext('Copying new config and map files...')); + error_log(gettext("\tCopying new config and map files...\n"), 3, $snort_rules_upd_log); - /* Determine which base etc file set to use for the master copy. */ - /* If the Snort VRT rules are not enabled, then use Emerging Threats. */ + /* Determine which config and map file set to use for the master copy. */ + /* If the Snort VRT rules are not enabled, then use Emerging Threats. */ if (($vrt_enabled == 'off') && ($et_enabled == 'on')) { - foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { - if (file_exists("{$snortdir}/ET_{$file}")) - @rename("{$snortdir}/ET_{$file}", "{$snortdir}/{$file}"); - } + $cfgs = glob("{$snortdir}/tmp/*reference.config"); + $cfgs[] = "{$snortdir}/reference.config"; + snort_merge_reference_configs($cfgs, "{$snortdir}/reference.config"); + $cfgs = glob("{$snortdir}/tmp/*classification.config"); + $cfgs[] = "{$snortdir}/classification.config"; + snort_merge_classification_configs($cfgs, "{$snortdir}/classification.config"); } elseif (($vrt_enabled == 'on') && ($et_enabled == 'off')) { foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { - if (file_exists("{$snortdir}/VRT_{$file}")) - @rename("{$snortdir}/VRT_{$file}", "{$snortdir}/{$file}"); + if (file_exists("{$snortdir}/tmp/VRT_{$file}")) + @copy("{$snortdir}/tmp/VRT_{$file}", "{$snortdir}/{$file}"); } } - else { - /* Both VRT and ET rules are enabled, so build combined */ - /* reference.config and classification.config files. */ - $cfgs = glob("{$snortdir}/*reference.config"); - snort_merge_reference_configs($cfgs, "{$snortdir}/reference.config"); - $cfgs = glob("{$snortdir}/*classification.config"); - snort_merge_classification_configs($cfgs, "{$snortdir}/classification.config"); + elseif (($vrt_enabled == 'on') && ($et_enabled == 'on')) { + /* Both VRT and ET rules are enabled, so build combined */ + /* reference.config and classification.config files. */ + $cfgs = glob("{$snortdir}/tmp/*reference.config"); + $cfgs[] = "{$snortdir}/reference.config"; + snort_merge_reference_configs($cfgs, "{$snortdir}/reference.config"); + $cfgs = glob("{$snortdir}/tmp/*classification.config"); + $cfgs[] = "{$snortdir}/classification.config"; + snort_merge_classification_configs($cfgs, "{$snortdir}/classification.config"); + /* Use the unicode.map and gen-msg.map files from VRT rules. */ + if (file_exists("{$snortdir}/tmp/VRT_unicode.map")) + @copy("{$snortdir}/tmp/VRT_unicode.map", "{$snortdir}/unicode.map"); + if (file_exists("{$snortdir}/tmp/VRT_gen-msg.map")) + @copy("{$snortdir}/tmp/VRT_gen-msg.map", "{$snortdir}/gen-msg.map"); } - /* Clean-up our temp versions of the config and map files. */ - update_status(gettext('Cleaning up temp files...')); - $cfgs = glob("{$snortdir}/??*_*.config"); - foreach ($cfgs as $file) { - if (file_exists($file)) - @unlink($file); - } - $cfgs = glob("{$snortdir}/??*_*.map"); - foreach ($cfgs as $file) { - if (file_exists($file)) - @unlink($file); - } - - /* Start the proccess for each configured interface */ + /* Start the rules rebuild proccess for each configured interface */ if (is_array($config['installedpackages']['snortglobal']['rule'])) { - foreach ($config['installedpackages']['snortglobal']['rule'] as $id => $value) { - /* Create configuration for each active Snort interface */ + /* Set the flag to force rule rebuilds since we downloaded new rules, */ + /* except when in post-install mode. Post-install does its own rebuild. */ + if ($is_postinstall) + $rebuild_rules = 'off'; + else + $rebuild_rules = 'on'; + + /* Create configuration for each active Snort interface */ + foreach ($config['installedpackages']['snortglobal']['rule'] as $id => $value) { $if_real = snort_get_real_interface($value['interface']); $tmp = "Updating rules configuration for: " . snort_get_friendly_interface($value['interface']) . " ..."; update_status(gettext($tmp)); - log_error($tmp); snort_apply_customizations($value, $if_real); + + /* Log a message in Update Log if protecting customized preprocessor rules. */ + $tmp = "\t" . $tmp . "\n"; + if ($value['protect_preproc_rules'] == 'on') { + $tmp .= gettext("\tPreprocessor text rules flagged as protected and not updated for "); + $tmp .= snort_get_friendly_interface($value['interface']) . "...\n"; + } + error_log($tmp, 3, $snort_rules_upd_log); } } - update_status(gettext('Restarting Snort to activate the new set of rules...')); - exec("/bin/sh /usr/local/etc/rc.d/snort.sh restart"); - sleep(20); - if (!is_process_running("snort")) - exec("/bin/sh /usr/local/etc/rc.d/snort.sh start"); - update_output_window(gettext("Snort has restarted with your new set of rules...")); - log_error("Snort has restarted with your new set of rules..."); + else { + update_output_window(gettext("Warning: No interfaces configured for Snort were found...")); + error_log(gettext("\tWarning: No interfaces configured for Snort were found...\n"), 3, $snort_rules_upd_log); + } + + /* Clear the rebuild rules flag. */ + $rebuild_rules = 'off'; + + /* remove old $tmpfname files */ + if (is_dir("{$snortdir}/tmp")) { + update_status(gettext("Cleaning up after rules extraction...")); + exec("/bin/rm -r {$snortdir}/tmp"); + } + + /* Restart snort if already running to pick up the new rules. */ + if (is_process_running("snort")) { + update_status(gettext('Restarting Snort to activate the new set of rules...')); + error_log(gettext("\tRestarting Snort to activate the new set of rules...\n"), 3, $snort_rules_upd_log); + restart_service("snort"); + update_output_window(gettext("Snort has restarted with your new set of rules...")); + log_error(gettext("[Snort] Snort has restarted with your new set of rules...")); + error_log(gettext("\tSnort has restarted with your new set of rules.\n"), 3, $snort_rules_upd_log); + } } update_status(gettext("The Rules update has finished...")); -log_error("The Rules update has finished..."); +log_error(gettext("[Snort] The Rules update has finished.")); +error_log(gettext("The Rules update has finished. Time: " . date("Y-m-d H:i:s"). "\n\n"), 3, $snort_rules_upd_log); conf_mount_ro(); ?> diff --git a/config/snort/snort_define_servers.php b/config/snort/snort_define_servers.php index 4085b325..b1d71631 100755 --- a/config/snort/snort_define_servers.php +++ b/config/snort/snort_define_servers.php @@ -33,7 +33,7 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $rebuild_rules; $id = $_GET['id']; if (isset($_POST['id'])) @@ -126,7 +126,9 @@ if ($_POST) { write_config(); - sync_snort_package_config(); + /* Update the snort conf file for this interface. */ + $rebuild_rules = "off"; + snort_generate_conf($a_nat[$id]); /* after click go to this page */ header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); diff --git a/config/snort/snort_download_updates.php b/config/snort/snort_download_updates.php index 0c879e44..36319977 100755 --- a/config/snort/snort_download_updates.php +++ b/config/snort/snort_download_updates.php @@ -36,16 +36,18 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $snort_rules_upd_log, $snort_rules_file, $emergingthreats_filename; $snortdir = SNORTDIR; -$snort_upd_log = "/tmp/snort_update.log"; + +$log = $snort_rules_upd_log; /* load only javascript that is needed */ $snort_load_jquery = 'yes'; $snort_load_jquery_colorbox = 'yes'; $snortdownload = $config['installedpackages']['snortglobal']['snortdownload']; $emergingthreats = $config['installedpackages']['snortglobal']['emergingthreats']; +$snortcommunityrules = $config['installedpackages']['snortglobal']['snortcommunityrules']; /* quick md5s chk */ $snort_org_sig_chk_local = 'N/A'; @@ -53,13 +55,28 @@ if (file_exists("{$snortdir}/{$snort_rules_file}.md5")) $snort_org_sig_chk_local = file_get_contents("{$snortdir}/{$snort_rules_file}.md5"); $emergingt_net_sig_chk_local = 'N/A'; -if (file_exists("{$snortdir}/emerging.rules.tar.gz.md5")) - $emergingt_net_sig_chk_local = file_get_contents("{$snortdir}/emerging.rules.tar.gz.md5"); +if (file_exists("{$snortdir}/{$emergingthreats_filename}.md5")) + $emergingt_net_sig_chk_local = file_get_contents("{$snortdir}/{$emergingthreats_filename}.md5"); + +$snort_community_sig_chk_local = 'N/A'; +if (file_exists("{$snortdir}/{$snort_community_rules_filename}.md5")) + $snort_community_sig_chk_local = file_get_contents("{$snortdir}/{$snort_community_rules_filename}.md5"); + +/* Check for postback to see if we should clear the update log file. */ +if (isset($_POST['clear'])) { + if (file_exists("{$snort_rules_upd_log}")) + mwexec("/bin/rm -f {$snort_rules_upd_log}"); +} + +if (isset($_POST['update'])) { + header("Location: /snort/snort_download_rules.php"); + exit; +} /* check for logfile */ -$update_logfile_chk = 'no'; -if (file_exists("{$snort_upd_log}")) - $update_logfile_chk = 'yes'; +$snort_rules_upd_logfile_chk = 'no'; +if (file_exists("{$snort_rules_upd_log}")) + $snort_rules_upd_logfile_chk = 'yes'; $pgtitle = "Services: Snort: Updates"; include_once("head.inc"); @@ -78,12 +95,30 @@ function popup(url) params += ', top=0, left=0' params += ', fullscreen=yes'; - newwin=window.open(url,'windowname4', params); + newwin=window.open(url,'LogViewer', params); if (window.focus) {newwin.focus()} return false; } + +function wopen(url, name, w, h) +{ +// Fudge factors for window decoration space. +// In my tests these work well on all platforms & browsers. +w += 32; +h += 96; + var win = window.open(url, + name, + 'width=' + w + ', height=' + h + ', ' + + 'location=no, menubar=no, ' + + 'status=no, toolbar=no, scrollbars=yes, resizable=yes'); + win.resizeTo(w, h); + win.focus(); +} + </script> +<form action="snort_download_updates.php" method="post" name="iform" id="iform"> + <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td> <?php @@ -101,8 +136,7 @@ function popup(url) <tr> <td> <div id="mainarea3"> - <table id="maintable4" class="tabcont" width="100%" border="0" - cellpadding="0" cellspacing="0"> + <table id="maintable4" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> <tr align="center"> <td> <br/> @@ -112,14 +146,15 @@ function popup(url) <td id="download_rules_td" style="background-color: #eeeeee"> <div height="32" width="725px" style="background-color: #eeeeee"> - <font color="#777777" size="1.5px"> + <font color="#777777" size="2.5px"> <p style="text-align: left; margin-left: 225px;"> - <b><?php echo gettext("INSTALLED SIGNATURE RULESET"); ?></b></font><br> - <br> - <font color="#FF850A" size="1px"><b>SNORT.ORG >>></b></font> + <b><?php echo gettext("INSTALLED RULESET SIGNATURES"); ?></b></font><br/> + <font color="#FF850A" size="1px"><b>SNORT.ORG --></b></font> <font size="1px" color="#000000"> <? echo $snort_org_sig_chk_local; ?></font><br> - <font color="#FF850A" size="1px"><b>EMERGINGTHREATS.NET >>></b></font> + <font color="#FF850A" size="1px"><b>EMERGINGTHREATS.NET --></b></font> <font size="1px" color="#000000"> <? echo $emergingt_net_sig_chk_local; ?></font><br> + <font color="#FF850A" size="1px"><b>SNORT GPLv2 COMMUNITY RULES --></b></font> + <font size="1px" color="#000000"> <? echo $snort_community_sig_chk_local; ?></font><br> </p> </div> </td> @@ -133,22 +168,23 @@ function popup(url) <div height="32" width="725px" style='background-color: #eeeeee'> <p style="text-align: left; margin-left: 225px;"> - <font color='#777777' size='1.5px'><b><?php echo gettext("UPDATE YOUR RULES"); ?></b></font><br> + <font color='#777777' size='2.5px'><b><?php echo gettext("UPDATE YOUR RULESET"); ?></b></font><br> <br/> <?php if ($snortdownload != 'on' && $emergingthreats != 'on') { echo ' - <button disabled="disabled"><span class="download">' . gettext("Update Rules") . ' </span></button><br/> + <button disabled="disabled"><span class="download">' . gettext("Update Rules") . '</span></button><br/> <p style="text-align:left; margin-left:150px;"> - <font color="#fc3608" size="2px"><b>' . gettext("WARNING:") . '</b></font><font size="1px" color="#000000"> ' . gettext('No rule types have been selected for download. "Global Settings Tab"') . '</font><br>'; + <font color="#fc3608" size="2px"><b>' . gettext("WARNING:") . '</b></font><font size="1px" color="#000000"> ' . gettext('No rule types have been selected for download. ') . + gettext('Visit the ') . '<a href="snort_interfaces_global.php">Global Settings Tab</a>' . gettext(' to select rule types.') . '</font><br>'; echo '</p>' . "\n"; } else { echo ' - <a href="/snort/snort_download_rules.php"><button ><span class="download">' . gettext("Update Rules") . ' </span></button></a><br/>' . "\n"; + <input type="submit" value="' . gettext("Update Rules") . '" name="update" id="Submit" class="formbtn" /><br/>' . "\n"; } @@ -166,19 +202,19 @@ function popup(url) <div height="32" width="725px" style='background-color: #eeeeee'> <p style="text-align: left; margin-left: 225px;"> - <font color='#777777' size='1.5px'><b><?php echo gettext("VIEW UPDATE LOG"); ?></b></font><br> + <font color='#777777' size='2.5px'><b><?php echo gettext("VIEW UPDATE LOG"); ?></b></font><br> <br> - <?php - if ($update_logfile_chk == 'yes') { + if ($snort_rules_upd_logfile_chk == 'yes') { echo " - <button href='/snort/snort_rules_edit.php?openruleset={$snort_upd_log}'><span class='pwhitetxt'>" . gettext("Update Log") . " </span></button>\n"; + <button class=\"formbtn\" onclick=\"wopen('snort_log_view.php?logfile={$log}', 'LogViewer', 800, 600)\"><span class='pwhitetxt'>" . gettext("View Log") . "</span></button>"; + echo " <input type=\"submit\" value=\"Clear Log\" name=\"clear\" id=\"Submit\" class=\"formbtn\" />\n"; }else{ echo " - <button disabled='disabled' href='/snort/snort_rules_edit.php?openruleset={$snort_upd_log}'><span class='pwhitetxt'>" . gettext("Update Log") . " </span></button>\n"; + <button disabled='disabled'><span class='pwhitetxt'>" . gettext("View Log") . "</span></button> " . gettext("Log is empty.") . "\n"; } - + echo '<br><br>' . gettext("The log file is limited to 1024K in size and automatically clears when the limit is exceeded."); ?> <br/> </p> @@ -194,8 +230,8 @@ function popup(url) <tr> <td id="download_rules_td" style='background-color: #eeeeee'> <div height="32" width="725px" style='background-color: #eeeeee'> - <font color='#FF850A' size='1px'><b><?php echo gettext("NOTE:"); ?></b></font><font size='1px' - color='#000000'> <?php echo gettext("Snort.org and Emergingthreats.net " . + <font size='1px'><span class="red"><b><?php echo gettext("NOTE:"); ?></b></span></font><font size='1px' + color='#000000'> <?php echo gettext("Snort.org and EmergingThreats.net " . "will go down from time to time. Please be patient."); ?> </font> </div> @@ -207,16 +243,12 @@ function popup(url) </tr> </table> </div> - - - - - <br> </td> </tr> </table> <!-- end of final table --></div> + </form> <?php include("fend.inc"); ?> </body> </html> diff --git a/config/snort/snort_interfaces.php b/config/snort/snort_interfaces.php index e8e690a8..e96be262 100755 --- a/config/snort/snort_interfaces.php +++ b/config/snort/snort_interfaces.php @@ -28,11 +28,17 @@ * POSSIBILITY OF SUCH DAMAGE. */ +// Turn on buffering to speed up rendering +ini_set('output_buffering','true'); + +// Start buffering with a cache size of 100000 +ob_start(null, "1000"); + $nocsrf = true; require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $rebuild_rules; $snortdir = SNORTDIR; @@ -61,10 +67,14 @@ if (isset($_POST['del_x'])) { } conf_mount_ro(); + /* If all the Snort interfaces are removed, then unset the config array. */ + if (empty($a_nat)) + unset($a_nat); + write_config(); sleep(2); - /* if there are no ifaces do not create snort.sh */ + /* if there are no ifaces remaining do not create snort.sh */ if (!empty($config['installedpackages']['snortglobal']['rule'])) snort_create_rc(); else { @@ -93,11 +103,11 @@ if ($_GET['act'] == 'bartoggle' && is_numeric($id)) { $if_friendly = snort_get_friendly_interface($snortcfg['interface']); if (snort_is_running($snortcfg['uuid'], $if_real, 'barnyard2') == 'no') { - log_error("Toggle(barnyard starting) for {$if_friendly}({$snortcfg['descr']}}..."); + log_error("Toggle (barnyard starting) for {$if_friendly}({$snortcfg['descr']})..."); sync_snort_package_config(); snort_barnyard_start($snortcfg, $if_real); } else { - log_error("Toggle(barnyard stopping) for {$if_friendly}({$snortcfg['descr']}}..."); + log_error("Toggle (barnyard stopping) for {$if_friendly}({$snortcfg['descr']})..."); snort_barnyard_stop($snortcfg, $if_real); } @@ -113,7 +123,7 @@ if ($_GET['act'] == 'toggle' && is_numeric($id)) { $if_friendly = snort_get_friendly_interface($snortcfg['interface']); if (snort_is_running($snortcfg['uuid'], $if_real) == 'yes') { - log_error("Toggle(snort stopping) for {$if_friendly}({$snortcfg['descr']})..."); + log_error("Toggle (snort stopping) for {$if_friendly}({$snortcfg['descr']})..."); snort_stop($snortcfg, $if_real); header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); @@ -122,8 +132,12 @@ if ($_GET['act'] == 'toggle' && is_numeric($id)) { header( 'Cache-Control: post-check=0, pre-check=0', false ); header( 'Pragma: no-cache' ); } else { - log_error("Toggle(snort starting) for {$if_friendly}({$snortcfg['descr']})..."); + log_error("Toggle (snort starting) for {$if_friendly}({$snortcfg['descr']})..."); + + /* set flag to rebuild interface rules before starting Snort */ + $rebuild_rules = "on"; sync_snort_package_config(); + $rebuild_rules = "off"; snort_start($snortcfg, $if_real); header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); @@ -190,10 +204,9 @@ if ($pfsense_stable == 'yes') <tr> <td> <div id="mainarea2"> - <table class="tabcont" width="100%" border="0" cellpadding="0" - cellspacing="0"> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> <tr id="frheader"> - <td width="5%" class="list"> </td> + <td width="3%" class="list"> </td> <td width="10%" class="listhdrr"><?php echo gettext("If"); ?></td> <td width="13%" class="listhdrr"><?php echo gettext("Snort"); ?></td> <td width="10%" class="listhdrr"><?php echo gettext("Performance"); ?></td> @@ -201,18 +214,26 @@ if ($pfsense_stable == 'yes') <td width="12%" class="listhdrr"><?php echo gettext("Barnyard2"); ?></td> <td width="30%" class="listhdr"><?php echo gettext("Description"); ?></td> <td width="3%" class="list"> - <table border="0" cellspacing="0" cellpadding="1"> + <table border="0" cellspacing="0" cellpadding="0"> <tr> - <td width="17"></td> - <td><a href="snort_interfaces_edit.php?id=<?php echo $id_gen;?>"><img + <td></td> + <td align="center" valign="middle"><a href="snort_interfaces_edit.php?id=<?php echo $id_gen;?>"><img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" title="<?php echo gettext('add interface');?>"></a></td> </tr> </table> </td> </tr> -<?php $nnats = $i = 0; foreach ($a_nat as $natent): ?> -<tr valign="top" id="fr<?=$nnats;?>"> +<?php $nnats = $i = 0; +/* If no interfaces are defined, then turn off the "no rules" warning */ +$no_rules_footnote = false; +if ($id_gen == 0) + $no_rules = false; +else + $no_rules = true; + +foreach ($a_nat as $natent): ?> + <tr valign="top" id="fr<?=$nnats;?>"> <?php /* convert fake interfaces to real and check if iface is up */ @@ -228,9 +249,23 @@ if ($pfsense_stable == 'yes') else $biconfn = 'block'; - ?> + /* See if interface has any rules defined and set boolean flag */ + $no_rules = true; + if (isset($natent['customrules']) && !empty($natent['customrules'])) + $no_rules = false; + if (isset($natent['rulesets']) && !empty($natent['rulesets'])) + $no_rules = false; + if (isset($natent['ips_policy']) && !empty($natent['ips_policy'])) + $no_rules = false; + /* Do not display the "no rules" warning if interface disabled */ + if ($natent['enable'] == "off") + $no_rules = false; + if ($no_rules) + $no_rules_footnote = true; +?> <td class="listt"> - <input type="checkbox" id="frc<?=$nnats;?>" name="rule[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$nnats;?>')" style="margin: 0; padding: 0;"></td> + <input type="checkbox" id="frc<?=$nnats;?>" name="rule[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$nnats;?>')" style="margin: 0; padding: 0;"> + </td> <td class="listr" id="frd<?=$nnats;?>" ondblclick="document.location='snort_interfaces_edit.php?id=<?=$nnats;?>';"> @@ -249,6 +284,7 @@ if ($pfsense_stable == 'yes') <img src='../themes/{$g['theme']}/images/icons/icon_{$iconfn}.gif' width='13' height='13' border='0' title='" . gettext('click to toggle start/stop snort') . "'></a>"; + echo ($no_rules) ? " <img src=\"../themes/{$g['theme']}/images/icons/icon_frmfld_imp.png\" width=\"15\" height=\"15\" border=\"0\">" : ""; } else echo strtoupper("disabled"); ?> @@ -263,7 +299,8 @@ if ($pfsense_stable == 'yes') }else{ $check_performance = "lowmem"; } - ?> <?=strtoupper($check_performance);?></td> + ?> <?=strtoupper($check_performance);?> + </td> <td class="listr" id="frd<?=$nnats;?>" ondblclick="document.location='snort_interfaces_edit.php?id=<?=$nnats;?>';"> @@ -275,7 +312,8 @@ if ($pfsense_stable == 'yes') } else { $check_blockoffenders = disabled; } - ?> <?=strtoupper($check_blockoffenders);?></td> + ?> <?=strtoupper($check_blockoffenders);?> + </td> <td class="listr" id="frd<?=$nnats;?>" ondblclick="document.location='snort_interfaces_edit.php?id=<?=$nnats;?>';"> @@ -293,33 +331,40 @@ if ($pfsense_stable == 'yes') </td> <td class="listbg" ondblclick="document.location='snort_interfaces_edit.php?id=<?=$nnats;?>';"> - <font color="#ffffff"> <?=htmlspecialchars($natent['descr']);?> + <font color="#ffffff"> <?=htmlspecialchars($natent['descr']);?> </td> <td valign="middle" class="list" nowrap> - <table border="0" cellspacing="0" cellpadding="1"> - <tr> - <td><a href="snort_interfaces_edit.php?id=<?=$i;?>"><img - src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" - width="17" height="17" border="0" title="<?php echo gettext('edit interface'); ?>"></a></td> - </tr> - </table> - - </tr> + <table border="0" cellspacing="0" cellpadding="0"> + <tr> + <td><a href="snort_interfaces_edit.php?id=<?=$i;?>"><img + src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" + width="17" height="17" border="0" title="<?php echo gettext('edit interface'); ?>"></a> + </td> + </tr> + </table> + </td> + </tr> <?php $i++; $nnats++; endforeach; ?> <tr> - <td class="list" colspan="8"></td> + <td class="list"></td> + <td class="list" colspan="6"> + <?php if ($no_rules_footnote): ?><br><img src="../themes/<?= $g['theme']; ?>/images/icons/icon_frmfld_imp.png" width="15" height="15" border="0"> + <span class="red">   <?php echo gettext("WARNING: Marked interface currently has no rules defined for Snort"); ?></span> + <?php else: ?> + <?php endif; ?> + </td> <td class="list" valign="middle" nowrap> - <table border="0" cellspacing="0" cellpadding="1"> - <tr> - <td><?php if ($nnats == 0): ?><img - src="../themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" - width="17" height="17" title="<?php echo gettext("delete selected interface"); ?>" border="0"><?php else: ?><input - name="del" type="image" - src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" - width="17" height="17" title="<?php echo gettext("delete selected interface"); ?>" - onclick="return confirm('Do you really want to delete the selected Snort mapping?')"><?php endif; ?></td> - </tr> - </table> + <table border="0" cellspacing="0" cellpadding="0"> + <tr> + <td><?php if ($nnats == 0): ?><img + src="../themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" + width="17" height="17" title="<?php echo gettext("delete selected interface"); ?>" border="0"><?php else: ?> + <input name="del" type="image" + src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" + width="17" height="17" title="<?php echo gettext("delete selected interface"); ?>" + onclick="return confirm('Do you really want to delete the selected Snort mapping?')"><?php endif; ?></td> + </tr> + </table> </td> </tr> </table> @@ -332,46 +377,59 @@ if ($pfsense_stable == 'yes') <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <td> - <div id="mainarea4"> - <table class="tabcont" width="100%" border="0" cellpadding="0" - cellspacing="0"> - <tr id="frheader"> - <td width="100%"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> <br> - <?php echo gettext('This is the <strong>Snort Menu</strong> where you can see an over ' . - 'view of all your interface settings. <br> ' . - 'Please edit the <strong>Global Settings</strong> tab before adding ' . - 'an interface.'); ?> <br> - <br> - <span class="red"><strong><?php echo gettext("Warning:"); ?></strong></span> <br> - <strong><?php echo gettext("New settings will not take effect until interface restart."); ?></strong> - <br> - <br> - <strong>Click</strong> on the <img - src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" - width="17" height="17" border="0" title="<?php echo gettext("Add Icon"); ?>"> icon to add a - interface.<strong> Click</strong> - on the <img - src="../themes/<?= $g['theme']; ?>/images/icons/icon_pass.gif" - width="13" height="13" border="0" title="<?php echo gettext("Start Icon"); ?>"> icon to <strong>start</strong> - snort and barnyard2. <br> - <strong>Click</strong> on the <img - src="../themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" - width="17" height="17" border="0" title="<?php echo gettext("Edit Icon"); ?>"> icon to edit a - interface and settings.<strong> Click</strong> - on the <img - src="../themes/<?= $g['theme']; ?>/images/icons/icon_block.gif" - width="13" height="13" border="0" title="<?php echo gettext("Stop Icon"); ?>"> icon to <strong>stop</strong> - snort and barnyard2. <br> - <strong> Click</strong> on the <img - src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" - width="17" height="17" border="0" title="<?php echo gettext("Delete Icon"); ?>"> icon to - delete a interface and settings.</td> - </tr> - </table> - </div> - + <table class="tabcont" width="100%" border="0" cellpadding="1" cellspacing="1"> + <tr> + <td colspan="3"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> <br> + <?php echo gettext('This is the <strong>Snort Menu</strong> where you can see an over ' . + 'view of all your interface settings. ' . + 'Please visit the <strong>Global Settings</strong> tab before adding ' . 'an interface.'); ?> + </td> + </tr> + <tr> + <td colspan="3"><br> + </td> + </tr> + <tr> + <td colspan="3"><span class="red"><strong><?php echo gettext("Warning:"); ?></strong></span><br> + <strong><?php echo gettext("New settings will not take effect until interface restart."); ?></strong> + </td> + </tr> + <tr> + <td colspan="3"><br> + </td> + </tr> + <tr> + <td><strong>Click</strong> on the <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" + width="17" height="17" border="0" title="<?php echo gettext("Add Icon"); ?>"> icon to add + an interface. + </td> + <td width="3%"> + </td> + <td><strong>Click</strong> on the <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_pass.gif" + width="13" height="13" border="0" title="<?php echo gettext("Start Icon"); ?>"> icon to <strong>start</strong> + snort and barnyard2. + </td> + </tr> + <tr> + <td><strong>Click</strong> on the <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" + width="17" height="17" border="0" title="<?php echo gettext("Edit Icon"); ?>"> icon to edit + an interface and settings. + <td width="3%"> + </td> + <td><strong>Click</strong> on the <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_block.gif" + width="13" height="13" border="0" title="<?php echo gettext("Stop Icon"); ?>"> icon to <strong>stop</strong> + snort and barnyard2. + </td> + </tr> + <tr> + <td colspan="3"><strong> Click</strong> on the <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" + width="17" height="17" border="0" title="<?php echo gettext("Delete Icon"); ?>"> icon to + delete an interface and settings. + </td> + </tr> + </table> + </td> </tr> - </td> </table> </form> <?php diff --git a/config/snort/snort_interfaces_edit.php b/config/snort/snort_interfaces_edit.php index d0fabbf4..8d7b9c06 100755 --- a/config/snort/snort_interfaces_edit.php +++ b/config/snort/snort_interfaces_edit.php @@ -31,7 +31,7 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $rebuild_rules; if (!is_array($config['installedpackages']['snortglobal'])) $config['installedpackages']['snortglobal'] = array(); @@ -50,10 +50,15 @@ if (is_null($id)) { } $pconfig = array(); -if (empty($snortglob['rule'][$id]['uuid'])) +if (empty($snortglob['rule'][$id]['uuid'])) { + /* Adding new interface, so flag rules to build. */ $pconfig['uuid'] = snort_generate_id(); -else + $rebuild_rules = "on"; +} +else { $pconfig['uuid'] = $a_rule[$id]['uuid']; + $rebuild_rules = "off"; +} $snort_uuid = $pconfig['uuid']; if (isset($id) && $a_rule[$id]) { @@ -77,14 +82,6 @@ if ($_POST["Submit"]) { if (!$_POST['interface']) $input_errors[] = "Interface is mandatory"; -/* - foreach ($a_rule as $natent) { - if (isset($id) && ($a_rule[$id]) && ($a_rule[$id] === $natent)) - continue; - if ($natent['interface'] == $_POST['interface']) - $input_errors[] = "This interface is already configured for another instance"; - } -*/ /* if no errors write to conf */ if (!$input_errors) { @@ -118,9 +115,17 @@ if ($_POST["Submit"]) { } else $a_rule[] = $natent; + /* If Snort is disabled on this interface, stop any running instance */ if ($natent['enable'] != 'on') snort_stop($natent, $if_real); + + /* Save configuration changes */ write_config(); + + /* Most changes don't require a rules rebuild, so default to "off" */ + $rebuild_rules = "off"; + + /* Update snort.conf and snort.sh files for this interface */ sync_snort_package_config(); header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); diff --git a/config/snort/snort_interfaces_global.php b/config/snort/snort_interfaces_global.php index 9dde8aaf..3c544436 100644 --- a/config/snort/snort_interfaces_global.php +++ b/config/snort/snort_interfaces_global.php @@ -50,6 +50,10 @@ $pconfig['snortloglimit'] = $config['installedpackages']['snortglobal']['snortlo $pconfig['snortloglimitsize'] = $config['installedpackages']['snortglobal']['snortloglimitsize']; $pconfig['autorulesupdate7'] = $config['installedpackages']['snortglobal']['autorulesupdate7']; $pconfig['forcekeepsettings'] = $config['installedpackages']['snortglobal']['forcekeepsettings']; +$pconfig['snortcommunityrules'] = $config['installedpackages']['snortglobal']['snortcommunityrules']; + +if (empty($pconfig['snortloglimit'])) + $pconfig['snortloglimit'] = 'on'; /* if no errors move foward */ if (!$input_errors) { @@ -58,7 +62,9 @@ if (!$input_errors) { $config['installedpackages']['snortglobal']['snortdownload'] = $_POST['snortdownload']; $config['installedpackages']['snortglobal']['oinkmastercode'] = $_POST['oinkmastercode']; + $config['installedpackages']['snortglobal']['snortcommunityrules'] = $_POST['snortcommunityrules'] ? 'on' : 'off'; $config['installedpackages']['snortglobal']['emergingthreats'] = $_POST['emergingthreats'] ? 'on' : 'off'; + $config['installedpackages']['snortglobal']['rm_blocked'] = $_POST['rm_blocked']; if ($_POST['snortloglimitsize']) { $config['installedpackages']['snortglobal']['snortloglimit'] = $_POST['snortloglimit']; @@ -110,6 +116,20 @@ if ($input_errors) ?> +<script language="JavaScript"> +<!-- +function enable_snort_vrt(btn) { + if (btn == 'off') { + document.iform.oinkmastercode.disabled = "true"; + } + if (btn == 'on') { + document.iform.oinkmastercode.disabled = ""; + } +} +//--> +</script> + + <form action="snort_interfaces_global.php" method="post" enctype="multipart/form-data" name="iform" id="iform"> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td class="tabnavtbl"> @@ -124,7 +144,8 @@ if ($input_errors) $tab_array[6] = array(gettext("Suppress"), false, "/snort/snort_interfaces_suppress.php"); display_top_tabs($tab_array); ?> -</td></tr> +</td> +</tr> <tr> <td class="tabcont"> <table width="100%" border="0" cellpadding="6" cellspacing="0"> @@ -132,55 +153,69 @@ if ($input_errors) <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Please Choose The " . "Type Of Rules You Wish To Download"); ?></td> </tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Install Snort.org rules"); ?></td> + <td width="22%" valign="top" class="vncell"><?php printf(gettext("Install %sSnort VRT%s rules"), '<strong>' , '</strong>'); ?></td> <td width="78%" class="vtable"> - <table cellpadding="0" cellspacing="0"> + <table width="100%" border="0" cellpadding="2" cellspacing="0"> <tr> - <td colspan="2"><input name="snortdownload" type="radio" - id="snortdownload" value="off" -<?php if($pconfig['snortdownload']=='off' || $pconfig['snortdownload']=='') echo 'checked'; ?>> - <?php printf(gettext("Do %sNOT%s Install"), '<strong>', '</strong>'); ?></td> + <td><input name="snortdownload" type="radio" id="snortdownload" value="off" onclick="enable_snort_vrt('off')" + <?php if($pconfig['snortdownload']=='off' || $pconfig['snortdownload']=='') echo 'checked'; ?> > </td> + <td><span class="vexpl"><?php printf(gettext("Do %sNOT%s Install"), '<strong>', '</strong>'); ?></span></td> </tr> <tr> - <td colspan="2"><input name="snortdownload" type="radio" - id="snortdownload" value="on" - <?php if($pconfig['snortdownload']=='on') echo 'checked'; ?>> <?php echo gettext("Install " . - "Basic Rules or Premium rules"); ?> <br> - <a - href="https://www.snort.org/signup" target="_blank"><?php echo gettext("Sign Up for a " . - "Basic Rule Account"); ?></a><br> - <a - href="http://www.snort.org/vrt/buy-a-subscription" - target="_blank"><?php echo gettext("Sign Up for Sourcefire VRT Certified Premium " . - "Rules. This Is Highly Recommended"); ?></a></td> - </tr> + <td><input name="snortdownload" type="radio" id="snortdownload" value="on" onclick="enable_snort_vrt('on')" + <?php if($pconfig['snortdownload']=='on') echo 'checked'; ?>></td> + <td><span class="vexpl"><?php echo gettext("Install Basic Rules or Premium rules"); ?></span></td> <tr> <td> </td> + <td><a href="https://www.snort.org/signup" target="_blank"><?php echo gettext("Sign Up for a Basic Rule Account"); ?> </a><br> + <a href="http://www.snort.org/vrt/buy-a-subscription" target="_blank"> + <?php echo gettext("Sign Up for Sourcefire VRT Certified Premium Rules. This Is Highly Recommended"); ?></a></td> </tr> - </table> - <table width="100%" border="0" cellpadding="6" cellspacing="0"> <tr> - <td colspan="2" valign="top" class="optsect_t2"><?php echo gettext("Oinkmaster code"); ?></td> + <td colspan="2"> </td> </tr> + </table> + <table width="100%" border="0" cellpadding="2" cellspacing="0"> <tr> - <td class="vncell" valign="top"><?php echo gettext("Code"); ?></td> - <td class="vtable"><input name="oinkmastercode" type="text" + <td colspan="2" valign="top"><b><span class="vexpl"><?php echo gettext("Oinkmaster Configuration"); ?></span></b></td> + </tr> + <tr> + <td valign="top"><span class="vexpl"><strong><?php echo gettext("Code"); ?><strong></span</td> + <td><input name="oinkmastercode" type="text" class="formfld" id="oinkmastercode" size="52" - value="<?=htmlspecialchars($pconfig['oinkmastercode']);?>"><br> - <?php echo gettext("Obtain a snort.org Oinkmaster code and paste here."); ?></td> - + value="<?=htmlspecialchars($pconfig['oinkmastercode']);?>" + <?php if($pconfig['snortdownload']<>'on') echo 'disabled'; ?>><br> + <?php echo gettext("Obtain a snort.org Oinkmaster code and paste it here."); ?></td> + </tr> </table> - </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php printf(gettext("Install %sEmergingthreats%s " . + <td width="22%" valign="top" class="vncell"><?php printf(gettext("Install %sSnort Community%s " . + "rules"), '<strong>' , '</strong>'); ?></td> + <td width="78%" class="vtable"> + <table width="100%" border="0" cellpadding="2" cellspacing="0"> + <tr> + <td valign="top" width="8%"><input name="snortcommunityrules" type="checkbox" value="yes" + <?php if ($config['installedpackages']['snortglobal']['snortcommunityrules']=="on") echo "checked"; ?> ></td> + <td><span class="vexpl"><?php echo gettext("The Snort Community Ruleset is a GPLv2 VRT certified ruleset that is distributed free of charge " . + "without any VRT License restrictions. This ruleset is updated daily and is a subset of the subscriber ruleset."); ?> + <br/><br/><?php printf(gettext("%sNote: %sIf you are a Snort VRT Paid Subscriber, the community ruleset is already built into your download of the Snort VRT rules, and there is no benefit in adding this rule set."),'<span class="red"><strong>' ,'</strong></span>'); ?></span><br></td> + </tr> + </table></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?php printf(gettext("Install %sEmerging Threats%s " . "rules"), '<strong>' , '</strong>'); ?></td> - <td width="78%" class="vtable"><input name="emergingthreats" - type="checkbox" value="yes" - <?php if ($config['installedpackages']['snortglobal']['emergingthreats']=="on") echo "checked"; ?> - ><br> - <?php echo gettext("Emerging Threats is an open source community that produces fastest " . - "moving and diverse Snort Rules."); ?></td> + <td width="78%" class="vtable"> + <table width="100%" border="0" cellpadding="2" cellspacing="0"> + <tr> + <td valign="top" width="8%"><input name="emergingthreats" type="checkbox" value="yes" + <?php if ($config['installedpackages']['snortglobal']['emergingthreats']=="on") echo "checked"; ?>> + <td><span class="vexpl"><?php echo gettext("Emerging Threats is an open source community that produces fast " . + "moving and diverse Snort Rules."); ?></span></td> + </tr> + </table> + </td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Update rules " . @@ -194,9 +229,9 @@ if ($input_errors) <?php if ($iface3 == $pconfig['autorulesupdate7']) echo "selected"; ?>> <?=htmlspecialchars($ifacename3);?></option> <?php endforeach; ?> - </select><br> - <span class="vexpl"><?php echo gettext("Please select the update times for rules."); ?><br> - <?php echo gettext("Hint: in most cases, every 12 hours is a good choice."); ?></span></td> + </select><span class="vexpl"> <?php echo gettext("Please select the update times for rules."); ?><br/><br/> + + <?php printf(gettext("%sHint%s: in most cases, every 12 hours is a good choice."), '<span class="red"><strong>','</strong></span>'); ?></span></td> </tr> <tr> <td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Settings"); ?></td> @@ -209,40 +244,32 @@ if ($input_errors) <br/> <br/> <span class="red"><strong><?php echo gettext("Note"); ?></span>:</strong><br> - <?php echo gettext("Available space is"); ?> <strong><?php echo $snortlogCurrentDSKsize; ?>MB</strong></td> + <?php echo gettext("Available space is"); ?> <strong><?php echo $snortlogCurrentDSKsize; ?> MB</strong></td> <td width="78%" class="vtable"> - <table cellpadding="0" cellspacing="0"> - <tr> - <td colspan="2"><input name="snortloglimit" type="radio" - id="snortloglimit" value="on" -<?php if($pconfig['snortloglimit']=='on') echo 'checked'; ?>> - <strong><?php echo gettext("Enable"); ?></strong> <?php echo gettext("directory size limit"); ?> (<strong><?php echo gettext("Default"); ?></strong>)</td> - </tr> - <tr> - <td colspan="2"><input name="snortloglimit" type="radio" - id="snortloglimit" value="off" -<?php if($pconfig['snortloglimit']=='off') echo 'checked'; ?>> <strong><?php echo gettext("Disable"); ?></strong> - <?php echo gettext("directory size limit"); ?><br> - <br> - <span class="red"><strong><?php echo gettext("Warning"); ?></span>:</strong> <?php echo gettext("Nanobsd " . - "should use no more than 10MB of space."); ?></td> - </tr> - <tr> - <td> </td> - </tr> - </table> - <table width="100%" border="0" cellpadding="6" cellspacing="0"> - <tr> - <td class="vncell3"><?php echo gettext("Size in"); ?> <strong>MB</strong></td> - <td class="vtable"><input name="snortloglimitsize" type="text" - class="formfld" id="snortloglimitsize" size="7" - value="<?=htmlspecialchars($pconfig['snortloglimitsize']);?>"> - <?php echo gettext("Default is"); ?> <strong>20%</strong> <?php echo gettext("of available space."); ?></td> - - </table> - + <table cellpadding="0" cellspacing="0"> + <tr> + <td colspan="2"><input name="snortloglimit" type="radio" id="snortloglimit" value="on" + <?php if($pconfig['snortloglimit']=='on') echo 'checked'; ?>><span class="vexpl"> + <strong><?php echo gettext("Enable"); ?></strong> <?php echo gettext("directory size limit"); ?> (<strong><?php echo gettext("Default"); ?></strong>)</span></td> + </tr> + <tr> + <td colspan="2"><input name="snortloglimit" type="radio" id="snortloglimit" value="off" + <?php if($pconfig['snortloglimit']=='off') echo 'checked'; ?>> <span class="vexpl"><strong><?php echo gettext("Disable"); ?></strong> + <?php echo gettext("directory size limit"); ?></span><br> + <br> + <span class="red"><strong><?php echo gettext("Warning"); ?></span>:</strong> <?php echo gettext("Nanobsd " . + "should use no more than 10MB of space."); ?></td> + </tr> + </table> + <table width="100%" border="0" cellpadding="2" cellspacing="0"> + <tr> + <td><span class="vexpl"><?php echo gettext("Size in"); ?> <strong>MB</strong></span></td> + <td><input name="snortloglimitsize" type="text" class="formfld" id="snortloglimitsize" size="10" value="<?=htmlspecialchars($pconfig['snortloglimitsize']);?>"> + <?php printf(gettext("Default is %s20%%%s of available space."), '<strong>', '</strong>'); ?></td> + </tr> + </table> + </td> </tr> - <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Remove blocked hosts " . "every"); ?></td> @@ -255,10 +282,9 @@ if ($input_errors) <?php if ($iface3 == $pconfig['rm_blocked']) echo "selected"; ?>> <?=htmlspecialchars($ifacename3);?></option> <?php endforeach; ?> - </select><br> - <span class="vexpl"><?php echo gettext("Please select the amount of time you would like " . - "hosts to be blocked for."); ?><br> - <?php echo gettext("Hint: in most cases, 1 hour is a good choice."); ?></span></td> + </select> + <?php echo gettext("Please select the amount of time you would like hosts to be blocked for."); ?><br/><br/> + <?php printf(gettext("%sHint:%s in most cases, 1 hour is a good choice."), '<span class="red"><strong>', '</strong></span>'); ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Keep snort settings " . @@ -266,8 +292,7 @@ if ($input_errors) <td width="78%" class="vtable"><input name="forcekeepsettings" id="forcekeepsettings" type="checkbox" value="yes" <?php if ($config['installedpackages']['snortglobal']['forcekeepsettings']=="on") echo "checked"; ?> - ><br> - <?php echo gettext("Settings will not be removed during deinstall."); ?></td> + > <?php echo gettext("Settings will not be removed during deinstall."); ?></td> </tr> <tr> <td width="22%" valign="top"> @@ -279,8 +304,8 @@ if ($input_errors) <td width="22%" valign="top"> </td> <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?><br> </strong></span> <?php echo gettext("Changing any settings on this page will affect all " . - "interfaces. Please, double check if your oink code is correct and " . - "the type of snort.org account you hold."); ?></span></td> + "interfaces. Double check that your oink code is correct, and verify the " . + "type of Snort.org account you hold."); ?></span></td> </tr> </table> </td></tr> diff --git a/config/snort/snort_interfaces_suppress.php b/config/snort/snort_interfaces_suppress.php index 93d3f2dc..32f2f6ba 100644 --- a/config/snort/snort_interfaces_suppress.php +++ b/config/snort/snort_interfaces_suppress.php @@ -134,10 +134,10 @@ if($pfsense_stable == 'yes'){echo '<p class="pgtitle">' . $pgtitle . '</p>';} </table> </td></tr> <tr> - <td colspan="3" width="100%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> + <td colspan="3" width="100%"><br/><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> <p><span class="vexpl"><?php echo gettext("Here you can create event filtering and " . - "suppression for your snort package rules."); ?><br> - <?php echo gettext("Please note that you must restart a running rule so that changes can " . + "suppression for your snort package rules."); ?><br/><br/> + <?php echo gettext("Please note that you must restart a running Interface so that changes can " . "take effect."); ?></span></p></td> </tr> </table> diff --git a/config/snort/snort_interfaces_whitelist.php b/config/snort/snort_interfaces_whitelist.php index f90cbe1f..a925ad45 100644 --- a/config/snort/snort_interfaces_whitelist.php +++ b/config/snort/snort_interfaces_whitelist.php @@ -154,15 +154,20 @@ if ($savemsg) print_info_box($savemsg); </tr> </table> <br> -<table width="100%" border="0" cellpadding="0" - cellspacing="0"> +<table width="100%" border="0" cellpadding="1" + cellspacing="1"> + <tr> <td width="100%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> <p><span class="vexpl"><?php echo gettext("Here you can create whitelist files for your " . "snort package rules."); ?><br> <?php echo gettext("Please add all the ips or networks you want to protect against snort " . "block decisions."); ?><br> <?php echo gettext("Remember that the default whitelist only includes local networks."); ?><br> - <?php echo gettext("Be careful, it is very easy to get locked out of you system."); ?></span></p></td> + <?php echo gettext("Be careful, it is very easy to get locked out of your system."); ?></span></p></td> + </tr> + <tr> + <td width="100%"><span class="vexpl"><?php echo gettext("Remember you must restart Snort on the interface for changes to take effect!"); ?></span></td> + </tr> </table> </form> <?php include("fend.inc"); ?> diff --git a/config/snort/snort_log_view.php b/config/snort/snort_log_view.php new file mode 100644 index 00000000..4fc8d990 --- /dev/null +++ b/config/snort/snort_log_view.php @@ -0,0 +1,89 @@ +<?php +/* + * snort_log_view.php + * + * Copyright (C) 2004, 2005 Scott Ullrich + * Copyright (C) 2011 Ermal Luci + * All rights reserved. + * + * Adapted for FreeNAS by Volker Theile (votdev@gmx.de) + * Copyright (C) 2006-2009 Volker Theile + * + * Adapted for Pfsense Snort package by Robert Zelaya + * Copyright (C) 2008-2009 Robert Zelaya + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +require_once("guiconfig.inc"); +require_once("/usr/local/pkg/snort/snort.inc"); + +$contents = ''; + +// Read the contents of the argument passed to us. +// Is it a fully qualified path and file? +if (file_exists($_GET['logfile'])) + $contents = file_get_contents($_GET['logfile']); +// It is not something we can display, so print an error. +else + $contents = gettext("\n\nERROR -- File: {$_GET['logfile']} not found!"); + +$pgtitle = array(gettext("Snort"), gettext("Log File Viewer")); +?> + +<?php include("head.inc");?> + +<body link="#000000" vlink="#000000" alink="#000000"> +<?php if ($savemsg) print_info_box($savemsg); ?> +<?php // include("fbegin.inc");?> + +<form action="snort_log_view.php" method="post"> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> +<tr> + <td class="tabcont"> + <table width="100%" cellpadding="0" cellspacing="6" bgcolor="#eeeeee"> + <tr> + <td class="pgtitle" colspan="2">Snort: Log File Viewer</td> + </tr> + <tr> + <td align="left" width="20%"> + <input type="button" class="formbtn" value="Return" onclick="window.close()"> + </td> + <td align="right"> + <b><?php echo gettext("Log File: ") . '</b> ' . $_GET['logfile']; ?> + </td> + </tr> + <tr> + <td colspan="2" valign="top" class="label"> + <div style="background: #eeeeee; width:100%; height:100%;" id="textareaitem"><!-- NOTE: The opening *and* the closing textarea tag must be on the same line. --> + <textarea style="width:100%; height:100%;" readonly wrap="off" rows="33" cols="80" name="code2"><?=$contents;?></textarea> + </div> + </td> + </tr> + </table> + </td> +</tr> +</table> +</form> +<?php // include("fend.inc");?> +</body> +</html> diff --git a/config/snort/snort_preprocessors.php b/config/snort/snort_preprocessors.php index 7d0348e9..cf6146cf 100755 --- a/config/snort/snort_preprocessors.php +++ b/config/snort/snort_preprocessors.php @@ -34,7 +34,13 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $rebuild_rules; +$snortlogdir = SNORTLOGDIR; + +if (!is_array($config['installedpackages']['snortglobal'])) { + $config['installedpackages']['snortglobal'] = array(); +} +$vrt_enabled = $config['installedpackages']['snortglobal']['snortdownload']; if (!is_array($config['installedpackages']['snortglobal']['rule'])) { $config['installedpackages']['snortglobal']['rule'] = array(); @@ -77,8 +83,43 @@ if (isset($id) && $a_nat[$id]) { $pconfig['dnp3_preproc'] = $a_nat[$id]['dnp3_preproc']; $pconfig['modbus_preproc'] = $a_nat[$id]['modbus_preproc']; $pconfig['gtp_preproc'] = $a_nat[$id]['gtp_preproc']; + $pconfig['preproc_auto_rule_disable'] = $a_nat[$id]['preproc_auto_rule_disable']; + $pconfig['protect_preproc_rules'] = $a_nat[$id]['protect_preproc_rules']; + + /* If not using the Snort VRT rules, then disable */ + /* the Sensitive Data (sdf) preprocessor. */ + if ($vrt_enabled == "off") + $pconfig['sensitive_data'] = "off"; + + /**********************************************************/ + /* To keep new users from shooting themselves in the foot */ + /* enable the most common and necessary preprocessors by */ + /* default. */ + /**********************************************************/ + if (empty($pconfig['ftp_preprocessor'])) + $pconfig['ftp_preprocessor'] = 'on'; + if (empty($pconfig['smtp_preprocessor'])) + $pconfig['smtp_preprocessor'] = 'on'; + if (empty($pconfig['dce_rpc_2'])) + $pconfig['dce_rpc_2'] = 'on'; + if (empty($pconfig['dns_preprocessor'])) + $pconfig['dns_preprocessor'] = 'on'; + if (empty($pconfig['ssl_preproc'])) + $pconfig['ssl_preproc'] = 'on'; + if (empty($pconfig['pop_preproc'])) + $pconfig['pop_preproc'] = 'on'; + if (empty($pconfig['imap_preproc'])) + $pconfig['imap_preproc'] = 'on'; + if (empty($pconfig['sip_preproc'])) + $pconfig['sip_preproc'] = 'on'; + if (empty($pconfig['other_preprocs'])) + $pconfig['other_preprocs'] = 'on'; } +/* Define the "disabled_preproc_rules.log" file for this interface */ +$iface = snort_get_friendly_interface($pconfig['interface']); +$disabled_rules_log = "{$snortlogdir}/{$iface}_disabled_preproc_rules.log"; + if ($_POST) { $natent = array(); $natent = $pconfig; @@ -120,6 +161,12 @@ if ($_POST) { $natent['sip_preproc'] = $_POST['sip_preproc'] ? 'on' : 'off'; $natent['modbus_preproc'] = $_POST['modbus_preproc'] ? 'on' : 'off'; $natent['gtp_preproc'] = $_POST['gtp_preproc'] ? 'on' : 'off'; + $natent['preproc_auto_rule_disable'] = $_POST['preproc_auto_rule_disable'] ? 'on' : 'off'; + $natent['protect_preproc_rules'] = $_POST['protect_preproc_rules'] ? 'on' : 'off'; + + /* If 'preproc_auto_rule_disable' is off, then clear log file */ + if ($natent['preproc_auto_rule_disable'] == 'off') + @unlink("{$disabled_rules_log}"); if (isset($id) && $a_nat[$id]) $a_nat[$id] = $natent; @@ -132,8 +179,15 @@ if ($_POST) { write_config(); - $if_real = snort_get_real_interface($pconfig['interface']); - sync_snort_package_config(); + /* Set flag to rebuild rules for this interface */ + $rebuild_rules = "on"; + + /*************************************************/ + /* Update the snort conf file and rebuild the */ + /* rules for this interface. */ + /*************************************************/ + snort_generate_conf($natent); + $rebuild_rules = "off"; /* after click go to this page */ header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); @@ -172,6 +226,25 @@ include_once("head.inc"); </script> <script type="text/javascript" src="/javascript/suggestions.js"> </script> + +<script language="javascript" type="text/javascript"> + +function wopen(url, name, w, h) +{ +// Fudge factors for window decoration space. +// In my tests these work well on all platforms & browsers. +w += 32; +h += 96; + var win = window.open(url, + name, + 'width=' + w + ', height=' + h + ', ' + + 'location=no, menubar=no, ' + + 'status=no, toolbar=no, scrollbars=yes, resizable=yes'); + win.resizeTo(w, h); + win.focus(); +} +</script> + <form action="snort_preprocessors.php" method="post" enctype="multipart/form-data" name="iform" id="iform"> <table width="100%" border="0" cellpadding="0" cellspacing="0"> @@ -191,32 +264,76 @@ include_once("head.inc"); <tr><td class="tabcont"> <table width="100%" border="0" cellpadding="6" cellspacing="0"> <tr> - <td colspan="2" align="center" valign="middle"> - <span class="red"><strong><?php echo gettext("NOTE"); ?></strong></span><br> + <td colspan="2" align="left" valign="middle"> <?php echo gettext("Rules may be dependent on preprocessors! Disabling preprocessors may result in "); ?> - <?php echo gettext("dependent rules being automatically disabled."); ?><br> - <?php echo gettext("Defaults will be used when there is no user input."); ?><br></td> + <?php echo gettext("Snort start failures unless dependent rules are also disabled."); ?> + <?php echo gettext("The Auto-Rule Disable feature can be used, but note the warning about compromising protection. " . + "Defaults will be used where no user input is provided."); ?></td> </tr> <tr> - <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Performance Statistics"); ?></td> + + <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Preprocessors Configuration"); ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td> - <td width="78%" class="vtable"><input name="perform_stat" - type="checkbox" value="on" + <td width="78%" class="vtable"><input name="perform_stat" type="checkbox" value="on" <?php if ($pconfig['perform_stat']=="on") echo "checked"; ?> onClick="enable_change(false)"> <?php echo gettext("Collect Performance Statistics for this interface."); ?></td> </tr> <tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Protect Customized Preprocessor Rules"); ?></td> + <td width="78%" class="vtable"><input name="protect_preproc_rules" type="checkbox" value="on" + <?php if ($pconfig['protect_preproc_rules']=="on") echo "checked "; + if ($vrt_enabled <> 'on') echo "disabled"; ?> + onClick="enable_change(false)"> <?php echo gettext("Check this box if you maintain customized preprocessor text rules files for this interface."); ?> + <table width="100%" border="0" cellpadding="2" cellpadding="2"> + <tr> + <td width="3%"> </td> + <td><?php echo gettext("Enable this only if you use customized preprocessor text rules files and " . + "you do not want them overwritten by automatic Snort VRT rule updates. " . + "This option is disabled when Snort VRT rules download is not enabled on the Global Settings tab."); ?><br/><br/> + <?php printf(gettext("%sHint:%s Most users should leave this unchecked."), '<span class="red"><strong>', '</strong></span>'); ?></span></td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Auto Rule Disable"); ?></td> + <td width="78%" class="vtable"><input name="preproc_auto_rule_disable" type="checkbox" value="on" + <?php if ($pconfig['preproc_auto_rule_disable']=="on") echo "checked"; ?> + onClick="enable_change(false)"> <?php echo gettext("Auto-disable text rules dependent on disabled preprocessors for this interface. "); + echo gettext("Default is ") . '<strong>' . gettext("Not Checked."); ?></strong><br/> + <table width="100%" border="0" cellpadding="2" cellpadding="2"> + <tr> + <td width="3%"> </td> + <td><span class="red"><strong><?php echo gettext("Warning: "); ?></strong></span> + <?php echo gettext("Enabling this option allows Snort to automatically disable any text rules " . + "containing rule options or content modifiers that are dependent upon the preprocessors " . + "you have not enabled. This may facilitate starting Snort without errors related to " . + "disabled preprocessors, but can substantially compromise the level of protection by " . + "automatically disabling detection rules."); ?></td> + </tr> + <?php if (file_exists($disabled_rules_log) && filesize($disabled_rules_log) > 0): ?> + <tr> + <td width="3%"> </td> + <td class="vexpl"><input type="button" class="formbtn" value="View" onclick="wopen('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$disabled_rules_log;?>','FileViewer',800,600)"/> + <?php echo gettext("Click to view the list of currently auto-disabled rules"); ?></td> + </tr> + <?php endif; ?> + </table> + </td> + </tr> + <tr> <td colspan="2" valign="top" class="listtopic"><?php echo gettext("HTTP Inspect Settings"); ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td> <td width="78%" class="vtable"><input name="http_inspect" type="checkbox" value="on" - <?php if ($pconfig['http_inspect']=="on") echo "checked"; ?> + <?php if ($pconfig['http_inspect']=="on" || empty($pconfig['http_inspect'])) echo "checked"; ?> onClick="enable_change(false)"> <?php echo gettext("Use HTTP Inspect to " . - "Normalize/Decode and detect HTTP traffic and protocol anomalies."); ?></td> + "Normalize/Decode and detect HTTP traffic and protocol anomalies. Default is "); ?> + <strong><?php echo gettext("Checked."); ?></strong></td> </tr> <tr> <td valign="top" class="vncell"><?php echo gettext("HTTP server flow depth"); ?></td> @@ -241,7 +358,7 @@ include_once("head.inc"); <td width="78%" class="vtable"> <select name="http_server_profile" class="formselect" id="http_server_profile"> <?php - $profile = array('All', 'Apache', 'IIS', 'IIS_4.0', 'IIS_5.0'); + $profile = array('All', 'Apache', 'IIS', 'IIS4_0', 'IIS5_0'); foreach ($profile as $val): ?> <option value="<?=strtolower($val);?>" <?php if (strtolower($val) == $pconfig['http_server_profile']) echo "selected"; ?>> @@ -275,9 +392,10 @@ include_once("head.inc"); <td width="22%" valign="top" class="vncell"><?php echo gettext("Disable HTTP Alerts"); ?></td> <td width="78%" class="vtable"><input name="noalert_http_inspect" type="checkbox" value="on" - <?php if ($pconfig['noalert_http_inspect']=="on") echo "checked"; ?> - onClick="enable_change(false)"> <?php echo gettext("Tick to turn off alerts from the HTTP Inspect " . - "preprocessor. This has no effect on HTTP rules in the rule set."); ?></td> + <?php if ($pconfig['noalert_http_inspect']=="on" || empty($pconfig['noalert_http_inspect'])) echo "checked"; ?> + onClick="enable_change(false)"> <?php echo gettext("Turn off alerts from HTTP Inspect " . + "preprocessor. This has no effect on HTTP rules. Default is "); ?> + <strong><?php echo gettext("Checked."); ?></strong></td> </tr> <tr> <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Stream5 Settings"); ?></td> @@ -382,7 +500,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['other_preprocs']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("Normalize/Decode RPC traffic and detects Back Orifice traffic on the network."); ?></td> + <?php echo gettext("Normalize/Decode RPC traffic and detects Back Orifice traffic on the network. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> @@ -391,7 +510,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['ftp_preprocessor']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("Normalize/Decode FTP and Telnet traffic and protocol anomalies."); ?></td> + <?php echo gettext("Normalize/Decode FTP and Telnet traffic and protocol anomalies. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> @@ -400,7 +520,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['pop_preproc']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("Normalize/Decode POP protocol for enforcement and buffer overflows."); ?></td> + <?php echo gettext("Normalize/Decode POP protocol for enforcement and buffer overflows. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> @@ -409,7 +530,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['imap_preproc']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("Normalize/Decode IMAP protocol for enforcement and buffer overflows."); ?></td> + <?php echo gettext("Normalize/Decode IMAP protocol for enforcement and buffer overflows. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> @@ -418,7 +540,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['smtp_preprocessor']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("Normalize/Decode SMTP protocol for enforcement and buffer overflows."); ?></td> + <?php echo gettext("Normalize/Decode SMTP protocol for enforcement and buffer overflows. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> @@ -427,7 +550,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['dce_rpc_2']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("The DCE/RPC preprocessor detects and decodes SMB and DCE/RPC traffic."); ?></td> + <?php echo gettext("The DCE/RPC preprocessor detects and decodes SMB and DCE/RPC traffic. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> @@ -436,7 +560,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['sip_preproc']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("The SIP preprocessor decodes SIP traffic and detects some vulnerabilities."); ?></td> + <?php echo gettext("The SIP preprocessor decodes SIP traffic and detects some vulnerabilities. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> @@ -454,7 +579,8 @@ include_once("head.inc"); type="checkbox" value="on" <?php if ($pconfig['dns_preprocessor']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("The DNS preprocessor decodes DNS Response traffic and detects some vulnerabilities."); ?></td> + <?php echo gettext("The DNS preprocessor decodes DNS Response traffic and detects some vulnerabilities. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?></td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> <?php echo gettext("SSL Data"); ?></td> @@ -462,16 +588,22 @@ include_once("head.inc"); <input name="ssl_preproc" type="checkbox" value="on" <?php if ($pconfig['ssl_preproc']=="on") echo "checked"; ?> onClick="enable_change(false)"><br> - <?php echo gettext("SSL data searches for irregularities during SSL protocol exchange"); ?> + <?php echo gettext("SSL data searches for irregularities during SSL protocol exchange. Default is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?> </td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> <?php echo gettext("Sensitive Data"); ?></td> <td width="78%" class="vtable"> <input name="sensitive_data" type="checkbox" value="on" - <?php if ($pconfig['sensitive_data']=="on") echo "checked"; ?> + <?php if ($pconfig['sensitive_data'] == "on") + echo "checked"; + elseif ($vrt_enabled == "off") + echo "disabled"; + ?> onClick="enable_change(false)"><br> - <?php echo gettext("Sensitive data searches for credit card or Social Security numbers in data"); ?> + <?php echo gettext("Sensitive data searches for credit card or Social Security numbers and e-mail addresses in data."); ?><br/> + <span class="red"><strong><?php echo gettext("Note: "); ?></strong></span><?php echo gettext("To enable this preprocessor, you must select the Snort VRT rules on the Global Settings tab."); ?> </td> </tr> <tr> @@ -507,7 +639,8 @@ include_once("head.inc"); <td width="22%" valign="top"> </td> <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> <br> - <?php echo gettext("Please save your settings before you click Start."); ?> </td> + <?php echo gettext("Please save your settings before you click Start. Preprocessor changes will rebuild the rules file. "); ?> + </br><?php echo gettext("This may take several seconds. Snort must also be restarted to activate any changes made on this screen."); ?></td> </tr> </table> </td></tr></table> diff --git a/config/snort/snort_rules.php b/config/snort/snort_rules.php index 7457632d..46c3c264 100755 --- a/config/snort/snort_rules.php +++ b/config/snort/snort_rules.php @@ -33,7 +33,7 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g, $flowbit_rules_file; +global $g, $flowbit_rules_file, $rebuild_rules; $snortdir = SNORTDIR; $rules_map = array(); @@ -92,6 +92,11 @@ if (empty($categories[0]) && ($currentruleset != "custom.rules")) { $currentruleset = "custom.rules"; } +/* One last sanity check -- if the rules directory is empty, default to loading custom rules */ +$tmp = glob("{$snortdir}/rules/*.rules"); +if (empty($tmp)) + $currentruleset = "custom.rules"; + $ruledir = "{$snortdir}/rules"; $rulefile = "{$ruledir}/{$currentruleset}"; if ($currentruleset != 'custom.rules') { @@ -100,7 +105,7 @@ if ($currentruleset != 'custom.rules') { if (substr($currentruleset, 0, 10) == "IPS Policy") $rules_map = snort_load_vrt_policy($a_rule[$id]['ips_policy']); elseif (!file_exists($rulefile)) - $input_errors[] = "{$currentruleset} seems to be missing!!! Please go to the Category tab and save the rule set again to regenerate it."; + $input_errors[] = gettext("{$currentruleset} seems to be missing!!! Please verify rules files have been downloaded, then go to the Categories tab and save the rule set again."); else $rules_map = snort_load_rules_map($rulefile); } @@ -207,10 +212,22 @@ if ($_GET['act'] == "resetall" && !empty($rules_map)) { exit; } +if ($_POST['clear']) { + unset($a_rule[$id]['customrules']); + write_config(); + $rebuild_rules = "on"; + snort_generate_conf($a_rule[$id]); + $rebuild_rules = "off"; + header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); + exit; +} + if ($_POST['customrules']) { $a_rule[$id]['customrules'] = base64_encode($_POST['customrules']); write_config(); - sync_snort_package_config(); + $rebuild_rules = "on"; + snort_generate_conf($a_rule[$id]); + $rebuild_rules = "off"; $output = ""; $retcode = ""; exec("snort -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -T 2>&1", $output, $retcode); @@ -221,11 +238,31 @@ if ($_POST['customrules']) { for($i = $start; $i > $end; $i--) $error .= $output[$i]; $input_errors[] = "Custom rules have errors:\n {$error}"; - } else { + } + else { header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); exit; } -} else if ($_POST) { +} + +else if ($_POST['apply']) { + + /* Save new configuration */ + write_config(); + + /*************************************************/ + /* Update the snort conf file and rebuild the */ + /* rules for this interface. */ + /*************************************************/ + $rebuild_rules = "on"; + snort_generate_conf($a_rule[$id]); + $rebuild_rules = "off"; + + /* Return to this same page */ + header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); + exit; +} +else if($_POST) { unset($a_rule[$id]['customrules']); write_config(); header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); @@ -274,6 +311,22 @@ function popup(url) if (window.focus) {newwin.focus()} return false; } + +function wopen(url, name, w, h) +{ +// Fudge factors for window decoration space. +// In my tests these work well on all platforms & browsers. +w += 32; +h += 96; + var win = window.open(url, + name, + 'width=' + w + ', height=' + h + ', ' + + 'location=no, menubar=no, ' + + 'status=no, toolbar=no, scrollbars=yes, resizable=yes'); + win.resizeTo(w, h); + win.focus(); +} + </script> <form action="/snort/snort_rules.php" method="post" name="iform" id="iform"> @@ -346,24 +399,30 @@ function popup(url) <input type='hidden' name='openruleset' value='custom.rules'> <input type='hidden' name='id' value='<?=$id;?>'> - <textarea wrap="on" cols="85" rows="40" name="customrules"><?=$pconfig['customrules'];?></textarea> + <textarea wrap="soft" cols="85" rows="40" name="customrules"><?=$pconfig['customrules'];?></textarea> </td> <td width="3%" class="list"> </td> </tr> <tr> + <td colspan="9"> </td> + </tr> + <tr> <td width="3%" class="list"> </td> - <td colspan="7" class="vtable"> - <input name="Submit" type="submit" class="formbtn" value="Save"> - <input type="button" class="formbtn" value="Cancel" onclick="history.back()"> + <td colspan="7"> + <input name="Submit" type="submit" class="formbtn" value=" Save "> + <input type="button" class="formbtn" value="Cancel" onclick="history.back()"> + <input name="clear" type="submit" class="formbtn" id="clear" value="Clear" onclick="return confirm('Do you really want to erase all custom rules?')"> </td> <td width="3%" class="list"> </td> </tr> <?php else: ?> <tr> <td width="3%" class="list"> </td> - <td colspan="7" class="listhdr" > </td> + <td colspan="7" class="listhdr" ><input type="submit" name="apply" id="apply" value="Apply Changes" class="formbtn"> + <?php echo gettext("Click to rebuild the rules with your changes. Snort must be restarted to use the new rules."); ?> + <input type='hidden' name='id' value='<?=$id;?>'></td> <td width="3%" align="center" valign="middle" class="listt"><a href="javascript: void(0)" - onclick="popup('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$currentruleset;?>')"> + onclick="wopen('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$currentruleset;?>','FileViewer',800,600)"> <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_service_restart.gif" <?php echo "onmouseover='this.src=\"../themes/{$g['theme']}/images/icons/icon_services_restart_mo.gif\"' onmouseout='this.src=\"../themes/{$g['theme']}/images/icons/icon_service_restart.gif\"' ";?> @@ -448,8 +507,8 @@ function popup(url) ?> <td width="3%" align="center" valign="middle" nowrap class="listt"> <a href="javascript: void(0)" - onclick="popup('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$currentruleset;?>&ids=<?=$sid;?>&gid=<?=$gid;?>')"><img - src="../themes/<?= $g['theme']; ?>/images/icons/icon_right.gif" + onclick="wopen('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$currentruleset;?>&ids=<?=$sid;?>&gid=<?=$gid;?>','FileViewer',800,600)"><img + src="../themes/<?= $g['theme']; ?>/images/icons/icon_right.gif" title="<?php echo gettext("Click to view rule"); ?>" width="17" height="17" border="0"></a> <!-- Codes by Quackit.com --> </td> diff --git a/config/snort/snort_rules_edit.php b/config/snort/snort_rules_edit.php index ab1a24b2..a1f45c07 100755 --- a/config/snort/snort_rules_edit.php +++ b/config/snort/snort_rules_edit.php @@ -62,6 +62,7 @@ $if_real = snort_get_real_interface($pconfig['interface']); $snort_uuid = $a_rule[$id]['uuid']; $file = $_GET['openruleset']; $contents = ''; +$wrap_flag = "off"; // Read the contents of the argument passed to us. // It may be an IPS policy string, an individual SID, @@ -69,8 +70,10 @@ $contents = ''; // Test for the special case of an IPS Policy file. if (substr($file, 0, 10) == "IPS Policy") { $rules_map = snort_load_vrt_policy($a_rule[$id]['ips_policy']); - if (isset($_GET['ids'])) + if (isset($_GET['ids'])) { $contents = $rules_map[$_GET['gid']][trim($_GET['ids'])]['rule']; + $wrap_flag = "soft"; + } else { $contents = "# Snort IPS Policy - " . ucfirst($a_rule[$id]['ips_policy']) . "\n\n"; foreach (array_keys($rules_map) as $k1) { @@ -86,6 +89,7 @@ if (substr($file, 0, 10) == "IPS Policy") { elseif (isset($_GET['ids'])) { $rules_map = snort_load_rules_map("{$snortdir}/rules/{$file}"); $contents = $rules_map[$_GET['gid']][trim($_GET['ids'])]['rule']; + $wrap_flag = "soft"; } // Is it our special flowbit rules file? elseif ($file == $flowbit_rules_file) @@ -102,14 +106,14 @@ else { exit; } -$pgtitle = array(gettext("Advanced"), gettext("File Viewer")); +$pgtitle = array(gettext("Snort"), gettext("File Viewer")); ?> <?php include("head.inc");?> <body link="#000000" vlink="#000000" alink="#000000"> <?php if ($savemsg) print_info_box($savemsg); ?> -<?php include("fbegin.inc");?> +<?php // include("fbegin.inc");?> <form action="snort_rules_edit.php" method="post"> <table width="100%" border="0" cellpadding="0" cellspacing="0"> @@ -117,14 +121,20 @@ $pgtitle = array(gettext("Advanced"), gettext("File Viewer")); <td class="tabcont"> <table width="100%" cellpadding="0" cellspacing="6" bgcolor="#eeeeee"> <tr> - <td> + <td class="pgtitle" colspan="2">Snort: Rules Viewer</td> + </tr> + <tr> + <td width="20%"> <input type="button" class="formbtn" value="Return" onclick="window.close()"> </td> + <td align="right"> + <b><?php echo gettext("Rules File: ") . '</b> ' . $file; ?> + </td> </tr> <tr> - <td valign="top" class="label"> - <div style="background: #eeeeee;" id="textareaitem"><!-- NOTE: The opening *and* the closing textarea tag must be on the same line. --> - <textarea wrap="off" rows="33" cols="90" name="code2"><?=$contents;?></textarea> + <td valign="top" class="label" colspan="2"> + <div style="background: #eeeeee; width:100%; height:100%;" id="textareaitem"><!-- NOTE: The opening *and* the closing textarea tag must be on the same line. --> + <textarea style="width:100%; height:100%;" wrap="<?=$wrap_flag?>" rows="33" cols="80" name="code2"><?=$contents;?></textarea> </div> </td> </tr> @@ -133,6 +143,6 @@ $pgtitle = array(gettext("Advanced"), gettext("File Viewer")); </tr> </table> </form> -<?php include("fend.inc");?> +<?php // include("fend.inc");?> </body> </html> diff --git a/config/snort/snort_rulesets.php b/config/snort/snort_rulesets.php index 23a24bea..64998810 100755 --- a/config/snort/snort_rulesets.php +++ b/config/snort/snort_rulesets.php @@ -32,7 +32,7 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g, $flowbit_rules_file; +global $g, $flowbit_rules_file, $rebuild_rules; $snortdir = SNORTDIR; @@ -62,13 +62,30 @@ $if_real = snort_get_real_interface($pconfig['interface']); $snort_uuid = $a_nat[$id]['uuid']; $snortdownload = $config['installedpackages']['snortglobal']['snortdownload']; $emergingdownload = $config['installedpackages']['snortglobal']['emergingthreats']; +$snortcommunitydownload = $config['installedpackages']['snortglobal']['snortcommunityrules']; + +$no_emerging_files = false; +$no_snort_files = false; +$no_community_files = false; + +/* Test rule categories currently downloaded to $SNORTDIR/rules and set appropriate flags */ +$test = glob("{$snortdir}/rules/emerging-*.rules"); +if (empty($test)) + $no_emerging_files = true; +$test = glob("{$snortdir}/rules/snort_*.rules"); +if (empty($test)) + $no_snort_files = true; +if (!file_exists("{$snortdir}/rules/GPLv2_community.rules")) + $no_community_files = true; if (($snortdownload == 'off') || ($a_nat[$id]['ips_policy_enable'] != 'on')) $policy_select_disable = "disabled"; if ($a_nat[$id]['autoflowbitrules'] == 'on') { - if (file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}")) + if (file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}") && + filesize("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}") > 0) { $btn_view_flowb_rules = ""; + } else $btn_view_flowb_rules = " disabled"; } @@ -119,7 +136,14 @@ if ($_POST["Submit"]) { } write_config(); - sync_snort_package_config(); + + /*************************************************/ + /* Update the snort conf file and rebuild the */ + /* rules for this interface. */ + /*************************************************/ + $rebuild_rules = "on"; + snort_generate_conf($a_nat[$id]); + $rebuild_rules = "off"; header("Location: /snort/snort_rulesets.php?id=$id"); exit; @@ -142,6 +166,11 @@ if ($_POST['selectall']) { foreach ($files as $file) $rulesets[] = basename($file); } + if ($snortcommunitydownload == 'on') { + $files = glob("{$snortdir}/rules/sc_*.rules"); + foreach ($files as $file) + $rulesets[] = basename($file); + } if ($snortdownload == 'on') { $files = glob("{$snortdir}/rules/snort*.rules"); foreach ($files as $file) @@ -193,6 +222,22 @@ function popup(url) if (window.focus) {newwin.focus()} return false; } + +function wopen(url, name, w, h) +{ +// Fudge factors for window decoration space. +// In my tests these work well on all platforms & browsers. +w += 32; +h += 96; + var win = window.open(url, + name, + 'width=' + w + ', height=' + h + ', ' + + 'location=no, menubar=no, ' + + 'status=no, toolbar=no, scrollbars=yes, resizable=yes'); + win.resizeTo(w, h); + win.focus(); +} + function enable_change() { var endis = !(document.iform.ips_policy_enable.checked); @@ -233,12 +278,15 @@ function enable_change() $iscfgdirempty = array(); if (file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/custom.rules")) $iscfgdirempty = (array)("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/custom.rules"); - if (empty($isrulesfolderempty) && empty($iscfgdirempty)): + if (empty($isrulesfolderempty)): ?> <tr> - <td> - <?php printf(gettext("# The rules directory is empty. %s/rules"), $snortdir); ?> <br/> - <?php echo gettext("Please go to the Updates tab to download/fetch the rules configured."); ?> + <td class="vexpl"><br/> + <?php printf(gettext("# The rules directory is empty: %s%s/rules%s"), '<strong>',$snortdir,'</strong>'); ?> <br/><br/> + <?php echo gettext("Please go to the ") . '<a href="snort_download_updates.php"><strong>' . gettext("Updates") . + '</strong></a>' . gettext(" tab to download the rules configured on the ") . + '<a href="snort_interfaces_global.php"><strong>' . gettext("Global") . + '</strong></a>' . gettext(" tab."); ?> </td> </tr> <?php else: @@ -258,28 +306,31 @@ function enable_change() </tr> <tr> <td colspan="6" valign="center" class="listn"> - <table width="100%" border="0" cellpadding="0" cellspacing="0"> + <table width="100%" border="0" cellpadding="2" cellspacing="2"> <tr> <td width="15%" class="listn"><?php echo gettext("Resolve Flowbits"); ?></td> - <td width="85%"><input name="autoflowbits" id="autoflowbitrules" type="checkbox" value="on" <?php if ($a_nat[$id]['autoflowbitrules'] == "on") echo "checked"; ?>/></td> + <td width="85%"><input name="autoflowbits" id="autoflowbitrules" type="checkbox" value="on" + <?php if ($a_nat[$id]['autoflowbitrules'] == "on" || empty($a_nat[$id]['autoflowbitrules'])) echo "checked"; ?>/> + <span class="vexpl"><?php echo gettext("If checked, Snort will auto-enable rules required for checked flowbits. "); + echo gettext("The Default is "); ?><strong><?php echo gettext("Checked."); ?></strong></span></td> </tr> <tr> <td width="15%" class="vncell"> </td> <td width="85%" class="vtable"> - <?php echo gettext("If ticked, Snort will examine the enabled rules in your chosen " . + <?php echo gettext("Snort will examine the enabled rules in your chosen " . "rule categories for checked flowbits. Any rules that set these dependent flowbits will " . - "be automatically enabled and added to the list of files in the interface rules directory."); ?><br/><br/></td> + "be automatically enabled and added to the list of files in the interface rules directory."); ?><br/></td> </tr> <tr> <td width="15%" class="listn"><?php echo gettext("Auto Flowbit Rules"); ?></td> - <td width="85%"><input type="button" class="formbtn" value="View" onclick="popup('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$flowbit_rules_file;?>')" <?php echo $btn_view_flowb_rules; ?>/></td> + <td width="85%"><input type="button" class="formbtn" value="View" onclick="wopen('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$flowbit_rules_file;?>','FileViewer',800,600)" <?php echo $btn_view_flowb_rules; ?>/> + <span class="vexpl"><?php echo gettext("Click to view auto-enabled rules required to satisfy flowbit dependencies"); ?></span></td> </tr> <tr> <td width="15%"> </td> <td width="85%"> - <?php echo gettext("Click to view auto-enabled rules required to satisfy flowbit " . - "dependencies from the selected rule categories below. Auto-enabled rules generating unwanted alerts " . - "should have their GID:SID added to the Suppression List for the interface."); ?><br/><br/></td> + <?php printf(gettext("%sNote: %sAuto-enabled rules generating unwanted alerts should have their GID:SID added to the Suppression List for the interface."), '<span class="red"><strong>', '</strong></span>'); ?> + <br/></td> </tr> </table> </td> @@ -289,20 +340,20 @@ function enable_change() </tr> <tr> <td colspan="6" valign="center" class="listn"> - <table width="100%" border="0" cellpadding="0" cellspacing="0"> + <table width="100%" border="0" cellpadding="2" cellspacing="2"> <tr> <td width="15%" class="listn"><?php echo gettext("Use IPS Policy"); ?></td> <td width="85%"><input name="ips_policy_enable" id="ips_policy_enable" type="checkbox" value="on" <?php if ($a_nat[$id]['ips_policy_enable'] == "on") echo "checked"; ?> - <?php if ($snortdownload == "off") echo "disabled" ?> onClick="enable_change()"/></td> + <?php if ($snortdownload == "off") echo "disabled" ?> onClick="enable_change()"/> <span class="vexpl"> + <?php echo gettext("If checked, Snort will use rules from the pre-defined IPS policy selected below."); ?></span></td> </tr> <tr> <td width="15%" class="vncell"> </td> <td width="85%" class="vtable"> - <?php echo gettext("If ticked, Snort will use rules from the pre-defined IPS policy " . - "selected below. You must be using the Snort VRT rules to use this option."); ?><br/> + <?php printf(gettext("%sNote:%s You must be using the Snort VRT rules to use this option."),'<span class="red"><strong>','</strong></span>'); ?> <?php echo gettext("Selecting this option disables manual selection of Snort VRT categories in the list below, " . "although Emerging Threats categories may still be selected if enabled on the Global Settings tab. " . - "These will be added to the pre-defined Snort IPS policy rules from the Snort VRT."); ?><br><br/></td> + "These will be added to the pre-defined Snort IPS policy rules from the Snort VRT."); ?><br/></td> </tr> <tr> <td width="15%" class="listn"><?php echo gettext("IPS Policy"); ?></td> @@ -311,15 +362,16 @@ function enable_change() <option value="balanced" <?php if ($pconfig['ips_policy'] == "balanced") echo "selected"; ?>><?php echo gettext("Balanced"); ?></option> <option value="security" <?php if ($pconfig['ips_policy'] == "security") echo "selected"; ?>><?php echo gettext("Security"); ?></option> </select> - </td> + <span class="vexpl"><?php echo gettext("Snort IPS policies are: Connectivity, Balanced or Security."); ?></span></td> </tr> <tr> <td width="15%"> </td> <td width="85%"> - <?php echo gettext("Snort IPS policies are: Connectivity, Balanced or Security. " . - "Connectivity blocks most major threats with few or no false positives. Balanced is a good starter policy. It " . - "is speedy, has good base coverage level, and covers most threats of the day. It includes all rules in Connectivity. " . - "Security is a stringent policy. It contains everything in the first two plus policy-type rules such as Flash in an Excel file."); ?><br/><br/></td> + <?php echo gettext("Connectivity blocks most major threats with few or no false positives. " . + "Balanced is a good starter policy. It is speedy, has good base coverage level, and covers " . + "most threats of the day. It includes all rules in Connectivity." . + "Security is a stringent policy. It contains everything in the first two " . + "plus policy-type rules such as Flash in an Excel file."); ?><br/></td> </tr> </table> </td> @@ -327,27 +379,75 @@ function enable_change() <tr> <td colspan="6" class="listtopic"><?php echo gettext("Check the rulesets that you would like Snort to load at startup."); ?><br/></td> </tr> + <tr> <td colspan="6"> </td> </tr> + <tr> + <td colspan="6"> + <table width=100% border="0" cellpadding="2" cellspacing="2"> + <tr> + <td valign="middle"><input value="Select All" type="submit" name="selectall" id="selectall" /></td> + <td valign="middle"><input value="Unselect All" type="submit" name="unselectall" id="selectall" /></td> + <td valign="middle"><input value="Save" class="formbtn" type="submit" name="Submit" id="Submit" /></td> + <td valign="middle"><span class="vexpl"><?php echo gettext("Click to save changes and auto-resolve flowbit rules (if option is selected above)"); ?></span></td> + </tr> + </table> + </tr> <tr> - <td colspan="1" align="middle" valign="center"><br/><input value="Select All" type="submit" name="selectall" id="selectall" /><br/></td> - <td colspan="1" align="middle" valign="center"><br/><input value="Unselect All" type="submit" name="unselectall" id="selectall" /><br/></td> - <td colspan="1" align="middle" valign="center"><br/><input value="Save" class="formbtn" type="submit" name="Submit" id="Submit" /></td> - <td colspan="3" valign="center"><?php echo gettext("Click to save changes and auto-resolve flowbit rules (if option is selected above)"); ?><br/></td> + <td colspan="6"> </td> </tr> - <tr> <td colspan="6"> </td> </tr> + + <?php if ($no_community_files) + $msg_community = "NOTE: Snort Community Rules have not been downloaded. Perform a Rules Update to enable them."; + else + $msg_community = "Snort GPLv2 Community Rules (VRT certified)"; + ?> + <?php if ($snortcommunitydownload == 'on'): ?> + <tr id="frheader"> + <td width="5%" class="listhdrr"><?php echo gettext("Enabled"); ?></td> + <td colspan="5" class="listhdrr"><?php echo gettext('Ruleset: Snort GPLv2 Community Rules');?></td> + </tr> + <?php if (in_array("GPLv2_community.rules", $enabled_rulesets_array)): ?> + <tr> + <td width="5" class="listr" align="center" valign="top"> + <input type="checkbox" name="toenable[]" value="GPLv2_community.rules" checked="checked"/></td> + <td colspan="5" class="listr"><a href='snort_rules.php?id=<?=$id;?>&openruleset=GPLv2_community.rules'><?php echo gettext("{$msg_community}"); ?></a></td> + </tr> + <?php else: ?> + <tr> + <td width="5" class="listr" align="center" valign="top"> + <input type="checkbox" name="toenable[]" value="GPLv2_community.rules" <?php if ($snortcommunitydownload == 'off') echo "disabled"; ?>/></td> + <td colspan="5" class="listr"><?php echo gettext("{$msg_community}"); ?></td> + </tr> + + <?php endif; ?> + <?php else: ?> + <tr> + <td colspan="6"> </td> + </tr> + <?php endif; ?> + + <?php if ($no_emerging_files) + $msg_emerging = "downloaded."; + else + $msg_emerging = "enabled."; + if ($no_snort_files) + $msg_snort = "downloaded."; + else + $msg_snort = "enabled."; + ?> <tr id="frheader"> - <?php if ($emergingdownload == 'on'): ?> - <td width="5%" class="listhdrr"><?php echo gettext("Enabled"); ?></td> + <?php if ($emergingdownload == 'on' && !$no_emerging_files): ?> + <td width="5%" class="listhdrr" align="center"><?php echo gettext("Enabled"); ?></td> <td width="25%" class="listhdrr"><?php echo gettext('Ruleset: Emerging Threats');?></td> <?php else: ?> - <td colspan="2" width="30%" class="listhdrr"><?php echo gettext("Emerging rules have not been enabled"); ?></td> + <td colspan="2" align="center" width="30%" class="listhdrr"><?php echo gettext("Emerging Threats rules not {$msg_emerging}"); ?></td> <?php endif; ?> - <?php if ($snortdownload == 'on'): ?> - <td width="5%" class="listhdrr"><?php echo gettext("Enabled"); ?></td> - <td width="25%" class="listhdrr"><?php echo gettext('Ruleset: Snort');?></td> - <td width="5%" class="listhdrr"><?php echo gettext("Enabled"); ?></td> - <td width="25%" class="listhdrr"><?php echo gettext('Ruleset: Snort SO');?></td> + <?php if ($snortdownload == 'on' && !$no_snort_files): ?> + <td width="5%" class="listhdrr" align="center"><?php echo gettext("Enabled"); ?></td> + <td width="25%" class="listhdrr"><?php echo gettext('Ruleset: Snort Text Rules');?></td> + <td width="5%" class="listhdrr" align="center"><?php echo gettext("Enabled"); ?></td> + <td width="25%" class="listhdrr"><?php echo gettext('Ruleset: Snort SO Rules');?></td> <?php else: ?> - <td colspan="2" width="60%" class="listhdrr"><?php echo gettext("Snort rules have not been enabled"); ?></td> + <td colspan="4" align="center" width="60%" class="listhdrr"><?php echo gettext("Snort VRT rules have not been {$msg_snort}"); ?></td> <?php endif; ?> </tr> <?php diff --git a/config/squid-reverse/squid.inc b/config/squid-reverse/squid.inc index fef9590c..0256d078 100644 --- a/config/squid-reverse/squid.inc +++ b/config/squid-reverse/squid.inc @@ -5,7 +5,7 @@ Copyright (C) 2006-2009 Scott Ullrich Copyright (C) 2006 Fernando Lemos Copyright (C) 2012 Martin Fuchs - Copyright (C) 2012 Marcello Coutinho + Copyright (C) 2012-2013 Marcello Coutinho Copyright (C) 2013 Gekkenhuis All rights reserved. @@ -225,6 +225,20 @@ function squid_install_command() { $config['installedpackages']['squidnac']['config'][0]['blacklist'] = $settingsnac['blacklist']; } } + + if(! empty($settingsnac['block_user_agent'])) { + if(strstr($settingsnac['block_user_agent'], ",")) { + $settingsnac['block_user_agent'] = base64_encode(implode("\n", explode(",", $settingsnac['block_user_agent']))); + $config['installedpackages']['squidnac']['config'][0]['block_user_agent'] = $settingsnac['block_user_agent']; + } + } + + if(! empty($settingsnac['block_reply_mime_type'])) { + if(strstr($settingsnac['block_reply_mime_type'], ",")) { + $settingsnac['block_reply_mime_type'] = base64_encode(implode("\n", explode(",", $settingsnac['block_reply_mime_type']))); + $config['installedpackages']['squidnac']['config'][0]['block_reply_mime_type'] = $settingsnac['block_reply_mime_type']; + } + } /*Migrate reverse settings*/ if (is_array($config['installedpackages']['squidreverse'])){ @@ -1078,6 +1092,8 @@ EOD; 'banned_hosts' => 'src', 'whitelist' => 'dstdom_regex -i', 'blacklist' => 'dstdom_regex -i', + 'block_user_agent' => 'browser -i', + 'block_reply_mime_type' => 'rep_mime_type -i', ); foreach ($options as $option => $directive) { $contents = sq_text_area_decode($settings[$option]); @@ -1291,6 +1307,18 @@ function squid_resync_auth() { $conf .= "http_access deny blacklist\n"; } } + if(! empty($settingsnac['block_user_agent'])) { + if (squid_is_valid_acl('block_user_agent')) { + $conf .= "# Block access with user agents and browsers\n"; + $conf .= "http_access deny block_user_agent\n"; + } + } + if(! empty($settingsnac['block_reply_mime_type'])) { + if (squid_is_valid_acl('block_reply_mime_type')) { + $conf .= "# Block access with mime type in the reply\n"; + $conf .= "http_reply_access deny block_reply_mime_type\n"; + } + } $transparent_proxy = ($settingsconfig['transparent_proxy'] == 'on'); $auth_method = (($settings['auth_method'] && !$transparent_proxy) ? $settings['auth_method'] : 'none'); @@ -1823,27 +1851,54 @@ EOD; /* Uses XMLRPC to synchronize the changes to a remote node */ function squid_sync_on_changes() { global $config, $g; - - log_error("[squid] xmlrpc sync is starting."); - $synconchanges = $config['installedpackages']['squidsync']['config'][0]['synconchanges']; - if(!$synconchanges) - return; - foreach ($config['installedpackages']['squidsync']['config'] as $rs ){ - foreach($rs['row'] as $sh){ - $sync_to_ip = $sh['ipaddress']; - $password = $sh['password']; - if($sh['username']) - $username = $sh['username']; - else - $username = 'admin'; - if($password && $sync_to_ip) - squid_do_xmlrpc_sync($sync_to_ip, $username, $password); + if (is_array($config['installedpackages']['squidsync']['config'])){ + $squid_sync=$config['installedpackages']['squidsync']['config'][0]; + $synconchanges = $squid_sync['synconchanges']; + $synctimeout = $squid_sync['synctimeout']; + switch ($synconchanges){ + case "manual": + if (is_array($squid_sync[row])){ + $rs=$squid_sync[row]; + } + else{ + log_error("[squid] xmlrpc sync is enabled but there is no hosts to push on squid config."); + return; + } + break; + case "auto": + if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){ + $system_carp=$config['installedpackages']['carpsettings']['config'][0]; + $rs[0]['ipaddress']=$system_carp['synchronizetoip']; + $rs[0]['username']=$system_carp['username']; + $rs[0]['password']=$system_carp['password']; + } + else{ + log_error("[squid] xmlrpc sync is enabled but there is no system backup hosts to push squid config."); + return; + } + break; + default: + return; + break; + } + if (is_array($rs)){ + log_error("[squid] xmlrpc sync is starting."); + foreach($rs as $sh){ + $sync_to_ip = $sh['ipaddress']; + $password = $sh['password']; + if($sh['username']) + $username = $sh['username']; + else + $username = 'admin'; + if($password && $sync_to_ip) + squid_do_xmlrpc_sync($sync_to_ip, $username, $password,$synctimeout); + } + log_error("[squid] xmlrpc sync is ending."); } - } - log_error("[squid] xmlrpc sync is ending."); + } } /* Do the actual XMLRPC sync */ -function squid_do_xmlrpc_sync($sync_to_ip, $username, $password) { +function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) { global $config, $g; if(!$username) @@ -1855,6 +1910,10 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password) { if(!$sync_to_ip) return; + if(!$synctimeout) + $synctimeout=250; + + $xmlrpc_sync_neighbor = $sync_to_ip; if($config['system']['webgui']['protocol'] != "") { $synchronizetoip = $config['system']['webgui']['protocol']; @@ -1897,15 +1956,15 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password) { $cli->setCredentials($username, $password); if($g['debug']) $cli->setDebug(1); - /* send our XMLRPC message and timeout after 250 seconds */ - $resp = $cli->send($msg, "250"); + /* send our XMLRPC message and timeout after defined sync timeout value*/ + $resp = $cli->send($msg, $synctimeout); if(!$resp) { $error = "A communications error occurred while attempting squid XMLRPC sync with {$url}:{$port}."; log_error($error); file_notice("sync_settings", $error, "squid Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); - $resp = $cli->send($msg, "250"); + $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting squid XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "squid Settings Sync", ""); @@ -1927,14 +1986,14 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password) { $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); $cli->setCredentials($username, $password); - $resp = $cli->send($msg, "250"); + $resp = $cli->send($msg, $synctimeout); if(!$resp) { $error = "A communications error occurred while attempting squid XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; log_error($error); file_notice("sync_settings", $error, "squid Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); - $resp = $cli->send($msg, "250"); + $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting squid XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "squid Settings Sync", ""); @@ -1943,5 +2002,4 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password) { } } - ?> diff --git a/config/squid-reverse/squid_nac.xml b/config/squid-reverse/squid_nac.xml index bc4a278e..659d626f 100644 --- a/config/squid-reverse/squid_nac.xml +++ b/config/squid-reverse/squid_nac.xml @@ -139,6 +139,24 @@ <encoding>base64</encoding> </field> <field> + <fielddescr>Block user agents</fielddescr> + <fieldname>block_user_agent</fieldname> + <description>Enter each user agent on a new line that will be blocked to the users that are allowed to use the proxy. You also can use regular expressions.</description> + <type>textarea</type> + <cols>50</cols> + <rows>5</rows> + <encoding>base64</encoding> + </field> + <field> + <fielddescr>Block MIME types (reply only)</fielddescr> + <fieldname>block_reply_mime_type</fieldname> + <description>Enter each MIME type on a new line that will be blocked to the users that are allowed to use the proxy. You also can use regular expressions. Useful to block javascript (application/x-javascript).</description> + <type>textarea</type> + <cols>50</cols> + <rows>5</rows> + <encoding>base64</encoding> + </field> + <field> <name>Squid Allowed ports</name> <type>listtopic</type> </field> diff --git a/config/squid-reverse/squid_reverse_sync.xml b/config/squid-reverse/squid_reverse_sync.xml index db5e6145..041576b8 100755 --- a/config/squid-reverse/squid_reverse_sync.xml +++ b/config/squid-reverse/squid_reverse_sync.xml @@ -9,7 +9,7 @@ /* squid_sync.xml part of the sarg package for pfSense - Copyright (C) 2012 Marcello Coutinho + Copyright (C) 2012-2013 Marcello Coutinho All rights reserved. */ /* ========================================================================== */ @@ -17,7 +17,7 @@ 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, + 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 @@ -80,8 +80,30 @@ <field> <fielddescr>Automatically sync squid configuration changes</fielddescr> <fieldname>synconchanges</fieldname> - <description>Automatically sync squid(normal and reverse) changes to the hosts defined below.</description> - <type>checkbox</type> + <description>Select a sync method for squid.</description> + <type>select</type> + <required/> + <default_value>auto</default_value> + <options> + <option><name>Sync to configured system backup server</name><value>auto</value></option> + <option><name>Sync to host(s) defined below</name><value>manual</value></option> + <option><name>Do not sync this package configuration</name><value>disabled</value></option> + </options> + </field> + <field> + <fielddescr>Sync timeout</fielddescr> + <fieldname>synctimeout</fieldname> + <description>Select sync max wait time</description> + <type>select</type> + <required/> + <default_value>250</default_value> + <options> + <option><name>250 seconds(Default)</name><value>250</value></option> + <option><name>120 seconds</name><value>120</value></option> + <option><name>90 seconds</name><value>90</value></option> + <option><name>60 seconds</name><value>60</value></option> + <option><name>30 seconds</name><value>30</value></option> + </options> </field> <field> <fielddescr>Remote Server</fielddescr> diff --git a/config/squid-reverse/squid_sync.xml b/config/squid-reverse/squid_sync.xml index 62a726f4..cdd91e78 100755 --- a/config/squid-reverse/squid_sync.xml +++ b/config/squid-reverse/squid_sync.xml @@ -9,7 +9,7 @@ /* squid_sync.xml part of the sarg package for pfSense - Copyright (C) 2012 Marcello Coutinho + Copyright (C) 2012-2013 Marcello Coutinho All rights reserved. */ /* ========================================================================== */ @@ -92,8 +92,30 @@ <field> <fielddescr>Automatically sync squid configuration changes</fielddescr> <fieldname>synconchanges</fieldname> - <description>Automatically sync squid(normal and reverse) changes to the hosts defined below.</description> - <type>checkbox</type> + <description>Select a sync method for squid.</description> + <type>select</type> + <required/> + <default_value>auto</default_value> + <options> + <option><name>Sync to configured system backup server</name><value>auto</value></option> + <option><name>Sync to host(s) defined below</name><value>manual</value></option> + <option><name>Do not sync this package configuration</name><value>disabled</value></option> + </options> + </field> + <field> + <fielddescr>Sync timeout</fielddescr> + <fieldname>synctimeout</fieldname> + <description>Select sync max wait time</description> + <type>select</type> + <required/> + <default_value>250</default_value> + <options> + <option><name>250 seconds(Default)</name><value>250</value></option> + <option><name>120 seconds</name><value>120</value></option> + <option><name>90 seconds</name><value>90</value></option> + <option><name>60 seconds</name><value>60</value></option> + <option><name>30 seconds</name><value>30</value></option> + </options> </field> <field> <fielddescr>Remote Server</fielddescr> diff --git a/config/squidGuard/squidguard_configurator.inc b/config/squidGuard/squidguard_configurator.inc index 81f9cd96..e57b7597 100644 --- a/config/squidGuard/squidguard_configurator.inc +++ b/config/squidGuard/squidguard_configurator.inc @@ -414,7 +414,6 @@ function squid_reconfigure($remove_only = '') global $squidguard_config; $conf = ''; $cust_opt = $config['installedpackages']['squid']['config'][0]['custom_options']; - # remove old options if (!empty($cust_opt)) { $conf = explode(";", $cust_opt); @@ -444,7 +443,7 @@ function squid_reconfigure($remove_only = '') if (is_array($conf)) $conf = implode(";", $conf); /* Only update squid options if we have something to do, otherwise this can interfere with squid's default options in a new install. */ - if (!empty($conf)) { + if ($conf != $cust_opt) { $config['installedpackages']['squid']['config'][0]['custom_options'] = $conf; write_config('Update redirector options to squid config.'); } diff --git a/config/systempatches/apply_patches.php b/config/systempatches/apply_patches.php new file mode 100644 index 00000000..3ac0d671 --- /dev/null +++ b/config/systempatches/apply_patches.php @@ -0,0 +1,11 @@ +#!/usr/local/bin/php +<?php +require_once("config.inc"); +require_once("patches.inc"); + +global $g, $config; + +echo "Applying patches..."; +bootup_apply_patches(); +echo "Done.\n"; +?>
\ No newline at end of file diff --git a/config/systempatches/patches.inc b/config/systempatches/patches.inc index 89610565..9b347620 100644 --- a/config/systempatches/patches.inc +++ b/config/systempatches/patches.inc @@ -29,11 +29,19 @@ require_once("globals.inc"); require_once("util.inc"); -$git_root_url = "http://github.com/bsdperimeter/pfsense/commit/"; +$git_root_url = "http://github.com/pfsense/pfsense/commit/"; $patch_suffix = ".patch"; $patch_dir = "/var/patches"; $patch_cmd = "/usr/bin/patch"; +function patch_package_install() { + patch_add_shellcmd(); +} + +function patch_package_deinstall() { + patch_remove_shellcmd(); +} + function patch_commit($patch, $action, $test=false, $fulldetail=false) { global $patch_dir, $patch_cmd, $patch_suffix; $directory = empty($patch['basedir']) ? "/" : $patch['basedir']; @@ -139,4 +147,55 @@ function is_github_url($url) { $urlbits = explode("/", $url); return (substr($urlbits[2], -10) == "github.com"); } -?>
\ No newline at end of file + +function bootup_apply_patches() { + global $config; + + $a_patches = &$config['installedpackages']['patches']['item']; + + foreach ($a_patches as $patch) { + /* Skip the patch if it should not be automatically applied. */ + if (!isset($patch['autoapply'])) + continue; + /* If the patch can be reverted it is already applied, so skip it. */ + if (!patch_test_revert($patch)) { + /* Only attempt to apply if it can be applied. */ + if (patch_test_apply($patch)) { + patch_apply($patch); + } + } + } +} + +function patch_add_shellcmd() { + global $config; + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (!is_array($a_earlyshellcmd)) + $a_earlyshellcmd = array(); + $found = false; + foreach ($a_earlyshellcmd as $idx => $cmd) + if (stristr($cmd, "apply_patches.php")) + $found = true; + if (!$found) { + $a_earlyshellcmd[] = "/usr/local/bin/php -f /usr/local/bin/apply_patches.php"; + write_config("System Patches package added a shellcmd"); + } +} + +function patch_remove_shellcmd() { + global $config; + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (!is_array($a_earlyshellcmd)) + $a_earlyshellcmd = array(); + $removed = false; + foreach ($a_earlyshellcmd as $idx => $cmd) { + if (stristr($cmd, "apply_patches.php")) { + unset($a_earlyshellcmd[$idx]); + $removed = true; + } + } + if ($removed) + write_config("System Patches package removed a shellcmd"); +} + +?> diff --git a/config/systempatches/system_patches.php b/config/systempatches/system_patches.php index 1dd6470b..70260e4b 100644 --- a/config/systempatches/system_patches.php +++ b/config/systempatches/system_patches.php @@ -179,11 +179,12 @@ include("head.inc"); <tr id="frheader"> <td width="5%" class="list"> </td> <td width="5%" class="listhdrr"><?=gettext("Description");?></td> -<td width="65%" class="listhdrr"><?=gettext("URL/ID");?></td> +<td width="60%" class="listhdrr"><?=gettext("URL/ID");?></td> <td width="5%" class="listhdrr"><?=gettext("Fetch");?></td> <td width="5%" class="listhdrr"><?=gettext("Test");?></td> <td width="5%" class="listhdrr"><?=gettext("Apply");?></td> <td width="5%" class="listhdr"><?=gettext("Revert");?></td> +<td width="5%" class="listhdr"><?=gettext("Auto Apply");?></td> <td width="5%" class="list"> <table border="0" cellspacing="0" cellpadding="1" summary="buttons"> <tr><td width="17"> @@ -242,6 +243,9 @@ foreach ($a_patches as $thispatch): <a href="system_patches.php?id=<?=$i;?>&act=revert"><?php echo gettext("Revert"); ?></a> <?php endif; ?> </td> + <td class="listr" onclick="fr_toggle(<?=$npatches;?>)" id="frd<?=$npatches;?>" ondblclick="document.location='system_patches_edit.php?id=<?=$npatches;?>';"> + <?= isset($thispatch['autoapply']) ? "Yes" : "No" ?> + </td> <td valign="middle" class="list" nowrap> <table border="0" cellspacing="0" cellpadding="1" summary="edit"> <tr> diff --git a/config/systempatches/system_patches_edit.php b/config/systempatches/system_patches_edit.php index 260a7300..5b30c9c5 100644 --- a/config/systempatches/system_patches_edit.php +++ b/config/systempatches/system_patches_edit.php @@ -127,6 +127,8 @@ if ($_POST) { } write_config(); + if ($thispatch['autoapply']) + patch_add_shellcmd(); header("Location: system_patches.php"); return; } @@ -165,7 +167,7 @@ include("head.inc"); <tr> <td width="22%" valign="top" class="vncell"><?=gettext("Patch Contents"); ?></td> <td width="78%" class="vtable"> - <textarea name="patch" class="" id="patch" rows="15" cols="70" wrap="off"><?=base64_decode($pconfig['patch']);?></textarea> + <textarea name="patch" class="" id="patch" rows="15" cols="70" wrap="off"><?=htmlspecialchars(base64_decode($pconfig['patch']));?></textarea> <br /> <span class="vexpl"><?=gettext("The contents of the patch. You can paste a patch here, or enter a URL/commit ID above, it can then be fetched into here automatically."); ?></span></td> </tr> <tr> @@ -192,7 +194,6 @@ include("head.inc"); <span class="vexpl"><?=gettext("Set this option to ignore whitespace in the patch."); ?></span> </td> </tr> -<!-- This isn't ready yet <tr> <td width="22%" valign="top" class="vncell"><?=gettext("Auto Apply"); ?></td> <td width="78%" class="vtable"> @@ -201,7 +202,6 @@ include("head.inc"); <span class="vexpl"><?=gettext("Set this option to apply the patch automatically when possible, useful for patches to survive after firmware updates."); ?></span> </td> </tr> ---> <tr> <td width="22%" valign="top"> </td> <td width="78%">Patch id: <?php echo $pconfig['uniqid']; ?></td> diff --git a/config/systempatches/systempatches.xml b/config/systempatches/systempatches.xml index 3802ba58..ea0eee78 100644 --- a/config/systempatches/systempatches.xml +++ b/config/systempatches/systempatches.xml @@ -40,8 +40,9 @@ <requirements>None</requirements> <faq>Applies patches supplied by the user to the firewall.</faq> <name>System Patches</name> - <version>0.5.1</version> + <version>0.8</version> <title>System: Patches</title> + <include_file>/usr/local/pkg/patches.inc</include_file> <menu> <name>Patches</name> <tooltiptext></tooltiptext> @@ -59,8 +60,19 @@ <item>http://www.pfsense.com/packages/config/systempatches/system_patches_edit.php</item> </additional_files_needed> <additional_files_needed> + <prefix>/usr/local/bin/</prefix> + <chmod>755</chmod> + <item>http://www.pfsense.com/packages/config/systempatches/apply_patches.php</item> + </additional_files_needed> + <additional_files_needed> <prefix>/usr/local/pkg/</prefix> <chmod>644</chmod> <item>http://www.pfsense.com/packages/config/systempatches/patches.inc</item> </additional_files_needed> + <custom_php_install_command> + patch_package_install(); + </custom_php_install_command> + <custom_php_deinstall_command> + patch_package_deinstall(); + </custom_php_deinstall_command> </packagegui>
\ No newline at end of file diff --git a/config/unbound/unbound.inc b/config/unbound/unbound.inc index 6588c5c2..c5cbfc49 100644 --- a/config/unbound/unbound.inc +++ b/config/unbound/unbound.inc @@ -23,6 +23,12 @@ POSSIBILITY OF SUCH DAMAGE. */ +// Define basedir constant for unbound according to FreeBSD version (PBI support or no PBI) +if (floatval(php_uname("r")) >= 8.3) + define("UNBOUND_BASE", "/usr/pbi/unbound-" . php_uname("m")); +else + define("UNBOUND_BASE", "/usr/local"); + if(!function_exists("is_service_running")) require_once("service-utils.inc"); @@ -40,34 +46,35 @@ function unbound_initial_setup() { // Make sure read-write conf_mount_rw(); - + if (!is_array($config['installedpackages']['unbound']['config'])) $config['installedpackages']['unbound']['config'] = array(); $unbound_config = &$config['installedpackages']['unbound']['config'][0]; // Ensure Unbound user exists - exec("/usr/sbin/pw useradd unbound"); + mwexec("/usr/sbin/pw useradd unbound", true); // Setup unbound // Create and chown dirs - mwexec("/bin/mkdir -p /usr/local/etc/unbound /usr/local/etc/unbound/dev"); - @chown("/usr/local/etc/unbound/.", "unbound"); - @chown("/usr/local/etc/unbound/dev.", "unbound"); + mwexec("/bin/mkdir -p " . UNBOUND_BASE . "/etc/unbound/dev"); + @chown(UNBOUND_BASE . "/etc/unbound/.", "unbound"); + @chown(UNBOUND_BASE . "/etc/unbound/dev.", "unbound"); // Touch needed files - @touch("/usr/local/etc/unbound/root.hints"); - @touch("/usr/local/etc/unbound/root-trust-anchor"); + @touch(UNBOUND_BASE . "/etc/unbound/root.hints"); + @touch(UNBOUND_BASE . "/etc/unbound/root-trust-anchor"); // Ensure files and folders belong to unbound - @chown("/usr/local/etc/unbound/root-trust-anchor", "unbound"); - @chgrp("/usr/local/etc/unbound/root-trust-anchor", "wheel"); - @chmod("/usr/local/etc/unbound/root-trust-anchor", 0600); + @chown(UNBOUND_BASE . "/etc/unbound/root-trust-anchor", "unbound"); + @chgrp(UNBOUND_BASE . "/etc/unbound/root-trust-anchor", "wheel"); + @chmod(UNBOUND_BASE . "/etc/unbound/root-trust-anchor", 0600); // We do not need the sample conf or the default rc.d startup file - @unlink_if_exists("/usr/local/etc/unbound/unbound.conf.sample"); + @unlink_if_exists(UNBOUND_BASE . "/etc/unbound/unbound.conf.sample"); + @unlink_if_exists(UNBOUND_BASE . "/etc/rc.d/unbound"); @unlink_if_exists("/usr/local/etc/rc.d/unbound"); - + // Setup rc file for startup and shutdown. unbound_rc_setup(); - + /* Check to see if Set initial interfaces that are allowed to query to lan, if that does not exist set it to the wan * */ @@ -77,34 +84,34 @@ function unbound_initial_setup() { else $unbound_config['active_interface'] = "wan"; } - + unbound_anchor_setup(); unbound_resync_config(); unbound_keys_setup(); - exec("/usr/sbin/chown -R unbound:wheel /usr/local/etc/unbound/*"); + exec("/usr/sbin/chown -R unbound:wheel " . UNBOUND_BASE . "/etc/unbound/*"); // Write out the XML config write_config(); - + // Back to read-only conf_mount_ro(); } function unbound_anchor_setup() { - + $conf = <<<EOD . IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 EOD; - file_put_contents("/usr/local/etc/unbound/root-trust-anchor", $conf); - + file_put_contents(UNBOUND_BASE . "/etc/unbound/root-trust-anchor", $conf); + } function unbound_keys_setup() { - + // Generate SSL Keys for controlling the unbound server - mwexec("/usr/local/sbin/unbound-control-setup"); + mwexec(UNBOUND_BASE . "/sbin/unbound-control-setup"); } @@ -148,25 +155,21 @@ ENDPHP\n"; } function unbound_install() { - - conf_mount_rw(); unbound_initial_setup(); - conf_mount_ro(); - } function unbound_control($action) { global $config, $g; - + $unbound_config = $config['installedpackages']['unbound']['config'][0]; $cache_dumpfile = "/var/tmp/unbound_cache"; - + switch ($action) { case "forward": /* Dont utilize forward cmd if Unbound is doing DNS queries directly * XXX: We could make this an option to then make pfSense use Unbound * as the recursive nameserver instead of upstream ones(?) - */ + */ if ($unbound_config['forwarding_mode'] == "on") { // Get configured DNS servers and add them as forwarders if (!isset($config['system']['dnsallowoverride'])) { @@ -182,7 +185,7 @@ function unbound_control($action) { $dns_servers .= " $nameserver"; } } - + if(is_service_running("unbound")) { unbound_ctl_exec("forward $dns_servers"); } else { @@ -192,7 +195,7 @@ function unbound_control($action) { } } break; - + case "start": //Start unbound if($unbound_config['unbound_status'] == "on") { @@ -203,28 +206,31 @@ function unbound_control($action) { @unlink("/var/run/dnsmasq.pid"); mwexec("/bin/ln -s /var/run/unbound.pid /var/run/dnsmasq.pid"); } + mwexec_bg("/usr/local/bin/unbound_monitor.sh"); fetch_root_hints(); } break; - + case "stop": //Stop unbound and unmount the file system if($unbound_config['unbound_status'] == "on") { - unbound_ctl_exec("stop"); + mwexec_bg("/usr/local/bin/unbound_monitor.sh stop"); + unbound_ctl_exec("stop"); } break; - + case "termstop": //Stop Unbound by sigkillbypid(); + mwexec_bg("/usr/local/bin/unbound_monitor.sh stop"); sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM"); break; - + case "dump_cache": //Dump Unbound's Cache if($unbound_config['dumpcache'] == "on") unbound_ctl_exec("dump_cache > $cache_dumpfile"); break; - + case "restore_cache": //Restore Unbound's Cache if ((is_service_running("unbound")) && ($unbound_config['dumpcache'] == "on")) { @@ -234,13 +240,13 @@ function unbound_control($action) { break; case "anchor_update": //Update the Root Trust Anchor - mwexec("/usr/local/sbin/unbound-anchor -a /usr/local/etc/unbound/root-trust-anchor", true); + mwexec(UNBOUND_BASE . "/sbin/unbound-anchor -a " . UNBOUND_BASE . "/etc/unbound/root-trust-anchor", true); break; default: break; - + } - + } function unbound_get_network_interface_addresses() { @@ -251,7 +257,7 @@ function unbound_get_network_interface_addresses() { $unboundint = explode(",", $unbound_config['active_interface']); $unbound_interfaces = array(); $i = 0; - + foreach ($unboundint as $unboundidx => $unboundif) { /* Configure IPv4 addresses */ if (is_ipaddr($interfaces[$unboundif]['ipaddr'])) { @@ -283,7 +289,7 @@ function unbound_get_network_interface_addresses() { $unbound_interfaces[$i]['ipv4']['subnet'] = find_interface_subnet($unboundrealif); $unbound_interfaces[$i]['ipv4']['network'] = gen_subnet($unbound_interfaces[$i]['ipv4']['ipaddr'],$unbound_interfaces[$i]['ipv4']['subnet']); } - + /* Configure IPv6 addresses */ if(function_exists("is_ipaddrv6")) { if(is_ipaddrv6($interfaces[$unboundif]['ipaddrv6'])) { @@ -370,7 +376,7 @@ function unbound_get_query_interface_addresses() { function unbound_acls_config() { global $config; - + /* Configure the ACLs */ if(is_array($config['installedpackages']['unboundacls']['config'])) { $unbound_acls = $config['installedpackages']['unboundacls']['config']; @@ -381,7 +387,7 @@ function unbound_acls_config() { if ($unbound_acl['aclaction'] == "allow snoop") $unbound_acl['aclaction'] = "allow_snoop"; $unboundcfg .= "access-control: {$network['acl_network']}/{$network['mask']} {$unbound_acl['aclaction']}\n"; - } + } } return $unboundcfg; } else @@ -390,12 +396,14 @@ function unbound_acls_config() { function unbound_resync_config() { global $config, $g, $input_errors; - + + $unbound_base = UNBOUND_BASE; + if (!is_array($config['installedpackages']['unbound']['config'])) $config['installedpackages']['unbound']['config'] = array(); $unbound_config = &$config['installedpackages']['unbound']['config'][0]; - + // Interfaces to bind to and setup acls for nics $unbound_bind_interfaces = ""; $unbound_allowed_networks = ""; @@ -420,19 +428,19 @@ function unbound_resync_config() { /* Configure user configured ACLs */ $unbound_allowed_networks .= unbound_acls_config(); - + if($unbound_config['dnssec_status'] == "on") { $module_config = "validator iterator"; - $anchor_file = "auto-trust-anchor-file: /usr/local/etc/unbound/root-trust-anchor"; + $anchor_file = "auto-trust-anchor-file: " . UNBOUND_BASE . "/etc/unbound/root-trust-anchor"; } else $module_config = "iterator"; - + // Host entries $host_entries = unbound_add_host_entries(); - + // Domain Overrides $domain_overrides = unbound_add_domain_overrides(); - + // Unbound Statistics if($unbound_config['stats'] == "on") { $stats_interval = $unbound_config['stats_interval']; @@ -440,13 +448,13 @@ function unbound_resync_config() { if ($unbound_config['extended_stats'] == "on") $extended_stats = "yes"; else - $extended_stats = "no"; + $extended_stats = "no"; } else { $stats_interval = "0"; $cumulative_stats = "no"; $extended_stats = "no"; } - + // Private-address support for DNS Rebinding if($unbound_config['private_address'] == "on") { $pvt_addr = <<<EOF @@ -467,7 +475,7 @@ EOF; //Setup optimization $optimization = unbound_optimization(); - + $unbound_config = &$config['installedpackages']['unboundadvanced']['config'][0]; // Setup Advanced options $log_verbosity = (isset($unbound_config['unbound_verbosity'])) ? $unbound_config['unbound_verbosity'] : "1"; @@ -488,8 +496,7 @@ EOF; $infra_lame_ttl = (!empty($unbound_config['infra_lame_ttl'])) ? $unbound_config['infra_lame_ttl'] : "900"; $infra_cache_numhosts = (!empty($unbound_config['infra_cache_numhosts'])) ? $unbound_config['infra_cache_numhosts'] : "10000"; $unwanted_reply_threshold = (!empty($unbound_config['unwanted_reply_threshold'])) ? $unbound_config['unwanted_reply_threshold'] : "0"; - - + $unbound_conf = <<<EOD ######################### @@ -502,7 +509,7 @@ EOF; server: chroot: "" username: "unbound" -directory: "/usr/local/etc/unbound" +directory: "{$unbound_base}/etc/unbound" pidfile: "{$g['varrun_path']}/unbound.pid" root-hints: "root.hints" harden-referral-path: no @@ -564,14 +571,14 @@ access-control: ::1 allow EOD; -# Handle custom options -if(!empty($unbound_config['custom_options'])) { - $custom_options = explode(";", ($unbound_config['custom_options'])); - $unbound_conf .= "# Unbound Custom options\n"; - foreach ($custom_options as $ent) { - $unbound_conf .= $ent."\n"; + # Handle custom options + if(!empty($unbound_config['custom_options'])) { + $custom_options = explode(";", ($unbound_config['custom_options'])); + $unbound_conf .= "# Unbound Custom options\n"; + foreach ($custom_options as $ent) { + $unbound_conf .= $ent."\n"; + } } -} $unbound_conf .= <<<EOD @@ -582,22 +589,24 @@ remote-control: control-enable: yes control-interface: 127.0.0.1 control-port: 953 -server-key-file: "/usr/local/etc/unbound/unbound_server.key" -server-cert-file: "/usr/local/etc/unbound/unbound_server.pem" -control-key-file: "/usr/local/etc/unbound/unbound_control.key" -control-cert-file: "/usr/local/etc/unbound/unbound_control.pem" +server-key-file: "{$unbound_base}/etc/unbound/unbound_server.key" +server-cert-file: "{$unbound_base}/etc/unbound/unbound_server.pem" +control-key-file: "{$unbound_base}/etc/unbound/unbound_control.key" +control-cert-file: "{$unbound_base}/etc/unbound/unbound_control.pem" EOD; - file_put_contents("/usr/local/etc/unbound/unbound.conf", $unbound_conf); - + conf_mount_rw(); + file_put_contents("{$unbound_base}/etc/unbound/unbound.conf", $unbound_conf); + conf_mount_ro(); + } function unbound_ctl_exec($cmd) { - - mwexec("/usr/local/sbin/unbound-control $cmd"); - + + mwexec(UNBOUND_BASE . "/sbin/unbound-control $cmd"); + } @@ -609,7 +618,7 @@ function unbound_optimization() { $unbound_config = $config['installedpackages']['unboundadvanced']['config'][0]; $optimization_settings = array(); - + // Set the number of threads equal to number of CPUs. // Use 1 (disable threading) if for some reason this sysctl fails. $numprocs = intval(trim(`/sbin/sysctl kern.smp.cpus | /usr/bin/cut -d" " -f2`)); @@ -617,7 +626,7 @@ function unbound_optimization() { $optimization['number_threads'] = "num-threads: {$numprocs}"; else $optimization['number_threads'] = "num-threads: 1"; - + // Slabs to help reduce lock contention. if ($numprocs > 4) { $optimization['msg_cache_slabs'] = "msg-cache-slabs: {$numprocs}"; @@ -630,7 +639,7 @@ function unbound_optimization() { $optimization['infra_cache_slabs'] = "infra-cache-slabs: 4"; $optimization['key_cache_slabs'] = "key-cache-slabs: 4"; } - + // Memory usage - default is 4Mb if nothing has been selected if(isset($unbound_config['msg_cache_size'])) { $rr = $unbound_config['msg_cache_size']*2; @@ -640,7 +649,7 @@ function unbound_optimization() { $optimization['msg_cache_size'] = "msg-cache-size: 4m"; $optimization['rrset_cache_size'] = "rrset-cache-size: 8m"; } - + // More outgoing connections per thread otherwise assign a default of 4096 for a single thread if($numprocs > 0) { $or = (1024/$numprocs) - 50; @@ -659,7 +668,7 @@ function unbound_optimization() { $optimization['so_rcvbuf'] = "so-rcvbuf: {$so}m"; else unset($optimization['so_rcvbuf']); - + } } // Safety check in case kern.ipc.maxsockbuf is deleted. @@ -671,12 +680,12 @@ function unbound_optimization() { function fetch_root_hints() { - $destination_file = "/usr/local/etc/unbound/root.hints"; + $destination_file = UNBOUND_BASE . "/etc/unbound/root.hints"; if (filesize($destination_file) == 0 ) { conf_mount_rw(); $fout = fopen($destination_file, "w"); $url = "ftp://ftp.internic.net/domain/named.cache"; - + $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); @@ -688,7 +697,7 @@ function fetch_root_hints() { fwrite($fout, $data); fclose($fout); conf_mount_ro(); - + return ($http_code == 200) ? true : $http_code; } else { return false; @@ -700,18 +709,18 @@ function unbound_validate($post, $type=null) { if($post['unbound_status'] == "on" && isset($config['dnsmasq']['enable'])) $input_errors[] = "The system dns-forwarder is still active. Disable it before enabling the Unbound service."; - + /* Validate the access lists */ if($type == "acl") { $acls = $post; // Check to ensure values entered is an action that is in the list if ($acls['aclaction'] != 'refuse' && $acls['aclaction'] != 'allow' && $acls['aclaction'] != 'allow_snoop' && $acls['aclaction'] != 'deny') $input_errors[] = "{$acls['aclaction']} is not a valid ACL Action. Please select one of the four actions defined in the list."; - + // Make sure there is at least 1 network defined. - if (!isset($acls['acl_network0'])) + if (!isset($acls['acl_network0'])) $input_errors[] = "You need to specify at least one network to create a valid ACL."; - + $count = 0; // Get number of rows added, should be passed by the form - will look into that later for($i=0; $i<99; $i++) { @@ -719,7 +728,7 @@ function unbound_validate($post, $type=null) { // Check to ensure values entered are networks if(!is_ipaddr($acls['acl_network'.$i]) && !is_subnet($acls['mask'.$i])) $input_errors[] = "{$acls['acl_network'.$i]}/{$acls['mask'.$i]} is not a valid network."; - } + } } } else if($type == "advanced") { if(!is_numeric($post['cache_max_ttl'])) @@ -732,7 +741,7 @@ function unbound_validate($post, $type=null) { $input_errors[] = "You must enter a valid number in 'TTL for lame delegation'."; if(!is_numeric($post['infra_cache_numhosts'])) $input_errors[] = "You must enter a valid number in 'Number of Hosts to cache'."; - + } else if($type == "basic") { /* Validate settings */ if($post['active_interface'] == "") @@ -742,9 +751,9 @@ function unbound_validate($post, $type=null) { function unbound_reconfigure() { global $config; - + $unbound_config = $config['installedpackages']['unbound']['config'][0]; - + if ($unbound_config['unbound_status'] != "on") { if(is_service_running("unbound")) unbound_control("termstop"); @@ -759,7 +768,7 @@ function unbound_reconfigure() { unbound_control("forward"); unbound_control("restore_cache"); } - } + } } function unbound_uninstall() { @@ -769,20 +778,20 @@ function unbound_uninstall() { unbound_control("termstop"); // Remove pkg config directory and startup file - mwexec("rm -rf /usr/local/etc/unbound"); + mwexec("rm -rf " . UNBOUND_BASE . "/etc/unbound"); @unlink("/usr/local/etc/rc.d/unbound.sh"); @unlink("{$g['varlog_path']}/unbound.log"); @unlink("/var/tmp/unbound_cache"); - conf_mount_ro(); + conf_mount_ro(); } function read_hosts() { - + // Open /etc/hosts and extract the only dhcpleases info $etc_hosts = array(); - foreach (file('/etc/hosts') as $line) { + foreach (file('/etc/hosts') as $line) { $d = preg_split('/\s/', $line, -1, PREG_SPLIT_NO_EMPTY); if (empty($d) || substr(reset($d), 0, 1) == "#") continue; @@ -806,12 +815,12 @@ function read_hosts() { */ function unbound_add_host_entries() { global $config; - + /* XXX: break this out into a separate config file and make use of include */ $unboundcfg = $config['installedpackages']['unbound']['config'][0]; $syscfg = $config['system']; $dnsmasqcfg = $config['dnsmasq']; - + $unbound_entries = "local-zone: \"{$syscfg['domain']}\" transparent\n"; // IPv4 entries $unbound_entries .= "local-data-ptr: \"127.0.0.1 localhost\"\n"; @@ -823,7 +832,7 @@ function unbound_add_host_entries() { $unbound_entries .= "local-data: \"localhost AAAA ::1\"\n"; $unbound_entries .= "local-data: \"localhost.{$syscfg['domain']} AAAA ::1\"\n"; } - + if ($config['interfaces']['lan']) { $cfgip = get_interface_ip("lan"); if (is_ipaddr($cfgip)) { @@ -866,12 +875,12 @@ function unbound_add_host_entries() { $host_entries .= "local-data: \"{$host['host']}{$host['domain']} IN A {$host['ip']}\"\n"; if (!empty($host['descr']) && $unboundcfg['txtsupport'] == 'on') $host_entries .= "local-data: '{$host['host']}{$host['domain']} TXT \"".addslashes($host['descr'])."\"'\n"; - + // Do not add duplicate entries $added_item[$current_host] = true; } } - $unbound_entries .= $host_entries; + $unbound_entries .= $host_entries; } // Static DHCP entries $host_entries = ""; @@ -886,7 +895,7 @@ function unbound_add_host_entries() { $host_entries .= "local-data: '{$host['hostname']}.{$syscfg['domain']} TXT \"".addslashes($host['descr'])."\"'\n"; } $unbound_entries .= $host_entries; - } + } // Handle DHCPLeases added host entries $dhcplcfg = read_hosts(); @@ -915,7 +924,7 @@ function unbound_add_domain_overrides($pvt=false) { // Domain overrides that have multiple entries need multiple stub-addr: added $sorted_domains = msort($domains, "domain"); - $result = array(); + $result = array(); foreach($sorted_domains as $domain) { $domain_key = current($domain); if(!isset($result[$domain_key])) { @@ -923,7 +932,7 @@ function unbound_add_domain_overrides($pvt=false) { } $result[$domain_key][] = $domain['ip']; } - + $domain_entries = ""; foreach($result as $domain=>$ips) { if($pvt == true) { @@ -939,7 +948,7 @@ function unbound_add_domain_overrides($pvt=false) { } } return $domain_entries; - } + } } function unbound_acl_id_used($id) { @@ -962,4 +971,4 @@ function unbound_get_next_id() { return $aclid; } -?>
\ No newline at end of file +?> diff --git a/config/unbound/unbound.xml b/config/unbound/unbound.xml index 202e8451..10de1f97 100644 --- a/config/unbound/unbound.xml +++ b/config/unbound/unbound.xml @@ -9,7 +9,7 @@ part of the Unbound package for pfSense (http://www.pfSense.com) Copyright (C) 2011 Warren Baker All rights reserved. - */ + */ /* ========================================================================== */ /* Redistribution and use in source and binary forms, with or without @@ -34,13 +34,13 @@ POSSIBILITY OF SUCH DAMAGE. */ /* ========================================================================== */ - ]]> + ]]> </copyright> <description>Unbound is a validating, recursive, and caching DNS resolver.</description> <requirements/> <faq/> <name>unbound</name> - <version>1.4.14</version> + <version>1.4.20_5</version> <title>Services: Unbound DNS Forwarder: Basic Settings</title> <include_file>/usr/local/pkg/unbound.inc</include_file> <menu> @@ -76,7 +76,7 @@ <item>http://www.pfsense.org/packages/config/unbound/unbound_advanced.xml</item> </additional_files_needed> <additional_files_needed> - <prefix>/usr/local/etc/rc.d/</prefix> + <prefix>/usr/local/bin/</prefix> <chmod>0755</chmod> <item>http://www.pfsense.org/packages/config/unbound/unbound_monitor.sh</item> </additional_files_needed> @@ -142,7 +142,7 @@ <fieldname>forwarding_mode</fieldname> <fielddescr>Enable forwarding mode</fielddescr> <description>Configure the server to make use of the DNS servers configured in <a href="system.php">System: General setup</a>. <br/> - <b>Note:</b> Disabling this will cause Unbound to perform DNS queries without + <b>Note:</b> Disabling this will cause Unbound to perform DNS queries without using the upstream configured DNS servers.</description> <type>checkbox</type> <default_value>on</default_value> diff --git a/config/unbound/unbound_acls.php b/config/unbound/unbound_acls.php index a7c3ea9e..721d3adb 100644 --- a/config/unbound/unbound_acls.php +++ b/config/unbound/unbound_acls.php @@ -95,7 +95,7 @@ if ($_POST) { $input_errors[] = gettext("You must enter a valid IPv4 address for {$networkacl[$x]['acl_network']}."); } } - + if (!$input_errors) { if ($pconfig['Submit'] == gettext("Save")) { @@ -173,7 +173,7 @@ if (is_subsystem_dirty("unbound")) print_info_box_np(gettext("The settings for Unbound DNS has changed. You must apply the configuration to take affect.")); ?> <table width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr> + <tr> <td class="tabnavtbl"> <ul id="tabnav"> <?php @@ -186,7 +186,7 @@ if (is_subsystem_dirty("unbound")) ?> </ul> </td> - </tr> + </tr> <tr> <td class="tabcont"> @@ -221,10 +221,10 @@ if (is_subsystem_dirty("unbound")) <br/> <span class="vexpl"> <?=gettext("Choose what to do with DNS requests that match the criteria specified below.");?> <br/> - <?=gettext("<b>Deny:</b> This actions stops queries from hosts within the netblock defined below.");?> <br/> - <?=gettext("<b>Refuse:</b> This actions also stops queries from hosts within the netblock defined below, but sends back DNS rcode REFUSED error message back tot eh client.");?> <br/> - <?=gettext("<b>Allow:</b> This actions allows queries from hosts within the netblock defined below.");?> <br/> - <?=gettext("<b>Allow Snoop:</b> This actions allows recursive and nonrecursive access from hosts within the netblock defined below. Used for cache snooping and ideally should only be configured for your administrative host.");?> <br/> + <?=gettext("<b>Deny:</b> This action stops queries from hosts within the netblock defined below.");?> <br/> + <?=gettext("<b>Refuse:</b> This action also stops queries from hosts within the netblock defined below, but sends a DNS rcode REFUSED error message back to the client.");?> <br/> + <?=gettext("<b>Allow:</b> This action allows queries from hosts within the netblock defined below.");?> <br/> + <?=gettext("<b>Allow Snoop:</b> This action allows recursive and nonrecursive access from hosts within the netblock defined below. Used for cache snooping and ideally should only be configured for your administrative host.");?> <br/> </span> </td> </tr> @@ -375,4 +375,4 @@ if (is_subsystem_dirty("unbound")) </tr> </table> </body> -<?php include("fend.inc"); ?>
\ No newline at end of file +<?php include("fend.inc"); ?> diff --git a/config/unbound/unbound_acls.xml b/config/unbound/unbound_acls.xml index 7c6840ce..04319169 100644 --- a/config/unbound/unbound_acls.xml +++ b/config/unbound/unbound_acls.xml @@ -99,10 +99,10 @@ <fieldname>aclaction</fieldname> <fielddescr>Action</fielddescr> <description><br/>Choose an action:<br/><br/> - <b>Allow:</b> This actions allows queries from hosts within the netblock(s) defined below.<br/> - <b>Allow Snoop:</b> This actions allows recursive and nonrecursive access from hosts within the netblock(s) defined below. Used for cache snooping and ideally should only be configured for your administrative host.<br/> - <b>Deny:</b> This actions stops queries from hosts within the netblock(s) defined below.<br/> - <b>Refuse:</b> This actions also stops queries from hosts within the netblock(s) defined below, but sends back DNS rcode REFUSED error message back to the client.</description> + <b>Allow:</b> This action allows queries from hosts within the netblock(s) defined below.<br/> + <b>Allow Snoop:</b> This action allows recursive and nonrecursive access from hosts within the netblock(s) defined below. Used for cache snooping and ideally should only be configured for your administrative host.<br/> + <b>Deny:</b> This action stops queries from hosts within the netblock(s) defined below.<br/> + <b>Refuse:</b> This action also stops queries from hosts within the netblock(s) defined below, but sends a DNS rcode REFUSED error message back to the client.</description> <type>select</type> <options> <option><name>Allow</name><value>allow</value></option> diff --git a/config/unbound/unbound_advanced.xml b/config/unbound/unbound_advanced.xml index 30fca482..7603d0aa 100644 --- a/config/unbound/unbound_advanced.xml +++ b/config/unbound/unbound_advanced.xml @@ -99,7 +99,7 @@ <field> <fieldname>prefetch</fieldname> <fielddescr>Prefetch Support</fielddescr> - <description>If enabled, the message cache elements are prefetched before they expire to keep the cache up to date. Enabling this option causes an increase of about 10 percent more traffic and load on the server, but popular items do not expire form the cache. Default is disabled.</description> + <description>If enabled, the message cache elements are prefetched before they expire to keep the cache up to date. Enabling this option causes an increase of about 10 percent more traffic and load on the server, but popular items do not expire from the cache. Default is disabled.</description> <type>checkbox</type> <default_value>off</default_value> <advancedfield/> @@ -123,7 +123,7 @@ <field> <fieldname>harden_dnssec_stripped</fieldname> <fielddescr>Harden DNSSEC data</fielddescr> - <description>If enabled, DNSSEC data is required for trust-anchored zones. If such data is absent, the zone is becomes bogus. If disabled then and no DNSSEC data is received, then the zone is made insecure. The default is enabled.</description> + <description>If enabled, DNSSEC data is required for trust-anchored zones. If such data is absent, the zone is considered bogus. If disabled and no DNSSEC data is received, then the zone is made insecure. The default is enabled.</description> <type>checkbox</type> <default_value>on</default_value> <advancedfield/> @@ -305,7 +305,7 @@ <field> <fielddescr>Custom Options</fielddescr> <fieldname>custom_options</fieldname> - <description>You can put your own custom options here, separated by semi-colons (;). These configurations options will then be added to the configuration file. <br/> <b>Note:</b> They need to be Unbound native configuration options, otherwise Unbound will <b>not</b> work.</description> + <description>You can put your own custom options here, separated by semi-colons (;). These configuration options will then be added to the configuration file. <br/> <b>Note:</b> They need to be Unbound native configuration options, otherwise Unbound will <b>not</b> work.</description> <type>textarea</type> <cols>65</cols> <rows>5</rows> diff --git a/config/unbound/unbound_monitor.sh b/config/unbound/unbound_monitor.sh index 152a308e..91e5a2ed 100755 --- a/config/unbound/unbound_monitor.sh +++ b/config/unbound/unbound_monitor.sh @@ -27,37 +27,65 @@ # POSSIBILITY OF SUCH DAMAGE. # +export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + set -e LOOP_SLEEP=5 +PIDFILE=/var/run/unbound_monitor.pid if [ -f /var/run/unbound_alarm ]; then rm /var/run/unbound_alarm fi +PID="" +if [ -f "${PIDFILE}" ]; then + PID=`head -n 1 ${PIDFILE}` +fi + +if [ "$1" = "stop" ]; then + if [ -n "${PID}" ] && ps -p ${PID} | grep -q unbound_monitor.sh; then + kill ${PID} + else + pkill -f unbound_monitor.sh + fi + exit 0 +fi + +if [ -n "${PID}" ] && ps -p ${PID} | grep -q unbound_monitor.sh; then + echo "There is another unbound monitor process running" + exit 0 +fi + +echo $$ > ${PIDFILE} + # Sleep 5 seconds on startup not to mangle with existing boot scripts. sleep 5 -while [ /bin/true ]; do - if [ ! -f /var/run/unbound_alarm ]; then - NUM_PROCS=`/bin/pgrep unbound | wc -l | awk '{print $1}'` - if [ $NUM_PROCS -lt 1 ]; then - # Unbound is not running - echo "Unbound has exited." | logger -p daemon.info -i -t Unbound_Alarm - echo "Attempting restart..." | logger -p daemon.info -i -t Unbound_Alarm - /usr/local/etc/rc.d/unbound.sh start - sleep 3 - touch /var/run/unbound_alarm - fi - fi - NUM_PROCS=`/bin/pgrep unbound | wc -l | awk '{print $1}'` - if [ $NUM_PROCS -gt 0 ]; then - if [ -f /var/run/unbound_alarm ]; then - echo "Unbound has resumed." | logger -p daemon.info -i -t Unbound_Alarm - rm /var/run/unbound_alarm - fi - fi - sleep $LOOP_SLEEP +while true; do + if [ ! -f "${PIDFILE}" ]; then + echo $$ > ${PIDFILE} + fi + + if [ ! -f /var/run/unbound_alarm ]; then + NUM_PROCS=`pgrep unbound | wc -l | awk '{print $1}'` + if [ $NUM_PROCS -lt 1 ]; then + # Unbound is not running + echo "Unbound has exited." | logger -p daemon.info -i -t Unbound_Alarm + echo "Attempting restart..." | logger -p daemon.info -i -t Unbound_Alarm + /usr/local/etc/rc.d/unbound.sh start + sleep 3 + touch /var/run/unbound_alarm + fi + fi + NUM_PROCS=`pgrep unbound | wc -l | awk '{print $1}'` + if [ $NUM_PROCS -gt 0 ]; then + if [ -f /var/run/unbound_alarm ]; then + echo "Unbound has resumed." | logger -p daemon.info -i -t Unbound_Alarm + rm /var/run/unbound_alarm + fi + fi + sleep $LOOP_SLEEP done if [ -f /var/run/unbound_alarm ]; then diff --git a/config/unbound/unbound_status.php b/config/unbound/unbound_status.php index d011b109..d7371f29 100644 --- a/config/unbound/unbound_status.php +++ b/config/unbound/unbound_status.php @@ -31,6 +31,12 @@ require("guiconfig.inc"); +// Define basedir constant for unbound according to FreeBSD version (PBI support or no PBI) +if (floatval(php_uname("r")) >= 8.3) + define("UNBOUND_BASE", "/usr/pbi/unbound-" . php_uname("m")); +else + define("UNBOUND_BASE", "/usr/local"); + if(!is_process_running("unbound")) { Header("Location: /pkg_edit.php?xml=unbound.xml&id=0"); exit; @@ -40,11 +46,11 @@ $pgtitle = "Services: Unbound DNS Forwarder: Status"; include("head.inc"); function doCmdT($title, $command, $rows) { - echo "<p>\n"; - echo "<a name=\"" . $title . "\">\n"; - echo "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n"; - echo "<tr><td class=\"listtopic\">" . $title . "</td></tr>\n"; - echo "<tr><td class=\"listlr\"><textarea style=\"font-family:courier\"cols=\"101\" rows=\"$rows\">"; /* no newline after pre */ + echo "<p>\n"; + echo "<a name=\"" . $title . "\">\n"; + echo "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n"; + echo "<tr><td class=\"listtopic\">" . $title . "</td></tr>\n"; + echo "<tr><td class=\"listlr\"><textarea style=\"font-family:courier\"cols=\"101\" rows=\"$rows\">"; /* no newline after pre */ if ($command == "dumpconfigxml") { $fd = @fopen("/conf/config.xml", "r"); @@ -71,46 +77,46 @@ function doCmdT($title, $command, $rows) { echo htmlspecialchars($execOutput[$i],ENT_NOQUOTES); } } - echo "</textarea></tr>\n"; - echo "</table>\n"; + echo "</textarea></tr>\n"; + echo "</table>\n"; } /* Execute a command, giving it a title which is the same as the command. */ function doCmd($command) { - doCmdT($command,$command); + doCmdT($command,$command); } /* Define a command, with a title, to be executed later. */ function defCmdT($title, $command, $rows = "20") { - global $commands; - $title = htmlspecialchars($title,ENT_NOQUOTES); - $commands[] = array($title, $command, $rows); + global $commands; + $title = htmlspecialchars($title,ENT_NOQUOTES); + $commands[] = array($title, $command, $rows); } /* Define a command, with a title which is the same as the command, * to be executed later. */ function defCmd($command) { - defCmdT($command,$command); + defCmdT($command,$command); } /* List all of the commands as an index. */ function listCmds() { - global $commands; - echo "<p>" . gettext("This status page includes the following information") . ":\n"; - echo "<ul width=\"100%\">\n"; - for ($i = 0; isset($commands[$i]); $i++ ) { - echo "<li><strong><a href=\"#" . $commands[$i][0] . "\">" . $commands[$i][0] . "</a></strong>\n"; - } - echo "</ul>\n"; + global $commands; + echo "<p>" . gettext("This status page includes the following information") . ":\n"; + echo "<ul width=\"100%\">\n"; + for ($i = 0; isset($commands[$i]); $i++ ) { + echo "<li><strong><a href=\"#" . $commands[$i][0] . "\">" . $commands[$i][0] . "</a></strong>\n"; + } + echo "</ul>\n"; } /* Execute all of the commands which were defined by a call to defCmd. */ function execCmds() { - global $commands; - for ($i = 0; isset($commands[$i]); $i++ ) { - doCmdT($commands[$i][0], $commands[$i][1], $commands[$i][2]); - } + global $commands; + for ($i = 0; isset($commands[$i]); $i++ ) { + doCmdT($commands[$i][0], $commands[$i][1], $commands[$i][2]); + } } ?> @@ -135,10 +141,10 @@ function execCmds() { </tr> </table> <table width="100%" border="0" cellpadding="0" cellspacing="0"> - <tr> - <td class="tabcont" width="100%"> + <tr> + <td class="tabcont" width="100%"> <?php - $entries = trim(exec("/usr/local/sbin/unbound-control dump_cache | wc -l")); + $entries = trim(exec(UNBOUND_BASE . "/sbin/unbound-control dump_cache | wc -l")); defCmdT("Unbound status", "unbound-control status", "6"); defCmdT("Unbound stats", "unbound-control stats_noreset"); defCmdT("Unbound stubs", "unbound-control list_stubs", "8"); @@ -146,12 +152,12 @@ function execCmds() { defCmdT("Unbound local zones", "unbound-control list_local_zones"); defCmdT("Unbound local data", "unbound-control list_local_data"); defCmdT("Unbound cache ($entries entries)", "unbound-control dump_cache", "60"); - defCmdT("Unbound configuration", "/bin/cat /usr/local/etc/unbound/unbound.conf", "60"); + defCmdT("Unbound configuration", "/bin/cat " . UNBOUND_BASE . "/etc/unbound/unbound.conf", "60"); listCmds(); execCmds(); ?> - </td> - </tr> + </td> + </tr> </table> </div> <?php include("fend.inc"); ?> diff --git a/config/widget-snort/snort_alerts.widget.php b/config/widget-snort/snort_alerts.widget.php index bb51a387..e488bc49 100644 --- a/config/widget-snort/snort_alerts.widget.php +++ b/config/widget-snort/snort_alerts.widget.php @@ -60,55 +60,61 @@ function sksort(&$array, $subkey="id", $sort_ascending=false) { /* check if firewall widget variable is set */ if (!isset($nentries)) $nentries = 5; -/* retrieve snort variables */ -require_once("/usr/local/pkg/snort/snort.inc"); -if (!is_array($config['installedpackages']['snortglobal']['rule'])) - $config['installedpackages']['snortglobal']['rule'] = array(); -$a_instance = &$config['installedpackages']['snortglobal']['rule']; +/* check if Snort include file exists before we use it */ +if (file_exists("/usr/local/pkg/snort/snort.inc")) { + require_once("/usr/local/pkg/snort/snort.inc"); -/* read log file(s) */ -$counter=0; -foreach ($a_instance as $instanceid => $instance) { - $snort_uuid = $a_instance[$instanceid]['uuid']; - $if_real = snort_get_real_interface($a_instance[$instanceid]['interface']); + /* retrieve snort variables */ + if (!is_array($config['installedpackages']['snortglobal']['rule'])) + $config['installedpackages']['snortglobal']['rule'] = array(); + $a_instance = &$config['installedpackages']['snortglobal']['rule']; + + /* read log file(s) */ + $counter=0; + foreach ($a_instance as $instanceid => $instance) { + $snort_uuid = $a_instance[$instanceid]['uuid']; + $if_real = snort_get_real_interface($a_instance[$instanceid]['interface']); - /* make sure alert file exists */ - if (file_exists("/var/log/snort/snort_{$if_real}{$snort_uuid}/alert")) { - exec("tail -n{$nentries} /var/log/snort/snort_{$if_real}{$snort_uuid}/alert > /tmp/alert_{$snort_uuid}"); - if (file_exists("/tmp/alert_{$snort_uuid}")) { - $tmpblocked = array_flip(snort_get_blocked_ips()); + /* make sure alert file exists */ + if (file_exists("/var/log/snort/snort_{$if_real}{$snort_uuid}/alert")) { + exec("tail -n{$nentries} /var/log/snort/snort_{$if_real}{$snort_uuid}/alert > /tmp/alert_{$snort_uuid}"); + if (file_exists("/tmp/alert_{$snort_uuid}")) { + $tmpblocked = array_flip(snort_get_blocked_ips()); - /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */ - /* File format timestamp,sig_generator,sig_id,sig_rev,msg,proto,src,srcport,dst,dstport,id,classification,priority */ - $fd = fopen("/tmp/alert_{$snort_uuid}", "r"); - while (($fields = fgetcsv($fd, 1000, ',', '"')) !== FALSE) { - if(count($fields) < 11) - continue; + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */ + /* File format timestamp,sig_generator,sig_id,sig_rev,msg,proto,src,srcport,dst,dstport,id,classification,priority */ + $fd = fopen("/tmp/alert_{$snort_uuid}", "r"); + while (($fields = fgetcsv($fd, 1000, ',', '"')) !== FALSE) { + if(count($fields) < 11) + continue; - $snort_alerts[$counter]['instanceid'] = $a_instance[$instanceid]['interface']; - $snort_alerts[$counter]['timestamp'] = $fields[0]; - $snort_alerts[$counter]['timeonly'] = substr($fields[0], 6, -8); - $snort_alerts[$counter]['dateonly'] = substr($fields[0], 0, -17); - $snort_alerts[$counter]['src'] = $fields[6]; - $snort_alerts[$counter]['srcport'] = $fields[7]; - $snort_alerts[$counter]['dst'] = $fields[8]; - $snort_alerts[$counter]['dstport'] = $fields[9]; - $snort_alerts[$counter]['priority'] = $fields[12]; - $snort_alerts[$counter]['category'] = $fields[11]; - $counter++; + $snort_alerts[$counter]['instanceid'] = $a_instance[$instanceid]['interface']; + $snort_alerts[$counter]['timestamp'] = $fields[0]; + $snort_alerts[$counter]['timeonly'] = substr($fields[0], strpos($fields[0], '-')+1, -8); + $snort_alerts[$counter]['dateonly'] = substr($fields[0], 0, strpos($fields[0], '-')); + $snort_alerts[$counter]['src'] = $fields[6]; + $snort_alerts[$counter]['srcport'] = $fields[7]; + $snort_alerts[$counter]['dst'] = $fields[8]; + $snort_alerts[$counter]['dstport'] = $fields[9]; + $snort_alerts[$counter]['priority'] = $fields[12]; + $snort_alerts[$counter]['category'] = $fields[11]; + $counter++; + }; + fclose($fd); + @unlink("/tmp/alert_{$snort_uuid}"); }; - fclose($fd); - @unlink("/tmp/alert_{$snort_uuid}"); }; }; -}; -/* sort the array */ -if (isset($config['syslog']['reverse'])) { - sksort($snort_alerts, 'timestamp', false); + /* sort the array */ + if (isset($config['syslog']['reverse'])) { + sksort($snort_alerts, 'timestamp', false); + } else { + sksort($snort_alerts, 'timestamp', true); + }; } else { - sksort($snort_alerts, 'timestamp', true); -}; + $msg = gettext("The Snort package is not installed."); +} /* display the result */ ?> @@ -131,7 +137,13 @@ if (is_array($snort_alerts)) { $counter++; if($counter >= $nentries) break; } -}; +} else { + if (!empty($msg)) { + echo (" <tr class=\"snort-alert-entry\"> + <td colspan=\"3\" align=\"center\"><br>{$msg}</br></td> + </tr>"); + } +} ?> </tbody> </table> diff --git a/config/widget-snort/widget-snort.inc b/config/widget-snort/widget-snort.inc new file mode 100644 index 00000000..105dd1e7 --- /dev/null +++ b/config/widget-snort/widget-snort.inc @@ -0,0 +1,24 @@ +<?php +require_once("config.inc"); +function widget_snort_uninstall() { + + global $config; + + /* Remove the Snort widget from the Dashboard display list */ + $widgets = $config['widgets']['sequence']; + if (!empty($widgets)) { + $widgetlist = explode(",", $widgets); + foreach ($widgetlist as $key => $widget) { + if (strstr($widget, "snort_alerts-container")) + unset($widgetlist[$key]); + } + $config['widgets']['sequence'] = implode(",", $widgetlist); + write_config(); + } + + /* Remove our associated files */ + unlink("/usr/local/www/widgets/include/widget-snort.inc"); + unlink("/usr/local/www/widgets/widgets/snort_alerts.widget.php"); + unlink("/usr/local/www/widgets/javascript/snort_alerts.js"); +} +?> diff --git a/config/widget-snort/widget-snort.xml b/config/widget-snort/widget-snort.xml index 785ac5b1..b415bd12 100644 --- a/config/widget-snort/widget-snort.xml +++ b/config/widget-snort/widget-snort.xml @@ -46,8 +46,15 @@ <requirements>Dashboard package and Snort</requirements> <faq>Currently there are no FAQ items provided.</faq> <name>widget-snort</name> - <version>0.5</version> + <version>0.3.4</version> <title>Widget - Snort</title> + <include_file>/usr/local/www/widgets/include/widget-snort.inc</include_file> + <menu> + </menu> + <service> + </service> + <tabs> + </tabs> <additional_files_needed> <prefix>/usr/local/www/widgets/javascript/</prefix> <chmod>0644</chmod> @@ -58,4 +65,20 @@ <chmod>0644</chmod> <item>http://www.pfsense.com/packages/config/widget-snort/snort_alerts.widget.php</item> </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/widgets/include/</prefix> + <chmod>0644</chmod> + <item>http://www.pfsense.com/packages/config/widget-snort/widget-snort.inc</item> + </additional_files_needed> + <fields> + </fields> + <custom_add_php_command> + </custom_add_php_command> + <custom_php_resync_config_command> + </custom_php_resync_config_command> + <custom_php_install_command> + </custom_php_install_command> + <custom_php_deinstall_command> + widget_snort_uninstall(); + </custom_php_deinstall_command> </packagegui> |