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 
31 #include "detect-parse.h"
32 #include "detect-engine.h"
33 #include "detect-engine-mpm.h"
34 #include "detect-msg.h"
35 
36 static int DetectMsgSetup (DetectEngineCtx *, Signature *, const char *);
37 #ifdef UNITTESTS
38 static void DetectMsgRegisterTests(void);
39 #endif
40 
41 void DetectMsgRegister (void)
42 {
44  sigmatch_table[DETECT_MSG].desc = "information about the rule and the possible alert";
45  sigmatch_table[DETECT_MSG].url = "/rules/meta.html#msg-message";
47  sigmatch_table[DETECT_MSG].Setup = DetectMsgSetup;
49 #ifdef UNITTESTS
50  sigmatch_table[DETECT_MSG].RegisterTests = DetectMsgRegisterTests;
51 #endif
53 }
54 
55 static int DetectMsgSetup (DetectEngineCtx *de_ctx, Signature *s, const char *msgstr)
56 {
57  size_t slen = strlen(msgstr);
58  if (slen == 0)
59  return -1;
60 
61  if (s->msg != NULL) {
62  SCLogError("duplicated 'msg' keyword detected");
63  return -1;
64  }
65 
66  char *str = SCStrdup(msgstr);
67  if (str == NULL)
68  return -1;
69 
70  char converted = 0;
71 
72  {
73  size_t i, x;
74  uint8_t escape = 0;
75 
76  /* it doesn't matter if we need to escape or not we remove the extra "\" to mimic snort */
77  for (i = 0, x = 0; i < slen; i++) {
78  //printf("str[%02u]: %c\n", i, str[i]);
79  if(!escape && str[i] == '\\') {
80  escape = 1;
81  } else if (escape) {
82  if (str[i] != ':' &&
83  str[i] != ';' &&
84  str[i] != '\\' &&
85  str[i] != '\"')
86  {
87  SCLogDebug("character \"%c\" does not need to be escaped but is" ,str[i]);
88  }
89  escape = 0;
90  converted = 1;
91 
92  str[x] = str[i];
93  x++;
94  }else{
95  str[x] = str[i];
96  x++;
97  }
98 
99  }
100 #if 0 //def DEBUG
101  if (SCLogDebugEnabled()) {
102  for (i = 0; i < x; i++) {
103  printf("%c", str[i]);
104  }
105  printf("\n");
106  }
107 #endif
108 
109  if (converted) {
110  slen = x;
111  str[slen] = '\0';
112  }
113  }
114 
115  s->msg = str;
116  return 0;
117 }
118 
119 /* -------------------------------------Unittests-----------------------------*/
120 
121 #ifdef UNITTESTS
122 static int DetectMsgParseTest01(void)
123 {
124  const char *teststringparsed = "flow stateless to_server";
127 
131 
133  "alert tcp any any -> any any (msg:\"flow stateless to_server\"; "
134  "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
135  "classtype:bad-unknown; sid: 40000002; rev: 1;)");
136  FAIL_IF_NULL(sig);
137  FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
138 
141  PASS;
142 }
143 
144 static int DetectMsgParseTest02(void)
145 {
146  const char *teststringparsed = "msg escape tests wxy'\"\\;:";
149 
151  "alert tcp any any -> any any (msg:\"msg escape tests \\w\\x\\y\\'\\\"\\\\;\\:\"; "
152  "flow:to_server,established; content:\"blah\"; uricontent:\"/blah/\"; sid: 100;)");
153  FAIL_IF_NULL(sig);
154 
155  FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
156 
158 
159  PASS;
160 }
161 
162 static int DetectMsgParseTest03(void)
163 {
164  const char *teststringparsed = "flow stateless to_server";
167 
171 
173  "alert tcp any any -> any any (msg: \"flow stateless to_server\"; "
174  "flow:stateless,to_server; content:\"flowstatelesscheck\"; "
175  "classtype:bad-unknown; sid: 40000002; rev: 1;)");
176  FAIL_IF_NULL(sig);
177  FAIL_IF(strcmp(sig->msg, teststringparsed) != 0);
178 
181  PASS;
182 }
183 
184 /**
185  * \brief this function registers unit tests for DetectMsg
186  */
187 void DetectMsgRegisterTests(void)
188 {
189  UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01);
190  UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02);
191  UtRegisterTest("DetectMsgParseTest03", DetectMsgParseTest03);
192 }
193 #endif /* UNITTESTS */
SigTableElmt_::url
const char * url
Definition: detect.h:1545
DetectMsgRegister
void DetectMsgRegister(void)
Definition: detect-msg.c:41
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:1544
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:78
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1529
SigTableElmt_::name
const char * name
Definition: detect.h:1542
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1533
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:995
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2912
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3965
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1524
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
detect-engine-mpm.h
detect.h
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1504
SIGMATCH_QUOTES_MANDATORY
#define SIGMATCH_QUOTES_MANDATORY
Definition: detect-engine-register.h:322
DETECT_MSG
@ DETECT_MSG
Definition: detect-engine-register.h:111
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:313
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
detect-parse.h
Signature_
Signature container.
Definition: detect.h:692
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2873
SIGMATCH_SUPPORT_FIREWALL
#define SIGMATCH_SUPPORT_FIREWALL
Definition: detect-engine-register.h:336
SCClassConfGenerateValidDummyClassConfigFD01
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
Definition: util-classification-config.c:586
Signature_::msg
char * msg
Definition: detect.h:764
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:519
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1531
SCClassConfDeInitContext
void SCClassConfDeInitContext(DetectEngineCtx *de_ctx)
Releases resources used by the Classification Config API.
Definition: util-classification-config.c:190
detect-msg.h