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  if (s->msg != NULL) {
63  SCLogError("duplicated 'msg' keyword detected");
64  return -1;
65  }
66 
67  char *str = SCStrdup(msgstr);
68  if (str == NULL)
69  return -1;
70 
71  char converted = 0;
72 
73  {
74  size_t i, x;
75  uint8_t escape = 0;
76 
77  /* it doesn't matter if we need to escape or not we remove the extra "\" to mimic snort */
78  for (i = 0, x = 0; i < slen; i++) {
79  //printf("str[%02u]: %c\n", i, str[i]);
80  if(!escape && str[i] == '\\') {
81  escape = 1;
82  } else if (escape) {
83  if (str[i] != ':' &&
84  str[i] != ';' &&
85  str[i] != '\\' &&
86  str[i] != '\"')
87  {
88  SCLogDebug("character \"%c\" does not need to be escaped but is" ,str[i]);
89  }
90  escape = 0;
91  converted = 1;
92 
93  str[x] = str[i];
94  x++;
95  }else{
96  str[x] = str[i];
97  x++;
98  }
99 
100  }
101 #if 0 //def DEBUG
102  if (SCLogDebugEnabled()) {
103  for (i = 0; i < x; i++) {
104  printf("%c", str[i]);
105  }
106  printf("\n");
107  }
108 #endif
109 
110  if (converted) {
111  slen = x;
112  str[slen] = '\0';
113  }
114  }
115 
116  s->msg = str;
117  return 0;
118 }
119 
120 /* -------------------------------------Unittests-----------------------------*/
121 
122 #ifdef UNITTESTS
123 static int DetectMsgParseTest01(void)
124 {
125  const char *teststringparsed = "flow stateless to_server";
128 
132 
134  "alert tcp any any -> any any (msg:\"flow stateless to_server\"; "
135  "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
136  "classtype:bad-unknown; sid: 40000002; rev: 1;)");
137  FAIL_IF_NULL(sig);
138  FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
139 
142  PASS;
143 }
144 
145 static int DetectMsgParseTest02(void)
146 {
147  const char *teststringparsed = "msg escape tests wxy'\"\\;:";
150 
152  "alert tcp any any -> any any (msg:\"msg escape tests \\w\\x\\y\\'\\\"\\\\;\\:\"; "
153  "flow:to_server,established; content:\"blah\"; uricontent:\"/blah/\"; sid: 100;)");
154  FAIL_IF_NULL(sig);
155 
156  FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
157 
159 
160  PASS;
161 }
162 
163 static int DetectMsgParseTest03(void)
164 {
165  const char *teststringparsed = "flow stateless to_server";
168 
172 
174  "alert tcp any any -> any any (msg: \"flow stateless to_server\"; "
175  "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
176  "classtype:bad-unknown; sid: 40000002; rev: 1;)");
177  FAIL_IF_NULL(sig);
178  FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
179 
182  PASS;
183 }
184 
185 /**
186  * \brief this function registers unit tests for DetectMsg
187  */
188 void DetectMsgRegisterTests(void)
189 {
190  UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01);
191  UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02);
192  UtRegisterTest("DetectMsgParseTest03", DetectMsgParseTest03);
193 }
194 #endif /* UNITTESTS */
SigTableElmt_::url
const char * url
Definition: detect.h:1461
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:1460
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1445
SigTableElmt_::name
const char * name
Definition: detect.h:1458
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1449
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:933
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2634
SIGMATCH_SUPPORT_FIREWALL
#define SIGMATCH_SUPPORT_FIREWALL
Definition: detect.h:1681
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3440
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1440
util-unittest.h
SIGMATCH_QUOTES_MANDATORY
#define SIGMATCH_QUOTES_MANDATORY
Definition: detect.h:1667
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
detect-engine-mpm.h
detect.h
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1420
DETECT_MSG
@ DETECT_MSG
Definition: detect-engine-register.h:102
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:308
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:271
detect-parse.h
Signature_
Signature container.
Definition: detect.h:668
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2595
SCClassConfGenerateValidDummyClassConfigFD01
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
Definition: util-classification-config.c:591
Signature_::msg
char * msg
Definition: detect.h:736
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:768
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:1447
SCClassConfDeInitContext
void SCClassConfDeInitContext(DetectEngineCtx *de_ctx)
Releases resources used by the Classification Config API.
Definition: util-classification-config.c:190
detect-msg.h