]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
file_data: update to API v2
authorVictor Julien <victor@inliniac.net>
Wed, 1 Nov 2017 07:33:09 +0000 (08:33 +0100)
committerVictor Julien <victor@inliniac.net>
Wed, 14 Feb 2018 13:25:46 +0000 (14:25 +0100)
As we can have multiple files per TX we use the multi inspect
buffer support.

By using this API file_data supports transforms.

Redo part of the flash decompression as a hard coded built-in sort
of transform.

src/detect-engine-filedata.c
src/detect-engine-filedata.h
src/detect-engine-hsbd.c
src/detect-engine-hsbd.h
src/detect-engine.c
src/detect-file-data.c
src/detect.c
src/detect.h
src/util-file-decompression.c
src/util-file-decompression.h

index bf751e16cd0eb0b3f58d5b6da949e0bd014804d8..155706bdab3ae12d3ebb184cdbde077488b2e04f 100644 (file)
 
 #include "app-layer-parser.h"
 
-#define BUFFER_STEP 50
-
-static inline int FiledataCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size)
+static InspectionBuffer *GetBuffer(InspectionBufferMultipleForList *fb, uint32_t id)
 {
-    if (size > det_ctx->file_data_buffers_size) {
-        uint16_t grow_by = size - det_ctx->file_data_buffers_size;
-        grow_by = MAX(grow_by, BUFFER_STEP);
-
-        void *ptmp = SCRealloc(det_ctx->file_data,
-                         (det_ctx->file_data_buffers_size + grow_by) * sizeof(FiledataReassembledBody));
-        if (ptmp == NULL) {
-            SCFree(det_ctx->file_data);
-            det_ctx->file_data = NULL;
-            det_ctx->file_data_buffers_size = 0;
-            det_ctx->file_data_buffers_list_len = 0;
-            return -1;
-        }
-        det_ctx->file_data = ptmp;
-
-        memset(det_ctx->file_data + det_ctx->file_data_buffers_size, 0, grow_by * sizeof(FiledataReassembledBody));
-        det_ctx->file_data_buffers_size += grow_by;
-    }
-    uint16_t i;
-    for (i = det_ctx->file_data_buffers_list_len;
-            i < det_ctx->file_data_buffers_size; i++)
-    {
-        det_ctx->file_data[i].buffer_len = 0;
-        det_ctx->file_data[i].offset = 0;
+    if (id >= fb->size) {
+        uint32_t old_size = fb->size;
+        uint32_t new_size = id + 1;
+        uint32_t grow_by = new_size - old_size;
+        SCLogDebug("size is %u, need %u, so growing by %u", old_size, new_size, grow_by);
+
+        void *ptr = SCRealloc(fb->inspection_buffers, (id + 1) * sizeof(InspectionBuffer));
+        if (ptr == NULL)
+            return NULL;
+
+        InspectionBuffer *to_zero = (InspectionBuffer *)ptr + old_size;
+        SCLogDebug("fb->inspection_buffers %p ptr %p to_zero %p", fb->inspection_buffers, ptr, to_zero);
+        memset((uint8_t *)to_zero, 0, (grow_by * sizeof(InspectionBuffer)));
+        fb->inspection_buffers = ptr;
+        fb->size = new_size;
     }
 
-    return 0;
+    InspectionBuffer *buffer = &fb->inspection_buffers[id];
+    SCLogDebug("using file_data buffer %p", buffer);
+    return buffer;
 }
 
-static const uint8_t *DetectEngineFiledataGetBufferForTX(uint64_t tx_id,
-                                               DetectEngineCtx *de_ctx,
-                                               DetectEngineThreadCtx *det_ctx,
-                                               Flow *f, File *curr_file,
-                                               uint8_t flags,
-                                               uint32_t *buffer_len,
-                                               uint32_t *stream_start_offset)
+static InspectionBuffer *FiledataGetDataCallback(DetectEngineThreadCtx *det_ctx,
+        const DetectEngineTransforms *transforms,
+        Flow *f, uint8_t flow_flags, File *cur_file,
+        int list_id, int local_file_id, bool first)
 {
     SCEnter();
-    int index = 0;
-    const uint8_t *buffer = NULL;
-    *buffer_len = 0;
-    *stream_start_offset = 0;
-    uint64_t file_size = FileDataSize(curr_file);
 
+    InspectionBufferMultipleForList *fb = &det_ctx->multi_inspect_buffers[list_id];
+    InspectionBuffer *buffer = GetBuffer(fb, local_file_id);
+    if (buffer == NULL)
+        return NULL;
+    if (!first && buffer->inspect != NULL)
+        return buffer;
+
+    const uint64_t file_size = FileDataSize(cur_file);
+    const DetectEngineCtx *de_ctx = det_ctx->de_ctx;
     const uint32_t content_limit = de_ctx->filedata_config[f->alproto].content_limit;
     const uint32_t content_inspect_min_size = de_ctx->filedata_config[f->alproto].content_inspect_min_size;
     // TODO this is unused, is that right?
     //const uint32_t content_inspect_window = de_ctx->filedata_config[f->alproto].content_inspect_window;
 
-    if (det_ctx->file_data_buffers_list_len == 0) {
-        if (FiledataCreateSpace(det_ctx, 1) < 0)
-            goto end;
-        index = 0;
-
-        if (det_ctx->file_data_buffers_list_len == 0) {
-            det_ctx->file_data_start_tx_id = tx_id;
-        }
-        det_ctx->file_data_buffers_list_len++;
-    } else {
-        if ((tx_id - det_ctx->file_data_start_tx_id) < det_ctx->file_data_buffers_list_len) {
-            if (det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].buffer_len != 0) {
-                *buffer_len = det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].buffer_len;
-                *stream_start_offset = det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].offset;
-                buffer = det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].buffer;
-
-                SCReturnPtr(buffer, "uint8_t");
-            }
-        } else {
-            if (FiledataCreateSpace(det_ctx, (tx_id - det_ctx->file_data_start_tx_id) + 1) < 0)
-                goto end;
-
-            if (det_ctx->file_data_buffers_list_len == 0) {
-                det_ctx->file_data_start_tx_id = tx_id;
-            }
-            det_ctx->file_data_buffers_list_len++;
-        }
-        index = (tx_id - det_ctx->file_data_start_tx_id);
-    }
-
     SCLogDebug("content_limit %u, content_inspect_min_size %u",
                 content_limit, content_inspect_min_size);
 
