From a3312a1d760770963724085eaa11c43c2bc5839b Mon Sep 17 00:00:00 2001 From: "Russ Combs (rucombs)" Date: Thu, 4 Aug 2016 13:48:47 -0400 Subject: [PATCH] Merge pull request #577 in SNORT/snort3 from hyper-sensitive to master Squashed commit of the following: commit 45bc7d00bcde706a4df09ec5ba416892a79f7b09 Author: Victor Roemer Date: Fri Jul 29 00:06:55 2016 -0400 Convert sd_pattern to Hyperscan engine. --- src/ips_options/CMakeLists.txt | 10 +- src/ips_options/Makefile.am | 10 +- src/ips_options/dev_notes.txt | 9 + src/ips_options/ips_sd_pattern.cc | 212 ++++++++++++--- .../{sd_pattern_match.h => ips_sd_pattern.h} | 39 +-- src/ips_options/sd_credit_card.cc | 2 +- src/ips_options/sd_credit_card.h | 2 +- src/ips_options/sd_pattern_match.cc | 252 ------------------ src/main/snort_config.cc | 3 + src/main/snort_config.h | 8 +- 10 files changed, 199 insertions(+), 348 deletions(-) rename src/ips_options/{sd_pattern_match.h => ips_sd_pattern.h} (51%) delete mode 100644 src/ips_options/sd_pattern_match.cc diff --git a/src/ips_options/CMakeLists.txt b/src/ips_options/CMakeLists.txt index 548d85ec5..d690a2259 100644 --- a/src/ips_options/CMakeLists.txt +++ b/src/ips_options/CMakeLists.txt @@ -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) diff --git a/src/ips_options/Makefile.am b/src/ips_options/Makefile.am index f43e47c41..e2c67c1b8 100644 --- a/src/ips_options/Makefile.am +++ b/src/ips_options/Makefile.am @@ -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 diff --git a/src/ips_options/dev_notes.txt b/src/ips_options/dev_notes.txt index 394d1b111..3d1100cb8 100644 --- a/src/ips_options/dev_notes.txt +++ b/src/ips_options/dev_notes.txt @@ -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. diff --git a/src/ips_options/ips_sd_pattern.cc b/src/ips_options/ips_sd_pattern.cc index fc5be6af8..771da208e 100644 --- a/src/ips_options/ips_sd_pattern.cc +++ b/src/ips_options/ips_sd_pattern.cc @@ -18,12 +18,15 @@ // ips_sd_pattern.cc author Victor Roemer -// FIXIT-M use Hyperscan +#include "ips_sd_pattern.h" #include #include #include +#include +#include + #include "framework/cursor.h" #include "framework/ips_option.h" #include "framework/module.h" @@ -34,22 +37,37 @@ #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(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 = { diff --git a/src/ips_options/sd_pattern_match.h b/src/ips_options/ips_sd_pattern.h similarity index 51% rename from src/ips_options/sd_pattern_match.h rename to src/ips_options/ips_sd_pattern.h index 7430c79ce..c7079cdb0 100644 --- a/src/ips_options/sd_pattern_match.h +++ b/src/ips_options/ips_sd_pattern.h @@ -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 @@ -17,37 +16,11 @@ // 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 -#include -#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 - diff --git a/src/ips_options/sd_credit_card.cc b/src/ips_options/sd_credit_card.cc index 8303e6065..02d17494f 100644 --- a/src/ips_options/sd_credit_card.cc +++ b/src/ips_options/sd_credit_card.cc @@ -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 */ diff --git a/src/ips_options/sd_credit_card.h b/src/ips_options/sd_credit_card.h index 684d084ad..1a0bca04d 100644 --- a/src/ips_options/sd_credit_card.h +++ b/src/ips_options/sd_credit_card.h @@ -24,6 +24,6 @@ #include -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 index 5443b482b..000000000 --- a/src/ips_options/sd_pattern_match.cc +++ /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 -#include -#include -#include - -#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; -} - diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 407e00c5f..ab8a51d35 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -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 } diff --git a/src/main/snort_config.h b/src/main/snort_config.h index f938f597e..45e13ce09 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -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 -- 2.47.2