support relative modifiers for http_client_body. Introduce body processing engine in detect-engine-hcbd.[ch]

remotes/origin/master-1.1.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 234656e5f6
commit 5c6a65dc58

@ -63,6 +63,7 @@ detect-engine-iponly.c detect-engine-iponly.h \
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-state.c detect-engine-state.h \
detect-parse.c detect-parse.h \
detect-ack.c detect-ack.h \

@ -25,6 +25,7 @@
* This file provides a HTTP protocol support for the engine using HTP library.
*/
#include "suricata.h"
#include "suricata-common.h"
#include "debug.h"
#include "decode.h"
@ -70,6 +71,7 @@ struct HTPCfgRec_ {
static SCRadixTree *cfgtree;
/** List of HTP configurations. */
static HTPCfgRec cfglist;
static HTPCfgRec cfglist_backup;
#ifdef DEBUG
static SCMutex htp_state_mem_lock = PTHREAD_MUTEX_INITIALIZER;
@ -537,7 +539,7 @@ static int HTPHandleResponseData(Flow *f, void *htp_state,
* \param len length of the chunk pointed by data
* \retval none
*/
void HtpBodyAppendChunk(HtpBody *body, uint8_t *data, uint32_t len)
void HtpBodyAppendChunk(SCHtpTxUserData *htud, HtpBody *body, uint8_t *data, uint32_t len)
{
SCEnter();
@ -560,6 +562,7 @@ void HtpBodyAppendChunk(HtpBody *body, uint8_t *data, uint32_t len)
}
memcpy(bd->data, data, len);
htud->content_len_so_far = len;
body->first = body->last = bd;
body->nchunks++;
bd->next = NULL;
@ -570,6 +573,11 @@ void HtpBodyAppendChunk(HtpBody *body, uint8_t *data, uint32_t len)
/* Weird, but sometimes htp lib calls the callback
* more than once for the same chunk, with more
* len, so updating the len */
if (body->last->len > len)
htud->content_len_so_far -= (body->last->len - len);
else
htud->content_len_so_far += (len - body->last->len);
body->last->len = len;
bd = body->last;
@ -593,6 +601,7 @@ void HtpBodyAppendChunk(HtpBody *body, uint8_t *data, uint32_t len)
}
memcpy(bd->data, data, len);
htud->content_len_so_far += len;
body->last->next = bd;
body->last = bd;
body->nchunks++;
@ -696,13 +705,17 @@ int HTPCallbackRequestBodyData(htp_tx_data_t *d)
htud->body.operation = HTP_BODY_NONE;
htud->body.pcre_flags = HTP_PCRE_NONE;
htp_header_t *cl = table_getc(d->tx->request_headers, "content-length");
if (cl != NULL)
htud->content_len = htp_parse_content_length(cl->value);
/* Set the user data for handling body chunks on this transaction */
htp_tx_set_user_data(d->tx, htud);
}
htud->body.operation = HTP_BODY_REQUEST;
HtpBodyAppendChunk(&htud->body, (uint8_t*)d->data, (uint32_t)d->len);
HtpBodyAppendChunk(htud, &htud->body, (uint8_t*)d->data, (uint32_t)d->len);
htud->body.pcre_flags = HTP_PCRE_NONE;
if (SCLogDebugEnabled()) {
HtpBodyPrint(&htud->body);
@ -1021,6 +1034,22 @@ static void HTPConfigure(void)
SCReturn;
}
static void HtpConfigCreateBackup(void)
{
cfglist_backup.cfg = cfglist.cfg;
cfglist_backup.next = cfglist.next;
return;
}
static void HtpConfigRestoreBackup(void)
{
cfglist.cfg = cfglist_backup.cfg;
cfglist.next = cfglist_backup.next;
return;
}
/**
* \brief Register the HTTP protocol and state handling functions to APP layer
* of the engine.
@ -1753,6 +1782,7 @@ libhtp:\n\
ConfCreateContextBackup();
ConfInit();
HtpConfigCreateBackup();
ConfYamlLoadString(input, strlen(input));
@ -1816,8 +1846,10 @@ libhtp:\n\
ret = 1;
end:
HTPFreeConfig();
ConfDeInit();
ConfRestoreContextBackup();
HtpConfigRestoreBackup();
return ret;
}
@ -1858,6 +1890,7 @@ libhtp:\n\
ConfCreateContextBackup();
ConfInit();
HtpConfigCreateBackup();
ConfYamlLoadString(input, strlen(input));
@ -1922,8 +1955,10 @@ libhtp:\n\
}
end:
HTPFreeConfig();
ConfDeInit();
ConfRestoreContextBackup();
HtpConfigRestoreBackup();
FlowL7DataPtrFree(&f);
StreamTcpFreeConfig(TRUE);

@ -85,7 +85,12 @@ typedef struct HtpBody_ {
/** Now the Body Chunks will be stored per transaction, at
* the tx user data */
typedef struct SCHtpTxUserData_ {
HtpBody body; /**< Body of the request (if any) */
/* Body of the request (if any) */
HtpBody body;
/* Holds the length of the htp request body */
uint32_t content_len;
/* Holds the length of the htp request body seen so far */
uint32_t content_len_so_far;
} SCHtpTxUserData;
typedef struct HtpState_ {

@ -83,12 +83,13 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
default:
pm = SigMatchGetLastSMFromLists(s, 4,
pm = SigMatchGetLastSMFromLists(s, 6,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH]);
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs "
"preceeding content or uricontent option");
"preceeding content or uricontent option or http_client_body option");
if (dubbed)
SCFree(str);
return -1;
@ -167,6 +168,20 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
case DETECT_AL_HTTP_CLIENT_BODY:
cd = (DetectContentData *)pm->ctx;
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");