-    SCLogDebug("file %p size %"PRIu64", state %d", curr_file, file_size, curr_file->state);
+    SCLogDebug("file %p size %"PRIu64", state %d", cur_file, file_size, cur_file->state);
 
     /* no new data */
-    if (curr_file->content_inspected == file_size) {
+    if (cur_file->content_inspected == file_size) {
         SCLogDebug("no new data");
-        goto end;
+        return NULL;
     }
 
     if (file_size == 0) {
         SCLogDebug("no data to inspect for this transaction");
-        goto end;
+        return NULL;
     }
 
     if ((content_limit == 0 || file_size < content_limit) &&
         file_size < content_inspect_min_size &&
-        !(flags & STREAM_EOF) && !(curr_file->state > FILE_STATE_OPENED)) {
+        !(flow_flags & STREAM_EOF) && !(cur_file->state > FILE_STATE_OPENED)) {
         SCLogDebug("we still haven't seen the entire content. "
                    "Let's defer content inspection till we see the "
                    "entire content.");
-        goto end;
+        return NULL;
     }
 
-    StreamingBufferGetDataAtOffset(curr_file->sb,
-            &det_ctx->file_data[index].buffer, &det_ctx->file_data[index].buffer_len,
-            curr_file->content_inspected);
+    const uint8_t *data;
+    uint32_t data_len;
 
-    det_ctx->file_data[index].offset = curr_file->content_inspected;
+    StreamingBufferGetDataAtOffset(cur_file->sb,
+            &data, &data_len,
+            cur_file->content_inspected);
+    InspectionBufferSetup(buffer, data, data_len);
+    buffer->inspect_offset = cur_file->content_inspected;
+    InspectionBufferApplyTransforms(buffer, transforms);
 
     /* update inspected tracker */
-    curr_file->content_inspected = FileDataSize(curr_file);
-
-    SCLogDebug("content_inspected %"PRIu64", offset %"PRIu64,
-            curr_file->content_inspected, det_ctx->file_data[index].offset);
+    cur_file->content_inspected = file_size;
+    SCLogDebug("content_inspected %"PRIu64, cur_file->content_inspected);
 
-    buffer = det_ctx->file_data[index].buffer;
-    *buffer_len = det_ctx->file_data[index].buffer_len;
-    *stream_start_offset = det_ctx->file_data[index].offset;
+    SCLogDebug("file_data buffer %p, data %p len %u offset %"PRIu64,
+        buffer, buffer->inspect, buffer->inspect_len, buffer->inspect_offset);
 
-end:
-    SCLogDebug("buffer %p, len %u", buffer, *buffer_len);
-    SCReturnPtr(buffer, "uint8_t");
+    SCReturnPtr(buffer, "InspectionBuffer");
 }
 
