New app inspection engine introduced. Moved existing inspecting engines to use it.

pull/146/head
Anoop Saldanha 13 years ago committed by Victor Julien
parent 7b4eac3e8d
commit b99f9fe890

@ -39,12 +39,12 @@ enum {
ALPROTO_DCERPC,
ALPROTO_DCERPC_UDP,
ALPROTO_IRC,
#ifdef UNITTESTS
ALPROTO_TEST,
#endif /* UNITESTS */
/* used by the probing parser when alproto detection fails
* permanently for that particular stream */
ALPROTO_FAILED,
#ifdef UNITTESTS
ALPROTO_TEST,
#endif /* UNITESTS */
/* keep last */
ALPROTO_MAX,
};

@ -201,54 +201,22 @@ static int DetectFileInspect(ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
* \retval 2 can't match
* \retval 3 can't match filestore signature
*
* \note flow is not locked at this time
* \note flow should be locked when this function's called.
*/
int DetectFileInspectHttp(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags, void *alstate, int tx_id) {
SCEnter();
int r = 0;
HtpState *htp_state = NULL;
int idx = 0;
int start_tx = 0;
int end_tx = 0;
int match = 0;
FileContainer *ffc;
/* locking the flow, we will inspect the htp state, files + we will set
* magic, so need a WRITE lock */
FLOWLOCK_WRLOCK(f);
htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
HtpState *htp_state = (HtpState *)alstate;
if (flags & STREAM_TOCLIENT)
ffc = htp_state->files_tc;
else
ffc = htp_state->files_ts;
if (htp_state->connp != NULL && htp_state->connp->conn != NULL)
{
start_tx = AppLayerTransactionGetInspectId(f);
if (start_tx == -1) {
goto end;
}
/* tx cnt is incremented after request finishes, so we need to inspect
* response one before the lowest. */
if ((flags & STREAM_TOCLIENT) && start_tx > 0)
start_tx--;
end_tx = (int)list_size(htp_state->connp->conn->transactions);
}
for (idx = start_tx ; idx < end_tx; idx++)
{
/* inspect files for this transaction */
det_ctx->tx_id = (uint16_t)idx;
det_ctx->tx_id = (uint16_t)tx_id;
match = DetectFileInspect(tv, det_ctx, f, s, flags, ffc);
int match = DetectFileInspect(tv, det_ctx, f, s, flags, ffc);
if (match == 1) {
r = 1;
} else if (match == 2) {
@ -262,9 +230,6 @@ int DetectFileInspectHttp(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineT
r = 3;
}
}
}
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return r;
}

@ -60,6 +60,27 @@
#define BUFFER_STEP 50
static inline int HCBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size)
{
if (size > det_ctx->hcbd_buffers_size) {
det_ctx->hcbd = SCRealloc(det_ctx->hcbd, (det_ctx->hcbd_buffers_size + BUFFER_STEP) * sizeof(HttpReassembledBody));
if (det_ctx->hcbd == NULL) {
det_ctx->hcbd_buffers_size = 0;
det_ctx->hcbd_buffers_list_len = 0;
return -1;
}
memset(det_ctx->hcbd + det_ctx->hcbd_buffers_size, 0, BUFFER_STEP * sizeof(HttpReassembledBody));
det_ctx->hcbd_buffers_size += BUFFER_STEP;
for (int i = det_ctx->hcbd_buffers_list_len; i < (size); i++) {
det_ctx->hcbd[i].buffer_len = 0;
det_ctx->hcbd[i].offset = 0;
}
}
return 0;
}
static uint8_t *DetectEngineHCBDGetBufferForTX(int tx_id,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
@ -67,29 +88,13 @@ static uint8_t *DetectEngineHCBDGetBufferForTX(int tx_id,
uint8_t flags,
uint32_t *buffer_len)
{
#define HCBDCreateSpace(det_ctx, size) do { \
if (size > det_ctx->hcbd_buffers_size) { \
det_ctx->hcbd = SCRealloc(det_ctx->hcbd, (det_ctx->hcbd_buffers_size + BUFFER_STEP) * sizeof(HttpReassembledBody)); \
if (det_ctx->hcbd == NULL) { \
det_ctx->hcbd_buffers_size = 0; \
det_ctx->hcbd_buffers_list_len = 0; \
goto end; \
} \
memset(det_ctx->hcbd + det_ctx->hcbd_buffers_size, 0, BUFFER_STEP * sizeof(HttpReassembledBody)); \
det_ctx->hcbd_buffers_size += BUFFER_STEP; \
} \
for (int i = det_ctx->hcbd_buffers_list_len; i < (size); i++) { \
det_ctx->hcbd[i].buffer_len = 0; \
det_ctx->hcbd[i].offset = 0; \
} \
} while (0)
int index = 0;
uint8_t *buffer = NULL;
*buffer_len = 0;
if (det_ctx->hcbd_buffers_list_len == 0) {
HCBDCreateSpace(det_ctx, 1);
if (HCBDCreateSpace(det_ctx, 1) < 0)
goto end;
index = 0;
} else {
if ((tx_id - det_ctx->hcbd_start_tx_id) < det_ctx->hcbd_buffers_list_len) {
@ -98,7 +103,8 @@ static uint8_t *DetectEngineHCBDGetBufferForTX(int tx_id,
return det_ctx->hcbd[(tx_id - det_ctx->hcbd_start_tx_id)].buffer;
}
} else {
HCBDCreateSpace(det_ctx, (tx_id - det_ctx->hcbd_start_tx_id) + 1);
if (HCBDCreateSpace(det_ctx, (tx_id - det_ctx->hcbd_start_tx_id) + 1) < 0)
goto end;
}
index = (tx_id - det_ctx->hcbd_start_tx_id);
}
@ -213,7 +219,7 @@ static uint8_t *DetectEngineHCBDGetBufferForTX(int tx_id,
return buffer;
}
int DetectEngineRunHttpClientBodyMpmV2(DetectEngineCtx *de_ctx,
int DetectEngineRunHttpClientBodyMpm(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Flow *f,
HtpState *htp_state, uint8_t flags)
{
@ -256,65 +262,38 @@ int DetectEngineRunHttpClientBodyMpmV2(DetectEngineCtx *de_ctx,
return cnt;
}
int DetectEngineInspectHttpClientBodyV2(ThreadVars *tv,
int DetectEngineInspectHttpClientBody(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
int r = 0;
HtpState *htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
FLOWLOCK_WRLOCK(f);
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
/* get the transaction id */
int idx = AppLayerTransactionGetInspectId(f);
/* error! get out of here */
if (idx == -1)
goto end;
int size = (int)list_size(htp_state->connp->conn->transactions);
for (; idx < size; idx++) {
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
uint32_t buffer_len = 0;
uint8_t *buffer = DetectEngineHCBDGetBufferForTX(idx,
uint8_t *buffer = DetectEngineHCBDGetBufferForTX(tx_id,
de_ctx, det_ctx,
f, htp_state,
flags,
&buffer_len);
if (buffer_len == 0)
continue;
return 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCBDMATCH],
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCBDMATCH],
f,
buffer,
buffer_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCBD, NULL);
if (r == 1) {
break;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
return r;
return 0;
}
void DetectEngineCleanHCBDBuffersV2(DetectEngineThreadCtx *det_ctx)
void DetectEngineCleanHCBDBuffers(DetectEngineThreadCtx *det_ctx)
{
if (det_ctx->hcbd_buffers_list_len > 0) {
for (int i = 0; i < det_ctx->hcbd_buffers_list_len; i++) {

@ -27,15 +27,15 @@
#include "app-layer-htp.h"
int DetectEngineRunHttpClientBodyMpmV2(DetectEngineCtx *,
int DetectEngineRunHttpClientBodyMpm(DetectEngineCtx *,
DetectEngineThreadCtx *, Flow *f,
HtpState *, uint8_t);
int DetectEngineInspectHttpClientBodyV2(ThreadVars *tv,
int DetectEngineInspectHttpClientBody(ThreadVars *tv,
DetectEngineCtx *,
DetectEngineThreadCtx *,
Signature *, Flow *,
uint8_t, void *, int);
void DetectEngineCleanHCBDBuffersV2(DetectEngineThreadCtx *);
void DetectEngineCleanHCBDBuffers(DetectEngineThreadCtx *);
void DetectEngineHttpClientBodyRegisterTests(void);

@ -134,35 +134,10 @@ int DetectEngineInspectHttpCookie(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = NULL;
htp_tx_t *tx = NULL;
int idx;
FLOWLOCK_RDLOCK(f);
htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
int size = (int)list_size(htp_state->connp->conn->transactions);
for (; idx < size; idx++) {
tx = list_get(htp_state->connp->conn->transactions, idx);
HtpState *htp_state = (HtpState *)alstate;
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL)
continue;
return 0;
htp_header_t *h = NULL;
if (flags & STREAM_TOSERVER) {
@ -170,37 +145,29 @@ int DetectEngineInspectHttpCookie(ThreadVars *tv,
"Cookie");
if (h == NULL) {
SCLogDebug("HTTP cookie header not present in this request");
continue;
return 0;
}
} else {
h = (htp_header_t *)table_getc(tx->response_headers,
"Set-Cookie");
if (h == NULL) {
SCLogDebug("HTTP Set-Cookie header not present in this request");
continue;
return 0;
}
}
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCDMATCH],
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCDMATCH],
f,
(uint8_t *)bstr_ptr(h->value),
bstr_len(h->value),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCD, NULL);
//r = DoInspectHttpCookie(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCDMATCH],
//(uint8_t *)bstr_ptr(h->value),
//bstr_len(h->value));
if (r == 1) {
break;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -58,6 +58,30 @@
#define BUFFER_STEP 50
static inline int HHDCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size) {
if (size > det_ctx->hhd_buffers_size) {
det_ctx->hhd_buffers = SCRealloc(det_ctx->hhd_buffers, (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint8_t *));
if (det_ctx->hhd_buffers == NULL) {
det_ctx->hhd_buffers_size = 0;
det_ctx->hhd_buffers_list_len = 0;
return -1;
}
memset(det_ctx->hhd_buffers + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint8_t *));
det_ctx->hhd_buffers_len = SCRealloc(det_ctx->hhd_buffers_len, (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint32_t));
if (det_ctx->hhd_buffers_len == NULL) {
det_ctx->hhd_buffers_size = 0;
det_ctx->hhd_buffers_list_len = 0;
return -1;
}
memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint32_t));
det_ctx->hhd_buffers_size += BUFFER_STEP;
}
memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_list_len, 0, (size - det_ctx->hhd_buffers_list_len) * sizeof(uint32_t));
return 0;
}
static uint8_t *DetectEngineHHDGetBufferForTX(int tx_id,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
@ -65,32 +89,12 @@ static uint8_t *DetectEngineHHDGetBufferForTX(int tx_id,
uint8_t flags,
uint32_t *buffer_len)
{
#define HHDCreateSpace(det_ctx, size) do { \
if (size > det_ctx->hhd_buffers_size) { \
det_ctx->hhd_buffers = SCRealloc(det_ctx->hhd_buffers, (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint8_t *)); \
if (det_ctx->hhd_buffers == NULL) { \
det_ctx->hhd_buffers_size = 0; \
det_ctx->hhd_buffers_list_len = 0; \
goto end; \
} \
memset(det_ctx->hhd_buffers + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint8_t *)); \
det_ctx->hhd_buffers_len = SCRealloc(det_ctx->hhd_buffers_len, (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint32_t)); \
if (det_ctx->hhd_buffers_len == NULL) { \
det_ctx->hhd_buffers_size = 0; \
det_ctx->hhd_buffers_list_len = 0; \
goto end; \
} \
memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint32_t)); \
det_ctx->hhd_buffers_size += BUFFER_STEP; \
} \
memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_list_len, 0, (size - det_ctx->hhd_buffers_list_len) * sizeof(uint32_t)); \
} while (0)
int index = 0;
*buffer_len = 0;
if (det_ctx->hhd_buffers_list_len == 0) {
HHDCreateSpace(det_ctx, 1);
if (HHDCreateSpace(det_ctx, 1) < 0)
goto end;
index = 0;
} else {
if ((tx_id - det_ctx->hhd_start_tx_id) < det_ctx->hhd_buffers_list_len) {
@ -99,7 +103,8 @@ static uint8_t *DetectEngineHHDGetBufferForTX(int tx_id,
return det_ctx->hhd_buffers[(tx_id - det_ctx->hhd_start_tx_id)];
}
} else {
HHDCreateSpace(det_ctx, (tx_id - det_ctx->hhd_start_tx_id) + 1);
if (HHDCreateSpace(det_ctx, (tx_id - det_ctx->hhd_start_tx_id) + 1) < 0)
goto end;
}
index = (tx_id - det_ctx->hhd_start_tx_id);
}
@ -173,7 +178,7 @@ static uint8_t *DetectEngineHHDGetBufferForTX(int tx_id,
return headers_buffer;
}
int DetectEngineRunHttpHeaderMpmV2(DetectEngineThreadCtx *det_ctx, Flow *f,
int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
HtpState *htp_state, uint8_t flags)
{
uint32_t cnt = 0;
@ -215,65 +220,37 @@ int DetectEngineRunHttpHeaderMpmV2(DetectEngineThreadCtx *det_ctx, Flow *f,
return cnt;
}
int DetectEngineInspectHttpHeaderV2(ThreadVars *tv,
int DetectEngineInspectHttpHeader(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
int r = 0;
HtpState *htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
FLOWLOCK_WRLOCK(f);
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
/* get the transaction id */
int idx = AppLayerTransactionGetInspectId(f);
/* error! get out of here */
if (idx == -1)
goto end;
int size = (int)list_size(htp_state->connp->conn->transactions);
for (; idx < size; idx++) {
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
uint32_t buffer_len = 0;
uint8_t *buffer = DetectEngineHHDGetBufferForTX(idx,
uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx_id,
de_ctx, det_ctx,
f, htp_state,
flags,
&buffer_len);
if (buffer_len == 0)
continue;
return 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HHDMATCH],
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HHDMATCH],
f,
buffer,
buffer_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHD, NULL);
if (r == 1) {
break;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
return r;
return 0;
}
void DetectEngineCleanHHDBuffersV2(DetectEngineThreadCtx *det_ctx)
void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *det_ctx)
{
if (det_ctx->hhd_buffers_list_len != 0) {
int i;

@ -25,14 +25,14 @@
#include "app-layer-htp.h"
int DetectEngineInspectHttpHeaderV2(ThreadVars *tv,
int DetectEngineInspectHttpHeader(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id);
int DetectEngineRunHttpHeaderMpmV2(DetectEngineThreadCtx *det_ctx, Flow *f,
int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
HtpState *htp_state, uint8_t flags);
void DetectEngineCleanHHDBuffersV2(DetectEngineThreadCtx *det_ctx);
void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *det_ctx);
void DetectEngineHttpHeaderRegisterTests(void);

@ -118,57 +118,23 @@ int DetectEngineInspectHttpMethod(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = NULL;
htp_tx_t *tx = NULL;
int idx;
FLOWLOCK_RDLOCK(f);
htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
int size = (int)list_size(htp_state->connp->conn->transactions);
for (; idx < size; idx++) {
tx = list_get(htp_state->connp->conn->transactions, idx);
HtpState *htp_state = (HtpState *)alstate;
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL || tx->request_method == NULL)
continue;
return 0;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HMDMATCH],
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HMDMATCH],
f,
(uint8_t *)bstr_ptr(tx->request_method),
bstr_len(tx->request_method),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HMD, NULL);
//r = DoInspectHttpMethod(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HMDMATCH],
//(uint8_t *)bstr_ptr(tx->request_method),
//bstr_len(tx->request_method));
if (r == 1) {
break;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -133,35 +133,10 @@ int DetectEngineInspectHttpRawHeader(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = NULL;
htp_tx_t *tx = NULL;
int idx;
FLOWLOCK_RDLOCK(f);
htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
int size = (int)list_size(htp_state->connp->conn->transactions);
for (; idx < size; idx++) {
tx = list_get(htp_state->connp->conn->transactions, idx);
HtpState *htp_state = (HtpState *)alstate;
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL)
continue;
return 0;
bstr *raw_headers = NULL;
if (flags & STREAM_TOSERVER) {
@ -173,27 +148,20 @@ int DetectEngineInspectHttpRawHeader(ThreadVars *tv,
}
#endif /* HAVE_HTP_TX_GET_RESPONSE_HEADERS_RAW */
if (raw_headers == NULL)
continue;
return 0;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRHDMATCH],
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRHDMATCH],
f,
(uint8_t *)bstr_ptr(raw_headers),
bstr_len(raw_headers),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHD, NULL);
//r = DoInspectHttpRawHeader(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRHDMATCH],
//(uint8_t *)bstr_ptr(raw_headers),
//bstr_len(raw_headers));
if (r == 1) {
break;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -122,67 +122,25 @@ int DetectEngineInspectHttpRawUri(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
SCReturnInt(0);
}
/* locking the flow, we will inspect the htp state */
FLOWLOCK_RDLOCK(f);
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
#ifdef DEBUG
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_HRUDMATCH];
DetectContentData *co = (DetectContentData *)sm->ctx;
SCLogDebug("co->id %"PRIu32, co->id);
#endif
int idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
htp_tx_t *tx = NULL;
int size = (int)list_size(htp_state->connp->conn->transactions);
for ( ; idx < size; idx++)
{
tx = list_get(htp_state->connp->conn->transactions, idx);
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL || tx->request_uri == NULL)
continue;
return 0;
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
det_ctx->inspection_recursion_counter = 0;
/* Inspect all the uricontents fetched on each
* transaction at the app layer */
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRUDMATCH],
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRUDMATCH],
f,
(uint8_t *)bstr_ptr(tx->request_uri),
bstr_len(tx->request_uri),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRUD, NULL);
//r = DoInspectHttpRawUri(de_ctx, det_ctx, s,
// s->sm_lists[DETECT_SM_LIST_HRUDMATCH],
// (uint8_t *)bstr_ptr(tx->request_uri),
// bstr_len(tx->request_uri));
if (r == 1) {
goto end;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -61,6 +61,27 @@
#define BUFFER_STEP 50
static inline int HSBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size)
{
if (size > det_ctx->hsbd_buffers_size) {
det_ctx->hsbd = SCRealloc(det_ctx->hsbd, (det_ctx->hsbd_buffers_size + BUFFER_STEP) * sizeof(HttpReassembledBody));
if (det_ctx->hsbd == NULL) {
det_ctx->hsbd_buffers_size = 0;
det_ctx->hsbd_buffers_list_len = 0;
return -1;
}
memset(det_ctx->hsbd + det_ctx->hsbd_buffers_size, 0, BUFFER_STEP * sizeof(HttpReassembledBody));
det_ctx->hsbd_buffers_size += BUFFER_STEP;
}
for (int i = det_ctx->hsbd_buffers_list_len; i < (size); i++) {
det_ctx->hsbd[i].buffer_len = 0;
det_ctx->hsbd[i].offset = 0;
}
return 0;
}
static uint8_t *DetectEngineHSBDGetBufferForTX(int tx_id,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
@ -68,29 +89,13 @@ static uint8_t *DetectEngineHSBDGetBufferForTX(int tx_id,
uint8_t flags,
uint32_t *buffer_len)
{
#define HSBDCreateSpace(det_ctx, size) do { \
if (size > det_ctx->hsbd_buffers_size) { \
det_ctx->hsbd = SCRealloc(det_ctx->hsbd, (det_ctx->hsbd_buffers_size + BUFFER_STEP) * sizeof(HttpReassembledBody)); \
if (det_ctx->hsbd == NULL) { \
det_ctx->hsbd_buffers_size = 0; \
det_ctx->hsbd_buffers_list_len = 0; \
goto end; \
} \
memset(det_ctx->hsbd + det_ctx->hsbd_buffers_size, 0, BUFFER_STEP * sizeof(HttpReassembledBody)); \
det_ctx->hsbd_buffers_size += BUFFER_STEP; \
} \
for (int i = det_ctx->hsbd_buffers_list_len; i < (size); i++) { \
det_ctx->hsbd[i].buffer_len = 0; \
det_ctx->hsbd[i].offset = 0; \
} \
} while (0)
int index = 0;
uint8_t *buffer = NULL;
*buffer_len = 0;
if (det_ctx->hsbd_buffers_list_len == 0) {
HSBDCreateSpace(det_ctx, 1);
if (HSBDCreateSpace(det_ctx, 1) < 0)
goto end;
index = 0;
} else {
if ((tx_id - det_ctx->hsbd_start_tx_id) < det_ctx->hsbd_buffers_list_len) {
@ -99,7 +104,8 @@ static uint8_t *DetectEngineHSBDGetBufferForTX(int tx_id,
return det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer;
}
} else {
HSBDCreateSpace(det_ctx, (tx_id - det_ctx->hsbd_start_tx_id) + 1);
if (HSBDCreateSpace(det_ctx, (tx_id - det_ctx->hsbd_start_tx_id) + 1) < 0)
goto end;
}
index = (tx_id - det_ctx->hsbd_start_tx_id);
}
@ -214,7 +220,7 @@ static uint8_t *DetectEngineHSBDGetBufferForTX(int tx_id,
return buffer;
}
int DetectEngineRunHttpServerBodyMpmV2(DetectEngineCtx *de_ctx,
int DetectEngineRunHttpServerBodyMpm(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Flow *f,
HtpState *htp_state, uint8_t flags)
{
@ -257,65 +263,37 @@ int DetectEngineRunHttpServerBodyMpmV2(DetectEngineCtx *de_ctx,
return cnt;
}
int DetectEngineInspectHttpServerBodyV2(ThreadVars *tv,
int DetectEngineInspectHttpServerBody(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
int r = 0;
HtpState *htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
FLOWLOCK_WRLOCK(f);
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
/* get the transaction id */
int idx = AppLayerTransactionGetInspectId(f);
/* error! get out of here */
if (idx == -1)
goto end;
int size = (int)list_size(htp_state->connp->conn->transactions);
for (; idx < size; idx++) {
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
uint32_t buffer_len = 0;
uint8_t *buffer = DetectEngineHSBDGetBufferForTX(idx,
uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx_id,
de_ctx, det_ctx,
f, htp_state,
flags,
&buffer_len);
if (buffer_len == 0)
continue;
return 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HSBDMATCH],
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HSBDMATCH],
f,
buffer,
buffer_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSBD, NULL);
if (r == 1) {
break;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
return r;
return 0;
}
void DetectEngineCleanHSBDBuffersV2(DetectEngineThreadCtx *det_ctx)
void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx)
{
if (det_ctx->hsbd_buffers_list_len > 0) {
for (int i = 0; i < det_ctx->hsbd_buffers_list_len; i++) {

@ -27,15 +27,15 @@
#include "app-layer-htp.h"
int DetectEngineRunHttpServerBodyMpmV2(DetectEngineCtx *de_ctx,
int DetectEngineRunHttpServerBodyMpm(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Flow *f,
HtpState *htp_state, uint8_t flags);
int DetectEngineInspectHttpServerBodyV2(ThreadVars *tv,
int DetectEngineInspectHttpServerBody(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id);
void DetectEngineCleanHSBDBuffersV2(DetectEngineThreadCtx *det_ctx);
void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx);
void DetectEngineHttpServerBodyRegisterTests(void);

@ -119,62 +119,24 @@ int DetectEngineInspectHttpStatCode(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
SCReturnInt(0);
}
/* locking the flow, we will inspect the htp state */
FLOWLOCK_RDLOCK(f);
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
#ifdef DEBUG
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_HSCDMATCH];
DetectContentData *co = (DetectContentData *)sm->ctx;
SCLogDebug("co->id %"PRIu32, co->id);
#endif
int idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
htp_tx_t *tx = NULL;
int size = (int)list_size(htp_state->connp->conn->transactions);
for ( ; idx < size; idx++)
{
tx = list_get(htp_state->connp->conn->transactions, idx);
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL || tx->response_status == NULL)
continue;
return 0;
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
det_ctx->inspection_recursion_counter = 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s,
int r = DetectEngineContentInspection(de_ctx, det_ctx, s,
s->sm_lists[DETECT_SM_LIST_HSCDMATCH],
f,
(uint8_t *)bstr_ptr(tx->response_status),
bstr_len(tx->response_status),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSCD, NULL);
if (r == 1) {
goto end;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -119,62 +119,24 @@ int DetectEngineInspectHttpStatMsg(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
SCReturnInt(0);
}
/* locking the flow, we will inspect the htp state */
FLOWLOCK_RDLOCK(f);
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
#ifdef DEBUG
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_HSMDMATCH];
DetectContentData *co = (DetectContentData *)sm->ctx;
SCLogDebug("co->id %"PRIu32, co->id);
#endif
int idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
htp_tx_t *tx = NULL;
int size = (int)list_size(htp_state->connp->conn->transactions);
for ( ; idx < size; idx++)
{
tx = list_get(htp_state->connp->conn->transactions, idx);
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL || tx->response_message == NULL)
continue;
return 0;
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
det_ctx->inspection_recursion_counter = 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s,
int r = DetectEngineContentInspection(de_ctx, det_ctx, s,
s->sm_lists[DETECT_SM_LIST_HSMDMATCH],
f,
(uint8_t *)bstr_ptr(tx->response_message),
bstr_len(tx->response_message),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSMD, NULL);
if (r == 1) {
goto end;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -125,61 +125,30 @@ int DetectEngineInspectHttpUA(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = NULL;
htp_tx_t *tx = NULL;
int idx;
FLOWLOCK_RDLOCK(f);
htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
goto end;
}
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
int size = (int)list_size(htp_state->connp->conn->transactions);
for (; idx < size; idx++) {
tx = list_get(htp_state->connp->conn->transactions, idx);
HtpState *htp_state = (HtpState *)alstate;
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL)
continue;
return 0;
htp_header_t *h = (htp_header_t *)table_getc(tx->request_headers,
"User-Agent");
if (h == NULL) {
SCLogDebug("HTTP user agent header not present in this request");
continue;
return 0;
}
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HUADMATCH],
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HUADMATCH],
f,
(uint8_t *)bstr_ptr(h->value),
bstr_len(h->value),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HUAD, NULL);
if (r == 1) {
break;
}
}
if (r == 1)
return 1;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -409,198 +409,47 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
/* Check the uricontent, http client body, http header keywords here */
if (alproto == ALPROTO_HTTP) {
if (flags & STREAM_TOSERVER) {
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_URI_INSPECT;
SCLogDebug("inspecting uri");
FLOWLOCK_WRLOCK(f);
if (DetectEngineInspectPacketUris(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1)
{
SCLogDebug("uri matched");
match_flags |= DE_STATE_FLAG_URI_MATCH;
} else {
SCLogDebug("uri inspected but no match");
}
}
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HCBD_INSPECT;
if (DetectEngineInspectHttpClientBodyV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HCBD_MATCH;
}
SCLogDebug("inspecting http client body");
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSBDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSBD_INSPECT;
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HHD_INSPECT;
if (DetectEngineInspectHttpHeaderV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HHD_MATCH;
}
SCLogDebug("inspecting http header");
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HRHD_INSPECT;
if (DetectEngineInspectHttpRawHeader(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HRHD_MATCH;
}
SCLogDebug("inspecting http raw header");
}
if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HMD_INSPECT;
if (DetectEngineInspectHttpMethod(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HMD_MATCH;
}
SCLogDebug("inspecting http method");
}
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HCD_INSPECT;
if (DetectEngineInspectHttpCookie(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HCD_MATCH;
}
SCLogDebug("inspecting http cookie");
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HRUD_INSPECT;
if (DetectEngineInspectHttpRawUri(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HRUD_MATCH;
}
SCLogDebug("inspecting http raw uri");
HtpState *htp_state = (HtpState *)alstate;
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
FLOWLOCK_UNLOCK(f);
SCReturnInt(0);
}
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TS_INSPECT;
int tx_id = AppLayerTransactionGetInspectId(f);
if (tx_id == -1) {
FLOWLOCK_UNLOCK(f);
SCReturnInt(0);
}
match = DetectFileInspectHttp(tv, de_ctx, det_ctx, s, f, flags, alstate, 0);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TS_MATCH;
} else if (match == 2) {
int total_txs = (int)list_size(htp_state->connp->conn->transactions);
for ( ; tx_id < total_txs; tx_id++) {
DetectEngineAppInspectionEngine *engine =
app_inspection_engine[ALPROTO_HTTP][(flags & STREAM_TOSERVER) ? 0 : 1];
while (engine != NULL) {
if (s->sm_lists[engine->sm_list] != NULL) {
inspect_flags |= engine->inspect_flags;
int r = engine->Callback(tv, de_ctx, det_ctx, s, f,
flags, alstate, tx_id);
if (r == 1) {
match_flags |= engine->match_flags;
} else if (r == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
} else if (r == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSCD_INSPECT;
}
if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HUAD_INSPECT;
if (DetectEngineInspectHttpUA(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HUAD_MATCH;
}
SCLogDebug("inspecting http cookie");
}
} else if (flags & STREAM_TOCLIENT) {
/* For to client set the flags in inspect so it can't match
* if the sig requires something only the request has. The rest
* will be inspected in the opposite direction. */
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_URI_INSPECT;
}
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HCBD_INSPECT;
}
if (s->sm_lists[DETECT_SM_LIST_HSBDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSBD_INSPECT;
if (DetectEngineInspectHttpServerBodyV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HSBD_MATCH;
}
SCLogDebug("inspecting http server body");
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HHD_INSPECT;
if (DetectEngineInspectHttpHeaderV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HHD_MATCH;
}
SCLogDebug("inspecting http header");
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HRHD_INSPECT;
if (DetectEngineInspectHttpRawHeader(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HRHD_MATCH;
engine = engine->next;
}
SCLogDebug("inspecting http raw header");
}
if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HMD_INSPECT;
}
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HCD_INSPECT;
if (DetectEngineInspectHttpCookie(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HCD_MATCH;
}
SCLogDebug("inspecting http cookie");
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HRUD_INSPECT;
if (inspect_flags == match_flags)
break;
}
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TC_INSPECT;
FLOWLOCK_UNLOCK(f);
match = DetectFileInspectHttp(tv, de_ctx, det_ctx, s, f, flags, alstate, 0);
SCLogDebug("match %d", match);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TC_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
if (DetectEngineInspectHttpStatMsg(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HSMD_MATCH;
}
SCLogDebug("inspecting http stat msg");
}
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSCD_INSPECT;
if (DetectEngineInspectHttpStatCode(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HSCD_MATCH;
}
SCLogDebug("inspecting http stat code");
}
if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HUAD_INSPECT;
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_DCE_INSPECT;
@ -809,266 +658,47 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
/* let's continue detection */
/* first, check uricontent */
if (alproto == ALPROTO_HTTP && (flags & STREAM_TOSERVER)) {
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_URI_MATCH)) {
SCLogDebug("inspecting uri");
inspect_flags |= DE_STATE_FLAG_URI_INSPECT;
if (DetectEngineInspectPacketUris(tv, de_ctx, det_ctx, s,
f, flags, alstate, 0) == 1)
{
SCLogDebug("uri matched");
match_flags |= DE_STATE_FLAG_URI_MATCH;
} else {
SCLogDebug("uri inspected but no match");
}
} else {
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");
inspect_flags |= DE_STATE_FLAG_HCBD_INSPECT;
if (DetectEngineInspectHttpClientBodyV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http client body matched");
match_flags |= DE_STATE_FLAG_HCBD_MATCH;
}
}
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSBDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSBD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HSBD_INSPECT;
}
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HHD_MATCH)) {
SCLogDebug("inspecting http header data");
inspect_flags |= DE_STATE_FLAG_HHD_INSPECT;
if (DetectEngineInspectHttpHeaderV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http header matched");
match_flags |= DE_STATE_FLAG_HHD_MATCH;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HRHD_MATCH)) {
SCLogDebug("inspecting http raw header data");
inspect_flags |= DE_STATE_FLAG_HRHD_INSPECT;
if (DetectEngineInspectHttpRawHeader(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http raw header matched");
match_flags |= DE_STATE_FLAG_HRHD_MATCH;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HMD_MATCH)) {
SCLogDebug("inspecting http method data");
inspect_flags |= DE_STATE_FLAG_HMD_INSPECT;
if (DetectEngineInspectHttpMethod(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http method matched");
match_flags |= DE_STATE_FLAG_HMD_MATCH;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HCD_MATCH)) {
SCLogDebug("inspecting http cookie data");
inspect_flags |= DE_STATE_FLAG_HCD_INSPECT;
if (DetectEngineInspectHttpCookie(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http cookie matched");
match_flags |= DE_STATE_FLAG_HCD_MATCH;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HRUD_MATCH)) {
SCLogDebug("inspecting http raw uri data");
inspect_flags |= DE_STATE_FLAG_HRUD_INSPECT;
if (DetectEngineInspectHttpRawUri(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http raw uri matched");
match_flags |= DE_STATE_FLAG_HRUD_MATCH;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_FILE_TS_MATCH)) {
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TS_INSPECT;
match = DetectFileInspectHttp(tv, de_ctx, det_ctx, s, f, flags, alstate, 0);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TS_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSMD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
}
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSCD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HSCD_INSPECT;
}
}
if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HUAD_MATCH)) {
SCLogDebug("inspecting http user agent data");
inspect_flags |= DE_STATE_FLAG_HUAD_INSPECT;
if (alproto == ALPROTO_HTTP) {
FLOWLOCK_WRLOCK(f);
if (DetectEngineInspectHttpUA(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http user agent matched");
match_flags |= DE_STATE_FLAG_HUAD_MATCH;
}
}
}
} else if (alproto == ALPROTO_HTTP && (flags & STREAM_TOCLIENT)) {
/* For to client set the flags in inspect so it can't match
* if the sig requires something only the request has. The rest
* will be inspected in the opposite direction. */
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_URI_MATCH)) {
inspect_flags |= DE_STATE_FLAG_URI_INSPECT;
}
}
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HCBD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HCBD_INSPECT;
}
HtpState *htp_state = (HtpState *)alstate;
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
FLOWLOCK_UNLOCK(f);
SCReturnInt(0);
}
if (s->sm_lists[DETECT_SM_LIST_HSBDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSBD_MATCH)) {
SCLogDebug("inspecting http server body data");
inspect_flags |= DE_STATE_FLAG_HSBD_INSPECT;
if (DetectEngineInspectHttpServerBodyV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http server body matched");
match_flags |= DE_STATE_FLAG_HSBD_MATCH;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HHD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HHD_INSPECT;
if (DetectEngineInspectHttpHeaderV2(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HHD_MATCH;
}
}
SCLogDebug("inspecting http header");
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HRHD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HRHD_INSPECT;
if (DetectEngineInspectHttpRawHeader(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HRHD_MATCH;
}
SCLogDebug("inspecting http raw header");
}
}
if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HMD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HMD_INSPECT;
}
}
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HCD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HCD_INSPECT;
if (DetectEngineInspectHttpCookie(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
match_flags |= DE_STATE_FLAG_HCD_MATCH;
}
SCLogDebug("inspecting http cookie");
}
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HRUD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HRUD_INSPECT;
}
int tx_id = AppLayerTransactionGetInspectId(f);
if (tx_id == -1) {
FLOWLOCK_UNLOCK(f);
SCReturnInt(0);
}
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_FILE_TC_MATCH)) {
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TC_INSPECT;
match = DetectFileInspectHttp(tv, de_ctx, det_ctx, s, f, flags, alstate, 0);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TC_MATCH;
} else if (match == 2) {
int total_txs = (int)list_size(htp_state->connp->conn->transactions);
for ( ; tx_id < total_txs; tx_id++) {
DetectEngineAppInspectionEngine *engine =
app_inspection_engine[ALPROTO_HTTP][(flags & STREAM_TOSERVER) ? 0 : 1];
while (engine != NULL) {
if (s->sm_lists[engine->sm_list] != NULL && !(item->flags & engine->match_flags)) {
inspect_flags |= engine->inspect_flags;
int r = engine->Callback(tv, de_ctx, det_ctx, s, f,
flags, alstate, tx_id);
if (r == 1) {
match_flags |= engine->match_flags;
} else if (r == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
} else if (r == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSMD_MATCH)) {
SCLogDebug("inspecting http stat msg data");
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
if (DetectEngineInspectHttpStatMsg(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http stat msg matched");
match_flags |= DE_STATE_FLAG_HSMD_MATCH;
}
engine = engine->next;
}
if (inspect_flags == match_flags)
break;
}
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSCD_MATCH)) {
SCLogDebug("inspecting http stat code data");
inspect_flags |= DE_STATE_FLAG_HSCD_INSPECT;
if (DetectEngineInspectHttpStatCode(tv, de_ctx, det_ctx, s, f,
flags, alstate, 0) == 1) {
SCLogDebug("http stat code matched");
match_flags |= DE_STATE_FLAG_HSCD_MATCH;
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HUAD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HUAD_INSPECT;
}
}
FLOWLOCK_UNLOCK(f);
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {

@ -65,43 +65,11 @@ int DetectEngineInspectPacketUris(ThreadVars *tv,
Signature *s, Flow *f, uint8_t flags,
void *alstate, int tx_id)
{
SCEnter();
int r = 0;
HtpState *htp_state = NULL;
HtpState *htp_state = (HtpState *)alstate;
htp_state = (HtpState *)alstate;
if (htp_state == NULL) {
SCLogDebug("no HTTP state");
SCReturnInt(0);
}
/* locking the flow, we will inspect the htp state */
FLOWLOCK_RDLOCK(f);
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
SCLogDebug("HTP state has no conn(p)");
goto end;
}
#ifdef DEBUG
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_UMATCH];
DetectContentData *co = (DetectContentData *)sm->ctx;
SCLogDebug("co->id %"PRIu32, co->id);
#endif
int idx = AppLayerTransactionGetInspectId(f);
if (idx == -1) {
goto end;
}
htp_tx_t *tx = NULL;
int size = (int)list_size(htp_state->connp->conn->transactions);
for ( ; idx < size; idx++)
{
tx = list_get(htp_state->connp->conn->transactions, idx);
htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
if (tx == NULL || tx->request_uri_normalized == NULL)
continue;
return 0;
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
@ -112,25 +80,16 @@ int DetectEngineInspectPacketUris(ThreadVars *tv,
/* Inspect all the uricontents fetched on each
* transaction at the app layer */
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_UMATCH],
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_UMATCH],
f,
(uint8_t *)bstr_ptr(tx->request_uri_normalized),
bstr_len(tx->request_uri_normalized),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_URI, NULL);
//r = DoInspectPacketUri(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_UMATCH],
//(uint8_t *)bstr_ptr(tx->request_uri_normalized),
//bstr_len(tx->request_uri_normalized));
if (r == 1) {
break;
return 1;
}
}
if (r < 1)
r = 0;
end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(r);
return 0;
}
/***********************************Unittests**********************************/

