suricata
util-action.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2022 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
22 */
23
24#include "suricata-common.h"
25
26#include "action-globals.h"
27#include "conf.h"
28#include "conf-yaml-loader.h"
29
30#include "detect.h"
31#include "detect-engine.h"
33
34#include "util-unittest.h"
35#include "util-action.h"
37#include "util-debug.h"
38
39/* Default order: */
41/* This order can be changed from config */
42
43/**
44 * \brief Return the priority associated to an action (to order sigs
45 * as specified at config)
46 * action_order_sigs has this priority by index val
47 * so action_order_sigs[0] has to be inspected first.
48 * This function is called from detect-engine-sigorder
49 * \param action can be one of ACTION_PASS, ACTION_DROP,
50 * ACTION_REJECT or ACTION_ALERT
51 * \retval uint8_t the priority (order of this actions)
52 */
53uint8_t ActionOrderVal(uint8_t action)
54{
55 /* reject_both and reject_dst have the same prio as reject */
56 if (action & ACTION_REJECT_ANY) {
57 action = ACTION_REJECT;
58 } else if (action & ACTION_DROP) {
59 action = ACTION_DROP;
60 } else if (action & ACTION_PASS) {
61 action = ACTION_PASS;
62 } else if (action & ACTION_ALERT) {
63 action = ACTION_ALERT;
64 } else if (action == 0) {
65 action = ACTION_ALERT;
66 }
67
68 for (uint8_t i = 0; i < 4; i++) {
69 if (action_order_sigs[i] == action) {
70 return i;
71 }
72 }
73 /* Unknown action, set just a low prio (high val) */
74 return 10;
75}
76
77/**
78 * \brief Return the ACTION_* bit from their ascii value
79 * \param action can be one of "pass", "drop",
80 * "reject" or "alert"
81 * \retval uint8_t can be one of ACTION_PASS, ACTION_DROP,
82 * ACTION_REJECT or ACTION_ALERT
83 */
84static uint8_t ActionAsciiToFlag(const char *action)
85{
86 if (strcmp(action,"pass") == 0)
87 return ACTION_PASS;
88 if (strcmp(action,"drop") == 0)
89 return ACTION_DROP;
90 if (strcmp(action,"reject") == 0)
91 return ACTION_REJECT;
92 if (strcmp(action,"alert") == 0)
93 return ACTION_ALERT;
94
95 return 0;
96}
97
98/**
99 * \brief Load the action order from config. If none is provided,
100 * it will be default to ACTION_PASS, ACTION_DROP,
101 * ACTION_REJECT, ACTION_ALERT (pass has the highest prio)
102 *
103 * \retval 0 on success; -1 on fatal error;
104 */
106{
107 uint8_t actions_used = 0;
108 uint8_t action_flag = 0;
109 uint8_t actions_config[4] = {0, 0, 0, 0};
110 int order = 0;
111
112 SCConfNode *action_order;
113 SCConfNode *action = NULL;
114
115 /* Let's load the order of actions from the general config */
116 action_order = SCConfGetNode("action-order");
117 if (action_order == NULL) {
118 /* No configuration, use defaults. */
119 return 0;
120 }
121 else {
122 TAILQ_FOREACH(action, &action_order->head, next) {
123 SCLogDebug("Loading action order : %s", action->val);
124 action_flag = ActionAsciiToFlag(action->val);
125 if (action_flag == 0) {
126 SCLogError("action-order, invalid action: \"%s\". Please, use"
127 " \"pass\",\"drop\",\"alert\",\"reject\". You have"
128 " to specify all of them, without quotes and without"
129 " capital letters",
130 action->val);
131 goto error;
132 }
133
134 if (actions_used & action_flag) {
135 SCLogError("action-order, action already set: \"%s\". Please,"
136 " use \"pass\",\"drop\",\"alert\",\"reject\". You"
137 " have to specify all of them, without quotes and"
138 " without capital letters",
139 action->val);
140 goto error;
141 }
142
143 if (order >= 4) {
144 SCLogError("action-order, you have already specified all the "
145 "possible actions plus \"%s\". Please, use \"pass\","
146 "\"drop\",\"alert\",\"reject\". You have to specify"
147 " all of them, without quotes and without capital"
148 " letters",
149 action->val);
150 goto error;
151 }
152 actions_used |= action_flag;
153 actions_config[order++] = action_flag;
154 }
155 }
156 if (order < 4) {
157 SCLogError("action-order, the config didn't specify all of the "
158 "actions. Please, use \"pass\",\"drop\",\"alert\","
159 "\"reject\". You have to specify all of them, without"
160 " quotes and without capital letters");
161 goto error;
162 }
163
164 /* Now, it's a valid config. Override the default preset */
165 for (order = 0; order < 4; order++) {
166 action_order_sigs[order] = actions_config[order];
167 }
168
169 return 0;
170
171 error:
172 return -1;
173}
174
175#ifdef UNITTESTS
176
177/**
178 * \test Check that we invalidate duplicated actions
179 * (It should default to pass, drop, reject, alert)
180 */
181static int UtilActionTest01(void)
182{
183 char config[] = "\
184%YAML 1.1\n\
185---\n\
186action-order:\n\
187 - alert\n\
188 - drop\n\
189 - reject\n\
190 - alert\n";
191
193 SCConfInit();
194 SCConfYamlLoadString(config, strlen(config));
195
202
203 /* Restore default values */
208 PASS;
209}
210
211/**
212 * \test Check that we invalidate with unknown keywords
213 * (It should default to pass, drop, reject, alert)
214 */
215static int UtilActionTest02(void)
216{
217 char config[] = "\
218%YAML 1.1\n\
219---\n\
220action-order:\n\
221 - alert\n\
222 - drop\n\
223 - reject\n\
224 - ftw\n";
225
227 SCConfInit();
228 SCConfYamlLoadString(config, strlen(config));
229
236
237 /* Restore default values */
242 PASS;
243}
244
245/**
246 * \test Check that we invalidate if any action is missing
247 * (It should default to pass, drop, reject, alert)
248 */
249static int UtilActionTest03(void)
250{
251 char config[] = "\
252%YAML 1.1\n\
253---\n\
254action-order:\n\
255 - alert\n\
256 - drop\n\
257 - reject\n";
258
260 SCConfInit();
261 SCConfYamlLoadString(config, strlen(config));
262
269
270 /* Restore default values */
275 PASS;
276}
277
278/**
279 * \test Check that we invalidate if any action is missing
280 * (It should default to pass, drop, reject, alert)
281 */
282static int UtilActionTest04(void)
283{
284 char config[] = "\
285%YAML 1.1\n\
286---\n\
287action-order:\n";
288
290 SCConfInit();
291 SCConfYamlLoadString(config, strlen(config));
292
299
300 /* Restore default values */
305 PASS;
306}
307
308/**
309 * \test Check that we invalidate with unknown keywords
310 * and/or more than the expected
311 * (It should default to pass, drop, reject, alert)
312 */
313static int UtilActionTest05(void)
314{
315 char config[] = "\
316%YAML 1.1\n\
317---\n\
318action-order:\n\
319 - alert\n\
320 - drop\n\
321 - reject\n\
322 - pass\n\
323 - whatever\n";
324
326 SCConfInit();
327 SCConfYamlLoadString(config, strlen(config));
328
335
336 /* Restore default values */
341 PASS;
342}
343
344/**
345 * \test Check that we load a valid config
346 */
347static int UtilActionTest06(void)
348{
349 char config[] = "\
350%YAML 1.1\n\
351---\n\
352action-order:\n\
353 - alert\n\
354 - drop\n\
355 - reject\n\
356 - pass\n";
357
359 SCConfInit();
360 SCConfYamlLoadString(config, strlen(config));
361
368
369 /* Restore default values */
374 PASS;
375}
376
377/**
378 * \test Check that we load a valid config
379 */
380static int UtilActionTest07(void)
381{
382 char config[] = "\
383%YAML 1.1\n\
384---\n\
385action-order:\n\
386 - pass\n\
387 - alert\n\
388 - drop\n\
389 - reject\n";
390
392 SCConfInit();
393 SCConfYamlLoadString(config, strlen(config));
394
401
402 /* Restore default values */
407 PASS;
408}
409
410/**
411 * \test Check that the expected defaults are loaded if the
412 * action-order configuration is not present.
413 */
414static int UtilActionTest08(void)
415{
416 char config[] = "%YAML 1.1\n"
417 "---\n";
418
420 SCConfInit();
421 SCConfYamlLoadString(config, strlen(config));
422
428
430 PASS;
431}
432
433/* Register unittests */
435{
436 /* Generic tests */
437 UtRegisterTest("UtilActionTest01", UtilActionTest01);
438 UtRegisterTest("UtilActionTest02", UtilActionTest02);
439 UtRegisterTest("UtilActionTest02", UtilActionTest02);
440 UtRegisterTest("UtilActionTest03", UtilActionTest03);
441 UtRegisterTest("UtilActionTest04", UtilActionTest04);
442 UtRegisterTest("UtilActionTest05", UtilActionTest05);
443 UtRegisterTest("UtilActionTest06", UtilActionTest06);
444 UtRegisterTest("UtilActionTest07", UtilActionTest07);
445 UtRegisterTest("UtilActionTest08", UtilActionTest08);
446}
447#endif
#define ACTION_REJECT
#define ACTION_PASS
#define ACTION_REJECT_ANY
#define ACTION_ALERT
#define ACTION_DROP
struct HtpBodyChunk_ * next
int SCConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
void SCConfInit(void)
Initialize the configuration system.
Definition conf.c:120
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
Definition conf.c:181
void SCConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition conf.c:684
void SCConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition conf.c:694
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:252
char * val
Definition conf.h:39
uint8_t ActionOrderVal(uint8_t action)
Return the priority associated to an action (to order sigs as specified at config) action_order_sigs ...
Definition util-action.c:53
void UtilActionRegisterTests(void)
uint8_t action_order_sigs[4]
Definition util-action.c:40
int ActionInitConfig(void)
Load the action order from config. If none is provided, it will be default to ACTION_PASS,...
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267