]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #184 in SNORT/snort3 from crc/fp4 to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 10 Dec 2015 12:39:48 +0000 (07:39 -0500)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 10 Dec 2015 12:39:48 +0000 (07:39 -0500)
Squashed commit of the following:

commit c8f7d4651a71920da0818c914ee8e167b8b058fc
Author: Russ Combs <rucombs@cisco.com>
Date:   Wed Dec 9 08:34:35 2015 -0500

    regex fast pattern support
    merge rule option types for content, pcre, and regex

27 files changed:
extra/src/search_engines/lowmem.cc
src/detection/detection_options.cc
src/detection/fp_create.cc
src/detection/fp_detect.cc
src/detection/pattern_match_data.h
src/detection/rule_option_types.h
src/framework/mpse.h
src/ips_options/ips_content.cc
src/ips_options/ips_pcre.cc
src/ips_options/ips_regex.cc
src/parser/parse_stream.cc
src/search_engines/CMakeLists.txt
src/search_engines/Makefile.am
src/search_engines/ac_banded.cc
src/search_engines/ac_bnfa.cc
src/search_engines/ac_full.cc
src/search_engines/ac_sparse.cc
src/search_engines/ac_sparse_bands.cc
src/search_engines/ac_std.cc
src/search_engines/acsmx2_api.cc
src/search_engines/hyperscan.cc
src/search_engines/intel_cpm.cc
src/search_engines/search_tool.cc
src/search_engines/test/hyperscan_test.cc
src/stream/tcp/test/CMakeLists.txt
src/utils/boyer_moore.cc
src/utils/boyer_moore.h

index 7bcb9c1749dd0dc43c49413e0e1993d7a4ae2deb..fdd29c62a03c74b136cc2def496c396354319f72 100644 (file)
@@ -58,9 +58,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return KTrieAddPattern(obj, P, m, noCase, negative, user);
+        return KTrieAddPattern(obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index fa73bfa6859cd73527de72da34b2a4a6e5304a9b..3b83ceb161c4e359f3cf3f99ed9ef4a63a13c39e 100644 (file)
@@ -319,7 +319,6 @@ static const char* const option_type_str[] =
     "RULE_OPTION_TYPE_LEAF_NODE",
     "RULE_OPTION_TYPE_CONTENT",
     "RULE_OPTION_TYPE_FLOWBIT",
-    "RULE_OPTION_TYPE_PCRE",
     "RULE_OPTION_TYPE_OTHER"
 };
 
@@ -340,7 +339,6 @@ void print_option_tree(detection_option_tree_node_t* node, int level)
             print_option_tree(node->children[i], level+1);
         );
 }
-
 #endif
 
 int add_detection_option_tree(
@@ -627,21 +625,21 @@ int detection_option_node_evaluate(
                     {
                         if ( child_state->result == DETECTION_OPTION_NO_MATCH )
                         {
-                            if ( (child_node->option_type == RULE_OPTION_TYPE_CONTENT ||
-                                  child_node->option_type == RULE_OPTION_TYPE_PCRE) &&
-                                 !child_node->is_relative )
+                            if ( !child_node->is_relative )
                             {
-                                // If it's a non-relative content or pcre, no reason
-                                // to check again.  Only increment result once.
-                                // Should hit this condition on first loop iteration.
-                                if ( loop_count == 1 )
-                                    ++result;
+                                if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT )
+                                {
+                                    // If it's a non-relative content or pcre, no reason
+                                    // to check again.  Only increment result once.
+                                    // Should hit this condition on first loop iteration.
+                                    if ( loop_count == 1 )
+                                        ++result;
 
-                                continue;
+                                    continue;
+                                }
                             }
 
-                            else if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT &&
-                                      child_node->is_relative )
+                            else if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT )
                             {
                                 // Check for an unbounded relative search.  If this
                                 // failed before, it's going to fail again so don't
index 1d2972d00ea29eba749e9456d345c06c859b832a..cb3e30bae2cee3bcb2ac1d7f44bee22cff1e9f17 100644 (file)
@@ -70,7 +70,7 @@ static unsigned mpse_count = 0;
 static void fpDeletePMX(void* data);
 
 static int fpGetFinalPattern(
-    FastPatternConfig*, PatternMatchData*, char** ret_pattern, int* ret_bytes);
+    FastPatternConfig*, PatternMatchData*, const char*& ret_pattern, int& ret_bytes);
 
 static void PrintFastPatternInfo(
     OptTreeNode*, PatternMatchData*, const char* pattern, int pattern_length);
@@ -345,14 +345,14 @@ static int pmx_create_tree(SnortConfig* sc, void* id, void** existing_tree)
 }
 
 /* FLP_Trim
-  *
   * Trim zero byte prefixes, this increases uniqueness
+  * will not alter regex since they can't contain bald \0
   *
   * returns
   *   length - of trimmed pattern
   *   buff - ptr to new beggining of trimmed buffer
   */
