]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1732 in SNORT/snort3 from ~RUCOMBS/snort3:rule_statez to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Mon, 9 Sep 2019 22:04:40 +0000 (18:04 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Mon, 9 Sep 2019 22:04:40 +0000 (18:04 -0400)
Squashed commit of the following:

commit 8f66afffc52f4eecc0436d23359f2eccd3ff18f2
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 4 17:53:18 2019 -0400

    doc: add bullets for $var parameter names and maxXX limits.

commit ff4bca6a07a6b5446332ce0d41272b9299f08998
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 4 16:59:12 2019 -0400

    rule_state: switch from regex parameter names to simpler parsing

    Performance when loading large rule sets (20K+ rules) with regex is unacceptable.
    Switch from regex to $var parameter names with name matching delegated to module.
    In this case, $gid_sid is used for rule_state["1:23456"] type configurations.  As
    you might have guessed, $ indicates parameters with variable names.

doc/params.txt
src/detection/rules.cc
src/framework/module.h
src/framework/parameter.h
src/main/modules.cc
src/managers/module_manager.cc

index 9fd4231c85a24b6be24decd75f2d8d07a1e36c4e..59110bfdd0561dc736c71376131cdcda4dfe5006 100644 (file)
@@ -32,6 +32,8 @@ information about the type and use of the parameter:
 * IPS rules may also have a wild card parameter, which is indicated by a
   *.  Used for unquoted, comma-separated lists such as service and metadata.
 * The snort module has command line options starting with a -.
+* $ denotes variable names, eg rule_state.$gid_sid which would be used
+  like rule_state["1:23456"] = { }.
 
 Some additional details to note:
 
@@ -47,4 +49,6 @@ Some additional details to note:
 * interval takes the form [operator]i, j<>k, or j<=>k where i,j,k are
   integers and operator is one of =, !, != (same as !), <, <=, >, >=.
   j<>k means j < int < k and j<=>k means j <= int <= k.
+* Ranges may use maxXX like { 1:max32 } since max32 is easier to read
+  than 4294967295.  To get the values of maxXX, use snort --help-limits.
 
index 58cb12ba304535000e4c122afc5a06f27057e374..94abe2e974b28a34e74a548823a995ee77263e24 100644 (file)
@@ -47,7 +47,7 @@ void RuleState::apply(SnortConfig* sc)
     OptTreeNode* otn = OtnLookup(sc->otn_map, gid, sid);
 
     if ( otn == nullptr )
-        ParseError("Rule state specified for invalid SID: %u GID: %u", sid, gid);
+        ParseError("Rule state specified for invalid rule %u:%u", gid, sid);
     else
     {
         if ( sc->global_rule_state )
index 61e883e1d3d8c981da30ebdf0b8f88d6122ccb3e..7c89d06b69a0106aaed0c23c772f6dbd2d2440d6 100644 (file)
@@ -92,6 +92,10 @@ public:
 
     virtual bool set(const char*, Value&, SnortConfig*);
 
+    // used to match parameters with $var names like <gid:sid> for rule_state
+    virtual bool matches(const char* /*param_name*/, std::string& /*lua_name*/)
+    { return false; }
+
     // ips events:
     virtual unsigned get_gid() const
     { return 0; }
index 2b0327801d10d6da7b18725a604ea451dd80f357..7779d7c5431c0bdd3bc087f27aff79a545e8bd86 100644 (file)
@@ -67,10 +67,6 @@ struct SO_PUBLIC Parameter
     const void* range;  // nullptr|const char*|RangeQuery*|const Parameter*
     const char* deflt;
     const char* help;
-    bool regex = false; // for name resolution
-
-    Parameter(const char* n, Type t, const void* r, const char* d, const char* h, bool re) :
-        name(n), type(t), range(r), deflt(d), help(h), regex(re) { }
 
     Parameter(const char* n, Type t, const void* r, const char* d, const char* h) :
         name(n), type(t), range(r), deflt(d), help(h) { }
index 420340c07bf8b525444d5f321718cca2f927f8ec..d449ed77c3e8d3b1067ba3435e6caf150416beff 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "modules.h"
 
-#include <regex>
 #include <sys/resource.h>
 
 #include "codecs/codec_module.h"
@@ -1841,11 +1840,10 @@ static const Parameter single_rule_state_params[] =
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
-static const char* rule_state_gid_sid_regex = "([0-9]+):([0-9]+)";
 static const Parameter rule_state_params[] =
 {
-    { rule_state_gid_sid_regex, Parameter::PT_LIST, single_rule_state_params, nullptr,
-      "defines rule state parameters for gid:sid", true },
+    { "$gid_sid", Parameter::PT_LIST, single_rule_state_params, nullptr,
+      "defines rule state parameters for gid:sid" },
 
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
@@ -1862,6 +1860,8 @@ public:
     bool begin(const char*, int, SnortConfig*) override;
     bool end(const char*, int, SnortConfig*) override;
 
+    bool matches(const char*, std::string&) override;
+
     Usage get_usage() const override
     { return DETECT; }
 
@@ -1871,21 +1871,30 @@ private:
     IpsPolicy::Enable enable;
 };
 
-bool RuleStateModule::set(const char* fqn, Value& v, SnortConfig*)
+bool RuleStateModule::matches(const char* param, std::string& name)
 {
-    static regex gid_sid(rule_state_gid_sid_regex);
+    if ( strcmp(param, "$gid_sid") )
+        return false;
+
+    std::stringstream ss(name);
+    char sep;
 
-    // the regex itself is passed as the fqn when declaring rule_state = { }
-    if ( strstr(fqn, rule_state_gid_sid_regex) )
+    ss >> gid >> sep >> sid;
+
+    if ( gid and sid and sep == ':' )
         return true;
 
-    cmatch match;
+    return false;
+}
 
-    if ( regex_search(fqn, match, gid_sid) )
-    {
-        gid = strtoul(match[1].str().c_str(), nullptr, 10);
-        sid = strtoul(match[2].str().c_str(), nullptr, 10);
+bool RuleStateModule::set(const char* fqn, Value& v, SnortConfig*)
+{
+    // the name itself is passed as the fqn when declaring rule_state = { }
+    if ( !strcmp(fqn, "$gid_sid") )
+        return true;
 
+    if ( gid and sid )
+    {
         if ( v.is("action") )
             action = IpsPolicy::Action(v.get_uint8());
 
@@ -1911,9 +1920,9 @@ bool RuleStateModule::begin(const char*, int, SnortConfig*)
 
 bool RuleStateModule::end(const char*, int, SnortConfig* sc)
 {
-    if ( gid )
+    if ( gid and sid )
         sc->rule_states.emplace_back(new RuleState(gid, sid, action, enable));
-    gid = 0;
+    gid = sid = 0;
     return true;
 }
 
index dc37b2a9455fcb636878770e2e3ceab13cd28b8c..cffc586c392a096971f6b2d5b7eba4981ee1cb1e 100644 (file)
@@ -29,7 +29,6 @@
 #include <cassert>
 #include <iostream>
 #include <mutex>
-#include <regex>
 #include <string>
 
 #include "framework/base_api.h"
@@ -345,7 +344,7 @@ static void dump_table(string& key, const char* pfx, const Parameter* p, bool li
 //-------------------------------------------------------------------------
 
 static const Parameter* get_params(
-    const string& sfx, const Parameter* p, int idx = 1)
+    const string& sfx, Module* m, const Parameter* p, int idx = 1)
 {
     size_t pos = sfx.find_first_of('.');
     std::string new_fqn;
@@ -363,9 +362,10 @@ static const Parameter* get_params(
     }
 
     string name = new_fqn.substr(0, new_fqn.find_first_of('.'));
+
     while ( p->name )
     {
-        if ( p->regex && regex_match(name, regex(p->name)) )
+        if ( *p->name == '$' and m->matches(p->name, name) )
             break;
 
         else if ( name == p->name )
@@ -396,7 +396,7 @@ static const Parameter* get_params(
     }
 
     p = (const Parameter*)p->range;
-    return get_params(new_fqn, p, idx);
+    return get_params(new_fqn, m, p, idx);
 }
 
 // FIXIT-M vars may have been defined on command line. that mechanism will
@@ -508,10 +508,10 @@ static bool set_value(const char* fqn, Value& v)
 
     // now we must traverse the mod params to get the leaf
     string s = fqn;
-    const Parameter* p = get_params(s, mod->get_parameters());
+    const Parameter* p = get_params(s, mod, mod->get_parameters());
 
     if ( !p )
-        p = get_params(s, mod->get_default_parameters());
+        p = get_params(s, mod, mod->get_default_parameters());
 
     if ( !p )
     {
@@ -729,10 +729,10 @@ SO_PUBLIC bool open_table(const char* s, int idx)
     if ( strcmp(m->get_name(), s) )
     {
         std::string sfqn = s;
-        p = get_params(sfqn, m->get_parameters(), idx);
+        p = get_params(sfqn, m, m->get_parameters(), idx);
 
         if ( !p )
-            p = get_params(sfqn, m->get_default_parameters(), idx);
+            p = get_params(sfqn, m, m->get_default_parameters(), idx);
 
         if ( !p )
         {