summaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/util-action.c
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:21:41 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:21:41 -0700
commit8879b125d26e8db1a5633de5a9c692eb2d1c4f83 (patch)
treec7259d85a991b83dfa85ab2e339360669fc1f58e /framework/src/suricata/src/util-action.c
parent13d05bc8458758ee39cb829098241e89616717ee (diff)
suricata checkin based on commit id a4bce14770beee46a537eda3c3f6e8e8565d5d0a
Change-Id: I9a214fa0ee95e58fc640e50bd604dac7f42db48f
Diffstat (limited to 'framework/src/suricata/src/util-action.c')
-rw-r--r--framework/src/suricata/src/util-action.c1627
1 files changed, 1627 insertions, 0 deletions
diff --git a/framework/src/suricata/src/util-action.c b/framework/src/suricata/src/util-action.c
new file mode 100644
index 00000000..2b349748
--- /dev/null
+++ b/framework/src/suricata/src/util-action.c
@@ -0,0 +1,1627 @@
+/* Copyright (C) 2007-2013 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 Pablo Rincon <pablo.rincon.crespo@gmail.com>
+ */
+
+#include "suricata-common.h"
+
+#include "action-globals.h"
+#include "conf.h"
+#include "conf-yaml-loader.h"
+
+#include "detect.h"
+#include "detect-engine.h"
+#include "detect-engine-sigorder.h"
+
+#include "util-unittest.h"
+#include "util-action.h"
+#include "util-unittest-helper.h"
+#include "util-debug.h"
+
+/* Default order: */
+uint8_t action_order_sigs[4] = {ACTION_PASS, ACTION_DROP, ACTION_REJECT, ACTION_ALERT};
+/* This order can be changed from config */
+
+/**
+ * \brief Return the priority associated to an action (to order sigs
+ * as specified at config)
+ * action_order_sigs has this priority by index val
+ * so action_order_sigs[0] has to be inspected first.
+ * This function is called from detect-engine-sigorder
+ * \param action can be one of ACTION_PASS, ACTION_DROP,
+ * ACTION_REJECT or ACTION_ALERT
+ * \retval uint8_t the priority (order of this actions)
+ */
+uint8_t ActionOrderVal(uint8_t action)
+{
+ /* reject_both and reject_dst have the same prio as reject */
+ if( (action & ACTION_REJECT) ||
+ (action & ACTION_REJECT_BOTH) ||
+ (action & ACTION_REJECT_DST)) {
+ action = ACTION_REJECT;
+ }
+ uint8_t i = 0;
+ for (; i < 4; i++) {
+ if (action_order_sigs[i] == action)
+ return i;
+ }
+ /* Unknown action, set just a low prio (high val) */
+ return 10;
+}
+
+/**
+ * \brief Return the ACTION_* bit from their ascii value
+ * \param action can be one of "pass", "drop",
+ * "reject" or "alert"
+ * \retval uint8_t can be one of ACTION_PASS, ACTION_DROP,
+ * ACTION_REJECT or ACTION_ALERT
+ */
+uint8_t ActionAsciiToFlag(char *action)
+{
+ if (strcmp(action,"pass") == 0)
+ return ACTION_PASS;
+ if (strcmp(action,"drop") == 0)
+ return ACTION_DROP;
+ if (strcmp(action,"reject") == 0)
+ return ACTION_REJECT;
+ if (strcmp(action,"alert") == 0)
+ return ACTION_ALERT;
+
+ return 0;
+}
+
+/**
+ * \brief Load the action order from config. If none is provided,
+ * it will be default to ACTION_PASS, ACTION_DROP,
+ * ACTION_REJECT, ACTION_ALERT (pass has the highest prio)
+ *
+ * \retval 0 on success; -1 on fatal error;
+ */
+int ActionInitConfig()
+{
+ uint8_t actions_used = 0;
+ uint8_t action_flag = 0;
+ uint8_t actions_config[4] = {0, 0, 0, 0};
+ int order = 0;
+
+ ConfNode *action_order;
+ ConfNode *action = NULL;
+
+ /* Let's load the order of actions from the general config */
+ action_order = ConfGetNode("action-order");
+ if (action_order == NULL) {
+ /* No configuration, use defaults. */
+ return 0;
+ }
+ else {
+ TAILQ_FOREACH(action, &action_order->head, next) {
+ SCLogDebug("Loading action order : %s", action->val);
+ action_flag = ActionAsciiToFlag(action->val);
+ if (action_flag == 0) {
+ SCLogError(SC_ERR_ACTION_ORDER, "action-order, invalid action: \"%s\". Please, use"
+ " \"pass\",\"drop\",\"alert\",\"reject\". You have"
+ " to specify all of them, without quotes and without"
+ " capital letters", action->val);
+ goto error;
+ }
+
+ if (actions_used & action_flag) {
+ SCLogError(SC_ERR_ACTION_ORDER, "action-order, action already set: \"%s\". Please,"
+ " use \"pass\",\"drop\",\"alert\",\"reject\". You"
+ " have to specify all of them, without quotes and"
+ " without capital letters", action->val);
+ goto error;
+ }
+
+ if (order >= 4) {
+ SCLogError(SC_ERR_ACTION_ORDER, "action-order, you have already specified all the "
+ "possible actions plus \"%s\". Please, use \"pass\","
+ "\"drop\",\"alert\",\"reject\". You have to specify"
+ " all of them, without quotes and without capital"
+ " letters", action->val);
+ goto error;
+ }
+ actions_used |= action_flag;
+ actions_config[order++] = action_flag;
+ }
+ }
+ if (order < 4) {
+ SCLogError(SC_ERR_ACTION_ORDER, "action-order, the config didn't specify all of the "
+ "actions. Please, use \"pass\",\"drop\",\"alert\","
+ "\"reject\". You have to specify all of them, without"
+ " quotes and without capital letters");
+ goto error;
+ }
+
+ /* Now, it's a valid config. Override the default preset */
+ for (order = 0; order < 4; order++) {
+ action_order_sigs[order] = actions_config[order];
+ }
+
+ return 0;
+
+ error:
+ return -1;
+}
+
+#ifdef UNITTESTS
+#include "util-unittest.h"
+
+/**
+ * \test Check that we invalidate duplicated actions
+ * (It should default to pass, drop, reject, alert)
+ */
+int UtilActionTest01(void)
+{
+ int res = 1;
+ char config[] = "\
+%YAML 1.1\n\
+---\n\
+action-order:\n\
+ - alert\n\
+ - drop\n\
+ - reject\n\
+ - alert\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ ActionInitConfig();
+ if (action_order_sigs[0] != ACTION_PASS ||
+ action_order_sigs[1] != ACTION_DROP ||
+ action_order_sigs[2] != ACTION_REJECT ||
+ action_order_sigs[3] != ACTION_ALERT)
+ {
+ res = 0;
+ }
+ ConfRestoreContextBackup();
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we invalidate with unknown keywords
+ * (It should default to pass, drop, reject, alert)
+ */
+int UtilActionTest02(void)
+{
+ int res = 1;
+ char config[] = "\
+%YAML 1.1\n\
+---\n\
+action-order:\n\
+ - alert\n\
+ - drop\n\
+ - reject\n\
+ - ftw\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ ActionInitConfig();
+ if (action_order_sigs[0] != ACTION_PASS ||
+ action_order_sigs[1] != ACTION_DROP ||
+ action_order_sigs[2] != ACTION_REJECT ||
+ action_order_sigs[3] != ACTION_ALERT)
+ {
+ res = 0;
+ }
+ ConfRestoreContextBackup();
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we invalidate if any action is missing
+ * (It should default to pass, drop, reject, alert)
+ */
+int UtilActionTest03(void)
+{
+ int res = 1;
+ char config[] = "\
+%YAML 1.1\n\
+---\n\
+action-order:\n\
+ - alert\n\
+ - drop\n\
+ - reject\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ ActionInitConfig();
+ if (action_order_sigs[0] != ACTION_PASS ||
+ action_order_sigs[1] != ACTION_DROP ||
+ action_order_sigs[2] != ACTION_REJECT ||
+ action_order_sigs[3] != ACTION_ALERT)
+ {
+ res = 0;
+ }
+ ConfRestoreContextBackup();
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we invalidate if any action is missing
+ * (It should default to pass, drop, reject, alert)
+ */
+int UtilActionTest04(void)
+{
+ int res = 1;
+ char config[] = "\
+%YAML 1.1\n\
+---\n\
+action-order:\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ ActionInitConfig();
+ if (action_order_sigs[0] != ACTION_PASS ||
+ action_order_sigs[1] != ACTION_DROP ||
+ action_order_sigs[2] != ACTION_REJECT ||
+ action_order_sigs[3] != ACTION_ALERT)
+ {
+ res = 0;
+ }
+ ConfRestoreContextBackup();
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we invalidate with unknown keywords
+ * and/or more than the expected
+ * (It should default to pass, drop, reject, alert)
+ */
+int UtilActionTest05(void)
+{
+ int res = 1;
+ char config[] = "\
+%YAML 1.1\n\
+---\n\
+action-order:\n\
+ - alert\n\
+ - drop\n\
+ - reject\n\
+ - pass\n\
+ - whatever\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ ActionInitConfig();
+ if (action_order_sigs[0] != ACTION_PASS ||
+ action_order_sigs[1] != ACTION_DROP ||
+ action_order_sigs[2] != ACTION_REJECT ||
+ action_order_sigs[3] != ACTION_ALERT)
+ {
+ res = 0;
+ }
+ ConfRestoreContextBackup();
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we load a valid config
+ */
+int UtilActionTest06(void)
+{
+ int res = 1;
+ char config[] = "\
+%YAML 1.1\n\
+---\n\
+action-order:\n\
+ - alert\n\
+ - drop\n\
+ - reject\n\
+ - pass\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ ActionInitConfig();
+ if (action_order_sigs[0] != ACTION_ALERT ||
+ action_order_sigs[1] != ACTION_DROP ||
+ action_order_sigs[2] != ACTION_REJECT ||
+ action_order_sigs[3] != ACTION_PASS)
+ {
+ res = 0;
+ }
+ ConfRestoreContextBackup();
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we load a valid config
+ */
+int UtilActionTest07(void)
+{
+ int res = 1;
+ char config[] = "\
+%YAML 1.1\n\
+---\n\
+action-order:\n\
+ - pass\n\
+ - alert\n\
+ - drop\n\
+ - reject\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ ActionInitConfig();
+ if (action_order_sigs[0] != ACTION_PASS ||
+ action_order_sigs[1] != ACTION_ALERT ||
+ action_order_sigs[2] != ACTION_DROP ||
+ action_order_sigs[3] != ACTION_REJECT)
+ {
+ res = 0;
+ }
+ ConfRestoreContextBackup();
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we handle the "pass" action
+ * correctly at the IP Only engine in the default case
+ */
+int UtilActionTest08(void)
+{
+ int res = 0;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "pass ip 192.168.1.1 80 -> any any (msg:\"sig 2\"; sid:2;)";
+ sigs[2]= "alert ip any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 0, 1},
+ {0, 0, 0},
+ {1, 0, 1} };
+ /* This means that with the second packet, the results will be
+ * all ({0,0,0}) since, we should match the "pass" rule first
+ */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ return res;
+}
+
+/**
+ * \test Check that we handle the "pass" action
+ * correctly at the IP Only engine with more
+ * prio to drop
+ */
+int UtilActionTest09(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_PASS;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "pass ip 192.168.1.1 80 -> any any (msg:\"sig 2\"; sid:2;)";
+ sigs[2]= "drop ip any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 0, 1},
+ {0, 0, 1},
+ {1, 0, 1} };
+ /* This means that with the second packet, the results will be
+ * all ({0,0,1}) since, we should match the "drop" rule first.
+ * Later the "pass" rule will avoid the "alert" rule match
+ */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we handle the "pass" action
+ * correctly at the detection engine in the default case
+ */
+int UtilActionTest10(void)
+{
+ int res = 0;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ uint8_t *buf2 = (uint8_t *)"wo!";
+ uint16_t buflen2 = strlen((char *)buf2);
+ Packet *p[3];
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf2, buflen2, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)";
+ sigs[1]= "pass ip any any -> any any (msg:\"sig 2\"; content:\"wo\"; sid:2;)";
+ sigs[2]= "alert ip any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 0, 1},
+ {0, 0, 0},
+ {1, 0, 1} };
+ /* This means that with the second packet, the results will be
+ * all ({0,0,0}) since, we should match the "pass" rule first
+ */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ return res;
+}
+
+/**
+ * \test Check that we handle the "pass" action
+ * correctly at the detection engine with more
+ * prio to drop
+ */
+int UtilActionTest11(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ uint8_t *buf2 = (uint8_t *)"Hi all wo!";
+ uint16_t buflen2 = strlen((char *)buf2);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_PASS;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf2, buflen2, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)";
+ sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"wo\"; sid:2;)";
+ sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 0, 1},
+ {0, 0, 1},
+ {1, 0, 1} };
+ /* This means that with the second packet, the results will be
+ * all ({0,0,1}) since, we should match the "drop" rule first.
+ * Later the "pass" rule will avoid the "alert" rule match
+ */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we handle the "pass" action
+ * correctly at the detection engine in the default case
+ */
+int UtilActionTest12(void)
+{
+ int res = 0;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "pass ip any any -> any any (msg:\"Testing normal 2\"; sid:2;)";
+ sigs[2]= "alert ip any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0} };
+ /* All should match the 3 sigs, but the action pass has prio */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ return res;
+}
+
+/**
+ * \test Check that we handle the "pass" action
+ * correctly at the detection engine with more
+ * prio to drop
+ */
+int UtilActionTest13(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_PASS;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)";
+ sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 0, 1},
+ {0, 0, 1},
+ {0, 0, 1} };
+ /* All the patckets should match the 3 sigs. As drop has more
+ * priority than pass, it should alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check that we handle the "pass" action
+ * correctly at the detection engine with more
+ * prio to drop and alert
+ */
+int UtilActionTest14(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_ALERT;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_PASS;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)";
+ sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 0, 1},
+ {1, 0, 1},
+ {1, 0, 1} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal)
+ */
+int UtilActionTest15(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal)
+ */
+int UtilActionTest16(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "drop tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "alert tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "pass tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal)
+ */
+int UtilActionTest17(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "pass tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "drop tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "alert tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal) with more prio for drop
+ */
+int UtilActionTest18(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_PASS;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 0, 1},
+ {0, 0, 1},
+ {0, 0, 1} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal) with more prio for drop
+ */
+int UtilActionTest19(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_PASS;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "drop tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "alert tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "pass tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 0, 0},
+ {1, 0, 0},
+ {1, 0, 0} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal) with more prio for drop
+ */
+int UtilActionTest20(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_PASS;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "pass tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "drop tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "alert tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 1, 0},
+ {0, 1, 0},
+ {0, 1, 0} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal) with more prio for alert and drop
+ */
+int UtilActionTest21(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_ALERT;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_PASS;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 0, 1},
+ {1, 0, 1},
+ {1, 0, 1} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal) with more prio for alert and drop
+ */
+int UtilActionTest22(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_ALERT;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_PASS;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "drop tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "alert tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "pass tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {1, 1, 0},
+ {1, 1, 0},
+ {1, 1, 0} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+end:
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+ return res;
+}
+
+/**
+ * \test Check mixed sigs (iponly and normal) with more prio for alert and drop
+ */
+int UtilActionTest23(void)
+{
+ int res = 1;
+ uint8_t *buf = (uint8_t *)"Hi all!";
+ uint16_t buflen = strlen((char *)buf);
+ Packet *p[3];
+
+ action_order_sigs[0] = ACTION_DROP;
+ action_order_sigs[1] = ACTION_ALERT;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_PASS;
+
+ p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+ p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.1", "192.168.1.5",
+ 80, 41424);
+ p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP,
+ "192.168.1.5", "192.168.1.1",
+ 41424, 80);
+
+ if (p[0] == NULL || p[1] == NULL ||p[2] == NULL)
+ goto end;
+
+ char *sigs[3];
+ sigs[0]= "pass tcp any any -> any any (msg:\"sig 1\"; sid:1;)";
+ sigs[1]= "drop tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)";
+ sigs[2]= "alert tcp any any -> any any (msg:\"sig 3\"; sid:3;)";
+
+ uint32_t sid[3] = {1, 2, 3};
+
+ uint32_t results[3][3] = {
+ {0, 1, 1},
+ {0, 1, 1},
+ {0, 1, 1} };
+ /* All the patckets should match the 3 sigs. As drop
+ * and alert have more priority than pass, both should
+ * alert on each packet */
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto cleanup;
+ de_ctx->flags |= DE_QUIET;
+
+ if (UTHAppendSigs(de_ctx, sigs, 3) == 0)
+ goto cleanup;
+
+ SCSigRegisterSignatureOrderingFuncs(de_ctx);
+ SCSigOrderSignatures(de_ctx);
+
+ res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3);
+
+cleanup:
+ UTHFreePackets(p, 3);
+
+ if (de_ctx != NULL) {
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ }
+
+ /* Restore default values */
+ action_order_sigs[0] = ACTION_PASS;
+ action_order_sigs[1] = ACTION_DROP;
+ action_order_sigs[2] = ACTION_REJECT;
+ action_order_sigs[3] = ACTION_ALERT;
+
+end:
+ return res;
+}
+
+/**
+ * \test Check that the expected defaults are loaded if the
+ * action-order configuration is not present.
+ */
+int UtilActionTest24(void)
+{
+ int res = 1;
+ char config[] = "%YAML 1.1\n"
+ "---\n";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ ConfYamlLoadString(config, strlen(config));
+
+ if (ActionInitConfig() != 0) {
+ res = 0;
+ goto done;
+ }
+ if (action_order_sigs[0] != ACTION_PASS ||
+ action_order_sigs[1] != ACTION_DROP ||
+ action_order_sigs[2] != ACTION_REJECT ||
+ action_order_sigs[3] != ACTION_ALERT) {
+ res = 0;
+ }
+
+done:
+ ConfRestoreContextBackup();
+ return res;
+}
+
+#endif
+
+/* Register unittests */
+void UtilActionRegisterTests(void)
+{
+#ifdef UNITTESTS
+ /* Generic tests */
+ UtRegisterTest("UtilActionTest01", UtilActionTest01, 1);
+ UtRegisterTest("UtilActionTest02", UtilActionTest02, 1);
+ UtRegisterTest("UtilActionTest02", UtilActionTest02, 1);
+ UtRegisterTest("UtilActionTest03", UtilActionTest03, 1);
+ UtRegisterTest("UtilActionTest04", UtilActionTest04, 1);
+ UtRegisterTest("UtilActionTest05", UtilActionTest05, 1);
+ UtRegisterTest("UtilActionTest06", UtilActionTest06, 1);
+ UtRegisterTest("UtilActionTest07", UtilActionTest07, 1);
+ UtRegisterTest("UtilActionTest08", UtilActionTest08, 1);
+ UtRegisterTest("UtilActionTest09", UtilActionTest09, 1);
+ UtRegisterTest("UtilActionTest10", UtilActionTest10, 1);
+ UtRegisterTest("UtilActionTest11", UtilActionTest11, 1);
+ UtRegisterTest("UtilActionTest12", UtilActionTest12, 1);
+ UtRegisterTest("UtilActionTest13", UtilActionTest13, 1);
+ UtRegisterTest("UtilActionTest14", UtilActionTest14, 1);
+ UtRegisterTest("UtilActionTest15", UtilActionTest15, 1);
+ UtRegisterTest("UtilActionTest16", UtilActionTest16, 1);
+ UtRegisterTest("UtilActionTest17", UtilActionTest17, 1);
+ UtRegisterTest("UtilActionTest18", UtilActionTest18, 1);
+ UtRegisterTest("UtilActionTest19", UtilActionTest19, 1);
+ UtRegisterTest("UtilActionTest20", UtilActionTest20, 1);
+ UtRegisterTest("UtilActionTest21", UtilActionTest21, 1);
+ UtRegisterTest("UtilActionTest22", UtilActionTest22, 1);
+ UtRegisterTest("UtilActionTest23", UtilActionTest23, 1);
+ UtRegisterTest("UtilActionTest24", UtilActionTest24, 1);
+#endif
+}