diff --git a/src/detect-content.c b/src/detect-content.c index d1b4bbae8a..a31200bda5 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -447,7 +447,8 @@ static int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, char *cont sm->type = DETECT_CONTENT; sm->ctx = (void *)cd; - cd->id = DetectContentGetId(de_ctx->mpm_pattern_id_store, cd); + //cd->id = DetectContentGetId(de_ctx->mpm_pattern_id_store, cd); + cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_CONTENT); DetectContentPrint(cd); diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 1c8905e988..315253b0d0 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -1572,7 +1572,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) typedef struct MpmPatternIdTableElmt_ { uint8_t *pattern; /**< ptr to the pattern */ uint16_t pattern_len; /**< pattern len */ - uint32_t id; /**< pattern id */ + PatIntId id; /**< pattern id */ + uint16_t dup_count; /**< duplicate count */ + uint8_t sm_type; /**< SigMatch type */ } MpmPatternIdTableElmt; /** \brief Hash compare func for MpmPatternId api @@ -1587,7 +1589,8 @@ static char MpmPatternIdCompare(void *p1, uint16_t len1, void *p2, uint16_t len2 MpmPatternIdTableElmt *e1 = (MpmPatternIdTableElmt *)p1; MpmPatternIdTableElmt *e2 = (MpmPatternIdTableElmt *)p2; - if (e1->pattern_len != e2->pattern_len) { + if (e1->pattern_len != e2->pattern_len || + e1->sm_type != e2->sm_type) { SCReturnInt(0); } @@ -1735,6 +1738,8 @@ uint32_t DetectUricontentGetId(MpmPatternIdStore *ht, DetectUricontentData *co) BUG_ON(e->pattern == NULL); memcpy(e->pattern, co->uricontent, co->uricontent_len); e->pattern_len = co->uricontent_len; + e->sm_type = DETECT_URICONTENT; + e->dup_count = 1; e->id = 0; r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt)); @@ -1751,6 +1756,7 @@ uint32_t DetectUricontentGetId(MpmPatternIdStore *ht, DetectUricontentData *co) ht->unique_patterns++; } else { id = r->id; + r->dup_count++; ht->shared_patterns++; } @@ -1761,3 +1767,160 @@ uint32_t DetectUricontentGetId(MpmPatternIdStore *ht, DetectUricontentData *co) SCReturnUInt(id); } +/** + * \brief Get the pattern id for a for any content related keyword. + * + * Supported keywords are content, http_client_body, + * http_method, http_uri, http_header, http_cookie. + * + * Please note that you can't use it to get a pattern id for + * uricontent. To retrieve a uricontent pattern id please + * use DetectUricontentGetId(). + * + * \param ht Mpm pattern id hash table store. + * \param ctx The keyword context. + * \param type The SigMatch context. + * + * \retval id Pattern id. + */ +uint32_t DetectPatternGetId(MpmPatternIdStore *ht, void *ctx, uint8_t sm_type) +{ + SCEnter(); + + MpmPatternIdTableElmt *e = NULL; + MpmPatternIdTableElmt *r = NULL; + PatIntId id = 0; + + e = malloc(sizeof(MpmPatternIdTableElmt)); + if (e == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } + + /* if uricontent had used content and content_len as its struct members + * we wouldn't have needed this if/else here */ + if (sm_type == DETECT_URICONTENT) { + DetectUricontentData *ud = ctx; + e->pattern = SCMalloc(ud->uricontent_len); + if (e->pattern == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } + memcpy(e->pattern, ud->uricontent, ud->uricontent_len); + e->pattern_len = ud->uricontent_len; + + /* CONTENT, HTTP_(CLIENT_BODY|METHOD|URI|COOKIE|HEADER) */ + } else { + DetectContentData *cd = ctx; + e->pattern = SCMalloc(cd->content_len); + if (e->pattern == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } + memcpy(e->pattern, cd->content, cd->content_len); + e->pattern_len = cd->content_len; + } + e->dup_count = 1; + e->sm_type = sm_type; + e->id = 0; + + r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt)); + if (r == NULL) { + /* we don't have a duplicate with this pattern + id type. If the id is + * for content, then it is the first entry for such a + * pattern + id combination. Let us create an entry for it */ + if (sm_type == DETECT_CONTENT) { + e->id = ht->max_id; + ht->max_id++; + id = e->id; + + int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt)); + BUG_ON(ret != 0); + + e = NULL; + + /* the id type is not content or uricontent. It would be one of + * those http_ modifiers against content then */ + } else { + /* we know that this is one of those http_ modifiers against content. + * So we would have seen a content before coming across this http_ + * modifier. Let's retrieve this content entry that has already + * been registered. */ + e->sm_type = DETECT_CONTENT; + MpmPatternIdTableElmt *tmp_r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt)); + if (tmp_r == NULL) { + SCLogError(SC_ERR_FATAL, "How can this happen? We have to have " + "a content of type DETECT_CONTENT already registered " + "at this point. Impossible"); + exit(EXIT_FAILURE); + } + + /* we have retrieved the content, and the content registered was the + * first entry made(dup_count is 1) for that content. Let us just + * reset the sm_type to the http_ keyword's sm_type */ + if (tmp_r->dup_count == 1) { + tmp_r->sm_type = sm_type; + id = tmp_r->id; + + /* interestingly we have more than one entry for this content. + * Out of these tmp_r->dup_count entries, one would be for the content + * entry made for this http_ modifier. Erase this entry and make + * a separate entry for the http_ modifier(of course with a new id) */ + } else { + tmp_r->dup_count--; + /* reset the sm_type, since we changed it to DETECT_CONTENT prev */ + e->sm_type = sm_type; + e->id = ht->max_id; + ht->max_id++; + id = e->id; + + int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt)); + BUG_ON(ret != 0); + + e = NULL; + } + } + + /* we do seem to have an entry for this already */ + } else { + /* oh cool! It is a duplicate for content, uricontent types. Update the + * dup_count and get out */ + if (sm_type == DETECT_CONTENT) { + r->dup_count++; + id = r->id; + goto end; + } + + /* uh oh! a duplicate for a http_ modifier type. Let's increase the + * dup_count for the entry */ + r->dup_count++; + id = r->id; + + /* let's get the content entry associated with the http keyword we are + * currently operating on */ + e->sm_type = DETECT_CONTENT; + MpmPatternIdTableElmt *tmp_r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt)); + if (tmp_r == NULL) { + SCLogError(SC_ERR_FATAL, "How can this happen? We have to have " + "a content of type DETECT_CONTENT already registered " + "at this point. Impossible"); + exit(EXIT_FAILURE); + } + /* so there are more than one content keyword entries for this pattern. + * Reduce the dup_count */ + if (tmp_r->dup_count > 1) { + tmp_r->dup_count--; + + /* We have just one entry. Remove this hash table entry */ + } else { + HashTableRemove(ht->hash, tmp_r, sizeof(MpmPatternIdTableElmt)); + ht->max_id--; + } + } + + end: + if (e != NULL) + MpmPatternIdTableElmtFree(e); + + SCReturnUInt(id); +} diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index 5218de8f3c..76f599a7dc 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -61,6 +61,7 @@ void MpmPatternIdTableFreeHash(MpmPatternIdStore *); uint32_t MpmPatternIdStoreGetMaxId(MpmPatternIdStore *); uint32_t DetectContentGetId(MpmPatternIdStore *, DetectContentData *); uint32_t DetectUricontentGetId(MpmPatternIdStore *, DetectUricontentData *); +uint32_t DetectPatternGetId(MpmPatternIdStore *, void *, uint8_t); #endif /* __DETECT_ENGINE_MPM_H__ */ diff --git a/src/detect-http-client-body.c b/src/detect-http-client-body.c index 121fd92611..0fa2d9f260 100644 --- a/src/detect-http-client-body.c +++ b/src/detect-http-client-body.c @@ -248,6 +248,8 @@ int DetectHttpClientBodySetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) DETECT_AL_HTTP_CLIENT_BODY_NOCASE : 0; hcbd->flags |= (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_NEGATED) ? DETECT_AL_HTTP_CLIENT_BODY_NEGATED : 0; + //hcbd->id = ((DetectContentData *)sm->ctx)->id; + hcbd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, hcbd, DETECT_AL_HTTP_CLIENT_BODY); hcbd->bm_ctx = ((DetectContentData *)sm->ctx)->bm_ctx; nm = SigMatchAlloc(); @@ -1770,6 +1772,243 @@ end: return result; } +int DetectHttpClientBodyTest16(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; http_client_body; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpClientBodyData *hcbd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hcbd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpClientBodyTest17(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_client_body; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpClientBodyData *hcbd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hcbd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpClientBodyTest18(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; content:one; http_client_body; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpClientBodyData *hcbd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 0 || hcbd->id != 1) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpClientBodyTest19(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_client_body; content:one; content:one; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpClientBodyData *hcbd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 1 || hcbd->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpClientBodyTest20(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_client_body; " + "content:one; content:one; http_client_body; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpClientBodyData *hcbd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpClientBodyData *hcbd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 1 || hcbd1->id != 0 || hcbd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpClientBodyTest21(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_client_body; " + "content:one; content:one; http_client_body; content:two; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpClientBodyData *hcbd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpClientBodyData *hcbd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 2 || hcbd1->id != 0 || hcbd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} #endif /* UNITTESTS */ @@ -1791,6 +2030,12 @@ void DetectHttpClientBodyRegisterTests(void) UtRegisterTest("DetectHttpClientBodyTest13", DetectHttpClientBodyTest13, 1); UtRegisterTest("DetectHttpClientBodyTest14", DetectHttpClientBodyTest14, 1); UtRegisterTest("DetectHttpClientBodyTest15", DetectHttpClientBodyTest15, 1); + UtRegisterTest("DetectHttpClientBodyTest16", DetectHttpClientBodyTest16, 1); + UtRegisterTest("DetectHttpClientBodyTest17", DetectHttpClientBodyTest17, 1); + UtRegisterTest("DetectHttpClientBodyTest18", DetectHttpClientBodyTest18, 1); + UtRegisterTest("DetectHttpClientBodyTest19", DetectHttpClientBodyTest19, 1); + UtRegisterTest("DetectHttpClientBodyTest20", DetectHttpClientBodyTest20, 1); + UtRegisterTest("DetectHttpClientBodyTest21", DetectHttpClientBodyTest21, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-http-client-body.h b/src/detect-http-client-body.h index a68457cd4d..d654be08ca 100644 --- a/src/detect-http-client-body.h +++ b/src/detect-http-client-body.h @@ -30,8 +30,12 @@ #include "util-spm-bm.h" typedef struct DetectHttpClientBodyData_ { + /* please keep the order of the first 2 members intact, since we use the + * same template obtained from DetectContentData to access these members + * for pattern id retrieval from DetectPatternGetId() */ uint8_t *content; uint8_t content_len; + PatIntId id; uint8_t flags; BmCtx *bm_ctx; } DetectHttpClientBodyData; diff --git a/src/detect-http-cookie.c b/src/detect-http-cookie.c index 955dc89d67..3a280f587d 100644 --- a/src/detect-http-cookie.c +++ b/src/detect-http-cookie.c @@ -144,14 +144,14 @@ int DetectHttpCookieMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, /* call the case insensitive version if nocase has been specified in the sig */ if (co->flags & DETECT_AL_HTTP_COOKIE_NOCASE) { if (SpmNocaseSearch((uint8_t *) bstr_ptr(h->value), bstr_size(h->value), - co->data, co->data_len) != NULL) { + co->content, co->content_len) != NULL) { SCLogDebug("match has been found in received request and given http_" "cookie rule"); ret = 1; } } else { if (SpmSearch((uint8_t *) bstr_ptr(h->value), bstr_size(h->value), - co->data, co->data_len) != NULL) { + co->content, co->content_len) != NULL) { SCLogDebug("match has been found in received request and given http_" "cookie rule"); ret = 1; @@ -178,8 +178,8 @@ void DetectHttpCookieFree(void *ptr) DetectHttpCookieData *hcd = (DetectHttpCookieData *)ptr; if (hcd == NULL) return; - if (hcd->data != NULL) - SCFree(hcd->data); + if (hcd->content != NULL) + SCFree(hcd->content); SCFree(hcd); } @@ -248,13 +248,15 @@ static int DetectHttpCookieSetup (DetectEngineCtx *de_ctx, Signature *s, char *s goto error; memset(hd, 0, sizeof(DetectHttpCookieData)); - hd->data_len = ((DetectContentData *)pm->ctx)->content_len; - hd->data = ((DetectContentData *)pm->ctx)->content; + hd->content_len = ((DetectContentData *)pm->ctx)->content_len; + hd->content = ((DetectContentData *)pm->ctx)->content; hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NOCASE) ? DETECT_AL_HTTP_COOKIE_NOCASE : 0; hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NEGATED) ? DETECT_AL_HTTP_COOKIE_NEGATED : 0; + hd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, hd, DETECT_AL_HTTP_COOKIE); nm->type = DETECT_AL_HTTP_COOKIE; + //hd->id = ((DetectContentData *)pm->ctx)->id; nm->ctx = (void *)hd; /* pull the previous content from the pmatch list, append @@ -477,6 +479,244 @@ end: return result; } +int DetectHttpCookieTest07(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; http_cookie; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpCookieData *hcd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hcd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpCookieTest08(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_cookie; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpCookieData *hcd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hcd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpCookieTest09(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; content:one; http_cookie; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpCookieData *hcd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 0 || hcd->id != 1) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpCookieTest10(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_cookie; content:one; content:one; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpCookieData *hcd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 1 || hcd->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpCookieTest11(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_cookie; " + "content:one; content:one; http_cookie; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpCookieData *hcd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpCookieData *hcd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 1 || hcd1->id != 0 || hcd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpCookieTest12(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_cookie; " + "content:one; content:one; http_cookie; content:two; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpCookieData *hcd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpCookieData *hcd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 2 || hcd1->id != 0 || hcd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + /** \test Check the signature working to alert when http_cookie is matched . */ static int DetectHttpCookieSigTest01(void) { int result = 0; @@ -1123,6 +1363,12 @@ void DetectHttpCookieRegisterTests (void) UtRegisterTest("DetectHttpCookieTest04", DetectHttpCookieTest04, 1); UtRegisterTest("DetectHttpCookieTest05", DetectHttpCookieTest05, 1); UtRegisterTest("DetectHttpCookieTest06", DetectHttpCookieTest06, 1); + UtRegisterTest("DetectHttpCookieTest07", DetectHttpCookieTest07, 1); + UtRegisterTest("DetectHttpCookieTest08", DetectHttpCookieTest08, 1); + UtRegisterTest("DetectHttpCookieTest09", DetectHttpCookieTest09, 1); + UtRegisterTest("DetectHttpCookieTest10", DetectHttpCookieTest10, 1); + UtRegisterTest("DetectHttpCookieTest11", DetectHttpCookieTest11, 1); + UtRegisterTest("DetectHttpCookieTest12", DetectHttpCookieTest12, 1); UtRegisterTest("DetectHttpCookieSigTest01", DetectHttpCookieSigTest01, 1); UtRegisterTest("DetectHttpCookieSigTest02", DetectHttpCookieSigTest02, 1); UtRegisterTest("DetectHttpCookieSigTest03", DetectHttpCookieSigTest03, 1); diff --git a/src/detect-http-cookie.h b/src/detect-http-cookie.h index a29b620c23..df428253f5 100644 --- a/src/detect-http-cookie.h +++ b/src/detect-http-cookie.h @@ -28,8 +28,12 @@ #define DETECT_AL_HTTP_COOKIE_NEGATED 0x02 typedef struct DetectHttpCookieData_ { - uint8_t *data; - uint8_t data_len; + /* please keep the order of the first 2 members intact, since we use the + * same template obtained from DetectContentData to access these members + * for pattern id retrieval from DetectPatternGetId() */ + uint8_t *content; + uint8_t content_len; + PatIntId id; uint8_t flags; } DetectHttpCookieData; diff --git a/src/detect-http-header.c b/src/detect-http-header.c index b3beb62644..e3446c5a26 100644 --- a/src/detect-http-header.c +++ b/src/detect-http-header.c @@ -238,6 +238,8 @@ int DetectHttpHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) DETECT_AL_HTTP_HEADER_NOCASE : 0; hcbd->flags |= (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_NEGATED) ? DETECT_AL_HTTP_HEADER_NEGATED : 0; + //hcbd->id = ((DetectContentData *)sm->ctx)->id; + hcbd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, hcbd, DETECT_AL_HTTP_HEADER); nm = SigMatchAlloc(); if (nm == NULL) { @@ -1313,6 +1315,244 @@ end: return result; } +int DetectHttpHeaderTest14(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpHeaderData *hhd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hhd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpHeaderTest15(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_header; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpHeaderData *hhd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hhd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpHeaderTest16(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; content:one; http_header; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpHeaderData *hhd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 0 || hhd->id != 1) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpHeaderTest17(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_header; content:one; content:one; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpHeaderData *hhd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 1 || hhd->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpHeaderTest18(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_header; " + "content:one; content:one; http_header; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpHeaderData *hhd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpHeaderData *hhd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 1 || hhd1->id != 0 || hhd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpHeaderTest19(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_header; " + "content:one; content:one; http_header; content:two; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpHeaderData *hhd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpHeaderData *hhd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 2 || hhd1->id != 0 || hhd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + #endif /* UNITTESTS */ void DetectHttpHeaderRegisterTests(void) @@ -1331,6 +1571,12 @@ void DetectHttpHeaderRegisterTests(void) UtRegisterTest("DetectHttpHeaderTest11", DetectHttpHeaderTest11, 1); UtRegisterTest("DetectHttpHeaderTest12", DetectHttpHeaderTest12, 1); UtRegisterTest("DetectHttpHeaderTest13", DetectHttpHeaderTest13, 1); + UtRegisterTest("DetectHttpHeaderTest14", DetectHttpHeaderTest14, 1); + UtRegisterTest("DetectHttpHeaderTest15", DetectHttpHeaderTest15, 1); + UtRegisterTest("DetectHttpHeaderTest16", DetectHttpHeaderTest16, 1); + UtRegisterTest("DetectHttpHeaderTest17", DetectHttpHeaderTest17, 1); + UtRegisterTest("DetectHttpHeaderTest18", DetectHttpHeaderTest18, 1); + UtRegisterTest("DetectHttpHeaderTest19", DetectHttpHeaderTest19, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-http-header.h b/src/detect-http-header.h index 5d098a5003..6044515654 100644 --- a/src/detect-http-header.h +++ b/src/detect-http-header.h @@ -28,8 +28,12 @@ #define DETECT_AL_HTTP_HEADER_NEGATED 0x02 typedef struct DetectHttpHeaderData_ { + /* please keep the order of the first 2 members intact, since we use the + * same template obtained from DetectContentData to access these members + * for pattern id retrieval from DetectPatternGetId() */ uint8_t *content; uint8_t content_len; + PatIntId id; uint8_t flags; } DetectHttpHeaderData; diff --git a/src/detect-http-method.c b/src/detect-http-method.c index 5c50194a3e..9cf3254e0b 100644 --- a/src/detect-http-method.c +++ b/src/detect-http-method.c @@ -214,6 +214,7 @@ static int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s, char *st method = bstr_memdup((char *)data->content, data->content_len); /** \todo error check */ data->method = htp_convert_method_to_number(method); + data->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, data, DETECT_AL_HTTP_METHOD); bstr_free(method); nm->type = DETECT_AL_HTTP_METHOD; @@ -398,6 +399,244 @@ int DetectHttpMethodTest05(void) return result; } +int DetectHttpMethodTest06(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; http_method; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpMethodData *hmd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hmd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpMethodTest07(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_method; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpMethodData *hmd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id == hmd->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpMethodTest08(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; content:one; http_method; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpMethodData *hmd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 0 || hmd->id != 1) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpMethodTest09(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_method; content:one; content:one; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpMethodData *hmd = de_ctx->sig_list->amatch_tail->ctx; + if (cd->id != 1 || hmd->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpMethodTest10(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_method; " + "content:one; content:one; http_method; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpMethodData *hmd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpMethodData *hmd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 1 || hmd1->id != 0 || hmd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpMethodTest11(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_method; " + "content:one; content:one; http_method; content:two; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectHttpMethodData *hmd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpMethodData *hmd2 = de_ctx->sig_list->amatch_tail->prev->ctx; + if (cd->id != 2 || hmd1->id != 0 || hmd2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + /** \test Check a signature with an known request method */ static int DetectHttpMethodSigTest01(void) { @@ -699,6 +938,12 @@ void DetectHttpMethodRegisterTests(void) { UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03, 1); UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04, 1); UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05, 1); + UtRegisterTest("DetectHttpMethodTest06", DetectHttpMethodTest06, 1); + UtRegisterTest("DetectHttpMethodTest07", DetectHttpMethodTest07, 1); + UtRegisterTest("DetectHttpMethodTest08", DetectHttpMethodTest08, 1); + UtRegisterTest("DetectHttpMethodTest09", DetectHttpMethodTest09, 1); + UtRegisterTest("DetectHttpMethodTest10", DetectHttpMethodTest10, 1); + UtRegisterTest("DetectHttpMethodTest11", DetectHttpMethodTest11, 1); UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01, 1); UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02, 1); UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03, 1); diff --git a/src/detect-http-method.h b/src/detect-http-method.h index 0df79371fb..f194e94c1a 100644 --- a/src/detect-http-method.h +++ b/src/detect-http-method.h @@ -28,8 +28,12 @@ #define DETECT_AL_HTTP_METHOD_NEGATED 0x02 typedef struct DetectHttpMethodData_ { + /* please keep the order of the first 2 members intact, since we use the + * same template obtained from DetectContentData to access these members + * for pattern id retrieval from DetectPatternGetId() */ uint8_t *content; /**< Raw HTTP method content to match */ - size_t content_len; /**< Raw HTTP method content length */ + uint8_t content_len; /**< Raw HTTP method content length */ + PatIntId id; int method; /**< Numeric HTTP method to match */ uint8_t flags; } DetectHttpMethodData; diff --git a/src/detect-http-uri.c b/src/detect-http-uri.c index fe7501b4eb..5830660ee7 100644 --- a/src/detect-http-uri.c +++ b/src/detect-http-uri.c @@ -143,6 +143,7 @@ static int DetectHttpUriSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) DETECT_URICONTENT_NOCASE : 0; duc->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NEGATED) ? DETECT_URICONTENT_NEGATED : 0; + duc->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, duc, DETECT_URICONTENT); duc->bm_ctx = BoyerMooreCtxInit(duc->uricontent, duc->uricontent_len); nm->type = DETECT_URICONTENT; @@ -349,6 +350,244 @@ end: return result; } +int DetectHttpUriTest06(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; http_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud = de_ctx->sig_list->umatch_tail->ctx; + if (cd->id == ud->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpUriTest07(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_uri; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud = de_ctx->sig_list->umatch_tail->ctx; + if (cd->id == ud->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpUriTest08(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; content:one; http_uri; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud = de_ctx->sig_list->umatch_tail->ctx; + if (cd->id != 0 || ud->id != 1) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpUriTest09(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_uri; content:one; content:one; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud = de_ctx->sig_list->umatch_tail->ctx; + if (cd->id != 1 || ud->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpUriTest10(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_uri; " + "content:one; content:one; http_uri; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud1 = de_ctx->sig_list->umatch_tail->ctx; + DetectUricontentData *ud2 = de_ctx->sig_list->umatch_tail->prev->ctx; + if (cd->id != 1 || ud1->id != 0 || ud2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpUriTest11(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_uri; " + "content:one; content:one; http_uri; content:two; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud1 = de_ctx->sig_list->umatch_tail->ctx; + DetectUricontentData *ud2 = de_ctx->sig_list->umatch_tail->prev->ctx; + if (cd->id != 2 || ud1->id != 0 || ud2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + #endif /* UNITTESTS */ /** @@ -362,6 +601,12 @@ void DetectHttpUriRegisterTests (void) UtRegisterTest("DetectHttpUriTest03", DetectHttpUriTest03, 1); UtRegisterTest("DetectHttpUriTest04", DetectHttpUriTest04, 1); UtRegisterTest("DetectHttpUriTest05", DetectHttpUriTest05, 1); + UtRegisterTest("DetectHttpUriTest06", DetectHttpUriTest06, 1); + UtRegisterTest("DetectHttpUriTest07", DetectHttpUriTest07, 1); + UtRegisterTest("DetectHttpUriTest08", DetectHttpUriTest08, 1); + UtRegisterTest("DetectHttpUriTest09", DetectHttpUriTest09, 1); + UtRegisterTest("DetectHttpUriTest10", DetectHttpUriTest10, 1); + UtRegisterTest("DetectHttpUriTest11", DetectHttpUriTest11, 1); #endif /* UNITTESTS */ } diff --git a/src/detect-uricontent.c b/src/detect-uricontent.c index 822828b070..501831a6f3 100644 --- a/src/detect-uricontent.c +++ b/src/detect-uricontent.c @@ -2112,6 +2112,222 @@ int DetectUriContentParseTest23(void) return result; } +int DetectUricontentSigTest08(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; content:one; http_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud = de_ctx->sig_list->umatch_tail->ctx; + if (cd->id == ud->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectUricontentSigTest09(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(uricontent:one; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud = de_ctx->sig_list->umatch_tail->ctx; + if (cd->id == ud->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectUricontentSigTest10(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(uricontent:one; content:one; content:one; http_uri; " + "content:two; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd1 = de_ctx->sig_list->pmatch_tail->prev->prev->ctx; + DetectContentData *cd2 = de_ctx->sig_list->pmatch_tail->prev->ctx; + DetectContentData *cd3 = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud1 = de_ctx->sig_list->umatch_tail->prev->ctx; + DetectUricontentData *ud2 = de_ctx->sig_list->umatch_tail->ctx; + if (cd1->id != 1 || cd2->id != 2 || cd3->id != 1 || ud1->id != 0 || ud2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectUricontentSigTest11(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_uri; content:one; uricontent:one; " + "content:two; content:one; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd1 = de_ctx->sig_list->pmatch_tail->prev->prev->ctx; + DetectContentData *cd2 = de_ctx->sig_list->pmatch_tail->prev->ctx; + DetectContentData *cd3 = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud1 = de_ctx->sig_list->umatch_tail->prev->ctx; + DetectUricontentData *ud2 = de_ctx->sig_list->umatch_tail->ctx; + if (cd1->id != 1 || cd2->id != 2 || cd3->id != 1 || ud1->id != 0 || ud2->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectUricontentSigTest12(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:one; http_uri; content:one; uricontent:one; " + "content:two; content:one; http_uri; content:one; " + "uricontent:one; uricontent: two; " + "content:one; content:three; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->pmatch == NULL) { + printf("de_ctx->sig_list->pmatch == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->umatch == NULL) { + printf("de_ctx->sig_list->umatch == NULL\n"); + goto end; + } + + DetectContentData *cd1 = de_ctx->sig_list->pmatch_tail->prev->prev->prev->prev->ctx; + DetectContentData *cd2 = de_ctx->sig_list->pmatch_tail->prev->prev->prev->ctx; + DetectContentData *cd3 = de_ctx->sig_list->pmatch_tail->prev->prev->ctx; + DetectContentData *cd4 = de_ctx->sig_list->pmatch_tail->prev->ctx; + DetectContentData *cd5 = de_ctx->sig_list->pmatch_tail->ctx; + DetectUricontentData *ud1 = de_ctx->sig_list->umatch_tail->prev->prev->prev->prev->ctx; + DetectUricontentData *ud2 = de_ctx->sig_list->umatch_tail->prev->prev->prev->ctx; + DetectUricontentData *ud3 = de_ctx->sig_list->umatch_tail->prev->prev->ctx; + DetectUricontentData *ud4 = de_ctx->sig_list->umatch_tail->prev->ctx; + DetectUricontentData *ud5 = de_ctx->sig_list->umatch_tail->ctx; + if (cd1->id != 1 || cd2->id != 2 || cd3->id != 1 || cd4->id != 1 || cd5->id != 4 || + ud1->id != 0 || ud2->id != 0 || ud3->id != 0 || ud4->id != 0 || ud5->id != 3) { + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + #endif /* UNITTESTS */ void HttpUriRegisterTests(void) { @@ -2120,6 +2336,7 @@ void HttpUriRegisterTests(void) { UtRegisterTest("HTTPUriTest02", HTTPUriTest02, 1); UtRegisterTest("HTTPUriTest03", HTTPUriTest03, 1); UtRegisterTest("HTTPUriTest04", HTTPUriTest04, 1); + UtRegisterTest("DetectUriSigTest01", DetectUriSigTest01, 1); UtRegisterTest("DetectUriSigTest02", DetectUriSigTest02, 1); UtRegisterTest("DetectUriSigTest03", DetectUriSigTest03, 1); @@ -2144,5 +2361,10 @@ void HttpUriRegisterTests(void) { UtRegisterTest("DetectUriContentParseTest21", DetectUriContentParseTest21, 1); UtRegisterTest("DetectUriContentParseTest22", DetectUriContentParseTest22, 1); UtRegisterTest("DetectUriContentParseTest23", DetectUriContentParseTest23, 1); + UtRegisterTest("DetectUricontentSigTest08", DetectUricontentSigTest08, 1); + UtRegisterTest("DetectUricontentSigTest09", DetectUricontentSigTest09, 1); + UtRegisterTest("DetectUricontentSigTest10", DetectUricontentSigTest10, 1); + UtRegisterTest("DetectUricontentSigTest11", DetectUricontentSigTest11, 1); + UtRegisterTest("DetectUricontentSigTest12", DetectUricontentSigTest12, 1); #endif /* UNITTESTS */ }