suricata
detect-msg.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2010 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 *
23 * Implements the msg keyword
24 */
25
26#include "suricata-common.h"
27#include "detect.h"
29#include "util-debug.h"
30#include "util-unittest.h"
31
32#include "detect-parse.h"
33#include "detect-engine.h"
34#include "detect-engine-mpm.h"
35#include "detect-msg.h"
36
37static int DetectMsgSetup (DetectEngineCtx *, Signature *, const char *);
38#ifdef UNITTESTS
39static void DetectMsgRegisterTests(void);
40#endif
41
43{
45 sigmatch_table[DETECT_MSG].desc = "information about the rule and the possible alert";
46 sigmatch_table[DETECT_MSG].url = "/rules/meta.html#msg-message";
48 sigmatch_table[DETECT_MSG].Setup = DetectMsgSetup;
50#ifdef UNITTESTS
51 sigmatch_table[DETECT_MSG].RegisterTests = DetectMsgRegisterTests;
52#endif
54}
55
56static int DetectMsgSetup (DetectEngineCtx *de_ctx, Signature *s, const char *msgstr)
57{
58 size_t slen = strlen(msgstr);
59 if (slen == 0)
60 return -1;
61
62 char input[slen + 1];
63 strlcpy(input, msgstr, slen + 1);
64 char *str = input;
65 char converted = 0;
66
67 {
68 size_t i, x;
69 uint8_t escape = 0;
70
71 /* it doesn't matter if we need to escape or not we remove the extra "\" to mimic snort */
72 for (i = 0, x = 0; i < slen; i++) {
73 //printf("str[%02u]: %c\n", i, str[i]);
74 if(!escape && str[i] == '\\') {
75 escape = 1;
76 } else if (escape) {
77 if (str[i] != ':' &&
78 str[i] != ';' &&
79 str[i] != '\\' &&
80 str[i] != '\"')
81 {
82 SCLogDebug("character \"%c\" does not need to be escaped but is" ,str[i]);
83 }
84 escape = 0;
85 converted = 1;
86
87 str[x] = str[i];
88 x++;
89 }else{
90 str[x] = str[i];
91 x++;
92 }
93
94 }
95#if 0 //def DEBUG
96 if (SCLogDebugEnabled()) {
97 for (i = 0; i < x; i++) {
98 printf("%c", str[i]);
99 }
100 printf("\n");
101 }
102#endif
103
104 if (converted) {
105 slen = x;
106 str[slen] = '\0';
107 }
108 }
109
110 if (s->msg != NULL) {
111 SCLogError("duplicated 'msg' keyword detected");
112 goto error;
113 }
114 s->msg = SCStrdup(str);
115 if (s->msg == NULL)
116 goto error;
117 return 0;
118
119error:
120 return -1;
121}
122
123/* -------------------------------------Unittests-----------------------------*/
124
125#ifdef UNITTESTS
126static int DetectMsgParseTest01(void)
127{
128 const char *teststringparsed = "flow stateless to_server";
131
134
136 "alert tcp any any -> any any (msg:\"flow stateless to_server\"; "
137 "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
138 "classtype:bad-unknown; sid: 40000002; rev: 1;)");
139 FAIL_IF_NULL(sig);
140
141 FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
142
144
145 PASS;
146}
147
148static int DetectMsgParseTest02(void)
149{
150 const char *teststringparsed = "msg escape tests wxy'\"\\;:";
153
155 "alert tcp any any -> any any (msg:\"msg escape tests \\w\\x\\y\\'\\\"\\\\;\\:\"; "
156 "flow:to_server,established; content:\"blah\"; uricontent:\"/blah/\"; sid: 100;)");
157 FAIL_IF_NULL(sig);
158
159 FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
160
162
163 PASS;
164}
165
166static int DetectMsgParseTest03(void)
167{
168 const char *teststringparsed = "flow stateless to_server";
171
174
176 "alert tcp any any -> any any (msg: \"flow stateless to_server\"; "
177 "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
178 "classtype:bad-unknown; sid: 40000002; rev: 1;)");
179 FAIL_IF_NULL(sig);
180
181 FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
182
184
185 PASS;
186}
187
188/**
189 * \brief this function registers unit tests for DetectMsg
190 */
191void DetectMsgRegisterTests(void)
192{
193 UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01);
194 UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02);
195 UtRegisterTest("DetectMsgParseTest03", DetectMsgParseTest03);
196}
197#endif /* UNITTESTS */
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 DetectMsgRegister(void)
Definition detect-msg.c:42
SigTableElmt * sigmatch_table
#define SIGMATCH_SUPPORT_FIREWALL
Definition detect.h:1682
#define SIGMATCH_QUOTES_MANDATORY
Definition detect.h:1668
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 PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
main detection engine ctx
Definition detect.h:932
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
const char * name
Definition detect.h:1459
Signature container.
Definition detect.h:668
char * msg
Definition detect.h:736
#define str(s)
size_t strlcpy(char *dst, const char *src, size_t siz)
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
bool SCClassConfLoadClassificationConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
Loads the Classtype info from the classification.config file.
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition util-debug.c:767
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCStrdup(s)
Definition util-mem.h:56