]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/http: clean up header buffer logic
authorVictor Julien <victor@inliniac.net>
Sat, 11 Sep 2021 07:47:31 +0000 (09:47 +0200)
committerVictor Julien <victor@inliniac.net>
Sat, 11 Sep 2021 09:01:38 +0000 (11:01 +0200)
Simplify and clean up header buffer management. The code was designed
to track buffers for several transactions in parallel, from when the
detection engine wasn't aware of transactions.

For http.start and http.header_names use generic mpm and inspect
functions.

src/detect-http-header-common.c
src/detect-http-header-common.h
src/detect-http-header-names.c
src/detect-http-header.c
src/detect-http-start.c

index 2495d057e7570bb6e1a3a30c43454e8547d7517a..3a8fe08c05ac8b16ffda6358f82440a5dac15a10 100644 (file)
@@ -1,4 +1,4 @@
-/* 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;
 }
@@ -84,59 +76,10 @@ void *HttpHeaderThreadDataInit(void *data)
 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)
 {
@@ -156,51 +99,18 @@ int HttpHeaderExpandBuffer(HttpHeaderThreadData *td,
     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;
 }
index c6fc5c684b89dfe775116d1ee396e8603836c88b..a9c830e2a2356647159600a3efbc39b69f40e31e 100644 (file)
@@ -31,26 +31,19 @@ typedef struct HttpHeaderBuffer_ {
 } 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);
index bc6115e170804d5c5879ba9248f530d2bf3515ca..717178e948696c2cceee08b95923fd7da564865e 100644 (file)
 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;
@@ -150,238 +144,43 @@ static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
     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;
 }
 
 /**
@@ -421,16 +220,18 @@ void DetectHttpHeaderNamesRegister(void)
 
     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,
index 722de79363fa61c221f9f1e08e07441cb87c3e67..bedee8f0c74844081b21f4ff51d72d540c09b802 100644 (file)
@@ -1,4 +1,4 @@
-/* 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
@@ -62,25 +62,19 @@ static void DetectHttpHeaderRegisterTests(void);
 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;
@@ -192,8 +186,7 @@ static int DetectEngineInspectBufferHttpHeader(
         }
 
         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;
@@ -262,8 +255,7 @@ static void PrefilterMpmHttpHeader(DetectEngineThreadCtx *det_ctx,
     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;
 
index 8aaa14e59f6dfd6952adf42e1eefd5aa60ed6255..3341d775b1c980fe1cc5a6e1c9387d11a34d611b 100644 (file)
@@ -1,4 +1,4 @@
-/* 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;
@@ -155,209 +149,22 @@ static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
     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)
@@ -372,7 +179,7 @@ static int DetectHttpStartSetup(DetectEngineCtx *de_ctx, Signature *s, const cha
 }
 
 /**
- * \brief Registers the keyword handlers for the "http_header" keyword.
+ * \brief Registers the keyword handlers for the "http_start" keyword.
  */
 void DetectHttpStartRegister(void)
 {
@@ -383,15 +190,15 @@ 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);