]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http_header: convert to use common code
authorVictor Julien <victor@inliniac.net>
Mon, 19 Dec 2016 16:06:11 +0000 (17:06 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 16 Feb 2017 09:35:41 +0000 (10:35 +0100)
src/detect-engine.c
src/detect-http-header.c
src/detect.c
src/detect.h

index d6a412f21ee09e386eef9babf29341918c371273..24da4209060553c04ccd5b74db4acb08f661dafb 100644 (file)
@@ -1807,8 +1807,6 @@ static DetectEngineThreadCtx *DetectEngineThreadCtxInitForReload(
 
 void DetectEngineThreadCtxFree(DetectEngineThreadCtx *det_ctx)
 {
-    int i;
-
     if (det_ctx->tenant_array != NULL) {
         SCFree(det_ctx->tenant_array);
         det_ctx->tenant_array = NULL;
@@ -1846,18 +1844,6 @@ void DetectEngineThreadCtxFree(DetectEngineThreadCtx *det_ctx)
     if (det_ctx->bj_values != NULL)
         SCFree(det_ctx->bj_values);
 
-    /* HHD temp storage */
-    for (i = 0; i < det_ctx->hhd_buffers_size; i++) {
-        if (det_ctx->hhd_buffers[i] != NULL)
-            SCFree(det_ctx->hhd_buffers[i]);
-    }
-    if (det_ctx->hhd_buffers)
-        SCFree(det_ctx->hhd_buffers);
-    det_ctx->hhd_buffers = NULL;
-    if (det_ctx->hhd_buffers_len)
-        SCFree(det_ctx->hhd_buffers_len);
-    det_ctx->hhd_buffers_len = NULL;
-
     /* HSBD */
     if (det_ctx->hsbd != NULL) {
         SCLogDebug("det_ctx hsbd %u", det_ctx->hsbd_buffers_size);
index fa65b9c062bb8ef5f7a302a02c91e333f950a0ec..5d2e1ec59d219e5501f69104ff35b52839bc1554 100644 (file)
 
 #include "app-layer-htp.h"
 #include "detect-http-header.h"
+#include "detect-http-header-common.h"
 #include "stream-tcp.h"
 
 static int DetectHttpHeaderSetup(DetectEngineCtx *, Signature *, char *);
 static void DetectHttpHeaderRegisterTests(void);
 static void DetectHttpHeaderSetupCallback(Signature *);
 static int g_http_header_buffer_id = 0;
+static int g_keyword_thread_id = 0;
 
-#define BUFFER_STEP 50
+#define BUFFER_TX_STEP      4
+#define BUFFER_SIZE_STEP    1024
+static HttpHeaderThreadDataConfig g_td_config = { BUFFER_TX_STEP, BUFFER_SIZE_STEP };
 
-static inline int HHDCreateSpace(DetectEngineThreadCtx *det_ctx, uint64_t size)
-{
-    if (size >= (USHRT_MAX - BUFFER_STEP))
-        return -1;
-
-    void *ptmp;
-    if (size > det_ctx->hhd_buffers_size) {
-        ptmp = SCRealloc(det_ctx->hhd_buffers,
-                         (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint8_t *));
-        if (ptmp == NULL) {
-            SCFree(det_ctx->hhd_buffers);
-            det_ctx->hhd_buffers = NULL;
-            det_ctx->hhd_buffers_size = 0;
-            det_ctx->hhd_buffers_list_len = 0;
-            return -1;
-        }
-        det_ctx->hhd_buffers = ptmp;
-
-        memset(det_ctx->hhd_buffers + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint8_t *));
-        ptmp = SCRealloc(det_ctx->hhd_buffers_len,
-                         (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint32_t));
-        if (ptmp == NULL) {
-            SCFree(det_ctx->hhd_buffers_len);
-            det_ctx->hhd_buffers_len = NULL;
-            det_ctx->hhd_buffers_size = 0;
-            det_ctx->hhd_buffers_list_len = 0;
-            return -1;
-        }
-        det_ctx->hhd_buffers_len = ptmp;
-
-        memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint32_t));
-        det_ctx->hhd_buffers_size += BUFFER_STEP;
-    }
-    memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_list_len, 0, (size - det_ctx->hhd_buffers_list_len) * sizeof(uint32_t));
-
-    return 0;
-}
-
-static uint8_t *DetectEngineHHDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
-                                              DetectEngineCtx *de_ctx,
-                                              DetectEngineThreadCtx *det_ctx,
-                                              Flow *f, HtpState *htp_state,
-                                              uint8_t flags,
-                                              uint32_t *buffer_len)
+static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
+        DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
+        Flow *f, HtpState *htp_state, uint8_t flags,
+        uint32_t *buffer_len)
 {
-    uint8_t *headers_buffer = NULL;
-    int index = 0;
     *buffer_len = 0;
 
-    if (det_ctx->hhd_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 (HHDCreateSpace(det_ctx, txs) < 0)
-            goto end;
-
-        index = (tx_id - base_inspect_id);
-        det_ctx->hhd_start_tx_id = base_inspect_id;
-        det_ctx->hhd_buffers_list_len = txs;
-    } else {
-        /* tx fits in our current buffers */
-        if ((tx_id - det_ctx->hhd_start_tx_id) < det_ctx->hhd_buffers_list_len) {
-            /* if we previously reassembled, return that buffer */
-            if (det_ctx->hhd_buffers_len[(tx_id - det_ctx->hhd_start_tx_id)] != 0) {
-                *buffer_len = det_ctx->hhd_buffers_len[(tx_id - det_ctx->hhd_start_tx_id)];
-                return det_ctx->hhd_buffers[(tx_id - det_ctx->hhd_start_tx_id)];
-            }
-            /* otherwise fall through */
-        } else {
-            /* not enough space, lets expand */
-            uint64_t txs = (tx_id - det_ctx->hhd_start_tx_id) + 1;
-            if (HHDCreateSpace(det_ctx, txs) < 0)
-                goto end;
-
-            det_ctx->hhd_buffers_list_len = txs;
-        }
-        index = (tx_id - det_ctx->hhd_start_tx_id);
+    HttpHeaderThreadData *hdr_td = NULL;
+    HttpHeaderBuffer *buf = HttpHeaderGetBufferSpaceForTXID(det_ctx, f, flags,
+            tx_id, 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;
     if (flags & STREAM_TOSERVER) {
         if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) <= HTP_REQUEST_HEADERS)
-            goto end;
+            return NULL;
         headers = tx->request_headers;
     } else {
         if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) <= HTP_RESPONSE_HEADERS)
