]> git.ipfire.org Git - people/ms/suricata.git/blame - src/detect-bypass.c
core: Remove unneeded consts
[people/ms/suricata.git] / src / detect-bypass.c
CommitLineData
07564c4e
GL
1/* Copyright (C) 2016 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 Giuseppe Longo <glongo@stamus-networks.com>
22 *
23 */
24
25#include "suricata-common.h"
26#include "threads.h"
27#include "app-layer.h"
28#include "app-layer-parser.h"
29#include "debug.h"
30#include "decode.h"
31
32#include "detect.h"
33#include "detect-parse.h"
34
35#include "detect-engine.h"
36#include "detect-engine-mpm.h"
37#include "detect-engine-state.h"
38#include "detect-engine-sigorder.h"
ab1200fb 39#include "detect-bypass.h"
07564c4e
GL
40
41#include "flow.h"
42#include "flow-var.h"
43#include "flow-util.h"
44
45#include "stream-tcp.h"
46
47#include "util-debug.h"
48#include "util-spm-bm.h"
49#include "util-unittest.h"
50#include "util-unittest-helper.h"
51#include "util-device.h"
52
14896365 53static int DetectBypassMatch(DetectEngineThreadCtx *, Packet *,
bfd4bc82 54 const Signature *, const SigMatchCtx *);
ab1200fb 55static int DetectBypassSetup(DetectEngineCtx *, Signature *, const char *);
6ab323d3 56#ifdef UNITTESTS
07564c4e 57static void DetectBypassRegisterTests(void);
6ab323d3 58#endif
07564c4e
GL
59
60/**
61 * \brief Registration function for keyword: bypass
62 */
63void DetectBypassRegister(void)
64{
65 sigmatch_table[DETECT_BYPASS].name = "bypass";
66 sigmatch_table[DETECT_BYPASS].desc = "call the bypass callback when the match of a sig is complete";
26bcc975 67 sigmatch_table[DETECT_BYPASS].url = "/rules/bypass-keyword.html";
07564c4e 68 sigmatch_table[DETECT_BYPASS].Match = DetectBypassMatch;
07564c4e
GL
69 sigmatch_table[DETECT_BYPASS].Setup = DetectBypassSetup;
70 sigmatch_table[DETECT_BYPASS].Free = NULL;
6ab323d3 71#ifdef UNITTESTS
07564c4e 72 sigmatch_table[DETECT_BYPASS].RegisterTests = DetectBypassRegisterTests;
6ab323d3 73#endif
07564c4e
GL
74 sigmatch_table[DETECT_BYPASS].flags = SIGMATCH_NOOPT;
75}
76
ab1200fb 77static int DetectBypassSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
07564c4e
GL
78{
79 SigMatch *sm = NULL;
80
81 if (s->flags & SIG_FLAG_FILESTORE) {
82 SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS,
83 "bypass can't work with filestore keyword");
84 return -1;
85 }
86 s->flags |= SIG_FLAG_BYPASS;
87
88 sm = SigMatchAlloc();
89 if (sm == NULL)
90 return -1;
91
92 sm->type = DETECT_BYPASS;
93 sm->ctx = NULL;
94 SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH);
95
96 return 0;
97}
98
14896365 99static int DetectBypassMatch(DetectEngineThreadCtx *det_ctx, Packet *p,
bfd4bc82 100 const Signature *s, const SigMatchCtx *ctx)
07564c4e
GL
101{
102 PacketBypassCallback(p);
103
104 return 1;
105}
106
107#ifdef UNITTESTS
9c2c258f
VJ
108#include "app-layer-htp.h"
109
07564c4e
GL
110static int callback_var = 0;
111
ab1200fb 112static int BypassCallback(Packet *p)
07564c4e
GL
113{
114 callback_var = 1;
115 return 1;
116}
117
ab1200fb 118static void ResetCallbackVar(void)
07564c4e
GL
119{
120 callback_var = 0;
121}
122
123static int DetectBypassTestSig01(void)
124{
125 TcpSession ssn;
126 Packet *p1 = NULL;
127 Packet *p2 = NULL;
128 ThreadVars th_v;
129 DetectEngineCtx *de_ctx = NULL;
130 DetectEngineThreadCtx *det_ctx = NULL;
131 HtpState *http_state = NULL;
132 Flow f;
133 uint8_t http_buf1[] =
134 "GET /index.html HTTP/1.0\r\n"
135 "Host: This is dummy message body\r\n"
136 "User-Agent: www.openinfosecfoundation.org\r\n"
137 "Content-Type: text/html\r\n"
138 "\r\n";
139 uint32_t http_len1 = sizeof(http_buf1) - 1;
140 uint8_t http_buf2[] =
141 "HTTP/1.0 200 ok\r\n"
142 "Content-Type: text/html\r\n"
143 "Content-Length: 7\r\n"
144 "\r\n"
145 "message";
146 uint32_t http_len2 = sizeof(http_buf2) - 1;
147 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
148 LiveDevice *livedev = SCMalloc(sizeof(LiveDevice));
149 FAIL_IF(livedev == NULL);
150
151 memset(&th_v, 0, sizeof(th_v));
152 memset(&f, 0, sizeof(f));
153 memset(&ssn, 0, sizeof(ssn));
154
155 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
156 FAIL_IF(p1 == NULL);
157 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
158 FAIL_IF(p2 == NULL);
159
160 p1->BypassPacketsFlow = BypassCallback;
161 p2->BypassPacketsFlow = BypassCallback;
162
163 FLOW_INITIALIZE(&f);
164 f.protoctx = (void *)&ssn;
165 f.proto = IPPROTO_TCP;
166 f.flags |= FLOW_IPV4;
167
168 p1->flow = &f;
169 p1->flowflags |= FLOW_PKT_TOSERVER;
170 p1->flowflags |= FLOW_PKT_ESTABLISHED;
171 p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
172 p1->livedev = livedev;
173 p2->flow = &f;
174 p2->flowflags |= FLOW_PKT_TOCLIENT;
175 p2->flowflags |= FLOW_PKT_ESTABLISHED;
176 p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
177 p2->livedev = livedev;
707f0272 178 f.alproto = ALPROTO_HTTP1;
07564c4e 179
1eeb9669 180 StreamTcpInitConfig(true);
07564c4e
GL
181
182 de_ctx = DetectEngineCtxInit();
183 FAIL_IF(de_ctx == NULL);
184
185 de_ctx->flags |= DE_QUIET;
186
ab1200fb 187 const char *sigs[3];
07564c4e
GL
188 sigs[0] = "alert tcp any any -> any any (bypass; content:\"GET \"; sid:1;)";
189 sigs[1] = "alert http any any -> any any "
190 "(bypass; content:\"message\"; http_server_body; "
191 "sid:2;)";
192 sigs[2] = "alert http any any -> any any "
193 "(bypass; content:\"message\"; http_host; "
194 "sid:3;)";
195 FAIL_IF(UTHAppendSigs(de_ctx, sigs, 3) == 0);
196
197 SCSigRegisterSignatureOrderingFuncs(de_ctx);
198 SCSigOrderSignatures(de_ctx);
199 SCSigSignatureOrderingModuleCleanup(de_ctx);
200
201 SigGroupBuild(de_ctx);
202 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
203
204 FLOWLOCK_WRLOCK(&f);
707f0272
PA
205 int r = AppLayerParserParse(
206 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
07564c4e
GL
207 FAIL_IF(r != 0);
208 FLOWLOCK_UNLOCK(&f);
209
210 http_state = f.alstate;
211 FAIL_IF(http_state == NULL);
212
213 /* do detect */
214 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
215
216 FAIL_IF(PacketAlertCheck(p1, 1));
217
218 FLOWLOCK_WRLOCK(&f);
707f0272
PA
219 r = AppLayerParserParse(
220 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
07564c4e
GL
221 FAIL_IF(r != 0);
222 FLOWLOCK_UNLOCK(&f);
223 /* do detect */
224 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
225
226 FAIL_IF(!(PacketAlertCheck(p2, 2)));
227 FAIL_IF(!(PacketAlertCheck(p1, 3)));
228
229 FAIL_IF(callback_var == 0);
230
1eeb9669 231 StreamTcpFreeConfig(true);
07564c4e
GL
232 FLOW_DESTROY(&f);
233 UTHFreePacket(p1);
234 UTHFreePacket(p2);
235 ResetCallbackVar();
236 SCFree(livedev);
237 PASS;
238}
07564c4e 239
39613778 240static void DetectBypassRegisterTests(void)
07564c4e 241{
07564c4e 242 UtRegisterTest("DetectBypassTestSig01", DetectBypassTestSig01);
07564c4e 243}
6ab323d3 244#endif /* UNITTESTS */