@ -42,7 +42,21 @@
#include "detect-engine-iponly.h"
#include "detect-engine-tag.h"
#include "detect-engine-uri.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hsbd.h"
#include "detect-engine-hhd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-hscd.h"
#include "detect-engine-hua.h"
#include "detect-engine-file.h"
#include "detect-engine.h"
#include "detect-engine-state.h"
#include "detect-byte-extract.h"
#include "detect-content.h"
@ -64,6 +78,7 @@
#include "util-var-name.h"
#include "tm-threads.h"
#include "runmodes.h"
#ifdef PROFILING
#include "util-profiling.h"
@ -77,6 +92,256 @@ static TmEcode DetectEngineThreadCtxInitForLiveRuleSwap(ThreadVars *, void *, vo
static uint8_t DetectEngineCtxLoadConf(DetectEngineCtx *);
/* 2 - for each direction */
DetectEngineAppInspectionEngine *app_inspection_engine[ALPROTO_MAX][2];
#if 0
static void DetectEnginePrintAppInspectionEngines(DetectEngineAppInspectionEngine *list[][2])
{
printf("\n");
uint16_t alproto = ALPROTO_UNKNOWN + 1;
for ( ; alproto < ALPROTO_MAX; alproto++) {
printf("alproto - %d\n", alproto);
int dir = 0;
for ( ; dir < 2; dir++) {
printf(" direction - %d\n", dir);
DetectEngineAppInspectionEngine *engine = list[alproto][dir];
while (engine != NULL) {
printf(" engine->alproto - %"PRIu16"\n", engine->alproto);
printf(" engine->dir - %"PRIu16"\n", engine->dir);
printf(" engine->sm_list - %d\n", engine->sm_list);
printf(" engine->inspect_flags - %"PRIu32"\n", engine->inspect_flags);
printf(" engine->match_flags - %"PRIu32"\n", engine->match_flags);
printf("\n");
engine = engine->next;
}
} /* for ( ; dir < 2; dir++) */
} /* for ( ; alproto < ALPROTO_MAX; alproto++) */
return;
}
#endif
void DetectEngineRegisterAppInspectionEngines(void)
{
struct tmp_t {
uint16_t alproto;
int32_t sm_list;
uint32_t inspect_flags;
uint32_t match_flags;
uint16_t dir;
int (*Callback)(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
int32_t tx_id);
};
struct tmp_t data_toserver[] = {
{ ALPROTO_HTTP,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
DE_STATE_FLAG_URI_MATCH,
0,
DetectEngineInspectPacketUris },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HCBDMATCH,
DE_STATE_FLAG_HCBD_INSPECT,
DE_STATE_FLAG_HCBD_MATCH,
0,
DetectEngineInspectHttpClientBody },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HHDMATCH,
DE_STATE_FLAG_HHD_INSPECT,
DE_STATE_FLAG_HHD_MATCH,
0,
DetectEngineInspectHttpHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HRHDMATCH,
DE_STATE_FLAG_HRHD_INSPECT,
DE_STATE_FLAG_HRHD_MATCH,
0,
DetectEngineInspectHttpRawHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HMDMATCH,
DE_STATE_FLAG_HMD_INSPECT,
DE_STATE_FLAG_HMD_MATCH,
0,
DetectEngineInspectHttpMethod },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HCDMATCH,
DE_STATE_FLAG_HCD_INSPECT,
DE_STATE_FLAG_HCD_MATCH,
0,
DetectEngineInspectHttpCookie },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HRUDMATCH,
DE_STATE_FLAG_HRUD_INSPECT,
DE_STATE_FLAG_HRUD_MATCH,
0,
DetectEngineInspectHttpRawUri },
{ ALPROTO_HTTP,
DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TS_INSPECT,
DE_STATE_FLAG_FILE_TS_MATCH,
0,
DetectFileInspectHttp },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HUADMATCH,
DE_STATE_FLAG_HUAD_INSPECT,
DE_STATE_FLAG_HUAD_MATCH,
0,
DetectEngineInspectHttpUA },
};
struct tmp_t data_toclient[] = {
{ ALPROTO_HTTP,
DETECT_SM_LIST_HSBDMATCH,
DE_STATE_FLAG_HSBD_INSPECT,
DE_STATE_FLAG_HSBD_MATCH,
1,
DetectEngineInspectHttpServerBody },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HHDMATCH,
DE_STATE_FLAG_HHD_INSPECT,
DE_STATE_FLAG_HHD_MATCH,
1,
DetectEngineInspectHttpHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HRHDMATCH,
DE_STATE_FLAG_HRHD_INSPECT,
DE_STATE_FLAG_HRHD_MATCH,
1,
DetectEngineInspectHttpRawHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HCDMATCH,
DE_STATE_FLAG_HCD_INSPECT,
DE_STATE_FLAG_HCD_MATCH,
1,
DetectEngineInspectHttpCookie },
{ ALPROTO_HTTP,
DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TC_INSPECT,
DE_STATE_FLAG_FILE_TC_MATCH,
1,
DetectFileInspectHttp },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HSMDMATCH,
DE_STATE_FLAG_HSMD_INSPECT,
DE_STATE_FLAG_HSMD_MATCH,
1,
DetectEngineInspectHttpStatMsg },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HSCDMATCH,
DE_STATE_FLAG_HSCD_INSPECT,
DE_STATE_FLAG_HSCD_MATCH,
1,
DetectEngineInspectHttpStatCode }
};
size_t i;
for (i = 0 ; i < sizeof(data_toserver) / sizeof(struct tmp_t); i++) {
DetectEngineRegisterAppInspectionEngine(data_toserver[i].alproto,
data_toserver[i].dir,
data_toserver[i].sm_list,
data_toserver[i].inspect_flags,
data_toserver[i].match_flags,
data_toserver[i].Callback,
app_inspection_engine);
}
for (i = 0 ; i < sizeof(data_toclient) / sizeof(struct tmp_t); i++) {
DetectEngineRegisterAppInspectionEngine(data_toclient[i].alproto,
data_toclient[i].dir,
data_toclient[i].sm_list,
data_toclient[i].inspect_flags,
data_toclient[i].match_flags,
data_toclient[i].Callback,
app_inspection_engine);
}
#if 0
DetectEnginePrintAppInspectionEngines(app_inspection_engine);
#endif
return;
}
static void AppendAppInspectionEngine(DetectEngineAppInspectionEngine *engine,
DetectEngineAppInspectionEngine *list[][2])
{
/* append to the list */
DetectEngineAppInspectionEngine *tmp = list[engine->alproto][engine->dir];
DetectEngineAppInspectionEngine *insert = NULL;
while (tmp != NULL) {
if (tmp->dir == engine->dir &&
(tmp->sm_list == engine->sm_list ||
tmp->inspect_flags == engine->inspect_flags ||
tmp->match_flags == engine->match_flags)) {
SCLogError(SC_ERR_DETECT_PREPARE, "App Inspection Engine already "
"registered for this direction(%"PRIu16") ||"
"sm_list(%d) || "
"[match(%"PRIu32")|inspect(%"PRIu32")]_flags",
tmp->dir, tmp->sm_list, tmp->inspect_flags,
tmp->match_flags);
exit(EXIT_FAILURE);
}
insert = tmp;
tmp = tmp->next;
}
if (insert == NULL)
list[engine->alproto][engine->dir] = engine;
else
insert->next = engine;
return;
}
void DetectEngineRegisterAppInspectionEngine(uint16_t alproto,
uint16_t dir,
int32_t sm_list,
uint32_t inspect_flags,
uint32_t match_flags,
int (*Callback)(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
int32_t tx_id),
DetectEngineAppInspectionEngine *list[][2])
{
if ((list == NULL) ||
(alproto <= ALPROTO_UNKNOWN && alproto >= ALPROTO_FAILED) ||
(dir > 1) ||
(sm_list < DETECT_SM_LIST_MATCH || sm_list >= DETECT_SM_LIST_MAX) ||
(Callback == NULL)) {
SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid arguments");
exit(EXIT_FAILURE);
}
DetectEngineAppInspectionEngine *new_engine = SCMalloc(sizeof(DetectEngineAppInspectionEngine));
if (unlikely(new_engine == NULL)) {
exit(EXIT_FAILURE);
}
memset(new_engine, 0, sizeof(*new_engine));
new_engine->alproto = alproto;
new_engine->dir = dir;
new_engine->sm_list = sm_list;
new_engine->inspect_flags = inspect_flags;
new_engine->match_flags = match_flags;
new_engine->Callback = Callback;
AppendAppInspectionEngine(new_engine, list);
return;
}
static void *DetectEngineLiveRuleSwap(void *arg)
{
SCEnter();
@ -1183,6 +1448,309 @@ static int DetectEngineTest04(void)
return result;
}
int DummyTestAppInspectionEngine01(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *sig,
Flow *f,
uint8_t flags,
void *alstate,
int32_t tx_id)
{
return 0;
}
int DummyTestAppInspectionEngine02(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *sig,
Flow *f,
uint8_t flags,
void *alstate,
int32_t tx_id)
{
return 0;
}
int DetectEngineTest05(void)
{
int result = 0;
DetectEngineAppInspectionEngine *engine_list[ALPROTO_MAX][2];
memset(engine_list, 0, sizeof(engine_list));
DetectEngineRegisterAppInspectionEngine(ALPROTO_HTTP,
0 /* STREAM_TOSERVER */,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
DE_STATE_FLAG_URI_MATCH,
DummyTestAppInspectionEngine01,
engine_list);
int alproto = ALPROTO_UNKNOWN + 1;
for ( ; alproto < ALPROTO_FAILED; alproto++) {
int dir = 0;
for ( ; dir < 2; dir++) {
if (alproto == ALPROTO_HTTP && dir == 0) {
if (engine_list[alproto][dir]->next != NULL) {
printf("more than one entry found\n");
goto end;
}
DetectEngineAppInspectionEngine *engine = engine_list[alproto][dir];
if (engine->alproto != alproto ||
engine->dir != dir ||
engine->sm_list != DETECT_SM_LIST_UMATCH ||
engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT ||
engine->match_flags != DE_STATE_FLAG_URI_MATCH ||
engine->Callback != DummyTestAppInspectionEngine01) {
printf("failed for http and dir(0-toserver)\n");
goto end;
}
} /* if (alproto == ALPROTO_HTTP && dir == 0) */
if (alproto == ALPROTO_HTTP && dir == 1) {
if (engine_list[alproto][dir] != NULL) {
printf("failed for http and dir(1-toclient)\n");
goto end;
}
}
if (alproto != ALPROTO_HTTP &&
engine_list[alproto][0] != NULL &&
engine_list[alproto][1] != NULL) {
printf("failed for protocol %d\n", alproto);
goto end;
}
} /* for ( ; dir < 2 ..)*/
} /* for ( ; alproto < ALPROTO_FAILED; ..) */
result = 1;
end:
return result;
}
int DetectEngineTest06(void)
{
int result = 0;
DetectEngineAppInspectionEngine *engine_list[ALPROTO_MAX][2];
memset(engine_list, 0, sizeof(engine_list));
DetectEngineRegisterAppInspectionEngine(ALPROTO_HTTP,
0 /* STREAM_TOSERVER */,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
DE_STATE_FLAG_URI_MATCH,
DummyTestAppInspectionEngine01,
engine_list);
DetectEngineRegisterAppInspectionEngine(ALPROTO_HTTP,
1 /* STREAM_TOCLIENT */,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
DE_STATE_FLAG_URI_MATCH,
DummyTestAppInspectionEngine02,
engine_list);
int alproto = ALPROTO_UNKNOWN + 1;
for ( ; alproto < ALPROTO_FAILED; alproto++) {
int dir = 0;
for ( ; dir < 2; dir++) {
if (alproto == ALPROTO_HTTP && dir == 0) {
if (engine_list[alproto][dir]->next != NULL) {
printf("more than one entry found\n");
goto end;
}
DetectEngineAppInspectionEngine *engine = engine_list[alproto][dir];
if (engine->alproto != alproto ||
engine->dir != dir ||
engine->sm_list != DETECT_SM_LIST_UMATCH ||
engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT ||
engine->match_flags != DE_STATE_FLAG_URI_MATCH ||
engine->Callback != DummyTestAppInspectionEngine01) {
printf("failed for http and dir(0-toserver)\n");
goto end;
}
} /* if (alproto == ALPROTO_HTTP && dir == 0) */
if (alproto == ALPROTO_HTTP && dir == 1) {
if (engine_list[alproto][dir]->next != NULL) {
printf("more than one entry found\n");
goto end;
}
DetectEngineAppInspectionEngine *engine = engine_list[alproto][dir];
if (engine->alproto != alproto ||
engine->dir != dir ||
engine->sm_list != DETECT_SM_LIST_UMATCH ||
engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT ||
engine->match_flags != DE_STATE_FLAG_URI_MATCH ||
engine->Callback != DummyTestAppInspectionEngine02) {
printf("failed for http and dir(0-toclient)\n");
goto end;
}
} /* if (alproto == ALPROTO_HTTP && dir == 1) */
if (alproto != ALPROTO_HTTP &&
engine_list[alproto][0] != NULL &&
engine_list[alproto][1] != NULL) {
printf("failed for protocol %d\n", alproto);
goto end;
}
} /* for ( ; dir < 2 ..)*/
} /* for ( ; alproto < ALPROTO_FAILED; ..) */
result = 1;
end:
return result;
}
int DetectEngineTest07(void)
{
int result = 0;
DetectEngineAppInspectionEngine *engine_list[ALPROTO_MAX][2];
memset(engine_list, 0, sizeof(engine_list));
struct test_data_t {
int32_t sm_list;
uint32_t inspect_flags;
uint32_t match_flags;
uint16_t dir;
int (*Callback)(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
int32_t tx_id);
};
struct test_data_t data[] = {
{ DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
DE_STATE_FLAG_URI_MATCH,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HCBDMATCH,
DE_STATE_FLAG_HCBD_INSPECT,
DE_STATE_FLAG_HCBD_MATCH,
0,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HSBDMATCH,
DE_STATE_FLAG_HSBD_INSPECT,
DE_STATE_FLAG_HSBD_MATCH,
1,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HHDMATCH,
DE_STATE_FLAG_HHD_INSPECT,
DE_STATE_FLAG_HHD_MATCH,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HRHDMATCH,
DE_STATE_FLAG_HRHD_INSPECT,
DE_STATE_FLAG_HRHD_MATCH,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HMDMATCH,
DE_STATE_FLAG_HMD_INSPECT,
DE_STATE_FLAG_HMD_MATCH,
0,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HCDMATCH,
DE_STATE_FLAG_HCD_INSPECT,
DE_STATE_FLAG_HCD_MATCH,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HRUDMATCH,
DE_STATE_FLAG_HRUD_INSPECT,
DE_STATE_FLAG_HRUD_MATCH,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TS_INSPECT,
DE_STATE_FLAG_FILE_TS_MATCH,
0,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TC_INSPECT,
DE_STATE_FLAG_FILE_TC_MATCH,
1,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HSMDMATCH,
DE_STATE_FLAG_HSMD_INSPECT,
DE_STATE_FLAG_HSMD_MATCH,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HSCDMATCH,
DE_STATE_FLAG_HSCD_INSPECT,
DE_STATE_FLAG_HSCD_MATCH,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HUADMATCH,
DE_STATE_FLAG_HUAD_INSPECT,
DE_STATE_FLAG_HUAD_MATCH,
0,
DummyTestAppInspectionEngine02 },
};
size_t i = 0;
for ( ; i < sizeof(data) / sizeof(struct test_data_t); i++) {
DetectEngineRegisterAppInspectionEngine(ALPROTO_HTTP,
data[i].dir /* STREAM_TOCLIENT */,
data[i].sm_list,
data[i].inspect_flags,
data[i].match_flags,
data[i].Callback,
engine_list);
}
#if 0
DetectEnginePrintAppInspectionEngines(engine_list);
#endif
int alproto = ALPROTO_UNKNOWN + 1;
for ( ; alproto < ALPROTO_FAILED; alproto++) {
int dir = 0;
for ( ; dir < 2; dir++) {
if (alproto == ALPROTO_HTTP) {
DetectEngineAppInspectionEngine *engine = engine_list[alproto][dir];
size_t i = 0;
for ( ; i < (sizeof(data) / sizeof(struct test_data_t)); i++) {
if (data[i].dir != dir)
continue;
if (engine->alproto != ALPROTO_HTTP ||
engine->dir != data[i].dir ||
engine->sm_list != data[i].sm_list ||
engine->inspect_flags != data[i].inspect_flags ||
engine->match_flags != data[i].match_flags ||
engine->Callback != data[i].Callback) {
printf("failed for http\n");
goto end;
}
engine = engine->next;
}
} else {
if (engine_list[alproto][0] != NULL &&
engine_list[alproto][1] != NULL) {
printf("failed for protocol %d\n", alproto);
goto end;
}
} /* else */
} /* for ( ; dir < 2; dir++) */
} /* for ( ; alproto < ALPROTO_FAILED; ..) */
result = 1;
end:
return result;
}
#endif
void DetectEngineRegisterTests()
@ -1193,6 +1761,9 @@ void DetectEngineRegisterTests()
UtRegisterTest("DetectEngineTest02", DetectEngineTest02, 1);
UtRegisterTest("DetectEngineTest03", DetectEngineTest03, 1);
UtRegisterTest("DetectEngineTest04", DetectEngineTest04, 1);
UtRegisterTest("DetectEngineTest05", DetectEngineTest05, 1);
UtRegisterTest("DetectEngineTest06", DetectEngineTest06, 1);
UtRegisterTest("DetectEngineTest07", DetectEngineTest07, 1);
#endif
return;

