mpm and fast pattern support for http_header. Also support relative modifiers for http_header

remotes/origin/master-1.1.x
Anoop Saldanha 14 years ago committed by Victor Julien
parent 778ec0939c
commit c61c68fd36

@ -64,6 +64,7 @@ detect-engine-payload.c detect-engine-payload.h \
detect-engine-dcepayload.c detect-engine-dcepayload.h \
detect-engine-uri.c detect-engine-uri.h \
detect-engine-hcbd.c detect-engine-hcbd.h \
detect-engine-hhd.c detect-engine-hhd.h \
detect-engine-state.c detect-engine-state.h \
detect-parse.c detect-parse.h \
detect-ack.c detect-ack.h \
@ -114,6 +115,7 @@ detect-icode.c detect-icode.h \
detect-http-cookie.c detect-http-cookie.h \
detect-http-method.c detect-http-method.h \
detect-http-header.c detect-http-header.h \
detect-http-raw-header.c detect-http-raw-header.h \
detect-http-uri.c detect-http-uri.h \
detect-tls-version.c detect-tls-version.h \
detect-ssh-proto-version.c detect-ssh-proto-version.h \

@ -46,6 +46,7 @@
#define DETECT_CONTENT_STREAM_MPM 0x1000
#define DETECT_CONTENT_URI_MPM 0x2000
#define DETECT_CONTENT_HCBD_MPM 0x4000
#define DETECT_CONTENT_HHD_MPM 0x8000
#define DETECT_CONTENT_IS_SINGLE(c) (!((c)->flags & DETECT_CONTENT_DISTANCE || \
(c)->flags & DETECT_CONTENT_WITHIN || \

@ -21,7 +21,7 @@
* \author Victor Julien <victor@inliniac.net>
* \author Anoop Saldanha <poonaatsoc@gmail.com>
*
* Implements the depth keyword
* Implements the depth keyword.
*/
#include "suricata-common.h"
@ -60,9 +60,9 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
DetectContentData *ud = NULL;
/* strip "'s */
if (depthstr[0] == '\"' && depthstr[strlen(depthstr)-1] == '\"') {
str = SCStrdup(depthstr+1);
str[strlen(depthstr)-2] = '\0';
if (depthstr[0] == '\"' && depthstr[strlen(depthstr) - 1] == '\"') {
str = SCStrdup(depthstr + 1);
str[strlen(depthstr) - 2] = '\0';
dubbed = 1;
}
@ -83,13 +83,15 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
default:
pm = SigMatchGetLastSMFromLists(s, 6,
pm = SigMatchGetLastSMFromLists(s, 8,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs "
"preceeding content or uricontent option or http_client_body option");
"preceeding content, uricontent option, http_client_body "
"or http_header option");
if (dubbed)
SCFree(str);
return -1;
@ -196,12 +198,38 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
case DETECT_AL_HTTP_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
default:
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs a preceeding "
"content (or uricontent) option");
if (dubbed) SCFree(str);
return -1;
break;
goto error;
}
if (dubbed)

@ -123,7 +123,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
SigMatchTransferSigMatchAcrossLists(pm1,
&s->sm_lists[DETECT_SM_LIST_PMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
&s->sm_lists[DETECT_SM_LIST_DMATCH], &s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
&s->sm_lists[DETECT_SM_LIST_DMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
pm = pm1;
} else {
/* within is against pm1 and we continue this way */
@ -137,7 +138,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
SigMatchTransferSigMatchAcrossLists(pm1,
&s->sm_lists[DETECT_SM_LIST_PMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
&s->sm_lists[DETECT_SM_LIST_DMATCH], &s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
&s->sm_lists[DETECT_SM_LIST_DMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
pm = pm1;
} else {
/* within is against pm1 and we continue this way */
@ -164,14 +166,15 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 6,
pm = SigMatchGetLastSMFromLists(s, 8,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content or uricontent option or http_client_body options");
"preceeding content, uricontent option, http_client_body "
"or http_header option");
if (dubbed)
SCFree(str);
return -1;
@ -389,6 +392,7 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_CLIENT_BODY, pm->prev);
if (pm == NULL) {
@ -396,7 +400,52 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
"needs preceeding http_client_body content");
goto error;
}
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
"has a fast_pattern:only; set. You can't "
"have relative keywords around a fast_pattern "
"only content");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
case DETECT_AL_HTTP_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_HEADER, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_header "
"needs preceeding http_header content");
goto error;
}
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
@ -405,22 +454,23 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
"only content");
goto error;
}
((DetectContentData *)pm->ctx)->flags |= DETECT_CONTENT_RELATIVE_NEXT;
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
default:
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");
if (dubbed) SCFree(str);
return -1;
break;
goto error;
}
if (dubbed) SCFree(str);
if (dubbed)
SCFree(str);
return 0;
error:
if (dubbed) SCFree(str);
if (dubbed)
SCFree(str);
return -1;
}

