diff options
Diffstat (limited to 'config')
22 files changed, 1492 insertions, 480 deletions
diff --git a/config/snort/snort.inc b/config/snort/snort.inc index 44dd133e..f1f5ad9b 100755 --- a/config/snort/snort.inc +++ b/config/snort/snort.inc @@ -42,14 +42,12 @@ require_once("filter.inc"); // Snort GUI needs some extra PHP memory space to manipulate large rules arrays ini_set("memory_limit", "192M"); -// 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 $all_rules, $flowbit_rules_file, $snort_enforcing_rules_file, $rebuild_rules, $is_postinstall; -global $snort_community_rules_filename, $snort_community_rules_url, $emergingthreats_filename; +// Explicitly declare this as global so it works through function call includes +global $rebuild_rules; /* package version */ -$snort_version = "2.9.4.1"; -$pfSense_snort_version = "2.5.8"; +$snort_version = "2.9.4.6"; +$pfSense_snort_version = "2.5.9"; $snort_package_version = "Snort {$snort_version} pkg v. {$pfSense_snort_version}"; // Define SNORTDIR and SNORTLIBDIR constants according to FreeBSD version (PBI support or no PBI) @@ -67,24 +65,20 @@ else { define("SNORTLIBDIR", "/usr/local/lib/snort"); } +/* Define some useful constants for 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"; - -/* 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; +define("VRT_DNLD_FILENAME", "snortrules-snapshot-2946.tar.gz"); +define("VRT_DNLD_URL", "https://www.snort.org/reg-rules/"); +define("ET_VERSION", "2.9.0"); +define("ET_DNLD_FILENAME", "emerging.rules.tar.gz"); +define("GPLV2_DNLD_FILENAME", "community-rules.tar.gz"); +define("GPLV2_DNLD_URL", "https://s3.amazonaws.com/snort-org/www/rules/community/"); +define("FLOWBITS_FILENAME", "flowbit-required.rules"); +define("ENFORCING_RULES_FILENAME", "snort.rules"); +define("RULES_UPD_LOGFILE", SNORTLOGDIR . "/snort_rules_update.log"); + +/* Rebuild Rules Flag -- if "true", rebuild enforcing rules and flowbit-rules files */ +$rebuild_rules = false; if (!is_array($config['installedpackages']['snortglobal'])) $config['installedpackages']['snortglobal'] = array(); @@ -107,19 +101,6 @@ function snort_get_blocked_ips() { return $blocked_ips_array; } -function snort_get_rule_part($source, $beginning, $ending, $start_pos) { - - $beginning_pos = strpos($source, $beginning, $start_pos); - if (!$beginning_pos) - return false; - $middle_pos = $beginning_pos + strlen($beginning); - $source = substr($source, $middle_pos); - $ending_pos = strpos($source, $ending, 0); - if (!$ending_pos) - return false; - return substr($source, 0, $ending_pos); -} - function snort_generate_id() { global $config; @@ -136,7 +117,7 @@ function snort_generate_id() { return $snort_uuid; } -function snort_load_suppress_sigs($snortcfg) { +function snort_load_suppress_sigs($snortcfg, $track_by=false) { global $config; @@ -144,7 +125,17 @@ function snort_load_suppress_sigs($snortcfg) { /* This function loads the GEN_ID and SIG_ID for all the */ /* suppressed alert entries from the Suppression List of */ /* the passed Snort interface. The results are returned */ - /* in an array with GEN_ID and SIG_ID as the keys. */ + /* in an array with GEN_ID and SIG_ID as the primary */ + /* keys. Any "track by_src" or "track by_dst" entries */ + /* in the Suppression List are tacked on as additional */ + /* keys in the array along with the IP address in either */ + /* IPv4 or IPv6 format when $track_by is passed as true. */ + /* */ + /* Sample returned array: */ + /* $suppress[1][2069] = "suppress" */ + /* $suppress[1][2070]['by_src']['10.1.1.5'] = "suppress" */ + /* $suppress[1][2070]['by_dst']['10.1.1.6'] = "suppress" */ + /* */ /**********************************************************/ $suppress = array(); @@ -169,12 +160,35 @@ function snort_load_suppress_sigs($snortcfg) { // Skip any comment lines if (preg_match('/^\s*#/', $line)) continue; - if (preg_match('/gen_id\b\s*(\d+),\s*sig_id\b\s*(\d+)/i', $line, $matches)) { + /* See if entry suppresses GID:SID for all hosts */ + if (preg_match('/\s*suppress\s*gen_id\b\s*(\d+),\s*sig_id\b\s*(\d+)\s*$/i', $line, $matches)) { $genid = $matches[1]; $sigid = $matches[2]; if (!empty($genid) && !empty($sigid)) $suppress[$genid][$sigid] = "suppress"; } + + /* Get "track by IP" entries if requested */ + if ($track_by) { + /* See if entry suppresses only by SRC or DST IPv4 address */ + if (preg_match('/\s*suppress\s*gen_id\b\s*(\d+),\s*sig_id\b\s*(\d+),\s*track\s*(by_src|by_dst),\s*ip\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*$/i', $line, $matches)) { + $genid = $matches[1]; + $sigid = $matches[2]; + $whichip = trim($matches[3]); + $ip = $matches[4]; + if (!empty($genid) && !empty($sigid) && !empty($whichip) && !empty($ip)) + $suppress[$genid][$sigid][$whichip][$ip] = "suppress"; + } + /* See if entry suppresses only by SRC or DST IPv6 address */ + if (preg_match('/\s*suppress\s*gen_id\b\s*(\d+),\s*sig_id\b\s*(\d+),\s*track\s*(by_src|by_dst),\s*ip\s*([0-9a-f\.:]+)\s*$/i', $line, $matches)) { + $genid = $matches[1]; + $sigid = $matches[2]; + $whichip = trim($matches[3]); + $ip = trim($matches[4]); + if (!empty($genid) && !empty($sigid) && !empty($whichip) && !empty($ip)) + $suppress[$genid][$sigid][$whichip][$ip] = "suppress"; + } + } } unset($tmp); } @@ -205,8 +219,13 @@ function snort_find_list($find_name, $type = 'whitelist') { /* func builds custom whitelists and the HOME_NET variable */ function snort_build_list($snortcfg, $listname = "", $whitelist = false) { - global $config, $g; - global $aliastable, $filterdns; + + /***********************************************************/ + /* The default is to build a HOME_NET variable unless */ + /* '$whitelist' is set to 'true' when calling. */ + /***********************************************************/ + + global $config, $g, $aliastable, $filterdns; $home_net = array(); if ($listname == 'default' || empty($listname)) { @@ -233,35 +252,56 @@ function snort_build_list($snortcfg, $listname = "", $whitelist = false) { /********************************************************************/ /* Always put the interface running Snort in HOME_NET and whitelist */ /* unless it's the WAN. WAN options are handled further down. */ + /* If the user specifically chose not to include LOCAL_NETS in the */ + /* WHITELIST, then do not include the Snort interface subnet in the */ + /* WHITELIST. We do include the actual LAN interface IP for Snort, */ + /* though, to prevent locking out the firewall itself. */ /********************************************************************/ $snortip = get_interface_ip($snortcfg['interface']); - if (is_ipaddr($snortip)) { - if ($snortcfg['interface'] <> "wan") { - $sn = get_interface_subnet($snortcfg['interface']); - $ip = gen_subnet($snortip, $sn) . "/{$sn}"; - if (!in_array($ip, $home_net)) - $home_net[] = $ip; + if (!$whitelist || $localnet == 'yes' || empty($localnet)) { + if (is_ipaddr($snortip)) { + if ($snortcfg['interface'] <> "wan") { + $sn = get_interface_subnet($snortcfg['interface']); + $ip = gen_subnet($snortip, $sn) . "/{$sn}"; + if (!in_array($ip, $home_net)) + $home_net[] = $ip; + } + } + } + else { + if (is_ipaddr($snortip)) { + if (!in_array($snortip, $home_net)) + $home_net[] = $snortip; } } + /* Handle IPv6 if available (2.1 and higher) */ if (function_exists('get_interface_ipv6')) { $snortip = get_interface_ipv6($snortcfg['interface']); - if (is_ipaddrv6($snortip)) { - if ($snortcfg['interface'] <> "wan") { - $sn = get_interface_subnetv6($snortcfg['interface']); - $ip = gen_subnetv6($snortip, $sn). "/{$sn}"; - if (!in_array($ip, $home_net)) - $home_net[] = $ip; + if (!$whitelist || $localnet == 'yes' || empty($localnet)) { + if (is_ipaddrv6($snortip)) { + if ($snortcfg['interface'] <> "wan") { + $sn = get_interface_subnetv6($snortcfg['interface']); + $ip = gen_subnetv6($snortip, $sn). "/{$sn}"; + if (!in_array($ip, $home_net)) + $home_net[] = $ip; + } + } + } + else { + if (is_ipaddrv6($snortip)) { + if (!in_array($snortip, $home_net)) + $home_net[] = $snortip; } } } - if ($localnet == 'yes') { + if (!$whitelist || $localnet == 'yes' || empty($localnet)) { /*************************************************************************/ /* Iterate through the interface list and write out whitelist items and */ /* also compile a HOME_NET list of all the local interfaces for snort. */ /* Skip the WAN interface as we do not typically want that whole subnet */ - /* whitelisted (just the interface IP itself). */ + /* whitelisted (just the i/f IP itself which was handled earlier). */ /*************************************************************************/ $int_array = get_configured_interface_list(); foreach ($int_array as $int) { @@ -433,17 +473,22 @@ function snort_start($snortcfg, $if_real) { } /**************************************************************/ -/* This function sends a SIGHUP to the Snort instance on the */ -/* passed interface to cause Snort to reload and parse the */ -/* running configuration without stopping packet processing. */ -/* It also executes the reload as a background process and */ -/* returns control immediately to the caller. */ +/* This function sends the passed SIGNAL to the Snort */ +/* instance on the passed interface to cause Snort to reload */ +/* and parse the running configuration without stopping */ +/* packet processing. It also executes the reload as a */ +/* background process and returns control immediately to the */ +/* caller. */ +/* */ +/* $signal = SIGHUP (default) parses and reloads config. */ +/* SIGURG updates Host Attribute Table. */ /**************************************************************/ -function snort_reload_config($snortcfg, $if_real) { +function snort_reload_config($snortcfg, $signal="SIGHUP") { global $config, $g; $snortdir = SNORTDIR; $snort_uuid = $snortcfg['uuid']; + $if_real = snort_get_real_interface($snortcfg['interface']); /******************************************************/ /* Only send the SIGHUP if Snort is running and we */ @@ -451,7 +496,7 @@ function snort_reload_config($snortcfg, $if_real) { /******************************************************/ if (file_exists("{$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid") && isvalidpid("{$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid")) { log_error("[Snort] Snort RELOAD CONFIG for {$snortcfg['descr']}({$if_real})..."); - exec("/bin/pkill -SIGHUP -F {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid 2>&1 &"); + exec("/bin/pkill -{$signal} -F {$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid 2>&1 &"); } } @@ -539,15 +584,14 @@ function snort_post_delete_logs($snort_uuid = 0) { } function snort_postinstall() { - global $config, $g, $snort_rules_file, $emerging_threats_version; - global $snort_version, $rebuild_rules, $is_postinstall; + global $config, $g, $rebuild_rules, $pkg_interface, $snort_gui_include; $snortdir = SNORTDIR; $snortlibdir = SNORTLIBDIR; $rcdir = RCFILEPREFIX; /* Set flag for post-install in progress */ - $is_postinstall = true; + $g['snort_postinstall'] = true; /* cleanup default files */ @rename("{$snortdir}/snort.conf-sample", "{$snortdir}/snort.conf"); @@ -586,11 +630,13 @@ function snort_postinstall() { update_output_window(gettext("Please wait... rebuilding installation with saved settings...")); log_error(gettext("[Snort] Downloading and updating configured rule types...")); update_output_window(gettext("Please wait... downloading and updating configured rule types...")); + if ($pkg_interface <> "console") + $snort_gui_include = true; @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"; + $rebuild_rules = true; sync_snort_package_config(); - $rebuild_rules = "off"; + $rebuild_rules = false; update_output_window(gettext("Finished rebuilding files...")); log_error(gettext("[Snort] Finished rebuilding installation from saved settings...")); @@ -605,7 +651,7 @@ function snort_postinstall() { } /* Done with post-install, so clear flag */ - $is_postinstall = false; + unset($g['snort_postinstall']); log_error(gettext("[Snort] Package post-installation tasks completed...")); } @@ -779,44 +825,63 @@ function snort_rules_up_install_cron($should_install) { $x++; } $snort_rules_up_info_ck = $config['installedpackages']['snortglobal']['autorulesupdate7']; + + /* See if a customized start time has been set for rule file updates */ + if (!empty($config['installedpackages']['snortglobal']['rule_update_starttime'])) + $snort_rules_upd_time = $config['installedpackages']['snortglobal']['rule_update_starttime']; + else + $snort_rules_upd_time = "00:03"; + if ($snort_rules_up_info_ck == "6h_up") { - $snort_rules_up_min = "3"; - $snort_rules_up_hr = "*/6"; + $snort_rules_up_min = intval(substr($snort_rules_upd_time, -2)); + $hour = intval(substr($snort_rules_upd_time, 0, 2)); + $snort_rules_up_hr = strval($hour); + for ($i=0; $i<3; $i++) { + $hour += 6; + if ($hour > 24) + $hour -= 24; + $snort_rules_up_hr .= "," . strval($hour); + } $snort_rules_up_mday = "*"; $snort_rules_up_month = "*"; $snort_rules_up_wday = "*"; } if ($snort_rules_up_info_ck == "12h_up") { - $snort_rules_up_min = "3"; - $snort_rules_up_hr = "*/12"; + $snort_rules_up_min = intval(substr($snort_rules_upd_time, -2)); + $hour = intval(substr($snort_rules_upd_time, 0, 2)); + $snort_rules_up_hr = strval($hour) . ","; + $hour += 12; + if ($hour > 24) + $hour -= 24; + $snort_rules_up_hr .= strval($hour); $snort_rules_up_mday = "*"; $snort_rules_up_month = "*"; $snort_rules_up_wday = "*"; } if ($snort_rules_up_info_ck == "1d_up") { - $snort_rules_up_min = "3"; - $snort_rules_up_hr = "0"; + $snort_rules_up_min = intval(substr($snort_rules_upd_time, -2)); + $snort_rules_up_hr = intval(substr($snort_rules_upd_time, 0, 2)); $snort_rules_up_mday = "*/1"; $snort_rules_up_month = "*"; $snort_rules_up_wday = "*"; } if ($snort_rules_up_info_ck == "4d_up") { - $snort_rules_up_min = "3"; - $snort_rules_up_hr = "0"; + $snort_rules_up_min = intval(substr($snort_rules_upd_time, -2)); + $snort_rules_up_hr = intval(substr($snort_rules_upd_time, 0, 2)); $snort_rules_up_mday = "*/4"; $snort_rules_up_month = "*"; $snort_rules_up_wday = "*"; } if ($snort_rules_up_info_ck == "7d_up") { - $snort_rules_up_min = "3"; - $snort_rules_up_hr = "0"; + $snort_rules_up_min = intval(substr($snort_rules_upd_time, -2)); + $snort_rules_up_hr = intval(substr($snort_rules_upd_time, 0, 2)); $snort_rules_up_mday = "*/7"; $snort_rules_up_month = "*"; $snort_rules_up_wday = "*"; } if ($snort_rules_up_info_ck == "28d_up") { - $snort_rules_up_min = "3"; - $snort_rules_up_hr = "0"; + $snort_rules_up_min = intval(substr($snort_rules_upd_time, -2)); + $snort_rules_up_hr = intval(substr($snort_rules_upd_time, 0, 2)); $snort_rules_up_mday = "*/28"; $snort_rules_up_month = "*"; $snort_rules_up_wday = "*"; @@ -847,8 +912,8 @@ 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, $flowbit_rules_file, $snort_enforcing_rules_file; - global $snort_version, $rebuild_rules, $is_postinstall; + global $config, $g; + global $rebuild_rules; $snortdir = SNORTDIR; $rcdir = RCFILEPREFIX; @@ -890,7 +955,7 @@ function sync_snort_package_config() { configure_cron(); /* Do not attempt package sync if reinstalling package or booting */ - if (!$is_postinstall && !$g['booting']) + if (!$g['snort_postinstall'] && !$g['booting']) snort_sync_on_changes(); conf_mount_ro(); @@ -1372,7 +1437,7 @@ function snort_get_set_flowbits($rules_map) { return $set_flowbits; } -function snort_find_flowbit_required_rules($all_rules, $unchecked_flowbits) { +function snort_find_flowbit_required_rules($rules, $unchecked_flowbits) { /********************************************************/ /* This function finds all rules that must be enabled */ @@ -1382,7 +1447,7 @@ function snort_find_flowbit_required_rules($all_rules, $unchecked_flowbits) { /********************************************************/ $required_flowbits_rules = array(); - foreach ($all_rules as $k1 => $rule) { + foreach ($rules as $k1 => $rule) { if (!is_array($rule)) continue; foreach ($rule as $k2 => $rule2) { @@ -1420,7 +1485,7 @@ function snort_find_flowbit_required_rules($all_rules, $unchecked_flowbits) { return $required_flowbits_rules; } -function snort_resolve_flowbits($active_rules) { +function snort_resolve_flowbits($rules, $active_rules) { /******************************************************/ /* This function auto-resolves flowbit requirements */ @@ -1435,16 +1500,14 @@ function snort_resolve_flowbits($active_rules) { /* interface to resolve flowbit */ /* dependencies for. */ /* */ - /* NOTE: this function assumes the global variable */ - /* $all_rules is populated with all the rules */ - /* currently downloaded. */ + /* $rules --> Rules Map array containing */ + /* all the available rules. */ /******************************************************/ - global $all_rules; $snortdir = SNORTDIR; /* Check $all_rules array to be sure it is filled. */ - if (empty($all_rules)) { + if (empty($rules)) { log_error(gettext("[Snort] WARNING: Flowbit resolution not done - no rules in {$snortdir}/rules/ ...")); return array(); } @@ -1463,7 +1526,7 @@ function snort_resolve_flowbits($active_rules) { /* Now find all the needed "set flowbit" rules from */ /* the master list of all rules. */ - $required_rules = snort_find_flowbit_required_rules($all_rules, $delta_flowbits); + $required_rules = snort_find_flowbit_required_rules($rules, $delta_flowbits); /* Cleanup and release memory we no longer need. */ unset($delta_flowbits); @@ -1477,9 +1540,16 @@ function snort_write_flowbit_rules_file($flowbit_rules, $rule_file) { /* This function takes an array of rules in the */ /* rules_map format and writes them to the file */ /* given. */ + /* */ + /* $flowbit_rules --> array of flowbit-required */ + /* rules. */ + /* */ + /* $rule_file --> filename to write the */ + /* flowbit-required rules */ + /* to. */ /************************************************/ - global $flowbit_rules_file; + $flowbit_rules_file = FLOWBITS_FILENAME; /* See if we were passed a directory or full */ /* filename to write the rules to, and adjust */ @@ -1511,39 +1581,37 @@ function snort_write_flowbit_rules_file($flowbit_rules, $rule_file) { } } -function snort_load_vrt_policy($policy, $load_rules_map=true) { +function snort_load_vrt_policy($policy, $all_rules=null) { /************************************************/ /* This function returns an array of all rules */ /* marked with the passed in $policy metadata. */ /* */ - /* $policy --> desired VRT security policy */ - /* 1. connectivity */ - /* 2. balanced */ - /* 3. security */ + /* $policy --> desired VRT security policy */ + /* 1. connectivity */ + /* 2. balanced */ + /* 3. security */ /* */ - /* $load_rules --> load a local copy of all */ - /* the rules if true. If */ - /* false, assume the global */ - /* $all_rules array is valid. */ + /* $all_rules --> optional Rules Map array of */ + /* rules to scan for policy. */ + /* If not provided, then an */ + /* array will be created. */ /************************************************/ - global $all_rules; $snortdir = SNORTDIR; $vrt_policy_rules = array(); - /* Refresh the map of all the rules if flag */ - /* is set. */ - if ($load_rules_map) { + /* Load a map of all the VRT rules if we were */ + /* not passed a pre-loaded one to use. */ + if (is_null($all_rules)) { /* Since only Snort VRT rules have IPS Policy metadata, */ /* limit our search to just those files. */ $snort_vrt_files = glob("{$snortdir}/rules/snort_*.rules"); - $all_rules = array(); $all_rules = snort_load_rules_map($snort_vrt_files); } - /* Now walk the rules list and find all those that are defined */ - /* defined as active for the chosen security policy. */ + /* Now walk the rules list and find all those that are */ + /* defined as active for the chosen security policy. */ foreach ($all_rules as $k1 => $arulem) { foreach ($arulem as $k2 => $arulem2) { if (strripos($arulem2['rule'], "policy {$policy}-ips") !== false) { @@ -1567,11 +1635,6 @@ function snort_load_vrt_policy($policy, $load_rules_map=true) { /* Release memory we no longer need. */ unset($arulem, $arulem2); - /* If we loaded the ALL_RULES map, */ - /* then release the global memory. */ - if ($load_rules_map == true) - unset($GLOBALS['all_rules']); - /* Return all the rules that match the policy. */ return $vrt_policy_rules; } @@ -1582,11 +1645,15 @@ function snort_write_enforcing_rules_file($rule_map, $rule_path) { /* This function takes a rules map array of */ /* the rules chosen for the active rule set */ /* and writes them out to the passed path. */ + /* */ + /* $rule_map --> Rules Map array of rules to */ + /* write to disk. */ + /* */ + /* $rule_path --> filename or directory where */ + /* rules file will be written. */ /************************************************/ - global $snort_enforcing_rules_file; - - $rule_file = "/{$snort_enforcing_rules_file}"; + $rule_file = "/" . ENFORCING_RULES_FILENAME; /* See if we were passed a directory or full */ /* filename to write the rules to, and adjust */ @@ -1968,12 +2035,13 @@ EOD; function snort_deinstall() { - global $config, $g, $snort_rules_upd_log; + global $config, $g; $snortdir = SNORTDIR; $snortlibdir = SNORTLIBDIR; $snortlogdir = SNORTLOGDIR; $rcdir = RCFILEPREFIX; + $snort_rules_upd_log = RULES_UPD_LOGFILE; log_error(gettext("[Snort] Snort package uninstall in progress...")); @@ -2060,13 +2128,28 @@ function snort_deinstall() { function snort_prepare_rule_files($snortcfg, $snortcfgdir) { - global $snort_enforcing_rules_file, $flowbit_rules_file, $rebuild_rules, $all_rules; + /***********************************************************/ + /* This function builds a new set of enforcing rules for */ + /* Snort and writes them to disk. */ + /* */ + /* $snortcfg --> pointer to applicable section of */ + /* config.xml containing settings for */ + /* the interface. */ + /* */ + /* $snortcfgdir --> pointer to physical directory on */ + /* disk where Snort configuration is */ + /* to be written. */ + /***********************************************************/ + + global $rebuild_rules; $snortdir = SNORTDIR; + $flowbit_rules_file = FLOWBITS_FILENAME; + $snort_enforcing_rules_file = ENFORCING_RULES_FILENAME; $no_rules_defined = true; /* If there is no reason to rebuild the rules, exit to save time. */ - if ($rebuild_rules == "off") + if (!$rebuild_rules) return; /* Log a message for rules rebuild in progress */ @@ -2076,10 +2159,10 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { if (!empty($snortcfg['rulesets']) || $snortcfg['ips_policy_enable'] == 'on') { $enabled_rules = array(); $enabled_files = array(); + $all_rules = array(); $no_rules_defined = false; /* Load up all the rules into a Rules Map array. */ - $all_rules = array(); $all_rules = snort_load_rules_map("{$snortdir}/rules/"); /* Create an array with the filenames of the enabled */ @@ -2119,7 +2202,7 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { /* 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'])) { - $policy_rules = snort_load_vrt_policy($snortcfg['ips_policy'], false); + $policy_rules = snort_load_vrt_policy($snortcfg['ips_policy'], $all_rules); foreach ($policy_rules as $k1 => $policy) { foreach ($policy as $k2 => $p) { if (!is_array($enabled_rules[$k1])) @@ -2151,7 +2234,7 @@ 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('[Snort] Enabling any flowbit-required rules for: ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); - $fbits = snort_resolve_flowbits($enabled_rules); + $fbits = snort_resolve_flowbits($all_rules, $enabled_rules); /* Check for and disable any flowbit-required rules dependent upon */ /* disabled preprocessors if this option is enabled for the interface. */ @@ -2164,8 +2247,6 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { } else /* Just put an empty file to always have the file present */ snort_write_flowbit_rules_file(array(), "{$snortcfgdir}/rules/{$flowbit_rules_file}"); - - unset($GLOBALS['all_rules']); } else { snort_write_enforcing_rules_file(array(), "{$snortcfgdir}/rules/{$snort_enforcing_rules_file}"); snort_write_flowbit_rules_file(array(), "{$snortcfgdir}/rules/{$flowbit_rules_file}"); @@ -2197,10 +2278,16 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules, $persist_log = fa /* non-enabled preprocessors are disabled to stop */ /* start-up errors from unknown rule options. */ /* */ - /* $snortcfg -> config parameters array for */ - /* the interface */ - /* $active_rules -> rules_map array of enabled */ - /* rules for the interface */ + /* $snortcfg --> config parameters array for */ + /* the interface. */ + /* */ + /* $active_rules --> rules_map array of enabled */ + /* rules for the interface. */ + /* */ + /* $persist_log --> flag indicating if new log */ + /* file should be created or */ + /* the existing one appended */ + /* to. */ /* */ /* NOTE: This feature must be enabled in the GUI */ /* by the user. Use of this feature can */ @@ -2350,11 +2437,13 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules, $persist_log = fa function snort_generate_conf($snortcfg) { - global $config, $g, $flowbit_rules_file, $snort_enforcing_rules_file, $rebuild_rules; + global $config, $g, $rebuild_rules; $snortdir = SNORTDIR; $snortlibdir = SNORTLIBDIR; $snortlogdir = SNORTLOGDIR; + $flowbit_rules_file = FLOWBITS_FILENAME; + $snort_enforcing_rules_file = ENFORCING_RULES_FILENAME; if (!is_array($config['installedpackages']['snortglobal']['rule'])) return; @@ -2432,7 +2521,7 @@ function snort_generate_conf($snortcfg) { $pfkill = ""; if ($snortcfg['blockoffenderskill'] == "on") $pfkill = "kill"; - $spoink_wlist = snort_build_list($snortcfg, $snortcfg['whitelistname']); + $spoink_wlist = snort_build_list($snortcfg, $snortcfg['whitelistname'], true); /* write whitelist */ @file_put_contents("{$snortcfgdir}/{$snortcfg['whitelistname']}", implode("\n", $spoink_wlist)); $spoink_type = "output alert_pf: {$snortcfgdir}/{$snortcfg['whitelistname']},snort2c,{$snortcfg['blockoffendersip']},{$pfkill}"; @@ -2878,6 +2967,15 @@ EOD; if ($snortcfg['cksumcheck'] == 'on') $cksumcheck = "none"; + /* Pull in user-configurable detection config options */ + $cfg_detect_settings = "search-method {$snort_performance} max-pattern-len 20 max_queue_events 5"; + if ($snortcfg['fpm_split_any_any'] == "on") + $cfg_detect_settings .= " split-any-any"; + if ($snortcfg['fpm_search_optimize'] == "on") + $cfg_detect_settings .= " search-optimize"; + if ($snortcfg['fpm_no_stream_inserts'] == "on") + $cfg_detect_settings .= " no_stream_inserts"; + /* Pull in user-configurable options for Frag3 preprocessor settings */ $frag3_disabled = ""; if ($snortcfg['frag3_detection'] == "off") @@ -2901,6 +2999,13 @@ EOD; if (!empty($snortcfg['frag3_policy'])) $frag3_policy = "policy {$snortcfg['frag3_policy']}"; + /* Grab any user-customized value for Protocol Aware Flushing (PAF) max PDUs */ + $paf_max_pdu_config = "config paf_max: "; + if (empty($snortcfg['max_paf']) || $snortcfg['max_paf'] == "0") + $paf_max_pdu_config .= "0"; + else + $paf_max_pdu_config .= $snortcfg['max_paf']; + /* Pull in user-configurable options for Stream5 preprocessor settings */ $stream5_reassembly = ""; if ($snortcfg['stream5_reassembly'] == "off") @@ -2948,7 +3053,19 @@ EOD; if (!empty($snortcfg['stream5_icmp_timeout'])) $stream5_icmp_timeout = "timeout {$snortcfg['stream5_icmp_timeout']}"; - /* build snort configuration file */ + /* Check for and configure Host Attribute Table if enabled */ + $host_attrib_config = ""; + if ($snortcfg['host_attribute_table'] == "on" && !empty($snortcfg['host_attribute_data'])) { + file_put_contents("{$snortcfgdir}/host_attributes", base64_decode($snortcfg['host_attribute_data'])); + $host_attrib_config = "# Host Attribute Table #\n"; + $host_attrib_config .= "attribute_table filename {$snortcfgdir}/host_attributes\n"; + if (!empty($snortcfg['max_attribute_hosts'])) + $host_attrib_config .= "config max_attribute_hosts: {$snortcfg['max_attribute_hosts']}\n"; + if (!empty($snortcfg['max_attribute_services_per_host'])) + $host_attrib_config .= "config max_attribute_services_per_host: {$snortcfg['max_attribute_services_per_host']}"; + } + + /* Finally, build the Snort configuration file */ $snort_conf_text = <<<EOD # snort configuration file @@ -2968,6 +3085,9 @@ var PREPROC_RULE_PATH {$snortcfgdir}/preproc_rules # Define Server Ports # {$portvardef} +# Configure quiet startup mode # +config quiet + # Configure the snort decoder # config checksum_mode: {$cksumcheck} config disable_decode_alerts @@ -2986,15 +3106,15 @@ config pcre_match_limit: 3500 config pcre_match_limit_recursion: 1500 # Configure the detection engine # -config detection: search-method {$snort_performance} search-optimize max-pattern-len 20 max_queue_events 5 +config detection: {$cfg_detect_settings} 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 +# Configure protocol aware flushing # +# For more information see README.stream5 # +{$paf_max_pdu_config} #Configure dynamically loaded libraries dynamicpreprocessor directory {$snort_dirs['dynamicpreprocessor']} @@ -3002,11 +3122,12 @@ dynamicengine directory {$snort_dirs['dynamicengine']} dynamicdetection directory {$snort_dirs['dynamicrules']} # Inline packet normalization. For more information, see README.normalize -preprocessor normalize_ip4 -preprocessor normalize_tcp: ips ecn stream -preprocessor normalize_icmp4 -preprocessor normalize_ip6 -preprocessor normalize_icmp6 +# Disabled since we do not use "inline" mode with pfSense +# preprocessor normalize_ip4 +# preprocessor normalize_tcp: ips ecn stream +# preprocessor normalize_icmp4 +# preprocessor normalize_ip6 +# preprocessor normalize_icmp6 # Flow and stream # preprocessor frag3_global: {$frag3_memcap}, {$frag3_max_frags}{$frag3_disabled} @@ -3019,6 +3140,8 @@ preprocessor stream5_icmp: {$stream5_icmp_timeout} {$snort_preprocessors} +{$host_attrib_config} + # Snort Output Logs # output alert_csv: alert timestamp,sig_generator,sig_id,sig_rev,msg,proto,src,srcport,dst,dstport,id,classification,priority {$alertsystemlog_type} @@ -3052,10 +3175,10 @@ EOD; /* Uses XMLRPC to synchronize the changes to a remote node */ function snort_sync_on_changes() { - global $config, $g, $is_postinstall; + global $config, $g; /* Do not attempt a package sync while booting up or installing package */ - if ($g['booting'] || $is_postinstall) + if ($g['booting'] || $g['snort_postinstall']) return; if (is_array($config['installedpackages']['snortsync']['config'])){ @@ -3117,10 +3240,10 @@ function snort_sync_on_changes() { /* Do the actual XMLRPC sync */ function snort_do_xmlrpc_sync($syncdownloadrules, $sync_to_ip, $username, $password, $synctimeout, $syncstartsnort) { - global $config, $g, $is_postinstall; + global $config, $g; /* Do not attempt a package sync while booting up or installing package */ - if ($g['booting'] || $is_postinstall) + if ($g['booting'] || $g['snort_postinstall']) return; if(!$username || !$password || !$sync_to_ip) { @@ -3192,28 +3315,35 @@ function snort_do_xmlrpc_sync($syncdownloadrules, $sync_to_ip, $username, $passw $snortstart .= "else {log_error(gettext(\"[snort] XMLRPC pkg sync: Snort is running...\"));\n}\n"; } - /* Build a series of commands for the secondary host to execute that will load the new settings. */ - $execcmd = <<<EOD + /* Build a series of commands as a PHP file for the secondary host to execute to load the new settings. */ + $snort_sync_cmd = <<<EOD + <?php require_once("/usr/local/pkg/snort/snort.inc"); require_once("service-utils.inc"); - global \$g, \$rebuild_rules, \$snort_gui_include, \$is_postinstall, \$pkg_interface; + global \$g, \$rebuild_rules, \$snort_gui_include, \$pkg_interface; \$orig_pkg_interface = \$pkg_interface; - \$is_postinstall = true; + \$g["snort_postinstall"] = true; + \$g["snort_sync_in_progress"] = true; \$snort_gui_include = false; \$pkg_interface = "console"; {$downloadrulescmd} - \$is_postinstall = false; - log_error(gettext("[snort] XMLRPC pkg sync: Generating snort.conf file using Master Host's settings...")); - \$rebuild_rules = "on"; + unset(\$g["snort_postinstall"]); + log_error(gettext("[snort] XMLRPC pkg sync: Generating snort.conf file using Master Host settings...")); + \$rebuild_rules = true; sync_snort_package_config(); - \$rebuild_rules = "off"; + \$rebuild_rules = false; {$snortstart} log_error(gettext("[snort] XMLRPC pkg sync process on this host is complete...")); \$pkg_interface = \$orig_pkg_interface; + unset(\$g["snort_sync_in_progress"]); return true; + ?> EOD; + /* First, have the target host write the commands to a PHP file in the /tmp directory */ + $execcmd = "file_put_contents('/tmp/snort_sync_cmds.php', '{$snort_sync_cmd}');"; + /* assemble xmlrpc payload */ $method = 'pfsense.exec_php'; $params = array( @@ -3221,7 +3351,7 @@ EOD; XML_RPC_encode($execcmd) ); - log_error("[snort] Snort XMLRPC sending reload configuration cmd to {$url}:{$port}."); + log_error("[snort] Snort XMLRPC sending reload configuration cmd set as a file to {$url}:{$port}."); $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); $cli->setCredentials($username, $password); @@ -3237,6 +3367,27 @@ EOD; } else { log_error("[snort] Snort pkg XMLRPC reload configuration success with {$url}:{$port} (pfsense.exec_php)."); } + + /* Now assemble a command to execute the previously sent PHP file in the background */ + $execcmd = "exec(\"/usr/local/bin/php -f '/tmp/snort_sync_cmds.php' > /dev/null 2>&1 &\");"; + $params2 = array( + XML_RPC_encode($password), + XML_RPC_encode($execcmd) + ); + log_error("[snort] Snort XMLRPC sending {$url}:{$port} cmd to execute configuration reload."); + $msg2 = new XML_RPC_Message($method, $params2); + $resp = $cli->send($msg2, $synctimeout); + if(!$resp) { + $error = "A communications error occurred while attempting snort XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; + log_error($error); + file_notice("sync_settings", $error, "snort Settings Sync", ""); + } elseif($resp->faultCode()) { + $error = "An error code was received while attempting snort XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); + log_error($error); + file_notice("sync_settings", $error, "snort Settings Sync", ""); + } else { + log_error("[snort] Snort pkg XMLRPC reload configuration success with {$url}:{$port} (pfsense.exec_php)."); + } } ?> diff --git a/config/snort/snort.xml b/config/snort/snort.xml index 1066b75c..ed731f74 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.4.1</version> - <title>Services:2.9.4.1 pkg v. 2.5.8</title> + <version>2.9.4.6</version> + <title>Services:2.9.4.6 pkg v. 2.5.9</title> <include_file>/usr/local/pkg/snort/snort.inc</include_file> <menu> <name>Snort</name> @@ -183,6 +183,11 @@ <chmod>077</chmod> <item>http://www.pfsense.com/packages/config/snort/snort_rules_flowbits.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_edit_hat_data.php</item> + </additional_files_needed> <fields> </fields> <custom_add_php_command> diff --git a/config/snort/snort_alerts.php b/config/snort/snort_alerts.php index 8c42fa89..c296f81b 100755 --- a/config/snort/snort_alerts.php +++ b/config/snort/snort_alerts.php @@ -40,6 +40,90 @@ require_once("/usr/local/pkg/snort/snort.inc"); $snortalertlogt = $config['installedpackages']['snortglobal']['snortalertlogtype']; $supplist = array(); +function snort_is_alert_globally_suppressed($list, $gid, $sid) { + + /************************************************/ + /* Checks the passed $gid:$sid to see if it has */ + /* been globally suppressed. If true, then any */ + /* "track by_src" or "track by_dst" options are */ + /* disabled since they are overridden by the */ + /* global suppression of the $gid:$sid. */ + /************************************************/ + + /* If entry has a child array, then it's by src or dst ip. */ + /* So if there is a child array or the keys are not set, */ + /* then this gid:sid is not globally suppressed. */ + if (is_array($list[$gid][$sid])) + return false; + elseif (!isset($list[$gid][$sid])) + return false; + else + return true; +} + +function snort_add_supplist_entry($suppress) { + + /************************************************/ + /* Adds the passed entry to the Suppress List */ + /* for the active interface. If a Suppress */ + /* List is defined for the interface, it is */ + /* used. If no list is defined, a new default */ + /* list is created using the interface name. */ + /* */ + /* On Entry: */ + /* $suppress --> suppression entry text */ + /* */ + /* Returns: */ + /* TRUE if successful or FALSE on failure */ + /************************************************/ + + global $config, $a_instance, $instanceid; + + if (!is_array($config['installedpackages']['snortglobal']['suppress'])) + $config['installedpackages']['snortglobal']['suppress'] = array(); + if (!is_array($config['installedpackages']['snortglobal']['suppress']['item'])) + $config['installedpackages']['snortglobal']['suppress']['item'] = array(); + $a_suppress = &$config['installedpackages']['snortglobal']['suppress']['item']; + + $found_list = false; + + /* If no Suppress List is set for the interface, then create one with the interface name */ + if (empty($a_instance[$instanceid]['suppresslistname']) || $a_instance[$instanceid]['suppresslistname'] == 'default') { + $s_list = array(); + $s_list['name'] = $a_instance[$instanceid]['interface'] . "suppress"; + $s_list['uuid'] = uniqid(); + $s_list['descr'] = "Auto-generated list for Alert suppression"; + $s_list['suppresspassthru'] = base64_encode($suppress); + $a_suppress[] = $s_list; + $a_instance[$instanceid]['suppresslistname'] = $s_list['name']; + $found_list = true; + } else { + /* If we get here, a Suppress List is defined for the interface so see if we can find it */ + foreach ($a_suppress as $a_id => $alist) { + if ($alist['name'] == $a_instance[$instanceid]['suppresslistname']) { + $found_list = true; + if (!empty($alist['suppresspassthru'])) { + $tmplist = base64_decode($alist['suppresspassthru']); + $tmplist .= "\n{$suppress}"; + $alist['suppresspassthru'] = base64_encode($tmplist); + $a_suppress[$a_id] = $alist; + } + } + } + } + + /* If we created a new list or updated an existing one, save the change, */ + /* tell Snort to load it, and return true; otherwise return false. */ + if ($found_list) { + write_config(); + sync_snort_package_config(); + snort_reload_config($a_instance[$instanceid]); + return true; + } + else + return false; +} + if ($_GET['instance']) $instanceid = $_GET['instance']; if ($_POST['instance']) @@ -92,35 +176,38 @@ if ($_GET['act'] == "addsuppress" && is_numeric($_GET['sidid']) && is_numeric($_ $suppress = "suppress gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}\n"; else $suppress = "#{$_GET['descr']}\nsuppress gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}"; - if (!is_array($config['installedpackages']['snortglobal']['suppress'])) - $config['installedpackages']['snortglobal']['suppress'] = array(); - if (!is_array($config['installedpackages']['snortglobal']['suppress']['item'])) - $config['installedpackages']['snortglobal']['suppress']['item'] = array(); - $a_suppress = &$config['installedpackages']['snortglobal']['suppress']['item']; - if (empty($a_instance[$instanceid]['suppresslistname']) || $a_instance[$instanceid]['suppresslistname'] == 'default') { - $s_list = array(); - $s_list['name'] = $a_instance[$instanceid]['interface'] . "suppress"; - $s_list['uuid'] = uniqid(); - $s_list['descr'] = "Auto-generated list for suppress"; - $s_list['suppresspassthru'] = base64_encode($suppress); - $a_suppress[] = $s_list; - $a_instance[$instanceid]['suppresslistname'] = $s_list['name']; - } else { - foreach ($a_suppress as $a_id => $alist) { - if ($alist['name'] == $a_instance[$instanceid]['suppresslistname']) { - if (!empty($alist['suppresspassthru'])) { - $tmplist = base64_decode($alist['suppresspassthru']); - $tmplist .= "\n{$suppress}"; - $alist['suppresspassthru'] = base64_encode($tmplist); - $a_suppress[$a_id] = $alist; - } - } - } + /* Add the new entry to the Suppress List */ + if (snort_add_supplist_entry($suppress)) + $savemsg = "An entry for 'suppress gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}' has been added to the Suppress List."; + else + $input_errors[] = gettext("Suppress List '{$a_instance[$instanceid]['suppresslistname']}' is defined for this interface, but it could not be found!"); +} + +if (($_GET['act'] == "addsuppress_srcip" || $_GET['act'] == "addsuppress_dstip") && is_numeric($_GET['sidid']) && is_numeric($_GET['gen_id'])) { + if ($_GET['act'] == "addsuppress_srcip") + $method = "by_src"; + else + $method = "by_dst"; + + /* Check for valid IP addresses, exit if not valid */ + if (is_ipaddr($_GET['ip']) || is_ipaddrv6($_GET['ip'])) { + if (empty($_GET['descr'])) + $suppress = "suppress gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}, track {$method}, ip {$_GET['ip']}\n"; + else + $suppress = "#{$_GET['descr']}\nsuppress gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}, track {$method}, ip {$_GET['ip']}\n"; } - $savemsg = "An entry for 'suppress gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}' has been added to the Suppress List."; - write_config(); - sync_snort_package_config(); + else { + header("Location: /snort/snort_alerts.php?instance={$instanceid}"); + exit; + } + + /* Add the new entry to the Suppress List */ + if (snort_add_supplist_entry($suppress)) + $savemsg = "An entry for 'suppress gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}, track {$method}, ip {$_GET['ip']}' has been added to the Suppress List."; + else + /* We did not find the defined list, so notify the user with an error */ + $input_errors[] = gettext("Suppress List '{$a_instance[$instanceid]['suppresslistname']}' is defined for this interface, but it could not be found!"); } if ($_GET['action'] == "clear" || $_POST['delete']) { @@ -162,7 +249,7 @@ if ($_POST['download']) { } /* Load up an array with the current Suppression List GID,SID values */ -$supplist = snort_load_suppress_sigs($a_instance[$instanceid]); +$supplist = snort_load_suppress_sigs($a_instance[$instanceid], true); $pgtitle = "Services: Snort: Snort Alerts"; include_once("head.inc"); @@ -265,6 +352,7 @@ if ($pconfig['arefresh'] == 'on') <col axis="string"> </colgroup> <thead> + <tr> <th class="listhdrr" axis="date"><?php echo gettext("DATE"); ?></th> <th class="listhdrr" axis="number"><?php echo gettext("PRI"); ?></th> <th class="listhdrr" axis="string"><?php echo gettext("PROTO"); ?></th> @@ -275,6 +363,7 @@ if ($pconfig['arefresh'] == 'on') <th class="listhdrr" axis="string"><?php echo gettext("DPORT"); ?></th> <th class="listhdrr" axis="number"><?php echo gettext("SID"); ?></th> <th class="listhdrr" axis="string"><?php echo gettext("DESCRIPTION"); ?></th> + </tr> </thead> <tbody> <?php @@ -307,9 +396,19 @@ if (file_exists("/var/log/snort/snort_{$if_real}{$snort_uuid}/alert")) { $alert_ip_src = $fields[6]; /* Add zero-width space as soft-break opportunity after each colon if we have an IPv6 address */ $alert_ip_src = str_replace(":", ":​", $alert_ip_src); + if (!snort_is_alert_globally_suppressed($supplist, $fields[1], $fields[2]) && + !isset($supplist[$fields[1]][$fields[2]]['by_src'][$fields[6]])) { + $alert_ip_src .= "<br/><a href='?instance={$instanceid}&act=addsuppress_srcip&sidid={$fields[2]}&gen_id={$fields[1]}&descr={$alert_descr_url}&ip=" . trim(urlencode($fields[6])) . "'>"; + $alert_ip_src .= "<img src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' "; + $alert_ip_src .= "title='" . gettext("Add this gen_id:sig_id track by_src IP to Suppress List") . "'></a>"; + } + elseif (isset($supplist[$fields[1]][$fields[2]]['by_src'][$fields[6]])) { + $alert_ip_src .= "<br/><img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='12' height='12' border='0' "; + $alert_ip_src .= "title='" . gettext("This gen_id:sig_id track by_src IP already in Suppress List") . "'/>"; + } if (isset($tmpblocked[$fields[6]])) { - $alert_ip_src .= "<br/><a href='?instance={$id}&todelete=" . trim(urlencode($fields[6])) . "'> - <img title=\"" . gettext("Remove host from Blocked Table") . "\" border=\"0\" width='10' height='10' name='todelete' id='todelete' alt=\"Remove from Blocked Hosts\" src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/></a>"; + $alert_ip_src .= " <a href='?instance={$id}&todelete=" . trim(urlencode($fields[6])) . "'> + <img title=\"" . gettext("Remove host from Blocked Table") . "\" border=\"0\" width='12' height='12' name='todelete' id='todelete' alt=\"Remove from Blocked Hosts\" src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/></a>"; } /* IP SRC Port */ $alert_src_p = $fields[7]; @@ -317,21 +416,31 @@ if (file_exists("/var/log/snort/snort_{$if_real}{$snort_uuid}/alert")) { $alert_ip_dst = $fields[8]; /* Add zero-width space as soft-break opportunity after each colon if we have an IPv6 address */ $alert_ip_dst = str_replace(":", ":​", $alert_ip_dst); + if (!snort_is_alert_globally_suppressed($supplist, $fields[1], $fields[2]) && + !isset($supplist[$fields[1]][$fields[2]]['by_dst'][$fields[8]])) { + $alert_ip_dst .= "<br/><a href='?instance={$instanceid}&act=addsuppress_dstip&sidid={$fields[2]}&gen_id={$fields[1]}&descr={$alert_descr_url}&ip=" . trim(urlencode($fields[8])) . "'>"; + $alert_ip_dst .= "<img src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' "; + $alert_ip_dst .= "title='" . gettext("Add this gen_id:sig_id track by_dst IP to Suppress List") . "'></a>"; + } + elseif (isset($supplist[$fields[1]][$fields[2]]['by_dst'][$fields[8]])) { + $alert_ip_dst .= "<br/><img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='12' height='12' border='0' "; + $alert_ip_dst .= "title='" . gettext("This gen_id:sig_id track by_dst IP already in Suppress List") . "'/>"; + } if (isset($tmpblocked[$fields[8]])) { - $alert_ip_dst .= "<br/><a href='?instance={$id}&todelete=" . trim(urlencode($fields[8])) . "'> - <img title=\"" . gettext("Remove host from Blocked Table") . "\" border=\"0\" width='10' height='10' name='todelete' id='todelete' alt=\"Remove from Blocked Hosts\" src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/></a>"; + $alert_ip_dst .= " <a href='?instance={$id}&todelete=" . trim(urlencode($fields[8])) . "'> + <img title=\"" . gettext("Remove host from Blocked Table") . "\" border=\"0\" width='12' height='12' name='todelete' id='todelete' alt=\"Remove from Blocked Hosts\" src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/></a>"; } /* IP DST Port */ $alert_dst_p = $fields[9]; /* SID */ $alert_sid_str = "{$fields[1]}:{$fields[2]}"; - if (!isset($supplist[$fields[1]][$fields[2]])) { + if (!snort_is_alert_globally_suppressed($supplist, $fields[1], $fields[2])) { $sidsupplink = "<a href='?instance={$instanceid}&act=addsuppress&sidid={$fields[2]}&gen_id={$fields[1]}&descr={$alert_descr_url}'>"; - $sidsupplink .= "<img src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='10' height='10' border='0' "; + $sidsupplink .= "<img src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' "; $sidsupplink .= "title='" . gettext("Add this gen_id:sig_id to Suppress List") . "'></a>"; } else { - $sidsupplink = "<img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='10' height='10' border='0' "; + $sidsupplink = "<img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='12' height='12' border='0' "; $sidsupplink .= "title='" . gettext("This gen_id:sig_id already in Suppress List") . "'/>"; } $alert_class = $fields[11]; @@ -368,5 +477,6 @@ if (file_exists("/var/log/snort/snort_{$if_real}{$snort_uuid}/alert")) { <?php include("fend.inc"); ?> + </body> </html> diff --git a/config/snort/snort_barnyard.php b/config/snort/snort_barnyard.php index 2773fe95..a5c1ffec 100644 --- a/config/snort/snort_barnyard.php +++ b/config/snort/snort_barnyard.php @@ -89,7 +89,7 @@ if ($_POST) { write_config(); /* No need to rebuild rules if just toggling Barnyard2 on or off */ - $rebuild_rules = "off"; + $rebuild_rules = false; sync_snort_package_config(); /* after click go to this page */ @@ -108,16 +108,11 @@ $pgtitle = "Snort: Interface: {$if_friendly} Barnyard2 Edit"; include_once("head.inc"); ?> -<body - link="#0000CC" vlink="#0000CC" alink="#0000CC"> - +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> <?php include("fbegin.inc"); ?> <?if($pfsense_stable == 'yes'){echo '<p class="pgtitle">' . $pgtitle . '</p>';}?> -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> -<?php include_once("fbegin.inc"); -?> <script language="JavaScript"> <!-- @@ -184,7 +179,7 @@ function enable_change(enable_change) { <td width="22%" valign="top" class="vncellreq"><?php echo gettext("Enable"); ?></td> <td width="78%" class="vtable"> <input name="barnyard_enable" type="checkbox" value="on" <?php if ($pconfig['barnyard_enable'] == "on") echo "checked"; ?> onClick="enable_change(false)"> - <strong><?php echo gettext("Enable Barnyard2"); ?></strong><br> + <strong><?php echo gettext("Enable Barnyard2"); ?></strong><br/> <?php echo gettext("This will enable barnyard2 for this interface. You will also have to set the database credentials."); ?></td> </tr> <tr> @@ -194,9 +189,9 @@ function enable_change(enable_change) { <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" style="width:95%;" size="85" - value="<?=htmlspecialchars($pconfig['barnyard_mysql']);?>"> <br> + value="<?=htmlspecialchars($pconfig['barnyard_mysql']);?>"> <br/> <span class="vexpl"><?php echo gettext("Example: output database: alert, mysql, " . - "dbname=snort user=snort host=localhost password=xyz"); ?><br> + "dbname=snort user=snort host=localhost password=xyz"); ?><br/> <?php echo gettext("Example: output database: log, mysql, dbname=snort user=snort " . "host=localhost password=xyz"); ?></span></td> </tr> @@ -204,11 +199,11 @@ function enable_change(enable_change) { <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Advanced Settings"); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"<?php echo gettext("Advanced configuration " . + <td width="22%" valign="top" class="vncell"><?php echo gettext("Advanced configuration " . "pass through"); ?></td> <td width="78%" class="vtable"><textarea name="barnconfigpassthru" style="width:95%;" cols="65" rows="7" id="barnconfigpassthru" ><?=htmlspecialchars($pconfig['barnconfigpassthru']);?></textarea> - <br> + <br/> <?php echo gettext("Arguments here will be automatically inserted into the running " . "barnyard2 configuration."); ?></td> </tr> @@ -220,8 +215,8 @@ function enable_change(enable_change) { </tr> <tr> <td width="22%" valign="top"> </td> - <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> - <br> + <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span></span> + <br/> <?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 43b351ab..56edfbc5 100644 --- a/config/snort/snort_blocked.php +++ b/config/snort/snort_blocked.php @@ -191,10 +191,12 @@ if ($pconfig['brefresh'] == 'on') <col width="10%" align="center"> </colgroup> <thead> + <tr> <th class="listhdrr" axis="number">#</th> <th class="listhdrr" axis="string"><?php echo gettext("IP"); ?></th> <th class="listhdrr" axis="string"><?php echo gettext("Alert Description"); ?></th> <th class="listhdrr"><?php echo gettext("Remove"); ?></th> + </tr> </thead> <tbody> <?php diff --git a/config/snort/snort_check_for_rule_updates.php b/config/snort/snort_check_for_rule_updates.php index 2b60b6ce..c40d6ff4 100755 --- a/config/snort/snort_check_for_rule_updates.php +++ b/config/snort/snort_check_for_rule_updates.php @@ -33,13 +33,33 @@ require_once("functions.inc"); require_once("service-utils.inc"); require_once "/usr/local/pkg/snort/snort.inc"; -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, $g, $pkg_interface; +global $g, $pkg_interface, $snort_gui_include, $rebuild_rules; + + +if (!defined("VRT_DNLD_FILENAME")) + define("VRT_DNLD_FILENAME", "snortrules-snapshot-2946.tar.gz"); +if (!defined("VRT_DNLD_URL")) + define("VRT_DNLD_URL", "https://www.snort.org/reg-rules/"); +if (!defined("ET_VERSION")) + define("ET_VERSION", "2.9.0"); +if (!defined("ET_DNLD_FILENAME")) + define("ET_DNLD_FILENAME", "emerging.rules.tar.gz"); +if (!defined("GPLV2_DNLD_FILENAME")) + define("GPLV2_DNLD_FILENAME", "community-rules.tar.gz"); +if (!defined("GPLV2_DNLD_URL")) + define("GPLV2_DNLD_URL", "https://s3.amazonaws.com/snort-org/www/rules/community/"); +if (!defined("FLOWBITS_FILENAME")) + define("FLOWBITS_FILENAME", "flowbit-required.rules"); +if (!defined("ENFORCING_RULES_FILENAME")) + define("ENFORCING_RULES_FILENAME", "snort.rules"); +if (!defined("RULES_UPD_LOGFILE")) + define("RULES_UPD_LOGFILE", SNORTLOGDIR . "/snort_rules_update.log"); + $snortdir = SNORTDIR; $snortlibdir = SNORTLIBDIR; $snortlogdir = SNORTLOGDIR; +$snort_rules_upd_log = RULES_UPD_LOGFILE; /* Save the state of $pkg_interface so we can restore it */ $pkg_interface_orig = $pkg_interface; @@ -56,21 +76,23 @@ $snortcommunityrules = $config['installedpackages']['snortglobal']['snortcommuni $vrt_enabled = $config['installedpackages']['snortglobal']['snortdownload']; $et_enabled = $config['installedpackages']['snortglobal']['emergingthreats']; -/* Directory where we download rule tarballs */ +/* Working directory for downloaded rules 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}/"; -/* Use current Sourcefire VRT download URL and abandon the old CGI one */ -$snort_rule_url = "https://www.snort.org/reg-rules/"; +/* Snort VRT rules filenames and URL */ +$snort_filename = VRT_DNLD_FILENAME; +$snort_filename_md5 = VRT_DNLD_FILENAME . ".md5"; +$snort_rule_url = VRT_DNLD_URL; -/* Emerging Threats rules MD5 file */ -$emergingthreats_filename_md5 = "{$emergingthreats_filename}.md5"; +/* Emerging Threats rules filenames and URL */ +$emergingthreats_filename = ET_DNLD_FILENAME; +$emergingthreats_filename_md5 = ET_DNLD_FILENAME . ".md5"; +$emerging_threats_version = ET_VERSION; -/* Snort GPLv2 Community Rules MD5 file */ -$snort_community_rules_filename_md5 = "{$snort_community_rules_filename}.md5"; +/* Snort GPLv2 Community Rules filenames and URL */ +$snort_community_rules_filename = GPLV2_DNLD_FILENAME; +$snort_community_rules_filename_md5 = GPLV2_DNLD_FILENAME . ".md5"; +$snort_community_rules_url = GPLV2_DNLD_URL; /* Custom function for rules file download via URL */ function snort_download_file_url($url, $file_out) { @@ -80,10 +102,11 @@ function snort_download_file_url($url, $file_out) { /* by $url using the CURL library functions and */ /* saves the content to the file specified by */ /* $file. */ - /* */ + /* */ + /* It provides logging of returned CURL errors. */ /************************************************/ - global $g, $config, $pkg_interface, $last_curl_error; + global $g, $config, $pkg_interface, $last_curl_error, $fout, $ch, $file_size, $downloaded; /* Array of message strings for HTTP Response Codes */ $http_resp_msg = array( 200 => "OK", 202 => "Accepted", 204 => "No Content", 205 => "Reset Content", @@ -97,19 +120,21 @@ function snort_download_file_url($url, $file_out) { $last_curl_error = ""; - /* If not in console mode, use the built-in progress-bar function */ - if ($pkg_interface <> "console") - return download_file_with_progress_bar($url, $file_out); - - /* Otherwise, use our custom function with no output */ - /* (Note: required to suppress errors from XMLRPC) */ - $fp = fopen($file_out, "wb"); - if ($fp) { + $fout = fopen($file_out, "wb"); + if ($fout) { $ch = curl_init($url); if (!$ch) return false; - curl_setopt($ch, CURLOPT_FILE, $fp); - curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_FILE, $fout); + + /* NOTE: required to suppress errors from XMLRPC due to progress bar output */ + if ($g['snort_sync_in_progress']) + curl_setopt($ch, CURLOPT_HEADER, false); + else { + curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header'); + curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'read_body'); + } + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Win64; x64; Trident/6.0)"); /* Don't verify SSL peers since we don't have the certificates to do so. */ @@ -134,7 +159,7 @@ function snort_download_file_url($url, $file_out) { if (isset($http_resp_msg[$http_code])) $last_curl_error = $http_resp_msg[$http_code]; curl_close($ch); - fclose($fp); + fclose($fout); /* If we had to try more than once, log it */ if ($counter > 1) log_error(gettext("File '" . basename($file_out) . "' download attempts: {$counter} ...")); @@ -417,9 +442,9 @@ if ($emergingthreats == "on") { /* If using Sourcefire VRT rules with ET, then we should use the open-nogpl ET rules. */ if ($vrt_enabled == "on") - $rc = snort_download_file_url("http://rules.emergingthreats.net/open-nogpl/snort-{$emerging_threats_version}/emerging.rules.tar.gz", "{$tmpfname}/{$emergingthreats_filename}"); + $rc = snort_download_file_url("http://rules.emergingthreats.net/open-nogpl/snort-{$emerging_threats_version}/{$emergingthreats_filename}", "{$tmpfname}/{$emergingthreats_filename}"); else - $rc = snort_download_file_url("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz", "{$tmpfname}/{$emergingthreats_filename}"); + $rc = snort_download_file_url("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/{$emergingthreats_filename}", "{$tmpfname}/{$emergingthreats_filename}"); /* Test for a valid rules file download. Turn off ET update if download failed. */ if ($rc === true) { @@ -675,10 +700,10 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules = /* 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'; + if ($g['snort_postinstall']) + $rebuild_rules = false; else - $rebuild_rules = 'on'; + $rebuild_rules = true; /* Create configuration for each active Snort interface */ foreach ($config['installedpackages']['snortglobal']['rule'] as $id => $value) { @@ -708,7 +733,7 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules = } /* Clear the rebuild rules flag. */ - $rebuild_rules = 'off'; + $rebuild_rules = false; /* remove old $tmpfname files */ if (is_dir("{$snortdir}/tmp")) { diff --git a/config/snort/snort_define_servers.php b/config/snort/snort_define_servers.php index 8c19325b..371bbecd 100755 --- a/config/snort/snort_define_servers.php +++ b/config/snort/snort_define_servers.php @@ -127,7 +127,7 @@ if ($_POST) { write_config(); /* Update the snort conf file for this interface. */ - $rebuild_rules = "off"; + $rebuild_rules = false; snort_generate_conf($a_nat[$id]); /* after click go to this page */ diff --git a/config/snort/snort_download_updates.php b/config/snort/snort_download_updates.php index c6e24532..1f87fbbc 100755 --- a/config/snort/snort_download_updates.php +++ b/config/snort/snort_download_updates.php @@ -36,11 +36,13 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g, $snort_rules_upd_log, $snort_rules_file, $emergingthreats_filename; - +/* Define some locally required variables from Snort constants */ $snortdir = SNORTDIR; - +$snort_rules_upd_log = RULES_UPD_LOGFILE; $log = $snort_rules_upd_log; +$snort_rules_file = VRT_DNLD_FILENAME; +$emergingthreats_filename = ET_DNLD_FILENAME; +$snort_community_rules_filename = GPLV2_DNLD_FILENAME; /* load only javascript that is needed */ $snort_load_jquery = 'yes'; @@ -133,8 +135,8 @@ h += 96; <tr> <td id="download_rules_td" style="background-color: #eeeeee"> <div height="32" width="725px" style="background-color: #eeeeee"> - <font color="#777777" size="2.5px"> <p style="text-align: left; margin-left: 225px;"> + <font color="#777777" size="2.5px"> <b><?php echo gettext("INSTALLED RULESET SIGNATURES"); ?></b></font><br/><br/> <font color="#FF850A" size="1px"><b>SNORT.ORG --></b></font> <font size="1px" color="#000000"> <? echo $snort_org_sig_chk_local; ?></font><br/> @@ -213,8 +215,9 @@ h += 96; <td id="download_rules_td" style='background-color: #eeeeee'> <div height="32" width="725px" style='background-color: #eeeeee'><span class="vexpl"> <span class="red"><b><?php echo gettext("NOTE:"); ?></b></span> - <?php echo gettext("Snort.org and EmergingThreats.net " . - "will go down from time to time. Please be patient."); ?></span> + <a href="http://www.snort.org/" target="_blank"><?php echo gettext("Snort.org") . "</a>" . + gettext(" and ") . "<a href=\"http://www.emergingthreats.net/\" target=\"_blank\">" . gettext("EmergingThreats.net") . "</a>" . + gettext(" will go down from time to time. Please be patient."); ?></span> </div> </td> </tr> diff --git a/config/snort/snort_edit_hat_data.php b/config/snort/snort_edit_hat_data.php new file mode 100644 index 00000000..f0562046 --- /dev/null +++ b/config/snort/snort_edit_hat_data.php @@ -0,0 +1,126 @@ +<?php +/* + * snort_edit_hat_data.php + * Copyright (C) 2004 Scott Ullrich + * Copyright (C) 2011-2012 Ermal Luci + * All rights reserved. + * + * originially part of m0n0wall (http://m0n0.ch/wall) + * Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. + * All rights reserved. + * + * modified for the pfsense snort package + * Copyright (C) 2009-2010 Robert Zelaya. + * 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. + */ + +require_once("guiconfig.inc"); +require_once("/usr/local/pkg/snort/snort.inc"); + +global $g, $rebuild_rules; + +$snortdir = SNORTDIR; + +if (!is_array($config['installedpackages']['snortglobal']['rule'])) { + $config['installedpackages']['snortglobal']['rule'] = array(); +} +$a_nat = &$config['installedpackages']['snortglobal']['rule']; + +$id = $_GET['id']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (is_null($id)) { + header("Location: /snort/snort_interfaces.php"); + exit; +} + +if (!empty($a_nat[$id]['host_attribute_data'])) + $pconfig['host_attribute_data'] = base64_decode($a_nat[$id]['host_attribute_data']); +else + $pconfig['host_attribute_data'] = ""; + +if ($_POST['clear']) { + unset($a_nat[$id]['host_attribute_data']); + write_config(); + $rebuild_rules = false; + snort_generate_conf($a_nat[$id]); + header("Location: /snort/snort_edit_hat_data.php?id={$id}"); + exit; +} + +if ($_POST['host_attribute_data']) { + $a_nat[$id]['host_attribute_data'] = base64_encode($_POST['host_attribute_data']); + write_config(); + $rebuild_rules = false; + snort_generate_conf($a_nat[$id]); + header("Location: /snort/snort_preprocessors.php?id={$id}"); + exit; +} + + +$if_friendly = snort_get_friendly_interface($a_nat[$id]['interface']); +$pgtitle = "Services: Snort: {$if_friendly} Host Attribute Table Data"; +include_once("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC" > + +<?php +include("fbegin.inc"); +if($pfsense_stable == 'yes'){echo '<p class="pgtitle">' . $pgtitle . '</p>';} +if ($input_errors) print_input_errors($input_errors); +if ($savemsg) + print_info_box($savemsg); +?> +<form action="snort_edit_hat_data.php" method="post" name="iform" id="iform"> +<div id="boxarea"> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> +<tr> +<td class="tabcont"> +<table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="middle" class="listtopic"><?php echo gettext("Edit Host Attribute Table Data"); ?></td> + </tr> + <tr> + <td> + <input type='hidden' name='id' value='<?=$id;?>'> + <textarea wrap="off" cols="80" rows="35" name="host_attribute_data" id="host_attribute_data" style="width:99%; height:100%;"><?=$pconfig['host_attribute_data'];?></textarea></td> + </tr> + <tr> + <td> + <input name="Submit" type="submit" class="formbtn" value="<?php echo gettext(" Save "); ?>" title=" <?php echo gettext("Save Host Attribute data"); ?>"/> + <input type="button" class="formbtn" value=" <?php echo gettext("Return"); ?>" onclick="parent.location='snort_preprocessors.php?id=<?=$id;?>'" title="<?php echo gettext("Return to Preprocessors tab"); ?>"/> + <input name="clear" type="submit" class="formbtn" id="clear" value="<?php echo gettext("Clear"); ?>" onclick="return confirm('<?php echo gettext("This will erase all Host Attribute data for the interface. Are you sure?"); ?>')" title="<?php echo gettext("Deletes all Host Attribute data"); ?>"/> + </td> + </tr> +</table> +</td> +</tr> +</table> +</div> +</form> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/snort/snort_interfaces.php b/config/snort/snort_interfaces.php index 390b83eb..84273167 100755 --- a/config/snort/snort_interfaces.php +++ b/config/snort/snort_interfaces.php @@ -145,9 +145,9 @@ if ($_GET['act'] == 'toggle' && is_numeric($id)) { log_error("Toggle (snort starting) for {$if_friendly}({$snortcfg['descr']})..."); /* set flag to rebuild interface rules before starting Snort */ - $rebuild_rules = "on"; + $rebuild_rules = true; sync_snort_package_config(); - $rebuild_rules = "off"; + $rebuild_rules = false; snort_start($snortcfg, $if_real); header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); @@ -364,7 +364,7 @@ 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']);?> </font> </td> <td valign="middle" class="list" nowrap> <table border="0" cellspacing="0" cellpadding="0"> diff --git a/config/snort/snort_interfaces_edit.php b/config/snort/snort_interfaces_edit.php index 08d7d2ba..bbd4338c 100755 --- a/config/snort/snort_interfaces_edit.php +++ b/config/snort/snort_interfaces_edit.php @@ -53,12 +53,12 @@ $pconfig = array(); if (empty($snortglob['rule'][$id]['uuid'])) { /* Adding new interface, so flag rules to build. */ $pconfig['uuid'] = snort_generate_id(); - $rebuild_rules = "on"; + $rebuild_rules = true; } else { $pconfig['uuid'] = $a_rule[$id]['uuid']; $pconfig['descr'] = $a_rule[$id]['descr']; - $rebuild_rules = "off"; + $rebuild_rules = false; } $snort_uuid = $pconfig['uuid']; @@ -137,6 +137,9 @@ if ($_POST["Submit"]) { if ($_POST['alertsystemlog'] == "on") { $natent['alertsystemlog'] = 'on'; }else{ $natent['alertsystemlog'] = 'off'; } if ($_POST['configpassthru']) $natent['configpassthru'] = base64_encode($_POST['configpassthru']); else unset($natent['configpassthru']); if ($_POST['cksumcheck']) $natent['cksumcheck'] = 'on'; else $natent['cksumcheck'] = 'off'; + if ($_POST['fpm_split_any_any'] == "on") { $natent['fpm_split_any_any'] = 'on'; }else{ $natent['fpm_split_any_any'] = 'off'; } + if ($_POST['fpm_search_optimize'] == "on") { $natent['fpm_search_optimize'] = 'on'; }else{ $natent['fpm_search_optimize'] = 'off'; } + if ($_POST['fpm_no_stream_inserts'] == "on") { $natent['fpm_no_stream_inserts'] = 'on'; }else{ $natent['fpm_no_stream_inserts'] = 'off'; } $if_real = snort_get_real_interface($natent['interface']); if (isset($id) && $a_rule[$id]) { @@ -158,7 +161,7 @@ if ($_POST["Submit"]) { write_config(); /* Most changes don't require a rules rebuild, so default to "off" */ - $rebuild_rules = "off"; + $rebuild_rules = false; /* Update snort.conf and snort.sh files for this interface */ sync_snort_package_config(); @@ -170,7 +173,7 @@ if ($_POST["Submit"]) { /* Snort instance to safely reload these parameters. */ /*******************************************************/ if ($snort_reload == true) - snort_reload_config($natent, $if_real); + snort_reload_config($natent, "SIGHUP"); header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); @@ -316,10 +319,10 @@ include_once("head.inc"); </td> </tr> <tr> - <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Performance Settings"); ?></td> + <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Detection Performance Settings"); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Memory Performance"); ?></td> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Search Method"); ?></td> <td width="78%" class="vtable"> <select name="performance" class="formselect" id="performance"> <?php @@ -332,7 +335,8 @@ include_once("head.inc"); <?=htmlspecialchars($ifacename2);?></option> <?php endforeach; ?> </select> - <?php echo gettext("Choose a search performance setting"); ?><br/> + <?php echo gettext("Choose a fast pattern matcher algorithm. ") . "<strong>" . gettext("Default") . + "</strong>" . gettext(" is ") . "<strong>" . gettext("AC-BNFA") . "</strong>"; ?>.<br/><br/> <span class="vexpl"><?php echo gettext("LOWMEM and AC-BNFA are recommended for low end " . "systems, AC-SPLIT: low memory, high performance, short-hand for search-method ac split-any-any, AC: high memory, " . "best performance, -NQ: the -nq option specifies that matches should not be queued and evaluated as they are found," . @@ -341,6 +345,39 @@ include_once("head.inc"); </span><br/></td> </tr> <tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Split ANY-ANY"); ?></td> + <td width="78%" class="vtable"> + <input name="fpm_split_any_any" id="fpm_split_any_any" type="checkbox" value="on" <?php if ($pconfig['fpm_split_any_any'] == "on") echo "checked"; ?>> + <?php echo gettext("Enable splitting of ANY-ANY port group.") . " <strong>" . gettext("Default") . "</strong>" . gettext(" is ") . + "<strong>" . gettext("Not Checked") . "</strong>"; ?>.<br/> + <br/><?php echo gettext("This setting is a memory/performance trade-off. It reduces memory footprint by not " . + "putting the ANY-ANY port group into every port group, but instead splits these rules off into a single port group. " . + "But doing so may require two port group evaluations per packet - one for the specific port group and one for the ANY-ANY " . + "port group, thus potentially reducing performance."); ?> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Search Optimize"); ?></td> + <td width="78%" class="vtable"> + <input name="fpm_search_optimize" id="fpm_search_optimize" type="checkbox" value="on" <?php if ($pconfig['fpm_search_optimize'] == "on" || empty($pconfig['fpm_search_optimize'])) echo "checked"; ?>> + <?php echo gettext("Enable search optimization.") . " <strong>" . gettext("Default") . "</strong>" . gettext(" is ") . + "<strong>" . gettext("Checked") . "</strong>"; ?>.<br/> + <br/><?php echo gettext("This setting optimizes fast pattern memory when used with search-methods AC or AC-SPLIT " . + "by dynamically determining the size of a state based on the total number of states. When used with AC-BNFA, " . + "some fail-state resolution will be attempted, potentially increasing performance."); ?> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Stream Inserts"); ?></td> + <td width="78%" class="vtable"> + <input name="fpm_no_stream_inserts" id="fpm_no_stream_inserts" type="checkbox" value="on" <? if ($pconfig['fpm_no_stream_inserts'] == "on") echo "checked"; ?>> + <?php echo gettext("Do not evaluate stream inserted packets against the detection engine.") . " <strong>" . gettext("Default") . "</strong>" . gettext(" is ") . + "<strong>" . gettext("Not Checked") . "</strong>"; ?>.<br/> + <br/><?php echo gettext("This is a potential performance improvement based on the idea the stream rebuilt packet " . + "will contain the payload in the inserted one, so the stream inserted packet does not need to be evaluated."); ?> + </td> + </tr> + <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Checksum Check Disable"); ?></td> <td width="78%" class="vtable"> <input name="cksumcheck" id="cksumcheck" type="checkbox" value="on" <?php if ($pconfig['cksumcheck'] == "on") echo "checked"; ?>> @@ -374,11 +411,11 @@ include_once("head.inc"); ?> </select> <input type="button" class="formbtns" value="View List" - onclick="viewList('<?=$id;?>','homelistname')" id="btnHomeNet" + onclick="viewList('<?=$id;?>','homelistname','homenet')" id="btnHomeNet" title="<?php echo gettext("Click to view currently selected Home Net contents"); ?>"/> <br/> <span class="vexpl"><?php echo gettext("Choose the Home Net you want this interface to use."); ?></span> - <br/></br> + <br/><br/> <span class="red"><?php echo gettext("Note:"); ?></span> <?php echo gettext("Default Home " . "Net adds only local networks, WAN IPs, Gateways, VPNs and VIPs."); ?><br/> <span class="red"><?php echo gettext("Hint:"); ?></span> <?php echo gettext("Create an Alias to hold a list of " . @@ -430,7 +467,7 @@ include_once("head.inc"); } ?> </select> - <input type="button" class="formbtns" value="View List" onclick="viewList('<?=$id;?>','whitelistname')" + <input type="button" class="formbtns" value="View List" onclick="viewList('<?=$id;?>','whitelistname','whitelist')" id="btnWhitelist" title="<?php echo gettext("Click to view currently selected Whitelist contents"); ?>"/> <br/> <span class="vexpl"><?php echo gettext("Choose the whitelist you want this interface to " . @@ -475,9 +512,9 @@ include_once("head.inc"); "be automatically inserted into the Snort configuration."); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Advanced configuration pass through"); ?></td> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Advanced configuration pass-through"); ?></td> <td width="78%" class="vtable"> - <textarea wrap="off" name="configpassthru" cols="65" rows="12" id="configpassthru"><?=htmlspecialchars($pconfig['configpassthru']);?></textarea> + <textarea style="width:98%; height:100%;" wrap="off" name="configpassthru" cols="60" rows="8" id="configpassthru"><?=htmlspecialchars($pconfig['configpassthru']);?></textarea> </td> </tr> <tr> @@ -489,7 +526,7 @@ include_once("head.inc"); </tr> <tr> <td width="22%" valign="top"> </td> - <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note: ") . "</strong></span>" . + <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note: ") . "</strong></span></span>" . gettext("Please save your settings before you attempt to start Snort."); ?> </td> </tr> diff --git a/config/snort/snort_interfaces_global.php b/config/snort/snort_interfaces_global.php index 0b9c5f2d..d28ec2b4 100644 --- a/config/snort/snort_interfaces_global.php +++ b/config/snort/snort_interfaces_global.php @@ -49,15 +49,22 @@ $pconfig['rm_blocked'] = $config['installedpackages']['snortglobal']['rm_blocked $pconfig['snortloglimit'] = $config['installedpackages']['snortglobal']['snortloglimit']; $pconfig['snortloglimitsize'] = $config['installedpackages']['snortglobal']['snortloglimitsize']; $pconfig['autorulesupdate7'] = $config['installedpackages']['snortglobal']['autorulesupdate7']; +$pconfig['rule_update_starttime'] = $config['installedpackages']['snortglobal']['rule_update_starttime']; $pconfig['forcekeepsettings'] = $config['installedpackages']['snortglobal']['forcekeepsettings']; $pconfig['snortcommunityrules'] = $config['installedpackages']['snortglobal']['snortcommunityrules']; if (empty($pconfig['snortloglimit'])) $pconfig['snortloglimit'] = 'on'; +if (empty($pconfig['rule_update_starttime'])) + $pconfig['rule_update_starttime'] = '00:03'; + +if ($_POST['rule_update_starttime']) { + if (!preg_match('/^([01]?[0-9]|2[0-3]):?([0-5][0-9])$/', $_POST['rule_update_starttime'])) + $input_errors[] = "Invalid Rule Update Start Time! Please supply a value in 24-hour format as 'HH:MM'."; +} /* if no errors move foward */ if (!$input_errors) { - if ($_POST["Submit"]) { $config['installedpackages']['snortglobal']['snortdownload'] = $_POST['snortdownload']; @@ -77,6 +84,14 @@ if (!$input_errors) { $config['installedpackages']['snortglobal']['snortloglimitsize'] = $snortloglimitDSKsize; } $config['installedpackages']['snortglobal']['autorulesupdate7'] = $_POST['autorulesupdate7']; + + /* Check and adjust format of Rule Update Starttime string to add colon and leading zero if necessary */ + $pos = strpos($_POST['rule_update_starttime'], ":"); + if ($pos === false) { + $tmp = str_pad($_POST['rule_update_starttime'], 4, "0", STR_PAD_LEFT); + $_POST['rule_update_starttime'] = substr($tmp, 0, 2) . ":" . substr($tmp, -2); + } + $config['installedpackages']['snortglobal']['rule_update_starttime'] = str_pad($_POST['rule_update_starttime'], 4, "0", STR_PAD_LEFT); $config['installedpackages']['snortglobal']['forcekeepsettings'] = $_POST['forcekeepsettings'] ? 'on' : 'off'; $retval = 0; @@ -116,20 +131,6 @@ 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> @@ -154,6 +155,7 @@ function enable_snort_vrt(btn) { <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Please Choose The " . "Type Of Rules You Wish To Download"); ?></td> </tr> +<tr> <td width="22%" valign="top" class="vncell"><?php printf(gettext("Install %sSnort VRT%s rules"), '<strong>' , '</strong>'); ?></td> <td width="78%" class="vtable"> <table width="100%" border="0" cellpadding="2" cellspacing="0"> @@ -181,7 +183,7 @@ function enable_snort_vrt(btn) { <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 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']);?>" @@ -218,11 +220,14 @@ function enable_snort_vrt(btn) { </table> </td> </tr> + <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Update rules " . - "automatically"); ?></td> + <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Rules Update Settings"); ?></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Update Interval"); ?></td> <td width="78%" class="vtable"> - <select name="autorulesupdate7" class="formselect" id="autorulesupdate7"> + <select name="autorulesupdate7" class="formselect" id="autorulesupdate7" onchange="enable_change_rules_upd()"> <?php $interfaces3 = array('never_up' => gettext('NEVER'), '6h_up' => gettext('6 HOURS'), '12h_up' => gettext('12 HOURS'), '1d_up' => gettext('1 DAY'), '4d_up' => gettext('4 DAYS'), '7d_up' => gettext('7 DAYS'), '28d_up' => gettext('28 DAYS')); foreach ($interfaces3 as $iface3 => $ifacename3): ?> @@ -230,21 +235,29 @@ function enable_snort_vrt(btn) { <?php if ($iface3 == $pconfig['autorulesupdate7']) echo "selected"; ?>> <?=htmlspecialchars($ifacename3);?></option> <?php endforeach; ?> - </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> + </select><span class="vexpl"> <?php echo gettext("Please select the interval for rule updates. Choosing ") . + "<strong>" . gettext("NEVER") . "</strong>" . gettext(" disables auto-updates."); ?><br/><br/> + <?php echo "<span class=\"red\"><strong>" . gettext("Hint: ") . "</strong></span>" . gettext("in most cases, every 12 hours is a good choice."); ?></span></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Update Start Time"); ?></td> + <td width="78%" class="vtable"><input type="text" class="formfld" name="rule_update_starttime" id="rule_update_starttime" size="4" + maxlength="5" value="<?=$pconfig['rule_update_starttime'];?>" <?php if ($pconfig['autorulesupdate7'] == "never_up") {echo "disabled";} ?>><span class="vexpl"> + <?php echo gettext("Enter the rule update start time in 24-hour format (HH:MM). ") . "<strong>" . + gettext("Default") . " </strong>" . gettext("is ") . "<strong>" . gettext("00:03") . "</strong></span>"; ?>.<br/><br/> + <?php echo gettext("Rules will update at the interval chosen above starting at the time specified here. For example, using the default " . + "start time of 00:03 and choosing 12 Hours for the interval, the rules will update at 00:03 and 12:03 each day."); ?></td> </tr> <tr> <td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Settings"); ?></td> </tr> - <tr> <?php $snortlogCurrentDSKsize = round(exec('df -k /var | grep -v "Filesystem" | awk \'{print $4}\'') / 1024); ?> <td width="22%" valign="top" class="vncell"><?php echo gettext("Log Directory Size " . "Limit"); ?><br/> <br/> <br/> - <span class="red"><strong><?php echo gettext("Note"); ?></span>:</strong><br> + <span class="red"><strong><?php echo gettext("Note:"); ?></strong></span><br/> <?php echo gettext("Available space is"); ?> <strong><?php echo $snortlogCurrentDSKsize; ?> MB</strong></td> <td width="78%" class="vtable"> <table cellpadding="0" cellspacing="0"> @@ -258,7 +271,7 @@ function enable_snort_vrt(btn) { <?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 " . + <span class="red"><strong><?php echo gettext("Warning:"); ?></strong></span> <?php echo gettext("Nanobsd " . "should use no more than 10MB of space."); ?></td> </tr> </table> @@ -314,5 +327,27 @@ function enable_snort_vrt(btn) { </table> </form> <?php include("fend.inc"); ?> + +<script language="JavaScript"> +<!-- +function enable_snort_vrt(btn) { + if (btn == 'off') { + document.iform.oinkmastercode.disabled = "true"; + } + if (btn == 'on') { + document.iform.oinkmastercode.disabled = ""; + } +} + +function enable_change_rules_upd() { + if (document.iform.autorulesupdate7.selectedIndex == 0) + document.iform.rule_update_starttime.disabled="true"; + else + document.iform.rule_update_starttime.disabled=""; +} + +//--> +</script> + </body> </html> diff --git a/config/snort/snort_interfaces_suppress.php b/config/snort/snort_interfaces_suppress.php index 8095ff37..780a6e92 100644 --- a/config/snort/snort_interfaces_suppress.php +++ b/config/snort/snort_interfaces_suppress.php @@ -98,7 +98,7 @@ if($pfsense_stable == 'yes'){echo '<p class="pgtitle">' . $pgtitle . '</p>';} <?=htmlspecialchars($list['name']);?></td> <td class="listbg" ondblclick="document.location='snort_interfaces_suppress_edit.php?id=<?=$i;?>';"> - <font color="#FFFFFF"> <?=htmlspecialchars($list['descr']);?> + <font color="#FFFFFF"> <?=htmlspecialchars($list['descr']);?> </font> </td> <td valign="middle" nowrap class="list"> @@ -130,17 +130,17 @@ if($pfsense_stable == 'yes'){echo '<p class="pgtitle">' . $pgtitle . '</p>';} width="17" height="17" border="0" title="<?php echo gettext("add a new list"); ?>"></a></td> </tr> </table> - </div> </td> </tr> </table> +</div> </td></tr> <tr> <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 " . + <p><?php echo gettext("Here you can create event filtering and " . "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> + "take effect."); ?></p></span></td> </tr> </table> </form> diff --git a/config/snort/snort_interfaces_suppress_edit.php b/config/snort/snort_interfaces_suppress_edit.php index 5e12f656..1eb16260 100644 --- a/config/snort/snort_interfaces_suppress_edit.php +++ b/config/snort/snort_interfaces_suppress_edit.php @@ -52,7 +52,6 @@ $id = $_GET['id']; if (isset($_POST['id'])) $id = $_POST['id']; - /* returns true if $name is a valid name for a whitelist file name or ip */ function is_validwhitelistname($name) { if (!is_string($name)) @@ -70,8 +69,10 @@ if (isset($id) && $a_suppress[$id]) { $pconfig['name'] = $a_suppress[$id]['name']; $pconfig['uuid'] = $a_suppress[$id]['uuid']; $pconfig['descr'] = $a_suppress[$id]['descr']; - if (!empty($a_suppress[$id]['suppresspassthru'])); + if (!empty($a_suppress[$id]['suppresspassthru'])) { $pconfig['suppresspassthru'] = base64_decode($a_suppress[$id]['suppresspassthru']); + $pconfig['suppresspassthru'] = str_replace("​", "", $pconfig['suppresspassthru']); + } if (empty($a_suppress[$id]['uuid'])) $pconfig['uuid'] = uniqid(); } @@ -107,8 +108,10 @@ if ($_POST['submit']) { $s_list['name'] = $_POST['name']; $s_list['uuid'] = uniqid(); $s_list['descr'] = mb_convert_encoding($_POST['descr'],"HTML-ENTITIES","auto"); - if ($_POST['suppresspassthru']) + if ($_POST['suppresspassthru']) { + $s_list['suppresspassthru'] = str_replace("​", "", $s_list['suppresspassthru']); $s_list['suppresspassthru'] = base64_encode($_POST['suppresspassthru']); + } if (isset($id) && $a_suppress[$id]) $a_suppress[$id] = $s_list; @@ -162,7 +165,7 @@ if ($savemsg) </tr> <tr> <td width="22%" valign="top" class="vncellreq"><?php echo gettext("Name"); ?></td> - <td width="78%" class="vtable"><input name="name" type="text" id="name" + <td width="78%" class="vtable"><input name="name" type="text" id="name" class="formfld unkown" size="40" value="<?=htmlspecialchars($pconfig['name']);?>" /> <br /> <span class="vexpl"> <?php echo gettext("The list name may only consist of the " . "characters \"a-z, A-Z, 0-9 and _\"."); ?> <span class="red"><?php echo gettext("Note:"); ?> </span> @@ -170,52 +173,42 @@ if ($savemsg) </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Description"); ?></td> - <td width="78%" class="vtable"><input name="descr" type="text" + <td width="78%" class="vtable"><input name="descr" type="text" class="formfld unkown" id="descr" size="40" value="<?=$pconfig['descr'];?>" /> <br /> <span class="vexpl"> <?php echo gettext("You may enter a description here for your " . "reference (not parsed)."); ?> </span></td> </tr> <tr> - <td colspan="2"> - <div style='background-color: #E0E0E0' id='redbox'> - <table width='100%'> - <tr> - <td width='8%'> </td> - <td width='70%'><font size="2" color='#FF850A'><b><?php echo gettext("NOTE:"); ?></b></font> - <font color='#000000'> <?php echo gettext("The threshold keyword " . + <td colspan="2" align="center" height="30px"> + <font size="2"><span class="red"><strong><?php echo gettext("NOTE:"); ?></strong></span></font> + <font color='#000000'> <?php echo gettext("The threshold keyword " . "is deprecated as of version 2.8.5. Use the event_filter keyword " . - "instead."); ?></font></td> - </tr> - </table> - </div> + "instead."); ?></font> </td> </tr> <tr> <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Apply suppression or " . - "filters to rules. Valid keywords are 'suppress', 'event_filter' and " . - "'rate_filter'."); ?></td> + "filters to rules. Valid keywords are 'suppress', 'event_filter' and 'rate_filter'."); ?></td> </tr> <tr> <td colspan="2" valign="top" class="vncell"><b><?php echo gettext("Example 1;"); ?></b> - suppress gen_id 1, sig_id 1852, track by_src, ip 10.1.1.54<br> + suppress gen_id 1, sig_id 1852, track by_src, ip 10.1.1.54<br/> <b><?php echo gettext("Example 2;"); ?></b> event_filter gen_id 1, sig_id 1851, type limit, - track by_src, count 1, seconds 60<br> + track by_src, count 1, seconds 60<br/> <b><?php echo gettext("Example 3;"); ?></b> rate_filter gen_id 135, sig_id 1, track by_src, count 100, seconds 1, new_action log, timeout 10</td> </tr> <tr> - <td width="10%" class="vncell"> <?php echo gettext("Advanced pass through"); ?></td> - <td width="100%" class="vtable"><textarea wrap="off" - name="suppresspassthru" cols="90" rows="28" id="suppresspassthru" class="formpre"><?=htmlspecialchars($pconfig['suppresspassthru']);?></textarea> + <td colspan="2" class="vtable"><textarea wrap="off" style="width:100%; height:100%;" + name="suppresspassthru" cols="90" rows="26" id="suppresspassthru" class="formpre"><?=htmlspecialchars($pconfig['suppresspassthru']);?></textarea> </td> </tr> <tr> - <td width="22%"> </td> - <td width="78%"><input id="submit" name="submit" type="submit" - class="formbtn" value="Save" /> <input id="cancelbutton" - name="cancelbutton" type="button" class="formbtn" value="Cancel" - onclick="history.back()" /> <?php if (isset($id) && $a_suppress[$id]): ?> - <input name="id" type="hidden" value="<?=$id;?>" /> <?php endif; ?> + <td colspan="2"><input id="submit" name="submit" type="submit" + class="formbtn" value="Save" /> <input id="cancelbutton" + name="cancelbutton" type="button" class="formbtn" value="Cancel" + onclick="history.back();"/> <?php if (isset($id) && $a_suppress[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"/> <?php endif; ?> </td> </tr> </table> diff --git a/config/snort/snort_interfaces_whitelist.php b/config/snort/snort_interfaces_whitelist.php index 73c9efda..ab22103e 100644 --- a/config/snort/snort_interfaces_whitelist.php +++ b/config/snort/snort_interfaces_whitelist.php @@ -160,12 +160,12 @@ if ($savemsg) print_info_box($savemsg); 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 " . + <p><?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 your system."); ?></span></p></td> + <?php echo gettext("Be careful, it is very easy to get locked out of your system."); ?></p></span></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> diff --git a/config/snort/snort_list_view.php b/config/snort/snort_list_view.php index b7de064b..856367ef 100644 --- a/config/snort/snort_list_view.php +++ b/config/snort/snort_list_view.php @@ -47,10 +47,14 @@ $type = $_GET['type']; if (isset($id) && isset($wlist)) { $a_rule = $config['installedpackages']['snortglobal']['rule'][$id]; - if ($type == "whitelist") { + if ($type == "homenet") { $list = snort_build_list($a_rule, $wlist); $contents = implode("\n", $list); } + elseif ($type == "whitelist") { + $list = snort_build_list($a_rule, $wlist, true); + $contents = implode("\n", $list); + } elseif ($type == "suppress") { $list = snort_find_list($wlist, $type); $contents = str_replace("\r", "", base64_decode($list['suppresspassthru'])); diff --git a/config/snort/snort_preprocessors.php b/config/snort/snort_preprocessors.php index 12981398..3f88efaa 100755 --- a/config/snort/snort_preprocessors.php +++ b/config/snort/snort_preprocessors.php @@ -61,6 +61,11 @@ if (isset($id) && $a_nat[$id]) { /* Get current values from config for page form fields */ $pconfig['perform_stat'] = $a_nat[$id]['perform_stat']; + $pconfig['host_attribute_table'] = $a_nat[$id]['host_attribute_table']; + $pconfig['host_attribute_data'] = $a_nat[$id]['host_attribute_data']; + $pconfig['max_attribute_hosts'] = $a_nat[$id]['max_attribute_hosts']; + $pconfig['max_attribute_services_per_host'] = $a_nat[$id]['max_attribute_services_per_host']; + $pconfig['max_paf'] = $a_nat[$id]['max_paf']; $pconfig['server_flow_depth'] = $a_nat[$id]['server_flow_depth']; $pconfig['http_server_profile'] = $a_nat[$id]['http_server_profile']; $pconfig['client_flow_depth'] = $a_nat[$id]['client_flow_depth']; @@ -124,6 +129,12 @@ if (isset($id) && $a_nat[$id]) { /* enable the most common required preprocessors by default */ /* and set reasonable values for any options. */ /************************************************************/ + if (empty($pconfig['max_attribute_hosts'])) + $pconfig['max_attribute_hosts'] = '10000'; + if (empty($pconfig['max_attribute_services_per_host'])) + $pconfig['max_attribute_services_per_host'] = '10'; + if (empty($pconfig['max_paf'])) + $pconfig['max_paf'] = '16000'; if (empty($pconfig['ftp_preprocessor'])) $pconfig['ftp_preprocessor'] = 'on'; if (empty($pconfig['smtp_preprocessor'])) @@ -200,6 +211,10 @@ if ($_POST['ResetAll']) { /* Reset all the preprocessor settings to defaults */ $pconfig['perform_stat'] = "off"; + $pconfig['host_attribute_table'] = "off"; + $pconfig['max_attribute_hosts'] = '10000'; + $pconfig['max_attribute_services_per_host'] = '10'; + $pconfig['max_paf'] = '16000'; $pconfig['server_flow_depth'] = "300"; $pconfig['http_server_profile'] = "all"; $pconfig['client_flow_depth'] = "300"; @@ -266,6 +281,9 @@ elseif ($_POST['Submit']) { /* if no errors write to conf */ if (!$input_errors) { /* post new options */ + if ($_POST['max_attribute_hosts'] != "") { $natent['max_attribute_hosts'] = $_POST['max_attribute_hosts']; }else{ $natent['max_attribute_hosts'] = "10000"; } + if ($_POST['max_attribute_services_per_host'] != "") { $natent['max_attribute_services_per_host'] = $_POST['max_attribute_services_per_host']; }else{ $natent['max_attribute_services_per_host'] = "10"; } + if ($_POST['max_paf'] != "") { $natent['max_paf'] = $_POST['max_paf']; }else{ $natent['max_paf'] = "16000"; } if ($_POST['server_flow_depth'] != "") { $natent['server_flow_depth'] = $_POST['server_flow_depth']; }else{ $natent['server_flow_depth'] = "300"; } if ($_POST['http_server_profile'] != "") { $natent['http_server_profile'] = $_POST['http_server_profile']; }else{ $natent['http_server_profile'] = "all"; } if ($_POST['client_flow_depth'] != "") { $natent['client_flow_depth'] = $_POST['client_flow_depth']; }else{ $natent['client_flow_depth'] = "300"; } @@ -295,6 +313,7 @@ elseif ($_POST['Submit']) { unset($natent['pscan_ignore_scanners']); $natent['perform_stat'] = $_POST['perform_stat'] ? 'on' : 'off'; + $natent['host_attribute_table'] = $_POST['host_attribute_table'] ? 'on' : 'off'; $natent['http_inspect'] = $_POST['http_inspect'] ? 'on' : 'off'; $natent['http_inspect_enable_xff'] = $_POST['http_inspect_enable_xff'] ? 'on' : 'off'; $natent['http_inspect_log_uri'] = $_POST['http_inspect_log_uri'] ? 'on' : 'off'; @@ -342,14 +361,22 @@ elseif ($_POST['Submit']) { write_config(); /* Set flag to rebuild rules for this interface */ - $rebuild_rules = "on"; + $rebuild_rules = true; /*************************************************/ - /* Update the snort conf file and rebuild the */ + /* Update the snort.conf file and rebuild the */ /* rules for this interface. */ /*************************************************/ snort_generate_conf($natent); - $rebuild_rules = "off"; + $rebuild_rules = false; + + /*******************************************************/ + /* Signal Snort to reload Host Attribute Table if one */ + /* is configured and saved. */ + /*******************************************************/ + if ($natent['host_attribute_table'] == "on" && + !empty($natent['host_attribute_data'])) + snort_reload_config($natent, "SIGURG"); /* after click go to this page */ header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); @@ -361,6 +388,47 @@ elseif ($_POST['Submit']) { exit; } } +elseif ($_POST['btn_import']) { + if (is_uploaded_file($_FILES['host_attribute_file']['tmp_name'])) { + $data = file_get_contents($_FILES['host_attribute_file']['tmp_name']); + if ($data === false) + $input_errors[] = gettext("Error uploading file {$_FILES['host_attribute_file']}!"); + else { + if (isset($id) && $a_nat[$id]) { + $a_nat[$id]['host_attribute_table'] = "on"; + $a_nat[$id]['host_attribute_data'] = base64_encode($data); + $pconfig['host_attribute_data'] = $a_nat[$id]['host_attribute_data']; + $a_nat[$id]['max_attribute_hosts'] = $pconfig['max_attribute_hosts']; + $a_nat[$id]['max_attribute_services_per_host'] = $pconfig['max_attribute_services_per_host']; + write_config(); + } + header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); + header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); + header( 'Cache-Control: no-store, no-cache, must-revalidate' ); + header( 'Cache-Control: post-check=0, pre-check=0', false ); + header( 'Pragma: no-cache' ); + header("Location: snort_preprocessors.php?id=$id"); + exit; + } + } + else + $input_errors[] = gettext("No filename specified for import!"); +} +elseif ($_POST['btn_edit_hat']) { + if (isset($id) && $a_nat[$id]) { + $a_nat[$id]['host_attribute_table'] = "on"; + $a_nat[$id]['max_attribute_hosts'] = $pconfig['max_attribute_hosts']; + $a_nat[$id]['max_attribute_services_per_host'] = $pconfig['max_attribute_services_per_host']; + write_config(); + header("Location: snort_edit_hat_data.php?id=$id"); + exit; + } +} + +/* If Host Attribute Table option is enabled, but */ +/* no Host Attribute data exists, flag an error. */ +if ($pconfig['host_attribute_table'] == 'on' && empty($pconfig['host_attribute_data'])) + $input_errors[] = gettext("The Host Attribute Table option is enabled, but no Host Attribute data has been loaded. Data may be entered manually or imported from a suitable file."); $if_friendly = snort_get_friendly_interface($pconfig['interface']); $pgtitle = "Snort: Interface {$if_friendly}: Preprocessors and Flow"; @@ -481,12 +549,105 @@ include_once("head.inc"); </td> </tr> <tr> + <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Host Attribute Table Settings"); ?></td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td> + <td width="78%" class="vtable"><input name="host_attribute_table" + type="checkbox" value="on" id="host_attribute_table" onclick="host_attribute_table_enable_change();" + <?php if ($pconfig['host_attribute_table']=="on") echo "checked"; ?>> + <?php echo gettext("Use a Host Attribute Table file to auto-configure applicable preprocessors. " . + "Default is "); ?><strong><?php echo gettext("Not Checked"); ?></strong>.</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Host Attribute Data"); ?></td> + <td width="78%" class="vtable"><strong><?php echo gettext("Import From File"); ?></strong><br/> + <input name="host_attribute_file" type="file" class="formfld unknown" value="on" id="host_attribute_file" size="40" + <?php if ($pconfig['host_attribute_table']<>"on") echo "disabled"; ?>> + <input type="submit" name="btn_import" id="btn_import" value="Import" class="formbtn" + <?php if ($pconfig['host_attribute_table']<>"on") echo "disabled"; ?>><br/> + <?php echo gettext("Choose the Host Attributes file to use for auto-configuration."); ?><br/><br/> + <span class="red"><strong><?php echo gettext("Warning: "); ?></strong></span> + <?php echo gettext("The Host Attributes file has a required format. See the "); ?><a href="http://manual.snort.org/" target="_blank"> + <?php echo gettext("Snort Manual"); ?></a><?php echo gettext(" for details. " . + "An improperly formatted file may cause Snort to crash or fail to start. The combination of "); ?> + <a href="http://nmap.org/" target="_blank"><?php echo gettext("NMap"); ?></a><?php echo gettext(" and "); ?> + <a href="http://code.google.com/p/hogger/" target="_blank"><?php echo gettext("Hogger"); ?></a><?php echo gettext(" or "); ?> + <a href="http://gamelinux.github.io/prads/" target="_blank"><?php echo gettext("PRADS"); ?></a><?php echo gettext(" can be used to " . + "scan networks and automatically generate a suitable Host Attribute Table file for import."); ?><br/><br/> + <input type="submit" id="btn_edit_hat" name="btn_edit_hat" value="<?php if (!empty($pconfig['host_attribute_data'])) {echo gettext(" Edit ");} else {echo gettext("Create");} ?>" + class="formbtn" + <?php if ($pconfig['host_attribute_table']<>"on") echo "disabled"; ?>> + <?php if (!empty($pconfig['host_attribute_data'])) {echo gettext("Click to View or Edit the Host Attribute data.");} + else {echo gettext("Click to Create Host Attribute data manually.");} + if ($pconfig['host_attribute_table']=="on" && empty($pconfig['host_attribute_data'])){ + echo "<br/><br/><span class=\"red\"><strong>" . gettext("Warning: ") . "</strong></span>" . + gettext("No Host Attribute Data loaded - import from a file or enter it manually."); + } ?></td> + </tr> + <tr> + <td valign="top" class="vncell"><?php echo gettext("Maximum Hosts"); ?></td> + <td class="vtable"> + <table cellpadding="0" cellspacing="0"> + <tr> + <td><input name="max_attribute_hosts" type="text" class="formfld" id="max_attribute_hosts" size="6" + value="<?=htmlspecialchars($pconfig['max_attribute_hosts']);?>" + <?php if ($pconfig['host_attribute_table']<>"on") echo "disabled"; ?>> + <?php echo gettext("Max number of hosts to read from the Attribute Table. Min is ") . + "<strong>" . gettext("32") . "</strong>" . gettext(" and Max is ") . "<strong>" . + gettext("524288") . "</strong>"; ?>.</td> + </tr> + </table> + <?php echo gettext("Sets a limit on the maximum number of hosts to read from the Attribute Table. If the number of hosts in " . + "the table exceeds this value, an error is logged and the remainder of the hosts are ignored. " . + "Default is ") . "<strong>" . gettext("10000") . "</strong>"; ?>.<br/> + </td> + </tr> + <tr> + <td valign="top" class="vncell"><?php echo gettext("Maximum Services Per Host"); ?></td> + <td class="vtable"> + <table cellpadding="0" cellspacing="0"> + <tr> + <td><input name="max_attribute_services_per_host" type="text" class="formfld" id="max_attribute_services_per_host" size="6" + value="<?=htmlspecialchars($pconfig['max_attribute_services_per_host']);?>" + <?php if ($pconfig['host_attribute_table']<>"on") echo "disabled"; ?>> + <?php echo gettext("Max number of per host services to read from the Attribute Table. Min is ") . + "<strong>" . gettext("1") . "</strong>" . gettext(" and Max is ") . "<strong>" . + gettext("65535") . "</strong>"; ?>.</td> + </tr> + </table> + <?php echo gettext("Sets the per host limit of services to read from the Attribute Table. For a given host, if the number of " . + "services read exceeds this value, an error is logged and the remainder of the services for that host are ignored. " . + "Default is ") . "<strong>" . gettext("10") . "</strong>"; ?>.<br/> + </td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Protocol Aware Flushing Setting"); ?></td> + </tr> + <tr> + <td valign="top" class="vncell"><?php echo gettext("Protocol Aware Flushing Maximum PDU"); ?></td> + <td class="vtable"> + <table cellpadding="0" cellspacing="0"> + <tr> + <td><input name="max_paf" type="text" class="formfld" id="max_paf" size="6" + value="<?=htmlspecialchars($pconfig['max_paf']);?>"> + <?php echo gettext("Max number of PDUs to be reassembled into a single PDU. Min is ") . + "<strong>" . gettext("0") . "</strong>" . gettext(" (off) and Max is ") . "<strong>" . + gettext("63780") . "</strong>"; ?>.</td> + </tr> + </table> + <?php echo gettext("Multiple PDUs within a single TCP segment, as well as one PDU spanning multiple TCP segments, will be " . + "reassembled into one PDU per packet for each PDU. PDUs larger than the configured maximum will be split into multiple packets. " . + "Default is ") . "<strong>" . gettext("16000") . "</strong>. " . gettext("A value of 0 disables Protocol Aware Flushing."); ?>.<br/> + </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" id="http_inspect" onclick="http_inspect_enable_change()" + <td width="78%" class="vtable"><input name="http_inspect" + type="checkbox" value="on" id="http_inspect" onclick="http_inspect_enable_change();" <?php if ($pconfig['http_inspect']=="on" || empty($pconfig['http_inspect'])) echo "checked"; ?>> <?php echo gettext("Use HTTP Inspect to " . "Normalize/Decode and detect HTTP traffic and protocol anomalies. Default is "); ?> @@ -578,7 +739,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="client_flow_depth" type="text" class="formfld" + <td><input name="client_flow_depth" type="text" class="formfld" id="client_flow_depth" size="6" value="<?=htmlspecialchars($pconfig['client_flow_depth']);?>"> <?php echo gettext("<strong>-1</strong> " . "to <strong>1460</strong> (<strong>-1</strong> disables HTTP " . @@ -586,17 +747,17 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("Amount of raw HTTP client request payload to inspect. Snort's " . - "performance may increase by adjusting this value."); ?><br> + "performance may increase by adjusting this value."); ?><br/> <?php echo gettext("Setting this value too low may cause false negatives. Values above 0 " . "are specified in bytes. Recommended setting is maximum (1460). Default value is <strong>300</strong>"); ?><br/> </td> </tr> <tr> <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" id="noalert_http_inspect" + <td width="78%" class="vtable"><input name="noalert_http_inspect" + type="checkbox" value="on" id="noalert_http_inspect" <?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 " . + 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> @@ -606,7 +767,7 @@ include_once("head.inc"); </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td> - <td width="78%" class="vtable"><input name="frag3_detection" type="checkbox" value="on" onclick="frag3_enable_change()" + <td width="78%" class="vtable"><input name="frag3_detection" type="checkbox" value="on" onclick="frag3_enable_change();" <?php if ($pconfig['frag3_detection']=="on") echo "checked "; ?> onClick="enable_change(false)"> <?php echo gettext("Use Frag3 Engine to detect IDS evasion attempts via target-based IP packet fragmentation. Default is ") . @@ -639,7 +800,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("The maximum number of simultaneous fragments to track. Default value is ") . - "<strong>8192</strong>."; ?><br> + "<strong>8192</strong>."; ?><br/> </td> </tr> <tr> @@ -654,7 +815,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("Sets the limit for the number of overlapping fragments allowed per packet. Default value is ") . - "<strong>0</strong>" . gettext(" (unlimited)."); ?><br> + "<strong>0</strong>" . gettext(" (unlimited)."); ?><br/> </td> </tr> <tr> @@ -669,7 +830,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("Defines smallest fragment size (payload size) that should be considered valid. Default value is ") . - "<strong>0</strong>" . gettext(" (check is disabled)."); ?><br> + "<strong>0</strong>" . gettext(" (check is disabled)."); ?><br/> </td> </tr> <tr> @@ -694,13 +855,13 @@ include_once("head.inc"); <?php $profile = array( 'BSD', 'BSD-Right', 'First', 'Last', 'Linux', 'Solaris', 'Windows' ); foreach ($profile as $val): ?> - <option value="<?=strtolower($val);?>" + <option value="<?=strtolower($val);?>" <?php if (strtolower($val) == $pconfig['frag3_policy']) echo "selected"; ?>> <?=gettext($val);?></option> <?php endforeach; ?> </select> <?php echo gettext("Choose the IP fragmentation target policy appropriate for the protected hosts. The default is ") . "<strong>" . gettext("BSD") . "</strong>"; ?>.<br/> - <?php echo gettext("Available OS targets are BSD, BSD-Right, First, Last, Linux, Solaris and Windows."); ?><br/></td> + <?php echo gettext("Available OS targets are BSD, BSD-Right, First, Last, Linux, Solaris and Windows."); ?><br/> </td> </tr> <tr> @@ -708,8 +869,8 @@ include_once("head.inc"); </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td> - <td width="78%" class="vtable"><input name="stream5_reassembly" type="checkbox" value="on" onclick="stream5_enable_change()" - <?php if ($pconfig['stream5_reassembly']=="on") echo "checked "; ?>"> + <td width="78%" class="vtable"><input name="stream5_reassembly" type="checkbox" value="on" onclick="stream5_enable_change();" + <?php if ($pconfig['stream5_reassembly']=="on") echo "checked"; ?>> <?php echo gettext("Use Stream5 session reassembly for TCP, UDP and/or ICMP traffic. Default is ") . "<strong>" . gettext("Checked") . "</strong>"; ?>.</td> </tr> @@ -750,7 +911,7 @@ include_once("head.inc"); <td width="22%" valign="top" class="vncell"><?php echo gettext("Do Not Store Large TCP Packets"); ?></td> <td width="78%" class="vtable"> <input name="stream5_dont_store_lg_pkts" type="checkbox" value="on" - <?php if ($pconfig['stream5_dont_store_lg_pkts']=="on") echo "checked "; ?>> + <?php if ($pconfig['stream5_dont_store_lg_pkts']=="on") echo "checked"; ?>> <?php echo gettext("Do not queue large packets in reassembly buffer to increase performance. Default is ") . "<strong>" . gettext("Not Checked") . "</strong>"; ?>.<br/> <?php echo "<span class=\"red\"><strong>" . gettext("Warning: ") . "</strong></span>" . @@ -761,7 +922,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="max_queued_bytes" type="text" class="formfld" + <td><input name="max_queued_bytes" type="text" class="formfld" id="max_queued_bytes" size="6" value="<?=htmlspecialchars($pconfig['max_queued_bytes']);?>"> <?php echo gettext("Minimum is <strong>1024</strong>, Maximum is <strong>1073741824</strong> " . @@ -770,7 +931,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("The number of bytes to be queued for reassembly for TCP sessions in " . - "memory. Default value is <strong>1048576</strong>"); ?>.<br> + "memory. Default value is <strong>1048576</strong>"); ?>.<br/> </td> </tr> <tr> @@ -778,7 +939,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="max_queued_segs" type="text" class="formfld" + <td><input name="max_queued_segs" type="text" class="formfld" id="max_queued_segs" size="6" value="<?=htmlspecialchars($pconfig['max_queued_segs']);?>"> <?php echo gettext("Minimum is <strong>2</strong>, Maximum is <strong>1073741824</strong> " . @@ -787,7 +948,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("The number of segments to be queued for reassembly for TCP sessions " . - "in memory. Default value is <strong>2621</strong>"); ?>.<br> + "in memory. Default value is <strong>2621</strong>"); ?>.<br/> </td> </tr> <tr> @@ -795,7 +956,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="stream5_mem_cap" type="text" class="formfld" + <td><input name="stream5_mem_cap" type="text" class="formfld" id="stream5_mem_cap" size="6" value="<?=htmlspecialchars($pconfig['stream5_mem_cap']);?>"> <?php echo gettext("Minimum is <strong>32768</strong>, Maximum is <strong>1073741824</strong> " . @@ -803,7 +964,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("The memory cap in bytes for TCP packet storage " . - "in RAM. Default value is <strong>8388608</strong> (8 MB)"); ?>.<br> + "in RAM. Default value is <strong>8388608</strong> (8 MB)"); ?>.<br/> </td> </tr> <tr> @@ -811,7 +972,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="stream5_overlap_limit" type="text" class="formfld" + <td><input name="stream5_overlap_limit" type="text" class="formfld" id="stream5_overlap_limit" size="6" value="<?=htmlspecialchars($pconfig['stream5_overlap_limit']);?>"> <?php echo gettext("Minimum is ") . "<strong>0</strong>" . gettext(" (unlimited), and the maximum is ") . @@ -819,7 +980,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("Sets the limit for the number of overlapping fragments allowed per packet. Default value is ") . - "<strong>0</strong>" . gettext(" (unlimited)."); ?><br> + "<strong>0</strong>" . gettext(" (unlimited)."); ?><br/> </td> </tr> <tr> @@ -827,7 +988,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="stream5_tcp_timeout" type="text" class="formfld" + <td><input name="stream5_tcp_timeout" type="text" class="formfld" id="stream5_tcp_timeout" size="6" value="<?=htmlspecialchars($pconfig['stream5_tcp_timeout']);?>"> <?php echo gettext("TCP Session timeout in seconds. Minimum is ") . "<strong>1</strong>" . gettext(" and the maximum is ") . @@ -835,7 +996,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("Sets the session reassembly timeout period for TCP packets. Default value is ") . - "<strong>30</strong>" . gettext(" seconds."); ?><br> + "<strong>30</strong>" . gettext(" seconds."); ?><br/> </td> </tr> <tr> @@ -843,7 +1004,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="stream5_udp_timeout" type="text" class="formfld" + <td><input name="stream5_udp_timeout" type="text" class="formfld" id="stream5_udp_timeout" size="6" value="<?=htmlspecialchars($pconfig['stream5_udp_timeout']);?>"> <?php echo gettext("UDP Session timeout in seconds. Minimum is ") . "<strong>1</strong>" . gettext(" and the maximum is ") . @@ -851,7 +1012,7 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("Sets the session reassembly timeout period for UDP packets. Default value is ") . - "<strong>30</strong>" . gettext(" seconds."); ?><br> + "<strong>30</strong>" . gettext(" seconds."); ?><br/> </td> </tr> <tr> @@ -859,7 +1020,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="stream5_icmp_timeout" type="text" class="formfld" + <td><input name="stream5_icmp_timeout" type="text" class="formfld" id="stream5_icmp_timeout" size="6" value="<?=htmlspecialchars($pconfig['stream5_icmp_timeout']);?>"> <?php echo gettext("ICMP Session timeout in seconds. Minimum is ") . "<strong>1</strong>" . gettext(" and the maximum is ") . @@ -867,33 +1028,32 @@ include_once("head.inc"); </tr> </table> <?php echo gettext("Sets the session reassembly timeout period for ICMP packets. Default value is ") . - "<strong>30</strong>" . gettext(" seconds."); ?><br> + "<strong>30</strong>" . gettext(" seconds."); ?><br/> </td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("IP Target Policy"); ?> </td> + <td width="22%" valign="top" class="vncell"><?php echo gettext("IP Target Policy"); ?></td> <td width="78%" class="vtable"> - <select name="stream5_policy" class="formselect" id="stream5_policy"> + <select name="stream5_policy" class="formselect" id="stream5_policy"> <?php $profile = array( 'BSD', 'First', 'HPUX', 'HPUX10', 'Irix', 'Last', 'Linux', 'MacOS', 'Old-Linux', 'Solaris', 'Vista', 'Windows', 'Win2003' ); foreach ($profile as $val): ?> - <option value="<?=strtolower($val);?>" + <option value="<?=strtolower($val);?>" <?php if (strtolower($val) == $pconfig['stream5_policy']) echo "selected"; ?>> <?=gettext($val);?></option> <?php endforeach; ?> </select> <?php echo gettext("Choose the TCP reassembly target policy appropriate for the protected hosts. The default is ") . "<strong>" . gettext("BSD") . "</strong>"; ?>.<br/> - <?php echo gettext("Available OS targets are BSD, First, HPUX, HPUX10, Irix, Last, Linux, MacOS, Old Linux, Solaris, Vista, Windows, and Win2003 Server."); ?><br/></td> + <?php echo gettext("Available OS targets are BSD, First, HPUX, HPUX10, Irix, Last, Linux, MacOS, Old Linux, Solaris, Vista, Windows, and Win2003 Server."); ?><br/> </td> </tr> <tr> <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Portscan Settings"); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> - <?php echo gettext("Portscan Detection"); ?></td> - <td width="78%" class="vtable"><input name="sf_portscan" onclick="sf_portscan_enable_change()" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td> + <td width="78%" class="vtable"><input name="sf_portscan" onclick="sf_portscan_enable_change();" type="checkbox" value="on" id="sf_portscan" <?php if ($pconfig['sf_portscan']=="on") echo "checked"; ?>> <?php echo gettext("Use Portscan Detection to detect various types of port scans and sweeps. Default is ") . @@ -902,12 +1062,12 @@ include_once("head.inc"); <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Protocol"); ?> </td> <td width="78%" class="vtable"> - <select name="pscan_protocol" class="formselect" id="pscan_protocol"> + <select name="pscan_protocol" class="formselect" id="pscan_protocol"> <?php $protos = array('all', 'tcp', 'udp', 'icmp', 'ip'); foreach ($protos as $val): ?> <option value="<?=$val;?>" - <?php if ($val == $pconfig['pscan_protocol']) echo "selected"; ?>> + <?php if ($val == $pconfig['pscan_protocol']) echo "selected"; ?>> <?=gettext($val);?></option> <?php endforeach; ?> </select> <?php echo gettext("Choose the Portscan protocol type to alert for (all, tcp, udp, icmp or ip). Default is ") . @@ -917,12 +1077,12 @@ include_once("head.inc"); <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Scan Type"); ?> </td> <td width="78%" class="vtable"> - <select name="pscan_type" class="formselect" id="pscan_type"> + <select name="pscan_type" class="formselect" id="pscan_type"> <?php $protos = array('all', 'portscan', 'portsweep', 'decoy_portscan', 'distributed_portscan'); foreach ($protos as $val): ?> <option value="<?=$val;?>" - <?php if ($val == $pconfig['pscan_type']) echo "selected"; ?>> + <?php if ($val == $pconfig['pscan_type']) echo "selected"; ?>> <?=gettext($val);?></option> <?php endforeach; ?> </select> <?php echo gettext("Choose the Portscan scan type to alert for. Default is ") . @@ -949,12 +1109,12 @@ include_once("head.inc"); <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Sensitivity"); ?> </td> <td width="78%" class="vtable"> - <select name="pscan_sense_level" class="formselect" id="pscan_sense_level"> + <select name="pscan_sense_level" class="formselect" id="pscan_sense_level"> <?php $levels = array('low', 'medium', 'high'); foreach ($levels as $val): ?> <option value="<?=$val;?>" - <?php if ($val == $pconfig['pscan_sense_level']) echo "selected"; ?>> + <?php if ($val == $pconfig['pscan_sense_level']) echo "selected"; ?>> <?=gettext(ucfirst($val));?></option> <?php endforeach; ?> </select> <?php echo gettext("Choose the Portscan sensitivity level (Low, Medium, High). Default is ") . @@ -980,7 +1140,7 @@ include_once("head.inc"); <td class="vtable"> <table cellpadding="0" cellspacing="0"> <tr> - <td><input name="pscan_memcap" type="text" class="formfld" + <td><input name="pscan_memcap" type="text" class="formfld" id="pscan_memcap" size="6" value="<?=htmlspecialchars($pconfig['pscan_memcap']);?>"> <?php echo gettext("Maximum memory in bytes to allocate for portscan detection. ") . @@ -990,13 +1150,13 @@ include_once("head.inc"); </table> <?php echo gettext("The maximum number of bytes to allocate for portscan detection. The higher this number, ") . gettext("the more nodes that can be tracked. Default is ") . - "<strong>10,000,000</strong>" . gettext(" bytes. (10 MB)"); ?><br> + "<strong>10,000,000</strong>" . gettext(" bytes. (10 MB)"); ?><br/> </td> </tr> <tr> <td width="22%" valign="top" class="vncell"><?php echo gettext("Ignore Scanners"); ?></td> <td width="78%" class="vtable"> - <input name="pscan_ignore_scanners" type="text" size="40" autocomplete="off" class="formfldalias" id="pscan_ignore_scanners" + <input name="pscan_ignore_scanners" type="text" size="40" autocomplete="off" class="formfldalias" id="pscan_ignore_scanners" value="<?=$pconfig['pscan_ignore_scanners'];?>"> <?php echo gettext("Leave blank for default. ") . gettext("Default value is ") . "<strong>" . gettext("\$HOME_NET") . "</strong>"; ?>.<br/> <?php echo gettext("Ignores the specified entity as a source of scan alerts. Entity must be a defined alias."); ?><br/> @@ -1006,97 +1166,79 @@ include_once("head.inc"); <td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Preprocessor Settings"); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> - <?php echo gettext("RPC Decode and Back Orifice detector"); ?></td> - <td width="78%" class="vtable"><input name="other_preprocs" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable RPC Decode and Back Orifice detector"); ?></td> + <td width="78%" class="vtable"><input name="other_preprocs" type="checkbox" value="on" <?php if ($pconfig['other_preprocs']=="on") echo "checked"; ?>> <?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> - <?php echo gettext("FTP and Telnet Normalizer"); ?></td> - <td width="78%" class="vtable"><input name="ftp_preprocessor" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable FTP and Telnet Normalizer"); ?></td> + <td width="78%" class="vtable"><input name="ftp_preprocessor" type="checkbox" value="on" <?php if ($pconfig['ftp_preprocessor']=="on") echo "checked"; ?>> <?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> - <?php echo gettext("POP Normalizer"); ?></td> - <td width="78%" class="vtable"><input name="pop_preproc" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable POP Normalizer"); ?></td> + <td width="78%" class="vtable"><input name="pop_preproc" type="checkbox" value="on" <?php if ($pconfig['pop_preproc']=="on") echo "checked"; ?>> <?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> - <?php echo gettext("IMAP Normalizer"); ?></td> - <td width="78%" class="vtable"><input name="imap_preproc" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable IMAP Normalizer"); ?></td> + <td width="78%" class="vtable"><input name="imap_preproc" type="checkbox" value="on" <?php if ($pconfig['imap_preproc']=="on") echo "checked"; ?>> <?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> - <?php echo gettext("SMTP Normalizer"); ?></td> - <td width="78%" class="vtable"><input name="smtp_preprocessor" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable SMTP Normalizer"); ?></td> + <td width="78%" class="vtable"><input name="smtp_preprocessor" type="checkbox" value="on" <?php if ($pconfig['smtp_preprocessor']=="on") echo "checked"; ?>> <?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> - <?php echo gettext("DCE/RPC2 Detection"); ?></td> - <td width="78%" class="vtable"><input name="dce_rpc_2" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable DCE/RPC2 Detection"); ?></td> + <td width="78%" class="vtable"><input name="dce_rpc_2" type="checkbox" value="on" <?php if ($pconfig['dce_rpc_2']=="on") echo "checked"; ?>> <?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> - <?php echo gettext("SIP Detection"); ?></td> - <td width="78%" class="vtable"><input name="sip_preproc" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable SIP Detection"); ?></td> + <td width="78%" class="vtable"><input name="sip_preproc" type="checkbox" value="on" <?php if ($pconfig['sip_preproc']=="on") echo "checked"; ?>> <?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> - <?php echo gettext("GTP Detection"); ?></td> - <td width="78%" class="vtable"><input name="gtp_preproc" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable GTP Detection"); ?></td> + <td width="78%" class="vtable"><input name="gtp_preproc" type="checkbox" value="on" <?php if ($pconfig['gtp_preproc']=="on") echo "checked"; ?>> <?php echo gettext("The GTP preprocessor decodes GPRS Tunneling Protocol traffic and detects intrusion attempts."); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> - <?php echo gettext("DNS Detection"); ?></td> - <td width="78%" class="vtable"><input name="dns_preprocessor" - type="checkbox" value="on" + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable DNS Detection"); ?></td> + <td width="78%" class="vtable"><input name="dns_preprocessor" type="checkbox" value="on" <?php if ($pconfig['dns_preprocessor']=="on") echo "checked"; ?>> <?php echo gettext("The DNS preprocessor decodes DNS Response traffic and detects 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> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable SSL Data"); ?></td> <td width="78%" class="vtable"> - <input name="ssl_preproc" type="checkbox" value="on" + <input name="ssl_preproc" type="checkbox" value="on" <?php if ($pconfig['ssl_preproc']=="on") echo "checked"; ?>> <?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="22%" valign="top" class="vncell"><?php echo gettext("Enable Sensitive Data"); ?></td> <td width="78%" class="vtable"> - <input name="sensitive_data" type="checkbox" value="on" + <input name="sensitive_data" type="checkbox" value="on" <?php if ($pconfig['sensitive_data'] == "on") echo "checked"; elseif ($vrt_enabled == "off") @@ -1104,47 +1246,49 @@ include_once("head.inc"); ?>> <?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."); ?> + <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> <td colspan="2" valign="top" class="listtopic"><?php echo gettext("SCADA Preprocessor Settings"); ?></td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> <?php echo gettext("Modbus Detection"); ?></td> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable Modbus Detection"); ?></td> <td width="78%" class="vtable"> - <input name="modbus_preproc" type="checkbox" value="on" + <input name="modbus_preproc" type="checkbox" value="on" <?php if ($pconfig['modbus_preproc']=="on") echo "checked"; ?>> <?php echo gettext("Modbus is a protocol used in SCADA networks. The default port is TCP 502.") . "<br/>" . - gettext("If your network does not contain Modbus-enabled devices, you should leave this preprocessor disabled."); ?> + "<span class=\"red\"><strong>" . gettext("Note: ") . "</strong></span>" . + gettext("If your network does not contain Modbus-enabled devices, you can leave this preprocessor disabled."); ?> </td> </tr> <tr> - <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> <?php echo gettext("DNP3 Detection"); ?></td> + <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable DNP3 Detection"); ?></td> <td width="78%" class="vtable"> - <input name="dnp3_preproc" type="checkbox" value="on" + <input name="dnp3_preproc" type="checkbox" value="on" <?php if ($pconfig['dnp3_preproc']=="on") echo "checked"; ?>> <?php echo gettext("DNP3 is a protocol used in SCADA networks. The default port is TCP 20000.") . "<br/>" . - gettext("If your network does not contain DNP3-enabled devices, you should leave this preprocessor disabled."); ?> + "<span class=\"red\"><strong>" . gettext("Note: ") . "</strong></span>" . + gettext("If your network does not contain DNP3-enabled devices, you can leave this preprocessor disabled."); ?> </td> </tr> <tr> <td width="22%" valign="top"> </td> - <td width="78%"> - <input name="Submit" type="submit" class="formbtn" value="Save" title="<?php echo - gettext("Save preprocessor settings"); ?>"/> - <input name="id" type="hidden" value="<?=$id;?>"> - <input name="ResetAll" type="submit" class="formbtn" value="Reset" title="<?php echo - gettext("Reset all settings to defaults") . "\" onclick=\"return confirm('" . - gettext("WARNING: This will reset ALL preprocessor settings to their defaults. Click OK to continue or CANCEL to quit.") . - "')\""; ?>/></td> - </tr> - <tr> - <td width="22%" valign="top"> </td> - <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note: "); ?></strong></span> - <?php echo gettext("Please save your settings before you exit. Preprocessor changes will rebuild the rules file. This "); ?> - <?php echo gettext("may take several seconds. Snort must also be restarted to activate any changes made on this screen."); ?></td> - </tr> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="Save" title="<?php echo + gettext("Save preprocessor settings"); ?>"> + <input name="id" type="hidden" value="<?=$id;?>"> + <input name="ResetAll" type="submit" class="formbtn" value="Reset" title="<?php echo + gettext("Reset all settings to defaults") . "\" onclick=\"return confirm('" . + gettext("WARNING: This will reset ALL preprocessor settings to their defaults. Click OK to continue or CANCEL to quit.") . + "');\""; ?>></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note: "); ?></strong></span></span> + <?php echo gettext("Please save your settings before you exit. Preprocessor changes will rebuild the rules file. This "); ?> + <?php echo gettext("may take several seconds. Snort must also be restarted to activate any changes made on this screen."); ?></td> + </tr> </table> </div> </td></tr></table> @@ -1201,6 +1345,15 @@ function frag3_enable_change() { document.iform.frag3_timeout.disabled=endis; } +function host_attribute_table_enable_change() { + var endis = !(document.iform.host_attribute_table.checked); + document.iform.host_attribute_file.disabled=endis; + document.iform.btn_import.disabled=endis; + document.iform.btn_edit_hat.disabled=endis; + document.iform.max_attribute_hosts.disabled=endis; + document.iform.max_attribute_services_per_host.disabled=endis; +} + function http_inspect_enable_change() { var endis = !(document.iform.http_inspect.checked); document.iform.http_inspect_enable_xff.disabled=endis; diff --git a/config/snort/snort_rules.php b/config/snort/snort_rules.php index ca63dae9..7853b955 100755 --- a/config/snort/snort_rules.php +++ b/config/snort/snort_rules.php @@ -193,6 +193,75 @@ if ($_GET['act'] == "toggle" && $_GET['ids'] && !empty($rules_map)) { write_config(); $_GET['openruleset'] = $currentruleset; +// header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); +// exit; + $anchor = "rule_{$sid}"; +} + +if ($_GET['act'] == "disable_all" && !empty($rules_map)) { + + // Mark all rules in the currently selected category "disabled". + foreach (array_keys($rules_map) as $k1) { + foreach (array_keys($rules_map[$k1]) as $k2) { + if (isset($enablesid[$k2])) + unset($enablesid[$k2]); + $disablesid[$k2] = "disablesid"; + } + } + // Write the updated enablesid and disablesid values to the config file. + $tmp = ""; + foreach ($enablesid as $k => $v) { + $tmp .= "||{$v} {$k}"; + } + if (!empty($tmp)) + $a_rule[$id]['rule_sid_on'] = $tmp; + else + unset($a_rule[$id]['rule_sid_on']); + $tmp = ""; + foreach ($disablesid as $k => $v) { + $tmp .= "||{$v} {$k}"; + } + if (!empty($tmp)) + $a_rule[$id]['rule_sid_off'] = $tmp; + else + unset($a_rule[$id]['rule_sid_off']); + write_config(); + + $_GET['openruleset'] = $currentruleset; + header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); + exit; +} + +if ($_GET['act'] == "enable_all" && !empty($rules_map)) { + + // Mark all rules in the currently selected category "enabled". + foreach (array_keys($rules_map) as $k1) { + foreach (array_keys($rules_map[$k1]) as $k2) { + if (isset($disablesid[$k2])) + unset($disablesid[$k2]); + $enablesid[$k2] = "enablesid"; + } + } + // Write the updated enablesid and disablesid values to the config file. + $tmp = ""; + foreach ($enablesid as $k => $v) { + $tmp .= "||{$v} {$k}"; + } + if (!empty($tmp)) + $a_rule[$id]['rule_sid_on'] = $tmp; + else + unset($a_rule[$id]['rule_sid_on']); + $tmp = ""; + foreach ($disablesid as $k => $v) { + $tmp .= "||{$v} {$k}"; + } + if (!empty($tmp)) + $a_rule[$id]['rule_sid_off'] = $tmp; + else + unset($a_rule[$id]['rule_sid_off']); + write_config(); + + $_GET['openruleset'] = $currentruleset; header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); exit; } @@ -250,9 +319,9 @@ if ($_GET['act'] == "resetall" && !empty($rules_map)) { if ($_POST['clear']) { unset($a_rule[$id]['customrules']); write_config(); - $rebuild_rules = "on"; + $rebuild_rules = true; snort_generate_conf($a_rule[$id]); - $rebuild_rules = "off"; + $rebuild_rules = false; header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); exit; } @@ -260,9 +329,9 @@ if ($_POST['clear']) { if ($_POST['customrules']) { $a_rule[$id]['customrules'] = base64_encode($_POST['customrules']); write_config(); - $rebuild_rules = "on"; + $rebuild_rules = true; snort_generate_conf($a_rule[$id]); - $rebuild_rules = "off"; + $rebuild_rules = false; $output = ""; $retcode = ""; exec("snort -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -T 2>&1", $output, $retcode); @@ -289,18 +358,18 @@ else if ($_POST['apply']) { /* Update the snort conf file and rebuild the */ /* rules for this interface. */ /*************************************************/ - $rebuild_rules = "on"; + $rebuild_rules = true; snort_generate_conf($a_rule[$id]); - $rebuild_rules = "off"; + $rebuild_rules = false; /* 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}"); +else if ($_POST['cancel']) { + + /* Return to this same page */ + header("Location: /snort/snort_rules.php?id={$id}"); exit; } @@ -398,8 +467,8 @@ if ($savemsg) { </tr> <tr> <td> - <input name="Submit" type="submit" class="formbtn" value="<?php echo gettext(" Save "); ?>" title=" <?php echo gettext("Save custom rules"); ?>"/> - <input type="button" class="formbtn" value=" <?php echo gettext("Cancel"); ?>" onclick="history.back()" title="<?php echo gettext("Cancel changes and return to last page"); ?>"/> + <input name="Submit" type="submit" class="formbtn" id="submit" value="<?php echo gettext(" Save "); ?>" title=" <?php echo gettext("Save custom rules"); ?>"/> + <input name="cancel" type="submit" class="formbtn" id="cancel" value="<?php echo gettext("Cancel"); ?>" title="<?php echo gettext("Cancel changes and return to last page"); ?>"/> <input name="clear" type="submit" class="formbtn" id="clear" value="<?php echo gettext("Clear"); ?>" onclick="return confirm('<?php echo gettext("This will erase all custom rules for the interface. Are you sure?"); ?>')" title="<?php echo gettext("Deletes all custom rules"); ?>"/> </td> </tr> @@ -411,10 +480,12 @@ if ($savemsg) { <td class="vncell"> <table width="100%" align="center" border="0" cellpadding="0" cellspacing="0"> <tr> - <td width="50%" valign="middle" rowspan="2"><input type="submit" name="apply" id="apply" value="<?php echo gettext("Apply"); ?>" class="formbtn" + <td rowspan="4" width="48%" valign="middle"><input type="submit" name="apply" id="apply" value="<?php echo gettext("Apply"); ?>" class="formbtn" title="<?php echo gettext("Click to rebuild the rules with your changes"); ?>"/> <input type='hidden' name='id' value='<?=$id;?>'/> - <input type='hidden' name='openruleset' value='<?=$currentruleset;?>'/></td> + <input type='hidden' name='openruleset' value='<?=$currentruleset;?>'/><br/><br/> + <span class="vexpl"><span class="red"><strong><?php echo gettext("Note: ") . "</strong></span>" . + gettext("Snort must be restarted to activate any SID enable/disable changes made on this tab."); ?></span></td> <td class="vexpl" valign="middle"><?php echo "<a href='?id={$id}&openruleset={$currentruleset}&act=resetcategory'> <img src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\" width=\"15\" height=\"15\" onmouseout='this.src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"' @@ -431,8 +502,20 @@ if ($savemsg) { <?php echo gettext("Remove all Enable/Disable changes in all Categories"); ?></td> </tr> <tr> - <td colspan="2" class="vexpl" valign="middle"><span class="red"><strong><?php echo gettext("Note: ") . "</strong></span>" . - gettext("Snort must be restarted to activate any SID enable/disable changes."); ?></td> + <td class="vexpl" valign="middle"><?php echo "<a href='?id={$id}&openruleset={$currentruleset}&act=disable_all'> + <img src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\" width=\"15\" height=\"15\" + onmouseout='this.src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"' + onmouseover='this.src=\"../themes/{$g['theme']}/images/icons/icon_x_mo.gif\"' border='0' + title='" . gettext("Click to disable all rules in the selected category") . "'></a>"?> + <?php echo gettext("Disable all rules in the current Category"); ?></td> + </tr> + <tr> + <td class="vexpl" valign="middle"><?php echo "<a href='?id={$id}&openruleset={$currentruleset}&act=enable_all'> + <img src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\" width=\"15\" height=\"15\" + onmouseout='this.src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"' + onmouseover='this.src=\"../themes/{$g['theme']}/images/icons/icon_x_mo.gif\"' border='0' + title='" . gettext("Click to enable all rules in the selected category") . "'></a>"?> + <?php echo gettext("Enable all rules in the current Category"); ?></td> </tr> </table> </td> @@ -456,6 +539,7 @@ if ($savemsg) { <col width="22" align="right" valign="middle"> </colgroup> <thead> + <tr> <th class="list"> </th> <th class="listhdrr"><?php echo gettext("SID"); ?></th> <th class="listhdrr"><?php echo gettext("Proto"); ?></th> @@ -470,6 +554,7 @@ if ($savemsg) { 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\"' ";?> title="<?php echo gettext("Click to view full text of all the category rules"); ?>" width="17" height="17" border="0"></a></th> + </tr> </thead> <tbody> @@ -519,7 +604,7 @@ if ($savemsg) { $message = snort_get_msg($v['rule']); echo "<tr><td class=\"listt\" align=\"left\" valign=\"middle\"> $textss - <a href='?id={$id}&openruleset={$currentruleset}&act=toggle&ids={$sid}'> + <a id=\"rule_{$sid}\" href='?id={$id}&openruleset={$currentruleset}&act=toggle&ids={$sid}'> <img src=\"../themes/{$g['theme']}/images/icons/{$iconb}\" width=\"11\" height=\"11\" border=\"0\" title='" . gettext("Click to toggle enabled/disabled state") . "'></a> @@ -532,19 +617,19 @@ if ($savemsg) { {$textss}{$protocol}{$textse} </td> <td class=\"listlr\" align=\"center\"> - {$srcspan}{$source}{$textse} + {$srcspan}{$source}</span> </td> <td class=\"listlr\" align=\"center\"> - {$srcprtspan}{$source_port}{$textse} + {$srcprtspan}{$source_port}</span> </td> <td class=\"listlr\" align=\"center\"> - {$dstspan}{$destination}{$textse} + {$dstspan}{$destination}</span> </td> <td class=\"listlr\" align=\"center\"> - {$dstprtspan}{$destination_port}{$textse} + {$dstprtspan}{$destination_port}</span> </td> <td class=\"listbg\" style=\"word-wrap:break-word; whitespace:pre-line;\"><font color=\"white\"> - {$textss}{$message}{$textse} + {$textss}{$message}{$textse}</font> </td>"; ?> <td align="right" valign="middle" nowrap class="listt"> @@ -615,17 +700,24 @@ 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(); + 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(); } +<?php if (!empty($anchor)): ?> + // Scroll the last enabled/disabled SID into view + window.location.hash = "<?=$anchor; ?>"; + window.scrollBy(0,-60); + +<?php endif;?> + </script> </body> </html> diff --git a/config/snort/snort_rules_flowbits.php b/config/snort/snort_rules_flowbits.php index 215399c6..7a653af8 100644 --- a/config/snort/snort_rules_flowbits.php +++ b/config/snort/snort_rules_flowbits.php @@ -38,9 +38,10 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g, $flowbit_rules_file, $rebuild_rules; +global $g, $rebuild_rules; $snortdir = SNORTDIR; +$flowbit_rules_file = FLOWBITS_FILENAME; $rules_map = array(); $supplist = array(); @@ -67,10 +68,10 @@ if ($a_nat[$id]['autoflowbitrules'] == 'on') { $rules_map = snort_load_rules_map("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}"); } else - $savemsg = "There are no flowbit-required rules necessary for the current enforcing rule set."; + $savemsg = gettext("There are no flowbit-required rules necessary for the current enforcing rule set."); } else - $input_errors[] = "Auto-Flowbit rule generation is disabled for this interface!"; + $input_errors[] = gettext("Auto-Flowbit rule generation is disabled for this interface!"); if ($_GET['act'] == "addsuppress" && is_numeric($_GET['sidid']) && is_numeric($_GET['gen_id'])) { $descr = snort_get_msg($rules_map[$_GET['gen_id']][$_GET['sidid']]['rule']); @@ -83,6 +84,7 @@ if ($_GET['act'] == "addsuppress" && is_numeric($_GET['sidid']) && is_numeric($_ if (!is_array($config['installedpackages']['snortglobal']['suppress']['item'])) $config['installedpackages']['snortglobal']['suppress']['item'] = array(); $a_suppress = &$config['installedpackages']['snortglobal']['suppress']['item']; + $found_list = false; if (empty($a_nat[$id]['suppresslistname']) || $a_nat[$id]['suppresslistname'] == 'default') { $s_list = array(); @@ -92,9 +94,11 @@ if ($_GET['act'] == "addsuppress" && is_numeric($_GET['sidid']) && is_numeric($_ $s_list['suppresspassthru'] = base64_encode($suppress); $a_suppress[] = $s_list; $a_nat[$id]['suppresslistname'] = $s_list['name']; + $found_list = true; } else { foreach ($a_suppress as $a_id => $alist) { if ($alist['name'] == $a_nat[$id]['suppresslistname']) { + $found_list = true; if (!empty($alist['suppresspassthru'])) { $tmplist = base64_decode($alist['suppresspassthru']); $tmplist .= "\n{$suppress}"; @@ -104,10 +108,16 @@ if ($_GET['act'] == "addsuppress" && is_numeric($_GET['sidid']) && is_numeric($_ } } } - write_config(); - $rebuild_rules = "off"; - sync_snort_package_config(); - $savemsg = "Wrote suppress rule for gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']} to the {$a_nat[$id]['suppresslistname']} Suppression List."; + if ($found_list) { + write_config(); + $rebuild_rules = false; + sync_snort_package_config(); + $savemsg = gettext("Wrote suppress rule for 'gen_id {$_GET['gen_id']}, sig_id {$_GET['sidid']}' to the '{$a_nat[$id]['suppresslistname']}' Suppression List."); + } + else { + /* We did not find the defined list, so notify the user with an error */ + $input_errors[] = gettext("Suppress List '{$a_nat[$id]['suppresslistname']}' is defined for this interface, but it could not be found!"); + } } function truncate($string, $length) { @@ -165,11 +175,11 @@ if ($savemsg) </tr> <tr> <td width="78%" class="vncell"> - <table width="100%" border="0 cellspacing="2" cellpadding="0"> + <table width="100%" border="0" cellspacing="2" cellpadding="0"> <tr> <td width="17px"><img src="../themes/<?=$g['theme']?>/images/icons/icon_plus.gif" width='12' height='12' border='0'/></td> <td><span class="vexpl"><?php echo gettext("Alert is Not Suppressed"); ?></span></td> - <td rowspan="3" align="right"><input id="cancelbutton" name="cancelbutton" type="button" class="formbtn" onclick="history.back()" <?php + <td rowspan="3" align="right"><input id="cancelbutton" name="cancelbutton" type="button" class="formbtn" onclick="parent.location='snort_rulesets.php?id=<?=$id;?>'" <?php echo "value=\"" . gettext("Return") . "\" title=\"" . gettext("Return to previous page") . "\""; ?>/></td> </tr> <tr> @@ -197,12 +207,14 @@ if ($savemsg) <col axis="string"> </colgroup> <thead> + <tr> <th class="listhdrr" axis="number"><?php echo gettext("SID"); ?></th> - <td class="listhdrr" axis="string"><?php echo gettext("Proto"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("Proto"); ?></th> <th class="listhdrr" axis="string"><?php echo gettext("Source"); ?></th> <th class="listhdrr" axis="string"><?php echo gettext("Destination"); ?></th> <th class="listhdrr" axis="string"><?php echo gettext("Flowbits"); ?></th> <th class="listhdrr" axis="string"><?php echo gettext("Message"); ?></th> + </tr> <thead> <tbody> <?php @@ -228,12 +240,12 @@ if ($savemsg) else { if (!isset($supplist[$gid][$sid])) { $supplink = "<a href=\"?id={$id}&act=addsuppress&sidid={$sid}&gen_id={$gid}\">"; - $supplink .= "<img src=\"../themes/{$g['theme']}/images/icons/icon_plus.gif\""; + $supplink .= "<img src=\"../themes/{$g['theme']}/images/icons/icon_plus.gif\" "; $supplink .= "width='12' height='12' border='0' title='"; $supplink .= gettext("Click to add to Suppress List") . "'/></a>"; } else { - $supplink .= "<img src=\"../themes/{$g['theme']}/images/icons/icon_plus_d.gif\""; + $supplink = "<img src=\"../themes/{$g['theme']}/images/icons/icon_plus_d.gif\" "; $supplink .= "width='12' height='12' border='0' title='"; $supplink .= gettext("Alert has been suppressed") . "'/>"; } @@ -260,7 +272,7 @@ if ($savemsg) <?php if ($count > 20): ?> <tr> <td align="center" valign="middle"> - <input id="cancelbutton" name="cancelbutton" type="button" class="formbtn" onclick="history.back()" <?php + <input id="cancelbutton" name="cancelbutton" type="button" class="formbtn" onclick="parent.location='snort_rulesets.php?id=<?=$id;?>'" <?php echo "value=\"" . gettext("Return") . "\" title=\"" . gettext("Return to previous page") . "\""; ?>/> <input name="id" type="hidden" value="<?=$id;?>" /> </td> diff --git a/config/snort/snort_rulesets.php b/config/snort/snort_rulesets.php index fa3efc1b..7ec0edbd 100755 --- a/config/snort/snort_rulesets.php +++ b/config/snort/snort_rulesets.php @@ -32,9 +32,10 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g, $flowbit_rules_file, $rebuild_rules; +global $g, $rebuild_rules; $snortdir = SNORTDIR; +$flowbit_rules_file = FLOWBITS_FILENAME; if (!is_array($config['installedpackages']['snortglobal']['rule'])) { $config['installedpackages']['snortglobal']['rule'] = array(); @@ -143,9 +144,9 @@ if ($_POST["Submit"]) { /* Update the snort conf file and rebuild the */ /* rules for this interface. */ /*************************************************/ - $rebuild_rules = "on"; + $rebuild_rules = true; snort_generate_conf($a_nat[$id]); - $rebuild_rules = "off"; + $rebuild_rules = false; header("Location: /snort/snort_rulesets.php?id=$id"); exit; diff --git a/config/sudo/sudo.inc b/config/sudo/sudo.inc new file mode 100644 index 00000000..a65753a1 --- /dev/null +++ b/config/sudo/sudo.inc @@ -0,0 +1,179 @@ +<?php +/* + sudo.inc + + Copyright (C) 2013 Jim Pingle (jpingle@gmail.com) + 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. +*/ + +$pfs_version = substr(trim(file_get_contents("/etc/version")),0,3); +switch ($pfs_version) { + case "1.2": + case "2.0": + define('SUDO_BASE','/usr/local'); + break; + default: + // Hackish way to detect if someone manually did pkg_add rather than use pbi. + if (is_dir('/usr/pbi/sudo-' . php_uname("m"))) + define('SUDO_BASE', '/usr/pbi/sudo-' . php_uname("m")); + else + define('SUDO_BASE','/usr/local'); +} + +define('SUDO_CONFIG_DIR', SUDO_BASE . '/etc'); +define('SUDO_SUDOERS', SUDO_CONFIG_DIR . '/sudoers'); + +function sudo_install() { + global $g, $config; + /* If we don't have a config, pre-load some good default sudo entries. */ + if (!is_array($config['installedpackages']['sudo']['config'][0]['row'])) { + $config['installedpackages']['sudo']['config'][0]['row'] = array( + 0 => array( + "username" => "user:root", + "runas" => "user:root", + "cmdlist" => "ALL" + ), + 1 => array( + "username" => "user:admin", + "runas" => "user:root", + "cmdlist" => "ALL" + ), + 2 => array( + "username" => "group:admins", + "runas" => "user:root", + "cmdlist" => "ALL" + ) + ); + } +} + +function sudo_write_config() { + global $config; + $sudoers = ""; + if (!is_array($config['installedpackages']['sudo']['config'][0]['row'])) { + /* No config, wipe sudoers file and bail. */ + unlink(SUDO_SUDOERS); + log_error("No sudo configuration found, removing sudoers file to prevent unpredictable results."); + return; + } + $sudocfg = &$config['installedpackages']['sudo']['config'][0]['row']; + /* Parse the config and massage it into proper sudo config lines. */ + foreach ($sudocfg as $sudo_commands) { + // (user|group) ALL=(ALL|user spec) ALL|command list + list($etype, $ename) = explode(":", $sudo_commands['username']); + $user = ($etype == "group") ? "%{$ename}" : $ename; + list($rtype, $rname) = explode(":", $sudo_commands['runas']); + $runas = ($rtype == "group") ? ":{$rname}" : $rname; + $nopasswd = ($sudo_commands['nopasswd'] == "ON") ? "NOPASSWD:" : ""; + $commands = (empty($sudo_commands['cmdlist'])) ? "ALL" : $sudo_commands['cmdlist']; + $commands = ($commands == "all") ? "ALL" : $commands; + $sudoers .= "{$user} ALL=({$runas}) {$nopasswd} {$commands}\n"; + } + + /* Check validity of the sudoers data created above. */ + $tmpsudoers = tempnam("/tmp", "sudoers"); + file_put_contents($tmpsudoers, $sudoers); + $result = exec("/usr/local/sbin/visudo -c -f {$tmpsudoers}"); + + /* If the file is OK, move it into place with the correct permissions, otherwise log an error and trash it. */ + if (stristr($result, "parsed OK")) { + rename($tmpsudoers, SUDO_SUDOERS); + chmod(SUDO_SUDOERS, 0440); + } else { + log_error("Sudoers file invalid: {$result}"); + unlink($tmpsudoers); + } +} + +/* Get a list of users and groups in a format we can use to make proper sudoers entries. +Optionally include "ALL" as a user (for use by the Run As list) + */ +function sudo_get_users($list_all_user = false) { + global $config; + if (!is_array($config['system']['user'])) + $config['system']['user'] = array(); + $a_user = &$config['system']['user']; + if (!is_array($config['system']['group'])) + $config['system']['group'] = array(); + $a_group = &$config['system']['group']; + $users = array(); + + /* Make an entry for root, even though admin is essentially the same as root, they are distinct. */ + $tmpuser = array(); + $tmpuser["name"] = "user:root"; + $tmpuser["descr"] = "User: root"; + $users[] = $tmpuser; + + /* Add the all user if we want it */ + if ($list_all_user) { + $tmpuser = array(); + $tmpuser["name"] = "user:ALL"; + $tmpuser["descr"] = "User: ALL Users"; + $users[] = $tmpuser; + } + + foreach ($a_user as $user) { + $tmpuser = array(); + $tmpuser["name"] = "user:{$user['name']}"; + $tmpuser["descr"] = "User: {$user['name']}"; + $users[] = $tmpuser; + } + + /* Add the wheel group here. We may need other manual groups later (e.g. operator) */ + $tmpuser = array(); + $tmpuser["name"] = "group:wheel"; + $tmpuser["descr"] = "Group: wheel"; + $users[] = $tmpuser; + + foreach ($a_group as $group) { + /* The "all" group is internal and doesn't make sense to use here. */ + if ($group['name'] == "all") + continue; + $tmpgroup = array(); + $tmpgroup["name"] = "group:{$group['name']}"; + $tmpgroup["descr"] = "Group: {$group['name']}"; + $users[] = $tmpgroup; + } + + return $users; +} + +/* Make sure commands passed in are valid executables to help ensure a valid sudoers file and expected behavior. + This also forces the user to give full paths to executables, which they should be doing anyhow. + */ +function sudo_validate_commands($input_errors) { + $idx = 0; + while(isset($_POST["cmdlist{$idx}"])) { + $commands = $_POST["cmdlist" . $idx++]; + if (strtoupper($commands) == "ALL") + continue; + $commands = explode(",", $commands); + foreach ($commands as $command) { + list($cmd, $params) = explode(" ", trim($command), 2); + if (!is_executable($cmd)) + $input_errors[] = htmlspecialchars($cmd) . " is not an executable command."; + } + } +} +?> diff --git a/config/sudo/sudo.xml b/config/sudo/sudo.xml new file mode 100644 index 00000000..56163abf --- /dev/null +++ b/config/sudo/sudo.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8" ?> +<packagegui> + <description>Sudo Command Control</description> + <requirements>None</requirements> + <name>sudo</name> + <version>0.1</version> + <title>Sudo - Shell Command Privilege Delegation Utility</title> + <include_file>/usr/local/pkg/sudo.inc</include_file> + <menu> + <name>sudo</name> + <tooltiptext></tooltiptext> + <section>System</section> + <url>/pkg_edit.php?xml=sudo.xml</url> + </menu> + <configpath>installedpackages->package->sudo</configpath> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/sudo/sudo.inc</item> + </additional_files_needed> + <fields> + <field> + <type>listtopic</type> + <name>Sudo Options</name> + </field> + <field> + <type>info</type> + <description><![CDATA[ +User permission definitions for allowing the use of sudo by shell users to run commands as other users, such as root. +<br /><br />More information on the full command options may be found in the <a href="http://www.sudo.ws/sudoers.man.html">sudoers manual</a>. +<br /><br />By default the command is "ALL" meaning the user can run any commands. Leaving the commands field blank assumes "ALL". A comma-separated list of commands can be supplied to limit the user to individual binaries. Full paths to binaries must be used. + ]]></description> + </field> + <field> + <fielddescr>User Permissions</fielddescr> + <fieldname>none</fieldname> + <type>rowhelper</type> + <rowhelper> + <rowhelperfield> + <fielddescr>User/Group</fielddescr> + <fieldname>username</fieldname> + <type>select_source</type> + <source><![CDATA[sudo_get_users()]]></source> + <source_name>descr</source_name> + <source_value>name</source_value> + <required/> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Run As</fielddescr> + <fieldname>runas</fieldname> + <type>select_source</type> + <source><![CDATA[sudo_get_users(true)]]></source> + <source_name>descr</source_name> + <source_value>name</source_value> + <required/> + </rowhelperfield> + <rowhelperfield> + <fielddescr>No Password</fielddescr> + <fieldname>nopasswd</fieldname> + <type>checkbox</type> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Command List</fielddescr> + <fieldname>cmdlist</fieldname> + <description>Commands the user may run. Comma-separated list, full paths preferred. Default: ALL</description> + <type>input</type> + <size>30</size> + <value>ALL</value> + </rowhelperfield> + </rowhelper> + </field> + </fields> + <custom_php_install_command> + <![CDATA[ + sudo_install(); + sudo_write_config(); + ]]> + </custom_php_install_command> + <custom_php_resync_config_command> + <![CDATA[ + sudo_write_config(); + ]]> + </custom_php_resync_config_command> + <custom_php_validation_command> + <![CDATA[ + sudo_validate_commands(&$input_errors); + ]]> + </custom_php_validation_command> +</packagegui> |