-int DetectEngineInspectFiledata(ThreadVars *tv,
+int DetectEngineInspectFiledata(
         DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
-        const Signature *s, const SigMatchData *smd,
-        Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id)
+        const DetectEngineAppInspectionEngine *engine,
+        const Signature *s,
+        Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
 {
     int r = 0;
     int match = 0;
-    uint32_t buffer_len = 0;
-    uint32_t stream_start_offset = 0;
-    const uint8_t *buffer = 0;
 
+    // TODO remove
     if (f->alproto == ALPROTO_HTTP) {
-        return DetectEngineInspectHttpServerBody(tv, de_ctx, det_ctx, s,
-                smd, f, flags, alstate, tx, tx_id);
+        abort();
+    }
+
+    const DetectEngineTransforms *transforms = NULL;
+    if (!engine->mpm) {
+        transforms = engine->v2.transforms;
     }
 
     FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto,
@@ -187,33 +151,31 @@ int DetectEngineInspectFiledata(ThreadVars *tv,
         return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
     }
 
+    int local_file_id = 0;
     File *file = ffc->head;
     for (; file != NULL; file = file->next) {
         if (file->txid != tx_id)
             continue;
 
-        buffer = DetectEngineFiledataGetBufferForTX(tx_id,
-                de_ctx, det_ctx,
-                f, file,
-                flags,
-                &buffer_len,
-                &stream_start_offset);
-        if (buffer_len == 0)
+        InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx,
+            transforms, f, flags, file, engine->sm_list, local_file_id, false);
+        if (buffer == NULL)
             continue;
 
         det_ctx->buffer_offset = 0;
         det_ctx->discontinue_matching = 0;
         det_ctx->inspection_recursion_counter = 0;
-        match = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
+        match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
                                               f,
-                                              (uint8_t *)buffer,
-                                              buffer_len,
-                                              stream_start_offset,
+                                              (uint8_t *)buffer->inspect,
+                                              buffer->inspect_len,
+                                              buffer->inspect_offset,
                                               DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
         if (match == 1) {
             r = 1;
             break;
         }
+        local_file_id++;
     }
 
     if (r == 1)
@@ -222,19 +184,11 @@ int DetectEngineInspectFiledata(ThreadVars *tv,
         return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
 }
 
-void DetectEngineCleanFiledataBuffers(DetectEngineThreadCtx *det_ctx)
-{
-    if (det_ctx->file_data_buffers_list_len > 0) {
-        for (int i = 0; i < det_ctx->file_data_buffers_list_len; i++) {
-            det_ctx->file_data[i].buffer_len = 0;
-            det_ctx->file_data[i].offset = 0;
-        }
-    }
-    det_ctx->file_data_buffers_list_len = 0;
-    det_ctx->file_data_start_tx_id = 0;
-
-    return;
-}
+typedef struct PrefilterMpmFiledata {
+    int list_id;
+    const MpmCtx *mpm_ctx;
+    const DetectEngineTransforms *transforms;
+} PrefilterMpmFiledata;
 
 /** \brief Filedata Filedata Mpm prefilter callback
  *
@@ -244,39 +198,61 @@ void DetectEngineCleanFiledataBuffers(DetectEngineThreadCtx *det_ctx)
  *  \param txv tx to inspect
  *  \param pectx inspection context
  */
-void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx,
+static void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx,
         const void *pectx,
         Packet *p, Flow *f, void *txv,
         const uint64_t idx, const uint8_t flags)
 {
     SCEnter();
 
-    const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
+    const PrefilterMpmFiledata *ctx = (const PrefilterMpmFiledata *)pectx;
+    const MpmCtx *mpm_ctx = ctx->mpm_ctx;
+    const int list_id = ctx->list_id;
+
     FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto,
                                                 f->alstate, flags);
+    int local_file_id = 0;
     if (ffc != NULL) {
         File *file = ffc->head;
         for (; file != NULL; file = file->next) {
             if (file->txid != idx)
                 continue;
 
-            uint32_t buffer_len = 0;
-            uint32_t stream_start_offset = 0;
+            InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx,
+                    ctx->transforms, f, flags, file, list_id, local_file_id, true);
+            if (buffer == NULL)
+                continue;
 
-            const uint8_t *buffer = DetectEngineFiledataGetBufferForTX(idx,
-                                                    det_ctx->de_ctx, det_ctx,
-                                                    f, file,
-                                                    flags,
-                                                    &buffer_len,
-                                                    &stream_start_offset);
-            if (buffer != NULL && buffer_len >= mpm_ctx->minlen) {
+            if (buffer->inspect_len >= mpm_ctx->minlen) {
                 (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
-                        &det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len);
+                        &det_ctx->mtcu, &det_ctx->pmq,
+                        buffer->inspect, buffer->inspect_len);
             }
         }
     }
 }
 
+static void PrefilterMpmFiledataFree(void *ptr)
+{
+    SCFree(ptr);
+}
+
+int PrefilterMpmFiledataRegister(DetectEngineCtx *de_ctx,
+        SigGroupHead *sgh, MpmCtx *mpm_ctx,
+        const DetectMpmAppLayerRegistery *mpm_reg, int list_id)
+{
+    PrefilterMpmFiledata *pectx = SCCalloc(1, sizeof(*pectx));
+    if (pectx == NULL)
+        return -1;
+    pectx->list_id = list_id;
+    pectx->mpm_ctx = mpm_ctx;
+    pectx->transforms = &mpm_reg->v2.transforms;
+
+    return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxFiledata,
+            mpm_reg->v2.alproto, mpm_reg->v2.tx_min_progress,
+            pectx, PrefilterMpmFiledataFree, mpm_reg->pname);
+}
+
 #ifdef UNITTESTS
 #include "tests/detect-engine-filedata.c"
 #endif /* UNITTESTS */