@ -29,8 +29,6 @@
#include "detect-engine-mpm.h"
#include "detect-parse.h"
#include "detect-engine-state.h"
#include "detect-uricontent.h"
#include "detect-urilen.h"
#include "detect-pcre.h"
#include "detect-isdataat.h"
#include "detect-bytetest.h"
@ -208,8 +206,8 @@ static int DoInspectHttpClientBody(DetectEngineCtx *de_ctx,
BUG_ON(sm->next == NULL);
/* see if the next payload keywords match. If not, we will
* search for another occurence of this uricontent and see
* if the others match then until we run out of matches */
* search for another occurence of this http client body content
* and see if the others match then until we run out of matches */
int r = DoInspectHttpClientBody(de_ctx, det_ctx, s, sm->next,
payload, payload_len);
if (r == 1) {
@ -2681,7 +2679,7 @@ end:
#endif /* UNITTESTS */
void HttpClientBodyRegisterTests(void)
void DetectEngineHttpClientBodyRegisterTests(void)
{
#ifdef UNITTESTS

@ -28,7 +28,7 @@
int DetectEngineInspectHttpClientBody(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *);
void DetectEngineCleanHCBDBuffers(DetectEngineThreadCtx *);
void HttpClientBodyRegisterTests(void);
void DetectEngineHttpClientBodyRegisterTests(void);
#endif /* __DETECT_ENGINE_HCBD_H__ */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,32 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/** \file
*
* \author Anoop Saldanha <poonaatsoc@gmail.com>
*/
#ifndef __DETECT_ENGINE_HHD_H__
#define __DETECT_ENGINE_HHD_H__
int DetectEngineInspectHttpHeader(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *);
void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *);
void DetectEngineHttpHeaderRegisterTests(void);
#endif /* __DETECT_ENGINE_HHD_H__ */

@ -263,12 +263,14 @@ uint32_t UriPatternSearch(DetectEngineThreadCtx *det_ctx,
SCReturnUInt(ret);
}
/** \brief Uri Pattern match -- searches for one pattern per signature.
/** \brief Http client body pattern match -- searches for one pattern per
* signature.
*
* \param det_ctx detection engine thread ctx
* \param p packet to inspect
* \param det_ctx Detection engine thread ctx.
* \param body The request body to inspect.
* \param body_len Body length.
*
* \retval ret number of matches
* \retval ret Number of matches.
*/
uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *det_ctx,
uint8_t *body, uint32_t body_len)
@ -286,6 +288,31 @@ uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *det_ctx,
SCReturnUInt(ret);
}
/**
* \brief Http header match -- searches for one pattern per signature.
*
* \param det_ctx Detection engine thread ctx.
* \param headers Headers to inspect.
* \param headers_len Headers length.
*
* \retval ret Number of matches.
*/
uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *det_ctx,
uint8_t *headers, uint32_t headers_len)
{
SCEnter();
if (det_ctx->sgh->mpm_hhd_ctx == NULL)
SCReturnUInt(0);
uint32_t ret;
ret = mpm_table[det_ctx->sgh->mpm_hhd_ctx->mpm_type].
Search(det_ctx->sgh->mpm_hhd_ctx, &det_ctx->mtcu,
&det_ctx->pmq, headers, headers_len);
SCReturnUInt(ret);
}
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param tv threadvars
@ -581,6 +608,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
DetectContentData *cd = NULL;
DetectContentData *ud = NULL;
DetectContentData *hcbd = NULL;
DetectContentData *hhd = NULL;
switch (mpm_sm->type) {
case DETECT_CONTENT:
{
@ -731,7 +759,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
}
} /* else - if (ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */
/* add the content to the "packet" mpm */
/* add the content to the "uri" mpm */
if (ud->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_uri_ctx->mpm_type].
AddPatternNocase(sgh->mpm_uri_ctx,
@ -757,7 +785,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
{
hcbd = (DetectContentData *)mpm_sm->ctx;
if (hcbd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
/* add the content to the "uri" mpm */
/* add the content to the "hcbd" mpm */
if (hcbd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hcbd_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hcbd_ctx,
@ -784,7 +812,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
}
} /* else - if (hcbd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */
/* add the content to the "packet" mpm */
/* add the content to the "hcbd" mpm */
if (hcbd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hcbd_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hcbd_ctx,
@ -806,6 +834,59 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
break;
} /* case DETECT_AL_HTTP_CLIENT_BODY */
case DETECT_AL_HTTP_HEADER:
{
hhd = (DetectContentData *)mpm_sm->ctx;
if (hhd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
/* add the content to the "hhd" mpm */
if (hhd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hhd_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hhd_ctx,
hhd->content + hhd->fp_chop_offset,
hhd->fp_chop_len,
0, 0, hhd->id, s->num, flags);
} else {
mpm_table[sgh->mpm_hhd_ctx->mpm_type].
AddPattern(sgh->mpm_hhd_ctx,
hhd->content + hhd->fp_chop_offset,
hhd->fp_chop_len,
0, 0, hhd->id, s->num, flags);
}
} else {
if (hhd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
if (DETECT_CONTENT_IS_SINGLE(hhd)) {
hhd->flags |= DETECT_CONTENT_HHD_MPM;
}
/* see if we can bypass the match validation for this pattern */
} else {
if (DETECT_CONTENT_IS_SINGLE(hhd)) {
hhd->flags |= DETECT_CONTENT_HHD_MPM;
}
} /* else - if (hhd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */
/* add the content to the "hhd" mpm */
if (hhd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hhd_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hhd_ctx,
hhd->content, hhd->content_len,
0, 0, hhd->id, s->num, flags);
} else {
mpm_table[sgh->mpm_hhd_ctx->mpm_type].
AddPattern(sgh->mpm_hhd_ctx,
hhd->content, hhd->content_len,
0, 0, hhd->id, s->num, flags);
}
}
/* tell matcher we are inspecting uri */
s->mpm_flags |= SIG_FLAG_MPM_HHDCONTENT;
s->mpm_hhdpattern_id = hhd->id;
if (hhd->flags & DETECT_CONTENT_NEGATED)
s->mpm_flags |= SIG_FLAG_MPM_HHDCONTENT_NEG;
break;
} /* case DETECT_AL_HTTP_HEADER */
} /* switch (mpm_sm->type) */
SCLogDebug("%"PRIu32" adding cd->id %"PRIu32" to the mpm phase "
@ -1853,7 +1934,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
uint32_t has_co_packet = 0; /**< our sgh has packet payload inspecting content */
uint32_t has_co_stream = 0; /**< our sgh has stream inspecting content */
uint32_t has_co_uri = 0; /**< our sgh has uri inspecting content */
/* used to indicate if sgh has atleast one sig with http_client_body */
uint32_t has_co_hcbd = 0;
/* used to indicate if sgh has atleast one sig with http_header */
uint32_t has_co_hhd = 0;
//uint32_t cnt = 0;
uint32_t sig = 0;
@ -1888,6 +1972,11 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
has_co_hcbd = 1;
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
has_co_hhd = 1;
}
}
if (has_co_packet > 0) {
@ -1902,6 +1991,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (has_co_hcbd > 0) {
sh->flags |= SIG_GROUP_HAVEHCBDCONTENT;
}
if (has_co_hhd > 0) {
sh->flags |= SIG_GROUP_HAVEHHDCONTENT;
}
/* intialize contexes */
if (sh->flags & SIG_GROUP_HAVECONTENT) {
@ -1965,7 +2057,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_hcbd_ctx = MpmFactoryGetMpmCtxForProfile(MPM_CTX_FACTORY_UNIQUE_CONTEXT);
}
if (sh->mpm_hcbd_ctx == NULL) {
SCLogDebug("sh->mpm_stream_ctx == NULL. This should never happen");
SCLogDebug("sh->mpm_hcbd_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
@ -1976,6 +2068,24 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
#endif
}
if (sh->flags & SIG_GROUP_HAVEHHDCONTENT) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_hhd_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hhd);
} else {
sh->mpm_hhd_ctx = MpmFactoryGetMpmCtxForProfile(MPM_CTX_FACTORY_UNIQUE_CONTEXT);
}
if (sh->mpm_hhd_ctx == NULL) {
SCLogDebug("sh->mpm_hhd_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
#ifndef __SC_CUDA_SUPPORT__
MpmInitCtx(sh->mpm_hhd_ctx, de_ctx->mpm_matcher, -1);
#else
MpmInitCtx(sh->mpm_hhd_ctx, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
#endif
}
/* for each signature in this group do */
//for (sig = 0; sig < sh->sig_cnt; sig++) {
// s = sh->match_array[sig];
@ -2108,7 +2218,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (sh->flags & SIG_GROUP_HAVECONTENT ||
sh->flags & SIG_GROUP_HAVESTREAMCONTENT ||
sh->flags & SIG_GROUP_HAVEURICONTENT ||
sh->flags & SIG_GROUP_HAVEHCBDCONTENT) {
sh->flags & SIG_GROUP_HAVEHCBDCONTENT ||
sh->flags & SIG_GROUP_HAVEHHDCONTENT) {
PatternMatchPreparePopulateMpm(de_ctx, sh);
@ -2157,6 +2268,18 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
}
if (sh->mpm_hhd_ctx != NULL) {
if (sh->mpm_hhd_ctx->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(sh->mpm_hhd_ctx);
sh->mpm_hhd_ctx = NULL;
} else {
if (sh->flags & SIG_GROUP_HAVEHHDCONTENT) {
if (mpm_table[sh->mpm_hhd_ctx->mpm_type].Prepare != NULL)
mpm_table[sh->mpm_hhd_ctx->mpm_type].Prepare(sh->mpm_hhd_ctx);
}
}
}
} /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */
} else {
MpmFactoryReClaimMpmCtx(sh->mpm_ctx);
@ -2167,6 +2290,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_uri_ctx = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hcbd_ctx);
sh->mpm_hcbd_ctx = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hhd_ctx);
sh->mpm_hhd_ctx = NULL;
}
///* uricontent */