@ -163,12 +163,14 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 4,
pm = SigMatchGetLastSMFromLists(s, 6,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH]);
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content or uricontent option");
"preceeding content or uricontent option or http_client_body options");
if (dubbed)
SCFree(str);
return -1;
@ -361,6 +363,29 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
break;
case DETECT_AL_HTTP_CLIENT_BODY:
cd = (DetectContentData *)pm->ctx;
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;
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_CLIENT_BODY, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_client_body "
"needs preceeding http_client_body content");
goto error;
}
((DetectContentData *)pm->ctx)->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
default:
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");

File diff suppressed because it is too large Load Diff

@ -0,0 +1,31 @@
/* 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_HCBD_H__
#define __DETECT_ENGINE_HCBD_H__
int DetectEngineInspectHttpClientBody(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *);
void HttpClientBodyRegisterTests(void);
#endif /* __DETECT_ENGINE_HCBD_H__ */

@ -31,6 +31,7 @@
#include "detect-engine-state.h"
#include "detect-engine-uri.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-dcepayload.h"
#include "stream-tcp.h"
@ -194,15 +195,16 @@ int DeStateUpdateInspectTransactionId(Flow *f, char direction) {
}
/**
* \brief Append a signature to the detect engine state
* \brief Append a signature to the detect engine state
*
* \param state the detect engine state
* \param s signature
* \param sm sigmatch
* \param uri did uri already match (if any)
* \param dce did dce already match (if any)
* \param state the detect engine state
* \param s signature
* \param sm sigmatch
* \param uri did uri already match (if any)
* \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) {
static void DeStateSignatureAppend(DetectEngineState *state, Signature *s, SigMatch *sm, char uri, char dce, char hcbd) {
DeStateStore *store = state->tail;
if (store == NULL) {
@ -236,12 +238,17 @@ static void DeStateSignatureAppend(DetectEngineState *state, Signature *s, SigMa
if (dce) {
store->store[idx].flags |= DE_STATE_FLAG_DCE_MATCH;
}
if (hcbd) {
store->store[idx].flags |= DE_STATE_FLAG_HCBD_MATCH;
}
store->store[idx].nm = sm;
state->cnt++;
SCLogDebug("store %p idx %"PRIuMAX" cnt %"PRIuMAX" sig id %"PRIuMAX"",
store, (uintmax_t)idx, (uintmax_t)state->cnt,
(uintmax_t)store->store[idx].sid);
return;
}
@ -293,6 +300,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
int r = 0;
char umatch = 0;
char uinspect = 0;
char hcbdmatch = 0;
char hcbdinspect = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -320,6 +329,14 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SCLogDebug("uri inspected but no match");
}
}
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
hcbdinspect = 1;
if (DetectEngineInspectHttpClientBody(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
hcbdmatch = 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;
@ -350,8 +367,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
}
appinspect = uinspect + dinspect;
appmatch = umatch + dmatch;
appinspect = uinspect + dinspect + hcbdinspect;
appmatch = umatch + dmatch + hcbdmatch;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
for ( ; sm != NULL; sm = sm->next) {
@ -393,8 +410,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
}
SCLogDebug("detection done, store results: sm %p, uri %d, dce %d",
sm, umatch, dmatch);
SCLogDebug("detection done, store results: sm %p, uri %d, dce %d", hcbd %d,
sm, umatch, dmatch, hcbdmatch);
SCMutexLock(&f->de_state_m);
/* match or no match, we store the state anyway
@ -404,7 +421,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
f->de_state = DetectEngineStateAlloc();
}
if (f->de_state != NULL) {
DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch);
DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch, hcbdmatch);
}
SCMutexUnlock(&f->de_state_m);
@ -426,6 +443,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
int match = 0;
char umatch = 0;
char uinspect = 0;
char hcbdmatch = 0;
char hcbdinspect = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -452,6 +471,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
umatch = 0;
uinspect = 0;
hcbdmatch = 0;
hcbdinspect = 0;
dmatch = 0;
dinspect = 0;
appinspect = 0;
@ -495,6 +516,19 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
SCLogDebug("uri already inspected");
}
}
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HCBD_MATCH)) {
SCLogDebug("inspecting http client body data");
hcbdinspect = 1;
if (DetectEngineInspectHttpClientBody(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
SCLogDebug("uri matched");
item->flags |= DE_STATE_FLAG_HCBD_MATCH;
hcbdmatch = 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)) {
@ -532,8 +566,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
appinspect = uinspect + dinspect;
appmatch = umatch + dmatch;
appinspect = uinspect + dinspect + hcbdinspect;
appmatch = umatch + dmatch + hcbdmatch;
SCLogDebug("appinspect %d, appmatch %d", appinspect, appmatch);
/* next, check the other sig matches */
@ -673,39 +707,39 @@ static int DeStateTest02(void) {
memset(&s, 0x00, sizeof(s));
s.num = 0;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 33;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 44;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 55;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 66;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 77;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 88;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 99;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 100;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 111;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 122;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 133;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 144;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 155;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 166;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
if (state->head == NULL) {
goto end;
@ -748,9 +782,9 @@ static int DeStateTest03(void) {
memset(&s, 0x00, sizeof(s));
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 1, 0);
DeStateSignatureAppend(state, &s, NULL, 1, 0, 0);
if (state->head == NULL) {
goto end;

@ -47,7 +47,8 @@
#define DE_STATE_FLAG_PAYLOAD_MATCH 0x01 /**< payload part of the sig matched */
#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_FULL_MATCH 0x08 /**< sig already fully matched */
#define DE_STATE_FLAG_HCBD_MATCH 0x08 /**< hcbd payload inspection part matched */
#define DE_STATE_FLAG_FULL_MATCH 0x10 /**< sig already fully matched */
/** per signature detection engine state */
typedef enum {

@ -64,11 +64,11 @@ void DetectHttpClientBodyRegister(void)
{
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].name = "http_client_body";
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].AppLayerMatch = DetectHttpClientBodyMatch;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].Setup = DetectHttpClientBodySetup;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].Free = DetectHttpClientBodyFree;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].RegisterTests = DetectHttpClientBodyRegisterTests;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].flags |= SIGMATCH_PAYLOAD ;
}
@ -235,39 +235,34 @@ int DetectHttpClientBodySetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
goto error;
}
/* setup the HttpClientBodyData's data from content data structure's data */
hcbd = SCMalloc(sizeof(DetectContentData));
if (hcbd == NULL)
goto error;
memset(hcbd, 0, sizeof(DetectContentData));
/* transfer the pattern details from the content struct to the clientbody struct */
hcbd->content = ((DetectContentData *)sm->ctx)->content;
hcbd->content_len = ((DetectContentData *)sm->ctx)->content_len;
hcbd->flags |= (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_NOCASE) ?
DETECT_CONTENT_NOCASE : 0;
hcbd->flags |= (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_NEGATED) ?
DETECT_CONTENT_NEGATED : 0;
//hcbd->id = ((DetectContentData *)sm->ctx)->id;
hcbd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, hcbd, DETECT_AL_HTTP_CLIENT_BODY);
hcbd->bm_ctx = ((DetectContentData *)sm->ctx)->bm_ctx;
nm = SigMatchAlloc();
if (nm == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
goto error;
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) {
SigMatch *pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_CONTENT, sm->prev);
/* pm is never NULL. So no NULL check */
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT;
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_client_body seen with a "
"distance or within without a previous http_client_body "
"content. Invalidating signature.");
goto error;
}
tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
}
nm->type = DETECT_AL_HTTP_CLIENT_BODY;
nm->ctx = (void *)hcbd;
cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_AL_HTTP_CLIENT_BODY);
sm->type = DETECT_AL_HTTP_CLIENT_BODY;
/* pull the previous content from the pmatch list, append
* the new match to the match list */
SigMatchReplaceContent(s, sm, nm);
/* free the old content sigmatch, the content pattern memory
* is taken over by the new sigmatch */
SCFree(sm->ctx);
SCFree(sm);
/* transfer the sm from the pmatch list to hcbdmatch list */
SigMatchTransferSigMatchAcrossLists(sm,
&s->sm_lists[DETECT_SM_LIST_PMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
&s->sm_lists[DETECT_SM_LIST_HCBDMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
/* flag the signature to indicate that we scan the app layer data */
s->flags |= SIG_FLAG_APPLAYER;
@ -484,7 +479,7 @@ static int DetectHttpClientBodyTest06(void)
"Content-Type: text/html\r\n"
"Content-Length: 26\r\n"
"\r\n"
"This is dummy message body\r\n";
"This is dummy message body";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
@ -581,11 +576,11 @@ static int DetectHttpClientBodyTest07(void)
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 67\r\n"
"Content-Length: 54\r\n"
"\r\n"
"This is dummy message body1";
uint8_t http2_buf[] =
"This is dummy message body2\r\n";
"This is dummy message body2";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
@ -647,8 +642,8 @@ static int DetectHttpClientBodyTest07(void)
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (!(PacketAlertCheck(p1, 1))) {
printf("sid 1 didn't match on p1 but should have: ");
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched on p1 but shouldn't have: ");
goto end;
}
@ -660,13 +655,11 @@ static int DetectHttpClientBodyTest07(void)
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
/* VJ right now we won't inspect the body another time if it
already matched once. Later we will take care of that.
if (!(PacketAlertCheck(p2, 1))) {
printf("sid 1 didn't match on p2 but should have: ");
goto end;
}
*/
result = 1;
end:
if (de_ctx != NULL)
@ -703,11 +696,11 @@ static int DetectHttpClientBodyTest08(void)
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 67\r\n"
"Content-Length: 46\r\n"
"\r\n"
"This is dummy body1";
uint8_t http2_buf[] =
"This is dummy message body2\r\n";
"This is dummy message body2";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
@ -827,11 +820,11 @@ static int DetectHttpClientBodyTest09(void)
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 67\r\n"
"Content-Length: 46\r\n"
"\r\n"
"This is dummy body1";
uint8_t http2_buf[] =
"This is dummy message body2\r\n";
"This is dummy message body2";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
@ -951,11 +944,11 @@ static int DetectHttpClientBodyTest10(void)
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 67\r\n"
"Content-Length: 46\r\n"
"\r\n"
"This is dummy bodY1";
uint8_t http2_buf[] =
"This is dummy message body2\r\n";
"This is dummy message body2";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
@ -1075,7 +1068,7 @@ static int DetectHttpClientBodyTest11(void)
"Content-Type: text/html\r\n"
"Content-Length: 26\r\n"
"\r\n"
"This is dummy message body\r\n";
"This is dummy message body";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
@ -1173,7 +1166,7 @@ static int DetectHttpClientBodyTest12(void)
"Content-Type: text/html\r\n"
"Content-Length: 26\r\n"
"\r\n"
"This is dummy message body\r\n";
"This is dummy message body";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
@ -1269,9 +1262,9 @@ static int DetectHttpClientBodyTest13(void)
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 100\r\n"
"Content-Length: 55\r\n"
"\r\n"
"longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n";
"longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
@ -1793,13 +1786,13 @@ int DetectHttpClientBodyTest16(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_HCBDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx;
if (cd->id == hcbd->id)
goto end;
@ -1832,13 +1825,13 @@ int DetectHttpClientBodyTest17(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_HCBDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx;
if (cd->id == hcbd->id)
goto end;
@ -1871,13 +1864,13 @@ int DetectHttpClientBodyTest18(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_HCBDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx;
if (cd->id != 0 || hcbd->id != 1)
goto end;
@ -1910,13 +1903,13 @@ int DetectHttpClientBodyTest19(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_HCBDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hcbd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx;
if (cd->id != 1 || hcbd->id != 0)
goto end;
@ -1950,14 +1943,14 @@ int DetectHttpClientBodyTest20(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_HCBDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hcbd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hcbd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->prev->ctx;
DetectContentData *hcbd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx;
DetectContentData *hcbd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx;
if (cd->id != 1 || hcbd1->id != 0 || hcbd2->id != 0)
goto end;
@ -1991,14 +1984,14 @@ int DetectHttpClientBodyTest21(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_HCBDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hcbd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hcbd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->prev->ctx;
DetectContentData *hcbd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx;
DetectContentData *hcbd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx;
if (cd->id != 2 || hcbd1->id != 0 || hcbd2->id != 0)
goto end;

@ -65,101 +65,101 @@ void DetectNocaseRegister (void) {
* \retval sm sigmatch of either content or uricontent that is the last
* or NULL if none was found
*/
static SigMatch *SigMatchGetLastNocasePattern(Signature *s) {
SCEnter();
BUG_ON(s == NULL);
SigMatch *co_sm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
SigMatch *ur_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_URICONTENT);
/* http client body SigMatch */
SigMatch *hcbd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_CLIENT_BODY);
/* http cookie SigMatch */
SigMatch *hcd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_COOKIE);
/* http header SigMatch */
SigMatch *hhd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_HEADER);
/* http method SigMatch */
SigMatch *hmd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_METHOD);
SigMatch *temp_sm = NULL;
SigMatch **sm_list = NULL;
uint8_t sm_list_count = 0;
if (co_sm != NULL) {
sm_list_count++;
if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
exit(EXIT_FAILURE);
}
sm_list[sm_list_count - 1] = co_sm;
}
if (ur_sm != NULL) {
sm_list_count++;
if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
exit(EXIT_FAILURE);
}
sm_list[sm_list_count - 1] = ur_sm;
}
if (hcbd_sm != NULL) {
sm_list_count++;
if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
exit(EXIT_FAILURE);
}
sm_list[sm_list_count - 1] = hcbd_sm;
}
if (hcd_sm != NULL) {
sm_list_count++;
if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
exit(EXIT_FAILURE);
}
sm_list[sm_list_count - 1] = hcd_sm;
}
if (hhd_sm != NULL) {
sm_list_count++;
if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
exit(EXIT_FAILURE);
}
sm_list[sm_list_count - 1] = hhd_sm;
}
if (hmd_sm != NULL) {
sm_list_count++;
if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
exit(EXIT_FAILURE);
}
sm_list[sm_list_count - 1] = hmd_sm;
}
if (sm_list_count == 0)
SCReturnPtr(NULL, "SigMatch");
/* find the highest idx sm, so we apply to the last sm that we support */
int i = 0, j = 0;
int swapped = 1;
while (swapped) {
swapped = 0;
for (j = i; j < sm_list_count - 1; j++) {
if (sm_list[j]->idx < sm_list[j + 1]->idx) {
temp_sm = sm_list[j];
sm_list[j] = sm_list[j + 1];
sm_list[j + 1] = temp_sm;
swapped = 1;
i++;
}
}
}
temp_sm = sm_list[0];
SCFree(sm_list);
SCReturnPtr(temp_sm, "SigMatch");
}
//static SigMatch *SigMatchGetLastNocasePattern(Signature *s) {
// SCEnter();
//
// BUG_ON(s == NULL);
//
// SigMatch *co_sm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
// SigMatch *ur_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_URICONTENT);
// /* http client body SigMatch */
// SigMatch *hcbd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_CLIENT_BODY);
// /* http cookie SigMatch */
// SigMatch *hcd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_COOKIE);
// /* http header SigMatch */
// SigMatch *hhd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_HEADER);
// /* http method SigMatch */
// SigMatch *hmd_sm = SigMatchGetLastSM(s->sm_lists_tail[DETECT_SM_LIST_AMATCH], DETECT_AL_HTTP_METHOD);
//
// SigMatch *temp_sm = NULL;
//
// SigMatch **sm_list = NULL;
// uint8_t sm_list_count = 0;
//
// if (co_sm != NULL) {
// sm_list_count++;
// if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
// SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
// exit(EXIT_FAILURE);
// }
// sm_list[sm_list_count - 1] = co_sm;
// }
// if (ur_sm != NULL) {
// sm_list_count++;
// if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
// SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
// exit(EXIT_FAILURE);
// }
// sm_list[sm_list_count - 1] = ur_sm;
// }
// if (hcbd_sm != NULL) {
// sm_list_count++;
// if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
// SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
// exit(EXIT_FAILURE);
// }
// sm_list[sm_list_count - 1] = hcbd_sm;
// }
// if (hcd_sm != NULL) {
// sm_list_count++;
// if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
// SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
// exit(EXIT_FAILURE);
// }
// sm_list[sm_list_count - 1] = hcd_sm;
// }
// if (hhd_sm != NULL) {
// sm_list_count++;
// if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
// SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
// exit(EXIT_FAILURE);
// }
// sm_list[sm_list_count - 1] = hhd_sm;
// }
//
// if (hmd_sm != NULL) {
// sm_list_count++;
// if ( (sm_list = SCRealloc(sm_list, sizeof(SigMatch *) * sm_list_count)) == NULL) {
// SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigMatchGetLastNocasePattern. Exiting...");
// exit(EXIT_FAILURE);
// }
// sm_list[sm_list_count - 1] = hmd_sm;
// }
//
// if (sm_list_count == 0)
// SCReturnPtr(NULL, "SigMatch");
//
// /* find the highest idx sm, so we apply to the last sm that we support */
// int i = 0, j = 0;
// int swapped = 1;
// while (swapped) {
// swapped = 0;
// for (j = i; j < sm_list_count - 1; j++) {
// if (sm_list[j]->idx < sm_list[j + 1]->idx) {
// temp_sm = sm_list[j];
// sm_list[j] = sm_list[j + 1];
// sm_list[j + 1] = temp_sm;
// swapped = 1;
// i++;
// }
// }
// }
//
// temp_sm = sm_list[0];
// SCFree(sm_list);
//
// SCReturnPtr(temp_sm, "SigMatch");
//}
/**
* \internal
@ -180,7 +180,14 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
}
/* Search for the first previous SigMatch that supports nocase */
SigMatch *pm = SigMatchGetLastNocasePattern(s);
//SigMatch *pm = SigMatchGetLastNocasePattern(s);
SigMatch *pm = SigMatchGetLastSMFromLists(s, 12,
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_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"
" content, uricontent, http_client_body, http_header, http_method, http_uri, http_cookie option");
@ -244,4 +251,3 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
SCReturnInt(0);
}

