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  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 
119 error:
120  return -1;
121 }
122 
123 /* -------------------------------------Unittests-----------------------------*/
124 
125 #ifdef UNITTESTS
126 static 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 
148 static 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 
166 static 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  */
191 void DetectMsgRegisterTests(void)
192 {
193  UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01);
194  UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02);
195  UtRegisterTest("DetectMsgParseTest03", DetectMsgParseTest03);
196 }
197 #endif /* UNITTESTS */
SigTableElmt_::url
const char * url
Definition: detect.h:1312
DetectMsgRegister
void DetectMsgRegister(void)
Definition: detect-msg.c:42
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1311
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:128
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1299
SigTableElmt_::name
const char * name
Definition: detect.h:1309
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1303
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:843
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2623
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2591
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1294
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:1509
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
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:1277
DETECT_MSG
@ DETECT_MSG
Definition: detect-engine-register.h:104
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
util-classification-config.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
str
#define str(s)
Definition: suricata-common.h:291
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
detect-parse.h
Signature_
Signature container.
Definition: detect.h:603
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2584
SCClassConfGenerateValidDummyClassConfigFD01
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
Definition: util-classification-config.c:587
Signature_::msg
char * msg
Definition: detect.h:661
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:767
SCClassConfLoadClassificationConfigFile
bool SCClassConfLoadClassificationConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
Loads the Classtype info from the classification.config file.
Definition: util-classification-config.c:524
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1301
detect-msg.h