/** * \brief This function is used to add the parsed "http_method" option * into the current signature. * * \param de_ctx Pointer to the Detection Engine Context. * \param s Pointer to the Current Signature. * \param str Pointer to the user provided option string. * * \retval 0 on Success. * \retval -1 on Failure. */ static int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) { SCEnter(); DetectContentData *cd = NULL; if ((str != NULL) && (strcmp(str, "") != 0)) { SCLogError(SC_ERR_INVALID_ARGUMENT, "http_method does not take an argument"); SCReturnInt(-1); } if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { SCLogError(SC_ERR_HTTP_METHOD_NEEDS_PRECEEDING_CONTENT, "http_method " "modifies preceding \"content\", but none was found"); SCReturnInt(-1); } SigMatch *sm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); if (sm == NULL) { SCLogError(SC_ERR_HTTP_METHOD_NEEDS_PRECEEDING_CONTENT, "http_method " "modifies preceding \"content\", but none was found"); SCReturnInt(-1); } cd = (DetectContentData *)sm->ctx; if (cd->flags & DETECT_CONTENT_RAWBYTES) { SCLogError(SC_ERR_HTTP_METHOD_INCOMPATIBLE_WITH_RAWBYTES, "http_method " "cannot be used with \"rawbytes\""); SCReturnInt(-1); } if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains keywords" "that conflict with http_method"); goto error; } if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) { SigMatch *pm = SigMatchGetLastSMFromLists(s, 4, DETECT_CONTENT, sm->prev, DETECT_PCRE, sm->prev); if (pm != NULL) { /* pm is never NULL. So no NULL check */ if (pm->type == DETECT_CONTENT) { DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT; } else { DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; tmp_pd->flags &= ~DETECT_PCRE_RELATIVE_NEXT; } } /* if (pm != NULL) */ /* please note. reassigning pm */ pm = SigMatchGetLastSMFromLists(s, 4, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]); if (pm == NULL) { SCLogError(SC_ERR_HTTP_METHOD_RELATIVE_MISSING, "http_method with " "a distance or within requires preceding http_method " "content, but none was found"); goto error; } if (pm->type == DETECT_PCRE) { DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT; } else { DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; } } cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_SM_LIST_HMDMATCH); sm->type = DETECT_CONTENT; /* transfer the sm from the pmatch list to hmdmatch list */ SigMatchTransferSigMatchAcrossLists(sm, &s->sm_lists[DETECT_SM_LIST_PMATCH], &s->sm_lists_tail[DETECT_SM_LIST_PMATCH], &s->sm_lists[DETECT_SM_LIST_HMDMATCH], &s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]); /* flag the signature to indicate that we scan the app layer data */ s->flags |= SIG_FLAG_APPLAYER; s->alproto = ALPROTO_HTTP; SCReturnInt(0); error: SCReturnInt(-1); }
static int DetectHttpStatMsgSetup (DetectEngineCtx *de_ctx, Signature *s, char *arg) { DetectContentData *cd = NULL; SigMatch *sm = NULL; if (arg != NULL && strcmp(arg, "") != 0) { SCLogError(SC_ERR_INVALID_ARGUMENT, "http_stat_msg supplied with args"); return -1; } sm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); /* if still we are unable to find any content previous keywords, it is an * invalid rule */ if (sm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "\"http_stat_msg\" keyword " "found inside the rule without a content context. " "Please use a \"content\" keyword before using the " "\"http_stat_msg\" keyword"); return -1; } cd = (DetectContentData *)sm->ctx; /* http_stat_msg should not be used with the rawbytes rule */ if (cd->flags & DETECT_CONTENT_RAWBYTES) { SCLogError(SC_ERR_INVALID_SIGNATURE, "http_stat_msg rule can not " "be used with the rawbytes rule keyword"); return -1; } if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http " "alproto set"); goto error; } if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) { SigMatch *pm = SigMatchGetLastSMFromLists(s, 4, DETECT_CONTENT, sm->prev, DETECT_PCRE, sm->prev); /* pm can be NULL now. To accomodate parsing sigs like - * content:one; http_modifier; content:two; distance:0; http_modifier */ if (pm != NULL) { if (pm->type == DETECT_CONTENT) { DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT; } else { DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; tmp_pd->flags &= ~ DETECT_PCRE_RELATIVE_NEXT; } } /* if (pm != NULL) */ /* reassigning pm */ pm = SigMatchGetLastSMFromLists(s, 4, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]); if (pm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "http_stat_msg seen with a " "distance or within without a previous http_stat_msg " "content. Invalidating signature."); goto error; } if (pm->type == DETECT_PCRE) { DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT; } else { DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; } } cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_SM_LIST_HSMDMATCH); sm->type = DETECT_CONTENT; /* transfer the sm from the pmatch list to hcbdmatch list */ SigMatchTransferSigMatchAcrossLists(sm, &s->sm_lists[DETECT_SM_LIST_PMATCH], &s->sm_lists_tail[DETECT_SM_LIST_PMATCH], &s->sm_lists[DETECT_SM_LIST_HSMDMATCH], &s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]); /* flag the signature to indicate that we scan the app layer data */ s->flags |= SIG_FLAG_APPLAYER; s->alproto = ALPROTO_HTTP; return 0; error: return -1; }
static int DetectHttpCookieSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { DetectContentData *cd = NULL; SigMatch *sm = NULL; if (str != NULL && strcmp(str, "") != 0) { SCLogError(SC_ERR_INVALID_ARGUMENT, "http_cookie shouldn't be supplied " "with an argument"); return -1; } if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { SCLogError(SC_ERR_HTTP_COOKIE_NEEDS_PRECEEDING_CONTENT, "http_cookie " "found inside the rule, without any preceding content keywords"); return -1; } sm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); if (sm == NULL) { SCLogWarning(SC_ERR_HTTP_COOKIE_NEEDS_PRECEEDING_CONTENT, "http_cookie " "found inside the rule, without a content context. Please use a " "content keyword before using http_cookie"); return -1; } cd = (DetectContentData *)sm->ctx; /* http_cookie should not be used with the rawbytes rule */ if (cd->flags & DETECT_CONTENT_RAWBYTES) { SCLogError(SC_ERR_HTTP_COOKIE_INCOMPATIBLE_WITH_RAWBYTES, "http_cookie " "rule can not be used with the rawbytes rule keyword"); return -1; } if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains keywords" "that conflict with http_cookie"); goto error; } if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) { SigMatch *pm = SigMatchGetLastSMFromLists(s, 4, DETECT_CONTENT, sm->prev, DETECT_PCRE, sm->prev); if (pm != NULL) { /* pm is never NULL. So no NULL check */ if (pm->type == DETECT_CONTENT) { DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT; } else { DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; tmp_pd->flags &= ~DETECT_PCRE_RELATIVE_NEXT; } } /* if (pm != NULL) */ /* please note. reassigning pm */ pm = SigMatchGetLastSMFromLists(s, 4, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]); if (pm == NULL) { SCLogError(SC_ERR_HTTP_COOKIE_RELATIVE_MISSING, "http_cookie with " "a distance or within requires preceding http_cookie " "content, but none was found"); goto error; } if (pm->type == DETECT_PCRE) { DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT; } else { DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; } } cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_SM_LIST_HCDMATCH); sm->type = DETECT_CONTENT; /* transfer the sm from the pmatch list to hcdmatch list */ SigMatchTransferSigMatchAcrossLists(sm, &s->sm_lists[DETECT_SM_LIST_PMATCH], &s->sm_lists_tail[DETECT_SM_LIST_PMATCH], &s->sm_lists[DETECT_SM_LIST_HCDMATCH], &s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]); /* flag the signature to indicate that we scan the app layer data */ s->flags |= SIG_FLAG_APPLAYER; s->alproto = ALPROTO_HTTP; return 0; error: return -1; }