From: Russ Combs Date: Thu, 19 Jun 2014 18:22:04 +0000 (-0400) Subject: updated fast_pattern* syntax X-Git-Tag: 3.0.0-233~1477 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc4899f54c8311d939ae3b573bbafcbf0134ce25;p=thirdparty%2Fsnort3.git updated fast_pattern* syntax --- diff --git a/src/ips_options/ips_content.cc b/src/ips_options/ips_content.cc index 9b4ee7762..573b51dd0 100644 --- a/src/ips_options/ips_content.cc +++ b/src/ips_options/ips_content.cc @@ -236,9 +236,10 @@ static void update_pmd(PatternMatchData* pmd) pmd->last_check = (PmdLastCheck*)SnortAlloc(get_instance_max() * sizeof(*pmd->last_check)); } -static int HasFastPattern(OptTreeNode *otn, int list_type) +static int FastPatterns(OptTreeNode *otn, int list_type) { OptFpList* fpl = otn ? otn->opt_func : nullptr; + int c = 0; while ( fpl ) { @@ -248,11 +249,11 @@ static int HasFastPattern(OptTreeNode *otn, int list_type) PatternMatchData* pmd = opt->get_data(); if ( pmd->fp ) - return 1; + c++; } fpl = fpl->next; } - return 0; + return c; } static int32_t ParseInt(const char* data, const char* tag) @@ -274,11 +275,8 @@ static int32_t ParseInt(const char* data, const char* tag) return value; } -// FIXIT the following comment is no longer true; -/* Since each content modifier can be parsed as a rule option, do this check - * after parsing the entire rule in FinalizeContentUniqueness() */ static void ValidateContent( - SnortConfig*, PatternMatchData *pmd, int) + SnortConfig*, PatternMatchData *pmd, OptTreeNode* otn) { if (pmd == NULL) return; @@ -308,6 +306,9 @@ static void ValidateContent( ParseError("Fast pattern only contents cannot be negated."); } } + + if ( FastPatterns(otn, RULE_OPTION_TYPE_CONTENT) > 1 ) + ParseError("Only one content per rule may be used for fast pattern matching."); } static void make_precomp(PatternMatchData * idx) @@ -717,82 +718,68 @@ static void PayloadSearchNocase( } static void PayloadSearchFastPattern( - PatternMatchData* pmd, char *data, OptTreeNode *otn) + PatternMatchData* pmd, char *data, OptTreeNode*) { - /* There can only be one fast pattern content in the rule, whether - * normal, http or other */ - if (pmd->fp) - { - ParseError("Cannot set fast_pattern modifier more than once " - "for the same \"content\"."); - } + if ( data ) + ParseError("'fast_pattern' does not take an argument"); - if (HasFastPattern(otn, RULE_OPTION_TYPE_CONTENT)) - ParseError("Can only use the fast_pattern modifier once in a rule."); + pmd->fp = 1; +} + +static void PayloadSearchFastPatternOnly( + PatternMatchData* pmd, char *data, OptTreeNode*) +{ + if ( data ) + ParseError("'fast_pattern_only' does not take an argument"); pmd->fp = 1; + pmd->fp_only = 1; +} - if (data != NULL) - { - const char *error_str = "Rule option \"fast_pattern\": Invalid parameter: " - "\"%s\". Valid parameters are: \"only\" | ,. " - "Offset and length must be integers less than 65536, offset cannot " - "be negative, length must be positive and (offset + length) must " - "evaluate to less than or equal to the actual pattern length. " - "Pattern length: %u"; - - if (isdigit((int)*data)) - { - /* Specifying offset and length of pattern to use for - * fast pattern matcher */ +static void PayloadSearchFastPatternOffset( + PatternMatchData* pmd, char *data, OptTreeNode*) +{ + if (data == NULL) + ParseError("Missing argument to 'fast_pattern_offset' option"); - long int offset, length; - char *endptr; - char **toks; - int num_toks; + long offset = ParseInt(data, "fast_pattern_offset"); - toks = mSplit(data, " ", 0, &num_toks, 0); - if (num_toks != 2) - { - mSplitFree(&toks, num_toks); - ParseError(error_str, data, pmd->pattern_size); - } + static const char* error_str = + "fast_pattern_offset must be non-negative and fast_pattern_offset + " + "fast_pattern_length must be less than or equal to the actual pattern " + "length which is %u."; - offset = SnortStrtol(toks[0], &endptr, 0); - if ((errno == ERANGE) || (*endptr != '\0') - || (offset < 0) || (offset > UINT16_MAX)) - { - mSplitFree(&toks, num_toks); - ParseError(error_str, data, pmd->pattern_size); - } + if ( (offset < 0) || (offset > UINT16_MAX)) + ParseError(error_str, data, pmd->pattern_size); - length = SnortStrtol(toks[1], &endptr, 0); - if ((errno == ERANGE) || (*endptr != '\0') - || (length <= 0) || (length > UINT16_MAX)) - { - mSplitFree(&toks, num_toks); - ParseError(error_str, data, pmd->pattern_size); - } + if ((int)pmd->pattern_size < (offset + pmd->fp_length)) + ParseError(error_str, data, pmd->pattern_size); - mSplitFree(&toks, num_toks); + pmd->fp_offset = offset; + pmd->fp = 1; +} - if ((int)pmd->pattern_size < (offset + length)) - ParseError(error_str, data, pmd->pattern_size); +static void PayloadSearchFastPatternLength( + PatternMatchData* pmd, char *data, OptTreeNode*) +{ + if (data == NULL) + ParseError("Missing argument to 'fast_pattern_length' option"); - pmd->fp_offset = (uint16_t)offset; - pmd->fp_length = (uint16_t)length; - } - else - { - /* Specifies that this content should only be used for - * fast pattern matching */ + long length = ParseInt(data, "fast_pattern_length"); - if (strcasecmp(data, PM_FP_ONLY) != 0) - ParseError(error_str, data, pmd->pattern_size); + const char* error_str = + "fast_pattern_length must be positive and fast_pattern_offset + " + "fast_pattern_length must be less than or equal to the actual pattern " + "length which is %u."; - pmd->fp_only = 1; - } - } + if ( (length < 0) || (length > UINT16_MAX)) + ParseError(error_str, data, pmd->pattern_size); + + if ((int)pmd->pattern_size < (pmd->fp_offset + length)) + ParseError(error_str, data, pmd->pattern_size); + + pmd->fp_length = length; + pmd->fp = 1; } //------------------------------------------------------------------------- @@ -1139,6 +1126,18 @@ static IpsOption* content_ctor( { PayloadSearchFastPattern(pmd, opt1, otn); } + else if (!strcasecmp(opts[0], "fast_pattern_only")) + { + PayloadSearchFastPatternOnly(pmd, opt1, otn); + } + else if (!strcasecmp(opts[0], "fast_pattern_offset")) + { + PayloadSearchFastPatternOffset(pmd, opt1, otn); + } + else if (!strcasecmp(opts[0], "fast_pattern_length")) + { + PayloadSearchFastPatternLength(pmd, opt1, otn); + } else if (!strcasecmp(opts[0], "distance")) { PayloadSearchDistance(pmd, opt1, otn); @@ -1155,7 +1154,7 @@ static IpsOption* content_ctor( } free(data_dup); - ValidateContent(sc, pmd, RULE_OPTION_TYPE_CONTENT); + ValidateContent(sc, pmd, otn); return new ContentOption(pmd, "content"); }