diff --git a/src/detect-content.c b/src/detect-content.c index 9c6520bcb0..98bff5bc2b 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -39,10 +39,14 @@ #include "flow-var.h" #include "detect-flow.h" +#include "util-unittest.h" + #include "threads.h" int DetectContentMatch (ThreadVars *, PatternMatcherThread *, Packet *, Signature *, SigMatch *); int DetectContentSetup (DetectEngineCtx *, Signature *, SigMatch *, char *); +void DetectContentRegisterTests(void); +void DetectContentFree(DetectContentData *); u_int8_t nocasetable[256]; #define _nc(c) nocasetable[(c)] @@ -52,7 +56,7 @@ void DetectContentRegister (void) { sigmatch_table[DETECT_CONTENT].Match = DetectContentMatch; sigmatch_table[DETECT_CONTENT].Setup = DetectContentSetup; sigmatch_table[DETECT_CONTENT].Free = NULL; - sigmatch_table[DETECT_CONTENT].RegisterTests = NULL; + sigmatch_table[DETECT_CONTENT].RegisterTests = DetectContentRegisterTests; /* create table for O(1) case conversion lookup */ u_int8_t c = 0; @@ -273,10 +277,9 @@ int DetectContentMatch (ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Sig return DoDetectContent(t, pmt, p, s, m, co); } -int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *contentstr) +DetectContentData *DetectContentParse (char *contentstr) { DetectContentData *cd = NULL; - SigMatch *sm = NULL; char *str = contentstr; char dubbed = 0; u_int16_t len; @@ -289,16 +292,16 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char len = strlen(str); if (len == 0) - return -1; + goto error; cd = malloc(sizeof(DetectContentData)); if (cd == NULL) { - printf("DetectContentSetup malloc failed\n"); + printf("DetectContentParse malloc failed\n"); goto error; } memset(cd,0,sizeof(DetectContentData)); - //printf("DetectContentSetup: \"%s\", len %u\n", str, len); + //printf("DetectContentParse: \"%s\", len %u\n", str, len); char converted = 0; { @@ -315,12 +318,12 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char } else { if (bin) { if (isdigit(str[i]) || - str[i] == 'A' || str[i] == 'a' || - str[i] == 'B' || str[i] == 'b' || - str[i] == 'C' || str[i] == 'c' || - str[i] == 'D' || str[i] == 'd' || - str[i] == 'E' || str[i] == 'e' || - str[i] == 'F' || str[i] == 'f') { + str[i] == 'A' || str[i] == 'a' || + str[i] == 'B' || str[i] == 'b' || + str[i] == 'C' || str[i] == 'c' || + str[i] == 'D' || str[i] == 'd' || + str[i] == 'E' || str[i] == 'e' || + str[i] == 'F' || str[i] == 'f') { // printf("part of binary: %c\n", str[i]); binstr[binpos] = (char)str[i]; @@ -360,7 +363,7 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char cd->content = malloc(len); if (cd->content == NULL) - return -1; + goto error; memcpy(cd->content, str, len); cd->content_len = len; @@ -370,8 +373,23 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char cd->distance = 0; cd->flags = 0; - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ + if (dubbed != 0) free(str); + return cd; + +error: + if (dubbed != 0) free(str); + if (cd != NULL) free(cd); + return NULL; +} + +int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *contentstr) +{ + DetectContentData *cd = NULL; + SigMatch *sm = NULL; + + cd = DetectContentParse(contentstr); + if (cd == NULL) goto error; + sm = SigMatchAlloc(); if (sm == NULL) goto error; @@ -386,14 +404,118 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char s->flags |= SIG_FLAG_MPM; - if (dubbed) free(str); return 0; error: - if (dubbed) free(str); - if (cd) free(cd); - if (sm) free(sm); + if (cd != NULL) DetectContentFree(cd); + if (sm != NULL) free(sm); return -1; } +/** + * \brief this function will free memory associated with DetectContentData + * + * \param cd pointer to DetectCotentData + */ +void DetectContentFree(DetectContentData *cd) { + free(cd); +} + +/** + * \test DetectCotentParseTest01 this is a test to make sure we can deal with escaped colons + */ +int DetectContentParseTest01 (void) { + int result = 1; + DetectContentData *cd = NULL; + char *teststring = "\"abc\\:def\""; + char *teststringparsed = "abc:def"; + cd = DetectContentParse(teststring); + if (cd != NULL) { + if(memcmp(cd->content, teststringparsed, sizeof(teststringparsed)) != 0){ + printf("expected %s got %s: ", teststringparsed, cd->content); + result = 0; + DetectContentFree(cd); + } + }else if(cd == NULL){ + printf("expected %s got NULL: ", teststringparsed); + result = 0; + } + return result; +} + +/** + * \test DetectCotentParseTest02 this is a test to make sure we can deal with escaped semi-colons + */ +int DetectContentParseTest02 (void) { + int result = 1; + DetectContentData *cd = NULL; + char *teststring = "\"abc\\;def\""; + char *teststringparsed = "abc;def"; + cd = DetectContentParse(teststring); + if (cd != NULL) { + if(memcmp(cd->content, teststringparsed, sizeof(teststringparsed)) != 0){ + printf("expected %s got %s: ", teststringparsed, cd->content); + result = 0; + DetectContentFree(cd); + } + }else if(cd == NULL){ + printf("expected %s got NULL: ", teststringparsed); + result = 0; + } + return result; +} + +/** + * \test DetectCotentParseTest03 this is a test to make sure we can deal with escaped double-quotes + */ +int DetectContentParseTest03 (void) { + int result = 1; + DetectContentData *cd = NULL; + char *teststring = "\"abc\\\"def\""; + char *teststringparsed = "abc\"def"; + cd = DetectContentParse(teststring); + if (cd != NULL) { + if(memcmp(cd->content, teststringparsed, sizeof(teststringparsed)) != 0){ + printf("expected %s got %s: ", teststringparsed, cd->content); + result = 0; + DetectContentFree(cd); + } + }else if(cd == NULL){ + printf("expected %s got NULL: ", teststringparsed); + result = 0; + } + return result; +} + +/** + * \test DetectCotentParseTest04 ****BROKEN***** this is a test to make sure we can deal with escaped backslashes + */ +int DetectContentParseTest04 (void) { + int result = 1; + DetectContentData *cd = NULL; + char *teststring = "\"abc\\\\def\""; + char *teststringparsed = "abc\\def"; + cd = DetectContentParse(teststring); + if (cd != NULL) { + printf("expected %s got %s: ", teststringparsed, cd->content); + if(memcmp(cd->content, teststringparsed, sizeof(teststringparsed)) != 0){ + printf("expected %s got %s: ", teststringparsed, cd->content); + result = 0; + DetectContentFree(cd); + } + }else if(cd == NULL){ + printf("expected %s got NULL: ", teststringparsed); + result = 0; + } + return result; +} +/** + * \brief this function registers unit tests for DetectFlow + */ +void DetectContentRegisterTests(void) { + UtRegisterTest("DetectContentParseTest01", DetectContentParseTest01, 1); + UtRegisterTest("DetectContentParseTest02", DetectContentParseTest02, 1); + UtRegisterTest("DetectContentParseTest03", DetectContentParseTest03, 1); + UtRegisterTest("DetectContentParseTest04", DetectContentParseTest04, 1); +}