-/* Copyright (C) 2007-2017 Open Information Security Foundation
+/* Copyright (C) 2007-2021 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
#include "detect-http-header-common.h"
-static inline int CreateSpace(HttpHeaderThreadData *td, uint64_t size);
-
void *HttpHeaderThreadDataInit(void *data)
{
HttpHeaderThreadData *td = SCCalloc(1, sizeof(*td));
if (td != NULL) {
if (data == NULL) {
- td->tx_step = 4;
td->size_step = 512;
} else {
HttpHeaderThreadDataConfig *c = data;
- td->tx_step = c->tx_step;
td->size_step = c->size_step;
}
/* initialize minimal buffers */
- (void)CreateSpace(td, 1);
- int i;
- for (i = 0; i < td->buffers_size; i++) {
- (void)HttpHeaderExpandBuffer(td, &td->buffers[i], 1);
- }
+ (void)HttpHeaderExpandBuffer(td, &td->buffer, 1);
}
return td;
}
void HttpHeaderThreadDataFree(void *data)
{
HttpHeaderThreadData *hdrnames = data;
-
- int i;
- for (i = 0; i < hdrnames->buffers_size; i++) {
- if (hdrnames->buffers[i].buffer)
- SCFree(hdrnames->buffers[i].buffer);
- if (hdrnames->buffers[i].size) {
- SCLogDebug("hdrnames->buffers[%d].size %u (%u)",
- i, hdrnames->buffers[i].size, hdrnames->buffers_size);
- }
- }
- SCFree(hdrnames->buffers);
+ SCFree(hdrnames->buffer.buffer);
SCFree(hdrnames);
}
-static void Reset(HttpHeaderThreadData *hdrnames, uint64_t tick)
-{
- uint16_t i;
- for (i = 0; i < hdrnames->buffers_list_len; i++) {
- hdrnames->buffers[i].len = 0;
- }
- hdrnames->buffers_list_len = 0;
- hdrnames->start_tx_id = 0;
- hdrnames->tick = tick;
-}
-
-static inline int CreateSpace(HttpHeaderThreadData *td, uint64_t size)
-{
- if (size >= SHRT_MAX)
- return -1;
-
- if (size > td->buffers_size) {
- uint16_t extra = td->tx_step;
- while (td->buffers_size + extra < size) {
- extra += td->tx_step;
- }
- SCLogDebug("adding %u to the buffer", extra);
-
- void *ptmp = SCRealloc(td->buffers,
- (td->buffers_size + extra) * sizeof(HttpHeaderBuffer));
- if (ptmp == NULL) {
- SCFree(td->buffers);
- td->buffers = NULL;
- td->buffers_size = 0;
- td->buffers_list_len = 0;
- return -1;
- }
- td->buffers = ptmp;
- memset(td->buffers + td->buffers_size, 0, extra * sizeof(HttpHeaderBuffer));
- td->buffers_size += extra;
- }
- return 0;
-}
-
int HttpHeaderExpandBuffer(HttpHeaderThreadData *td,
HttpHeaderBuffer *buf, uint32_t size)
{
return 0;
}
-HttpHeaderBuffer *HttpHeaderGetBufferSpaceForTXID(DetectEngineThreadCtx *det_ctx,
- Flow *f, uint8_t flags, uint64_t tx_id, const int keyword_id,
- HttpHeaderThreadData **ret_hdr_td)
+HttpHeaderBuffer *HttpHeaderGetBufferSpace(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
+ const int keyword_id, HttpHeaderThreadData **ret_hdr_td)
{
- int index = 0;
*ret_hdr_td = NULL;
HttpHeaderThreadData *hdr_td =
DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, keyword_id);
if (hdr_td == NULL)
return NULL;
- if (hdr_td->tick != det_ctx->ticker)
- Reset(hdr_td, det_ctx->ticker);
*ret_hdr_td = hdr_td;
- if (hdr_td->buffers_list_len == 0) {
- /* get the inspect id to use as a 'base id' */
- uint64_t base_inspect_id = AppLayerParserGetTransactionInspectId(f->alparser, flags);
- BUG_ON(base_inspect_id > tx_id);
- /* see how many space we need for the current tx_id */
- uint64_t txs = (tx_id - base_inspect_id) + 1;
- if (CreateSpace(hdr_td, txs) < 0)
- return NULL;
-
- index = (tx_id - base_inspect_id);
- hdr_td->start_tx_id = base_inspect_id;
- hdr_td->buffers_list_len = txs;
- } else {
- /* tx fits in our current buffers */
- if ((tx_id - hdr_td->start_tx_id) < hdr_td->buffers_list_len) {
- /* if we previously reassembled, return that buffer */
- if (hdr_td->buffers[(tx_id - hdr_td->start_tx_id)].len != 0) {
- return &hdr_td->buffers[(tx_id - hdr_td->start_tx_id)];
- }
- /* otherwise fall through */
- } else {
- /* not enough space, lets expand */
- uint64_t txs = (tx_id - hdr_td->start_tx_id) + 1;
- if (CreateSpace(hdr_td, txs) < 0)
- return NULL;
-
- hdr_td->buffers_list_len = txs;
- }
- index = (tx_id - hdr_td->start_tx_id);
- }
- HttpHeaderBuffer *buf = &hdr_td->buffers[index];
+ HttpHeaderBuffer *buf = &hdr_td->buffer;
+ buf->len = 0;
return buf;
}
} HttpHeaderBuffer;
typedef struct HttpHeaderThreadConfig_ {
- uint16_t tx_step;
uint16_t size_step;
} HttpHeaderThreadDataConfig;
typedef struct HttpHeaderThreadData_ {
- HttpHeaderBuffer *buffers; /**< array of buffers */
- uint16_t buffers_size; /**< number of buffers */
- uint16_t buffers_list_len;
+ HttpHeaderBuffer buffer; /**< array of buffers */
uint16_t size_step; /**< increase size of HttpHeaderBuffer::buffer with this */
- uint16_t tx_step; /**< increase number of txs with this */
- uint64_t start_tx_id;
- uint64_t tick;
} HttpHeaderThreadData;
void *HttpHeaderThreadDataInit(void *data);
void HttpHeaderThreadDataFree(void *data);
-HttpHeaderBuffer *HttpHeaderGetBufferSpaceForTXID(DetectEngineThreadCtx *det_ctx,
- Flow *f, uint8_t flags, uint64_t tx_id, const int keyword_id,
- HttpHeaderThreadData **ret_hdr_td);
+HttpHeaderBuffer *HttpHeaderGetBufferSpace(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags,
+ const int keyword_id, HttpHeaderThreadData **ret_hdr_td);
int HttpHeaderExpandBuffer(HttpHeaderThreadData *td,
HttpHeaderBuffer *buf, uint32_t size);
static int g_buffer_id = 0;
static int g_keyword_thread_id = 0;
-#define BUFFER_TX_STEP 4
#define BUFFER_SIZE_STEP 256
-static HttpHeaderThreadDataConfig g_td_config = { BUFFER_TX_STEP, BUFFER_SIZE_STEP };
+static HttpHeaderThreadDataConfig g_td_config = { BUFFER_SIZE_STEP };
-static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
- DetectEngineThreadCtx *det_ctx,
- Flow *f, uint8_t flags, uint32_t *buffer_len)
+static uint8_t *GetBufferForTX(
+ htp_tx_t *tx, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, uint32_t *buffer_len)
{
*buffer_len = 0;
HttpHeaderThreadData *hdr_td = NULL;
- HttpHeaderBuffer *buf = HttpHeaderGetBufferSpaceForTXID(det_ctx, f, flags,
- tx_id, g_keyword_thread_id, &hdr_td);
+ HttpHeaderBuffer *buf =
+ HttpHeaderGetBufferSpace(det_ctx, f, flags, g_keyword_thread_id, &hdr_td);
if (unlikely(buf == NULL)) {
return NULL;
- } else if (buf->len > 0) {
- /* already filled buf, reuse */
- *buffer_len = buf->len;
- return buf->buffer;
}
htp_table_t *headers;
return buf->buffer;
}
-static InspectionBuffer *GetBuffer2ForTX(DetectEngineThreadCtx *det_ctx,
- const DetectEngineTransforms *transforms, Flow *_f, const uint8_t flow_flags, void *txv,
+static InspectionBuffer *GetBuffer1ForTX(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv,
const int list_id)
{
- InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
- if (buffer->inspect == NULL) {
- uint32_t b_len = 0;
- const uint8_t *b = NULL;
-
- if (rs_http2_tx_get_header_names(txv, flow_flags, &b, &b_len) != 1)
- return NULL;
- if (b == NULL || b_len == 0)
- return NULL;
-
- InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len);
- InspectionBufferApplyTransforms(buffer, transforms);
- }
-
- return buffer;
-}
-
-typedef struct PrefilterMpmHttpHeaderCtx {
- int list_id;
- const MpmCtx *mpm_ctx;
- const DetectEngineTransforms *transforms;
-} PrefilterMpmHttpHeaderCtx;
-
-/** \brief HTTP Headers Mpm prefilter callback
- *
- * \param det_ctx detection engine thread ctx
- * \param p packet to inspect
- * \param f flow to inspect
- * \param txv tx to inspect
- * \param pectx inspection context
- */
-static void PrefilterTxHttpRequestHeaderNames(DetectEngineThreadCtx *det_ctx,
- const void *pectx,
- Packet *p, Flow *f, void *txv,
- const uint64_t idx, const uint8_t flags)
-{
- SCEnter();
-
- htp_tx_t *tx = (htp_tx_t *)txv;
- if (tx->request_headers == NULL)
- return;
-
- const PrefilterMpmHttpHeaderCtx *ctx = pectx;
- const MpmCtx *mpm_ctx = ctx->mpm_ctx;
- SCLogDebug("running on list %d", ctx->list_id);
-
- const int list_id = ctx->list_id;
- InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
- if (buffer->inspect == NULL) {
- uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx,
- f, flags, &rawdata_len);
- if (rawdata_len == 0)
- return;
-
- /* setup buffer and apply transforms */
- InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len);
- InspectionBufferApplyTransforms(buffer, ctx->transforms);
- }
-
- const uint32_t data_len = buffer->inspect_len;
- const uint8_t *data = buffer->inspect;
-
- SCLogDebug("mpm'ing buffer:");
- //PrintRawDataFp(stdout, data, data_len);
-
- if (data != NULL && data_len >= mpm_ctx->minlen) {
- (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
- &det_ctx->mtcu, &det_ctx->pmq, data, data_len);
- }
-}
-
-static void PrefilterMpmHttpHeaderFree(void *ptr)
-{
- SCFree(ptr);
-}
-
-static int PrefilterTxHttpRequestHeaderNamesRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx,
- const DetectBufferMpmRegistery *mpm_reg, int list_id)
-{
- SCEnter();
-
- PrefilterMpmHttpHeaderCtx *pectx = SCCalloc(1, sizeof(*pectx));
- if (pectx == NULL)
- return -1;
- pectx->list_id = list_id;
- pectx->mpm_ctx = mpm_ctx;
- pectx->transforms = &mpm_reg->transforms;
-
- int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpRequestHeaderNames,
- mpm_reg->app_v2.alproto, HTP_REQUEST_HEADERS,
- pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname);
- if (r != 0) {
- SCFree(pectx);
- return r;
- }
-
- return r;
-}
-
-/** \brief HTTP Headers Mpm prefilter callback
- *
- * \param det_ctx detection engine thread ctx
- * \param p packet to inspect
- * \param f flow to inspect
- * \param txv tx to inspect
- * \param pectx inspection context
- */
-static void PrefilterTxHttpResponseHeaderNames(DetectEngineThreadCtx *det_ctx,
- const void *pectx,
- Packet *p, Flow *f, void *txv,
- const uint64_t idx, const uint8_t flags)
-{
- SCEnter();
-
- htp_tx_t *tx = (htp_tx_t *)txv;
- if (tx->response_headers == NULL)
- return;
-
- const PrefilterMpmHttpHeaderCtx *ctx = pectx;
- const MpmCtx *mpm_ctx = ctx->mpm_ctx;
- SCLogDebug("running on list %d", ctx->list_id);
-
- const int list_id = ctx->list_id;
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx,
- f, flags, &rawdata_len);
+ uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flow_flags, &rawdata_len);
if (rawdata_len == 0)
- return;
+ return NULL;
- /* setup buffer and apply transforms */
InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len);
- InspectionBufferApplyTransforms(buffer, ctx->transforms);
- }
-
- const uint32_t data_len = buffer->inspect_len;
- const uint8_t *data = buffer->inspect;
-
- SCLogDebug("mpm'ing buffer:");
- //PrintRawDataFp(stdout, data, data_len);
-
- if (data != NULL && data_len >= mpm_ctx->minlen) {
- (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
- &det_ctx->mtcu, &det_ctx->pmq, data, data_len);
- }
-}
-
-static int PrefilterTxHttpResponseHeaderNamesRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx,
- const DetectBufferMpmRegistery *mpm_reg, int list_id)
-{
- SCEnter();
-
- PrefilterMpmHttpHeaderCtx *pectx = SCCalloc(1, sizeof(*pectx));
- if (pectx == NULL)
- return -1;
- pectx->list_id = list_id;
- pectx->mpm_ctx = mpm_ctx;
- pectx->transforms = &mpm_reg->transforms;
-
- int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpResponseHeaderNames,
- mpm_reg->app_v2.alproto, HTP_RESPONSE_HEADERS,
- pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname);
- if (r != 0) {
- SCFree(pectx);
- return r;
+ InspectionBufferApplyTransforms(buffer, transforms);
}
- return r;
+ return buffer;
}
-static int InspectEngineHttpHeaderNames(
- DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
- const DetectEngineAppInspectionEngine *engine,
- const Signature *s,
- Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
+static InspectionBuffer *GetBuffer2ForTX(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms, Flow *_f, const uint8_t flow_flags, void *txv,
+ const int list_id)
{
- const int list_id = engine->sm_list;
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
- SCLogDebug("setting up inspect buffer %d", list_id);
+ uint32_t b_len = 0;
+ const uint8_t *b = NULL;
- /* if prefilter didn't already run, we need to consider transformations */
- const DetectEngineTransforms *transforms = NULL;
- if (!engine->mpm) {
- transforms = engine->v2.transforms;
- }
+ if (rs_http2_tx_get_header_names(txv, flow_flags, &b, &b_len) != 1)
+ return NULL;
+ if (b == NULL || b_len == 0)
+ return NULL;
- uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, tx_id, det_ctx,
- f, flags, &rawdata_len);
- if (rawdata_len == 0) {
- SCLogDebug("no data");
- goto end;
- }
- /* setup buffer and apply transforms */
- InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len);
+ InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len);
InspectionBufferApplyTransforms(buffer, transforms);
}
- const uint32_t data_len = buffer->inspect_len;
- const uint8_t *data = buffer->inspect;
- const uint64_t offset = buffer->inspect_offset;
-
- det_ctx->buffer_offset = 0;
- det_ctx->discontinue_matching = 0;
- det_ctx->inspection_recursion_counter = 0;
- int r = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
- NULL, f, (uint8_t *)data, data_len, offset,
- DETECT_CI_FLAGS_SINGLE,
- DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
- if (r == 1)
- return DETECT_ENGINE_INSPECT_SIG_MATCH;
-
- end:
- if (flags & STREAM_TOSERVER) {
- if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) >
- HTP_REQUEST_HEADERS)
- return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
- } else {
- if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) >
- HTP_RESPONSE_HEADERS)
- return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
- }
- return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ return buffer;
}
/**
sigmatch_table[DETECT_AL_HTTP_HEADER_NAMES].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER;
- DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2,
- PrefilterTxHttpRequestHeaderNamesRegister, NULL, ALPROTO_HTTP1, HTP_REQUEST_HEADERS);
- DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2,
- PrefilterTxHttpResponseHeaderNamesRegister, NULL, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS);
+ /* http1 */
+ DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
+ GetBuffer1ForTX, ALPROTO_HTTP1, HTP_REQUEST_HEADERS);
+ DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
+ GetBuffer1ForTX, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS);
DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOSERVER,
- HTP_REQUEST_HEADERS, InspectEngineHttpHeaderNames, NULL);
+ HTP_REQUEST_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX);
DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOCLIENT,
- HTP_RESPONSE_HEADERS, InspectEngineHttpHeaderNames, NULL);
+ HTP_RESPONSE_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX);
+ /* http2 */
DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
GetBuffer2ForTX, ALPROTO_HTTP2, HTTP2StateDataClient);
DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
-/* Copyright (C) 2007-2018 Open Information Security Foundation
+/* Copyright (C) 2007-2021 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
static int g_http_header_buffer_id = 0;
static int g_keyword_thread_id = 0;
-#define BUFFER_TX_STEP 4
#define BUFFER_SIZE_STEP 1024
-static HttpHeaderThreadDataConfig g_td_config = { BUFFER_TX_STEP, BUFFER_SIZE_STEP };
+static HttpHeaderThreadDataConfig g_td_config = { BUFFER_SIZE_STEP };
-static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
- DetectEngineThreadCtx *det_ctx,
- Flow *f, uint8_t flags, uint32_t *buffer_len)
+static uint8_t *GetBufferForTX(
+ htp_tx_t *tx, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, uint32_t *buffer_len)
{
*buffer_len = 0;
HttpHeaderThreadData *hdr_td = NULL;
- HttpHeaderBuffer *buf = HttpHeaderGetBufferSpaceForTXID(det_ctx, f, flags,
- tx_id, g_keyword_thread_id, &hdr_td);
+ HttpHeaderBuffer *buf =
+ HttpHeaderGetBufferSpace(det_ctx, f, flags, g_keyword_thread_id, &hdr_td);
if (unlikely(buf == NULL)) {
return NULL;
- } else if (buf->len > 0) {
- /* already filled buf, reuse */
- *buffer_len = buf->len;
- return buf->buffer;
}
htp_table_t *headers;
}
uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, tx_id, det_ctx,
- f, flags, &rawdata_len);
+ uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flags, &rawdata_len);
if (rawdata_len == 0) {
SCLogDebug("no data");
goto end;
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx,
- f, flags, &rawdata_len);
+ uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flags, &rawdata_len);
if (rawdata_len == 0)
return;
-/* Copyright (C) 2007-2019 Open Information Security Foundation
+/* Copyright (C) 2007-2021 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
static int g_buffer_id = 0;
static int g_keyword_thread_id = 0;
-#define BUFFER_TX_STEP 4
#define BUFFER_SIZE_STEP 2048
-static HttpHeaderThreadDataConfig g_td_config = { BUFFER_TX_STEP, BUFFER_SIZE_STEP };
+static HttpHeaderThreadDataConfig g_td_config = { BUFFER_SIZE_STEP };
-static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
- DetectEngineThreadCtx *det_ctx,
- Flow *f, uint8_t flags, uint32_t *buffer_len)
+static uint8_t *GetBufferForTX(
+ htp_tx_t *tx, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, uint32_t *buffer_len)
{
*buffer_len = 0;
HttpHeaderThreadData *hdr_td = NULL;
- HttpHeaderBuffer *buf = HttpHeaderGetBufferSpaceForTXID(det_ctx, f, flags,
- tx_id, g_keyword_thread_id, &hdr_td);
+ HttpHeaderBuffer *buf =
+ HttpHeaderGetBufferSpace(det_ctx, f, flags, g_keyword_thread_id, &hdr_td);
if (unlikely(buf == NULL)) {
return NULL;
- } else if (buf->len > 0) {
- /* already filled buf, reuse */
- *buffer_len = buf->len;
- return buf->buffer;
}
bstr *line = NULL;
return buf->buffer;
}
-typedef struct PrefilterMpmHttpStartCtx {
- int list_id;
- const MpmCtx *mpm_ctx;
- const DetectEngineTransforms *transforms;
-} PrefilterMpmHttpStartCtx;
-
-/** \brief HTTP Headers Mpm prefilter callback
- *
- * \param det_ctx detection engine thread ctx
- * \param p packet to inspect
- * \param f flow to inspect
- * \param txv tx to inspect
- * \param pectx inspection context
- */
-static void PrefilterTxHttpRequestStart(DetectEngineThreadCtx *det_ctx,
- const void *pectx,
- Packet *p, Flow *f, void *txv,
- const uint64_t idx, const uint8_t flags)
+static InspectionBuffer *GetBuffer1ForTX(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv,
+ const int list_id)
{
- SCEnter();
-
- const PrefilterMpmHttpStartCtx *ctx = pectx;
- const MpmCtx *mpm_ctx = ctx->mpm_ctx;
- SCLogDebug("running on list %d", ctx->list_id);
-
- const int list_id = ctx->list_id;
- InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
- if (buffer->inspect == NULL) {
- uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx,
- f, flags, &rawdata_len);
- if (rawdata_len == 0)
- return;
-
- /* setup buffer and apply transforms */
- InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len);
- InspectionBufferApplyTransforms(buffer, ctx->transforms);
- }
-
- const uint32_t data_len = buffer->inspect_len;
- const uint8_t *data = buffer->inspect;
-
- SCLogDebug("mpm'ing buffer:");
- //PrintRawDataFp(stdout, data, data_len);
-
- if (data != NULL && data_len >= mpm_ctx->minlen) {
- (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
- &det_ctx->mtcu, &det_ctx->pmq, data, data_len);
- }
-}
-
-static void PrefilterMpmHttpHeaderFree(void *ptr)
-{
- SCFree(ptr);
-}
-
-static int PrefilterTxHttpRequestStartRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx,
- const DetectBufferMpmRegistery *mpm_reg, int list_id)
-{
- SCEnter();
-
- PrefilterMpmHttpStartCtx *pectx = SCCalloc(1, sizeof(*pectx));
- if (pectx == NULL)
- return -1;
- pectx->list_id = list_id;
- pectx->mpm_ctx = mpm_ctx;
- pectx->transforms = &mpm_reg->transforms;
-
- int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpRequestStart,
- mpm_reg->app_v2.alproto, HTP_REQUEST_HEADERS,
- pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname);
- if (r != 0) {
- SCFree(pectx);
- return r;
- }
-
- return r;
-}
-
-/** \brief HTTP Headers Mpm prefilter callback
- *
- * \param det_ctx detection engine thread ctx
- * \param p packet to inspect
- * \param f flow to inspect
- * \param txv tx to inspect
- * \param pectx inspection context
- */
-static void PrefilterTxHttpResponseStart(DetectEngineThreadCtx *det_ctx,
- const void *pectx,
- Packet *p, Flow *f, void *txv,
- const uint64_t idx, const uint8_t flags)
-{
- SCEnter();
-
- const PrefilterMpmHttpStartCtx *ctx = pectx;
- const MpmCtx *mpm_ctx = ctx->mpm_ctx;
- SCLogDebug("running on list %d", ctx->list_id);
-
- const int list_id = ctx->list_id;
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx,
- f, flags, &rawdata_len);
+ uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flow_flags, &rawdata_len);
if (rawdata_len == 0)
- return;
-
- /* setup buffer and apply transforms */
- InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len);
- InspectionBufferApplyTransforms(buffer, ctx->transforms);
- }
-
- const uint32_t data_len = buffer->inspect_len;
- const uint8_t *data = buffer->inspect;
-
- SCLogDebug("mpm'ing buffer:");
- //PrintRawDataFp(stdout, data, data_len);
-
- if (data != NULL && data_len >= mpm_ctx->minlen) {
- (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
- &det_ctx->mtcu, &det_ctx->pmq, data, data_len);
- }
-}
-
-static int PrefilterTxHttpResponseStartRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx,
- const DetectBufferMpmRegistery *mpm_reg, int list_id)
-{
- SCEnter();
-
- PrefilterMpmHttpStartCtx *pectx = SCCalloc(1, sizeof(*pectx));
- if (pectx == NULL)
- return -1;
- pectx->list_id = list_id;
- pectx->mpm_ctx = mpm_ctx;
- pectx->transforms = &mpm_reg->transforms;
-
- int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpResponseStart,
- mpm_reg->app_v2.alproto, HTP_RESPONSE_HEADERS,
- pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname);
- if (r != 0) {
- SCFree(pectx);
- return r;
- }
-
- return r;
-}
-
-static int InspectEngineHttpStart(
- DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
- const DetectEngineAppInspectionEngine *engine,
- const Signature *s,
- Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
-{
- const int list_id = engine->sm_list;
- InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
- if (buffer->inspect == NULL) {
- SCLogDebug("setting up inspect buffer %d", list_id);
-
- /* if prefilter didn't already run, we need to consider transformations */
- const DetectEngineTransforms *transforms = NULL;
- if (!engine->mpm) {
- transforms = engine->v2.transforms;
- }
+ return NULL;
- uint32_t rawdata_len = 0;
- uint8_t *rawdata = GetBufferForTX(txv, tx_id, det_ctx,
- f, flags, &rawdata_len);
- if (rawdata_len == 0) {
- SCLogDebug("no data");
- goto end;
- }
- /* setup buffer and apply transforms */
InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len);
InspectionBufferApplyTransforms(buffer, transforms);
}
- const uint32_t data_len = buffer->inspect_len;
- const uint8_t *data = buffer->inspect;
- const uint64_t offset = buffer->inspect_offset;
-
- det_ctx->buffer_offset = 0;
- det_ctx->discontinue_matching = 0;
- det_ctx->inspection_recursion_counter = 0;
- int r = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
- NULL, f, (uint8_t *)data, data_len, offset,
- DETECT_CI_FLAGS_SINGLE,
- DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
- if (r == 1)
- return DETECT_ENGINE_INSPECT_SIG_MATCH;
-
- end:
- if (flags & STREAM_TOSERVER) {
- if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) >
- HTP_REQUEST_HEADERS)
- return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
- } else {
- if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) >
- HTP_RESPONSE_HEADERS)
- return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
- }
- return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ return buffer;
}
static int DetectHttpStartSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
}
/**
- * \brief Registers the keyword handlers for the "http_header" keyword.
+ * \brief Registers the keyword handlers for the "http_start" keyword.
*/
void DetectHttpStartRegister(void)
{
sigmatch_table[DETECT_AL_HTTP_START].Setup = DetectHttpStartSetup;
sigmatch_table[DETECT_AL_HTTP_START].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER;
- DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2,
- PrefilterTxHttpRequestStartRegister, NULL, ALPROTO_HTTP1, HTP_REQUEST_HEADERS);
- DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2,
- PrefilterTxHttpResponseStartRegister, NULL, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS);
+ DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
+ GetBuffer1ForTX, ALPROTO_HTTP1, HTP_REQUEST_HEADERS);
+ DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
+ GetBuffer1ForTX, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS);
DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOSERVER,
- HTP_REQUEST_HEADERS, InspectEngineHttpStart, NULL);
+ HTP_REQUEST_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX);
DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOCLIENT,
- HTP_RESPONSE_HEADERS, InspectEngineHttpStart, NULL);
+ HTP_RESPONSE_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX);
DetectBufferTypeSetDescriptionByName(BUFFER_NAME,
BUFFER_DESC);