index 515915d3f3630bee1124c6deabe4808b33e80310..6e3d21f60c1d60d18e9ce005803cb2eb85eb10cd 100644 (file)
 int PrefilterMpmFiledataRegister(DetectEngineCtx *de_ctx,
         SigGroupHead *sgh, MpmCtx *mpm_ctx,
         const DetectMpmAppLayerRegistery *mpm_reg, int list_id);
-void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx,
-        const void *pectx,
-        Packet *p, Flow *f, void *txv,
-        const uint64_t idx, const uint8_t flags);
-int DetectEngineInspectFiledata(ThreadVars *tv,
+int DetectEngineInspectFiledata(
         DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
-        const Signature *s, const SigMatchData *smd,
-        Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id);
+        const DetectEngineAppInspectionEngine *engine,
+        const Signature *s,
+        Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
 
 void DetectEngineCleanFiledataBuffers(DetectEngineThreadCtx *det_ctx);
 
index 0ec43e05da423ab8acedfbcfb6cdfd6d97853e17..bc607e132fe9575317d4ba8f495abf3f9cbc8f8c 100644 (file)
 
 #include "util-validate.h"
 
-#define BUFFER_STEP 50
 
-static inline int HSBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint64_t size)
+InspectionBuffer *HttpServerBodyGetDataCallback(DetectEngineThreadCtx *det_ctx,
+        const DetectEngineTransforms *transforms,
+        Flow *f, const uint8_t flow_flags,
+        void *txv, const int list_id)
 {
-    if (size >= (USHRT_MAX - BUFFER_STEP))
-        return -1;
-
-    void *ptmp;
-    if (size > det_ctx->hsbd_buffers_size) {
-        uint16_t grow_by = size - det_ctx->hsbd_buffers_size;
-        grow_by = MAX(grow_by, BUFFER_STEP);
-
-        ptmp = SCRealloc(det_ctx->hsbd,
-                         (det_ctx->hsbd_buffers_size + grow_by) * sizeof(HttpReassembledBody));
-        if (ptmp == NULL) {
-            SCFree(det_ctx->hsbd);
-            det_ctx->hsbd = NULL;
-            det_ctx->hsbd_buffers_size = 0;
-            det_ctx->hsbd_buffers_list_len = 0;
-            return -1;
-        }
-        det_ctx->hsbd = ptmp;
-
-        memset(det_ctx->hsbd + det_ctx->hsbd_buffers_size, 0, grow_by * sizeof(HttpReassembledBody));
-        det_ctx->hsbd_buffers_size += grow_by;
-    }
-    uint16_t i;
-    for (i = det_ctx->hsbd_buffers_list_len; i < det_ctx->hsbd_buffers_size; i++) {
-        det_ctx->hsbd[i].buffer_len = 0;
-        det_ctx->hsbd[i].offset = 0;
-        det_ctx->hsbd[i].decompressed_buffer_len = 0;
-    }
-
-    return 0;
-}
+    SCEnter();
 
-static const uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
-                                               DetectEngineCtx *de_ctx,
-                                               DetectEngineThreadCtx *det_ctx,
-                                               Flow *f, HtpState *htp_state,
-                                               uint8_t flags,
-                                               int *hsbd_index,
-                                               uint32_t *buffer_len,
-                                               uint32_t *stream_start_offset)
-{
-    int index = 0;
-    const uint8_t *buffer = NULL;
-    *buffer_len = 0;
-    *stream_start_offset = 0;
-
-    if (det_ctx->hsbd_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 (HSBDCreateSpace(det_ctx, txs) < 0)
-            goto end;
-        index = (tx_id - base_inspect_id);
-        det_ctx->hsbd_start_tx_id = base_inspect_id;
-        det_ctx->hsbd_buffers_list_len = txs;
-        *hsbd_index = index;
-    } else {
-        if ((tx_id - det_ctx->hsbd_start_tx_id) < det_ctx->hsbd_buffers_list_len) {
-            if (det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer_len != 0) {
-                *buffer_len = det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer_len;
-                *stream_start_offset = det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].offset;
-                *hsbd_index = (tx_id - det_ctx->hsbd_start_tx_id);
-                return det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer;
-            }
-        } else {
-            uint64_t txs = (tx_id - det_ctx->hsbd_start_tx_id) + 1;
-            if (HSBDCreateSpace(det_ctx, txs) < 0)
-                goto end;
+    InspectionBuffer *buffer = &det_ctx->inspect_buffers[list_id];
+    if (buffer->inspect != NULL)
+        return buffer;
 
-            det_ctx->hsbd_buffers_list_len = txs;
-        }
-        index = (tx_id - det_ctx->hsbd_start_tx_id);
-        *hsbd_index = index;
-    }
+    htp_tx_t *tx = txv;
+    HtpState *htp_state = f->alstate;
+    const uint8_t flags = flow_flags;
 
     HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
     if (htud == NULL) {
         SCLogDebug("no htud");
-        goto end;
+        return NULL;
     }
 
     /* no new data */
     if (htud->response_body.body_inspected == htud->response_body.content_len_so_far) {
         SCLogDebug("no new data");
-        goto end;
+        return NULL;
     }
 
     HtpBodyChunk *cur = htud->response_body.first;
     if (cur == NULL) {
         SCLogDebug("No http chunks to inspect for this transacation");
-        goto end;
+        return NULL;
     }
 
     SCLogDebug("response.body_limit %u response_body.content_len_so_far %"PRIu64
@@ -185,7 +120,7 @@ static const uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_i
             SCLogDebug("we still haven't seen the entire response body.  "
                        "Let's defer body inspection till we see the "
                        "entire body.");
-            goto end;
+            return NULL;
         }
     }
 
