]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #577 in SNORT/snort3 from hyper-sensitive to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 4 Aug 2016 17:48:47 +0000 (13:48 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 4 Aug 2016 17:48:47 +0000 (13:48 -0400)
Squashed commit of the following:

commit 45bc7d00bcde706a4df09ec5ba416892a79f7b09
Author: Victor Roemer <viroemer@cisco.com>
Date:   Fri Jul 29 00:06:55 2016 -0400

    Convert sd_pattern to Hyperscan engine.

src/ips_options/CMakeLists.txt
src/ips_options/Makefile.am
src/ips_options/dev_notes.txt
src/ips_options/ips_sd_pattern.cc
src/ips_options/ips_sd_pattern.h [moved from src/ips_options/sd_pattern_match.h with 51% similarity]
src/ips_options/sd_credit_card.cc
src/ips_options/sd_credit_card.h
src/ips_options/sd_pattern_match.cc [deleted file]
src/main/snort_config.cc
src/main/snort_config.h

index 548d85ec5f9bab31fa18476b7b9d3842cab062fc..d690a22597fd0e42bd2d60dfd52f85025dae5ae9 100644 (file)
@@ -32,11 +32,6 @@ SET( PLUGIN_LIST
     ips_rem.cc
     ips_rev.cc
     ips_rpc.cc
-    ips_sd_pattern.cc
-    sd_credit_card.cc
-    sd_credit_card.h
-    sd_pattern_match.cc
-    sd_pattern_match.h
     ips_seq.cc
     ips_session.cc
     ips_sid.cc
@@ -76,7 +71,9 @@ set (IPS_SOURCES
 )
 
 if ( HAVE_HYPERSCAN )
-    set(OPTION_LIST ips_regex.cc ips_regex.h)
+    set(OPTION_LIST ips_regex.cc ips_regex.h
+        ips_sd_pattern.cc ips_sd_pattern.h
+        sd_credit_card.cc sd_credit_card.h)
 endif ()
 
 if (STATIC_IPS_OPTIONS)
@@ -122,7 +119,6 @@ else (STATIC_IPS_OPTIONS)
     add_shared_library(ips_rem ips_options ips_rem.cc)
     add_shared_library(ips_rev ips_options ips_rev.cc)
     add_shared_library(ips_rpc ips_options ips_rpc.cc)
-    add_shared_library(ips_sd_pattern ips_options ips_sd_pattern.cc sd_credit_card.cc sd_credit_card.h sd_pattern_match.cc sd_pattern_match.h)
     add_shared_library(ips_sid ips_options ips_sid.cc)
     add_shared_library(ips_seq ips_options ips_seq.cc)
     add_shared_library(ips_session ips_options ips_session.cc)
index f43e47c414bf6bf1c9b175a9cdea25b1c0a981ef..e2c67c1b8588d473e4ee3dc06e4739f6b39ada70 100644 (file)
@@ -31,9 +31,6 @@ ips_raw_data.cc \
 ips_rem.cc \
 ips_rev.cc \
 ips_rpc.cc \
-ips_sd_pattern.cc \
-sd_credit_card.cc sd_credit_card.h \
-sd_pattern_match.cc sd_pattern_match.h \
 ips_seq.cc \
 ips_session.cc \
 ips_sid.cc \
@@ -66,6 +63,7 @@ ips_so.cc
 
 if HAVE_HYPERSCAN
 libips_options_a_SOURCES += ips_regex.cc ips_regex.h
+libips_options_a_SOURCES += ips_sd_pattern.cc ips_sd_pattern.h sd_credit_card.cc sd_credit_card.h
 endif
 
 if STATIC_IPS_OPTIONS
@@ -229,12 +227,6 @@ libips_rpc_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libips_rpc_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -shared
 libips_rpc_la_SOURCES = ips_rpc.cc
 
-optlib_LTLIBRARIES += libips_sd_pattern.la
-libips_sd_pattern_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
-libips_sd_pattern_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -shared
-libips_sd_pattern_la_SOURCES = ips_sd_pattern.cc sd_credit_card.cc \
-                                                          sd_credit_card.h sd_pattern_match.cc sd_pattern_match.h
-
 optlib_LTLIBRARIES += libips_seq.la
 libips_seq_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libips_seq_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -shared
index 394d1b11173face992ff7c9ded2819a7964f5a11..3d1100cb8daea7726f73f3fb142cc6b2069e869f 100644 (file)
@@ -10,3 +10,12 @@ Several options use RangeCheck to implement upper and/or lower bound
 semantics.  The Snort 2X options had various implementations of ranges so
 3X differs in some places.
 
+The "regex" and "sd_pattern" options both use hyperscan for pattern matching.
+Hyperscan is an "optional" dependency for Snort3; These rule options will 
+not exist without satisfying that dependency.
+
+Hyperscan documentation can be found online 
+http://01org.github.io/hyperscan/dev-reference
+
+The "sd_pattern" will be used as a fast pattern in the future (like "regex")
+for performance. 
index fc5be6af8ca23d5f047d4f34cf6054ef5f231759..771da208eb313ecaf8a3831464ac77429f69ff2b 100644 (file)
 
 // ips_sd_pattern.cc author Victor Roemer <viroemer@cisco.com>
 
-// FIXIT-M use Hyperscan
+#include "ips_sd_pattern.h"
 
 #include <string.h>
 #include <assert.h>
 #include <string>
 
+#include <hs_compile.h>
+#include <hs_runtime.h>
+
 #include "framework/cursor.h"
 #include "framework/ips_option.h"
 #include "framework/module.h"
 #include "main/thread.h"
 #include "parser/parser.h"
 #include "profiler/profiler.h"
-#include "sd_pattern_match.h"
+#include "sd_credit_card.h"
 #include "log/obfuscator.h"
 
 #define s_name "sd_pattern"
 #define s_help "rule option for detecting sensitive data"
 
+#define SD_SOCIAL_PATTERN          "\\b\\d{3}-\\d{2}-\\d{4}\\b"
+#define SD_SOCIAL_NODASHES_PATTERN "\\b\\d{9}\\b"
+#define SD_CREDIT_PATTERN_ALL      "\\b\\d{4}[- ]?\\d{4}[- ]?\\d{2}[- ]?\\d{2}[- ]?\\d{3,4}\\b"
+
+// we need to update scratch in the main thread as each pattern is processed
+// and then clone to thread specific after all rules are loaded.  s_scratch is
+// a prototype that is large enough for all uses.
+
+// FIXIT-L Determine if it's worthwhile to use a single scratch space for both
+// "regex" and "sd_pattern" keywords.
+// FIXIT-L See ips_regex.cc for more information.
+static hs_scratch_t* s_scratch = nullptr;
+
 struct SdStats
 {
-    PegCount nomatch_notfound;
     PegCount nomatch_threshold;
+    PegCount nomatch_notfound;
+    PegCount terminated;
 };
 
 const PegInfo sd_pegs[] =
 {
     { "below threshold", "sd_pattern matched but missed threshold" },
     { "pattern not found", "sd_pattern did not not match" },
+    { "terminated", "hyperscan terminated" },
     { nullptr, nullptr }
 };
 
@@ -57,9 +75,19 @@ static THREAD_LOCAL SdStats s_stats;
 
 struct SdPatternConfig
 {
+    hs_database_t* db;
+
     std::string pii;
     unsigned threshold = 1;
-    bool obfuscate_pii;
+    bool obfuscate_pii = false;
+    int (*validate)(const uint8_t* buf, unsigned long long buflen) = nullptr;
+
+    inline bool operator==(const SdPatternConfig& rhs) const
+    {
+        if ( pii == rhs.pii and threshold == rhs.threshold )
+            return true;
+        return false;
+    }
 };
 
 static THREAD_LOCAL ProfileStats sd_pattern_perf_stats;
@@ -81,25 +109,29 @@ public:
 
 private:
     unsigned SdSearch(Cursor&, Packet*);
-
     const SdPatternConfig config;
-    SdOptionData* opt;
 };
 
 SdPatternOption::SdPatternOption(const SdPatternConfig& c) :
     IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE), config(c)
 {
-    opt = new SdOptionData(config.pii, config.obfuscate_pii);
+    if ( hs_error_t err = hs_alloc_scratch(config.db, &s_scratch) )
+    {
+        // FIXIT-L why is this failing but everything is working?
+        ParseError("can't initialize sd_pattern for %s (%d) %p",
+                config.pii.c_str(), err, (void*)s_scratch);
+    }
 }
 
 SdPatternOption::~SdPatternOption()