@ -27,7 +27,26 @@
#include "detect.h"
#include "tm-threads.h"
typedef struct DetectEngineAppInspectionEngine_ {
uint16_t alproto;
uint16_t dir;
int32_t sm_list;
uint32_t inspect_flags;
uint32_t match_flags;
int (*Callback)(ThreadVars *tv,
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f, uint8_t flags, void *alstate,
int32_t tx_id);
struct DetectEngineAppInspectionEngine_ *next;
} DetectEngineAppInspectionEngine;
extern DetectEngineAppInspectionEngine *app_inspection_engine[ALPROTO_MAX][2];
/* prototypes */
void DetectEngineRegisterAppInspectionEngines(void);
void DetectEngineSpawnLiveRuleSwapMgmtThread(void);
DetectEngineCtx *DetectEngineCtxInit(void);
DetectEngineCtx *DetectEngineGetGlobalDeCtx(void);
@ -41,5 +60,28 @@ TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *);
void DetectEngineResetMaxSigId(DetectEngineCtx *);
void DetectEngineRegisterTests(void);
/**
* \brief Registers an app inspection engine.
*
* \param alproto App layer protocol for which we will register the engine.
* \param direction The direction for the engine. 0 - toserver; 1- toclient.
* \param sm_list The SigMatch list against which the engine works.
* \param inspect_flags The inspection flags to be used by de_state
* against the engine.
* \param match_flags The match flags to be used by de_state in tandem with
* the inpsect_flags.
* \param Callback The engine callback.
*/
void DetectEngineRegisterAppInspectionEngine(uint16_t alproto,
uint16_t direction,
int32_t sm_list,
uint32_t inspect_flags,
uint32_t match_flags,
int (*Callback)(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
int32_t tx_id),
DetectEngineAppInspectionEngine *list[][2]);
#endif /* __DETECT_ENGINE_H__ */