-static int FLP_Trim(char* p, int plen, char** buff)
+static int FLP_Trim(const char* p, int plen, const char** buff)
 {
     int i;
     int size = 0;
@@ -561,7 +561,7 @@ static int fpFinishPortGroupRule(
     SnortConfig* sc, PortGroup* pg,
     OptTreeNode* otn, PatternMatchData* pmd, FastPatternConfig* fp)
 {
-    char* pattern;
+    const char* pattern;
     int pattern_length;
 
     if ( !pmd )
@@ -577,7 +577,7 @@ static int fpFinishPortGroupRule(
         else
             pg->add_rule();
 
-        if (fpGetFinalPattern(fp, pmd, &pattern, &pattern_length) == -1)
+        if (fpGetFinalPattern(fp, pmd, pattern, pattern_length) == -1)
             return -1;
 
         /* create pmx */
@@ -610,8 +610,8 @@ static int fpFinishPortGroupRule(
                 pg->mpse[pmd->pm_type]->set_opt(1);
         }
 
-        pg->mpse[pmd->pm_type]->add_pattern(
-            sc, (uint8_t*)pattern, pattern_length, pmd->no_case, pmd->negated, pmx);
+        Mpse::PatternDescriptor desc(pmd->no_case, pmd->negated, pmd->literal);
+        pg->mpse[pmd->pm_type]->add_pattern(sc, (uint8_t*)pattern, pattern_length, desc, pmx);
     }
 
     return 0;
@@ -933,32 +933,34 @@ static void fpFreeRuleMaps(SnortConfig* sc)
 
 static int fpGetFinalPattern(
     FastPatternConfig* fp, PatternMatchData* pmd,
-    char** ret_pattern, int* ret_bytes)
+    const char*& ret_pattern, int& ret_bytes)
 {
-    char* pattern;
-    int bytes;
-
-    if ((fp == NULL) || (pmd == NULL)
-        || (ret_pattern == NULL) || (ret_bytes == NULL))
+    if ( !fp or !pmd )
     {
         return -1;
     }
 
-    pattern = pmd->pattern_buf;
-    bytes = pmd->pattern_size;
+    const char* pattern = pmd->pattern_buf;
+    int bytes = pmd->pattern_size;
 
-    /* Don't mess with fast pattern only contents - they should be inserted
-     * into the pattern matcher as is since the content won't be evaluated
-     * as a rule option.
-     * Don't mess with negated contents since truncating them could
-     * inadvertantly disable evaluation of a rule - the shorter pattern
-     * may be found, while the unaltered pattern may not be found,
-     * disabling inspection of a rule we should inspect */
-    if (pmd->fp_only > 0 || pmd->negated)
-    {
-        *ret_pattern = pattern;
-        *ret_bytes = bytes;
+    // Don't mess with:
+    //
+    // 1. fast pattern only contents - they should be inserted into the
+    // pattern matcher as is since the content won't be evaluated as a rule
+    // option.
+    //
+    // 2. negated contents since truncating them could inadvertantly
+    // disable evaluation of a rule - the shorter pattern may be found,
+    // while the unaltered pattern may not be found, disabling inspection
+    // of a rule we should inspect.
+    //
+    // 3. non-literals like regex - truncation could invalidate the
+    // expression.
 
+    if ( pmd->fp_only > 0 or pmd->negated or !pmd->literal )
+    {
+        ret_pattern = pattern;
+        ret_bytes = bytes;
         return 0;
     }
 
@@ -1003,8 +1005,8 @@ static int fpGetFinalPattern(
         }
     }
 
-    *ret_pattern = pattern;
-    *ret_bytes = fp->set_max(bytes);
+    ret_pattern = pattern;
+    ret_bytes = fp->set_max(bytes);
 
     return 0;
 }
index 8cdbf01dd82d6e2908da5317f397ae2122e20002..a6a3625c3a48244765847326a5137bfe567e6d08 100644 (file)
@@ -466,10 +466,6 @@ static int rule_tree_match(
     PMX* pmx = (PMX*)user;
     OTNX_MATCH_DATA* pomd = (OTNX_MATCH_DATA*)context;
 
-    //unsigned sz = pmx->pmd->pattern_size;
-    //assert(sz <= (unsigned)index and (unsigned)index <= pomd->size);
-    //assert(!strncasecmp((char*)pmx->pmd->pattern_buf, (char*)pomd->data+index-sz, sz));
-
     detection_option_tree_root_t* root = (detection_option_tree_root_t*)tree;
     detection_option_eval_data_t eval_data;
     NCListNode* ncl;
index 9c52bd6679dbeb1b583c4595e950575f166e063a..8959fb4da1935288c69527aee966e208317e48f7 100644 (file)
@@ -37,26 +37,28 @@ struct PmdLastCheck
 struct PatternMatchData
 {
     // used by both
-    uint8_t negated;        /* search for "not this pattern" */
-    uint8_t fp;             /* For fast_pattern arguments */
-    uint8_t no_case;        /* Toggle case sensitivity */
-    uint8_t relative;       /* do relative pattern searching */
+    bool negated;        // search for "not this pattern"
+    bool fp;             // For fast_pattern arguments
+    bool no_case;        // Toggle case sensitivity
+    bool relative;       // do relative pattern searching
 
     uint16_t fp_offset;
     uint16_t fp_length;
 
-    int offset;             /* pattern search start offset */
-    int depth;              /* pattern search depth */
+    int offset;              // pattern search start offset
+    int depth;               // pattern search depth
 
-    unsigned pattern_size;  /* size of app layer pattern */
-    char* pattern_buf;      /* app layer pattern to match on */
+    unsigned pattern_size;   // size of app layer pattern
+    const char* pattern_buf; // app layer pattern to match on
+
+    bool literal;            // set to plain contents
 
     // not used by ips_content
     int8_t fp_only;
     uint8_t pm_type;
 
-    unsigned replace_size;  /* size of app layer replace pattern */
-    char* replace_buf;      /* app layer pattern to replace with */
+    unsigned replace_size;   // size of app layer replace pattern
+    const char* replace_buf; // app layer pattern to replace with
 
     // FIXIT-L wasting some memory here:
     // - this is not used by content option logic directly
index a8da9894fd6d2f5c46d7dd492d11e7519638d7f5..c9806b9a02a0b39a7435e2b44e8e758d8dbce06b 100644 (file)
@@ -31,7 +31,6 @@ enum option_type_t
     RULE_OPTION_TYPE_LEAF_NODE,
     RULE_OPTION_TYPE_CONTENT,
     RULE_OPTION_TYPE_FLOWBIT,
-    RULE_OPTION_TYPE_PCRE,  // pcre and regex
     RULE_OPTION_TYPE_OTHER
 };
 
index fb735f742d6a9d5538a3e152909ce6a557eba916..64dd16d3906d16bce5128a807adac887f6f11e3a 100644 (file)
@@ -51,9 +51,19 @@ public:
 public:
     virtual ~Mpse() { }
 
+    struct PatternDescriptor
+    {
+        bool no_case;
+        bool negated;
+        bool literal;
+
+        PatternDescriptor(bool noc = false, bool neg = false, bool lit = false)
+        { no_case = noc; negated = neg; literal = lit; }
+    };
+
     virtual int add_pattern(
         SnortConfig* sc, const uint8_t* pat, unsigned len,
-        bool noCase, bool negate, void* user) = 0;
+        const PatternDescriptor&, void* user) = 0;
 
     virtual int prep_patterns(SnortConfig*) = 0;
 
index 300b87ec38777757102f2560424e8f30a785c3d5..1beda0c08455e6f0578dc5459e612e3175b15c49 100644 (file)
@@ -161,7 +161,7 @@ ContentOption::~ContentOption()
         return;
 
     if ( cd->pmd.pattern_buf )
-        free(cd->pmd.pattern_buf);
+        free((char*)cd->pmd.pattern_buf);
 
     if ( cd->pmd.last_check )
         free(cd->pmd.last_check);
@@ -439,10 +439,12 @@ static void parse_content(ContentData* cd, const char* rule)
     unsigned dummy_size = buf.size();
 
     cd->pmd.pattern_buf = (char*)SnortAlloc(dummy_size+1);
-    memcpy(cd->pmd.pattern_buf, tmp_buf, dummy_size);
+    memcpy((char*)cd->pmd.pattern_buf, tmp_buf, dummy_size);
 
     cd->pmd.pattern_size = dummy_size;
     cd->pmd.negated = negated;
+    cd->pmd.literal = true;
+
     cd->set_max_jump_size();
 }
 