@ -37,6 +37,7 @@ uint32_t PacketPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *);
uint32_t UriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint16_t);
uint32_t StreamPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t);
uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);
uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);
void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *);
void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg);

@ -32,6 +32,7 @@
#include "detect-engine-uri.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hhd.h"
#include "detect-engine-dcepayload.h"
#include "stream-tcp.h"
@ -204,7 +205,9 @@ int DeStateUpdateInspectTransactionId(Flow *f, char direction) {
* \param dce did dce already match (if any)
* \param hcbd did http client body already match (if any)
*/
static void DeStateSignatureAppend(DetectEngineState *state, Signature *s, SigMatch *sm, char uri, char dce, char hcbd) {
static void DeStateSignatureAppend(DetectEngineState *state, Signature *s,
SigMatch *sm, char uri, char dce, char hcbd,
char hhd) {
DeStateStore *store = state->tail;
if (store == NULL) {
@ -241,6 +244,9 @@ static void DeStateSignatureAppend(DetectEngineState *state, Signature *s, SigMa
if (hcbd) {
store->store[idx].flags |= DE_STATE_FLAG_HCBD_MATCH;
}
if (hhd) {
store->store[idx].flags |= DE_STATE_FLAG_HHD_MATCH;
}
store->store[idx].nm = sm;
state->cnt++;
@ -302,6 +308,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
char uinspect = 0;
char hcbdmatch = 0;
char hcbdinspect = 0;
char hhdmatch = 0;
char hhdinspect = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -313,7 +321,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SCLogDebug("s->id %"PRIu32, s->id);
/* Check the uricontent keywords here. */
/* Check the uricontent, http client body, http header keywords here */
if (alproto == ALPROTO_HTTP && (flags & STREAM_TOSERVER)) {
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
uinspect = 1;
@ -337,6 +345,15 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
SCLogDebug("inspecting http client body");
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
hhdinspect = 1;
if (DetectEngineInspectHttpHeader(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
hhdmatch = 1;
}
SCLogDebug("inspecting http client body");
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
dinspect = 1;
@ -367,8 +384,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
}
appinspect = uinspect + dinspect + hcbdinspect;
appmatch = umatch + dmatch + hcbdmatch;
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
for ( ; sm != NULL; sm = sm->next) {
@ -410,8 +427,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
}
SCLogDebug("detection done, store results: sm %p, uri %d, dce %d, hcbd %d",
sm, umatch, dmatch, hcbdmatch);
SCLogDebug("detection done, store results: sm %p, uri %d, dce %d, hcbd %d "
"hhd %d", sm, umatch, dmatch, hcbdmatch, hhdmatch);
SCMutexLock(&f->de_state_m);
/* match or no match, we store the state anyway
@ -421,7 +438,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
f->de_state = DetectEngineStateAlloc();
}
if (f->de_state != NULL) {
DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch, hcbdmatch);
/* \todo shift to an array to transfer these match values*/
DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch, hcbdmatch, hhdmatch);
}
SCMutexUnlock(&f->de_state_m);
@ -445,6 +463,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
char uinspect = 0;
char hcbdmatch = 0;
char hcbdinspect = 0;
char hhdmatch = 0;
char hhdinspect = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -473,6 +493,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
uinspect = 0;
hcbdmatch = 0;
hcbdinspect = 0;
hhdmatch = 0;
hhdinspect = 0;
dmatch = 0;
dinspect = 0;
appinspect = 0;
@ -523,12 +545,25 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
if (DetectEngineInspectHttpClientBody(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
SCLogDebug("uri matched");
SCLogDebug("http client body matched");
item->flags |= DE_STATE_FLAG_HCBD_MATCH;
hcbdmatch = 1;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HHD_MATCH)) {
SCLogDebug("inspecting http header data");
hhdinspect = 1;
if (DetectEngineInspectHttpHeader(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
SCLogDebug("http header matched");
item->flags |= DE_STATE_FLAG_HHD_MATCH;
hhdmatch = 1;
}
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_DCE_MATCH)) {
@ -566,8 +601,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
appinspect = uinspect + dinspect + hcbdinspect;
appmatch = umatch + dmatch + hcbdmatch;
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch;
SCLogDebug("appinspect %d, appmatch %d", appinspect, appmatch);
/* next, check the other sig matches */
@ -707,39 +742,39 @@ static int DeStateTest02(void) {
memset(&s, 0x00, sizeof(s));
s.num = 0;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 33;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 44;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 55;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 66;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 77;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 88;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 99;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 100;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 111;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 122;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 133;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 144;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 155;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 166;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
if (state->head == NULL) {
goto end;
@ -782,9 +817,9 @@ static int DeStateTest03(void) {
memset(&s, 0x00, sizeof(s));
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 1, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 1, 0, 0, 0);
if (state->head == NULL) {
goto end;

@ -48,7 +48,8 @@
#define DE_STATE_FLAG_URI_MATCH 0x02 /**< uri part of the sig matched */
#define DE_STATE_FLAG_DCE_MATCH 0x04 /**< dce payload inspection part matched */
#define DE_STATE_FLAG_HCBD_MATCH 0x08 /**< hcbd payload inspection part matched */
#define DE_STATE_FLAG_FULL_MATCH 0x10 /**< sig already fully matched */
#define DE_STATE_FLAG_HHD_MATCH 0x10 /**< hcbd payload inspection part matched */
#define DE_STATE_FLAG_FULL_MATCH 0x20 /**< sig already fully matched */
/** per signature detection engine state */
typedef enum {

File diff suppressed because it is too large Load Diff

@ -188,20 +188,11 @@ int DetectHttpClientBodyMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
*/
int DetectHttpClientBodySetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
/* http_client_body_data (hcbd) */
DetectContentData *hcbd = NULL;
SigMatch *nm = NULL;
DetectContentData *cd = NULL;
SigMatch *sm = NULL;
if (arg != NULL && strcmp(arg, "") != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_client_body supplied with no "
"args");
return -1;
}
if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_client_body found inside the "
"rule, without any preceding content keywords");
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_client_body supplied with args");
return -1;
}
@ -216,19 +207,21 @@ int DetectHttpClientBodySetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
return -1;
}
cd = (DetectContentData *)sm->ctx;
/* http_client_body should not be used with the rawbytes rule */
if ( ((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_RAWBYTES) {
if (cd->flags & DETECT_CONTENT_RAWBYTES) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_client_body rule can not "
"be used with the rawbytes rule keyword");
return -1;
}
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords");
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http "
"alproto set");
goto error;
}
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) {
SigMatch *pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, sm->prev,
@ -272,11 +265,11 @@ int DetectHttpClientBodySetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
return 0;
error:
if (hcbd != NULL)
DetectHttpClientBodyFree(hcbd);
if (cd != NULL)
DetectHttpClientBodyFree(cd);
if(nm != NULL)
SCFree(nm);
if (sm != NULL)
SCFree(sm);
return -1;
}

@ -21,8 +21,6 @@
* \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
*
* Implements support for http_header keyword.
*
* \todo this is actually the raw match.
*/
#include "suricata-common.h"
@ -35,6 +33,7 @@
#include "detect-engine-mpm.h"
#include "detect-engine-state.h"
#include "detect-content.h"
#include "detect-pcre.h"
#include "flow.h"
#include "flow-var.h"
@ -75,23 +74,6 @@ void DetectHttpHeaderRegister(void)
sigmatch_table[DETECT_AL_HTTP_HEADER].flags |= SIGMATCH_PAYLOAD ;
}
/**
* \brief Registers the keyword handlers for the "http_raw_header" keyword.
*/
void DetectHttpRawHeaderRegister(void)
{
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].name = "http_raw_header";
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].AppLayerMatch = DetectHttpHeaderMatch;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Setup = DetectHttpHeaderSetup;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Free = DetectHttpHeaderFree;
//sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].RegisterTests = DetectHttpHeaderRegisterTests;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].RegisterTests = NULL;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].flags |= SIGMATCH_PAYLOAD ;
}
/**
* \brief App layer match function for the "http_header" keyword.
*
@ -194,23 +176,16 @@ void DetectHttpHeaderFree(void *ptr)
*/
int DetectHttpHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
/* http_header_data (hhd) */
DetectContentData *hhd = NULL;
SigMatch *nm = NULL;
DetectContentData *cd = NULL;
SigMatch *sm = NULL;
if (arg != NULL && strcmp(arg, "") != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_header supplied with no args");
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_header supplied with args");
return -1;
}
if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_header found inside the "
"rule, without any preceding content keywords");
return -1;
}
sm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
sm = SigMatchGetLastSMFromLists(s, 2,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
/* if still we are unable to find any content previous keywords, it is an
* invalid rule */
if (sm == NULL) {
@ -221,59 +196,57 @@ int DetectHttpHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
return -1;
}
if (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogWarning(SC_WARN_COMPATIBILITY,
"http_header cannot be used with \"fast_pattern\" currently."
"Unsetting fast_pattern on this modifier. Signature ==> %s", s->sig_str);
((DetectContentData *)sm->ctx)->flags &= ~DETECT_CONTENT_FAST_PATTERN;
}
/* cast for further use */
cd = (DetectContentData *)sm->ctx;
/* http_header should not be used with the rawbytes rule */
if (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_RAWBYTES) {
if (cd->flags & DETECT_CONTENT_RAWBYTES) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_header rule can not "
"be used with the rawbytes rule keyword");
return -1;
}
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords");
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http "
"alproto set");
goto error;
}
/* setup the HttpHeaderData's data from content data structure's data */
hhd = SCMalloc(sizeof(DetectContentData));
if (hhd == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
exit(EXIT_FAILURE);
}
memset(hhd, 0, sizeof(DetectContentData));
/* transfer the pattern details from the content struct to the clientbody struct */
DetectContentData *cd = (DetectContentData *)sm->ctx;
hhd->content = cd->content;
hhd->content_len = cd->content_len;
hhd->flags |= cd->flags & DETECT_CONTENT_NOCASE ? DETECT_CONTENT_NOCASE : 0;
hhd->flags |= cd->flags & DETECT_CONTENT_NEGATED ? DETECT_CONTENT_NEGATED : 0;
//hhd->id = ((DetectContentData *)sm->ctx)->id;
hhd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, hhd, DETECT_AL_HTTP_HEADER);
nm = SigMatchAlloc();
if (nm == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
goto error;
}
nm->type = DETECT_AL_HTTP_HEADER;
nm->ctx = (void *)hhd;
if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) {
SigMatch *pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, sm->prev,
DETECT_PCRE, sm->prev);
/* pm is never NULL. So no NULL check */
if (pm->type == DETECT_CONTENT) {
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT;
} else {
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
tmp_pd->flags &= ~DETECT_PCRE_RELATIVE_NEXT;
}
/* pull the previous content from the pmatch list, append
* the new match to the match list */
SigMatchReplaceContent(s, sm, nm);
/* please note. reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_HEADER,
s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_header seen with a "
"distance or within without a previous http_header "
"content. Invalidating signature.");
goto error;
}
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
}
cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_AL_HTTP_HEADER);
sm->type = DETECT_AL_HTTP_HEADER;
/* free the old content sigmatch, the content pattern memory
* is taken over by the new sigmatch */
BoyerMooreCtxDeInit(((DetectContentData *)sm->ctx)->bm_ctx);
SCFree(sm->ctx);
SCFree(sm);
/* transfer the sm from the pmatch list to hhdmatch list */
SigMatchTransferSigMatchAcrossLists(sm,
&s->sm_lists[DETECT_SM_LIST_PMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
&s->sm_lists[DETECT_SM_LIST_HHDMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
/* flag the signature to indicate that we scan the app layer data */
s->flags |= SIG_FLAG_APPLAYER;
@ -282,9 +255,10 @@ int DetectHttpHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
return 0;
error:
if (hhd != NULL)
DetectHttpHeaderFree(hhd);
if(nm != NULL)
if (cd != NULL)
DetectHttpHeaderFree(cd);
if(sm != NULL)
SCFree(sm);
return -1;
@ -321,11 +295,12 @@ static int DetectHttpHeaderTest01(void)
goto end;
}
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH];
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH];
if (sm != NULL) {
result &= (sm->type == DETECT_AL_HTTP_HEADER);
result &= (sm->next == NULL);
} else {
result = 0;
printf("Error updating content pattern to http_header pattern: ");
}
@ -853,6 +828,7 @@ static int DetectHttpHeaderTest09(void)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->mpm_matcher = MPM_AC;
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
@ -882,7 +858,7 @@ static int DetectHttpHeaderTest09(void)
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if ((PacketAlertCheck(p1, 1))) {
printf("sid 1 didn't match but should have: ");
printf("sid 1 matched but shouldn't have: ");
goto end;
}
@ -1352,13 +1328,13 @@ int DetectHttpHeaderTest14(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx;
if (cd->id == hhd->id)
goto end;
@ -1391,13 +1367,13 @@ int DetectHttpHeaderTest15(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx;
if (cd->id == hhd->id)
goto end;
@ -1430,13 +1406,13 @@ int DetectHttpHeaderTest16(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx;
if (cd->id != 0 || hhd->id != 1)
goto end;
@ -1469,13 +1445,13 @@ int DetectHttpHeaderTest17(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx;
if (cd->id != 1 || hhd->id != 0)
goto end;
@ -1509,14 +1485,14 @@ int DetectHttpHeaderTest18(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->prev->ctx;
DetectContentData *hhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx;
DetectContentData *hhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx;
if (cd->id != 1 || hhd1->id != 0 || hhd2->id != 0)
goto end;
@ -1550,14 +1526,14 @@ int DetectHttpHeaderTest19(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->prev->ctx;
DetectContentData *hhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx;
DetectContentData *hhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx;
if (cd->id != 2 || hhd1->id != 0 || hhd2->id != 0)
goto end;

@ -294,7 +294,7 @@ static int DetectHttpRawHeaderTest01(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; "
"content:one; http_header; sid:1;)");
"content:one; http_raw_header; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
} else {
@ -335,7 +335,7 @@ static int DetectHttpRawHeaderTest02(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; "
"content:one; http_header:; sid:1;)");
"content:one; http_raw_header:; sid:1;)");
if (de_ctx->sig_list != NULL)
result = 1;
else
@ -365,7 +365,7 @@ static int DetectHttpRawHeaderTest03(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; "
"http_header; sid:1;)");
"http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL)
result = 1;
else
@ -395,7 +395,7 @@ static int DetectHttpRawHeaderTest04(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; "
"content:one; rawbytes; http_header; sid:1;)");
"content:one; rawbytes; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL)
result = 1;
else
@ -425,7 +425,7 @@ static int DetectHttpRawHeaderTest05(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; "
"content:one; nocase; http_header; sid:1;)");
"content:one; nocase; http_raw_header; sid:1;)");
if (de_ctx->sig_list != NULL)
result = 1;
else
@ -490,7 +490,7 @@ static int DetectHttpRawHeaderTest06(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:\"Content-Type: text/html\"; http_header; "
"content:\"Content-Type: text/html\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -596,7 +596,7 @@ static int DetectHttpRawHeaderTest07(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:Mozilla; http_header; "
"content:Mozilla; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -716,7 +716,7 @@ static int DetectHttpRawHeaderTest08(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:\"Gecko/20091221 Firefox/3.5.7\"; http_header; "
"content:\"Gecko/20091221 Firefox/3.5.7\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -837,7 +837,7 @@ static int DetectHttpRawHeaderTest09(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:\"Firefox/3.5.7|0D 0A|Content\"; http_header; "
"content:\"Firefox/3.5.7|0D 0A|Content\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -958,7 +958,7 @@ static int DetectHttpRawHeaderTest10(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_header;"
"content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_raw_header;"
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -1071,7 +1071,7 @@ static int DetectHttpRawHeaderTest11(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:!lalalalala; http_header; "
"content:!lalalalala; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -1168,7 +1168,7 @@ static int DetectHttpRawHeaderTest12(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:!\"User-Agent: Mozilla/5.0 \"; http_header; "
"content:!\"User-Agent: Mozilla/5.0 \"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -1266,7 +1266,7 @@ static int DetectHttpRawHeaderTest13(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
"content:\"Host: www.openinfosecfoundation.org\"; http_header; "
"content:\"Host: www.openinfosecfoundation.org\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
@ -1322,7 +1322,7 @@ int DetectHttpRawHeaderTest14(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; content:one; http_header; sid:1;)");
"(content:one; content:one; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
@ -1361,7 +1361,7 @@ int DetectHttpRawHeaderTest15(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_header; content:one; sid:1;)");
"(content:one; http_raw_header; content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
@ -1400,7 +1400,7 @@ int DetectHttpRawHeaderTest16(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; content:one; content:one; http_header; content:one; sid:1;)");
"(content:one; content:one; content:one; http_raw_header; content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
@ -1439,7 +1439,7 @@ int DetectHttpRawHeaderTest17(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_header; content:one; content:one; content:one; sid:1;)");
"(content:one; http_raw_header; content:one; content:one; content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
@ -1478,8 +1478,8 @@ int DetectHttpRawHeaderTest18(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_header; "
"content:one; content:one; http_header; content:one; sid:1;)");
"(content:one; http_raw_header; "
"content:one; content:one; http_raw_header; content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
@ -1519,8 +1519,8 @@ int DetectHttpRawHeaderTest19(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_header; "
"content:one; content:one; http_header; content:two; sid:1;)");
"(content:one; http_raw_header; "
"content:one; content:one; http_raw_header; content:two; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;

@ -185,8 +185,8 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_AMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_AMATCH],
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_AMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "\"nocase\" needs a preceeding"

@ -21,7 +21,7 @@
* \author Victor Julien <victor@inliniac.net>
* \author Anoop Saldanha <poonaatsoc@gmail.com>
*
* Implements the offset keyword
* Implements the offset keyword.
*/
#include "suricata-common.h"
@ -80,10 +80,11 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
default:
pm = SigMatchGetLastSMFromLists(s, 6,
pm = SigMatchGetLastSMFromLists(s, 8,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "offset needs"
"preceeding content or uricontent option or http_client_body option");
@ -206,14 +207,41 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
case DETECT_AL_HTTP_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
break;
default:
SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs a preceeding"
" content or uricontent option");
if (dubbed)
SCFree(str);
return -1;
break;
goto error;
}
if (dubbed)

@ -169,13 +169,15 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 6,
pm = SigMatchGetLastSMFromLists(s, 8,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content or uricontent or http_client_body option");
"preceeding content, uricontent, http_client_body or "
"http_header option");
if (dubbed)
SCFree(str);
return -1;
@ -412,6 +414,7 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_CLIENT_BODY, pm->prev);
if (pm == NULL) {
@ -419,7 +422,54 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
"needs preceeding http_client_body content");
goto error;
}
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
"has a fast_pattern:only; set. You can't "
"have relative keywords around a fast_pattern "
"only content");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
case DETECT_AL_HTTP_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", ud->within,
ud->content_len);
goto error;
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_HEADER, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_header_body "
"needs preceeding http_header content");
goto error;
}
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
@ -428,17 +478,14 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
"only content");
goto error;
}
((DetectContentData *)pm->ctx)->flags |= DETECT_CONTENT_RELATIVE_NEXT;
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
default:
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two "
"preceeding content or uricontent options");
if (dubbed)
SCFree(str);
return -1;
break;
goto error;
}
if (dubbed)
@ -451,6 +498,8 @@ error:
return -1;
}
/***********************************Unittests**********************************/
#ifdef UNITTESTS
#include "util-unittest-helper.h"
/**

@ -112,9 +112,11 @@
#include "detect-detection-filter.h"
#include "detect-http-client-body.h"
#include "detect-http-header.h"
#include "detect-http-raw-header.h"
#include "detect-http-uri.h"
#include "detect-http-stat-msg.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hhd.h"
#include "util-rule-vars.h"
@ -682,7 +684,8 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx,
/* de_state check, filter out all signatures that already had a match before
* or just partially match */
if (s->flags & SIG_FLAG_AMATCH || s->flags & SIG_FLAG_UMATCH ||
s->flags & SIG_FLAG_DMATCH || s->flags & SIG_FLAG_HCBDMATCH)
s->flags & SIG_FLAG_DMATCH || s->flags & SIG_FLAG_HCBDMATCH ||
s->flags & SIG_FLAG_HHDMATCH)
{
/* we run after DeStateDetectContinueDetection, so we might have
* state NEW here. In that case we'd want to continue detection
@ -876,6 +879,9 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
det_ctx->de_have_hcbd = TRUE;
det_ctx->de_mpm_scanned_hcbd = FALSE;
det_ctx->de_have_hhd = TRUE;
det_ctx->de_mpm_scanned_hhd = FALSE;
SCEnter();
/* No need to perform any detection on this packet, if the the given flag is set.*/
@ -1173,7 +1179,9 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HCBDMATCH]) {
s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
if (alstate == NULL) {
SCLogDebug("state matches but no state, we can't match");
goto next;
@ -1311,6 +1319,7 @@ end:
//}
DetectEngineCleanHCBDBuffers(det_ctx);
DetectEngineCleanHHDBuffers(det_ctx);
/* store the found sgh (or NULL) in the flow to save us from looking it
* up again for the next packet. Also return any stream chunk we processed
@ -1485,6 +1494,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
return 0;
@ -1559,6 +1571,9 @@ static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL)
return 0;
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH];
/* check for conflicting keywords */
for ( ;sm != NULL; sm = sm->next) {
@ -1651,6 +1666,11 @@ static int SignatureCreateMask(Signature *s) {
SCLogDebug("sig requires http app state");
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
s->mask |= SIG_MASK_REQUIRE_HTTP_STATE;
SCLogDebug("sig requires http app state");
}
SigMatch *sm;
for (sm = s->sm_lists[DETECT_SM_LIST_AMATCH] ; sm != NULL; sm = sm->next) {
switch(sm->type) {
@ -1726,6 +1746,9 @@ static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx)
de_ctx->sgh_mpm_context_hcbd =
MpmFactoryRegisterMpmCtxProfile("hcbd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_hhd =
MpmFactoryRegisterMpmCtxProfile("hhd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_app_proto_detect =
MpmFactoryRegisterMpmCtxProfile("app_proto_detect", 0);
@ -3680,6 +3703,12 @@ int SigGroupBuild (DetectEngineCtx *de_ctx) {
}
//printf("hcbd- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hhd);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("hhd- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_stream);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);

@ -86,7 +86,12 @@ enum {
DETECT_SM_LIST_AMATCH,
DETECT_SM_LIST_DMATCH,
DETECT_SM_LIST_TMATCH,
/* list for http_client_body keyword and the ones relative to it */
DETECT_SM_LIST_HCBDMATCH,
/* list for http_header keyword and the ones relative to it */
DETECT_SM_LIST_HHDMATCH,
/* list for http_raw_header keyword and the ones relative to it */
DETECT_SM_LIST_HRHDMATCH,
DETECT_SM_LIST_MAX,
};
@ -229,17 +234,23 @@ typedef struct DetectPort_ {
#define SIG_FLAG_AMATCH 0x00080000
#define SIG_FLAG_DMATCH 0x00100000
#define SIG_FLAG_HCBDMATCH 0x00200000
#define SIG_FLAG_HHDMATCH 0x00400000
#define SIG_FLAG_MPM_PACKET 0x00400000
#define SIG_FLAG_MPM_PACKET_NEG 0x00800000
#define SIG_FLAG_MPM_STREAM 0x01000000
#define SIG_FLAG_MPM_STREAM_NEG 0x02000000
#define SIG_FLAG_MPM_URICONTENT 0x04000000
#define SIG_FLAG_MPM_URICONTENT_NEG 0x08000000
#define SIG_FLAG_MPM_HCBDCONTENT 0x10000000
#define SIG_FLAG_MPM_HCBDCONTENT_NEG 0x20000000
#define SIG_FLAG_MPM_PACKET 0x00800000
#define SIG_FLAG_MPM_PACKET_NEG 0x01000000
#define SIG_FLAG_MPM_STREAM 0x02000000
#define SIG_FLAG_MPM_STREAM_NEG 0x04000000
#define SIG_FLAG_MPM_URICONTENT 0x08000000
#define SIG_FLAG_MPM_URICONTENT_NEG 0x10000000
#define SIG_FLAG_MPM_HCBDCONTENT 0x20000000
#define SIG_FLAG_MPM_HCBDCONTENT_NEG 0x40000000
#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x80000000
/* the mpm specific flags in Signature, held in Signature->mpm_flags */
#define SIG_FLAG_MPM_HHDCONTENT 0x00000001
#define SIG_FLAG_MPM_HHDCONTENT_NEG 0x00000002
#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x40000000
/* signature mask flags */
#define SIG_MASK_REQUIRE_PAYLOAD 0x01
@ -338,6 +349,9 @@ typedef struct Signature_ {
uint64_t hdr_copy2;
};
/* mpm flags */
uint32_t mpm_flags;
//PatIntId mpm_pattern_id;
//PatIntId mpm_stream_pattern_id;
@ -356,6 +370,7 @@ typedef struct Signature_ {
/** pattern in the mpm matcher */
PatIntId mpm_uripattern_id;
PatIntId mpm_hcbdpattern_id;
PatIntId mpm_hhdpattern_id;
/* the fast pattern added from this signature */
SigMatch *mpm_sm;
@ -609,6 +624,7 @@ typedef struct DetectEngineCtx_ {
/* maximum recursion depth for content inspection */
int inspection_recursion_limit;
/* conf parameter that limits the length of the http request body inspected */
int hcbd_buffer_limit;
/* array containing all sgh's in use so we can loop
@ -621,6 +637,7 @@ typedef struct DetectEngineCtx_ {
int32_t sgh_mpm_context_stream;
int32_t sgh_mpm_context_uri;
int32_t sgh_mpm_context_hcbd;
int32_t sgh_mpm_context_hhd;
int32_t sgh_mpm_context_app_proto_detect;
/** sgh for signatures that match against invalid packets. In those cases
@ -668,10 +685,18 @@ typedef struct DetectionEngineThreadCtx_ {
char de_have_hcbd;
char de_mpm_scanned_hcbd;
/* detectione engine context for hhd mpm */
char de_have_hhd;
char de_mpm_scanned_hhd;
uint8_t **hcbd_buffers;
uint32_t *hcbd_buffers_len;
uint16_t hcbd_buffers_list_len;
uint8_t **hhd_buffers;
uint32_t *hhd_buffers_len;
uint16_t hhd_buffers_list_len;
/** id for alert counter */
uint16_t counter_alerts;
@ -763,11 +788,12 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HAVEURICONTENT 0x0002
#define SIG_GROUP_HAVESTREAMCONTENT 0x0004
#define SIG_GROUP_HAVEHCBDCONTENT 0x0008
#define SIG_GROUP_HEAD_MPM_COPY 0x0010
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x0020
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x0040
#define SIG_GROUP_HEAD_FREE 0x0080
#define SIG_GROUP_HEAD_REFERENCED 0x0100 /**< sgh is being referenced by others, don't clear */
#define SIG_GROUP_HAVEHHDCONTENT 0x0010
#define SIG_GROUP_HEAD_MPM_COPY 0x0020
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x0040
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x0080
#define SIG_GROUP_HEAD_FREE 0x0100
#define SIG_GROUP_HEAD_REFERENCED 0x0200 /**< sgh is being referenced by others, don't clear */
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -810,6 +836,7 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_stream_ctx;
MpmCtx *mpm_uri_ctx;
MpmCtx *mpm_hcbd_ctx;
MpmCtx *mpm_hhd_ctx;
uint16_t mpm_uricontent_maxlen;
uint16_t pad1;
#if __WORDSIZE == 64

@ -54,6 +54,7 @@
#include "detect-engine-dcepayload.h"
#include "detect-engine-uri.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hhd.h"
#include "detect-engine-state.h"
#include "detect-engine-tag.h"
#include "detect-fast-pattern.h"
@ -968,7 +969,8 @@ int main(int argc, char **argv)
DeStateRegisterTests();
DetectRingBufferRegisterTests();
MemcmpRegisterTests();
HttpClientBodyRegisterTests();
DetectEngineHttpClientBodyRegisterTests();
DetectEngineHttpHeaderRegisterTests();
DetectEngineRegisterTests();
SCLogRegisterTests();
if (list_unittests) {

Loading…
Cancel
Save