@@ -211,148 +146,35 @@ static const uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_i
         }
     }
 
-    StreamingBufferGetDataAtOffset(htud->response_body.sb,
-            &det_ctx->hsbd[index].buffer, &det_ctx->hsbd[index].buffer_len,
-            offset);
-    det_ctx->hsbd[index].offset = offset;
-
-    /* move inspected tracker to end of the data. HtpBodyPrune will consider
-     * the window sizes when freeing data */
-    htud->response_body.body_inspected = htud->response_body.content_len_so_far;
-    SCLogDebug("htud->response_body.body_inspected now: %"PRIu64, htud->response_body.body_inspected);
-
-    buffer = det_ctx->hsbd[index].buffer;
-    *buffer_len = det_ctx->hsbd[index].buffer_len;
-    *stream_start_offset = det_ctx->hsbd[index].offset;
- end:
-    return buffer;
-}
-
-/** \brief HTTP Server Body 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 PrefilterTxHttpResponseBody(DetectEngineThreadCtx *det_ctx,
-        const void *pectx,
-        Packet *p, Flow *f, void *txv,
-        const uint64_t idx, const uint8_t flags)
-{
-    SCEnter();
+    const uint8_t *data;
+    uint32_t data_len;
 
-    const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
-    htp_tx_t *tx = (htp_tx_t *)txv;
-    HtpState *htp_state = f->alstate;
-    int ret = 0;
-    int hsbd_index = 0;
-    uint32_t buffer_len = 0;
-    uint32_t stream_start_offset = 0;
-    const uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, idx,
-                                                     NULL, det_ctx,
-                                                     f, htp_state,
-                                                     flags,
-                                                     &hsbd_index,
-                                                     &buffer_len,
-                                                     &stream_start_offset);
+    StreamingBufferGetDataAtOffset(htud->response_body.sb,
+            &data, &data_len, offset);
+    InspectionBufferSetup(buffer, data, data_len);
+    buffer->inspect_offset = offset;
 
+    /* built-in 'transformation' */
     if (htp_state->cfg->swf_decompression_enabled) {
-        int swf_file_type = FileIsSwfFile(buffer, buffer_len);
+        int swf_file_type = FileIsSwfFile(data, data_len);
         if (swf_file_type == FILE_SWF_ZLIB_COMPRESSION ||
             swf_file_type == FILE_SWF_LZMA_COMPRESSION)
         {
-            ret = FileSwfDecompression(buffer, buffer_len,
+            (void)FileSwfDecompression(data, data_len,
                                        det_ctx,
-                                       hsbd_index,
+                                       buffer,
                                        htp_state->cfg->swf_compression_type,
                                        htp_state->cfg->swf_decompress_depth,
                                        htp_state->cfg->swf_compress_depth);
-
-            if (ret == 1 && det_ctx->hsbd &&
-                det_ctx->hsbd[hsbd_index].decompressed_buffer_len != 0) {
-                buffer = det_ctx->hsbd[hsbd_index].decompressed_buffer;
-                buffer_len = det_ctx->hsbd[hsbd_index].decompressed_buffer_len;
-            }
         }
     }
 
-    if (buffer_len >= mpm_ctx->minlen) {
-        (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
-                &det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len);
-    }
-}
-
-int PrefilterTxHttpResponseBodyRegister(DetectEngineCtx *de_ctx,
-        SigGroupHead *sgh, MpmCtx *mpm_ctx)
-{
-    SCEnter();
-
-    return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpResponseBody,
-        ALPROTO_HTTP, HTP_RESPONSE_BODY,
-        mpm_ctx, NULL, "file_data (http response)");
-}
-
-
-int DetectEngineInspectHttpServerBody(ThreadVars *tv,
-        DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
-        const Signature *s, const SigMatchData *smd,
-        Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id)
-{
-    HtpState *htp_state = (HtpState *)alstate;
-    int hsbd_index = 0;
-    uint32_t buffer_len = 0;
-    uint32_t stream_start_offset = 0;
-    const uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, tx_id,
-                                                     de_ctx, det_ctx,
-                                                     f, htp_state,
-                                                     flags,
-                                                     &hsbd_index,
-                                                     &buffer_len,
-                                                     &stream_start_offset);
-
-    if (htp_state->cfg->swf_decompression_enabled) {
-        if (det_ctx->hsbd && det_ctx->hsbd[hsbd_index].decompressed_buffer_len != 0) {
-            buffer = det_ctx->hsbd[hsbd_index].decompressed_buffer;
-            buffer_len = det_ctx->hsbd[hsbd_index].decompressed_buffer_len;
-        }
-    }
-
-    if (buffer_len == 0)
-        goto end;
-
-    det_ctx->buffer_offset = 0;
-    det_ctx->discontinue_matching = 0;
-    det_ctx->inspection_recursion_counter = 0;
-    int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
-                                          f,
-                                          (uint8_t *)buffer,
-                                          buffer_len,
-                                          stream_start_offset,
-                                          DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
-    if (r == 1)
-        return DETECT_ENGINE_INSPECT_SIG_MATCH;
-
- end:
-    if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY)
-        return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
-    else
-        return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
-}
-
-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++) {
-            det_ctx->hsbd[i].buffer_len = 0;
-            det_ctx->hsbd[i].offset = 0;
-        }
-    }
-    det_ctx->hsbd_buffers_list_len = 0;
-    det_ctx->hsbd_start_tx_id = 0;
+    /* move inspected tracker to end of the data. HtpBodyPrune will consider
+     * the window sizes when freeing data */
+    htud->response_body.body_inspected = htud->response_body.content_len_so_far;
+    SCLogDebug("htud->response_body.body_inspected now: %"PRIu64, htud->response_body.body_inspected);
 