-{
-    delete opt;
+{ 
+    if ( config.db )
+        hs_free_database(config.db);
 }
 
 uint32_t SdPatternOption::hash() const
 {
-    uint32_t a = 0, b = 0, c = 0;
+    uint32_t a = 0, b = 0, c = config.threshold;
     mix_str(a, b, c, config.pii.c_str());
     mix_str(a, b, c, get_name());
     finalize(a, b, c);
@@ -113,48 +145,75 @@ bool SdPatternOption::operator==(const IpsOption& ips) const
 
     const SdPatternOption& rhs = static_cast<const SdPatternOption&>(ips);
 
-    if ( config.pii == rhs.config.pii
-        and config.threshold == rhs.config.threshold )
+    if ( config == rhs.config )
         return true;
 
     return false;
 }
 
+struct hsContext 
+{
+    hsContext(const SdPatternConfig &c_, Packet* p_, const uint8_t* const start_)
+        : config(c_), packet(p_), start(start_) {}
+
+    unsigned int count = 0;
+
+    SdPatternConfig config;
+    Packet* packet = nullptr;
+    const uint8_t* const start = nullptr;
+    const uint8_t* buf = nullptr;
+};
+
+// FIXIT-H Count matches
+// FIXIT-H afix this to SdPatternOption
+int hs_match(unsigned int /*id*/, unsigned long long from,
+        unsigned long long to, unsigned int /*flags*/, void *context)
+{
+    hsContext* ctx = (hsContext*) context;
+
+    assert(ctx);
+    assert(ctx->packet);
+    assert(ctx->start);
+
+    unsigned long long len = to - from;
+    if ( ctx->config.validate && ctx->config.validate(ctx->buf, len) != 1 )
+        return 0;
+
+    ctx->count++;
+
+    if ( ctx->config.obfuscate_pii )
+    {
+        if ( !ctx->packet->obfuscator )
+            ctx->packet->obfuscator = new Obfuscator();
+
+        uint32_t off = ctx->buf - ctx->start;
+        // FIXIT-L Make configurable or don't show any PII partials (0 for user defined??) 
+        len = len > 4 ? len - 4 : len;
+        ctx->packet->obfuscator->push(off, len);
+    }
+
+    return 0;
+}
+
 unsigned SdPatternOption::SdSearch(Cursor& c, Packet* p)
 {
     const uint8_t* const start = c.buffer();
     const uint8_t* buf = c.start();
-    uint16_t buflen = c.length();
-    const uint8_t* const end = buf + buflen;
+    unsigned int buflen = c.length();
 
-    unsigned count = 0;
-    while (buf < end && count < config.threshold)
-    {
-        uint16_t match_len = 0;
+    SnortState* ss = snort_conf->state + get_instance_id();
+    assert(ss->sdpattern_scratch);
 
-        if ( opt->match(buf, &match_len, buflen) )
-        {
-            if ( opt->obfuscate_pii )
-            {
-                if ( !p->obfuscator )
-                    p->obfuscator = new Obfuscator();
-
-                uint32_t off = buf - start;
-                p->obfuscator->push(off, match_len - 4);
-            }
-
-            buf += match_len;
-            buflen -= match_len;
-            count++;
-        }
-        else
-        {
-            buf++;
-            buflen--;
-        }
-    }
+    hsContext ctx(config, p, start);
+    ctx.buf = buf;
+
+    hs_error_t stat = hs_scan(config.db, (const char*)buf, buflen, 0,
+        (hs_scratch_t*)ss->sdpattern_scratch, hs_match, (void*)&ctx);
 
-    return count;
+    if ( stat == HS_SCAN_TERMINATED )
+        ++s_stats.terminated;
+
+    return ctx.count;
 }
 
 int SdPatternOption::eval(Cursor& c, Packet* p)
@@ -195,6 +254,7 @@ public:
 
     bool begin(const char*, int, SnortConfig*) override;
     bool set(const char*, Value& v, SnortConfig*) override;
+    bool end(const char*, int, SnortConfig*) override;
 
     const PegInfo* get_pegs() const override
     { return sd_pegs; }
@@ -220,7 +280,8 @@ bool SdPatternModule::begin(const char*, int, SnortConfig*)
 
 bool SdPatternModule::set(const char*, Value& v, SnortConfig* sc)
 {
-    config.obfuscate_pii = sc->obfuscate_pii;
+    config.obfuscate_pii = false;
+
     if ( v.is("~pattern") )
     {
         config.pii = v.get_string();
@@ -233,9 +294,74 @@ bool SdPatternModule::set(const char*, Value& v, SnortConfig* sc)
     else
         return false;
 
+    // Check if built-in pattern should be used.
+    if (config.pii == "credit_card")
+    {
+        config.pii = SD_CREDIT_PATTERN_ALL;
+        config.validate = SdLuhnAlgorithm;
+        config.obfuscate_pii = sc->obfuscate_pii;
+    }
+
+    else if (config.pii == "us_social")
+    {
+        config.pii = SD_SOCIAL_PATTERN;
+        config.obfuscate_pii = sc->obfuscate_pii;
+    }
+
+    else if (config.pii == "us_social_nodashes")
+    {
+        config.pii = SD_SOCIAL_NODASHES_PATTERN;
+        config.obfuscate_pii = sc->obfuscate_pii;
+    }
+
+    return true;
+}
+
+bool SdPatternModule::end(const char*, int, SnortConfig*)
+{
+    hs_compile_error_t* err = nullptr;
+
+    if ( hs_compile(config.pii.c_str(), HS_FLAG_DOTALL|HS_FLAG_SOM_LEFTMOST, HS_MODE_BLOCK, nullptr, &config.db, &err)
+        or !config.db )
+    {
+        ParseError("can't compile regex '%s'", config.pii.c_str());
+        hs_free_compile_error(err);
+        return false;
+    }
     return true;
 }
 
+//-------------------------------------------------------------------------
+// public methods
+//-------------------------------------------------------------------------
+
+void sdpattern_setup(SnortConfig* sc)
+{
+    for ( unsigned i = 0; i < sc->num_slots; ++i )
+    {
+        SnortState* ss = sc->state + i;
+
+        if ( s_scratch )
+            hs_clone_scratch(s_scratch, (hs_scratch_t**)&ss->sdpattern_scratch);
+        else
+            ss->sdpattern_scratch = nullptr;
+    }
+}
+
+void sdpattern_cleanup(SnortConfig* sc)
+{
+    for ( unsigned i = 0; i < sc->num_slots; ++i )
+    {
+        SnortState* ss = sc->state + i;
+
+        if ( ss->sdpattern_scratch )
+        {
+            hs_free_scratch((hs_scratch_t*)ss->sdpattern_scratch);
+            ss->sdpattern_scratch = nullptr;
+        }
+    }
+}
+
 //-------------------------------------------------------------------------
 // api methods
 //-------------------------------------------------------------------------
@@ -259,7 +385,9 @@ static IpsOption* sd_pattern_ctor(Module* m, OptTreeNode*)
 }
 
 static void sd_pattern_dtor(IpsOption* p)
-{ delete p; }
+{ 
+    delete p;
+}
 
 static const IpsApi sd_pattern_api =
 {
similarity index 51%
rename from src/ips_options/sd_pattern_match.h
rename to src/ips_options/ips_sd_pattern.h
index 7430c79ceba327aac3cf712492e968f7f48f865f..c7079cdb0380d0dee6f4c408c17db1e9a8446eb3 100644 (file)
@@ -1,6 +1,5 @@
 //--------------------------------------------------------------------------
-// Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2009-2013 Sourcefire, Inc.
+// Copyright (C) 2015-2016 Cisco and/or its affiliates. All rights reserved.
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License Version 2 as published
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// sd_pattern_match.h author Ryan Jordan
+#ifndef IPS_SD_PATTERN_H
+#define IPS_SD_PATTERN_H
 
-#ifndef SD_PATTERN_MATCH_H
-#define SD_PATTERN_MATCH_H
-
-#include <iostream>
-#include <stdint.h>
-#include "utils/util.h"
-
-#define SD_SOCIAL_PATTERN          "\\b\\d{3}-\\d{2}-\\d{4}\\b"
-#define SD_SOCIAL_NODASHES_PATTERN "\\b\\d{9}\\b"
-#define SD_CREDIT_PATTERN_ALL      "\\b\\d{4} ?-?\\d{4} ?-?\\d{2} ?-?\\d{2} ?-?\\d{3}\\d?\\b"
-
-class SdOptionData
-{
-public:
-    friend class SdPatternOption;
-
-    SdOptionData(std::string pattern, bool obfuscate);
-
-    ~SdOptionData()
-    { snort_free(pattern); }
-
-    void ExpandBrackets();
-    bool match(const uint8_t* const buf, uint16_t* const buf_index, uint16_t buflen);
-
-private:
-    char* pattern;
-    int (*validate)(const uint8_t* buf, uint32_t buflen) = nullptr;
-    bool obfuscate_pii = false;
-};
+struct SnortConfig;
+void sdpattern_setup(SnortConfig*);
+void sdpattern_cleanup(SnortConfig*);
 
 #endif
-
index 8303e60659b68790de865a765a9dd8f02a599aff..02d17494fb966144d4a23cf8269e64482e5f9225 100644 (file)
@@ -61,7 +61,7 @@ static inline int CheckIssuers(const uint8_t *cardnum, uint32_t buflen)
  *
  * Returns: 1 on match, 0 otherwise.
  */
-int SdLuhnAlgorithm(const uint8_t *buf, uint32_t buflen)
+int SdLuhnAlgorithm(const uint8_t *buf, unsigned long long buflen)
 {
     int i, digits, alternate, sum, val;
     char cc_digits[CC_COPY_BUF_LEN]; /* Normalized CC# string */
index 684d084addc0102988e8c235e43ddd484b5be1fd..1a0bca04de079f1e0c010db15a07ae0b8564606c 100644 (file)
@@ -24,6 +24,6 @@
 
 #include <stdint.h>
 
-int SdLuhnAlgorithm(const uint8_t *buf, uint32_t buflen);
+int SdLuhnAlgorithm(const uint8_t *buf, unsigned long long buflen);
 
 #endif
diff --git a/src/ips_options/sd_pattern_match.cc b/src/ips_options/sd_pattern_match.cc
deleted file mode 100644 (file)
index 5443b48..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2009-2013 Sourcefire, Inc.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation.  You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//--------------------------------------------------------------------------
-
-// sd_pattern_match.cc author Ryan Jordan
-
-#include "sd_pattern_match.h"
-#include "sd_credit_card.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "log/messages.h"
-#include "utils/util.h"
-
-SdOptionData::SdOptionData(std::string pattern_, bool obfuscate_)
-{
-    if (pattern_ == "credit_card")
-    {
-        pattern_ = SD_CREDIT_PATTERN_ALL;
-        validate = SdLuhnAlgorithm;
-        obfuscate_pii = obfuscate_;
-    }
-
-    else if (pattern_ == "us_social")
-    {
-        pattern_ = SD_SOCIAL_PATTERN;
-        obfuscate_pii = obfuscate_;
-    }
-
-    else if (pattern_ == "us_social_nodashes")
-    {
-        pattern_ = SD_SOCIAL_NODASHES_PATTERN;
-        obfuscate_pii = obfuscate_;
-    }
-
-    pattern = snort_strdup(pattern_.c_str());
-    ExpandBrackets();
-}
-
-void SdOptionData::ExpandBrackets()
-{
-    char* bracket_index, * new_pii, * endptr, * pii_position;
-    unsigned long int new_pii_size, repetitions, total_reps = 0;
-    unsigned int num_brackets = 0;
-
-    if ( !pattern )
-        return;
-
-    bracket_index = strchr(pattern, '{');
-
-    if ( bracket_index == pattern )
-        ParseError("sd_pattern \"%s\" starts with curly brackets which have nothing to modify.", pattern);
-
-    while ( bracket_index )
-    {
-        if ( (bracket_index > pattern) && (*(bracket_index-1) == '\\') )
-        {
-            // Ignore escaped brackets
-            bracket_index = strchr(bracket_index+1, '{');
-            continue;
-        }
-
-        // Check for the case of one bracket set modifying another, i.e. "{3}{4}"
-        // Note: "\}{4}" is OK
-        if ( (bracket_index > pattern + 1) && (*(bracket_index - 1) == '}') && (*(bracket_index - 2) != '\\') )
-            ParseError("sd_pattern \"%s\" contains curly brackets which have nothing to modify.", pattern);
-
-        repetitions = strtoul(bracket_index+1, &endptr, 10);
-
-        if ( *endptr != '}' && *endptr != '\0' )
-            ParseError("sd_pattern \"%s\" contains curly brackets with non-digits inside.", pattern);
-
-        else if (*endptr == '\0')
-            ParseError("sd_pattern \"%s\" contains an unterminated curly bracket.", pattern);
-
-        if ( (bracket_index > pattern+1) && (*(bracket_index-2) == '\\') )
-            total_reps += (repetitions * 2);
-        else
-            total_reps += repetitions;
-
-        num_brackets++;
-
-        bracket_index = strchr(bracket_index+1, '{');
-    }
-
-    if ( num_brackets == 0 )
-        return;
-
-    new_pii_size = (strlen(pattern) + total_reps - 2 * num_brackets + 1);
-    new_pii = (char*)snort_calloc(new_pii_size, sizeof(*new_pii));
-
-    pii_position = pattern;
-
-    while (*pii_position != '\0')
-    {
-        char repeated_section[3] = {'\0'};
-        unsigned long int i, reps = 1;
-
-        repeated_section[0] = pii_position[0];
-        pii_position++;
-
-        if ( repeated_section[0] == '\\'
-          && pii_position[0] != '\0' )
-        {
-            repeated_section[1] = pii_position[0];
-            pii_position++;
-        }
-
-        if ( pii_position[0] == '{' )
-        {
-            reps = strtoul(pii_position+1, &endptr, 10);
-            pii_position = endptr+1;
-        }
-
-        for (i = 0; i < reps; i++)
-            strncat(new_pii, repeated_section, 2);
-    }
-
-    snort_free(pattern);
-    pattern = new_pii;
-}
-
-bool SdOptionData::match(const uint8_t * const buf, uint16_t * const buf_index, uint16_t buflen)
-{
-    uint16_t pattern_index = 0;
-    bool node_match = true;
-
-    while ( *buf_index < buflen && pattern[pattern_index] != '\0' && node_match )
-    {
-        char const * const pc = &pattern[pattern_index];
-
-        if ( pc[0] == '\\' && pc[1] != '\0' )
-        {
-match__rescan:
-            pattern_index++;
-            switch ( pattern[pattern_index] )
-            {
-                // Escaped special character
-                case '\\':
-                case '{':
-                case '}':
-                case '?':
-                    node_match = (buf[*buf_index] == pattern[pattern_index]);
-                    break;
-
-                // \d : match digit
-                case 'd':
-                    node_match = isdigit((int)buf[*buf_index]);
-                    break;
-
-                // \D : match non-digit
-                case 'D':
-                    node_match = !isdigit((int)buf[*buf_index]);
-                    break;
-
-                // \w : match alphanumeric
-                case 'w':
-                    node_match = isalnum((int)buf[*buf_index]);
-                    break;
-
-                // \W : match non-alphanumeric */
-                case 'W':
-                    node_match = !isalnum((int)buf[*buf_index]);
-                    break;
-
-                // \l : match a letter
-                case 'l':
-                    node_match = isalpha((int)buf[*buf_index]);
-                    break;
-
-                // \L : match a non-letter
-                case 'L':
-                    node_match = !isalpha((int)buf[*buf_index]);
-                    break;
-
-                // \b : match a numeric boundary
-                case 'b':
-                    node_match = !isdigit((int)buf[*buf_index]);
-                    if ( !node_match && *buf_index == 0
-                      && pattern[pattern_index+1] != '\0'
-                      && pattern[pattern_index+2] != '\0' )
-                    {
-                        pattern_index++;
-                        goto match__rescan;
-                    }
-            }
-        }
-        else
-        {
-            // Normal byte match
-            node_match = (buf[*buf_index] == pattern[pattern_index]);
-        }
-
-        // Handle optional characters
-        if (pattern[pattern_index + 1] == '?')
-        {
-            pattern_index += 2;
-            if (node_match)
-                (*buf_index)++;
-            else
-                node_match = true;
-        }
-        else
-        {
-            (*buf_index)++;
-            pattern_index++;
-        }
-    }
-
-    if ( !node_match )
-        return false;
-
-    if( *buf_index == buflen )
-    {
-        char const * const pc = &pattern[pattern_index];
-
-        // '\b' can match EOM
-        if ( !(pc[0] == '\\' && pc[1] == 'b') )
-        {
-            if( (pc[0] == '\0') )
-                return true;
-
-            else
-                return false;
-        }
-    }
-
-    if ( validate && validate(buf, *buf_index) != 1 )
-        return false;
-
-    // Success!
-    return true;
-}
-
index 407e00c5f52bf862d752a3b30897aaba047e05cd..ab8a51d3506b23ef96d6c23c0346d115b1b614d2 100644 (file)
@@ -47,6 +47,7 @@
 
 #ifdef HAVE_HYPERSCAN
 #include "ips_options/ips_regex.h"
+#include "ips_options/ips_sd_pattern.h"
 #include "search_engines/hyperscan.h"
 #endif
 
@@ -188,6 +189,7 @@ SnortConfig::~SnortConfig()
 
 #ifdef HAVE_HYPERSCAN
     hyperscan_cleanup(this);
+    sdpattern_cleanup(this);
     regex_cleanup(this);
 #endif
     pcre_cleanup(this);
@@ -275,6 +277,7 @@ void SnortConfig::setup()
     pcre_setup(this);
 #ifdef HAVE_HYPERSCAN
     regex_setup(this);
+    sdpattern_setup(this);
     hyperscan_setup(this);
 #endif
 }
index f938f597ee3560d8a93bfcaf8a90466c0607584b..45e13ce093a5f17fa03d3d09dcc44d0348b8030d 100644 (file)
@@ -136,11 +136,13 @@ struct SnortState
 {
     int* pcre_ovector;
 
-    // regex and hs are conditionally built but these are unconditional to
-    // avoid compatibility issues with plugins.  if these are conditional
-    // then API_OPTIONS must be updated.  note: fwd decls don't work here.
+    // regex hyperscan and sdpattern are conditionally built but these are
+    // unconditional to avoid compatibility issues with plugins.  if these are
+    // conditional then API_OPTIONS must be updated.
+    // note: fwd decls don't work here.
     void* regex_scratch;
     void* hyperscan_scratch;
+    void* sdpattern_scratch;
 };
 
 struct SnortConfig