@@ -685,8 +687,10 @@ bool ContentModule::end(const char*, int, SnortConfig*)
     }
     if ( cd->pmd.no_case )
     {
+        char* s = (char*)cd->pmd.pattern_buf;
+
         for ( unsigned i = 0; i < cd->pmd.pattern_size; i++ )
-            cd->pmd.pattern_buf[i] = toupper(cd->pmd.pattern_buf[i]);
+            s[i] = toupper(cd->pmd.pattern_buf[i]);
     }
     cd->setup_bm();
     return true;
index b6b09f81ee6faae26d3ad2c989739262899cdd4e..b93bff66759ea7397513bca4541968c69c331065 100644 (file)
@@ -352,7 +352,7 @@ syntax:
     if ( !pcre_data->expression )
         pcre_data->expression = SnortStrdup("");
 
-    ParseError("unable to parse pcre regex %s", data);
+    ParseError("unable to parse pcre %s", data);
 }
 
 /**
@@ -454,7 +454,7 @@ class PcreOption : public IpsOption
 {
 public:
     PcreOption(PcreData* c) :
-        IpsOption(s_name, RULE_OPTION_TYPE_PCRE)
+        IpsOption(s_name, RULE_OPTION_TYPE_CONTENT)
     { config = c; }
 
     ~PcreOption();
@@ -659,14 +659,14 @@ void pcre_cleanup(SnortConfig* sc)
 
 static const Parameter s_params[] =
 {
-    { "~regex", Parameter::PT_STRING, nullptr, nullptr,
+    { "~re", Parameter::PT_STRING, nullptr, nullptr,
       "Snort regular expression" },
 
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
 #define s_help \
-    "rule option for matching payload data with regex"
+    "rule option for matching payload data with pcre"
 
 class PcreModule : public Module
 {
@@ -704,7 +704,7 @@ bool PcreModule::begin(const char*, int, SnortConfig*)
 
 bool PcreModule::set(const char*, Value& v, SnortConfig*)
 {
-    if ( v.is("~regex") )
+    if ( v.is("~re") )
         pcre_parse(v.get_string(), data);
 
     else
index 0de6aebbabb94859ec8bab44a910dd8a2963a790..7407129f27672ecaa9cec939d14719dd999fc4f9 100644 (file)
@@ -19,6 +19,8 @@
 // ips_regex.cc author Russ Combs <rucombs@cisco.com>
 // FIXIT-H add ! and anchor support like pcre and update retry
 
+#include <string.h>
+
 #include <assert.h>
 #include <string>
 
@@ -29,6 +31,7 @@
 #include "framework/ips_option.h"
 #include "framework/module.h"
 #include "detection/detection_defines.h"
+#include "detection/pattern_match_data.h"
 #include "hash/sfhashfcn.h"
 #include "main/snort_config.h"
 #include "main/thread.h"
@@ -42,6 +45,7 @@
 
 struct RegexConfig
 {
+    PatternMatchData pmd;
     std::string re;
     hs_database_t* db;
     unsigned flags;
@@ -52,10 +56,10 @@ struct RegexConfig
 
     void reset()
     {
+        memset(&pmd, 0, sizeof(pmd));
         re.clear();
         db = nullptr;
         flags = 0;
-        relative = false;
     }
 };
 
@@ -90,16 +94,21 @@ public:
     { return CAT_ADJUST; }
 
     bool is_relative() override
-    { return config.relative; }
+    { return config.pmd.relative; }
 
-    int eval(Cursor&, Packet*) override;
     bool retry() override;
 
+    PatternMatchData* get_pattern() override
+    { return &config.pmd; }
+
+    int eval(Cursor&, Packet*) override;
+
 private:
     RegexConfig config;
 };
 
-RegexOption::RegexOption(const RegexConfig& c) : IpsOption(s_name, RULE_OPTION_TYPE_PCRE)
+RegexOption::RegexOption(const RegexConfig& c) :
+    IpsOption(s_name, RULE_OPTION_TYPE_CONTENT)
 {
     config = c;
 
@@ -109,6 +118,10 @@ RegexOption::RegexOption(const RegexConfig& c) : IpsOption(s_name, RULE_OPTION_T
         //ParseError("can't initialize regex for '%s' (%d) %p",
         //    config.re.c_str(), err, s_scratch);
     }
+    config.pmd.pattern_buf = config.re.c_str();
+    config.pmd.pattern_size = config.re.size();
+    config.pmd.fp_length = config.pmd.pattern_size;
+    config.pmd.fp_offset = 0;
 }
 
 RegexOption::~RegexOption()
@@ -119,7 +132,7 @@ RegexOption::~RegexOption()
 
 uint32_t RegexOption::hash() const
 {
-    uint32_t a = config.flags, b = config.relative, c = 0;
+    uint32_t a = config.flags, b = config.pmd.relative, c = 0;
     mix_str(a, b, c, config.re.c_str());
     mix_str(a, b, c, get_name());
     finalize(a, b, c);
@@ -135,7 +148,7 @@ bool RegexOption::operator==(const IpsOption& ips) const
 
     if ( config.re == rhs.config.re and 
          config.flags == rhs.config.flags and
-         config.relative == rhs.config.relative )
+         config.pmd.relative == rhs.config.pmd.relative )
         return true;
 
     return false;
@@ -190,7 +203,7 @@ bool RegexOption::retry()
 
 static const Parameter s_params[] =
 {
-    { "~", Parameter::PT_STRING, nullptr, nullptr,
+    { "~re", Parameter::PT_STRING, nullptr, nullptr,
       "hyperscan regular expression" },
 
     { "nocase", Parameter::PT_IMPLIED, nullptr, nullptr,
@@ -245,7 +258,7 @@ bool RegexModule::begin(const char*, int, SnortConfig*)
 
 bool RegexModule::set(const char*, Value& v, SnortConfig*)
 {
-    if ( v.is("~") )
+    if ( v.is("~re") )
     {
         config.re = v.get_string();
         // remove quotes
@@ -263,7 +276,7 @@ bool RegexModule::set(const char*, Value& v, SnortConfig*)
         config.flags |= HS_FLAG_MULTILINE;
 
     else if ( v.is("relative") )
-        config.relative = true;
+        config.pmd.relative = true;
 
     else
         return false;
index 71ba4991d971c247fc5c60329cd4ab95b0057f8d..13c41e075936ec8bd6e0a9726afa34535e3a6407 100644 (file)
@@ -83,7 +83,7 @@ static uint8_t to_hex(char c)
 }
 
 static TokenType get_token(
-    istream& is, string& s, const char* punct, bool esc)
+    istream& is, string& s, const char* punct, int esc)
 {
     static int prev = EOF;
     int c, list = 0, state = 0;
@@ -205,7 +205,7 @@ static TokenType get_token(
                 return TT_STRING;
             }
             else if ( c == '\\' )
-                state = esc ? 4 : 16;
+                state = (esc > 0) ? 4 : 16;
             else if ( c == '\n' )
                 ParseWarning(WARN_RULES, "line break in string on line %d\n", lines-1);
             else
@@ -605,6 +605,20 @@ static bool exec(
     return false;
 }
 
+// FIXIT-L this should not be by name
+// probably should remove content escaping except for \" so
+// that individual rule options can do whatever
+static int get_escape(const string& s)
+{
+    if ( s == "pcre" )
+        return 0;  // no escape, option goes to ;
+
+    else if ( s == "regex" )
+        return -1; // no escape, option goes to "
+
+    return 1;      // escape, option goes to "
+}
+
 // parse_body() is called at the end of a stub rule to parse the detection
 // options in an so rule.  similar to parse_stream() except we start in a
 // different state.
@@ -614,7 +628,7 @@ static void parse_body(const char* extra, RuleParseState& rps, struct SnortConfi
 
     string tok;
     TokenType type;
-    bool esc = true;
+    int esc = 1;
 
     int num = 8;
     const char* punct = "(:,;)";
@@ -627,7 +641,7 @@ static void parse_body(const char* extra, RuleParseState& rps, struct SnortConfi
         exec(s->action, tok, rps, sc);
 
         num = s->next;
-        esc = (rps.key != "pcre");
+        esc = get_escape(rps.key);
 
         if ( s->punct )
             punct = s->punct;
@@ -638,7 +652,7 @@ void parse_stream(istream& is, struct SnortConfig* sc)
 {
     string tok;
     TokenType type;
-    bool esc = true;
+    int esc = 1;
 
     int num = 0;
     const char* punct = fsm[0].punct;
@@ -658,7 +672,7 @@ void parse_stream(istream& is, struct SnortConfig* sc)
             break;
 
         num = s->next;
-        esc = (rps.key != "pcre");
+        esc = get_escape(rps.key);
 
         if ( s->punct )
             punct = s->punct;
index 1d81950476bffb94aa3d8de88284e9a3a248146e..450f8601746f5180dc82994b52c38c502c5b0ca3 100644 (file)
@@ -41,33 +41,31 @@ if ( HAVE_HYPERSCAN )
     )
 endif ()
 
+# FIXIT ideally don't include pat_stats.cc separately
+
 set (SEARCH_ENGINE_SOURCES
+    pat_stats.cc
     search_engines.cc
     search_engines.h
     search_tool.cc
     search_tool.h
     ${BNFA_SOURCES}
+    ${HYPER_SOURCES}
 )
 
-# FIXIT ideally don't include pat_stats.cc separately
-
 if ( STATIC_SEARCH_ENGINES )
     add_library(search_engines STATIC
         ${ACSMX_SOURCES}
         ${ACSMX2_SOURCES}
         ${INTEL_SOURCES}
-        ${HYPER_SOURCES}
         ${SEARCH_ENGINE_SOURCES}
         ${SEARCH_ENGINE_INCLUDES}
-        pat_stats.cc
     )
 
 else ( STATIC_SEARCH_ENGINES)
     add_library(search_engines STATIC
         ${SEARCH_ENGINE_SOURCES}
         ${SEARCH_ENGINE_INCLUDES}
-        ${BNFA_SOURCES}
-        pat_stats.cc
     )
 
     add_shared_library(acsmx search_engines ${ACSMX_SOURCES} pat_stats.cc)
index 71d5fa3c782ee174ca9655f84b980a86ae7b58cc..56e679ea552f9acfb16cf8dbec703deb25a06606 100644 (file)
@@ -41,8 +41,7 @@ endif
 plugin_list = \
 $(acsmx_sources) \
 $(acsmx2_sources) \
-$(intel_sources) \
-$(hyper_sources)
+$(intel_sources)
 
 libsearch_engines_a_SOURCES = \
 search_engines.cc \
@@ -50,7 +49,8 @@ search_engines.h \
 search_tool.cc \
 search_tool.h \
 pat_stats.cc \
-$(bnfa_sources)
+$(bnfa_sources) \
+$(hyper_sources)
 
 # FIXIT ideally don't include pat_stats.cc separately
 
index 5973c582215433e816da5aa0cceeb50b6cb96d2f..e718dc9d3731f0ddf95022c8b2691abc017188ac 100644 (file)
@@ -53,9 +53,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return acsmAddPattern2(obj, P, m, noCase, negative, user);
+        return acsmAddPattern2(obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index 57b0717e8d8273a0ae302dc366f4bce4be443b88..a196c440984139ed69be5c0ee7012c19cde95c7a 100644 (file)
@@ -66,9 +66,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return bnfaAddPattern(obj, P, m, noCase, negative, user);
+        return bnfaAddPattern(obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index 585c54921bb872162d5ba4ebd2a635325d3b36bd..69bc011ac6c7337c9cb539e793be2e59c84e8f4e 100644 (file)
@@ -58,9 +58,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return acsmAddPattern2(obj, P, m, noCase, negative, user);
+        return acsmAddPattern2(obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index a7af7f7b24a100554f7834e7b7eacef3c422992e..9c8b160a619ab2e869674fe64ec137a657954356 100644 (file)
@@ -49,9 +49,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return acsmAddPattern2(obj, P, m, noCase, negative, user);
+        return acsmAddPattern2(obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index 24e397e7f0cd629264948efe060c555da16728e7..a9595c6ef2291115dff1bb7123b86fefd83cea5b 100644 (file)
@@ -52,9 +52,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return acsmAddPattern2(obj, P, m, noCase, negative, user);
+        return acsmAddPattern2(obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index 2b58f389abc850555bb153b339c28ef4e4f5c207..b6e70178d2624562bf80c34a225bffdbcfd8d4c2 100644 (file)
@@ -53,9 +53,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return acsmAddPattern(obj, P, m, noCase, negative, user);
+        return acsmAddPattern(obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index e3f99ec27e92bf495c28e54a00d996bf28519b2d..3cf7f5728786ce36f390f5b769d1ad8e84c3383e 100644 (file)
 #include "framework/mpse.h"
 
 #ifdef BUILDING_SO
+extern const BaseApi* se_ac_banded;
+extern const BaseApi* se_ac_full;
+extern const BaseApi* se_ac_sparse;
+extern const BaseApi* se_ac_sparse_bands;
+
 SO_PUBLIC const BaseApi* snort_plugins[] =
 {
     se_ac_banded,
     se_ac_full,
-    se_ac_full_q,
     se_ac_sparse,
     se_ac_sparse_bands,
     nullptr
index 00b2da373e904c1d2b3d44cf8080c5a087bd9088..399c996c2391398830c262f6b89c49e895b1f162 100644 (file)
@@ -44,37 +44,43 @@ struct Pattern
     void* user_tree;
     void* user_list;
 
-    Pattern(const uint8_t* s, unsigned n, bool bc, bool bn, void* u)
-    {
-        // FIXIT-H only escape content patterns, not regex patterns
-        escape(s, n);
-        len = n;
-        no_case = bc;
-        negate = bn;
-        user = u;
-        user_tree = user_list = nullptr;
-    }
-    void escape(const uint8_t* s, unsigned n)
+    Pattern(const uint8_t*, unsigned, const Mpse::PatternDescriptor&, void*);
+    void escape(const uint8_t*, unsigned, bool);
+};
+
+Pattern::Pattern(
+    const uint8_t* s, unsigned n, const Mpse::PatternDescriptor& d, void* u)
+{
+    escape(s, n, d.literal);
+
+    len = n;
+    no_case = d.no_case;
+    negate = d.negated;
+    user = u;
+    user_tree = user_list = nullptr;
+}
+
+void Pattern::escape(const uint8_t* s, unsigned n, bool literal)
+{
+    for ( unsigned i = 0; i < n; ++i )
     {
-        for ( unsigned i = 0; i < n; ++i )
+        if ( !isprint(s[i]) )
         {
-            if ( !isprint(s[i]) )
-            {
-                char hex[5];
-                snprintf(hex, sizeof(hex), "\\x%02X", s[i]);
-                pat += hex;
-            }
-            else
-            {
-                const char* special = ".^$*+?()[]{}\\|";
+            char hex[5];
+            snprintf(hex, sizeof(hex), "\\x%02X", s[i]);
+            pat += hex;
+        }
+        else
+        {
+            const char* special = ".^$*+?()[]{}\\|";
+
+            if ( literal and strchr(special, s[i]) )
+                pat += '\\';
 
-                if ( strchr(special, s[i]) )
-                    pat += '\\';
-                pat += s[i];
-            }
+            pat += s[i];
         }
     }
-};
+}
 
 typedef std::vector<Pattern> PatternVector;
 
@@ -108,9 +114,9 @@ public:
 
     int add_pattern(
         SnortConfig*, const uint8_t* pat, unsigned len,
-        bool no_case, bool negate, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        Pattern p(pat, len, no_case, negate, user);
+        Pattern p(pat, len, desc, user);
         pvector.push_back(p);
         ++patterns;
         return 0;
@@ -342,13 +348,13 @@ static const MpseApi hs_api =
     hs_print,
 };
 
-#ifdef BUILDING_SO
-SO_PUBLIC const BaseApi* snort_plugins[] =
-{
-    &hs_api.base,
-    nullptr
-};
-#else
+//#ifdef BUILDING_SO
+//SO_PUBLIC const BaseApi* snort_plugins[] =
+//{
+//    &hs_api.base,
+//    nullptr
+//};
+//#else
 const BaseApi* se_hyperscan = &hs_api.base;
-#endif
+//#endif
 
index eefe000b46598bc374bb9f23e7e762f8ed11b3be..09bc9726b88581ed9b861540bbe4167af9099383 100644 (file)
@@ -55,9 +55,9 @@ public:
 
     int add_pattern(
         SnortConfig* sc, const uint8_t* P, unsigned m,
-        bool noCase, bool negative, void* user) override
+        const PatternDescriptor& desc, void* user) override
     {
-        return IntelPmAddPattern(sc, obj, P, m, noCase, negative, user);
+        return IntelPmAddPattern(sc, obj, P, m, desc.no_case, desc.negated, user);
     }
 
     int prep_patterns(SnortConfig* sc) override
index cd04e50ef451d59bf575101d7c5d6bb61e97e01b..f2b493f9b06046eafe6912a0e2865e803ee8491f 100644 (file)
@@ -45,8 +45,10 @@ void SearchTool::add(const char* pat, unsigned len, int id, bool no_case)
 
 void SearchTool::add(const uint8_t* pat, unsigned len, int id, bool no_case)
 {
+    Mpse::PatternDescriptor desc(no_case);
+
     if ( mpse )
-        mpse->add_pattern(nullptr,  pat, len, no_case, false, (void*)(long)id);
+        mpse->add_pattern(nullptr,  pat, len, desc, (void*)(long)id);
 
     if ( len > max_len )
         max_len = len;
index fe9a4dd9dbf575026bf1afa38fbfbe312e4e2092..56b374b7e828a58f0d478ecf5b9163a2fdeba553 100644 (file)
@@ -166,7 +166,9 @@ TEST(mpse_hs_match, empty)
 
 TEST(mpse_hs_match, single)
 {
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, false, false, s_user) == 0);
+    Mpse::PatternDescriptor desc;
+
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, desc, s_user) == 0);
     CHECK(hs->prep_patterns(snort_conf) == 0);
     CHECK(hs->get_pattern_count() == 1);
 
@@ -179,9 +181,11 @@ TEST(mpse_hs_match, single)
 
 TEST(mpse_hs_match, other)
 {
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, false, true, s_user) == 0);
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"\rbar\n", 3, false, true, s_user) == 0);
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"(baz)", 3, false, true, s_user) == 0);
+    Mpse::PatternDescriptor desc(false, true, false);
+
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, desc, s_user) == 0);
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"\rbar\n", 3, desc, s_user) == 0);
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"(baz)", 3, desc, s_user) == 0);
 
     CHECK(hs->prep_patterns(snort_conf) == 0);
     CHECK(hs->get_pattern_count() == 3);
@@ -195,9 +199,11 @@ TEST(mpse_hs_match, other)
 
 TEST(mpse_hs_match, multi)
 {
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, false, false, s_user) == 0);
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"bar", 3, false, false, s_user) == 0);
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"baz", 3, false, false, s_user) == 0);
+    Mpse::PatternDescriptor desc;
+
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, desc, s_user) == 0);
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"bar", 3, desc, s_user) == 0);
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"baz", 3, desc, s_user) == 0);
 
     CHECK(hs->prep_patterns(snort_conf) == 0);
     CHECK(hs->get_pattern_count() == 3);
@@ -211,8 +217,10 @@ TEST(mpse_hs_match, multi)
 #if 0
 TEST(mpse_hs_match, regex)
 {
+    Mpse::PatternDescriptor desc;
+
     CHECK(hs->add_pattern(
-            nullptr, (uint8_t*)"(foo)|(bar)|(baz)", 17, false, false, s_user) == 0);
+            nullptr, (uint8_t*)"(foo)|(bar)|(baz)", 17, desc, s_user) == 0);
 
     CHECK(hs->prep_patterns(snort_conf) == 0);
     CHECK(hs->get_pattern_count() == 1);
@@ -225,9 +233,11 @@ TEST(mpse_hs_match, regex)
 
 TEST(mpse_hs_match, pcre)
 {
+    Mpse::PatternDescriptor desc;
+
     // from sid 23286
     CHECK(hs->add_pattern(
-            nullptr, (uint8_t*)"\\.definition\\s*\\(", 21, false, false, s_user) == 0);
+            nullptr, (uint8_t*)"\\.definition\\s*\\(", 21, desc, s_user) == 0);
 
     CHECK(hs->prep_patterns(snort_conf) == 0);
     CHECK(hs->get_pattern_count() == 1);
@@ -275,8 +285,10 @@ TEST_GROUP(mpse_hs_multi)
 
 TEST(mpse_hs_multi, single)
 {
-    CHECK(hs1->add_pattern(nullptr, (uint8_t*)"uba", 3, false, false, s_user) == 0);
-    CHECK(hs2->add_pattern(nullptr, (uint8_t*)"tuba", 4, false, false, s_user) == 0);
+    Mpse::PatternDescriptor desc;
+
+    CHECK(hs1->add_pattern(nullptr, (uint8_t*)"uba", 3, desc, s_user) == 0);
+    CHECK(hs2->add_pattern(nullptr, (uint8_t*)"tuba", 4, desc, s_user) == 0);
 
     CHECK(hs1->prep_patterns(snort_conf) == 0);
     CHECK(hs2->prep_patterns(snort_conf) == 0);
index 5d04d91b3e20f5c234d2e0a4fbc3cae25e7231d6..ad48bea56ddc6133cf66ac2742376e6353a13ad3 100644 (file)
@@ -9,5 +9,5 @@ add_library( stream_tcp_test
 )
 
 # this test is broken, uncomment below when fixed
-#add_cpputest( tcp_normalizer_test stream_tcp_test )
+add_cpputest( tcp_normalizer_test stream_tcp_test )
 
index 849645a69acfa27cae2ee9ba83a34e818b8083ec..021521860f0e091c56e07c5b14884eb91d728941 100644 (file)
@@ -95,7 +95,7 @@ int main()
  *      int * - the skip table
  *
  ****************************************************************/
