From 19d701ddf07d855128ded0cf2b573ce468e3bdd6 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Wed, 20 Jan 2016 01:10:01 +0000 Subject: Removing Suricata and Audit from source repo, and updated build.sh to avoid building suricata. Will re-address this in C release via tar balls. Change-Id: I3710076f8b7f3313cb3cb5260c4eb0a6834d4f6e Signed-off-by: Ashlee Young --- framework/src/suricata/src/detect-pcre.c | 4193 ------------------------------ 1 file changed, 4193 deletions(-) delete mode 100644 framework/src/suricata/src/detect-pcre.c (limited to 'framework/src/suricata/src/detect-pcre.c') diff --git a/framework/src/suricata/src/detect-pcre.c b/framework/src/suricata/src/detect-pcre.c deleted file mode 100644 index d69f1da6..00000000 --- a/framework/src/suricata/src/detect-pcre.c +++ /dev/null @@ -1,4193 +0,0 @@ -/* Copyright (C) 2007-2013 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 Victor Julien - * - * Implements the pcre keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "pkt-var.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "detect-pcre.h" -#include "detect-flowvar.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-sigorder.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "util-var-name.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-print.h" -#include "util-pool.h" - -#include "conf.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "stream.h" -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" - -#include "stream.h" - - -#define PARSE_CAPTURE_REGEX "\\(\\?P\\<([A-z]+)\\_([A-z0-9_]+)\\>" -#define PARSE_REGEX "(?ctx; - - if (pe->flags & DETECT_PCRE_RELATIVE) { - ptr = payload + det_ctx->buffer_offset; - len = payload_len - det_ctx->buffer_offset; - } else { - ptr = payload; - len = payload_len; - } - - int start_offset = 0; - if (det_ctx->pcre_match_start_offset != 0) { - start_offset = (payload + det_ctx->pcre_match_start_offset - ptr); - } - - /* run the actual pcre detection */ - ret = pcre_exec(pe->re, pe->sd, (char *)ptr, len, start_offset, 0, ov, MAX_SUBSTRINGS); - SCLogDebug("ret %d (negating %s)", ret, (pe->flags & DETECT_PCRE_NEGATE) ? "set" : "not set"); - - if (ret == PCRE_ERROR_NOMATCH) { - if (pe->flags & DETECT_PCRE_NEGATE) { - /* regex didn't match with negate option means we - * consider it a match */ - ret = 1; - } else { - ret = 0; - } - } else if (ret >= 0) { - if (pe->flags & DETECT_PCRE_NEGATE) { - /* regex matched but we're negated, so not - * considering it a match */ - ret = 0; - } else { - /* regex matched and we're not negated, - * considering it a match */ - - SCLogDebug("ret %d capidx %u", ret, pe->capidx); - - /* see if we need to do substring capturing. */ - if (ret > 1 && pe->capidx != 0) { - SCLogDebug("capturing"); - const char *str_ptr; - ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (ret) { - if (pe->flags & DETECT_PCRE_CAPTURE_PKT) { - if (p != NULL) { - PktVarAdd(p, pe->capname, (uint8_t *)str_ptr, ret); - } - } else if (pe->flags & DETECT_PCRE_CAPTURE_FLOW) { - if (f != NULL) { - /* store max 64k. Errors are ignored */ - capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff; - (void)DetectFlowvarStoreMatch(det_ctx, pe->capidx, - (uint8_t *)str_ptr, capture_len, - DETECT_FLOWVAR_TYPE_POSTMATCH); - } - } - } - } - - /* update offset for pcre RELATIVE */ - det_ctx->buffer_offset = (ptr + ov[1]) - payload; - det_ctx->pcre_match_start_offset = (ptr + ov[0] + 1) - payload; - - ret = 1; - } - - } else { - SCLogDebug("pcre had matching error"); - ret = 0; - } - SCReturnInt(ret); -} - -static int DetectPcreSetList(int list, int set) -{ - if (list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "only one pcre option to specify a buffer type is allowed"); - return -1; - } - return set; -} - -static int DetectPcreHasUpperCase(const char *re) -{ - size_t len = strlen(re); - int is_meta = 0; - - for (size_t i = 0; i < len; i++) { - if (is_meta) { - is_meta = 0; - } - else if (re[i] == '\\') { - is_meta = 1; - } - else if (isupper((unsigned char)re[i])) { - return 1; - } - } - - return 0; -} - -static DetectPcreData *DetectPcreParse (DetectEngineCtx *de_ctx, char *regexstr, int *sm_list) -{ - int ec; - const char *eb; - int eo; - int opts = 0; - DetectPcreData *pd = NULL; - char *op = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - size_t slen = strlen(regexstr); - char re[slen], op_str[64] = ""; - uint16_t pos = 0; - uint8_t negate = 0; - - while (pos < slen && isspace((unsigned char)regexstr[pos])) { - pos++; - } - - if (regexstr[pos] == '!') { - negate = 1; - pos++; - } - - ret = pcre_exec(parse_regex, parse_regex_study, regexstr + pos, slen-pos, - 0, 0, ov, MAX_SUBSTRINGS); - if (ret <= 0) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre parse error: %s", regexstr); - goto error; - } - - res = pcre_copy_substring((char *)regexstr + pos, ov, MAX_SUBSTRINGS, - 1, re, slen); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return NULL; - } - - if (ret > 2) { - res = pcre_copy_substring((char *)regexstr + pos, ov, MAX_SUBSTRINGS, - 2, op_str, sizeof(op_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return NULL; - } - op = op_str; - } - //printf("ret %" PRId32 " re \'%s\', op \'%s\'\n", ret, re, op); - - pd = SCMalloc(sizeof(DetectPcreData)); - if (unlikely(pd == NULL)) - goto error; - memset(pd, 0, sizeof(DetectPcreData)); - - if (negate) - pd->flags |= DETECT_PCRE_NEGATE; - - if (op != NULL) { - while (*op) { - SCLogDebug("regex option %c", *op); - - switch (*op) { - case 'A': - opts |= PCRE_ANCHORED; - break; - case 'E': - opts |= PCRE_DOLLAR_ENDONLY; - break; - case 'G': - opts |= PCRE_UNGREEDY; - break; - - case 'i': - opts |= PCRE_CASELESS; - pd->flags |= DETECT_PCRE_CASELESS; - break; - case 'm': - opts |= PCRE_MULTILINE; - break; - case 's': - opts |= PCRE_DOTALL; - break; - case 'x': - opts |= PCRE_EXTENDED; - break; - - case 'O': - pd->flags |= DETECT_PCRE_MATCH_LIMIT; - break; - - case 'B': /* snort's option */ - if (*sm_list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'B' inconsistent with chosen buffer"); - goto error; - } - pd->flags |= DETECT_PCRE_RAWBYTES; - break; - case 'R': /* snort's option */ - pd->flags |= DETECT_PCRE_RELATIVE; - break; - - /* buffer selection */ - - case 'U': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'U' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_UMATCH); - break; - case 'V': - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'V' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HUADMATCH); - break; - case 'W': - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'W' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HHHDMATCH); - break; - case 'Z': - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'Z' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HRHHDMATCH); - break; - case 'H': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'H' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HHDMATCH); - break; - case 'I': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'I' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HRUDMATCH); - break; - case 'D': /* snort's option */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HRHDMATCH); - break; - case 'M': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'M' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HMDMATCH); - break; - case 'C': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'C' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HCDMATCH); - break; - case 'P': - /* snort's option (http request body inspection) */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HCBDMATCH); - break; - case 'Q': - /* suricata extension (http response body inspection) */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_FILEDATA); - break; - case 'Y': - /* snort's option */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HSMDMATCH); - break; - case 'S': - /* snort's option */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HSCDMATCH); - break; - default: - SCLogError(SC_ERR_UNKNOWN_REGEX_MOD, "unknown regex modifier '%c'", *op); - goto error; - } - op++; - } - } - if (*sm_list == -1) - goto error; - - SCLogDebug("DetectPcreParse: \"%s\"", re); - - /* host header */ - if (*sm_list == DETECT_SM_LIST_HHHDMATCH) { - if (pd->flags & DETECT_PCRE_CASELESS) { - SCLogWarning(SC_ERR_INVALID_SIGNATURE, "http host pcre(\"W\") " - "specified along with \"i(caseless)\" modifier. " - "Since the hostname buffer we match against " - "is actually lowercase, having a " - "nocase is redundant."); - } - else if (DetectPcreHasUpperCase(re)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre host(\"W\") " - "specified has an uppercase char. " - "Since the hostname buffer we match against " - "is actually lowercase, please specify an " - "all lowercase based pcre."); - goto error; - } - } - - /* Try to compile as if all (...) groups had been meant as (?:...), - * which is the common case in most rules. - * If we fail because a capture group is later referenced (e.g., \1), - * PCRE will let us know. - */ - pd->re = pcre_compile2(re, opts | PCRE_NO_AUTO_CAPTURE, &ec, &eb, &eo, NULL); - if (pd->re == NULL && ec == 15) { // reference to non-existent subpattern - pd->re = pcre_compile(re, opts, &eb, &eo, NULL); - } - - if(pd->re == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", regexstr, eo, eb); - goto error; - } -#ifdef PCRE_HAVE_JIT - pd->sd = pcre_study(pd->re, PCRE_STUDY_JIT_COMPILE, &eb); - if(eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed : %s", eb); - goto error; - } - - int jit = 0; - ret = pcre_fullinfo(pd->re, pd->sd, PCRE_INFO_JIT, &jit); - if (ret != 0 || jit != 1) { - /* warning, so we won't print the sig after this. Adding - * file and line to the message so the admin can figure - * out what sig this is about */ - SCLogDebug("PCRE JIT compiler does not support: %s. " - "Falling back to regular PCRE handling (%s:%d)", - regexstr, de_ctx->rule_file, de_ctx->rule_line); - } -#else - pd->sd = pcre_study(pd->re, 0, &eb); - if(eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed : %s", eb); - goto error; - } -#endif /*PCRE_HAVE_JIT*/ - - if (pd->sd == NULL) - pd->sd = (pcre_extra *) SCCalloc(1,sizeof(pcre_extra)); - - if (pd->sd) { - if(pd->flags & DETECT_PCRE_MATCH_LIMIT) { - if(pcre_match_limit >= -1) { - pd->sd->match_limit = pcre_match_limit; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT; - } -#ifndef NO_PCRE_MATCH_RLIMIT - if(pcre_match_limit_recursion >= -1) { - pd->sd->match_limit_recursion = pcre_match_limit_recursion; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - } -#endif /* NO_PCRE_MATCH_RLIMIT */ - } else { - pd->sd->match_limit = SC_MATCH_LIMIT_DEFAULT; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT; -#ifndef NO_PCRE_MATCH_RLIMIT - pd->sd->match_limit_recursion = SC_MATCH_LIMIT_RECURSION_DEFAULT; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; -#endif /* NO_PCRE_MATCH_RLIMIT */ - } - } else { - goto error; - } - - return pd; - -error: - if (pd != NULL && pd->re != NULL) - pcre_free(pd->re); - if (pd != NULL && pd->sd != NULL) - pcre_free(pd->sd); - if (pd) - SCFree(pd); - return NULL; -} - -/** \internal - * \brief check if we need to extract capture settings and set them up if needed - */ -static int DetectPcreParseCapture(char *regexstr, DetectEngineCtx *de_ctx, DetectPcreData *pd) -{ - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char type_str[16] = ""; - size_t cap_buffer_len = strlen(regexstr); - char capture_str[cap_buffer_len]; - memset(capture_str, 0x00, cap_buffer_len); - - if (de_ctx == NULL) - goto error; - - SCLogDebug("\'%s\'", regexstr); - - ret = pcre_exec(parse_capture_regex, parse_capture_regex_study, regexstr, strlen(regexstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3) { - return 0; - } - - res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS, 1, type_str, sizeof(type_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS, 2, capture_str, cap_buffer_len); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - if (strlen(capture_str) == 0 || strlen(type_str) == 0) { - goto error; - } - - SCLogDebug("type \'%s\'", type_str); - SCLogDebug("capture \'%s\'", capture_str); - - pd->capname = SCStrdup(capture_str); - if (unlikely(pd->capname == NULL)) - goto error; - - if (strcmp(type_str, "pkt") == 0) { - pd->flags |= DETECT_PCRE_CAPTURE_PKT; - } else if (strcmp(type_str, "flow") == 0) { - pd->flags |= DETECT_PCRE_CAPTURE_FLOW; - SCLogDebug("flow capture"); - } - if (pd->capname != NULL) { - if (pd->flags & DETECT_PCRE_CAPTURE_PKT) - pd->capidx = VariableNameGetIdx(de_ctx, (char *)pd->capname, VAR_TYPE_PKT_VAR); - else if (pd->flags & DETECT_PCRE_CAPTURE_FLOW) - pd->capidx = VariableNameGetIdx(de_ctx, (char *)pd->capname, VAR_TYPE_FLOW_VAR); - } - - SCLogDebug("pd->capname %s", pd->capname); - return 0; - -error: - if (pd->capname != NULL) { - SCFree(pd->capname); - pd->capname = NULL; - } - return -1; -} - -static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexstr) -{ - SCEnter(); - DetectPcreData *pd = NULL; - SigMatch *sm = NULL; - int ret = -1; - int parsed_sm_list = DETECT_SM_LIST_NOTSET; - - pd = DetectPcreParse(de_ctx, regexstr, &parsed_sm_list); - if (pd == NULL) - goto error; - if (DetectPcreParseCapture(regexstr, de_ctx, pd) < 0) - goto error; - - if (parsed_sm_list == DETECT_SM_LIST_UMATCH || - parsed_sm_list == DETECT_SM_LIST_HRUDMATCH || - parsed_sm_list == DETECT_SM_LIST_HCBDMATCH || - parsed_sm_list == DETECT_SM_LIST_FILEDATA || - parsed_sm_list == DETECT_SM_LIST_HHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HRHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HSMDMATCH || - parsed_sm_list == DETECT_SM_LIST_HSCDMATCH || - parsed_sm_list == DETECT_SM_LIST_HHHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HRHHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HMDMATCH || - parsed_sm_list == DETECT_SM_LIST_HCDMATCH || - parsed_sm_list == DETECT_SM_LIST_HUADMATCH) - { - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " - "Conflicting alprotos detected for this rule. Http " - "pcre modifier found along with a different protocol " - "for the rule."); - goto error; - } - if (s->list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre found with http " - "modifier set, with file_data/dce_stub_data sticky " - "option set."); - goto error; - } - } - - int sm_list = -1; - if (s->list != DETECT_SM_LIST_NOTSET) { - if (s->list == DETECT_SM_LIST_FILEDATA) { - SCLogDebug("adding to http server body list because of file data"); - AppLayerHtpEnableResponseBodyCallback(); - } else if (s->list == DETECT_SM_LIST_DMATCH) { - SCLogDebug("adding to dmatch list because of dce_stub_data"); - } else if (s->list == DETECT_SM_LIST_DNSQUERYNAME_MATCH) { - SCLogDebug("adding to DETECT_SM_LIST_DNSQUERYNAME_MATCH list because of dns_query"); - } - s->flags |= SIG_FLAG_APPLAYER; - sm_list = s->list; - } else { - switch(parsed_sm_list) { - case DETECT_SM_LIST_HCBDMATCH: - AppLayerHtpEnableRequestBodyCallback(); - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_HTTP; - sm_list = parsed_sm_list; - break; - - case DETECT_SM_LIST_FILEDATA: - AppLayerHtpEnableResponseBodyCallback(); - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_HTTP; - sm_list = parsed_sm_list; - break; - - case DETECT_SM_LIST_UMATCH: - case DETECT_SM_LIST_HRUDMATCH: - case DETECT_SM_LIST_HHDMATCH: - case DETECT_SM_LIST_HRHDMATCH: - case DETECT_SM_LIST_HHHDMATCH: - case DETECT_SM_LIST_HRHHDMATCH: - case DETECT_SM_LIST_HSMDMATCH: - case DETECT_SM_LIST_HSCDMATCH: - case DETECT_SM_LIST_HCDMATCH: - case DETECT_SM_LIST_HMDMATCH: - case DETECT_SM_LIST_HUADMATCH: - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_HTTP; - sm_list = parsed_sm_list; - break; - case DETECT_SM_LIST_NOTSET: - sm_list = DETECT_SM_LIST_PMATCH; - break; - } - } - if (sm_list == -1) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->type = DETECT_PCRE; - sm->ctx = (void *)pd; - SigMatchAppendSMToList(s, sm, sm_list); - - if (pd->capidx != 0) { - if (DetectFlowvarPostMatchSetup(s, pd->capidx) < 0) - goto error_nofree; - } - - if (!(pd->flags & DETECT_PCRE_RELATIVE)) - goto okay; - - /* errors below shouldn't free pd */ - - SigMatch *prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, sm->prev, - DETECT_PCRE, sm->prev); - if (s->list == DETECT_SM_LIST_NOTSET && prev_pm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre with /R (relative) needs " - "preceeding match in the same buffer"); - goto error_nofree; - /* null is allowed when we use a sticky buffer */ - } else if (prev_pm == NULL) - goto okay; - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *tmp = (DetectPcreData *)prev_pm->ctx; - tmp->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - okay: - ret = 0; - SCReturnInt(ret); - error: - DetectPcreFree(pd); - error_nofree: - SCReturnInt(ret); -} - -void DetectPcreFree(void *ptr) -{ - if (ptr == NULL) - return; - - DetectPcreData *pd = (DetectPcreData *)ptr; - - if (pd->capname != NULL) - SCFree(pd->capname); - if (pd->re != NULL) - pcre_free(pd->re); - if (pd->sd != NULL) - pcre_free(pd->sd); - - SCFree(pd); - return; -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectPcreParseTest01 make sure we don't allow invalid opts 7. - */ -static int DetectPcreParseTest01 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/7"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd != NULL) { - printf("expected NULL: got %p", pd); - result = 0; - DetectPcreFree(pd); - } - - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest02 make sure we don't allow invalid opts Ui$. - */ -static int DetectPcreParseTest02 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/Ui$"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd != NULL) { - printf("expected NULL: got %p", pd); - result = 0; - DetectPcreFree(pd); - } - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest03 make sure we don't allow invalid opts UZi. - */ -static int DetectPcreParseTest03 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/UNi"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd != NULL) { - printf("expected NULL: got %p", pd); - result = 0; - DetectPcreFree(pd); - } - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest04 make sure we allow escaped " - */ -static int DetectPcreParseTest04 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b\\\"lah/i"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest05 make sure we parse pcre with no opts - */ -static int DetectPcreParseTest05 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b(l|a)h/"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest06 make sure we parse pcre with smi opts - */ -static int DetectPcreParseTest06 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b(l|a)h/smi"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest07 make sure we parse pcre with /Ui opts - */ -static int DetectPcreParseTest07 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/Ui"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest08 make sure we parse pcre with O opts - */ -static int DetectPcreParseTest08 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b(l|a)h/O"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest09 make sure we parse pcre with a content - * that has slashes - */ -static int DetectPcreParseTest09 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/lala\\\\/"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Test pcre option for dce sig(yeah I'm bored of writing test titles). - */ -int DetectPcreParseTest10(void) -{ - Signature *s = SigAlloc(); - int result = 1; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - result = 0; - goto end; - } - - s->alproto = ALPROTO_DCERPC; - - result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - SigFree(s); - - s = SigAlloc(); - /* failure since we have no preceding content/pcre/bytejump */ - result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - end: - SigFree(s); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option for dce sig. - */ -int DetectPcreParseTest11(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "pcre:/bamboo/R; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_PCRE); - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "pcre:/bamboo/R; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_PCRE); - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "pcre:/bamboo/RB; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_PCRE); - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (!(data->flags & DETECT_PCRE_RAWBYTES) || - !(data->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; pcre:/bamboo/; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option with file data. pcre is relative to file_data, - * so relative flag should be unset. - */ -static int DetectPcreParseTest12(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; pcre:/abc/R; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_PCRE) { - printf("last sm not pcre: "); - goto end; - } - - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - printf("flags not right: "); - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option with file data. - */ -static int DetectPcreParseTest13(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; content:\"abc\"; pcre:/def/R; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_PCRE) { - printf("last sm not pcre: "); - goto end; - } - - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - printf("flags not right: "); - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option with file data. - */ -static int DetectPcreParseTest14(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; pcre:/def/; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_PCRE) { - printf("last sm not pcre: "); - goto end; - } - - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - data->flags & DETECT_PCRE_RELATIVE) { - printf("flags not right: "); - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Check a signature with pcre relative method */ -int DetectPcreParseTest15(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 pcre relative http_method\"; " - "content:\"GET\"; " - "http_method; pcre:\"/abc/RM\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - - -/** \test Check a signature with pcre relative cookie */ -int DetectPcreParseTest16(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 pcre relative http_cookie\"; " - "content:\"test\"; " - "http_cookie; pcre:\"/abc/RC\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative raw header */ -int DetectPcreParseTest17(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 pcre relative http_raw_header\"; " - "flow:to_server; content:\"test\"; " - "http_raw_header; pcre:\"/abc/RD\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative header */ -int DetectPcreParseTest18(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 pcre relative http_header\"; " - "content:\"test\"; " - "http_header; pcre:\"/abc/RH\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative client-body */ -int DetectPcreParseTest19(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 pcre relativie http_client_body\"; " - "content:\"test\"; " - "http_client_body; pcre:\"/abc/RP\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative raw uri */ -int DetectPcreParseTest20(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:\"test\"; " - "http_raw_uri; pcre:\"/abc/RI\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative uricontent */ -int DetectPcreParseTest21(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 pcre relative uricontent\"; " - "uricontent:\"test\"; " - "pcre:\"/abc/RU\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative http_uri */ -int DetectPcreParseTest22(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 pcre relative http_uri\"; " - "content:\"test\"; " - "http_uri; pcre:\"/abc/RU\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre relative */ -int DetectPcreParseTest23(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 inconsistent pcre relative\"; " - "content:\"GET\"; " - "http_cookie; pcre:\"/abc/RM\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse shouldn't have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre modifiers */ -int DetectPcreParseTest24(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 inconsistent pcre modifiers\"; " - "pcre:\"/abc/UI\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre modifiers */ -int DetectPcreParseTest25(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 inconsistent pcre modifiers\"; " - "pcre:\"/abc/DH\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre modifiers */ -static int DetectPcreParseTest26(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 http any any -> any any " - "(msg:\"Testing inconsistent pcre modifiers\"; " - "pcre:\"/abc/F\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Bug 1098 */ -static int DetectPcreParseTest27(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 80 " - "(content:\"baduricontent\"; http_raw_uri; " - "pcre:\"/^[a-z]{5}\\.html/R\"; sid:2; rev:2;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectPcreTestSig01Real(int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - Flow f; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(TcpSession)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/^gEt/i\"; pcre:\"/\\/two\\//U; pcre:\"/GET \\/two\\//\"; pcre:\"/\\s+HTTP/R\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, buf, buflen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 1) { - result = 1; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} -static int DetectPcreTestSig01B2g (void) -{ - return DetectPcreTestSig01Real(MPM_B2G); -} -static int DetectPcreTestSig01B3g (void) -{ - return DetectPcreTestSig01Real(MPM_B3G); -} -static int DetectPcreTestSig01Wm (void) -{ - return DetectPcreTestSig01Real(MPM_WUMANBER); -} - -static int DetectPcreTestSig02Real(int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - Flow f; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - - FLOW_INITIALIZE(&f); - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - pcre_match_limit = 100; - pcre_match_limit_recursion = 100; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/two/O\"; sid:2;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 2) == 1) { - result = 1; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - FLOW_DESTROY(&f); -end: - UTHFreePackets(&p, 1); - return result; -} -static int DetectPcreTestSig02B2g (void) -{ - return DetectPcreTestSig02Real(MPM_B2G); -} -static int DetectPcreTestSig02B3g (void) -{ - return DetectPcreTestSig02Real(MPM_B3G); -} -static int DetectPcreTestSig02Wm (void) -{ - return DetectPcreTestSig02Real(MPM_WUMANBER); -} - -/** - * \test DetectPcreTestSig03Real negation test ! outside of "" this sig should not match - */ -static int DetectPcreTestSig03Real(int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 1; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - result = 0; - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"GET\"; pcre:!\"/two/\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)){ - printf("sid 1 matched even though it shouldn't have:"); - result = 0; - } - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} - -static int DetectPcreTestSig03B2g (void) -{ - return DetectPcreTestSig03Real(MPM_B2G); -} -static int DetectPcreTestSig03B3g (void) -{ - return DetectPcreTestSig03Real(MPM_B3G); -} -static int DetectPcreTestSig03Wm (void) -{ - return DetectPcreTestSig03Real(MPM_WUMANBER); -} - -/** - * \test Check the signature with pcre modifier P (match with L7 to http body data) - */ -static int DetectPcreModifPTest04(void) -{ - int result = 0; - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "X-Powered-By: PHP/5.2.5\r\n" - "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n" - "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n" - "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" - "Pragma: no-cache\r\n" - "Keep-Alive: timeout=15, max=100\r\n" - "Connection: Keep-Alive\r\n" - "Transfer-Encoding: chunked\r\n" - "Content-Type: text/html; charset=utf-8\r\n" - "\r\n" - "15" - "\r\n" - "flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"Pcre modifier P\"; pcre:\"/DOCTYPE/P\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"" - "Pcre modifier P (no match)\"; pcre:\"/blah/P\"; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sid 2 matched but shouldn't: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Check the signature with pcre modifier P (match with L7 to http body data) - * over fragmented chunks (DOCTYPE fragmented) - */ -static int DetectPcreModifPTest05(void) -{ - int result = 0; - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "X-Powered-By: PHP/5.2.5\r\n" - "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n" - "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n" - "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" - "Pragma: no-cache\r\n" - "Keep-Alive: timeout=15, max=100\r\n" - "Connection: Keep-Alive\r\n" - "Transfer-Encoding: chunked\r\n" - "Content-Type: text/html; charset=utf-8\r\n" - "\r\n" - "15" - "\r\n" - "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); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"Pcre modifier P\"; pcre:\"/DOC/P\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"" - "Pcre modifier P (no match)\"; pcre:\"/DOCTYPE/P\"; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - if (PacketAlertCheck(p1, 2)) { - printf("sid 2 did match on p1 but shouldn't have: "); - /* It's a partial match over 2 chunks*/ - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect for p2 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 did match on p2 but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p2, 2))) { - printf("sid 2 didn't match on p2 but should have: "); - /* It's a partial match over 2 chunks*/ - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -int DetectPcreTestSig06() -{ - uint8_t *buf = (uint8_t *) - "lalala lalala\\ lala\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/ lalala\\\\/\"; sid:1;)"; - if (UTHPacketMatchSig(p, sig) == 0) { - result = 0; - goto end; - } - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test anchored pcre */ -int DetectPcreTestSig07() -{ - uint8_t *buf = (uint8_t *) - "lalala\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)"; - if (UTHPacketMatchSig(p, sig) == 0) { - result = 0; - goto end; - } - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test anchored pcre */ -int DetectPcreTestSig08() -{ - /* test it also without ending in a newline "\n" */ - uint8_t *buf = (uint8_t *) - "lalala"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)"; - if (UTHPacketMatchSig(p, sig) == 0) { - result = 0; - goto end; - } - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test Check the signature working to alert when cookie modifier is - * passed to pcre - */ -static int DetectPcreTestSig09(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; pcre:\"/dummy/C\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when cookie modifier is - * passed to a negated pcre - */ -static int DetectPcreTestSig10(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummoOOooooO\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; pcre:!\"/dummy/C\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 should match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when method modifier is - * passed to pcre - */ -static int DetectPcreTestSig11(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP method\"; pcre:\"/POST/M\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when method modifier is - * passed to a negated pcre - */ -static int DetectPcreTestSig12(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummoOOooooO\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP method\"; pcre:!\"/POST/M\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 should match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when header modifier is - * passed to pcre - */ -static int DetectPcreTestSig13(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP header\"; pcre:\"/User[-_]Agent[:]?\\sMozilla/H\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when header modifier is - * passed to a negated pcre - */ -static int DetectPcreTestSig14(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: IEXPLORER/1.0\r\n" - "Cookie: dummoOOooooO\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP header\"; pcre:!\"/User-Agent[:]?\\s+Mozilla/H\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 should match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when cookie and relative modifiers are - * passed to pcre - */ -static int DetectPcreTestSig15(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy 1234\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"pcre relative HTTP cookie\"; content:\"dummy\";" - " http_cookie; pcre:\"/1234/RC\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when method and relative modifiers are - * passed to pcre - */ -static int DetectPcreTestSig16(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy 1234\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"pcre relative HTTP method\"; content:\"PO\";" - " http_method; pcre:\"/ST/RM\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Test tracking of body chunks per transactions (on requests) - */ -static int DetectPcreTxBodyChunksTest01(void) -{ - int result = 0; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "GET / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - AppLayerHtpEnableRequestBodyCallback(); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - /* Now we should have 2 transactions, each with it's own list - * of request body chunks (let's test it) */ - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* hardcoded check of the transactions and it's client body chunks */ - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1); - if (htud == NULL) { - printf("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - HtpBodyChunk *cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body one!!", strlen("Body one!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - htud = (HtpTxUserData *) htp_tx_get_user_data(t2); - - cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body two!!", strlen("Body two!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SCMutexUnlock(&f.m); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test test pcre P modifier with multiple pipelined http transactions */ -static int DetectPcreTxBodyChunksTest02(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("signature matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (5): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* hardcoded check of the transactions and it's client body chunks */ - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1); - - HtpBodyChunk *cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body one!!", strlen("Body one!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - htud = (HtpTxUserData *) htp_tx_get_user_data(t2); - - cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body two!!", strlen("Body two!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test multiple http transactions and body chunks of request handling */ -static int DetectPcreTxBodyChunksTest03(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("signature matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (5): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test flowvar capture on http buffer - */ -static int DetectPcreFlowvarCapture01(void) -{ - int result = 0; - uint8_t uabuf1[] = - "Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13"; - uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */ - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "\r\n" - "flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, pd->capidx); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_str.value_len != ualen1) { - printf("%u != %u: ", fv->data.fv_str.value_len, ualen1); - goto end; - } - - if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - PrintRawDataFp(stdout, uabuf1, ualen1); - - printf("buffer mismatch: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \test flowvar capture on http buffer, capture overwrite - */ -static int DetectPcreFlowvarCapture02(void) -{ - int result = 0; - uint8_t uabuf1[] = - "Apache"; - uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */ - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "\r\n" - "flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; priority:1; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; priority:3; sid:2;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - if (pd1->capidx != pd2->capidx) { - printf("capidx mismatch, %u != %u: ", pd1->capidx, pd2->capidx); - goto end; - } - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - SCSigSignatureOrderingModuleCleanup(de_ctx); - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, pd1->capidx); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_str.value_len != ualen1) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - PrintRawDataFp(stdout, uabuf1, ualen1); - printf("%u != %u: ", fv->data.fv_str.value_len, ualen1); - goto end; - } - - if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - PrintRawDataFp(stdout, uabuf1, ualen1); - - printf("buffer mismatch: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \test flowvar capture on http buffer, capture overwrite + no matching sigs, so flowvars should not be set. - */ -static int DetectPcreFlowvarCapture03(void) -{ - int result = 0; - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "\r\n" - "flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:1; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:3; sid:2;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - if (pd1->capidx != pd2->capidx) { - printf("capidx mismatch, %u != %u: ", pd1->capidx, pd2->capidx); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but shouldn't have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, pd1->capidx); - if (fv != NULL) { - printf("flowvar, shouldn't have one: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \brief Test parsing of pcre's with the W modifier set. - */ -static int DetectPcreParseHttpHost(void) -{ - int result = 0; - DetectPcreData *pd = NULL; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - return 0; - } - - pd = DetectPcreParse(de_ctx, "/domain\\.com/W", &list); - if (pd == NULL) { - goto end; - } - DetectPcreFree(pd); - - list = DETECT_SM_LIST_NOTSET; - pd = DetectPcreParse(de_ctx, "/dOmain\\.com/W", &list); - if (pd != NULL) { - DetectPcreFree(pd); - goto end; - } - - /* Uppercase meta characters are valid. */ - list = DETECT_SM_LIST_NOTSET; - pd = DetectPcreParse(de_ctx, "/domain\\D+\\.com/W", &list); - if (pd == NULL) { - goto end; - } - DetectPcreFree(pd); - - /* This should not parse as the first \ escapes the second \, then - * we have a D. */ - list = DETECT_SM_LIST_NOTSET; - pd = DetectPcreParse(de_ctx, "/\\\\Ddomain\\.com/W", &list); - if (pd != NULL) { - DetectPcreFree(pd); - goto end; - } - - result = 1; - -end: - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectPcre - */ -void DetectPcreRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectPcreParseTest01", DetectPcreParseTest01, 1); - UtRegisterTest("DetectPcreParseTest02", DetectPcreParseTest02, 1); - UtRegisterTest("DetectPcreParseTest03", DetectPcreParseTest03, 1); - UtRegisterTest("DetectPcreParseTest04", DetectPcreParseTest04, 1); - UtRegisterTest("DetectPcreParseTest05", DetectPcreParseTest05, 1); - UtRegisterTest("DetectPcreParseTest06", DetectPcreParseTest06, 1); - UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07, 1); - UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08, 1); - UtRegisterTest("DetectPcreParseTest09", DetectPcreParseTest09, 1); - UtRegisterTest("DetectPcreParseTest10", DetectPcreParseTest10, 1); - UtRegisterTest("DetectPcreParseTest11", DetectPcreParseTest11, 1); - UtRegisterTest("DetectPcreParseTest12", DetectPcreParseTest12, 1); - UtRegisterTest("DetectPcreParseTest13", DetectPcreParseTest13, 1); - UtRegisterTest("DetectPcreParseTest14", DetectPcreParseTest14, 1); - UtRegisterTest("DetectPcreParseTest15", DetectPcreParseTest15, 1); - UtRegisterTest("DetectPcreParseTest16", DetectPcreParseTest16, 1); - UtRegisterTest("DetectPcreParseTest17", DetectPcreParseTest17, 1); - UtRegisterTest("DetectPcreParseTest18", DetectPcreParseTest18, 1); - UtRegisterTest("DetectPcreParseTest19", DetectPcreParseTest19, 1); - UtRegisterTest("DetectPcreParseTest20", DetectPcreParseTest20, 1); - UtRegisterTest("DetectPcreParseTest21", DetectPcreParseTest21, 1); - UtRegisterTest("DetectPcreParseTest22", DetectPcreParseTest22, 1); - UtRegisterTest("DetectPcreParseTest23", DetectPcreParseTest23, 1); - UtRegisterTest("DetectPcreParseTest24", DetectPcreParseTest24, 1); - UtRegisterTest("DetectPcreParseTest25", DetectPcreParseTest25, 1); - UtRegisterTest("DetectPcreParseTest26", DetectPcreParseTest26, 1); - UtRegisterTest("DetectPcreParseTest27", DetectPcreParseTest27, 1); - - UtRegisterTest("DetectPcreTestSig01B2g -- pcre test", DetectPcreTestSig01B2g, 1); - UtRegisterTest("DetectPcreTestSig01B3g -- pcre test", DetectPcreTestSig01B3g, 1); - UtRegisterTest("DetectPcreTestSig01Wm -- pcre test", DetectPcreTestSig01Wm, 1); - UtRegisterTest("DetectPcreTestSig02B2g -- pcre test", DetectPcreTestSig02B2g, 1); - UtRegisterTest("DetectPcreTestSig02B3g -- pcre test", DetectPcreTestSig02B3g, 1); - UtRegisterTest("DetectPcreTestSig02Wm -- pcre test", DetectPcreTestSig02Wm, 1); - UtRegisterTest("DetectPcreTestSig03B2g -- negated pcre test", DetectPcreTestSig03B2g, 1); - UtRegisterTest("DetectPcreTestSig03B3g -- negated pcre test", DetectPcreTestSig03B3g, 1); - UtRegisterTest("DetectPcreTestSig03Wm -- negated pcre test", DetectPcreTestSig03Wm, 1); - - UtRegisterTest("DetectPcreModifPTest04 -- Modifier P", DetectPcreModifPTest04, 1); - UtRegisterTest("DetectPcreModifPTest05 -- Modifier P fragmented", DetectPcreModifPTest05, 1); - UtRegisterTest("DetectPcreTestSig06", DetectPcreTestSig06, 1); - UtRegisterTest("DetectPcreTestSig07 -- anchored pcre", DetectPcreTestSig07, 1); - UtRegisterTest("DetectPcreTestSig08 -- anchored pcre", DetectPcreTestSig08, 1); - UtRegisterTest("DetectPcreTestSig09 -- Cookie modifier", DetectPcreTestSig09, 1); - UtRegisterTest("DetectPcreTestSig10 -- negated Cookie modifier", DetectPcreTestSig10, 1); - UtRegisterTest("DetectPcreTestSig11 -- Method modifier", DetectPcreTestSig11, 1); - UtRegisterTest("DetectPcreTestSig12 -- negated Method modifier", DetectPcreTestSig12, 1); - UtRegisterTest("DetectPcreTestSig13 -- Header modifier", DetectPcreTestSig13, 1); - UtRegisterTest("DetectPcreTestSig14 -- negated Header modifier", DetectPcreTestSig14, 1); - UtRegisterTest("DetectPcreTestSig15 -- relative Cookie modifier", DetectPcreTestSig15, 1); - UtRegisterTest("DetectPcreTestSig16 -- relative Method modifier", DetectPcreTestSig16, 1); - - UtRegisterTest("DetectPcreTxBodyChunksTest01", DetectPcreTxBodyChunksTest01, 1); - UtRegisterTest("DetectPcreTxBodyChunksTest02 -- modifier P, body chunks per tx", DetectPcreTxBodyChunksTest02, 1); - UtRegisterTest("DetectPcreTxBodyChunksTest03 -- modifier P, body chunks per tx", DetectPcreTxBodyChunksTest03, 1); - - UtRegisterTest("DetectPcreFlowvarCapture01 -- capture for http_header", DetectPcreFlowvarCapture01, 1); - UtRegisterTest("DetectPcreFlowvarCapture02 -- capture for http_header", DetectPcreFlowvarCapture02, 1); - UtRegisterTest("DetectPcreFlowvarCapture03 -- capture for http_header", DetectPcreFlowvarCapture03, 1); - - UtRegisterTest("DetectPcreParseHttpHost", DetectPcreParseHttpHost, 1); - -#endif /* UNITTESTS */ -} - -- cgit 1.2.3-korg