@ -80,12 +80,13 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
default:
pm = SigMatchGetLastSMFromLists(s, 4,
pm = SigMatchGetLastSMFromLists(s, 6,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH]);
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs"
"preceeding content or uricontent option");
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "offset needs"
"preceeding content or uricontent option or http_client_body option");
if (dubbed)
SCFree(str);
return -1;
@ -94,6 +95,7 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
}
/* we can remove this switch now with the unified structure */
DetectContentData *ud = NULL;
DetectContentData *cd = NULL;
switch (pm->type) {
@ -173,6 +175,23 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
case DETECT_AL_HTTP_CLIENT_BODY:
cd = (DetectContentData *)pm->ctx;
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");

@ -1361,6 +1361,8 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
sig->flags |= SIG_FLAG_AMATCH;
if (sig->sm_lists[DETECT_SM_LIST_AMATCH])
sig->flags |= SIG_FLAG_AMATCH;
if (sig->sm_lists[DETECT_SM_LIST_HCBDMATCH])
sig->flags |= SIG_FLAG_HCBDMATCH;
SCLogDebug("sig %"PRIu32" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
sig->id, sig->flags & SIG_FLAG_APPLAYER ? "set" : "not set",

@ -169,12 +169,13 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 4,
pm = SigMatchGetLastSMFromLists(s, 6,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH]);
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content or uricontent option");
"preceeding content or uricontent or http_client_body option");
if (dubbed)
SCFree(str);
return -1;
@ -382,8 +383,32 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
break;
break;
case DETECT_AL_HTTP_CLIENT_BODY:
cd = (DetectContentData *)pm->ctx;
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;
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_CLIENT_BODY, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_client_body "
"needs preceeding http_client_body content");
goto error;
}
((DetectContentData *)pm->ctx)->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
default:
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two "