-    return;
+    SCReturnPtr(buffer, "InspectionBuffer");
 }
 
 /***********************************Unittests**********************************/
index b11ec651a36a1c933ed83d3f9ec7ecf0b148b3ce..060269b82bb49dbb29a9482d96bbc505bdb92a6c 100644 (file)
@@ -23,8 +23,6 @@
 #ifndef __DETECT_ENGINE_HSBD_H__
 #define __DETECT_ENGINE_HSBD_H__
 
-#define ENGINE_HSBD_BUFFER_LIMIT 20000
-
 #include "app-layer-htp.h"
 
 int PrefilterTxHttpResponseBodyRegister(DetectEngineCtx *de_ctx,
@@ -36,6 +34,10 @@ int DetectEngineInspectHttpServerBody(ThreadVars *tv,
         Flow *f, uint8_t flags, void *alstate,
         void *tx, uint64_t tx_id);
 
+InspectionBuffer *HttpServerBodyGetDataCallback(DetectEngineThreadCtx *det_ctx,
+        const DetectEngineTransforms *transform,
+        Flow *f, const uint8_t flow_flags, void *txv, const int list_id);
+
 void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx);
 
 void DetectEngineHttpServerBodyRegisterTests(void);
index 647205c1d5813bb64aa0f1f4c1efe5e5483aab3e..ac53d1919c02ed2aaf3e07c95cf43ac295037788 100644 (file)
@@ -2451,15 +2451,6 @@ static void DetectEngineThreadCtxFree(DetectEngineThreadCtx *det_ctx)
     if (det_ctx->bj_values != NULL)
         SCFree(det_ctx->bj_values);
 
-    /* HSBD */
-    if (det_ctx->hsbd != NULL) {
-        if (det_ctx->hsbd->decompressed_buffer != NULL) {
-            SCFree(det_ctx->hsbd->decompressed_buffer);
-        }
-        SCLogDebug("det_ctx hsbd %u", det_ctx->hsbd_buffers_size);
-        SCFree(det_ctx->hsbd);
-    }
-
     /* HSCB */
     if (det_ctx->hcbd != NULL) {
         SCLogDebug("det_ctx hcbd %u", det_ctx->hcbd_buffers_size);
index 7136527e94169ba528d36b45fbf11cdc89bc21ca..51a9046717c16344765c2563a21a9e8321cc9e4b 100644 (file)
@@ -54,9 +54,6 @@ static void DetectFiledataRegisterTests(void);
 static void DetectFiledataSetupCallback(Signature *s);
 static int g_file_data_buffer_id = 0;
 
-static int PrefilterTxSmtpFiledataRegister(DetectEngineCtx *de_ctx,
-        SigGroupHead *sgh, MpmCtx *mpm_ctx);
-
 /**
  * \brief Registration function for keyword: file_data
  */
@@ -71,18 +68,20 @@ void DetectFiledataRegister(void)
     sigmatch_table[DETECT_FILE_DATA].RegisterTests = DetectFiledataRegisterTests;
     sigmatch_table[DETECT_FILE_DATA].flags = SIGMATCH_NOOPT;
 
-    DetectAppLayerMpmRegister("file_data", SIG_FLAG_TOSERVER, 2,
-            PrefilterTxSmtpFiledataRegister);
-    DetectAppLayerMpmRegister("file_data", SIG_FLAG_TOCLIENT, 2,
-            PrefilterTxHttpResponseBodyRegister);
+    DetectAppLayerMpmRegister2("file_data", SIG_FLAG_TOSERVER, 2,
+            PrefilterMpmFiledataRegister, NULL,
+            ALPROTO_SMTP, 0);
+    DetectAppLayerMpmRegister2("file_data", SIG_FLAG_TOCLIENT, 2,
+            PrefilterGenericMpmRegister,
+            HttpServerBodyGetDataCallback,
+            ALPROTO_HTTP, HTP_RESPONSE_BODY);
 
-    DetectAppLayerInspectEngineRegister("file_data",
+    DetectAppLayerInspectEngineRegister2("file_data",
             ALPROTO_HTTP, SIG_FLAG_TOCLIENT, HTP_RESPONSE_BODY,
-            DetectEngineInspectFiledata);
-    DetectAppLayerInspectEngineRegister("file_data",
+            DetectEngineInspectBufferGeneric, HttpServerBodyGetDataCallback);
+    DetectAppLayerInspectEngineRegister2("file_data",
             ALPROTO_SMTP, SIG_FLAG_TOSERVER, 0,
-            DetectEngineInspectFiledata);
-
+            DetectEngineInspectFiledata, NULL);
     DetectBufferTypeRegisterSetupCallback("file_data",
             DetectFiledataSetupCallback);
 
@@ -92,16 +91,6 @@ void DetectFiledataRegister(void)
     g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
 }
 
