From: Russ Combs Date: Wed, 18 Mar 2015 17:32:10 +0000 (-0400) Subject: apply module defaults; bump build to 142 X-Git-Tag: 3.0.0-233~1021 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b58b2e80c77e7ea31e018aee5765dea456f7cef2;p=thirdparty%2Fsnort3.git apply module defaults; bump build to 142 --- diff --git a/ChangeLog b/ChangeLog index 2bb9788b7..f7480db15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ -Pending - build 142 +15/03/18 - build 142 +-- apply defaults from parameter tables instead of relying on ctors etc. -- fix static analysis issues reported by xcode -- change policy names with a-b form to a_b for consistency -- make all warnings optional diff --git a/README b/README index 23e132935..058ec9684 100644 --- a/README +++ b/README @@ -158,6 +158,8 @@ Then give it a go: $my_path/bin/snort -c $my_path/etc/snort/snort.lua -R $my_path/etc/snort/sample.rules \ --pcap-filter \*.pcap --pcap-dir pcaps/ -A alert_fast --max-packet-threads 8 +Additional examples are given in doc/usage.txt. + DOCUMENTATION Take a look at the manual, parts of which are generated by the code so it diff --git a/lua/classification.lua b/lua/classification.lua deleted file mode 100644 index 1c7794c8f..000000000 --- a/lua/classification.lua +++ /dev/null @@ -1,140 +0,0 @@ --- The following includes information for prioritizing rules --- --- Each classification includes a shortname, a description, and a default --- priority for that classification. --- --- This allows alerts to be classified and prioritized. You can specify --- what priority each classification has. Any rule can override the default --- priority for that rule. --- --- Here are a few example rules: --- --- alert TCP any any -> any 80 (msg: "EXPLOIT ntpdx overflow"; --- dsize: > 128; classtype:attempted-admin; priority:10; --- --- alert TCP any any -> any 25 (msg:"SMTP expn root"; flags:A+; \ --- content:"expn root"; nocase; classtype:attempted-recon;) --- --- The first rule will set its type to "attempted-admin" and override --- the default priority for that type to 10. --- --- The second rule set its type to "attempted-recon" and set its --- priority to the default for that type. - -classifications = -{ - { name = 'not-suspicious', priority = 3, - text = 'Not Suspicious Traffic' }, - - { name = 'unknown', priority = 3, - text = 'Unknown Traffic' }, - - { name = 'bad-unknown', priority = 2, - text = 'Potentially Bad Traffic' }, - - { name = 'attempted-recon', priority = 2, - text = 'Attempted Information Leak' }, - - { name = 'successful-recon-limited', priority = 2, - text = 'Information Leak' }, - - { name = 'successful-recon-largescale', priority = 2, - text = 'Large Scale Information Leak' }, - - { name = 'attempted-dos', priority = 2, - text = 'Attempted Denial of Service' }, - - { name = 'successful-dos', priority = 2, - text = 'Denial of Service' }, - - { name = 'attempted-user', priority = 1, - text = 'Attempted User Privilege Gain' }, - - { name = 'unsuccessful-user', priority = 1, - text = 'Unsuccessful User Privilege Gain' }, - - { name = 'successful-user', priority = 1, - text = 'Successful User Privilege Gain' }, - - { name = 'attempted-admin', priority = 1, - text = 'Attempted Administrator Privilege Gain' }, - - { name = 'successful-admin', priority = 1, - text = 'Successful Administrator Privilege Gain' }, - - { name = 'rpc-portmap-decode', priority = 2, - text = 'Decode of an RPC Query' }, - - { name = 'shellcode-detect', priority = 1, - text = 'Executable code was detected' }, - - { name = 'string-detect', priority = 3, - text = 'A suspicious string was detected' }, - - { name = 'suspicious-filename-detect', priority = 2, - text = 'A suspicious filename was detected' }, - - { name = 'suspicious-login', priority = 2, - text = 'An attempted login using a suspicious username was detected' }, - - { name = 'system-call-detect', priority = 2, - text = 'A system call was detected' }, - - { name = 'tcp-connection', priority = 4, - text = 'A TCP connection was detected' }, - - { name = 'trojan-activity', priority = 1, - text = 'A Network Trojan was detected' }, - - { name = 'unusual-client-port-connection', priority = 2, - text = 'A client was using an unusual port' }, - - { name = 'network-scan', priority = 3, - text = 'Detection of a Network Scan' }, - - { name = 'denial-of-service', priority = 2, - text = 'Detection of a Denial of Service Attack' }, - - { name = 'non-standard-protocol', priority = 2, - text = 'Detection of a non-standard protocol or event' }, - - { name = 'protocol-command-decode', priority = 3, - text = 'Generic Protocol Command Decode' }, - - { name = 'web-application-activity', priority = 2, - text = 'access to a potentially vulnerable web application' }, - - { name = 'web-application-attack', priority = 1, - text = 'Web Application Attack' }, - - { name = 'misc-activity', priority = 3, - text = 'Misc activity' }, - - { name = 'misc-attack', priority = 2, - text = 'Misc Attack' }, - - { name = 'icmp-event', priority = 3, - text = 'Generic ICMP event' }, - - { name = 'inappropriate-content', priority = 1, - text = 'Inappropriate Content was Detected' }, - - { name = 'policy-violation', priority = 1, - text = 'Potential Corporate Privacy Violation' }, - - { name = 'default-login-attempt', priority = 2, - text = 'Attempt to login by a default username and password' }, - - { name = 'sdf', priority = 2, - text = 'Senstive Data' }, - - { name = 'file-format', priority = 1, - text = 'Known malicious file or file based exploit' }, - - { name = 'malware-cnc', priority = 1, - text = 'Known malware command and control traffic' }, - - { name = 'client-side-exploit', priority = 1, - text = 'Known client side exploit attempt' } -} - diff --git a/lua/reference.lua b/lua/reference.lua deleted file mode 100644 index b5daefe49..000000000 --- a/lua/reference.lua +++ /dev/null @@ -1,17 +0,0 @@ --- The following defines URLs for the references found in the rules - -references = -{ - { name = 'bugtraq', url = 'http://www.securityfocus.com/bid/' }, - { name = 'cve', url = 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=' }, - { name = 'arachNIDS', url = 'http://www.whitehats.com/info/IDS' }, - { name = 'osvdb', url = 'http://osvdb.org/show/osvdb/' }, - - -- Note, this one needs a suffix as well.... lets add that in a bit. - { name = 'McAfee', url = 'http://vil.nai.com/vil/content/v_' }, - - { name = 'nessus', url = 'http://cgi.nessus.org/plugins/dump.php3?id=' }, - { name = 'url', url = 'http://' }, - { name = 'msb', url = 'http://technet.microsoft.com/en-us/security/bulletin/' } -} - diff --git a/lua/snort.lua b/lua/snort.lua index 7669b585c..47da29f95 100644 --- a/lua/snort.lua +++ b/lua/snort.lua @@ -35,8 +35,6 @@ if ( not conf_dir ) then end dofile(conf_dir .. '/snort_defaults.lua') -dofile(conf_dir .. '/classification.lua') -dofile(conf_dir .. '/reference.lua') --------------------------------------------------------------------------- -- configure modules diff --git a/lua/snort_defaults.lua b/lua/snort_defaults.lua index 08f7d0a73..10fcd51f9 100644 --- a/lua/snort_defaults.lua +++ b/lua/snort_defaults.lua @@ -198,19 +198,9 @@ default_ftp_server = } --------------------------------------------------------------------------- --- default wizard +-- default http profiles --------------------------------------------------------------------------- -http_methods = -- build from default_http_methods -{ - 'GET', 'POST', 'PUT', 'SEARCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK', - 'NOTIFY', 'POLL', 'BCOPY', 'BDELETE', 'BMOVE', 'LINK', 'UNLINK', 'OPTIONS', - 'HEAD', 'DELETE', 'TRACE', 'TRACK', 'CONNECT', 'SOURCE', 'SUBSCRIBE', - 'UNSUBSCRIBE', 'PROPFIND', 'PROPPATCH', 'BPROPFIND', 'BPROPPATCH', - 'RPC_CONNECT', 'PROXY_SUCCESS', 'BITS_POST', 'CCM_POST', 'SMS_POST', - 'RPC_IN_DATA', 'RPC_OUT_DATA', 'RPC_ECHO_DATA' -} - http_profile_default = { profile_type = 'default', @@ -346,6 +336,20 @@ http_profile_iis_50 = whitespace_chars ='0x9 0xb 0xc 0xd' } +--------------------------------------------------------------------------- +-- default wizard +--------------------------------------------------------------------------- + +http_methods = -- build from default_http_methods +{ + 'GET', 'POST', 'PUT', 'SEARCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK', + 'NOTIFY', 'POLL', 'BCOPY', 'BDELETE', 'BMOVE', 'LINK', 'UNLINK', 'OPTIONS', + 'HEAD', 'DELETE', 'TRACE', 'TRACK', 'CONNECT', 'SOURCE', 'SUBSCRIBE', + 'UNSUBSCRIBE', 'PROPFIND', 'PROPPATCH', 'BPROPFIND', 'BPROPPATCH', + 'RPC_CONNECT', 'PROXY_SUCCESS', 'BITS_POST', 'CCM_POST', 'SMS_POST', + 'RPC_IN_DATA', 'RPC_OUT_DATA', 'RPC_ECHO_DATA' +} + ftp_commands = -- build from ftp_default_commands { 'ABOR', 'ACCT', 'ADAT', 'ALLO', 'APPE', 'AUTH', 'CCC', 'CDUP', 'CEL', @@ -435,3 +439,140 @@ default_wizard = } } +--------------------------------------------------------------------------- +-- default references +--------------------------------------------------------------------------- + +references = +{ + { name = 'bugtraq', url = 'http://www.securityfocus.com/bid/' }, + { name = 'cve', url = 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=' }, + { name = 'arachNIDS', url = 'http://www.whitehats.com/info/IDS' }, + { name = 'osvdb', url = 'http://osvdb.org/show/osvdb/' }, + { name = 'McAfee', url = 'http://vil.nai.com/vil/content/v_' }, + { name = 'nessus', url = 'http://cgi.nessus.org/plugins/dump.php3?id=' }, + { name = 'url', url = 'http://' }, + { name = 'msb', url = 'http://technet.microsoft.com/en-us/security/bulletin/' } +} + +--------------------------------------------------------------------------- +-- default classifications +--------------------------------------------------------------------------- + +classifications = +{ + { name = 'not-suspicious', priority = 3, + text = 'Not Suspicious Traffic' }, + + { name = 'unknown', priority = 3, + text = 'Unknown Traffic' }, + + { name = 'bad-unknown', priority = 2, + text = 'Potentially Bad Traffic' }, + + { name = 'attempted-recon', priority = 2, + text = 'Attempted Information Leak' }, + + { name = 'successful-recon-limited', priority = 2, + text = 'Information Leak' }, + + { name = 'successful-recon-largescale', priority = 2, + text = 'Large Scale Information Leak' }, + + { name = 'attempted-dos', priority = 2, + text = 'Attempted Denial of Service' }, + + { name = 'successful-dos', priority = 2, + text = 'Denial of Service' }, + + { name = 'attempted-user', priority = 1, + text = 'Attempted User Privilege Gain' }, + + { name = 'unsuccessful-user', priority = 1, + text = 'Unsuccessful User Privilege Gain' }, + + { name = 'successful-user', priority = 1, + text = 'Successful User Privilege Gain' }, + + { name = 'attempted-admin', priority = 1, + text = 'Attempted Administrator Privilege Gain' }, + + { name = 'successful-admin', priority = 1, + text = 'Successful Administrator Privilege Gain' }, + + { name = 'rpc-portmap-decode', priority = 2, + text = 'Decode of an RPC Query' }, + + { name = 'shellcode-detect', priority = 1, + text = 'Executable code was detected' }, + + { name = 'string-detect', priority = 3, + text = 'A suspicious string was detected' }, + + { name = 'suspicious-filename-detect', priority = 2, + text = 'A suspicious filename was detected' }, + + { name = 'suspicious-login', priority = 2, + text = 'An attempted login using a suspicious username was detected' }, + + { name = 'system-call-detect', priority = 2, + text = 'A system call was detected' }, + + { name = 'tcp-connection', priority = 4, + text = 'A TCP connection was detected' }, + + { name = 'trojan-activity', priority = 1, + text = 'A Network Trojan was detected' }, + + { name = 'unusual-client-port-connection', priority = 2, + text = 'A client was using an unusual port' }, + + { name = 'network-scan', priority = 3, + text = 'Detection of a Network Scan' }, + + { name = 'denial-of-service', priority = 2, + text = 'Detection of a Denial of Service Attack' }, + + { name = 'non-standard-protocol', priority = 2, + text = 'Detection of a non-standard protocol or event' }, + + { name = 'protocol-command-decode', priority = 3, + text = 'Generic Protocol Command Decode' }, + + { name = 'web-application-activity', priority = 2, + text = 'access to a potentially vulnerable web application' }, + + { name = 'web-application-attack', priority = 1, + text = 'Web Application Attack' }, + + { name = 'misc-activity', priority = 3, + text = 'Misc activity' }, + + { name = 'misc-attack', priority = 2, + text = 'Misc Attack' }, + + { name = 'icmp-event', priority = 3, + text = 'Generic ICMP event' }, + + { name = 'inappropriate-content', priority = 1, + text = 'Inappropriate Content was Detected' }, + + { name = 'policy-violation', priority = 1, + text = 'Potential Corporate Privacy Violation' }, + + { name = 'default-login-attempt', priority = 2, + text = 'Attempt to login by a default username and password' }, + + { name = 'sdf', priority = 2, + text = 'Senstive Data' }, + + { name = 'file-format', priority = 1, + text = 'Known malicious file or file based exploit' }, + + { name = 'malware-cnc', priority = 1, + text = 'Known malware command and control traffic' }, + + { name = 'client-side-exploit', priority = 1, + text = 'Known client side exploit attempt' } +} + diff --git a/src/actions/act_react.cc b/src/actions/act_react.cc index 8820dee92..e500a6533 100644 --- a/src/actions/act_react.cc +++ b/src/actions/act_react.cc @@ -256,7 +256,7 @@ static void react_config(ReactData* rd) static const Parameter s_params[] = { - { "msg", Parameter::PT_BOOL, nullptr, nullptr, + { "msg", Parameter::PT_BOOL, nullptr, "false", " use rule message in response page" }, { "page", Parameter::PT_STRING, nullptr, nullptr, diff --git a/src/framework/parameter.cc b/src/framework/parameter.cc index 3e4c98aab..79730ee95 100644 --- a/src/framework/parameter.cc +++ b/src/framework/parameter.cc @@ -21,6 +21,7 @@ #include #include +#include #include "utils/dnet_header.h" #include @@ -402,6 +403,27 @@ const char* Parameter::get_type() const return pt2str[type]; } +bool Parameter::get_bool() const +{ + if ( !deflt ) + return false; + + return ( strchr(deflt, 't') || strchr(deflt, 'T') ); +} + +double Parameter::get_number() const +{ + if ( !deflt ) + return 0; + + return strtod(deflt, nullptr); +} + +const char* Parameter::get_string() const +{ + return deflt ? deflt : ""; +} + const Parameter* Parameter::find(const Parameter* p, const char* s) { while ( p->name ) diff --git a/src/framework/parameter.h b/src/framework/parameter.h index 8ac712da8..9d4f2cb3d 100644 --- a/src/framework/parameter.h +++ b/src/framework/parameter.h @@ -66,6 +66,10 @@ struct Parameter bool is_quoted() const { return ( type > PT_PORT ); } + bool get_bool() const; + double get_number() const; + const char* get_string() const; + static const Parameter* find(const Parameter*, const char*); }; diff --git a/src/ips_options/ips_base64.cc b/src/ips_options/ips_base64.cc index 4a3978c01..ca71ea9e2 100644 --- a/src/ips_options/ips_base64.cc +++ b/src/ips_options/ips_base64.cc @@ -190,7 +190,7 @@ static const Parameter s_params[] = { "bytes", Parameter::PT_INT, "1:", nullptr, "Number of base64 encoded bytes to decode." }, - { "offset", Parameter::PT_INT, "0:", nullptr, + { "offset", Parameter::PT_INT, "0:", "0", "Bytes past start of buffer to start decoding." }, { "relative", Parameter::PT_IMPLIED, nullptr, nullptr, diff --git a/src/ips_options/ips_byte_extract.cc b/src/ips_options/ips_byte_extract.cc index 1abf53558..8e5303a86 100644 --- a/src/ips_options/ips_byte_extract.cc +++ b/src/ips_options/ips_byte_extract.cc @@ -395,10 +395,10 @@ static const Parameter s_params[] = { "relative", Parameter::PT_IMPLIED, nullptr, nullptr, "offset from cursor instead of start of buffer" }, - { "multiplier", Parameter::PT_INT, "1:65535", nullptr, + { "multiplier", Parameter::PT_INT, "1:65535", "1", "scale extracted value by given amount" }, - { "align", Parameter::PT_INT, "0:4", nullptr, + { "align", Parameter::PT_INT, "0:4", "0", "round the number of converted bytes up to the next 2- or 4-byte boundary" }, { "big", Parameter::PT_IMPLIED, nullptr, nullptr, diff --git a/src/ips_options/ips_byte_jump.cc b/src/ips_options/ips_byte_jump.cc index 693861fa3..b51385d4f 100644 --- a/src/ips_options/ips_byte_jump.cc +++ b/src/ips_options/ips_byte_jump.cc @@ -314,13 +314,13 @@ static const Parameter s_params[] = { "from_beginning", Parameter::PT_IMPLIED, nullptr, nullptr, "jump from start of buffer instead of cursor" }, - { "multiplier", Parameter::PT_INT, "1:65535", nullptr, + { "multiplier", Parameter::PT_INT, "1:65535", "1", "scale extracted value by given amount" }, - { "align", Parameter::PT_INT, "0:4", nullptr, + { "align", Parameter::PT_INT, "0:4", "0", "round the number of converted bytes up to the next 2- or 4-byte boundary" }, - { "post_offset", Parameter::PT_INT, "-65535:65535", nullptr, + { "post_offset", Parameter::PT_INT, "-65535:65535", "0", "also skip forward or backwards (positive of negative value) this number of bytes" }, { "big", Parameter::PT_IMPLIED, nullptr, nullptr, diff --git a/src/ips_options/ips_content.cc b/src/ips_options/ips_content.cc index 60724591f..93a04245a 100644 --- a/src/ips_options/ips_content.cc +++ b/src/ips_options/ips_content.cc @@ -666,7 +666,7 @@ static const Parameter s_params[] = { "fast_pattern", Parameter::PT_IMPLIED, nullptr, nullptr, "use this content in the fast pattern matcher instead of the content selected by default" }, - { "fast_pattern_offset", Parameter::PT_INT, nullptr, nullptr, + { "fast_pattern_offset", Parameter::PT_INT, "0:", "0", "number of leading characters of this content the fast pattern matcher should exclude" }, { "fast_pattern_length", Parameter::PT_INT, "1:", nullptr, diff --git a/src/loggers/log_codecs.cc b/src/loggers/log_codecs.cc index 40e290f49..b6eef99db 100644 --- a/src/loggers/log_codecs.cc +++ b/src/loggers/log_codecs.cc @@ -51,7 +51,7 @@ static const unsigned ALERT_FLAG_MSG = 0x01; static const Parameter ex_params[] = { - { "file", Parameter::PT_BOOL, nullptr, "stdout", + { "file", Parameter::PT_BOOL, nullptr, "false", "output to " F_NAME " instead of stdout" }, { "msg", Parameter::PT_BOOL, nullptr, "false", diff --git a/src/main/build.h b/src/main/build.h index 82a4dbefa..965491a71 100644 --- a/src/main/build.h +++ b/src/main/build.h @@ -7,5 +7,5 @@ // // //-----------------------------------------------// -#define BUILD "141" +#define BUILD "142" diff --git a/src/main/modules.cc b/src/main/modules.cc index 9cb63b4a0..958fe25b6 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -322,7 +322,7 @@ bool SearchEngineModule::set(const char*, Value& v, SnortConfig* sc) static const Parameter profile_rule_params[] = { { "count", Parameter::PT_INT, "-1:", "-1", - "print results to given level (-1 = all, 0 = off?)" }, + "print results to given level (-1 = all, 0 = off)" }, { "sort", Parameter::PT_ENUM, "checks | avg_ticks | total_ticks | matches | no_matches | " @@ -335,7 +335,7 @@ static const Parameter profile_rule_params[] = static const Parameter profile_module_params[] = { { "count", Parameter::PT_INT, "-1:", "-1", - "print results to given level (-1 = all, 0 = off?)" }, + "print results to given level (-1 = all, 0 = off)" }, { "sort", Parameter::PT_ENUM, "checks | avg_ticks | total_ticks", "avg_ticks", diff --git a/src/main/snort_module.cc b/src/main/snort_module.cc index 59a46615a..57962af10 100644 --- a/src/main/snort_module.cc +++ b/src/main/snort_module.cc @@ -191,7 +191,7 @@ static const Parameter s_params[] = { "-S", Parameter::PT_STRING, nullptr, nullptr, " set rules file variable n equal to value v" }, - { "-s", Parameter::PT_INT, "68:65535", nullptr, + { "-s", Parameter::PT_INT, "68:65535", "1514", " (same as --snaplen)" }, { "-T", Parameter::PT_IMPLIED, nullptr, nullptr, @@ -229,8 +229,9 @@ static const Parameter s_params[] = { "-y", Parameter::PT_IMPLIED, nullptr, nullptr, "include year in timestamp in the alert and log files" }, - { "-z", Parameter::PT_INT, "1:", nullptr, - " maximum number of packet threads (same as --max-packet-threads)" }, + { "-z", Parameter::PT_INT, "0:", "1", + " maximum number of packet threads (same as --max-packet-threads)\n" + " 0 gets the number of CPU cores reported by the system" }, { "--alert-before-pass", Parameter::PT_IMPLIED, nullptr, nullptr, "process alert, drop, sdrop, or reject before pass; " @@ -336,8 +337,9 @@ static const Parameter s_params[] = { "--markup", Parameter::PT_IMPLIED, nullptr, nullptr, "output help in asciidoc compatible format" }, - { "--max-packet-threads", Parameter::PT_INT, "0:", nullptr, - " configure maximum number of packet threads (same as -z)" }, + { "--max-packet-threads", Parameter::PT_INT, "0:", "1", + " configure maximum number of packet threads (same as -z)\n" + " 0 gets the number of CPU cores reported by the system" }, { "--nostamps", Parameter::PT_IMPLIED, nullptr, nullptr, "don't include timestamps in log file names" }, @@ -412,7 +414,7 @@ static const Parameter s_params[] = { "--skip", Parameter::PT_INT, "0:", nullptr, " skip 1st n packets", }, - { "--snaplen", Parameter::PT_INT, "68:65535", nullptr, + { "--snaplen", Parameter::PT_INT, "68:65535", "1514", " set snaplen of packet (same as -s)", }, { "--stdin-rules", Parameter::PT_IMPLIED, nullptr, nullptr, diff --git a/src/managers/module_manager.cc b/src/managers/module_manager.cc index c2517b462..6eb4e2561 100644 --- a/src/managers/module_manager.cc +++ b/src/managers/module_manager.cc @@ -57,6 +57,7 @@ struct ModHook typedef list ModuleList; static ModuleList s_modules; static unsigned s_errors = 0; + static string s_current; static string s_name; static string s_type; @@ -64,6 +65,18 @@ static string s_type; // for callbacks from Lua static SnortConfig* s_config = nullptr; +// forward decls +extern "C" +{ + bool open_table(const char*, int); + void close_table(const char*, int); + + bool set_bool(const char* fqn, bool val); + bool set_number(const char* fqn, double val); + bool set_string(const char* fqn, const char* val); + bool set_alias(const char* from, const char* to); +} + //------------------------------------------------------------------------- // ModHook foo //------------------------------------------------------------------------- @@ -301,7 +314,8 @@ static void dump_table(string& key, const char* pfx, const Parameter* p, bool li // set methods //------------------------------------------------------------------------- -static const Parameter* get_params(const string& sfx, const Parameter* p) +static const Parameter* get_params( + const string& sfx, const Parameter* p, int idx = 1) { size_t pos = sfx.find_first_of('.'); std::string new_fqn; @@ -329,9 +343,9 @@ static const Parameter* get_params(const string& sfx, const Parameter* p) p->type != Parameter::PT_LIST ) return p; - if (new_fqn.find_first_of('.') == std::string::npos) + if ( new_fqn.find_first_of('.') == std::string::npos ) { - if (p->type == Parameter::PT_LIST) + if ( idx && p->type == Parameter::PT_LIST ) { const Parameter* tmp_p = reinterpret_cast(p->range); @@ -345,7 +359,7 @@ static const Parameter* get_params(const string& sfx, const Parameter* p) } p = (const Parameter*)p->range; - return get_params(new_fqn, p); + return get_params(new_fqn, p, idx); } // FIXIT-M vars may have been defined on command line @@ -476,20 +490,146 @@ static bool set_value(const char* fqn, Value& v) } //------------------------------------------------------------------------- -// ffi methods +// defaults - set all parameter table defaults for each configured module +// but there are no internal default list or list items. since Lua calls +// open table for each explicitly configured table only, here is what we +// do: +// +// -- on open_table(), call Module::begin() for each module, list, and list +// item +// -- recursively set all defaults after calling Module::begin(), skipping +// lists and list items +// -- on close_table(), call Module::begin() for each module, list, and list +// item //------------------------------------------------------------------------- -extern "C" +static bool top_level(const char* s) +{ return !strchr(s, '.'); } + +static bool begin(Module* m, const Parameter* p, const char* s, int idx, int depth) { - bool open_table(const char*, int); - void close_table(const char*, int); + if ( !p ) + { + p = m->get_parameters(); + assert(p); + } - bool set_bool(const char* fqn, bool val); - bool set_number(const char* fqn, double val); - bool set_string(const char* fqn, const char* val); - bool set_alias(const char* from, const char* to); + // Module::begin() top-level, lists, and list items only + if ( top_level(s) or + (!idx and p->type == Parameter::PT_LIST) or + (idx and p->type != Parameter::PT_LIST) ) + { + //printf("begin %s %d\n", s, idx); + if ( !m->begin(s, idx, s_config) ) + return false; + } + // don't set list defaults + if ( m->is_list() or p->type == Parameter::PT_LIST ) + { + if ( !idx ) + return true; + } + + // set list item defaults only if explicitly configured + // (this is why it is done here and not in the loop below) + if ( p->type == Parameter::PT_LIST ) + { + const Parameter* t = + reinterpret_cast(p->range); + + return begin(m, t, s, idx, depth+1); + } + + // don't begin subtables again + if ( !top_level(s) && !depth ) + return true; + + while ( p->name ) + { + string fqn = s; + fqn += '.'; + fqn += p->name; + + switch ( p->type ) + { + // traverse subtables only to set defaults + case Parameter::PT_TABLE: + { + const Parameter* t = + reinterpret_cast(p->range); + + if ( !begin(m, t, fqn.c_str(), idx, depth+1) ) + return false; + } + break; + + // skip lists, they must be configured explicitly + case Parameter::PT_LIST: + case Parameter::PT_MAX: + break; + + case Parameter::PT_BOOL: + if ( p->deflt ) + { + bool b = p->get_bool(); + //printf("set default %s = %s\n", fqn.c_str(), p->deflt); + set_bool(fqn.c_str(), b); + } + break; + + case Parameter::PT_INT: + case Parameter::PT_PORT: + case Parameter::PT_REAL: + if ( p->deflt ) + { + double d = p->get_number(); + //printf("set default %s = %f\n", fqn.c_str(), d); + set_number(fqn.c_str(), d); + } + break; + + // everything else is a string of some sort + default: + if ( p->deflt ) + { + //printf("set default %s = %s\n", fqn.c_str(), p->deflt); + set_string(fqn.c_str(), p->deflt); + } + break; + } + ++p; + } + return true; } +// no need to recurse here; we only call Module::end() for +// top-level, lists, and list items +static bool end(Module* m, const Parameter* p, const char* s, int idx) +{ + bool top_param = !p; + + if ( !p ) + { + p = m->get_parameters(); + assert(p); + } + // same as begin() but we must include top_param to catch + // top-level lists + if ( top_level(s) or + (top_param and p->type != Parameter::PT_TABLE) or + (!idx and p->type == Parameter::PT_LIST) or + (idx and p->type != Parameter::PT_LIST) ) + { + //printf("end %s %d\n", s, idx); + return m->end(s, idx, s_config); + } + return true; +} + +//------------------------------------------------------------------------- +// ffi methods +//------------------------------------------------------------------------- + SO_PUBLIC bool set_alias(const char* from, const char* to) { s_name = from; @@ -499,6 +639,8 @@ SO_PUBLIC bool set_alias(const char* from, const char* to) SO_PUBLIC bool open_table(const char* s, int idx) { + //printf("open %s %d\n", s, idx); + const char* orig = s; string fqn = s; set_type(fqn); @@ -519,13 +661,13 @@ SO_PUBLIC bool open_table(const char* s, int idx) if ( snort_is_reloading() && h && h->api && h->api->type != PT_INSPECTOR ) return false; - //printf("open %s %d\n", s, idx); Module* m = h->mod; + const Parameter* p = nullptr; - if (strcmp(m->get_name(), s)) + if ( strcmp(m->get_name(), s) ) { std::string fqn = s; - const Parameter* const p = get_params(fqn, m->get_parameters()); + p = get_params(fqn, m->get_parameters(), idx); if ( !p ) { @@ -548,7 +690,7 @@ SO_PUBLIC bool open_table(const char* s, int idx) s_current = key; } - if ( !m->begin(s, idx, s_config) ) + if ( !begin(m, p, s, idx, 0) ) { ParseError("can't open %s", m->get_name()); return false; @@ -558,6 +700,8 @@ SO_PUBLIC bool open_table(const char* s, int idx) SO_PUBLIC void close_table(const char* s, int idx) { + //printf("close %s %d\n", s, idx); + string fqn = s; set_type(fqn); s = fqn.c_str(); @@ -565,11 +709,9 @@ SO_PUBLIC void close_table(const char* s, int idx) string key = fqn; set_top(key); - //printf("close %s %d\n", s, idx); - if ( ModHook* h = get_hook(key.c_str()) ) { - if ( !h->mod->end(s, idx, s_config) ) + if ( !end(h->mod, nullptr, s, idx) ) ParseError("can't close %s", h->mod->get_name()); else if ( !s_name.empty() ) diff --git a/src/network_inspectors/binder/bind_module.cc b/src/network_inspectors/binder/bind_module.cc index 87f19c5ba..b8d00bdd8 100644 --- a/src/network_inspectors/binder/bind_module.cc +++ b/src/network_inspectors/binder/bind_module.cc @@ -56,7 +56,7 @@ static const Parameter binder_when_params[] = { // FIXIT when.policy_id should be an arbitrary string auto converted // into index for binder matching and lookups - { "policy_id", Parameter::PT_INT, "0:", nullptr, + { "policy_id", Parameter::PT_INT, "0:", "0", "unique ID for selection of this config by external logic" }, { "ifaces", Parameter::PT_BIT_LIST, "255", nullptr, @@ -97,8 +97,8 @@ static const Parameter binder_use_params[] = { "type", Parameter::PT_STRING, nullptr, nullptr, "select module for binding" }, - { "name", Parameter::PT_STRING, nullptr, "defaults to type", - "symbol name" }, + { "name", Parameter::PT_STRING, nullptr, nullptr, + "symbol name (defaults to type)" }, { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; diff --git a/src/stream/base/stream_module.cc b/src/stream/base/stream_module.cc index d7844cd17..ab8105a22 100644 --- a/src/stream/base/stream_module.cc +++ b/src/stream/base/stream_module.cc @@ -43,7 +43,7 @@ static StreamModuleConfig stream_cfg = static const Parameter proto_params[] = { - { "memcap", Parameter::PT_INT, "0:", nullptr, + { "memcap", Parameter::PT_INT, "0:", "0", "maximum cache memory" }, { "idle_timeout", Parameter::PT_INT, "1:", "60",