@ -681,7 +681,7 @@ 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_DMATCH || s->flags & SIG_FLAG_HCBDMATCH)
{
/* we run after DeStateDetectContinueDetection, so we might have
* state NEW here. In that case we'd want to continue detection
@ -1144,7 +1144,10 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SCLogDebug("s->sm_lists[DETECT_SM_LIST_AMATCH] %p, s->sm_lists[DETECT_SM_LIST_UMATCH] %p, s->sm_lists[DETECT_SM_LIST_DMATCH] %p",
s->sm_lists[DETECT_SM_LIST_AMATCH], s->sm_lists[DETECT_SM_LIST_UMATCH], s->sm_lists[DETECT_SM_LIST_DMATCH]);
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) {
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]) {
if (alstate == NULL) {
SCLogDebug("state matches but no state, we can't match");
goto next;
@ -1451,6 +1454,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
return 0;
@ -1522,6 +1528,9 @@ static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL)
return 0;
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH];
/* check for conflicting keywords */
for ( ;sm != NULL; sm = sm->next) {
@ -1606,7 +1615,12 @@ static int SignatureCreateMask(Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
s->mask |= SIG_MASK_REQUIRE_HTTP_STATE;
SCLogDebug("sig requires dce http state");
SCLogDebug("sig requires http state");
}
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
s->mask |= SIG_MASK_REQUIRE_HTTP_STATE;
SCLogDebug("sig requires http app state");
}
SigMatch *sm;

@ -86,6 +86,7 @@ enum {
DETECT_SM_LIST_AMATCH,
DETECT_SM_LIST_DMATCH,
DETECT_SM_LIST_TMATCH,
DETECT_SM_LIST_HCBDMATCH,
DETECT_SM_LIST_MAX,
};
@ -227,13 +228,14 @@ typedef struct DetectPort_ {
#define SIG_FLAG_UMATCH 0x00040000
#define SIG_FLAG_AMATCH 0x00080000
#define SIG_FLAG_DMATCH 0x00100000
#define SIG_FLAG_HCBDMATCH 0x00200000
#define SIG_FLAG_MPM_PACKET 0x00200000
#define SIG_FLAG_MPM_STREAM 0x00400000
#define SIG_FLAG_MPM_URICONTENT 0x00800000
#define SIG_FLAG_MPM_URICONTENT_NEG 0x01000000
#define SIG_FLAG_MPM_PACKET 0x00400000
#define SIG_FLAG_MPM_STREAM 0x00800000
#define SIG_FLAG_MPM_URICONTENT 0x01000000
#define SIG_FLAG_MPM_URICONTENT_NEG 0x02000000
#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x02000000
#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x04000000
/* signature mask flags */
#define SIG_MASK_REQUIRE_PAYLOAD 0x01

@ -53,6 +53,7 @@
#include "detect-engine-payload.h"
#include "detect-engine-dcepayload.h"
#include "detect-engine-uri.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-state.h"
#include "detect-engine-tag.h"
#include "detect-fast-pattern.h"
@ -942,7 +943,6 @@ int main(int argc, char **argv)
TmqhFlowRegisterTests();
FlowRegisterTests();
SCSigRegisterSignatureOrderingTests();
SCLogRegisterTests();
SCRadixRegisterTests();
DefragRegisterTests();
SigGroupHeadRegisterTests();
@ -968,7 +968,9 @@ int main(int argc, char **argv)
DeStateRegisterTests();
DetectRingBufferRegisterTests();
MemcmpRegisterTests();
HttpClientBodyRegisterTests();
DetectEngineRegisterTests();
SCLogRegisterTests();
if (list_unittests) {
UtListTests(regex_arg);
}

Loading…
Cancel
Save