-static int PrefilterTxSmtpFiledataRegister(DetectEngineCtx *de_ctx,
-        SigGroupHead *sgh, MpmCtx *mpm_ctx)
-{
-    SCEnter();
-
-    return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxFiledata,
-        ALPROTO_SMTP, 0,
-        mpm_ctx, NULL, "file_data (smtp)");
-}
-
 #define FILEDATA_CONTENT_LIMIT 100000
 #define FILEDATA_CONTENT_INSPECT_MIN_SIZE 32768
 #define FILEDATA_CONTENT_INSPECT_WINDOW 4096
@@ -163,7 +152,7 @@ static int DetectFiledataSetup (DetectEngineCtx *de_ctx, Signature *s, const cha
         return -1;
     }
 
-    s->init_data->list = DetectBufferTypeGetByName("file_data");
+    DetectBufferSetActiveList(s, DetectBufferTypeGetByName("file_data"));
 
     SetupDetectEngineConfig(de_ctx);
     return 0;
index a0f5e1a874f3dee881ae77b0c0633f116f2965a0..30009ecc069aab5fff5b6b820c1f991a9e8fde85 100644 (file)
@@ -1046,8 +1046,6 @@ static void DetectRunCleanup(DetectEngineThreadCtx *det_ctx,
                     det_ctx->raw_stream_progress);
 
             DetectEngineCleanHCBDBuffers(det_ctx);
-            DetectEngineCleanHSBDBuffers(det_ctx);
-            DetectEngineCleanFiledataBuffers(det_ctx);
         }
     }
     PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP);
index 64efe593b4e3d6749016ec7a29fe56e662268e4f..311f36740480537bdcca32c417c6a7271db2bf0e 100644 (file)
@@ -908,13 +908,6 @@ typedef struct HttpReassembledBody_ {
     uint64_t offset;        /**< data offset */
 } HttpReassembledBody;
 
-typedef struct FiledataReassembledBody_ {
-    const uint8_t *buffer;
-    uint32_t buffer_size;   /**< size of the buffer itself */
-    uint32_t buffer_len;    /**< data len in the buffer */
-    uint64_t offset;        /**< data offset */
-} FiledataReassembledBody;
-
 #define DETECT_FILESTORE_MAX 15
 
 typedef struct SignatureNonPrefilterStore_ {
@@ -977,21 +970,11 @@ typedef struct DetectEngineThreadCtx_ {
     /* counter for the filestore array below -- up here for cache reasons. */
     uint16_t filestore_cnt;
 
-    HttpReassembledBody *hsbd;
-    uint64_t hsbd_start_tx_id;
-    uint16_t hsbd_buffers_size;
-    uint16_t hsbd_buffers_list_len;
-
     HttpReassembledBody *hcbd;
     uint64_t hcbd_start_tx_id;
     uint16_t hcbd_buffers_size;
     uint16_t hcbd_buffers_list_len;
 
-    FiledataReassembledBody *file_data;
-    uint64_t file_data_start_tx_id;
-    uint16_t file_data_buffers_size;
-    uint16_t file_data_buffers_list_len;
-
     /** id for alert counter */
     uint16_t counter_alerts;
 #ifdef PROFILING
index 9ce8158684285a22708859ee3a59d4d59416f48e..9d561e0833453f34de9f5ee2c5e76e85f409d2d3 100644 (file)
@@ -27,6 +27,7 @@
 #include "suricata-common.h"
 #include "suricata.h"
 
+#include "detect-engine.h"
 #include "app-layer-htp.h"
 
 #include "util-file-decompression.h"
@@ -69,7 +70,7 @@ int FileIsSwfFile(const uint8_t *buffer, uint32_t buffer_len)
  */
 int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len,
                          DetectEngineThreadCtx *det_ctx,
-                         int index,
+                         InspectionBuffer *out_buffer,
                          int swf_type,
                          uint32_t decompress_depth,
                          uint32_t compress_depth)
@@ -129,43 +130,35 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len,
     uint32_t decompressed_data_len = (decompress_depth == 0) ? decompressed_swf_len : decompress_depth;
     decompressed_data_len += 8;
 
-    if (det_ctx->hsbd[index].decompressed_buffer_len == 0 ||
-        det_ctx->hsbd[index].decompressed_buffer_len < decompressed_data_len) {
-        void *ptmp = NULL;
-        ptmp = SCRealloc(det_ctx->hsbd[index].decompressed_buffer,
-                         decompressed_data_len);
-        if (ptmp == NULL) {
-            DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_NO_MEM);
-            return 0;
-        }
-        det_ctx->hsbd[index].decompressed_buffer = ptmp;
+    /* make sure the inspection buffer has enough space */
+    InspectionBufferCheckAndExpand(out_buffer, decompressed_data_len);
+    if (out_buffer->size < decompressed_data_len) {
+        DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_NO_MEM);
+        return 0;
     }