-            goto end;
+            return NULL;
         headers = tx->response_headers;
     }
     if (headers == NULL)
-        goto end;
+        return NULL;
 
-    htp_header_t *h = NULL;
-    headers_buffer = det_ctx->hhd_buffers[index];
-    size_t headers_buffer_len = 0;
     size_t i = 0;
-
     size_t no_of_headers = htp_table_size(headers);
     for (; i < no_of_headers; i++) {
-        h = htp_table_get_index(headers, i, NULL);
+        htp_header_t *h = htp_table_get_index(headers, i, NULL);
         size_t size1 = bstr_size(h->name);
         size_t size2 = bstr_size(h->value);
 
@@ -186,39 +123,35 @@ static uint8_t *DetectEngineHHDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
             }
         }
 
-        /* the extra 4 bytes if for ": " and "\r\n" */
-        uint8_t *new_headers_buffer = SCRealloc(headers_buffer, headers_buffer_len + size1 + size2 + 4);
-        if (unlikely(new_headers_buffer == NULL)) {
-            if (headers_buffer != NULL) {
-                SCFree(headers_buffer);
-                headers_buffer = NULL;
+        size_t size = size1 + size2 + 4;
+#if 0
+        if (i + 1 == no_of_headers)
+            size += 2;
+#endif
+        if (size + buf->len > buf->size) {
+            if (HttpHeaderExpandBuffer(hdr_td, buf, size) != 0) {
+                return NULL;
             }
-            det_ctx->hhd_buffers[index] = NULL;
-            det_ctx->hhd_buffers_len[index] = 0;
-            goto end;
         }
-        headers_buffer = new_headers_buffer;
-
-        memcpy(headers_buffer + headers_buffer_len, bstr_ptr(h->name), size1);
-        headers_buffer_len += size1;
-        headers_buffer[headers_buffer_len] = ':';
-        headers_buffer[headers_buffer_len + 1] = ' ';
-        headers_buffer_len += 2;
-        memcpy(headers_buffer + headers_buffer_len, bstr_ptr(h->value), size2);
-        headers_buffer_len += size2 + 2;
-        /* \r */
-        headers_buffer[headers_buffer_len - 2] = '\r';
-        /* \n */
-        headers_buffer[headers_buffer_len - 1] = '\n';
-    }
-
-    /* store the buffers.  We will need it for further inspection */
-    det_ctx->hhd_buffers[index] = headers_buffer;
-    det_ctx->hhd_buffers_len[index] = headers_buffer_len;
-
-    *buffer_len = (uint32_t)headers_buffer_len;
- end:
-    return headers_buffer;
+
+        memcpy(buf->buffer + buf->len, bstr_ptr(h->name), bstr_size(h->name));
+        buf->len += bstr_size(h->name);
+        buf->buffer[buf->len++] = ':';
+        buf->buffer[buf->len++] = ' ';
+        memcpy(buf->buffer + buf->len, bstr_ptr(h->value), bstr_size(h->value));
+        buf->len += bstr_size(h->value);
+        buf->buffer[buf->len++] = '\r';
+        buf->buffer[buf->len++] = '\n';
+#if 0 // looks like this breaks existing rules
+        if (i + 1 == no_of_headers) {
+            buf->buffer[buf->len++] = '\r';
+            buf->buffer[buf->len++] = '\n';
+        }
+#endif
+    }
+
+    *buffer_len = buf->len;
+    return buf->buffer;
 }
 
 /** \brief HTTP Headers Mpm prefilter callback
@@ -244,11 +177,9 @@ static void PrefilterTxHttpRequestHeaders(DetectEngineThreadCtx *det_ctx,
 
     HtpState *htp_state = f->alstate;
     uint32_t buffer_len = 0;
-    const uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx, idx,
-                                                    NULL, det_ctx,
-                                                    f, htp_state,
-                                                    flags,
-                                                    &buffer_len);
+    const uint8_t *buffer = GetBufferForTX(tx, idx,
+            NULL, det_ctx, f, htp_state,
+            flags, &buffer_len);
 
     if (buffer_len >= mpm_ctx->minlen) {
         (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
@@ -327,7 +258,7 @@ static void PrefilterTxHttpResponseHeaders(DetectEngineThreadCtx *det_ctx,
 
     HtpState *htp_state = f->alstate;
     uint32_t buffer_len = 0;
-    const uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx, idx,
+    const uint8_t *buffer = GetBufferForTX(tx, idx,
                                                     NULL, det_ctx,
                                                     f, htp_state,
                                                     flags,
@@ -394,11 +325,9 @@ static int DetectEngineInspectHttpHeader(ThreadVars *tv,
 {
     HtpState *htp_state = (HtpState *)alstate;
     uint32_t buffer_len = 0;
-    uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx, tx_id,
-                                                    de_ctx, det_ctx,
-                                                    f, htp_state,
-                                                    flags,
-                                                    &buffer_len);
+    uint8_t *buffer = GetBufferForTX(tx, tx_id, de_ctx, det_ctx,
+            f, htp_state,
+            flags, &buffer_len);
     if (buffer_len == 0)
         goto end;
 
@@ -425,20 +354,6 @@ static int DetectEngineInspectHttpHeader(ThreadVars *tv,
     return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
 }
 
-void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *det_ctx)
-{
-    if (det_ctx->hhd_buffers_list_len != 0) {
-        int i;
-        for (i = 0; i < det_ctx->hhd_buffers_list_len; i++) {
-            det_ctx->hhd_buffers_len[i] = 0;
-        }
-        det_ctx->hhd_buffers_list_len = 0;
-    }
-    det_ctx->hhd_start_tx_id = 0;
-
-    return;
-}
-
 /**
  * \brief The setup function for the http_header keyword for a signature.
  *
@@ -499,6 +414,9 @@ void DetectHttpHeaderRegister(void)
             DetectHttpHeaderSetupCallback);
 
     g_http_header_buffer_id = DetectBufferTypeGetByName("http_header");
+
+    g_keyword_thread_id = DetectRegisterThreadCtxGlobalFuncs("http_header",
+            HttpHeaderThreadDataInit, &g_td_config, HttpHeaderThreadDataFree);
 }
 
 /************************************Unittests*********************************/
index 37576ddc36dcba45d5b7c83e25614a67f53f90ac..881608c3a78d74bff750ddb02e6ad014684f7bea 100644 (file)
@@ -1577,7 +1577,6 @@ end:
 
     DetectEngineCleanHCBDBuffers(det_ctx);
     DetectEngineCleanHSBDBuffers(det_ctx);
-    DetectEngineCleanHHDBuffers(det_ctx);
     DetectEngineCleanSMTPBuffers(det_ctx);
 
     /* store the found sgh (or NULL) in the flow to save us from looking it
index 8a68f6774d19dcdf6ddc913b73cf288a1cb7ac62..9b0526384409c4fa4661cc878598275a6a399de4 100644 (file)
@@ -817,12 +817,6 @@ typedef struct DetectEngineThreadCtx_ {
     uint16_t hcbd_buffers_size;
     uint16_t hcbd_buffers_list_len;
 
-    uint8_t **hhd_buffers;
-    uint32_t *hhd_buffers_len;
-    uint16_t hhd_buffers_size;
-    uint16_t hhd_buffers_list_len;
-    uint64_t hhd_start_tx_id;
-
     FiledataReassembledBody *smtp;
     uint64_t smtp_start_tx_id;
     uint16_t smtp_buffers_size;