diff --git a/src/Makefile.am b/src/Makefile.am index 5515f785dd..19120566cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,6 +76,7 @@ detect-engine-hhd.c detect-engine-hhd.h \ detect-engine-hrhd.c detect-engine-hrhd.h \ detect-engine-hmd.c detect-engine-hmd.h \ detect-engine-hcd.c detect-engine-hcd.h \ +detect-engine-hrud.c detect-engine-hrud.h \ detect-engine-state.c detect-engine-state.h \ detect-parse.c detect-parse.h \ detect-ack.c detect-ack.h \ @@ -129,6 +130,7 @@ detect-http-method.c detect-http-method.h \ detect-http-header.c detect-http-header.h \ detect-http-raw-header.c detect-http-raw-header.h \ detect-http-uri.c detect-http-uri.h \ +detect-http-raw-uri.c detect-http-raw-uri.h \ detect-tls-version.c detect-tls-version.h \ detect-ssh-proto-version.c detect-ssh-proto-version.h \ detect-ssh-software-version.c detect-ssh-software-version.h \ diff --git a/src/detect-content.h b/src/detect-content.h index 5e1dd55ab3..bbc30da4a8 100644 --- a/src/detect-content.h +++ b/src/detect-content.h @@ -50,6 +50,7 @@ #define DETECT_CONTENT_HRHD_MPM 0x00010000 #define DETECT_CONTENT_HMD_MPM 0x00020000 #define DETECT_CONTENT_HCD_MPM 0x00040000 +#define DETECT_CONTENT_HRUD_MPM 0x00080000 #define DETECT_CONTENT_IS_SINGLE(c) (!((c)->flags & DETECT_CONTENT_DISTANCE || \ (c)->flags & DETECT_CONTENT_WITHIN || \ diff --git a/src/detect-depth.c b/src/detect-depth.c index d55fd5630e..2b3f46b23e 100644 --- a/src/detect-depth.c +++ b/src/detect-depth.c @@ -85,9 +85,10 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths break; default: - pm = SigMatchGetLastSMFromLists(s, 14, + pm = SigMatchGetLastSMFromLists(s, 16, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], @@ -96,8 +97,9 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths if (pm == NULL) { SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs " "preceeding content, uricontent option, http_client_body, " - "http_header option, http_raw_header option or " - "http_method option or http_cookie option"); + "http_header option, http_raw_header option, " + "http_method option, http_cookie or " + "http_raw_uri option"); if (dubbed) SCFree(str); return -1; @@ -106,6 +108,8 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths break; } + /* i swear we will clean this up :). Use a single version for all. Using + * separate versions for all now, to avoiding breaking any code */ switch (pm->type) { case DETECT_URICONTENT: ud = (DetectContentData *)pm->ctx; @@ -316,6 +320,34 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths break; + case DETECT_AL_HTTP_RAW_URI: + cd = (DetectContentData *)pm->ctx; + if (cd->flags & DETECT_CONTENT_NEGATED) { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "negated keyword set along with a fast_pattern"); + goto error; + } + } else { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "keyword set along with a fast_pattern:only;"); + goto error; + } + } + + cd->depth = (uint32_t)atoi(str); + if (cd->depth < cd->content_len) { + cd->depth = cd->content_len; + SCLogDebug("depth increased to %"PRIu32" to match pattern len ", + cd->depth); + } + /* Now update the real limit, as depth is relative to the offset */ + cd->depth += cd->offset; + cd->flags |= DETECT_CONTENT_DEPTH; + + break; + default: SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs a preceeding " "content (or uricontent) option"); diff --git a/src/detect-distance.c b/src/detect-distance.c index 6491b01ded..879f4d242b 100644 --- a/src/detect-distance.c +++ b/src/detect-distance.c @@ -168,9 +168,10 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, } } } else { - pm = SigMatchGetLastSMFromLists(s, 14, + pm = SigMatchGetLastSMFromLists(s, 16, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], @@ -179,8 +180,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, if (pm == NULL) { SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs" "preceeding content, uricontent option, http_client_body, " - "http_header, http_raw_header or http_method or " - "http_cookie option"); + "http_header, http_raw_header, http_method, " + "http_cookie or http_raw_uri option"); if (dubbed) SCFree(str); return -1; @@ -638,6 +639,59 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, break; + case DETECT_AL_HTTP_RAW_URI: + cd = (DetectContentData *)pm->ctx; + if (cd->flags & DETECT_CONTENT_NEGATED) { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "negated keyword set along with a fast_pattern"); + goto error; + } + } else { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "keyword set along with a fast_pattern:only;"); + goto error; + } + } + + cd->distance = strtol(str, NULL, 10); + if (cd->flags & DETECT_CONTENT_WITHIN) { + if ((cd->distance + cd->content_len) > cd->within) { + cd->within = cd->distance + cd->content_len; + } + } + cd->flags |= DETECT_CONTENT_DISTANCE; + + /* reassigning pm */ + pm = SigMatchGetLastSMFromLists(s, 4, + DETECT_AL_HTTP_RAW_URI, pm->prev, + DETECT_PCRE, pm->prev); + if (pm == NULL) { + SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for " + "http_raw_uri needs preceeding http_raw_uri " + "content"); + goto error; + } + + if (pm->type == DETECT_PCRE) { + DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; + tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT; + } else { + /* reassigning cd */ + cd = (DetectContentData *)pm->ctx; + if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword " + "has a fast_pattern:only; set. You can't " + "have relative keywords around a fast_pattern " + "only content"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + } + + break; + default: SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two " "preceeding content or uricontent options"); diff --git a/src/detect-engine-hrud.c b/src/detect-engine-hrud.c new file mode 100644 index 0000000000..03f4b40f41 --- /dev/null +++ b/src/detect-engine-hrud.c @@ -0,0 +1,3875 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** \file + * + * \author Anoop Saldanha + */ + +#include "suricata-common.h" +#include "suricata.h" +#include "decode.h" + +#include "detect.h" +#include "detect-engine.h" +#include "detect-engine-hrud.h" +#include "detect-engine-mpm.h" +#include "detect-parse.h" +#include "detect-engine-state.h" +#include "detect-pcre.h" +#include "detect-isdataat.h" +#include "detect-bytetest.h" +#include "detect-bytejump.h" + +#include "flow-util.h" +#include "util-spm.h" +#include "util-debug.h" +#include "util-print.h" +#include "flow.h" +#include "detect-flow.h" +#include "flow-var.h" +#include "threads.h" +#include "flow-alert-sid.h" + +#include "stream-tcp.h" +#include "stream.h" +#include "app-layer-parser.h" + +#include "util-unittest.h" +#include "util-unittest-helper.h" +#include "app-layer.h" +#include "app-layer-htp.h" +#include "app-layer-protos.h" + +/** + * \brief Run the actual payload match function for http raw uri. + * + * For accounting the last match in relative matching the + * det_ctx->payload_offset var is used. + * + * \param de_ctx Detection engine context. + * \param det_ctx Detection engine thread context. + * \param s Signature to inspect. + * \param sm SigMatch to inspect. + * \param payload Ptr to the http raw uri to inspect. + * \param payload_len Length of the http raw uri. + * + * \retval 0 no match. + * \retval 1 match. + */ +static int DoInspectHttpRawUri(DetectEngineCtx *de_ctx, + DetectEngineThreadCtx *det_ctx, + Signature *s, SigMatch *sm, + uint8_t *payload, uint32_t payload_len) +{ + SCEnter(); + + det_ctx->inspection_recursion_counter++; + + if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { + det_ctx->discontinue_matching = 1; + SCReturnInt(0); + } + + if (sm == NULL) { + SCReturnInt(0); + } + + if (sm->type == DETECT_AL_HTTP_RAW_URI) { + if (payload_len == 0) { + SCReturnInt(0); + } + + DetectContentData *cd = (DetectContentData *)sm->ctx; + + /* disabled to avoid the FP from inspecting multiple transactions */ + //if (cd->flags & DETECT_CONTENT_HRUD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) + // goto match; + + /* rule parsers should take care of this */ +#ifdef DEBUG + BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); +#endif + + /* search for our pattern, checking the matches recursively. + * if we match we look for the next SigMatch as well */ + uint8_t *found = NULL; + uint32_t offset = 0; + uint32_t depth = payload_len; + uint32_t prev_offset = 0; /**< used in recursive searching */ + uint32_t prev_payload_offset = det_ctx->payload_offset; + + do { + if (cd->flags & DETECT_CONTENT_DISTANCE || + cd->flags & DETECT_CONTENT_WITHIN) { + SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); + + offset = prev_payload_offset; + depth = payload_len; + + if (cd->flags & DETECT_CONTENT_DISTANCE) { + if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) + offset = 0; + else + offset += cd->distance; + } + + if (cd->flags & DETECT_CONTENT_WITHIN) { + if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within)) { + depth = prev_payload_offset + cd->within; + } + } + + if (cd->depth != 0) { + if ((cd->depth + prev_payload_offset) < depth) { + depth = prev_payload_offset + cd->depth; + } + } + + if (cd->offset > offset) { + offset = cd->offset; + } + } else { /* implied no relative matches */ + /* set depth */ + if (cd->depth != 0) { + depth = cd->depth; + } + + /* set offset */ + offset = cd->offset; + prev_payload_offset = 0; + } + + /* update offset with prev_offset if we're searching for + * matches after the first occurence. */ + if (prev_offset != 0) + offset = prev_offset; + + if (depth > payload_len) + depth = payload_len; + + /* if offset is bigger than depth we can never match on a pattern. + * We can however, "match" on a negated pattern. */ + if (offset > depth || depth == 0) { + if (cd->flags & DETECT_CONTENT_NEGATED) { + goto match; + } else { + SCReturnInt(0); + } + } + + uint8_t *spayload = payload + offset; + uint32_t spayload_len = depth - offset; + uint32_t match_offset = 0; +#ifdef DEBUG + BUG_ON(spayload_len > payload_len); +#endif + + /* do the actual search with boyer moore precooked ctx */ + if (cd->flags & DETECT_CONTENT_NOCASE) { + found = BoyerMooreNocase(cd->content, cd->content_len, + spayload, spayload_len, + cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); + } else { + found = BoyerMoore(cd->content, cd->content_len, + spayload, spayload_len, + cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); + } + + /* next we evaluate the result in combination with the + * negation flag. */ + if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { + SCReturnInt(0); + } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { + goto match; + } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { + det_ctx->discontinue_matching = 1; + SCReturnInt(0); + } else { + match_offset = (uint32_t)((found - payload) + cd->content_len); + det_ctx->payload_offset = match_offset; + + if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { + SCLogDebug("no relative match coming up, so this is a match"); + goto match; + } + + /* bail out if we have no next match. Technically this is an + * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT + * flag set. */ + if (sm->next == NULL) { + SCReturnInt(0); + } + + /* see if the next payload keywords match. If not, we will + * search for another occurence of this http header content and + * see if the others match then until we run out of matches */ + int r = DoInspectHttpRawUri(de_ctx, det_ctx, s, sm->next, + payload, payload_len); + if (r == 1) { + SCReturnInt(1); + } + + if (det_ctx->discontinue_matching) + SCReturnInt(0); + + /* set the previous match offset to the start of this match + 1 */ + prev_offset = (match_offset - (cd->content_len - 1)); + SCLogDebug("trying to see if there is another match after " + "prev_offset %"PRIu32, prev_offset); + } + + } while(1); + + } else if (sm->type == DETECT_PCRE) { + SCLogDebug("inspecting pcre"); + DetectPcreData *pe = (DetectPcreData *)sm->ctx; + uint32_t prev_payload_offset = det_ctx->payload_offset; + uint32_t prev_offset = 0; + int r = 0; + + det_ctx->pcre_match_start_offset = 0; + do { + r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, + payload, payload_len); + + if (r == 0) { + det_ctx->discontinue_matching = 1; + SCReturnInt(0); + } + + if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { + SCLogDebug("no relative match coming up, so this is a match"); + goto match; + } + + /* save it, in case we need to do a pcre match once again */ + prev_offset = det_ctx->pcre_match_start_offset; + + /* see if the next payload keywords match. If not, we will + * search for another occurence of this pcre and see + * if the others match, until we run out of matches */ + int r = DoInspectHttpRawUri(de_ctx, det_ctx, s, sm->next, + payload, payload_len); + if (r == 1) { + SCReturnInt(1); + } + + if (det_ctx->discontinue_matching) + SCReturnInt(0); + + det_ctx->payload_offset = prev_payload_offset; + det_ctx->pcre_match_start_offset = prev_offset; + } while (1); + + } else if (sm->type == DETECT_ISDATAAT) { + SCLogDebug("inspecting isdataat"); + + DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; + if (id->flags & ISDATAAT_RELATIVE) { + if (det_ctx->payload_offset + id->dataat > payload_len) { + SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len); + if (id->flags & ISDATAAT_NEGATED) + goto match; + SCReturnInt(0); + } else { + SCLogDebug("relative isdataat match"); + if (id->flags & ISDATAAT_NEGATED) + SCReturnInt(0); + goto match; + } + } else { + if (id->dataat < payload_len) { + SCLogDebug("absolute isdataat match"); + if (id->flags & ISDATAAT_NEGATED) + SCReturnInt(0); + goto match; + } else { + SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len); + if (id->flags & ISDATAAT_NEGATED) + goto match; + SCReturnInt(0); + } + } + } else { + /* we should never get here, but bail out just in case */ + SCLogDebug("sm->type %u", sm->type); +#ifdef DEBUG + BUG_ON(1); +#endif + } + + SCReturnInt(0); + +match: + /* this sigmatch matched, inspect the next one. If it was the last, + * the payload portion of the signature matched. */ + if (sm->next != NULL) { + int r = DoInspectHttpRawUri(de_ctx, det_ctx, s, sm->next, payload, + payload_len); + SCReturnInt(r); + } else { + SCReturnInt(1); + } +} + +/** + * \brief Run the mpm against raw http uris. + * + * \retval cnt Number of matches reported by the mpm algo. + */ +int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *det_ctx, Flow *f, + HtpState *htp_state) +{ + SCEnter(); + + uint32_t cnt = 0; + + if (htp_state == NULL) { + SCLogDebug("no HTTP state"); + SCReturnInt(0); + } + + /* locking the flow, we will inspect the htp state */ + SCMutexLock(&f->m); + + if (htp_state->connp == NULL || htp_state->connp->conn == NULL) { + SCLogDebug("HTP state has no conn(p)"); + goto end; + } + + size_t idx = AppLayerTransactionGetInspectId(f); + htp_tx_t *tx = NULL; + + for ( ; idx < list_size(htp_state->connp->conn->transactions); idx++) + { + tx = list_get(htp_state->connp->conn->transactions, idx); + if (tx == NULL || tx->request_uri == NULL) + continue; + + cnt += HttpRawUriPatternSearch(det_ctx, + (uint8_t *)bstr_ptr(tx->request_uri), + bstr_len(tx->request_uri)); + } + +end: + SCMutexUnlock(&f->m); + SCReturnInt(cnt); +} + +/** + * \brief Do the http_raw_uri content inspection for a signature. + * + * \param de_ctx Detection engine context. + * \param det_ctx Detection engine thread context. + * \param s Signature to inspect. + * \param f Flow. + * \param flags App layer flags. + * \param state App layer state. + * + * \retval 0 No match. + * \retval 1 Match. + */ +int DetectEngineInspectHttpRawUri(DetectEngineCtx *de_ctx, + DetectEngineThreadCtx *det_ctx, + Signature *s, Flow *f, uint8_t flags, + void *alstate) +{ + SCEnter(); + + SigMatch *sm = NULL; + int r = 0; + + HtpState *htp_state = (HtpState *)alstate; + if (htp_state == NULL) { + SCLogDebug("no HTTP state"); + SCReturnInt(0); + } + + /* locking the flow, we will inspect the htp state */ + SCMutexLock(&f->m); + + if (htp_state->connp == NULL || htp_state->connp->conn == NULL) { + SCLogDebug("HTP state has no conn(p)"); + goto end; + } + + sm = s->sm_lists[DETECT_SM_LIST_HRUDMATCH]; + +#ifdef DEBUG + DetectContentData *co = (DetectContentData *)sm->ctx; + SCLogDebug("co->id %"PRIu32, co->id); +#endif + + size_t idx = AppLayerTransactionGetInspectId(f); + htp_tx_t *tx = NULL; + + for ( ; idx < list_size(htp_state->connp->conn->transactions); idx++) + { + tx = list_get(htp_state->connp->conn->transactions, idx); + if (tx == NULL || tx->request_uri == NULL) + continue; + + det_ctx->discontinue_matching = 0; + det_ctx->payload_offset = 0; + det_ctx->inspection_recursion_counter = 0; + + /* Inspect all the uricontents fetched on each + * transaction at the app layer */ + r = DoInspectHttpRawUri(de_ctx, det_ctx, s, + s->sm_lists[DETECT_SM_LIST_HRUDMATCH], + (uint8_t *)bstr_ptr(tx->request_uri), + bstr_len(tx->request_uri)); + if (r == 1) { + goto end; + } + } + +end: + SCMutexUnlock(&f->m); + SCReturnInt(r); +} + +/***********************************Unittests**********************************/ + +#ifdef UNITTESTS + +static int DetectEngineHttpRawUriTest01(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/b/../c"; + uint8_t http2_buf[] = + "/./d.html HTTP/1.1\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:../c/./d; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if ((PacketAlertCheck(p1, 1))) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!(PacketAlertCheck(p2, 1))) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest02(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 19\r\n" + "\r\n" + "This is dummy body1"; + uint32_t http1_len = sizeof(http1_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:/c/./d; http_raw_uri; offset:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (!(PacketAlertCheck(p1, 1))) { + printf("sid 1 didn't match but should have\n"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest03(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/b/../"; + uint8_t http2_buf[] = + "c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:/a/b; http_raw_uri; offset:10; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest04(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/b/../"; + uint8_t http2_buf[] = + "c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:!/a/b; http_raw_uri; offset:10; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest05(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/b/"; + uint8_t http2_buf[] = + "../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:a/b; http_raw_uri; depth:10; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest06(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/b/"; + uint8_t http2_buf[] = + "../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:!/a/b; http_raw_uri; depth:25; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest07(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/b/"; + uint8_t http2_buf[] = + "../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:!/c/./d; http_raw_uri; depth:12; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest08(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a/"; + uint8_t http2_buf[] = + "b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:!/c/./d; http_raw_uri; depth:18; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest09(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:/a; http_raw_uri; " + "content:./c/.; http_raw_uri; within:9; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest10(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:/a; http_raw_uri; " + "content:!boom; http_raw_uri; within:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest11(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:./a; http_raw_uri; " + "content:boom; http_raw_uri; within:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest12(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:./a; http_raw_uri; " + "content:!/b/..; http_raw_uri; within:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest13(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:./a; http_raw_uri; " + "content:/c/.; http_raw_uri; distance:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest14(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:./a; http_raw_uri; " + "content:!b/..; http_raw_uri; distance:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest15(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:./a; http_raw_uri; " + "content:/c/; http_raw_uri; distance:7; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest16(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:./a; http_raw_uri; " + "content:!/c/; http_raw_uri; distance:4; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest17(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http1_buf[] = "This_is_dummy_body1"; + uint32_t http1_len = sizeof(http1_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:body1; http_raw_uri; " + "content:bambu; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + /* start the search phase */ + det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); + uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len); + if (r != 1) { + printf("expected 1 result, got %"PRIu32": ", r); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + return result; +} + +static int DetectEngineHttpRawUriTest18(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http1_buf[] = "This_is_dummy_body1"; + uint32_t http1_len = sizeof(http1_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:body1; http_raw_uri; " + "content:bambu; http_raw_uri; fast_pattern; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + /* start the search phase */ + det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); + uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len); + if (r != 0) { + printf("expected 0 result, got %"PRIu32": ", r); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + return result; +} + +static int DetectEngineHttpRawUriTest19(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http1_buf[] = "This_is_dummy_body1"; + uint32_t http1_len = sizeof(http1_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:bambu; http_raw_uri; " + "content:is; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + /* start the search phase */ + det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); + uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len); + if (r != 0) { + printf("expected 0 result, got %"PRIu32": ", r); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + return result; +} + +static int DetectEngineHttpRawUriTest20(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http1_buf[] = "This_is_dummy_body1"; + uint32_t http1_len = sizeof(http1_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "content:bambu; http_raw_uri; " + "content:is; http_raw_uri; fast_pattern; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + /* start the search phase */ + det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); + uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len); + if (r != 2) { + printf("expected 2 result, got %"PRIu32": ", r); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + return result; +} + +static int DetectEngineHttpRawUriTest21(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:!/c/; http_raw_uri; within:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest22(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:!/c/; within:5; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest23(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:!/c/; distance:3; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest24(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:!/c/; distance:10; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest25(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:/c/; within:10; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest26(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:/c/; within:5; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest27(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:/c/; distance:5; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpRawUriTest28(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /../a"; + uint8_t http2_buf[] = + "/b/../c/./d.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 46\r\n" + "\r\n" + "This is dummy body1" + "This is dummy message body2"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p1->flow = &f; + p1->flowflags |= FLOW_PKT_TOSERVER; + p1->flowflags |= FLOW_PKT_ESTABLISHED; + p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http raw uri test\"; " + "pcre:/\\.\\/a/I; " + "content:/c/; distance:10; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: \n"); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if (PacketAlertCheck(p1, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + FlowL7DataPtrFree(&f); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +/** + * \test Test multiple relative contents with a negated content. + */ +static int DetectEngineHttpRawUriTest29(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /../a/b/../c/./d.html HTTP/1.0\r\n" + "User-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p->flow = &f; + p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative raw uri contents\"; " + "content:/c/; http_raw_uri; " + "isdataat:4,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sig 1 didn't alert, but it should have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + +/** + * \test Test multiple relative contents with a negated content. + */ +static int DetectEngineHttpRawUriTest30(void) +{ + int result = 0; + uint8_t *http_buf = (uint8_t *)"POST /../a/b/../c/./d.html HTTP/1.0\r\n" + "User-Agent: Mozilla/1.0\r\n"; + uint32_t http_buf_len = strlen((char *)http_buf); + Flow f; + TcpSession ssn; + HtpState *http_state = NULL; + Packet *p = NULL; + ThreadVars tv; + DetectEngineThreadCtx *det_ctx = NULL; + + memset(&tv, 0, sizeof(ThreadVars)); + memset(&f, 0, sizeof(Flow)); + memset(&ssn, 0, sizeof(TcpSession)); + + p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.src.family = AF_INET; + f.dst.family = AF_INET; + + p->flow = &f; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + FlowL7DataPtrInit(&f); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->mpm_matcher = MPM_B2G; + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"test multiple relative raw uri contents\"; " + "uricontent:/c/; isdataat:!10,relative; sid:1;)"); + if (de_ctx->sig_list == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + goto end; + } + + http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)]; + if (http_state == NULL) { + printf("no http state: "); + goto end; + } + + /* do detect */ + SigMatchSignatures(&tv, de_ctx, det_ctx, p); + + if (!PacketAlertCheck(p, 1)) { + printf("sig 1 didn't alert, but it should have: "); + goto end; + } + + result = 1; + +end: + if (det_ctx != NULL) + DetectEngineThreadCtxDeinit(&tv, det_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePacket(p); + return result; +} + +#endif /* UNITTESTS */ + +void DetectEngineHttpRawUriRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DetectEngineHttpRawUriTest01", + DetectEngineHttpRawUriTest01, 1); + UtRegisterTest("DetectEngineHttpRawUriTest02", + DetectEngineHttpRawUriTest02, 1); + UtRegisterTest("DetectEngineHttpRawUriTest03", + DetectEngineHttpRawUriTest03, 1); + UtRegisterTest("DetectEngineHttpRawUriTest04", + DetectEngineHttpRawUriTest04, 1); + UtRegisterTest("DetectEngineHttpRawUriTest05", + DetectEngineHttpRawUriTest05, 1); + UtRegisterTest("DetectEngineHttpRawUriTest06", + DetectEngineHttpRawUriTest06, 1); + UtRegisterTest("DetectEngineHttpRawUriTest07", + DetectEngineHttpRawUriTest07, 1); + UtRegisterTest("DetectEngineHttpRawUriTest08", + DetectEngineHttpRawUriTest08, 1); + UtRegisterTest("DetectEngineHttpRawUriTest09", + DetectEngineHttpRawUriTest09, 1); + UtRegisterTest("DetectEngineHttpRawUriTest10", + DetectEngineHttpRawUriTest10, 1); + UtRegisterTest("DetectEngineHttpRawUriTest11", + DetectEngineHttpRawUriTest11, 1); + UtRegisterTest("DetectEngineHttpRawUriTest12", + DetectEngineHttpRawUriTest12, 1); + UtRegisterTest("DetectEngineHttpRawUriTest13", + DetectEngineHttpRawUriTest13, 1); + UtRegisterTest("DetectEngineHttpRawUriTest14", + DetectEngineHttpRawUriTest14, 1); + UtRegisterTest("DetectEngineHttpRawUriTest15", + DetectEngineHttpRawUriTest15, 1); + UtRegisterTest("DetectEngineHttpRawUriTest16", + DetectEngineHttpRawUriTest16, 1); + UtRegisterTest("DetectEngineHttpRawUriTest17", + DetectEngineHttpRawUriTest17, 1); + UtRegisterTest("DetectEngineHttpRawUriTest18", + DetectEngineHttpRawUriTest18, 1); + UtRegisterTest("DetectEngineHttpRawUriTest19", + DetectEngineHttpRawUriTest19, 1); + UtRegisterTest("DetectEngineHttpRawUriTest20", + DetectEngineHttpRawUriTest20, 1); + UtRegisterTest("DetectEngineHttpRawUriTest21", + DetectEngineHttpRawUriTest21, 1); + UtRegisterTest("DetectEngineHttpRawUriTest22", + DetectEngineHttpRawUriTest22, 1); + UtRegisterTest("DetectEngineHttpRawUriTest23", + DetectEngineHttpRawUriTest23, 1); + UtRegisterTest("DetectEngineHttpRawUriTest24", + DetectEngineHttpRawUriTest24, 1); + UtRegisterTest("DetectEngineHttpRawUriTest25", + DetectEngineHttpRawUriTest25, 1); + UtRegisterTest("DetectEngineHttpRawUriTest26", + DetectEngineHttpRawUriTest26, 1); + UtRegisterTest("DetectEngineHttpRawUriTest27", + DetectEngineHttpRawUriTest27, 1); + UtRegisterTest("DetectEngineHttpRawUriTest28", + DetectEngineHttpRawUriTest28, 1); + UtRegisterTest("DetectEngineHttpRawUriTest29", + DetectEngineHttpRawUriTest29, 1); + UtRegisterTest("DetectEngineHttpRawUriTest30", + DetectEngineHttpRawUriTest30, 1); +#endif /* UNITTESTS */ + + return; +} diff --git a/src/detect-engine-hrud.h b/src/detect-engine-hrud.h new file mode 100644 index 0000000000..bd6e44c807 --- /dev/null +++ b/src/detect-engine-hrud.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Anoop Saldanha + */ + +#ifndef __DETECT_ENGINE_HRUD_H__ +#define __DETECT_ENGINE_HRUD_H__ + +#include "app-layer-htp.h" + +int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *, + Flow *f, HtpState *); +int DetectEngineInspectHttpRawUri(DetectEngineCtx *, DetectEngineThreadCtx *, + Signature *, Flow *, uint8_t, void *); +void DetectEngineHttpRawUriRegisterTests(void); + +#endif /* __DETECT_ENGINE_HRUD_H__ */ diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index f3402baad2..dcbeb8019b 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -381,6 +381,31 @@ uint32_t HttpCookiePatternSearch(DetectEngineThreadCtx *det_ctx, SCReturnUInt(ret); } +/** + * \brief Http raw uri match -- searches for one pattern per signature. + * + * \param det_ctx Detection engine thread ctx. + * \param uri Raw uri to inspect. + * \param uri_len Raw uri length. + * + * \retval ret Number of matches. + */ +uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *det_ctx, + uint8_t *uri, uint32_t uri_len) +{ + SCEnter(); + + if (det_ctx->sgh->mpm_hrud_ctx == NULL) + SCReturnUInt(0); + + uint32_t ret; + ret = mpm_table[det_ctx->sgh->mpm_hrud_ctx->mpm_type]. + Search(det_ctx->sgh->mpm_hrud_ctx, &det_ctx->mtcu, + &det_ctx->pmq, uri, uri_len); + + SCReturnUInt(ret); +} + /** \brief Pattern match -- searches for only one pattern per signature. * * \param det_ctx detection engine thread ctx @@ -679,6 +704,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, DetectContentData *hrhd = NULL; DetectContentData *hmd = NULL; DetectContentData *hcd = NULL; + DetectContentData *hrud = NULL; switch (mpm_sm->type) { case DETECT_CONTENT: { @@ -1135,6 +1161,61 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, break; } /* case DETECT_AL_HTTP_COOKIE */ + case DETECT_AL_HTTP_RAW_URI: + { + hrud = (DetectContentData *)mpm_sm->ctx; + if (hrud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { + /* add the content to the "hrud" mpm */ + if (hrud->flags & DETECT_CONTENT_NOCASE) { + mpm_table[sgh->mpm_hrud_ctx->mpm_type]. + AddPatternNocase(sgh->mpm_hrud_ctx, + hrud->content + hrud->fp_chop_offset, + hrud->fp_chop_len, + 0, 0, hrud->id, s->num, flags); + } else { + mpm_table[sgh->mpm_hrud_ctx->mpm_type]. + AddPattern(sgh->mpm_hrud_ctx, + hrud->content + hrud->fp_chop_offset, + hrud->fp_chop_len, + 0, 0, hrud->id, s->num, flags); + } + } else { + if (hrud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { + if (DETECT_CONTENT_IS_SINGLE(hrud)) { + hrud->flags |= DETECT_CONTENT_HRUD_MPM; + } + + /* see if we can bypass the match validation for this pattern */ + } else { + if (DETECT_CONTENT_IS_SINGLE(hrud)) { + hrud->flags |= DETECT_CONTENT_HRUD_MPM; + } + } /* else - if (hrud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */ + + /* add the content to the "hrud" mpm */ + if (hrud->flags & DETECT_CONTENT_NOCASE) { + mpm_table[sgh->mpm_hrud_ctx->mpm_type]. + AddPatternNocase(sgh->mpm_hrud_ctx, + hrud->content, hrud->content_len, + 0, 0, hrud->id, s->num, flags); + } else { + mpm_table[sgh->mpm_hrud_ctx->mpm_type]. + AddPattern(sgh->mpm_hrud_ctx, + hrud->content, hrud->content_len, + 0, 0, hrud->id, s->num, flags); + } + } + /* tell matcher we are inspecting raw uri */ + s->flags |= SIG_FLAG_MPM_HRUDCONTENT; + s->mpm_http_pattern_id = hrud->id; + if (hrud->flags & DETECT_CONTENT_NEGATED) + s->flags |= SIG_FLAG_MPM_HRUDCONTENT_NEG; + + sgh->flags |= SIG_GROUP_HEAD_MPM_HRUD; + + break; + } /* case DETECT_AL_HTTP_RAW_URI */ + } /* switch (mpm_sm->type) */ SCLogDebug("%"PRIu32" adding cd->id %"PRIu32" to the mpm phase " @@ -1436,6 +1517,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) uint32_t has_co_hmd = 0; /* used to indicate if sgh has atleast one sig with http_cookie */ uint32_t has_co_hcd = 0; + /* used to indicate if sgh has atleast one sig with http_raw_uri */ + uint32_t has_co_hrud = 0; //uint32_t cnt = 0; uint32_t sig = 0; @@ -1477,6 +1560,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) { has_co_hcd = 1; } + + if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { + has_co_hrud = 1; + } } if (has_co_packet > 0) { @@ -1503,6 +1590,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) if (has_co_hcd > 0) { sh->flags |= SIG_GROUP_HAVEHCDCONTENT; } + if (has_co_hrud > 0) { + sh->flags |= SIG_GROUP_HAVEHRUDCONTENT; + } /* intialize contexes */ if (sh->flags & SIG_GROUP_HAVECONTENT) { @@ -1649,6 +1739,24 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) #endif } + if (sh->flags & SIG_GROUP_HAVEHRUDCONTENT) { + if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { + sh->mpm_hrud_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hrud); + } else { + sh->mpm_hrud_ctx = MpmFactoryGetMpmCtxForProfile(MPM_CTX_FACTORY_UNIQUE_CONTEXT); + } + if (sh->mpm_hrud_ctx == NULL) { + SCLogDebug("sh->mpm_hrud_ctx == NULL. This should never happen"); + exit(EXIT_FAILURE); + } + +#ifndef __SC_CUDA_SUPPORT__ + MpmInitCtx(sh->mpm_hrud_ctx, de_ctx->mpm_matcher, -1); +#else + MpmInitCtx(sh->mpm_hrud_ctx, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle); +#endif + } + if (sh->flags & SIG_GROUP_HAVECONTENT || sh->flags & SIG_GROUP_HAVESTREAMCONTENT || sh->flags & SIG_GROUP_HAVEURICONTENT || @@ -1656,7 +1764,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) sh->flags & SIG_GROUP_HAVEHHDCONTENT || sh->flags & SIG_GROUP_HAVEHRHDCONTENT || sh->flags & SIG_GROUP_HAVEHMDCONTENT || - sh->flags & SIG_GROUP_HAVEHCDCONTENT) { + sh->flags & SIG_GROUP_HAVEHCDCONTENT || + sh->flags & SIG_GROUP_HAVEHRUDCONTENT) { PatternMatchPreparePopulateMpm(de_ctx, sh); @@ -1749,6 +1858,17 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) } } } + if (sh->mpm_hrud_ctx != NULL) { + if (sh->mpm_hrud_ctx->pattern_cnt == 0) { + MpmFactoryReClaimMpmCtx(sh->mpm_hrud_ctx); + sh->mpm_hrud_ctx = NULL; + } else { + if (sh->flags & SIG_GROUP_HAVEHRUDCONTENT) { + if (mpm_table[sh->mpm_hrud_ctx->mpm_type].Prepare != NULL) + mpm_table[sh->mpm_hrud_ctx->mpm_type].Prepare(sh->mpm_hrud_ctx); + } + } + } } /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */ } else { @@ -1768,9 +1888,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) sh->mpm_hmd_ctx = NULL; MpmFactoryReClaimMpmCtx(sh->mpm_hcd_ctx); sh->mpm_hcd_ctx = NULL; + MpmFactoryReClaimMpmCtx(sh->mpm_hrud_ctx); + sh->mpm_hrud_ctx = NULL; } - return 0; } diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index fa6fdaa69a..de804715ab 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -42,6 +42,7 @@ uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); uint32_t HttpMethodPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); uint32_t HttpCookiePatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); +uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *); void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg); diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index a83ec93b9c..103c5af003 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -36,6 +36,7 @@ #include "detect-engine-hrhd.h" #include "detect-engine-hmd.h" #include "detect-engine-hcd.h" +#include "detect-engine-hrud.h" #include "detect-engine-dcepayload.h" #include "stream-tcp.h" @@ -213,7 +214,8 @@ int DeStateUpdateInspectTransactionId(Flow *f, char direction) { */ static void DeStateSignatureAppend(DetectEngineState *state, Signature *s, SigMatch *sm, char uri, char dce, char hcbd, - char hhd, char hrhd, char hmd, char hcd) { + char hhd, char hrhd, char hmd, char hcd, + char hrud) { DeStateStore *store = state->tail; if (store == NULL) { @@ -260,6 +262,9 @@ static void DeStateSignatureAppend(DetectEngineState *state, Signature *s, if (hcd) { store->store[idx].flags |= DE_STATE_FLAG_HCD_MATCH; } + if (hrud) { + store->store[idx].flags |= DE_STATE_FLAG_HRUD_MATCH; + } store->store[idx].nm = sm; state->cnt++; @@ -329,6 +334,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, char hmdmatch = 0; char hcdinspect = 0; char hcdmatch = 0; + char hrudinspect = 0; + char hrudmatch = 0; char dmatch = 0; char dinspect = 0; char appinspect = 0; @@ -396,6 +403,14 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, } SCLogDebug("inspecting http cookie"); } + if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { + hrudinspect = 1; + if (DetectEngineInspectHttpRawUri(de_ctx, det_ctx, s, f, + flags, alstate) == 1) { + hrudmatch = 1; + } + SCLogDebug("inspecting http raw uri"); + } } else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) { @@ -427,8 +442,10 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, } } - appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + hrhdinspect + hmdinspect + hcdinspect; - appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch + hmdmatch + hcdmatch; + appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + + hrhdinspect + hmdinspect + hcdinspect + hrudinspect; + appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch + + hmdmatch + hcdmatch + hrudmatch; if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { for ( ; sm != NULL; sm = sm->next) { @@ -471,8 +488,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, } SCLogDebug("detection done, store results: sm %p, uri %d, dce %d, hcbd %d, " - "hhd %d, hrhd %d hmd %d hcd %d", sm, umatch, dmatch, hcbdmatch, - hhdmatch, hrhdmatch, hmdmatch, hcdmatch); + "hhd %d, hrhd %d hmd %d hcd %d hrud %d", sm, umatch, dmatch, + hcbdmatch, hhdmatch, hrhdmatch, hmdmatch, hcdmatch, hrudmatch); SCMutexLock(&f->de_state_m); /* match or no match, we store the state anyway @@ -484,7 +501,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, if (f->de_state != NULL) { /* \todo shift to an array to transfer these match values*/ DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch, hcbdmatch, - hhdmatch, hrhdmatch, hmdmatch, hcdmatch); + hhdmatch, hrhdmatch, hmdmatch, hcdmatch, hrudmatch); } SCMutexUnlock(&f->de_state_m); @@ -515,6 +532,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete char hmdinspect = 0; char hcdmatch = 0; char hcdinspect = 0; + char hrudmatch = 0; + char hrudinspect = 0; char dmatch = 0; char dinspect = 0; char appinspect = 0; @@ -551,6 +570,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete hmdinspect = 0; hcdmatch = 0; hcdinspect = 0; + hrudmatch = 0; + hrudinspect = 0; dmatch = 0; dinspect = 0; appinspect = 0; @@ -659,6 +680,19 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete } } } + if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { + if (!(item->flags & DE_STATE_FLAG_HRUD_MATCH)) { + SCLogDebug("inspecting http raw uri data"); + hrudinspect = 1; + + if (DetectEngineInspectHttpRawUri(de_ctx, det_ctx, s, f, + flags, alstate) == 1) { + SCLogDebug("http raw uri matched"); + item->flags |= DE_STATE_FLAG_HRUD_MATCH; + hrudmatch = 1; + } + } + } } else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) { @@ -697,8 +731,10 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete } - appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + hrhdinspect + hmdinspect + hcdinspect; - appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch + hmdmatch + hcdmatch; + appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + + hrhdinspect + hmdinspect + hcdinspect + hrudinspect; + appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch + + hmdmatch + hcdmatch + hrudmatch; SCLogDebug("appinspect %d, appmatch %d", appinspect, appmatch); /* next, check the other sig matches */ @@ -838,39 +874,39 @@ static int DeStateTest02(void) { memset(&s, 0x00, sizeof(s)); s.num = 0; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 11; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 22; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 33; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 44; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 55; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 66; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 77; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 88; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 99; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 100; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 111; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 122; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 133; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 144; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 155; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 166; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); if (state->head == NULL) { goto end; @@ -913,9 +949,9 @@ static int DeStateTest03(void) { memset(&s, 0x00, sizeof(s)); s.num = 11; - DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0); s.num = 22; - DeStateSignatureAppend(state, &s, NULL, 1, 0, 0, 0, 0, 0, 0); + DeStateSignatureAppend(state, &s, NULL, 1, 0, 0, 0, 0, 0, 0, 0); if (state->head == NULL) { goto end; diff --git a/src/detect-engine-state.h b/src/detect-engine-state.h index 362ad61ede..9723216b0d 100644 --- a/src/detect-engine-state.h +++ b/src/detect-engine-state.h @@ -52,7 +52,8 @@ #define DE_STATE_FLAG_HRHD_MATCH 0x0020 /**< hrhd payload inspection part matched */ #define DE_STATE_FLAG_HMD_MATCH 0x0040 /**< hmd payload inspection part matched */ #define DE_STATE_FLAG_HCD_MATCH 0x0080 /**< hcd payload inspection part matched */ -#define DE_STATE_FLAG_FULL_MATCH 0x0100 /**< sig already fully matched */ +#define DE_STATE_FLAG_HRUD_MATCH 0x0100 /**< hrud payload inspection part matched */ +#define DE_STATE_FLAG_FULL_MATCH 0x0200 /**< sig already fully matched */ /** per signature detection engine state */ typedef enum { diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index b45f35deac..aa2c8e7363 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -140,6 +140,9 @@ void SupportFastPatternForSigMatchTypes(void) SupportFastPatternForSigMatchType(DETECT_AL_HTTP_COOKIE); SupportFastPatternForSigMatchList(DETECT_SM_LIST_HCDMATCH); + SupportFastPatternForSigMatchType(DETECT_AL_HTTP_RAW_URI); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRUDMATCH); + return; } @@ -210,23 +213,26 @@ static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, char *a s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL && s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] == NULL && s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH] == NULL) { + s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH] == NULL && + s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH] == NULL) { SCLogWarning(SC_WARN_COMPATIBILITY, "fast_pattern found inside the " "rule, without a preceding content based keyword. " "Currently we provide fast_pattern support for content, " "uricontent, http_client_body, http_header, " - "http_raw_header, http_method or http_cookie option"); + "http_raw_header, http_method, http_cookie or " + "http_raw_uri option"); return -1; } - SigMatch *pm = SigMatchGetLastSMFromLists(s, 12, + SigMatch *pm = SigMatchGetLastSMFromLists(s, 16, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]); + DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], + DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]); if (pm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside " "the rule, without a content context. Please use a " @@ -9913,6 +9919,1188 @@ int DetectFastPatternTest342(void) } + + + + + + + + + + + + + + + + + + + +int DetectFastPatternTest343(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_raw_uri; " + "content:!oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_NEGATED && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +/** + * \test Checks if a fast_pattern is registered in a Signature for uricontent. + */ +int DetectFastPatternTest344(void) +{ + SigMatch *sm = NULL; + 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/\"; fast_pattern:only; http_raw_uri; " + "msg:\"Testing fast_pattern\"; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + result = 0; + sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; + if (sm != NULL) { + if ( ((DetectContentData *)sm->ctx)->flags & + DETECT_CONTENT_FAST_PATTERN) { + result = 1; + } else { + result = 0; + } + } + + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +/** + * \test Checks if a fast_pattern is registered in a Signature for uricontent. + */ +int DetectFastPatternTest345(void) +{ + SigMatch *sm = NULL; + 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:oneoneone; fast_pattern:3,4; http_raw_uri; " + "msg:\"Testing fast_pattern\"; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + result = 0; + sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; + if (sm != NULL) { + if ( ((DetectContentData *)sm->ctx)->flags & + DETECT_CONTENT_FAST_PATTERN) { + result = 1; + } else { + result = 0; + } + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest346(void) +{ + SigMatch *sm = NULL; + 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; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + result = 0; + sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; + DetectContentData *ud = sm->ctx; + if (sm != NULL) { + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && + ud->fp_chop_offset == 0 && + ud->fp_chop_len == 0) { + result = 1; + } else { + result = 0; + } + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest347(void) +{ + SigMatch *sm = NULL; + 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:oneoneone; fast_pattern:3,4; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + result = 0; + sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; + DetectContentData *ud = sm->ctx; + if (sm != NULL) { + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest348(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_raw_uri; " + "content:two; fast_pattern:only; http_raw_uri; distance:10; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest349(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_raw_uri; " + "content:two; distance:10; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest350(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_raw_uri; " + "content:two; fast_pattern:only; http_raw_uri; within:10; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest351(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_raw_uri; " + "content:two; within:10; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest352(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_raw_uri; " + "content:two; fast_pattern:only; http_raw_uri; offset:10; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest353(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_raw_uri; " + "content:two; offset:10; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest354(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_raw_uri; " + "content:two; fast_pattern:only; http_raw_uri; depth:10; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest355(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_raw_uri; " + "content:two; depth:10; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest356(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_raw_uri; " + "content:!two; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest357(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_raw_uri; " + "content:two; http_raw_uri; distance:30; " + "content:two; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && + ud->fp_chop_offset == 0 && + ud->fp_chop_len == 0) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest358(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_raw_uri; " + "content:two; http_raw_uri; within:30; " + "content:two; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && + ud->fp_chop_offset == 0 && + ud->fp_chop_len == 0) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest359(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_raw_uri; " + "content:two; http_raw_uri; offset:30; " + "content:two; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && + ud->fp_chop_offset == 0 && + ud->fp_chop_len == 0) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest360(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_raw_uri; " + "content:two; http_raw_uri; depth:30; " + "content:two; fast_pattern:only; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && + ud->fp_chop_offset == 0 && + ud->fp_chop_len == 0) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest361(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; fast_pattern; http_raw_uri; " + "content:two; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_NEGATED && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && + ud->fp_chop_offset == 0 && + ud->fp_chop_len == 0) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest362(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:two; http_raw_uri; " + "content:!one; fast_pattern; http_raw_uri; distance:20; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest363(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:two; http_raw_uri; " + "content:!one; fast_pattern; http_raw_uri; within:20; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest364(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:two; http_raw_uri; " + "content:!one; fast_pattern; http_raw_uri; offset:20; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest365(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:two; http_raw_uri; " + "content:!one; fast_pattern; http_raw_uri; depth:20; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest366(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_raw_uri; " + "content:oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest367(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_raw_uri; " + "content:oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; distance:30; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest368(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_raw_uri; " + "content:oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; within:30; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest369(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_raw_uri; " + "content:oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; offset:30; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest370(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_raw_uri; " + "content:oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; depth:30; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest371(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_raw_uri; " + "content:two; http_raw_uri; distance:10; " + "content:oneonethree; fast_pattern:3,4; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest372(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_raw_uri; " + "content:two; http_raw_uri; within:10; " + "content:oneonethree; fast_pattern:3,4; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest373(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_raw_uri; " + "content:two; http_raw_uri; offset:10; " + "content:oneonethree; fast_pattern:3,4; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest374(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_raw_uri; " + "content:two; http_raw_uri; depth:10; " + "content:oneonethree; fast_pattern:3,4; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest375(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_raw_uri; " + "content:two; fast_pattern:65977,4; http_raw_uri; " + "content:three; http_raw_uri; distance:10; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest376(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_raw_uri; " + "content:oneonetwo; fast_pattern:3,65977; http_raw_uri; " + "content:three; distance:10; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest377(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_raw_uri; " + "content:two; fast_pattern:65534,4; http_raw_uri; " + "content:three; http_raw_uri; distance:10; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest378(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_raw_uri; " + "content:!oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_NEGATED && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest379(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_raw_uri; " + "content:!oneonetwo; fast_pattern:3,4; http_raw_uri; distance:10; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest380(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_raw_uri; " + "content:!oneonetwo; fast_pattern:3,4; http_raw_uri; within:10; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest381(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_raw_uri; " + "content:!oneonetwo; fast_pattern:3,4; http_raw_uri; offset:10; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest382(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_raw_uri; " + "content:!oneonetwo; fast_pattern:3,4; http_raw_uri; depth:10; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectFastPatternTest383(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_raw_uri; " + "content:!oneonetwo; fast_pattern:3,4; http_raw_uri; " + "content:three; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + DetectContentData *ud = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + if (ud->flags & DETECT_CONTENT_FAST_PATTERN && + ud->flags & DETECT_CONTENT_NEGATED && + !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && + ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && + ud->fp_chop_offset == 3 && + ud->fp_chop_len == 4) { + result = 1; + } else { + result = 0; + } + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + #endif void DetectFastPatternRegisterTests(void) @@ -10277,6 +11465,49 @@ void DetectFastPatternRegisterTests(void) UtRegisterTest("DetectFastPatternTest340", DetectFastPatternTest340, 1); UtRegisterTest("DetectFastPatternTest341", DetectFastPatternTest341, 1); UtRegisterTest("DetectFastPatternTest342", DetectFastPatternTest342, 1); + /* http_cookie fast_pattern tests ^ */ + /* http_raw_uri fast_pattern tests v */ + UtRegisterTest("DetectFastPatternTest343", DetectFastPatternTest343, 1); + UtRegisterTest("DetectFastPatternTest344", DetectFastPatternTest344, 1); + UtRegisterTest("DetectFastPatternTest345", DetectFastPatternTest345, 1); + UtRegisterTest("DetectFastPatternTest346", DetectFastPatternTest346, 1); + UtRegisterTest("DetectFastPatternTest347", DetectFastPatternTest347, 1); + UtRegisterTest("DetectFastPatternTest348", DetectFastPatternTest348, 1); + UtRegisterTest("DetectFastPatternTest349", DetectFastPatternTest349, 1); + UtRegisterTest("DetectFastPatternTest350", DetectFastPatternTest350, 1); + UtRegisterTest("DetectFastPatternTest351", DetectFastPatternTest351, 1); + UtRegisterTest("DetectFastPatternTest352", DetectFastPatternTest352, 1); + UtRegisterTest("DetectFastPatternTest353", DetectFastPatternTest353, 1); + UtRegisterTest("DetectFastPatternTest354", DetectFastPatternTest354, 1); + UtRegisterTest("DetectFastPatternTest355", DetectFastPatternTest355, 1); + UtRegisterTest("DetectFastPatternTest356", DetectFastPatternTest356, 1); + UtRegisterTest("DetectFastPatternTest357", DetectFastPatternTest357, 1); + UtRegisterTest("DetectFastPatternTest358", DetectFastPatternTest358, 1); + UtRegisterTest("DetectFastPatternTest359", DetectFastPatternTest359, 1); + UtRegisterTest("DetectFastPatternTest360", DetectFastPatternTest360, 1); + UtRegisterTest("DetectFastPatternTest361", DetectFastPatternTest361, 1); + UtRegisterTest("DetectFastPatternTest362", DetectFastPatternTest362, 1); + UtRegisterTest("DetectFastPatternTest363", DetectFastPatternTest363, 1); + UtRegisterTest("DetectFastPatternTest364", DetectFastPatternTest364, 1); + UtRegisterTest("DetectFastPatternTest365", DetectFastPatternTest365, 1); + UtRegisterTest("DetectFastPatternTest366", DetectFastPatternTest366, 1); + UtRegisterTest("DetectFastPatternTest367", DetectFastPatternTest367, 1); + UtRegisterTest("DetectFastPatternTest368", DetectFastPatternTest368, 1); + UtRegisterTest("DetectFastPatternTest369", DetectFastPatternTest369, 1); + UtRegisterTest("DetectFastPatternTest370", DetectFastPatternTest370, 1); + UtRegisterTest("DetectFastPatternTest371", DetectFastPatternTest371, 1); + UtRegisterTest("DetectFastPatternTest372", DetectFastPatternTest372, 1); + UtRegisterTest("DetectFastPatternTest373", DetectFastPatternTest373, 1); + UtRegisterTest("DetectFastPatternTest374", DetectFastPatternTest374, 1); + UtRegisterTest("DetectFastPatternTest375", DetectFastPatternTest375, 1); + UtRegisterTest("DetectFastPatternTest376", DetectFastPatternTest376, 1); + UtRegisterTest("DetectFastPatternTest377", DetectFastPatternTest377, 1); + UtRegisterTest("DetectFastPatternTest378", DetectFastPatternTest378, 1); + UtRegisterTest("DetectFastPatternTest379", DetectFastPatternTest379, 1); + UtRegisterTest("DetectFastPatternTest380", DetectFastPatternTest380, 1); + UtRegisterTest("DetectFastPatternTest381", DetectFastPatternTest381, 1); + UtRegisterTest("DetectFastPatternTest382", DetectFastPatternTest382, 1); + UtRegisterTest("DetectFastPatternTest383", DetectFastPatternTest383, 1); #endif return; diff --git a/src/detect-http-raw-uri.c b/src/detect-http-raw-uri.c new file mode 100644 index 0000000000..ab287a6a32 --- /dev/null +++ b/src/detect-http-raw-uri.c @@ -0,0 +1,905 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Anoop Saldanha + */ + +#include "suricata-common.h" +#include "threads.h" +#include "debug.h" +#include "decode.h" +#include "detect.h" + +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-mpm.h" +#include "detect-content.h" +#include "detect-pcre.h" + +#include "flow.h" +#include "flow-var.h" + +#include "util-debug.h" +#include "util-unittest.h" +#include "util-spm.h" +#include "util-print.h" + +#include "app-layer.h" + +#include +#include "app-layer-htp.h" +#include "detect-http-raw-uri.h" +#include "stream-tcp.h" + +static int DetectHttpRawUriSetup(DetectEngineCtx *, Signature *, char *); +static void DetectHttpRawUriRegisterTests(void); + +/** + * \brief Registration function for keyword http_raw_uri. + */ +void DetectHttpRawUriRegister(void) +{ + sigmatch_table[DETECT_AL_HTTP_RAW_URI].name = "http_raw_uri"; + sigmatch_table[DETECT_AL_HTTP_RAW_URI].Match = NULL; + sigmatch_table[DETECT_AL_HTTP_RAW_URI].AppLayerMatch = NULL; + sigmatch_table[DETECT_AL_HTTP_RAW_URI].alproto = ALPROTO_HTTP; + sigmatch_table[DETECT_AL_HTTP_RAW_URI].Setup = DetectHttpRawUriSetup; + sigmatch_table[DETECT_AL_HTTP_RAW_URI].Free = NULL; + sigmatch_table[DETECT_AL_HTTP_RAW_URI].RegisterTests = DetectHttpRawUriRegisterTests; + sigmatch_table[DETECT_AL_HTTP_RAW_URI].flags |= SIGMATCH_PAYLOAD; + + return; +} + +/** + * \brief Sets up the http_raw_uri modifier keyword. + * + * \param de_ctx Pointer to the Detection Engine Context. + * \param s Pointer to the Signature to which the current keyword belongs. + * \param arg Should hold an empty string always. + * + * \retval 0 On success. + * \retval -1 On failure. + */ +static int DetectHttpRawUriSetup(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_raw_uri shouldn't be " + "supplied with an argument"); + goto error; + } + + sm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); + if (sm == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "\"http_raw_uri\" keyword " + "found inside the rule without a content context. " + "Please use a \"content\" keyword before using the " + "\"http_raw_uri\" keyword"); + goto error; + } + + cd = (DetectContentData *)sm->ctx; + + /* http_raw_uri should not be used with the rawbytes rule */ + if (cd->flags & DETECT_CONTENT_RAWBYTES) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "http_raw_uri rule can not " + "be used with the rawbytes rule keyword"); + goto error; + } + + 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_AL_HTTP_RAW_URI, + s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], + DETECT_PCRE, + s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]); + if (pm == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "rawuricontent seen with a " + "distance or within without a previous http_raw_uri " + "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_AL_HTTP_RAW_URI); + sm->type = DETECT_AL_HTTP_RAW_URI; + + /* transfer the sm from the pmatch list to hrudmatch list */ + SigMatchTransferSigMatchAcrossLists(sm, + &s->sm_lists[DETECT_SM_LIST_PMATCH], + &s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + &s->sm_lists[DETECT_SM_LIST_HRUDMATCH], + &s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]); + + /* Flagged the signature as to inspect the app layer data */ + s->flags |= SIG_FLAG_APPLAYER; + s->alproto = ALPROTO_HTTP; + + return 0; + +error: + return -1; +} + + +/******************************** UNITESTS **********************************/ + +#ifdef UNITTESTS + +#include "stream-tcp-reassemble.h" + +/** + * \test Checks if a http_raw_uri is registered in a Signature, if content is not + * specified in the signature. + */ +int DetectHttpRawUriTest01(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 tcp any any -> any any " + "(msg:\"Testing http_raw_uri\"; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) + result = 1; + +end: + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + +/** + * \test Checks if a http_raw_uri is registered in a Signature, if some parameter + * is specified with http_raw_uri in the signature. + */ +int DetectHttpRawUriTest02(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 tcp any any -> any any " + "(msg:\"Testing http_raw_uri\"; content:\"one\"; " + "http_raw_uri:wrong; sid:1;)"); + if (de_ctx->sig_list == NULL) + result = 1; + +end: + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + +/** + * \test Checks if a http_raw_uri is registered in a Signature. + */ +int DetectHttpRawUriTest03(void) +{ + SigMatch *sm = NULL; + 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 tcp any any -> any any " + "(msg:\"Testing http_raw_uri\"; " + "content:\"one\"; http_raw_uri; " + "content:\"two\"; http_raw_uri; " + "content:\"three\"; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("sig parse failed: "); + goto end; + } + + sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; + if (sm == NULL) { + printf("no sigmatch(es): "); + goto end; + } + + while (sm != NULL) { + if (sm->type == DETECT_AL_HTTP_RAW_URI) { + result = 1; + } else { + printf("expected DETECT_AL_HTTP_RAW_URI(%d), got %d: ", + DETECT_AL_HTTP_RAW_URI, sm->type); + goto end; + } + sm = sm->next; + } + +end: + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + +/** + * \test Checks if a http_raw_uri is registered in a Signature, when rawbytes is + * also specified in the signature. + */ +int DetectHttpRawUriTest04(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 tcp any any -> any any " + "(msg:\"Testing http_raw_uri\"; " + "content:\"one\"; rawbytes; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + result = 1; + + end: + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + +/** + * \test Checks if a http_raw_uri is successfully converted to a rawuricontent. + * + */ +int DetectHttpRawUriTest05(void) +{ + DetectEngineCtx *de_ctx = NULL; + Signature *s = NULL; + int result = 0; + + if ((de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + s = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_raw_uri\"; " + "content:\"we are testing http_raw_uri keyword\"; http_raw_uri; " + "sid:1;)"); + if (s == NULL) { + printf("sig failed to parse\n"); + goto end; + } + if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) + goto end; + if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH]->type != DETECT_AL_HTTP_RAW_URI) { + printf("wrong type\n"); + goto end; + } + + char *str = "we are testing http_raw_uri keyword"; + int uricomp = memcmp((const char *) + ((DetectContentData*)s->sm_lists[DETECT_SM_LIST_HRUDMATCH]->ctx)->content, + str, + strlen(str) - 1); + int urilen = ((DetectContentData*)s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx)->content_len; + if (uricomp != 0 || + urilen != strlen("we are testing http_raw_uri keyword")) { + printf("sig failed to parse, content not setup properly\n"); + goto end; + } + result = 1; + +end: + if (de_ctx != NULL) + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + SigGroupCleanup(de_ctx); + return result; +} + +int DetectHttpRawUriTest06(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_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *cd = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; + DetectContentData *ud = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (cd->id == ud->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest07(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_raw_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->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *cd = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; + DetectContentData *ud = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (cd->id == ud->id) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest08(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_raw_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->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *cd = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; + DetectContentData *ud = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (cd->id != 0 || ud->id != 1) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest09(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_raw_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->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *cd = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; + DetectContentData *ud = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (cd->id != 1 || ud->id != 0) + goto end; + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest10(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_raw_uri; " + "content:one; " + "content:one; http_raw_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->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *cd = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; + DetectContentData *ud1 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + DetectContentData *ud2 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->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 DetectHttpRawUriTest11(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_raw_uri; " + "content:one; " + "content:one; http_raw_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->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *cd = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; + DetectContentData *ud1 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + DetectContentData *ud2 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->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; +} + +int DetectHttpRawUriTest12(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_raw_uri; " + "content:two; distance:0; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *ud1 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + DetectContentData *ud2 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(ud1->content, "one", ud1->content_len) != 0 || + ud2->flags != DETECT_CONTENT_DISTANCE || + memcmp(ud2->content, "two", ud1->content_len) != 0) { + /* inside body */ + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest13(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_raw_uri; " + "content:two; within:5; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *ud1 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + DetectContentData *ud2 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(ud1->content, "one", ud1->content_len) != 0 || + ud2->flags != DETECT_CONTENT_WITHIN || + memcmp(ud2->content, "two", ud1->content_len) != 0) { + /* inside the body */ + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest14(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; within:5; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list != NULL) { + printf("de_ctx->sig_list != NULL\n"); + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest15(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_raw_uri; within:5; sid:1;)"); + if (de_ctx->sig_list != NULL) { + printf("de_ctx->sig_list != NULL\n"); + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest16(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; within:5; sid:1;)"); + if (de_ctx->sig_list != NULL) { + printf("de_ctx->sig_list != NULL\n"); + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest17(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_raw_uri; " + "content:two; distance:0; http_raw_uri; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *ud1 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + DetectContentData *ud2 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(ud1->content, "one", ud1->content_len) != 0 || + ud2->flags != DETECT_CONTENT_DISTANCE || + memcmp(ud2->content, "two", ud1->content_len) != 0) { + /* inside body */ + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +int DetectHttpRawUriTest18(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_raw_uri; " + "content:two; within:5; http_raw_uri; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); + goto end; + } + + DetectContentData *ud1 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; + DetectContentData *ud2 = + de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; + if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(ud1->content, "one", ud1->content_len) != 0 || + ud2->flags != DETECT_CONTENT_WITHIN || + memcmp(ud2->content, "two", ud1->content_len) != 0) { + /* inside body */ + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +#endif /* UNITTESTS */ + +/** + * \brief Register the UNITTESTS for the http_uri keyword + */ +static void DetectHttpRawUriRegisterTests (void) +{ +#ifdef UNITTESTS /* UNITTESTS */ + UtRegisterTest("DetectHttpRawUriTest01", DetectHttpRawUriTest01, 1); + UtRegisterTest("DetectHttpRawUriTest02", DetectHttpRawUriTest02, 1); + UtRegisterTest("DetectHttpRawUriTest03", DetectHttpRawUriTest03, 1); + UtRegisterTest("DetectHttpRawUriTest04", DetectHttpRawUriTest04, 1); + UtRegisterTest("DetectHttpRawUriTest05", DetectHttpRawUriTest05, 1); + UtRegisterTest("DetectHttpRawUriTest06", DetectHttpRawUriTest06, 1); + UtRegisterTest("DetectHttpRawUriTest07", DetectHttpRawUriTest07, 1); + UtRegisterTest("DetectHttpRawUriTest08", DetectHttpRawUriTest08, 1); + UtRegisterTest("DetectHttpRawUriTest09", DetectHttpRawUriTest09, 1); + UtRegisterTest("DetectHttpRawUriTest10", DetectHttpRawUriTest10, 1); + UtRegisterTest("DetectHttpRawUriTest11", DetectHttpRawUriTest11, 1); + UtRegisterTest("DetectHttpRawUriTest12", DetectHttpRawUriTest12, 1); + UtRegisterTest("DetectHttpRawUriTest13", DetectHttpRawUriTest13, 1); + UtRegisterTest("DetectHttpRawUriTest14", DetectHttpRawUriTest14, 1); + UtRegisterTest("DetectHttpRawUriTest15", DetectHttpRawUriTest15, 1); + UtRegisterTest("DetectHttpRawUriTest16", DetectHttpRawUriTest16, 1); + UtRegisterTest("DetectHttpRawUriTest17", DetectHttpRawUriTest17, 1); + UtRegisterTest("DetectHttpRawUriTest18", DetectHttpRawUriTest18, 1); +#endif /* UNITTESTS */ + + return; +} diff --git a/src/detect-http-raw-uri.h b/src/detect-http-raw-uri.h new file mode 100644 index 0000000000..ee29fb2c76 --- /dev/null +++ b/src/detect-http-raw-uri.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Anoop Saldanha + * + */ + +#ifndef __DETECT_HTTP_URI_H__ +#define __DETECT_HTTP_URI_H__ + +void DetectHttpRawUriRegister(void); + +#endif /* __DETECT_HTTP_URI_H__ */ diff --git a/src/detect-isdataat.c b/src/detect-isdataat.c index fa513a2323..39a1dd66e1 100644 --- a/src/detect-isdataat.c +++ b/src/detect-isdataat.c @@ -280,28 +280,30 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst DETECT_BYTEJUMP, sm->prev, DETECT_PCRE, sm->prev); } else { - pm = SigMatchGetLastSMFromLists(s, 30, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + pm = SigMatchGetLastSMFromLists(s, 34, + DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], /* 1 */ DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], + DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], /* 5 */ DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], + DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], /* 10 */ DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], /* 15 */ + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); if (pm == NULL) { if (idad->flags & ISDATAAT_RELATIVE) { SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen " "without a previous content uricontent, " "http_client_body, http_header, http_raw_header, " - "http_method or http_cookie keyword"); + "http_method, http_cookie or http_raw_uri keyword"); goto error; } else { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); @@ -333,6 +335,9 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst case DETECT_AL_HTTP_COOKIE: list_type = DETECT_SM_LIST_HCDMATCH; break; + case DETECT_AL_HTTP_RAW_URI: + list_type = DETECT_SM_LIST_HRUDMATCH; + break; default: /* would never happen */ break; @@ -360,7 +365,8 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst } else { SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content, pcre, " "uricontent, http_client_body, http_header, " - "http_raw_header, http_method or http_cookie keyword"); + "http_raw_header, http_method, http_cookie or " + "http_raw_uri keyword"); goto error; } } @@ -376,6 +382,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst case DETECT_AL_HTTP_RAW_HEADER: case DETECT_AL_HTTP_METHOD: case DETECT_AL_HTTP_COOKIE: + case DETECT_AL_HTTP_RAW_URI: /* Set the relative next flag on the prev sigmatch */ cd = (DetectContentData *)prev_pm->ctx; if (cd == NULL) { diff --git a/src/detect-nocase.c b/src/detect-nocase.c index b2d9f603c3..c93777a774 100644 --- a/src/detect-nocase.c +++ b/src/detect-nocase.c @@ -181,17 +181,19 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls /* Search for the first previous SigMatch that supports nocase */ //SigMatch *pm = SigMatchGetLastNocasePattern(s); - SigMatch *pm = SigMatchGetLastSMFromLists(s, 14, + SigMatch *pm = SigMatchGetLastSMFromLists(s, 16, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], + DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]); if (pm == NULL) { - SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "\"nocase\" needs a preceeding" - " content, uricontent, http_client_body, http_header, http_method, http_uri, http_cookie option"); + SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "\"nocase\" needs a preceeding " + "content, uricontent, http_client_body, http_header, " + "http_method, http_uri, http_cookie or http_raw_uri option"); SCReturnInt(-1); } @@ -202,6 +204,7 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls DetectContentData *dhhd = NULL; DetectContentData *dhrhd = NULL; DetectContentData *dhmd = NULL; + DetectContentData *dhrud = NULL; switch (pm->type) { case DETECT_URICONTENT: @@ -247,10 +250,16 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls dhcd = (DetectContentData *) pm->ctx; dhcd->flags |= DETECT_CONTENT_NOCASE; break; + case DETECT_AL_HTTP_RAW_URI: + dhrud = (DetectContentData *) pm->ctx; + dhrud->flags |= DETECT_CONTENT_NOCASE; + break; /* should never happen */ default: SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "\"nocase\" needs a" - " preceeding content, uricontent, http_client_body or http_cookie option"); + " preceeding content, uricontent, http_client_body " + "http_header, http_raw_header, http_method, " + "http_cookie, http_raw_uri option"); SCReturnInt(-1); break; } diff --git a/src/detect-offset.c b/src/detect-offset.c index 5cae3068aa..68abd1ee99 100644 --- a/src/detect-offset.c +++ b/src/detect-offset.c @@ -82,19 +82,20 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr) break; default: - pm = SigMatchGetLastSMFromLists(s, 14, + pm = SigMatchGetLastSMFromLists(s, 16, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]); + DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], + DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]); if (pm == NULL) { SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "offset needs" "preceeding content or uricontent option, http_client_body " - "http_header, http_raw_header, http_method or " - "http_cookie option"); + "http_header, http_raw_header, http_method, " + "http_cookie or http_raw_uri option"); if (dubbed) SCFree(str); return -1; @@ -338,6 +339,37 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr) break; + case DETECT_AL_HTTP_RAW_URI: + cd = (DetectContentData *)pm->ctx; + if (cd->flags & DETECT_CONTENT_NEGATED) { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "negated keyword set along with a fast_pattern"); + goto error; + } + } else { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "keyword set along with a fast_pattern:only;"); + goto error; + } + } + + cd->offset = (uint32_t)atoi(str); + if (cd->depth != 0) { + if (cd->depth < cd->content_len) { + SCLogDebug("depth increased to %"PRIu32" to match pattern len", + cd->content_len); + cd->depth = cd->content_len; + } + /* Updating the depth as is relative to the offset */ + cd->depth += cd->offset; + } + + cd->flags |= DETECT_CONTENT_OFFSET; + + break; + default: SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs a preceeding" " content or uricontent option"); diff --git a/src/detect-parse.c b/src/detect-parse.c index 0cad637b26..bc19eaaae5 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -1441,6 +1441,8 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) { sig->flags |= SIG_FLAG_STATE_MATCH; if (sig->sm_lists[DETECT_SM_LIST_HCDMATCH]) sig->flags |= SIG_FLAG_STATE_MATCH; + if (sig->sm_lists[DETECT_SM_LIST_HRUDMATCH]) + sig->flags |= SIG_FLAG_STATE_MATCH; SCLogDebug("sig %"PRIu32" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s", sig->id, sig->flags & SIG_FLAG_APPLAYER ? "set" : "not set", diff --git a/src/detect-pcre.c b/src/detect-pcre.c index ba4d852d70..4230eb506d 100644 --- a/src/detect-pcre.c +++ b/src/detect-pcre.c @@ -842,6 +842,9 @@ DetectPcreData *DetectPcreParse (char *regexstr) case 'H': /* snort's option */ pd->flags |= DETECT_PCRE_HEADER; break; + case 'I': /* snort's option */ + pd->flags |= DETECT_PCRE_HTTP_RAW_URI; + break; case 'D': /* snort's option */ pd->flags |= DETECT_PCRE_RAW_HEADER; break; @@ -1004,7 +1007,8 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst (pd->flags & DETECT_PCRE_HEADER) || (pd->flags & DETECT_PCRE_RAW_HEADER) || (pd->flags & DETECT_PCRE_COOKIE) || - (pd->flags & DETECT_PCRE_HTTP_BODY_AL) ) { + (pd->flags & DETECT_PCRE_HTTP_BODY_AL) || + (pd->flags & DETECT_PCRE_HTTP_RAW_URI) ) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " "DCERPC rule has pcre keyword with http related modifier."); goto error; @@ -1068,6 +1072,16 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst s->alproto = ALPROTO_HTTP; SigMatchAppendUricontent(s, sm); + } else if (pd->flags & DETECT_PCRE_HTTP_RAW_URI) { + s->flags |= SIG_FLAG_APPLAYER; + if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { + SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting" + " keywords."); + goto error; + } + s->alproto = ALPROTO_HTTP; + + SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRUDMATCH); } else { if (s->alproto == ALPROTO_DCERPC && pd->flags & DETECT_PCRE_RELATIVE) { SigMatch *pm = NULL; @@ -1100,12 +1114,13 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst SCReturnInt(0); } - prev_sm = SigMatchGetLastSMFromLists(s, 12, + prev_sm = SigMatchGetLastSMFromLists(s, 14, DETECT_CONTENT, sm->prev, DETECT_URICONTENT, sm->prev, DETECT_AL_HTTP_CLIENT_BODY, sm->prev, DETECT_AL_HTTP_HEADER, sm->prev, DETECT_AL_HTTP_RAW_HEADER, sm->prev, + DETECT_AL_HTTP_RAW_URI, sm->prev, DETECT_PCRE, sm->prev); if (prev_sm == NULL) { if (s->alproto == ALPROTO_DCERPC) { @@ -1128,6 +1143,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst case DETECT_AL_HTTP_CLIENT_BODY: case DETECT_AL_HTTP_HEADER: case DETECT_AL_HTTP_RAW_HEADER: + case DETECT_AL_HTTP_RAW_URI: /* Set the relative next flag on the prev sigmatch */ cd = (DetectContentData *)prev_sm->ctx; if (cd == NULL) { diff --git a/src/detect-pcre.h b/src/detect-pcre.h index 005b4dbb40..ce89aeee4f 100644 --- a/src/detect-pcre.h +++ b/src/detect-pcre.h @@ -40,8 +40,9 @@ #define DETECT_PCRE_RAW_HEADER 0x0200 #define DETECT_PCRE_COOKIE 0x0400 #define DETECT_PCRE_METHOD 0x0800 +#define DETECT_PCRE_HTTP_RAW_URI 0x1000 -#define DETECT_PCRE_NEGATE 0x1000 +#define DETECT_PCRE_NEGATE 0x2000 typedef struct DetectPcreData_ { /* pcre options */ diff --git a/src/detect-within.c b/src/detect-within.c index 1013d1c73a..19fc386bf1 100644 --- a/src/detect-within.c +++ b/src/detect-within.c @@ -171,19 +171,20 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi } } } else { - pm = SigMatchGetLastSMFromLists(s, 14, + pm = SigMatchGetLastSMFromLists(s, 16, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]); + DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], + DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]); if (pm == NULL) { SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs" "preceeding content, uricontent, http_client_body, " - "http_header, http_raw_header, http_method or " - "http_cookie option"); + "http_header, http_raw_header, http_method, " + "http_cookie or http_raw_uri option"); if (dubbed) SCFree(str); return -1; @@ -665,6 +666,60 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi break; + case DETECT_AL_HTTP_RAW_URI: + cd = (DetectContentData *)pm->ctx; + if (cd->flags & DETECT_CONTENT_NEGATED) { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "negated keyword set along with a fast_pattern"); + goto error; + } + } else { + if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative " + "keyword set along with a fast_pattern:only;"); + goto error; + } + } + + cd->within = strtol(str, NULL, 10); + if (cd->within < (int32_t)cd->content_len) { + SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is " + "less than the content length \"%"PRIu32"\" which is invalid, since " + "this will never match. Invalidating signature", cd->within, + cd->content_len); + goto error; + } + cd->flags |= DETECT_CONTENT_WITHIN; + + /* reassigning pm */ + pm = SigMatchGetLastSMFromLists(s, 4, + DETECT_AL_HTTP_RAW_URI, pm->prev, + DETECT_PCRE, pm->prev); + if (pm == NULL) { + SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_raw_uri " + "needs preceeding http_cookie content"); + goto error; + } + + if (pm->type == DETECT_PCRE) { + DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; + tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT; + } else { + /* reassigning cd */ + cd = (DetectContentData *)pm->ctx; + if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword " + "has a fast_pattern:only; set. You can't " + "have relative keywords around a fast_pattern " + "only content"); + goto error; + } + cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; + } + + break; + default: SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two " "preceeding content or uricontent options"); diff --git a/src/detect.c b/src/detect.c index 0d24096502..5f35042b2f 100644 --- a/src/detect.c +++ b/src/detect.c @@ -114,12 +114,14 @@ #include "detect-http-header.h" #include "detect-http-raw-header.h" #include "detect-http-uri.h" +#include "detect-http-raw-uri.h" #include "detect-http-stat-msg.h" #include "detect-engine-hcbd.h" #include "detect-engine-hhd.h" #include "detect-engine-hrhd.h" #include "detect-engine-hmd.h" #include "detect-engine-hcd.h" +#include "detect-engine-hrud.h" #include "util-rule-vars.h" @@ -831,6 +833,16 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx, } } } + + if (s->flags & SIG_FLAG_MPM_HRUDCONTENT) { + if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_http_pattern_id / 8)] & + (1 << (s->mpm_http_pattern_id % 8)))) { + if (!(s->flags & SIG_FLAG_MPM_HRUDCONTENT_NEG)) { + continue; + } + } + } + /* de_state check, filter out all signatures that already had a match before * or just partially match */ if (s->flags & SIG_FLAG_STATE_MATCH) { @@ -1073,6 +1085,10 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx, cnt = DetectEngineRunHttpCookieMpm(det_ctx, p->flow, alstate); SCLogDebug("hcd search: cnt %" PRIu32, cnt); } + if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRUD) { + cnt = DetectEngineRunHttpRawUriMpm(det_ctx, p->flow, alstate); + SCLogDebug("hrud search: cnt %" PRIu32, cnt); + } } } else { SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED"); @@ -1719,6 +1735,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) { if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) return 0; + if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) + return 0; + if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) return 0; @@ -1789,7 +1808,8 @@ static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) { s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL || s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL || s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) + s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL || + s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { SCReturnInt(0); } @@ -1901,6 +1921,11 @@ static int SignatureCreateMask(Signature *s) { SCLogDebug("sig requires http app state"); } + if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { + s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; + SCLogDebug("sig requires http app state"); + } + SigMatch *sm; for (sm = s->sm_lists[DETECT_SM_LIST_AMATCH] ; sm != NULL; sm = sm->next) { switch(sm->type) { @@ -1909,7 +1934,9 @@ static int SignatureCreateMask(Signature *s) { case DETECT_AL_URILEN: case DETECT_AL_HTTP_CLIENT_BODY: case DETECT_AL_HTTP_HEADER: + case DETECT_AL_HTTP_RAW_HEADER: case DETECT_AL_HTTP_URI: + case DETECT_AL_HTTP_RAW_URI: case DETECT_PCRE_HTTPBODY: case DETECT_PCRE_HTTPCOOKIE: case DETECT_PCRE_HTTPHEADER: @@ -1995,6 +2022,9 @@ static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx) de_ctx->sgh_mpm_context_hcd = MpmFactoryRegisterMpmCtxProfile("hcd", MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); + de_ctx->sgh_mpm_context_hrud = + MpmFactoryRegisterMpmCtxProfile("hrud", + MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); de_ctx->sgh_mpm_context_app_proto_detect = MpmFactoryRegisterMpmCtxProfile("app_proto_detect", 0); @@ -3892,6 +3922,12 @@ int SigGroupBuild (DetectEngineCtx *de_ctx) { } //printf("hcd- %d\n", mpm_ctx->pattern_cnt); + mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hrud); + if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { + mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); + } + //printf("hrud- %d\n", mpm_ctx->pattern_cnt); + mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_stream); if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); @@ -3985,6 +4021,7 @@ void SigTableSetup(void) { DetectHttpRawHeaderRegister(); DetectHttpClientBodyRegister(); DetectHttpUriRegister(); + DetectHttpRawUriRegister(); DetectAsn1Register(); DetectSshVersionRegister(); DetectSslStateRegister(); diff --git a/src/detect.h b/src/detect.h index fee18953ff..014406a1dd 100644 --- a/src/detect.h +++ b/src/detect.h @@ -83,6 +83,7 @@ struct SCSigSignatureWrapper_; enum { DETECT_SM_LIST_MATCH = 0, DETECT_SM_LIST_PMATCH, + /* list for http_uri keyword and the ones relative to it */ DETECT_SM_LIST_UMATCH, DETECT_SM_LIST_AMATCH, DETECT_SM_LIST_DMATCH, @@ -97,6 +98,8 @@ enum { DETECT_SM_LIST_HMDMATCH, /* list for http_cookie keyword and the ones relative to it */ DETECT_SM_LIST_HCDMATCH, + /* list for http_raw_uri keyword and the ones relative to it */ + DETECT_SM_LIST_HRUDMATCH, DETECT_SM_LIST_MAX, }; @@ -253,7 +256,10 @@ typedef struct DetectPort_ { #define SIG_FLAG_MPM_HCDCONTENT 0x08000000 #define SIG_FLAG_MPM_HCDCONTENT_NEG 0x10000000 -#define SIG_FLAG_REQUIRE_FLOWVAR 0x20000000 /**< signature can only match if a flowbit, flowvar or flowint is available. */ +#define SIG_FLAG_MPM_HRUDCONTENT 0x20000000 +#define SIG_FLAG_MPM_HRUDCONTENT_NEG 0x40000000 + +#define SIG_FLAG_REQUIRE_FLOWVAR 0x80000000 /**< signature can only match if a flowbit, flowvar or flowint is available. */ /* signature init flags */ #define SIG_FLAG_DEONLY 0x00000001 /**< decode event only signature */ @@ -661,6 +667,7 @@ typedef struct DetectEngineCtx_ { int32_t sgh_mpm_context_hrhd; int32_t sgh_mpm_context_hmd; int32_t sgh_mpm_context_hcd; + int32_t sgh_mpm_context_hrud; int32_t sgh_mpm_context_app_proto_detect; /** sgh for signatures that match against invalid packets. In those cases @@ -819,19 +826,21 @@ typedef struct SigTableElmt_ { #define SIG_GROUP_HAVEHRHDCONTENT 0x00000020 #define SIG_GROUP_HAVEHMDCONTENT 0x00000040 #define SIG_GROUP_HAVEHCDCONTENT 0x00000080 -#define SIG_GROUP_HEAD_MPM_COPY 0x00000100 -#define SIG_GROUP_HEAD_MPM_URI_COPY 0x00000200 -#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x00000400 -#define SIG_GROUP_HEAD_FREE 0x00000800 -#define SIG_GROUP_HEAD_MPM_PACKET 0x00001000 -#define SIG_GROUP_HEAD_MPM_STREAM 0x00002000 -#define SIG_GROUP_HEAD_MPM_URI 0x00004000 -#define SIG_GROUP_HEAD_MPM_HCBD 0x00008000 -#define SIG_GROUP_HEAD_MPM_HHD 0x00010000 -#define SIG_GROUP_HEAD_MPM_HRHD 0x00020000 -#define SIG_GROUP_HEAD_MPM_HMD 0x00040000 -#define SIG_GROUP_HEAD_MPM_HCD 0x00080000 -#define SIG_GROUP_HEAD_REFERENCED 0x00100000 /**< sgh is being referenced by others, don't clear */ +#define SIG_GROUP_HAVEHRUDCONTENT 0x00000100 +#define SIG_GROUP_HEAD_MPM_COPY 0x00000200 +#define SIG_GROUP_HEAD_MPM_URI_COPY 0x00000400 +#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x00000800 +#define SIG_GROUP_HEAD_FREE 0x00001000 +#define SIG_GROUP_HEAD_MPM_PACKET 0x00002000 +#define SIG_GROUP_HEAD_MPM_STREAM 0x00004000 +#define SIG_GROUP_HEAD_MPM_URI 0x00008000 +#define SIG_GROUP_HEAD_MPM_HCBD 0x00010000 +#define SIG_GROUP_HEAD_MPM_HHD 0x00020000 +#define SIG_GROUP_HEAD_MPM_HRHD 0x00040000 +#define SIG_GROUP_HEAD_MPM_HMD 0x00080000 +#define SIG_GROUP_HEAD_MPM_HCD 0x00100000 +#define SIG_GROUP_HEAD_MPM_HRUD 0x00200000 +#define SIG_GROUP_HEAD_REFERENCED 0x00400000 /**< sgh is being referenced by others, don't clear */ typedef struct SigGroupHeadInitData_ { /* list of content containers @@ -877,6 +886,7 @@ typedef struct SigGroupHead_ { MpmCtx *mpm_hrhd_ctx; MpmCtx *mpm_hmd_ctx; MpmCtx *mpm_hcd_ctx; + MpmCtx *mpm_hrud_ctx; uint16_t mpm_streamcontent_maxlen; uint16_t mpm_uricontent_maxlen; @@ -980,6 +990,7 @@ enum { DETECT_AL_HTTP_HEADER, DETECT_AL_HTTP_RAW_HEADER, DETECT_AL_HTTP_URI, + DETECT_AL_HTTP_RAW_URI, DETECT_AL_HTTP_STAT_MSG, DETECT_AL_HTTP_STAT_CODE, DETECT_AL_SSH_PROTOVERSION, diff --git a/src/suricata.c b/src/suricata.c index 10ecc1b1e6..a667a77c1b 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -59,6 +59,7 @@ #include "detect-engine-hrhd.h" #include "detect-engine-hmd.h" #include "detect-engine-hcd.h" +#include "detect-engine-hrud.h" #include "detect-engine-state.h" #include "detect-engine-tag.h" #include "detect-fast-pattern.h" @@ -1168,6 +1169,7 @@ int main(int argc, char **argv) DetectEngineHttpRawHeaderRegisterTests(); DetectEngineHttpMethodRegisterTests(); DetectEngineHttpCookieRegisterTests(); + DetectEngineHttpRawUriRegisterTests(); DetectEngineRegisterTests(); SCLogRegisterTests(); if (list_unittests) {