-
-    det_ctx->hsbd[index].decompressed_buffer_len = decompressed_data_len;
-    memset(det_ctx->hsbd[index].decompressed_buffer, 0x00,
-           det_ctx->hsbd[index].decompressed_buffer_len);
+    out_buffer->len = decompressed_data_len;
 
     /*
      * FWS format
      * | 4 bytes         | 4 bytes    | n bytes |
      * | 'FWS' + version | script len | data    |
      */
-    det_ctx->hsbd[index].decompressed_buffer[0] = 'F';
-    det_ctx->hsbd[index].decompressed_buffer[1] = 'W';
-    det_ctx->hsbd[index].decompressed_buffer[2] = 'S';
-    det_ctx->hsbd[index].decompressed_buffer[3] = swf_version;
-    memcpy(det_ctx->hsbd[index].decompressed_buffer  + 4, &decompressed_swf_len, 4);
+    out_buffer->buf[0] = 'F';
+    out_buffer->buf[1] = 'W';
+    out_buffer->buf[2] = 'S';
+    out_buffer->buf[3] = swf_version;
+    memcpy(out_buffer->buf + 4, &decompressed_swf_len, 4);
+    memset(out_buffer->buf + 8, 0, decompressed_data_len - 8);
 
     if ((swf_type == HTTP_SWF_COMPRESSION_ZLIB || swf_type == HTTP_SWF_COMPRESSION_BOTH) &&
-        compression_type == FILE_SWF_ZLIB_COMPRESSION)
+            compression_type == FILE_SWF_ZLIB_COMPRESSION)
     {
         /* the first 8 bytes represents the fws header, see 'FWS format' above.
          * data will start from 8th bytes
          */
         r = FileSwfZlibDecompression(det_ctx,
                                      (uint8_t *)buffer + offset, compressed_data_len,
-                                     det_ctx->hsbd[index].decompressed_buffer + 8,
-                                     det_ctx->hsbd[index].decompressed_buffer_len - 8);
+                                     out_buffer->buf + 8, out_buffer->len - 8);
         if (r == 0)
             goto error;
 
@@ -195,8 +188,7 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len,
          */
         r = FileSwfLzmaDecompression(det_ctx,
                                      compressed_data, compressed_data_len,
-                                     det_ctx->hsbd[index].decompressed_buffer + 8,
-                                     det_ctx->hsbd[index].decompressed_buffer_len - 8);
+                                     out_buffer->buf + 8, out_buffer->len - 8);
         SCFree(compressed_data);
         if (r == 0)
             goto error;
@@ -204,11 +196,13 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len,
         goto error;
     }
 
+    /* all went well so switch the buffer's inspect pointer/size
+     * to use the new data. */
+    out_buffer->inspect = out_buffer->buf;
+    out_buffer->inspect_len = out_buffer->len;
+
     return 1;
 
 error:
-    det_ctx->hsbd[index].decompressed_buffer_len = 0;
-    memset(det_ctx->hsbd[index].decompressed_buffer, 0x00,
-           det_ctx->hsbd[index].decompressed_buffer_len);
     return 0;
 }
index 420be043430c6c5c6b6852be4b1dde610b83adfc..043d68319115ec7def493ab73b178b1a64f3b3c6 100644 (file)
@@ -37,7 +37,7 @@ enum {
 int FileIsSwfFile(const uint8_t *buffer, uint32_t buffer_len);
 int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len,
                          DetectEngineThreadCtx *det_ctx,
-                         int hsbd_index,
+                         InspectionBuffer *out_buffer,
                          int swf_type,
                          uint32_t decompress_depth, uint32_t compress_depth);