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 
37 static int DetectMsgSetup (DetectEngineCtx *, Signature *, const char *);
38 void DetectMsgRegisterTests(void);
39 
40 void DetectMsgRegister (void)
41 {
43  sigmatch_table[DETECT_MSG].desc = "information about the rule and the possible alert";
44  sigmatch_table[DETECT_MSG].url = DOC_URL DOC_VERSION "/rules/meta.html#msg-message";
46  sigmatch_table[DETECT_MSG].Setup = DetectMsgSetup;
50 }
51 
52 static int DetectMsgSetup (DetectEngineCtx *de_ctx, Signature *s, const char *msgstr)
53 {
54  size_t slen = strlen(msgstr);
55  if (slen == 0)
56  return -1;
57 
58  char input[slen + 1];
59  strlcpy(input, msgstr, slen + 1);
60  char *str = input;
61  char converted = 0;
62 
63  {
64  uint16_t i, x;
65  uint8_t escape = 0;
66 
67  /* it doesn't matter if we need to escape or not we remove the extra "\" to mimic snort */
68  for (i = 0, x = 0; i < slen; i++) {
69  //printf("str[%02u]: %c\n", i, str[i]);
70  if(!escape && str[i] == '\\') {
71  escape = 1;
72  } else if (escape) {
73  if (str[i] != ':' &&
74  str[i] != ';' &&
75  str[i] != '\\' &&
76  str[i] != '\"')
77  {
78  SCLogDebug("character \"%c\" does not need to be escaped but is" ,str[i]);
79  }
80  escape = 0;
81  converted = 1;
82 
83  str[x] = str[i];
84  x++;
85  }else{
86  str[x] = str[i];
87  x++;
88  }
89 
90  }
91 #if 0 //def DEBUG
92  if (SCLogDebugEnabled()) {
93  for (i = 0; i < x; i++) {
94  printf("%c", str[i]);
95  }
96  printf("\n");
97  }
98 #endif
99 
100  if (converted) {
101  slen = x;
102  str[slen] = '\0';
103  }
104  }
105 
106  if (s->msg != NULL) {
107  SCLogError(SC_ERR_INVALID_SIGNATURE, "duplicated 'msg' keyword detected");
108  goto error;
109  }
110  s->msg = SCStrdup(str);
111  if (s->msg == NULL)
112  goto error;
113  return 0;
114 
115 error:
116  return -1;
117 }
118 
119 /* -------------------------------------Unittests-----------------------------*/
120 
121 #ifdef UNITTESTS
122 static int DetectMsgParseTest01(void)
123 {
124  int result = 0;
125  Signature *sig = NULL;
126  const char *teststringparsed = "flow stateless to_server";
128  if (de_ctx == NULL)
129  goto end;
130 
133 
134  sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"flow stateless to_server\"; flow:stateless,to_server; content:\"flowstatelesscheck\"; classtype:bad-unknown; sid: 40000002; rev: 1;)");
135  if(sig == NULL)
136  goto end;
137 
138  if (strcmp(sig->msg, teststringparsed) != 0) {
139  printf("got \"%s\", expected: \"%s\": ", sig->msg, teststringparsed);
140  goto end;
141  }
142 
143  result = 1;
144 end:
145  if (sig != NULL)
146  SigFree(sig);
147  if (de_ctx != NULL)
148  DetectEngineCtxFree(de_ctx);
149  return result;
150 }
151 
152 static int DetectMsgParseTest02(void)
153 {
154  int result = 0;
155  Signature *sig = NULL;
156  const char *teststringparsed = "msg escape tests wxy'\"\\;:";
158  if (de_ctx == NULL)
159  goto end;
160 
161  sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"msg escape tests \\w\\x\\y\\'\\\"\\\\;\\:\"; flow:to_server,established; content:\"blah\"; uricontent:\"/blah/\"; sid: 100;)");
162  if(sig == NULL)
163  goto end;
164 
165  if (strcmp(sig->msg, teststringparsed) != 0) {
166  printf("got \"%s\", expected: \"%s\": ",sig->msg, teststringparsed);
167  goto end;
168  }
169 
170  result = 1;
171 end:
172  if (sig != NULL)
173  SigFree(sig);
174  if (de_ctx != NULL)
175  DetectEngineCtxFree(de_ctx);
176  return result;
177 }
178 
179 static int DetectMsgParseTest03(void)
180 {
181  int result = 0;
182  Signature *sig = NULL;
183  const char *teststringparsed = "flow stateless to_server";
185  if (de_ctx == NULL)
186  goto end;
187 
190 
191  sig = SigInit(de_ctx, "alert tcp any any -> any any (msg: \"flow stateless to_server\"; flow:stateless,to_server; content:\"flowstatelesscheck\"; classtype:bad-unknown; sid: 40000002; rev: 1;)");
192  if(sig == NULL)
193  goto end;
194 
195  if (strcmp(sig->msg, teststringparsed) != 0) {
196  printf("got \"%s\", expected: \"%s\": ", sig->msg, teststringparsed);
197  goto end;
198  }
199 
200  result = 1;
201 end:
202  if (sig != NULL)
203  SigFree(sig);
204  if (de_ctx != NULL)
205  DetectEngineCtxFree(de_ctx);
206  return result;
207 }
208 
209 #endif /* UNITTESTS */
210 
211 /**
212  * \brief this function registers unit tests for DetectMsg
213  */
215 {
216 #ifdef UNITTESTS /* UNITTESTS */
217  UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01);
218  UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02);
219  UtRegisterTest("DetectMsgParseTest03", DetectMsgParseTest03);
220 #endif /* UNITTESTS */
221 }
222 
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define SCLogDebug(...)
Definition: util-debug.h:335
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
char * msg
Definition: detect.h:580
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
main detection engine ctx
Definition: detect.h:761
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:624
#define str(s)
void(* Free)(void *)
Definition: detect.h:1191
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void SigFree(Signature *)
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define SIGMATCH_QUOTES_MANDATORY
Definition: detect.h:1385
void SCClassConfLoadClassficationConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
Loads the Classtype info from the classification.config file.
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1170
const char * desc
Definition: detect.h:1202
void DetectMsgRegisterTests(void)
this function registers unit tests for DetectMsg
Definition: detect-msg.c:214
const char * url
Definition: detect.h:1203
#define SCStrdup(a)
Definition: util-mem.h:268
#define DOC_URL
Definition: suricata.h:86
#define DOC_VERSION
Definition: suricata.h:91
void DetectMsgRegister(void)
Definition: detect-msg.c:40
uint16_t flags
Definition: detect.h:1194
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
void(* RegisterTests)(void)
Definition: detect.h:1192
DetectEngineCtx * DetectEngineCtxInit(void)