-int* make_skip(char* ptrn, int plen)
+int* make_skip(const char* ptrn, int plen)
 {
     int i;
     int* skip = (int*)SnortAlloc(256* sizeof(int));
@@ -123,11 +123,11 @@ int* make_skip(char* ptrn, int plen)
  *      int * - the shift table
  *
  ****************************************************************/
-int* make_shift(char* ptrn, int plen)
+int* make_shift(const char* ptrn, int plen)
 {
     int* shift = (int*)SnortAlloc(plen * sizeof(int));
     int* sptr = shift + plen - 1;
-    char* pptr = ptrn + plen - 1;
+    const char* pptr = ptrn + plen - 1;
     char c;
 
     c = ptrn[plen - 1];
@@ -136,7 +136,7 @@ int* make_shift(char* ptrn, int plen)
 
     while (sptr-- != shift)
     {
-        char* p1 = ptrn + plen - 2, * p2, * p3;
+        const char* p1 = ptrn + plen - 2, * p2, * p3;
 
         do
         {
index 291415463b1556aa75c441b67ad88677ac158301..183d28cdc4e4f246a6a91fefa97d3dc115c1e01b 100644 (file)
@@ -26,8 +26,8 @@
 #include "main/snort_types.h"
 
 // FIXIT-M: No associated resource destructor for make_skip & make_shift :(
-SO_PUBLIC int* make_skip(char*, int);
-SO_PUBLIC int* make_shift(char*, int);
+SO_PUBLIC int* make_skip(const char*, int);
+SO_PUBLIC int* make_shift(const char*, int);
 
 SO_PUBLIC int mSearch(const char*, int, const char*, int, int*, int*);
 SO_PUBLIC int mSearchCI(const char*, int, const char*, int, int*, int*);