From 0f1dd0d7ea46fb9a3b8d46d0da31c4af77774040 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Tue, 9 Jun 2015 14:26:57 -0600 Subject: [PATCH] flowbits: strip leading and trailing spaces in name Redmine bug 1481. Strip leading and trailing white space. Factor out parsing from setup while in here. --- src/detect-flowbits.c | 126 +++++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 21 deletions(-) diff --git a/src/detect-flowbits.c b/src/detect-flowbits.c index bb95c95cd6..2c10f49955 100644 --- a/src/detect-flowbits.c +++ b/src/detect-flowbits.c @@ -46,7 +46,7 @@ #include "util-unittest.h" #include "util-debug.h" -#define PARSE_REGEX "([a-z]+)(?:,(.*))?" +#define PARSE_REGEX "([a-z]+)(?:,\\s*([^\\s]*))?" static pcre *parse_regex; static pcre_extra *parse_regex_study; @@ -176,36 +176,51 @@ int DetectFlowbitMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p return 0; } -int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) +static int DetectFlowbitParse(char *str, char *cmd, int cmd_len, char *name, + int name_len) { - DetectFlowbitsData *cd = NULL; - SigMatch *sm = NULL; - uint8_t fb_cmd = 0; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char fb_cmd_str[16] = "", fb_name[256] = ""; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 2 && ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for flowbits.", rawstr); - return -1; + const int max_substrings = 30; + int count, rc; + int ov[max_substrings]; + + count = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, + ov, max_substrings); + if (count != 2 && count != 3) { + SCLogError(SC_ERR_PCRE_MATCH, + "\"%s\" is not a valid setting for flowbits.", str); + return 0; } - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, fb_cmd_str, sizeof(fb_cmd_str)); - if (res < 0) { + rc = pcre_copy_substring((char *)str, ov, max_substrings, 1, cmd, cmd_len); + if (rc < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return -1; + return 0; } - if (ret == 3) { - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, fb_name, sizeof(fb_name)); - if (res < 0) { + if (count == 3) { + rc = pcre_copy_substring((char *)str, ov, max_substrings, 2, name, + name_len); + if (rc < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; + return 0; } } + return 1; +} + +int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) +{ + DetectFlowbitsData *cd = NULL; + SigMatch *sm = NULL; + uint8_t fb_cmd = 0; + char fb_cmd_str[16] = "", fb_name[256] = ""; + + if (!DetectFlowbitParse(rawstr, fb_cmd_str, sizeof(fb_cmd_str), fb_name, + sizeof(fb_name))) { + return -1; + } + if (strcmp(fb_cmd_str,"noalert") == 0) { fb_cmd = DETECT_FLOWBITS_CMD_NOALERT; } else if (strcmp(fb_cmd_str,"isset") == 0) { @@ -297,6 +312,74 @@ void DetectFlowbitFree (void *ptr) } #ifdef UNITTESTS + +static int FlowBitsTestParse01(void) +{ + int ret = 0; + char command[16] = "", name[16] = ""; + + /* Single argument version. */ + if (!DetectFlowbitParse("noalert", command, sizeof(command), name, + sizeof(name))) { + goto end; + } + if (strcmp(command, "noalert") != 0) { + goto end; + } + + /* No leading or trailing spaces. */ + if (!DetectFlowbitParse("set,flowbit", command, sizeof(command), name, + sizeof(name))) { + goto end; + } + if (strcmp(command, "set") != 0) { + goto end; + } + if (strcmp(name, "flowbit") != 0) { + goto end; + } + + /* Leading space. */ + if (!DetectFlowbitParse("set, flowbit", command, sizeof(command), name, + sizeof(name))) { + goto end; + } + if (strcmp(command, "set") != 0) { + goto end; + } + if (strcmp(name, "flowbit") != 0) { + goto end; + } + + /* Trailing space. */ + if (!DetectFlowbitParse("set,flowbit ", command, sizeof(command), name, + sizeof(name))) { + goto end; + } + if (strcmp(command, "set") != 0) { + goto end; + } + if (strcmp(name, "flowbit") != 0) { + goto end; + } + + /* Leading and trailing space. */ + if (!DetectFlowbitParse("set, flowbit ", command, sizeof(command), name, + sizeof(name))) { + goto end; + } + if (strcmp(command, "set") != 0) { + goto end; + } + if (strcmp(name, "flowbit") != 0) { + goto end; + } + + ret = 1; +end: + return ret; +} + /** * \test FlowBitsTestSig01 is a test for a valid noalert flowbits option * @@ -1060,6 +1143,7 @@ end: void FlowBitsRegisterTests(void) { #ifdef UNITTESTS + UtRegisterTest("FlowBitsTestParse01", FlowBitsTestParse01, 1); UtRegisterTest("FlowBitsTestSig01", FlowBitsTestSig01, 0); UtRegisterTest("FlowBitsTestSig02", FlowBitsTestSig02, 0); UtRegisterTest("FlowBitsTestSig03", FlowBitsTestSig03, 0);