diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:21:41 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:21:41 -0700 |
commit | 8879b125d26e8db1a5633de5a9c692eb2d1c4f83 (patch) | |
tree | c7259d85a991b83dfa85ab2e339360669fc1f58e /framework/src/suricata/src/util-action.c | |
parent | 13d05bc8458758ee39cb829098241e89616717ee (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.c | 1627 |
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 +} |