@ -1261,7 +1261,7 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCBD) {
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCBD);
DetectEngineRunHttpClientBodyMpmV2(de_ctx, det_ctx, p->flow, alstate, flags);
DetectEngineRunHttpClientBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCBD);
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HMD) {
@ -1277,7 +1277,7 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
} else { /* implied FLOW_PKT_TOCLIENT */
if (p->flowflags & FLOW_PKT_TOCLIENT && det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSBD) {
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSBD);
DetectEngineRunHttpServerBodyMpmV2(de_ctx, det_ctx, p->flow, alstate, flags);
DetectEngineRunHttpServerBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSBD);
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSMD) {
@ -1293,7 +1293,7 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHD) {
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHD);
DetectEngineRunHttpHeaderMpmV2(det_ctx, p->flow, alstate, flags);
DetectEngineRunHttpHeaderMpm(det_ctx, p->flow, alstate, flags);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHD);
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) {
@ -1901,12 +1901,9 @@ end:
/* cleanup pkt specific part of the patternmatcher */
PacketPatternCleanup(th_v, det_ctx);
//DetectEngineCleanHCBDBuffers(det_ctx);
DetectEngineCleanHCBDBuffersV2(det_ctx);
//DetectEngineCleanHSBDBuffers(det_ctx);
DetectEngineCleanHSBDBuffersV2(det_ctx);
//DetectEngineCleanHHDBuffers(det_ctx);
DetectEngineCleanHHDBuffersV2(det_ctx);
DetectEngineCleanHCBDBuffers(det_ctx);
DetectEngineCleanHSBDBuffers(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

@ -1520,6 +1520,8 @@ int main(int argc, char **argv)
AppLayerHtpNeedFileInspection();
DetectEngineRegisterAppInspectionEngines();
if (rule_reload) {
if (sig_file == NULL)
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2Idle);

Loading…
Cancel
Save