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 #ifdef UNITTESTS
39 static void DetectMsgRegisterTests(void);
40 #endif
41 
42 void DetectMsgRegister (void)
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 
56 static 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  uint16_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(SC_ERR_INVALID_SIGNATURE, "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 
119 error:
120  return -1;
121 }
122 
123 /* -------------------------------------Unittests-----------------------------*/
124 
125 #ifdef UNITTESTS
126 static int DetectMsgParseTest01(void)
127 {
128  int result = 0;
129  Signature *sig = NULL;
130  const char *teststringparsed = "flow stateless to_server";
132  if (de_ctx == NULL)
133  goto end;
134 
137 
138  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;)");
139  if(sig == NULL)
140  goto end;
141 
142  if (strcmp(sig->msg, teststringparsed) != 0) {
143  printf("got \"%s\", expected: \"%s\": ", sig->msg, teststringparsed);
144  goto end;
145  }
146 
147  result = 1;
148 end:
149  if (sig != NULL)
150  SigFree(de_ctx, sig);
151  if (de_ctx != NULL)
153  return result;
154 }
155 
156 static int DetectMsgParseTest02(void)
157 {
158  int result = 0;
159  Signature *sig = NULL;
160  const char *teststringparsed = "msg escape tests wxy'\"\\;:";
162  if (de_ctx == NULL)
163  goto end;
164 
165  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;)");
166  if(sig == NULL)
167  goto end;
168 
169  if (strcmp(sig->msg, teststringparsed) != 0) {
170  printf("got \"%s\", expected: \"%s\": ",sig->msg, teststringparsed);
171  goto end;
172  }
173 
174  result = 1;
175 end:
176  if (sig != NULL)
177  SigFree(de_ctx, sig);
178  if (de_ctx != NULL)
180  return result;
181 }
182 
183 static int DetectMsgParseTest03(void)
184 {
185  int result = 0;
186  Signature *sig = NULL;
187  const char *teststringparsed = "flow stateless to_server";
189  if (de_ctx == NULL)
190  goto end;
191 
194 
195  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;)");
196  if(sig == NULL)
197  goto end;
198 
199  if (strcmp(sig->msg, teststringparsed) != 0) {
200  printf("got \"%s\", expected: \"%s\": ", sig->msg, teststringparsed);
201  goto end;
202  }
203 
204  result = 1;
205 end:
206  if (sig != NULL)
207  SigFree(de_ctx, sig);
208  if (de_ctx != NULL)
210  return result;
211 }
212 
213 /**
214  * \brief this function registers unit tests for DetectMsg
215  */
216 void DetectMsgRegisterTests(void)
217 {
218  UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01);
219  UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02);
220  UtRegisterTest("DetectMsgParseTest03", DetectMsgParseTest03);
221 }
222 #endif /* UNITTESTS */
SigTableElmt_::url
const char * url
Definition: detect.h:1214
DetectMsgRegister
void DetectMsgRegister(void)
Definition: detect-msg.c:42
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1213
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1201
SigTableElmt_::name
const char * name
Definition: detect.h:1211
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1381
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
SCClassConfLoadClassficationConfigFile
void SCClassConfLoadClassficationConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
Loads the Classtype info from the classification.config file.
Definition: util-classification-config.c:527
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2056
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1205
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:767
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2093
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1196
util-unittest.h
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
SIGMATCH_QUOTES_MANDATORY
#define SIGMATCH_QUOTES_MANDATORY
Definition: detect.h:1396
util-debug.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
detect-engine-mpm.h
detect.h
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1179
DETECT_MSG
@ DETECT_MSG
Definition: detect-engine-register.h:58
suricata-common.h
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
util-classification-config.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
str
#define str(s)
Definition: suricata-common.h:273
detect-parse.h
Signature_
Signature container.
Definition: detect.h:528
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2048
SCClassConfGenerateValidDummyClassConfigFD01
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
Definition: util-classification-config.c:584
Signature_::msg
char * msg
Definition: detect.h:586
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:662
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1203
detect-msg.h