]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/transform: initial compress_whitespace implementation
authorVictor Julien <victor@inliniac.net>
Wed, 25 Oct 2017 07:27:02 +0000 (09:27 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 14 Feb 2018 13:25:46 +0000 (14:25 +0100)
src/Makefile.am
src/detect-engine-register.c
src/detect-engine-register.h
src/detect-transform-compress-whitespace.c [new file with mode: 0644]
src/detect-transform-compress-whitespace.h [new file with mode: 0644]

index 8413a3182a5dc1ca6bd552ee37cf2e86c079b90a..ffbcdb9db65bf567432378add2bea198736eb818 100644 (file)
@@ -250,6 +250,7 @@ detect-tls.c detect-tls.h \
 detect-tls-cert-validity.c detect-tls-cert-validity.h \
 detect-tls-version.c detect-tls-version.h \
 detect-tos.c detect-tos.h \
+detect-transform-compress-whitespace.c detect-transform-compress-whitespace.h \
 detect-transform-strip-whitespace.c detect-transform-strip-whitespace.h \
 detect-ttl.c detect-ttl.h \
 detect-uricontent.c detect-uricontent.h \
index f5b3cc2092e17b002e89ab39c2eec070bc75daea..972547022a2ea8774a6a2e628e2d1ea45c9d1827 100644 (file)
 #include "detect-ftpdata.h"
 #include "detect-engine-content-inspection.h"
 
+#include "detect-transform-compress-whitespace.h"
 #include "detect-transform-strip-whitespace.h"
 
 #include "util-rule-vars.h"
@@ -481,6 +482,7 @@ void SigTableSetup(void)
     DetectTemplateBufferRegister();
     DetectBypassRegister();
 
+    DetectTransformCompressWhitespaceRegister();
     DetectTransformStripWhitespaceRegister();
 
     /* close keyword registration */
index 94388a05ed5fbd58a34d3a8366544778b1d924aa..a16e36cdd5a63c0a4e70a9d78a2ae44136fcd185 100644 (file)
@@ -199,6 +199,7 @@ enum {
 
     DETECT_PREFILTER,
 
+    DETECT_TRANSFORM_COMPRESS_WHITESPACE,
     DETECT_TRANSFORM_STRIP_WHITESPACE,
 
     /* make sure this stays last */
diff --git a/src/detect-transform-compress-whitespace.c b/src/detect-transform-compress-whitespace.c
new file mode 100644 (file)
index 0000000..60e84b5
--- /dev/null
@@ -0,0 +1,190 @@
+/* Copyright (C) 2007-2010 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
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Victor Julien <victor@inliniac.net>
+ *
+ * Implements the nocase keyword
+ */
+
+#include "suricata-common.h"
+
+#include "detect.h"
+#include "detect-engine.h"
+#include "detect-engine-prefilter.h"
+#include "detect-parse.h"
+#include "detect-transform-compress-whitespace.h"
+
+#include "util-unittest.h"
+#include "util-print.h"
+
+static int DetectTransformCompressWhitespaceSetup (DetectEngineCtx *, Signature *, const char *);
+static void DetectTransformCompressWhitespaceRegisterTests(void);
+
+static void TransformCompressWhitespace(InspectionBuffer *buffer);
+
+void DetectTransformCompressWhitespaceRegister(void)
+{
+    sigmatch_table[DETECT_TRANSFORM_COMPRESS_WHITESPACE].name = "compress_whitespace";
+    sigmatch_table[DETECT_TRANSFORM_COMPRESS_WHITESPACE].desc =
+        "modify buffer to strip whitespace before inspection";
+    sigmatch_table[DETECT_TRANSFORM_COMPRESS_WHITESPACE].url =
+        DOC_URL DOC_VERSION "/rules/transformations.html#compress_whitespace";
+    sigmatch_table[DETECT_TRANSFORM_COMPRESS_WHITESPACE].Transform =
+        TransformCompressWhitespace;
+    sigmatch_table[DETECT_TRANSFORM_COMPRESS_WHITESPACE].Setup =
+        DetectTransformCompressWhitespaceSetup;
+    sigmatch_table[DETECT_TRANSFORM_COMPRESS_WHITESPACE].RegisterTests =
+        DetectTransformCompressWhitespaceRegisterTests;
+
+    sigmatch_table[DETECT_TRANSFORM_COMPRESS_WHITESPACE].flags |= SIGMATCH_NOOPT;
+}
+
+/**
+ *  \internal
+ *  \brief Apply the nocase keyword to the last pattern match, either content or uricontent
+ *  \param det_ctx detection engine ctx
+ *  \param s signature
+ *  \param nullstr should be null
+ *  \retval 0 ok
+ *  \retval -1 failure
+ */
+static int DetectTransformCompressWhitespaceSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr)
+{
+    SCEnter();
+    int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_COMPRESS_WHITESPACE);
+    SCReturnInt(r);
+}
+
+static void TransformCompressWhitespace(InspectionBuffer *buffer)
+{
+    const uint8_t *input = buffer->inspect;
+    const uint32_t input_len = buffer->inspect_len;
+    uint8_t output[input_len]; // we can only shrink
+    uint8_t *oi = output, *os = output;
+
+    //PrintRawDataFp(stdout, input, input_len);
+    for (uint32_t i = 0; i < input_len; ) {
+        if (!(isspace(*input))) {
+            *oi++ = *input++;
+            i++;
+        } else {
+            *oi++ = *input++;
+            i++;
+
+            while (i < input_len && isspace(*input)) {
+                input++;
+                i++;
+            }
+        }
+    }
+    uint32_t output_size = oi - os;
+    //PrintRawDataFp(stdout, output, output_size);
+
+    InspectionBufferCopy(buffer, os, output_size);
+}
+
+#ifdef UNITTESTS
+static int TransformDoubleWhitespace(InspectionBuffer *buffer)
+{
+    const uint8_t *input = buffer->inspect;
+    const uint32_t input_len = buffer->inspect_len;
+    uint8_t output[input_len * 2]; // if all chars are whitespace this fits
+    uint8_t *oi = output, *os = output;
+
+    PrintRawDataFp(stdout, input, input_len);
+    for (uint32_t i = 0; i < input_len; i++) {
+        if (isspace(*input)) {
+            *oi++ = *input;
+        }
+        *oi++ = *input;
+        input++;
+    }
+    uint32_t output_size = oi - os;
+    PrintRawDataFp(stdout, output, output_size);
+
+    InspectionBufferCopy(buffer, os, output_size);
+    return 0;
+}
+
+static int DetectTransformCompressWhitespaceTest01(void)
+{
+    const uint8_t *input = (const uint8_t *)" A B C D ";
+    uint32_t input_len = strlen((char *)input);
+
+    InspectionBuffer buffer;
+    InspectionBufferInit(&buffer, 8);
+    InspectionBufferSetup(&buffer, input, input_len);
+    PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
+    TransformCompressWhitespace(&buffer);
+    PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
+    InspectionBufferFree(&buffer);
+    PASS;
+}
+
+static int DetectTransformCompressWhitespaceTest02(void)
+{
+    const uint8_t *input = (const uint8_t *)" A B C D ";
+    uint32_t input_len = strlen((char *)input);
+
+    InspectionBuffer buffer;
+    InspectionBufferInit(&buffer, 8);
+    InspectionBufferSetup(&buffer, input, input_len);
+    PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
+    TransformDoubleWhitespace(&buffer);
+    PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
+    TransformDoubleWhitespace(&buffer);
+    PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
+    TransformCompressWhitespace(&buffer);
+    PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
+    InspectionBufferFree(&buffer);
+    PASS;
+}
+
+static int DetectTransformCompressWhitespaceTest03(void)
+{
+    const char rule[] = "alert http any any -> any any (http_request_line; strip_whitespace; content:\"GET/HTTP\"; sid:1;)";
+    ThreadVars th_v;
+    DetectEngineThreadCtx *det_ctx = NULL;
+    memset(&th_v, 0, sizeof(th_v));
+
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    FAIL_IF_NULL(de_ctx);
+    Signature *s = DetectEngineAppendSig(de_ctx, rule);
+    FAIL_IF_NULL(s);
+    SigGroupBuild(de_ctx);
+    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+    DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
+    DetectEngineCtxFree(de_ctx);
+    PASS;
+}
+
+#endif
+
+static void DetectTransformCompressWhitespaceRegisterTests(void)
+{
+#ifdef UNITTESTS
+    UtRegisterTest("DetectTransformCompressWhitespaceTest01",
+            DetectTransformCompressWhitespaceTest01);
+    UtRegisterTest("DetectTransformCompressWhitespaceTest02",
+            DetectTransformCompressWhitespaceTest02);
+    UtRegisterTest("DetectTransformCompressWhitespaceTest03",
+            DetectTransformCompressWhitespaceTest03);
+#endif
+}
diff --git a/src/detect-transform-compress-whitespace.h b/src/detect-transform-compress-whitespace.h
new file mode 100644 (file)
index 0000000..800d9a7
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2017 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
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * \file
+ *
+ * \author Victor Julien <victor@inliniac.net>
+ */
+
+#ifndef __DETECT_TRANSFORM_COMPRESS_WHITESPACE_H__
+#define __DETECT_TRANSFORM_COMPRESS_WHITESPACE_H__
+
+/* prototypes */
+void DetectTransformCompressWhitespaceRegister (void);
+
+#endif /* __DETECT_TRANSFORM_COMPRESS_WHITESPACE_H__ */