suricata
detect-priority.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2020 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 Victor Julien <victor@inliniac.net>
22 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23 *
24 * Implements the priority keyword
25 */
26
27#include "suricata-common.h"
28#include "detect.h"
29#include "detect-parse.h"
30#include "detect-priority.h"
31#include "detect-engine.h"
32#include "detect-engine-mpm.h"
33#include "util-error.h"
34#include "util-debug.h"
35#include "util-unittest.h"
36
37#define PARSE_REGEX "^\\s*(\\d+|\"\\d+\")\\s*$"
38
39static DetectParseRegex parse_regex;
40
41static int DetectPrioritySetup (DetectEngineCtx *, Signature *, const char *);
42#ifdef UNITTESTS
43static void PriorityRegisterTests(void);
44#endif
45
46/**
47 * \brief Registers the handler functions for the "priority" keyword
48 */
50{
52 sigmatch_table[DETECT_PRIORITY].desc = "rules with a higher priority will be examined first";
53 sigmatch_table[DETECT_PRIORITY].url = "/rules/meta.html#priority";
54 sigmatch_table[DETECT_PRIORITY].Setup = DetectPrioritySetup;
55#ifdef UNITTESTS
56 sigmatch_table[DETECT_PRIORITY].RegisterTests = PriorityRegisterTests;
57#endif
59}
60
61static int DetectPrioritySetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
62{
63 char copy_str[128] = "";
64 size_t pcre2len;
65
66 pcre2_match_data *match = NULL;
67 int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
68 if (ret < 0) {
69 SCLogError("Invalid Priority in Signature "
70 "- %s",
71 rawstr);
72 if (match)
73 pcre2_match_data_free(match);
74 return -1;
75 }
76
77 pcre2len = sizeof(copy_str);
78 ret = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)copy_str, &pcre2len);
79 if (ret < 0) {
80 SCLogError("pcre2_substring_copy_bynumber failed");
81 pcre2_match_data_free(match);
82 return -1;
83 }
84
85 pcre2_match_data_free(match);
86 char *endptr = NULL;
87 int prio = (int)strtol(copy_str, &endptr, 10);
88 if (endptr == NULL || *endptr != '\0') {
89 SCLogError("Saw an invalid character as arg "
90 "to priority keyword");
91 return -1;
92 }
93
95 SCLogWarning("duplicate priority "
96 "keyword. Using highest priority in the rule");
97 s->prio = MIN(s->prio, prio);
98 } else {
99 s->prio = prio;
101 }
102 return 0;
103}
104
105/*------------------------------Unittests-------------------------------------*/
106
107#ifdef UNITTESTS
108
109static int DetectPriorityTest01(void)
110{
113
114 de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
115 "(msg:\"Priority test\"; priority:2; sid:1;)");
117
119
121 PASS;
122}
123
124static int DetectPriorityTest02(void)
125{
128
129 Signature *sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
130 "(msg:\"Priority test\"; priority:1; sid:1;)");
131 FAIL_IF_NULL(sig);
132 FAIL_IF_NOT(sig->prio == 1);
133
134 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
135 "(msg:\"Priority test\"; priority:boo; sid:2;)");
136 FAIL_IF_NOT_NULL(sig);
137
138 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
139 "(msg:\"Priority test\"; priority:10boo; sid:3;)");
140 FAIL_IF_NOT_NULL(sig);
141
142 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
143 "(msg:\"Priority test\"; priority:b10oo; sid:4;)");
144 FAIL_IF_NOT_NULL(sig);
145
146 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
147 "(msg:\"Priority test\"; priority:boo10; sid:5;)");
148 FAIL_IF_NOT_NULL(sig);
149
150 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
151 "(msg:\"Priority test\"; priority:-1; sid:6;)");
152 FAIL_IF_NOT_NULL(sig);
153
154 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
155 "(msg:\"Priority test\"; sid:7;)");
156 FAIL_IF_NULL(sig);
157 FAIL_IF_NOT(sig->prio == 3);
158
159 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
160 "(msg:\"Priority test\"; priority:5; priority:4; sid:8;)");
161 FAIL_IF_NULL(sig);
162 FAIL_IF_NOT(sig->prio == 4);
163
164 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
165 "(msg:\"Priority test\"; priority:5; priority:4; "
166 "priority:1; sid:9;)");
167 FAIL_IF_NULL(sig);
168 FAIL_IF_NOT(sig->prio == 1);
169
171 PASS;
172}
173
174/**
175 * \brief This function registers unit tests for Classification Config API.
176 */
177static void PriorityRegisterTests(void)
178{
179 UtRegisterTest("DetectPriorityTest01", DetectPriorityTest01);
180 UtRegisterTest("DetectPriorityTest02", DetectPriorityTest02);
181}
182#endif /* UNITTESTS */
@ DETECT_PRIORITY
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
SigTableElmt * sigmatch_table
void DetectPriorityRegister(void)
Registers the handler functions for the "priority" keyword.
#define PARSE_REGEX
#define SIG_FLAG_INIT_PRIO_EXPLICIT
Definition detect.h:298
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
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 FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
main detection engine ctx
Definition detect.h:932
Signature * sig_list
Definition detect.h:941
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
const char * name
Definition detect.h:1459
uint32_t init_flags
Definition detect.h:608
Signature container.
Definition detect.h:668
SignatureInitData * init_data
Definition detect.h:747
int prio
Definition detect.h:716
#define MIN(x, y)
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267