1 /* Copyright (C) 2007-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 * \ingroup httplayer
20 *
21 * @{
22 */
23
24
25 /** \file
26 *
27 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
28 * \author Victor Julien <victor@inliniac.net>
29 *
30 * \brief Handle HTTP request body match corresponding to http_client_body
31 * keyword.
32 *
33 */
34
35 #include "../suricata-common.h"
36 #include "../suricata.h"
37 #include "../decode.h"
38
39 #include "detect.h"
40 #include "detect-engine.h"
41 #include "detect-engine-mpm.h"
42 #include "detect-parse.h"
43 #include "detect-engine-state.h"
44 #include "detect-engine-content-inspection.h"
45 #include "detect-engine-prefilter.h"
46 #include "detect-isdataat.h"
47 #include "stream-tcp-reassemble.h"
48
49
50 #include "flow-util.h"
51 #include "util-debug.h"
52 #include "util-print.h"
53 #include "flow.h"
54
55 #include "app-layer-parser.h"
56
57 #include "stream-tcp.h"
58
59 #include "util-unittest.h"
60 #include "util-unittest-helper.h"
61 #include "app-layer.h"
62 #include "app-layer-htp.h"
63 #include "app-layer-protos.h"
64
65 #include "conf.h"
66 #include "conf-yaml-loader.h"
67
68 #include "util-validate.h"
69
70 #ifdef UNITTESTS
71
72 /**
73 * \test Test parser accepting valid rules and rejecting invalid rules
74 */
DetectHttpClientBodyParserTest01(void)75 static int DetectHttpClientBodyParserTest01(void)
76 {
77 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; http_client_body; sid:1;)", true));
78 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; nocase; http_client_body; sid:1;)", true));
79 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; endswith; http_client_body; sid:1;)", true));
80 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; http_client_body; sid:1;)", true));
81 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; endswith; http_client_body; sid:1;)", true));
82
83 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; rawbytes; http_client_body; sid:1;)", false));
84 FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http_client_body; sid:1;)", false));
85 FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; content:\"abc\"; http_client_body; sid:1;)", false));
86 PASS;
87 }
88
89 /**
90 * \test Test parser accepting valid rules and rejecting invalid rules
91 */
DetectHttpClientBodyParserTest02(void)92 static int DetectHttpClientBodyParserTest02(void)
93 {
94 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; sid:1;)", true));
95 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; nocase; sid:1;)", true));
96 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; endswith; sid:1;)", true));
97 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; startswith; sid:1;)", true));
98 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; startswith; endswith; sid:1;)", true));
99 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; bsize:10; sid:1;)", true));
100
101 FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; rawbytes; sid:1;)", false));
102 FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http.request_body; sid:1;)", false));
103 FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; http.request_body; content:\"abc\"; sid:1;)", false));
104 PASS;
105 }
106
107 struct TestSteps {
108 const uint8_t *input;
109 size_t input_size; /**< if 0 strlen will be used */
110 int direction; /**< STREAM_TOSERVER, STREAM_TOCLIENT */
111 int expect;
112 };
113
RunTest(struct TestSteps * steps,const char * sig,const char * yaml)114 static int RunTest (struct TestSteps *steps, const char *sig, const char *yaml)
115 {
116 TcpSession ssn;
117 Flow f;
118 ThreadVars th_v;
119 DetectEngineThreadCtx *det_ctx = NULL;
120 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
121 FAIL_IF_NULL(alp_tctx);
122
123 memset(&th_v, 0, sizeof(th_v));
124 memset(&f, 0, sizeof(f));
125 memset(&ssn, 0, sizeof(ssn));
126
127 if (yaml) {
128 ConfCreateContextBackup();
129 ConfInit();
130 HtpConfigCreateBackup();
131
132 ConfYamlLoadString(yaml, strlen(yaml));
133 HTPConfigure();
134 }
135
136 StreamTcpInitConfig(TRUE);
137
138 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
139 FAIL_IF_NULL(de_ctx);
140 de_ctx->flags |= DE_QUIET;
141
142 FLOW_INITIALIZE(&f);
143 f.protoctx = (void *)&ssn;
144 f.proto = IPPROTO_TCP;
145 f.flags |= FLOW_IPV4;
146 f.alproto = ALPROTO_HTTP;
147
148 SCLogDebug("sig %s", sig);
149 Signature *s = DetectEngineAppendSig(de_ctx, (char *)sig);
150 FAIL_IF_NULL(s);
151
152 SigGroupBuild(de_ctx);
153 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
154 FAIL_IF_NULL(det_ctx);
155
156 struct TestSteps *b = steps;
157 int i = 0;
158 while (b->input != NULL) {
159 SCLogDebug("chunk %p %d", b, i);
160 Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
161 FAIL_IF_NULL(p);
162 p->flow = &f;
163 p->flowflags = (b->direction == STREAM_TOSERVER) ? FLOW_PKT_TOSERVER : FLOW_PKT_TOCLIENT;
164 p->flowflags |= FLOW_PKT_ESTABLISHED;
165 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
166
167 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
168 b->direction, (uint8_t *)b->input,
169 b->input_size ? b->input_size : strlen((const char *)b->input));
170 FAIL_IF_NOT(r == 0);
171
172 /* do detect */
173 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
174
175 int match = PacketAlertCheck(p, 1);
176 FAIL_IF_NOT (b->expect == match);
177
178 UTHFreePackets(&p, 1);
179 b++;
180 i++;
181 }
182
183 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
184 AppLayerParserThreadCtxFree(alp_tctx);
185 DetectEngineCtxFree(de_ctx);
186
187 StreamTcpFreeConfig(TRUE);
188 FLOW_DESTROY(&f);
189
190 if (yaml) {
191 HtpConfigRestoreBackup();
192 ConfRestoreContextBackup();
193 }
194 PASS;
195 }
196
DetectEngineHttpClientBodyTest01(void)197 static int DetectEngineHttpClientBodyTest01(void)
198 {
199 struct TestSteps steps[] = {
200 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
201 "Host: www.openinfosecfoundation.org\r\n"
202 "Content-Type: text/html\r\n"
203 "Content-Length: 46\r\n"
204 "\r\n"
205 "This is dummy body1",
206 0, STREAM_TOSERVER, 0 },
207 { (const uint8_t *)"This is dummy message body2",
208 0, STREAM_TOSERVER, 1 },
209 { NULL, 0, 0, 0 },
210 };
211
212 const char *sig = "alert http any any -> any any (content:\"body1This\"; http_client_body; sid:1;)";
213 return RunTest(steps, sig, NULL);
214 }
215
DetectEngineHttpClientBodyTest02(void)216 static int DetectEngineHttpClientBodyTest02(void)
217 {
218 struct TestSteps steps[] = {
219 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
220 "Host: www.openinfosecfoundation.org\r\n"
221 "Content-Type: text/html\r\n"
222 "Content-Length: 19\r\n"
223 "\r\n"
224 "This is dummy body1",
225 0, STREAM_TOSERVER, 1 },
226 { NULL, 0, 0, 0 },
227 };
228
229 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:5; sid:1;)";
230 return RunTest(steps, sig, NULL);
231 }
232
DetectEngineHttpClientBodyTest03(void)233 static int DetectEngineHttpClientBodyTest03(void)
234 {
235 struct TestSteps steps[] = {
236 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
237 "Host: www.openinfosecfoundation.org\r\n"
238 "Content-Type: text/html\r\n"
239 "Content-Length: 46\r\n"
240 "\r\n"
241 "This is dummy body1",
242 0, STREAM_TOSERVER, 0 },
243 { (const uint8_t *)"This is dummy message body2",
244 0, STREAM_TOSERVER, 0 },
245 { NULL, 0, 0, 0 },
246 };
247
248 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:16; sid:1;)";
249 return RunTest(steps, sig, NULL);
250 }
251
DetectEngineHttpClientBodyTest04(void)252 static int DetectEngineHttpClientBodyTest04(void)
253 {
254 struct TestSteps steps[] = {
255 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
256 "Host: www.openinfosecfoundation.org\r\n"
257 "Content-Type: text/html\r\n"
258 "Content-Length: 46\r\n"
259 "\r\n"
260 "This is dummy body1",
261 0, STREAM_TOSERVER, 0 },
262 { (const uint8_t *)"This is dummy message body2",
263 0, STREAM_TOSERVER, 1 },
264 { NULL, 0, 0, 0 },
265 };
266
267 const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; offset:16; sid:1;)";
268 return RunTest(steps, sig, NULL);
269 }
270
DetectEngineHttpClientBodyTest05(void)271 static int DetectEngineHttpClientBodyTest05(void)
272 {
273 struct TestSteps steps[] = {
274 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
275 "Host: www.openinfosecfoundation.org\r\n"
276 "Content-Type: text/html\r\n"
277 "Content-Length: 46\r\n"
278 "\r\n"
279 "This is dummy body1",
280 0, STREAM_TOSERVER, 0 },
281 { (const uint8_t *)"This is dummy message body2",
282 0, STREAM_TOSERVER, 1 },
283 { NULL, 0, 0, 0 },
284 };
285
286 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; depth:25; sid:1;)";
287 return RunTest(steps, sig, NULL);
288 }
289
DetectEngineHttpClientBodyTest06(void)290 static int DetectEngineHttpClientBodyTest06(void)
291 {
292 struct TestSteps steps[] = {
293 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
294 "Host: www.openinfosecfoundation.org\r\n"
295 "Content-Type: text/html\r\n"
296 "Content-Length: 46\r\n"
297 "\r\n"
298 "This is dummy body1",
299 0, STREAM_TOSERVER, 0 },
300 { (const uint8_t *)"This is dummy message body2",
301 0, STREAM_TOSERVER, 0 },
302 { NULL, 0, 0, 0 },
303 };
304
305 const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:25; sid:1;)";
306 return RunTest(steps, sig, NULL);
307 }
308
DetectEngineHttpClientBodyTest07(void)309 static int DetectEngineHttpClientBodyTest07(void)
310 {
311 struct TestSteps steps[] = {
312 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
313 "Host: www.openinfosecfoundation.org\r\n"
314 "Content-Type: text/html\r\n"
315 "Content-Length: 46\r\n"
316 "\r\n"
317 "This is dummy body1",
318 0, STREAM_TOSERVER, 0 },
319 { (const uint8_t *)"This is dummy message body2",
320 0, STREAM_TOSERVER, 1 },
321 { NULL, 0, 0, 0 },
322 };
323
324 const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:15; sid:1;)";
325 return RunTest(steps, sig, NULL);
326 }
327
DetectEngineHttpClientBodyTest08(void)328 static int DetectEngineHttpClientBodyTest08(void)
329 {
330 struct TestSteps steps[] = {
331 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
332 "Host: www.openinfosecfoundation.org\r\n"
333 "Content-Type: text/html\r\n"
334 "Content-Length: 46\r\n"
335 "\r\n"
336 "This is dummy body1",
337 0, STREAM_TOSERVER, 0 },
338 { (const uint8_t *)"This is dummy message body2",
339 0, STREAM_TOSERVER, 1 },
340 { NULL, 0, 0, 0 },
341 };
342
343 const char *sig = "alert http any any -> any any (content:\"This is dummy body1This is dummy message body2\"; http_client_body; sid:1;)";
344 return RunTest(steps, sig, NULL);
345 }
346
DetectEngineHttpClientBodyTest09(void)347 static int DetectEngineHttpClientBodyTest09(void)
348 {
349 struct TestSteps steps[] = {
350 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
351 "Host: www.openinfosecfoundation.org\r\n"
352 "Content-Type: text/html\r\n"
353 "Content-Length: 46\r\n"
354 "\r\n"
355 "This is dummy body1",
356 0, STREAM_TOSERVER, 0 },
357 { (const uint8_t *)"This is dummy message body2",
358 0, STREAM_TOSERVER, 1 },
359 { NULL, 0, 0, 0 },
360 };
361
362 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"This\"; http_client_body; within:5; sid:1;)";
363 return RunTest(steps, sig, NULL);
364 }
365
DetectEngineHttpClientBodyTest10(void)366 static int DetectEngineHttpClientBodyTest10(void)
367 {
368 struct TestSteps steps[] = {
369 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
370 "Host: www.openinfosecfoundation.org\r\n"
371 "Content-Type: text/html\r\n"
372 "Content-Length: 46\r\n"
373 "\r\n"
374 "This is dummy body1",
375 0, STREAM_TOSERVER, 0 },
376 { (const uint8_t *)"This is dummy message body2",
377 0, STREAM_TOSERVER, 1 },
378 { NULL, 0, 0, 0 },
379 };
380
381 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"boom\"; http_client_body; within:5; sid:1;)";
382 return RunTest(steps, sig, NULL);
383 }
384
DetectEngineHttpClientBodyTest11(void)385 static int DetectEngineHttpClientBodyTest11(void)
386 {
387 struct TestSteps steps[] = {
388 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
389 "Host: www.openinfosecfoundation.org\r\n"
390 "Content-Type: text/html\r\n"
391 "Content-Length: 46\r\n"
392 "\r\n"
393 "This is dummy body1",
394 0, STREAM_TOSERVER, 0 },
395 { (const uint8_t *)"This is dummy message body2",
396 0, STREAM_TOSERVER, 0 },
397 { NULL, 0, 0, 0 },
398 };
399
400 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"boom\"; http_client_body; within:5; sid:1;)";
401 return RunTest(steps, sig, NULL);
402 }
403
DetectEngineHttpClientBodyTest12(void)404 static int DetectEngineHttpClientBodyTest12(void)
405 {
406 struct TestSteps steps[] = {
407 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
408 "Host: www.openinfosecfoundation.org\r\n"
409 "Content-Type: text/html\r\n"
410 "Content-Length: 46\r\n"
411 "\r\n"
412 "This is dummy body1",
413 0, STREAM_TOSERVER, 0 },
414 { (const uint8_t *)"This is dummy message body2",
415 0, STREAM_TOSERVER, 0 },
416 { NULL, 0, 0, 0 },
417 };
418
419 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"This\"; http_client_body; within:5; sid:1;)";
420 return RunTest(steps, sig, NULL);
421 }
422
DetectEngineHttpClientBodyTest13(void)423 static int DetectEngineHttpClientBodyTest13(void)
424 {
425 struct TestSteps steps[] = {
426 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
427 "Host: www.openinfosecfoundation.org\r\n"
428 "Content-Type: text/html\r\n"
429 "Content-Length: 46\r\n"
430 "\r\n"
431 "This is dummy body1",
432 0, STREAM_TOSERVER, 0 },
433 { (const uint8_t *)"This is dummy message body2",
434 0, STREAM_TOSERVER, 1 },
435 { NULL, 0, 0, 0 },
436 };
437
438 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:5; sid:1;)";
439 return RunTest(steps, sig, NULL);
440 }
441
DetectEngineHttpClientBodyTest14(void)442 static int DetectEngineHttpClientBodyTest14(void)
443 {
444 struct TestSteps steps[] = {
445 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
446 "Host: www.openinfosecfoundation.org\r\n"
447 "Content-Type: text/html\r\n"
448 "Content-Length: 46\r\n"
449 "\r\n"
450 "This is dummy body1",
451 0, STREAM_TOSERVER, 0 },
452 { (const uint8_t *)"This is dummy message body2",
453 0, STREAM_TOSERVER, 1 },
454 { NULL, 0, 0, 0 },
455 };
456
457 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:10; sid:1;)";
458 return RunTest(steps, sig, NULL);
459 }
460
DetectEngineHttpClientBodyTest15(void)461 static int DetectEngineHttpClientBodyTest15(void)
462 {
463 struct TestSteps steps[] = {
464 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
465 "Host: www.openinfosecfoundation.org\r\n"
466 "Content-Type: text/html\r\n"
467 "Content-Length: 46\r\n"
468 "\r\n"
469 "This is dummy body1",
470 0, STREAM_TOSERVER, 0 },
471 { (const uint8_t *)"This is dummy message body2",
472 0, STREAM_TOSERVER, 0 },
473 { NULL, 0, 0, 0 },
474 };
475
476 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:10; sid:1;)";
477 return RunTest(steps, sig, NULL);
478 }
479
DetectEngineHttpClientBodyTest16(void)480 static int DetectEngineHttpClientBodyTest16(void)
481 {
482 struct TestSteps steps[] = {
483 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
484 "Host: www.openinfosecfoundation.org\r\n"
485 "Content-Type: text/html\r\n"
486 "Content-Length: 46\r\n"
487 "\r\n"
488 "This is dummy body1",
489 0, STREAM_TOSERVER, 0 },
490 { (const uint8_t *)"This is dummy message body2",
491 0, STREAM_TOSERVER, 0 },
492 { NULL, 0, 0, 0 },
493 };
494
495 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:5; sid:1;)";
496 return RunTest(steps, sig, NULL);
497 }
498
DetectEngineHttpClientBodyTest17(void)499 static int DetectEngineHttpClientBodyTest17(void)
500 {
501 struct TestSteps steps[] = {
502 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
503 "Host: www.openinfosecfoundation.org\r\n"
504 "Content-Type: text/html\r\n"
505 "Content-Length: 19\r\n"
506 "\r\n"
507 "This is dummy body1",
508 0, STREAM_TOSERVER, 0 },
509 { NULL, 0, 0, 0 },
510 };
511
512 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; sid:1;)";
513 return RunTest(steps, sig, NULL);
514 }
515
DetectEngineHttpClientBodyTest18(void)516 static int DetectEngineHttpClientBodyTest18(void)
517 {
518 struct TestSteps steps[] = {
519 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
520 "Host: www.openinfosecfoundation.org\r\n"
521 "Content-Type: text/html\r\n"
522 "Content-Length: 19\r\n"
523 "\r\n"
524 "This is dummy body1",
525 0, STREAM_TOSERVER, 0 },
526 { NULL, 0, 0, 0 },
527 };
528
529 const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; fast_pattern; sid:1;)";
530 return RunTest(steps, sig, NULL);
531 }
532
DetectEngineHttpClientBodyTest19(void)533 static int DetectEngineHttpClientBodyTest19(void)
534 {
535 struct TestSteps steps[] = {
536 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
537 "Host: www.openinfosecfoundation.org\r\n"
538 "Content-Type: text/html\r\n"
539 "Content-Length: 19\r\n"
540 "\r\n"
541 "This is dummy body1",
542 0, STREAM_TOSERVER, 0 },
543 { NULL, 0, 0, 0 },
544 };
545
546 const char *sig = "alert http any any -> any any (content:\"bambu\"; http_client_body; content:\"is\"; http_client_body; sid:1;)";
547 return RunTest(steps, sig, NULL);
548 }
549
DetectEngineHttpClientBodyTest20(void)550 static int DetectEngineHttpClientBodyTest20(void)
551 {
552 struct TestSteps steps[] = {
553 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
554 "Host: www.openinfosecfoundation.org\r\n"
555 "Content-Type: text/html\r\n"
556 "Content-Length: 19\r\n"
557 "\r\n"
558 "This is dummy body1",
559 0, STREAM_TOSERVER, 1 },
560 { NULL, 0, 0, 0 },
561 };
562
563 const char *sig = "alert http any any -> any any (content:\"is\"; http_client_body; fast_pattern; sid:1;)";
564 return RunTest(steps, sig, NULL);
565 }
566
DetectEngineHttpClientBodyTest21(void)567 static int DetectEngineHttpClientBodyTest21(void)
568 {
569 struct TestSteps steps[] = {
570 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
571 "Host: www.openinfosecfoundation.org\r\n"
572 "Content-Type: text/html\r\n"
573 "Content-Length: 46\r\n"
574 "\r\n"
575 "This is dummy body1",
576 0, STREAM_TOSERVER, 0 },
577 { (const uint8_t *)"This is dummy message body2",
578 0, STREAM_TOSERVER, 1 },
579 { NULL, 0, 0, 0 },
580 };
581
582 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; http_client_body; within:7; sid:1;)";
583 return RunTest(steps, sig, NULL);
584 }
585
DetectEngineHttpClientBodyTest22(void)586 static int DetectEngineHttpClientBodyTest22(void)
587 {
588 struct TestSteps steps[] = {
589 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
590 "Host: www.openinfosecfoundation.org\r\n"
591 "Content-Type: text/html\r\n"
592 "Content-Length: 46\r\n"
593 "\r\n"
594 "This is dummy body1",
595 0, STREAM_TOSERVER, 0 },
596 { (const uint8_t *)"This is dummy message body2",
597 0, STREAM_TOSERVER, 1 },
598 { NULL, 0, 0, 0 },
599 };
600
601 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; within:7; http_client_body; sid:1;)";
602 return RunTest(steps, sig, NULL);
603 }
604
DetectEngineHttpClientBodyTest23(void)605 static int DetectEngineHttpClientBodyTest23(void)
606 {
607 struct TestSteps steps[] = {
608 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
609 "Host: www.openinfosecfoundation.org\r\n"
610 "Content-Type: text/html\r\n"
611 "Content-Length: 46\r\n"
612 "\r\n"
613 "This is dummy body1",
614 0, STREAM_TOSERVER, 0 },
615 { (const uint8_t *)"This is dummy message body2",
616 0, STREAM_TOSERVER, 0 },
617 { NULL, 0, 0, 0 },
618 };
619
620 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:3; http_client_body; sid:1;)";
621 return RunTest(steps, sig, NULL);
622 }
623
DetectEngineHttpClientBodyTest24(void)624 static int DetectEngineHttpClientBodyTest24(void)
625 {
626 struct TestSteps steps[] = {
627 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
628 "Host: www.openinfosecfoundation.org\r\n"
629 "Content-Type: text/html\r\n"
630 "Content-Length: 46\r\n"
631 "\r\n"
632 "This is dummy body1",
633 0, STREAM_TOSERVER, 0 },
634 { (const uint8_t *)"This is dummy message body2",
635 0, STREAM_TOSERVER, 1 },
636 { NULL, 0, 0, 0 },
637 };
638
639 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:13; http_client_body; sid:1;)";
640 return RunTest(steps, sig, NULL);
641 }
642
DetectEngineHttpClientBodyTest25(void)643 static int DetectEngineHttpClientBodyTest25(void)
644 {
645 struct TestSteps steps[] = {
646 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
647 "Host: www.openinfosecfoundation.org\r\n"
648 "Content-Type: text/html\r\n"
649 "Content-Length: 46\r\n"
650 "\r\n"
651 "This is dummy body1",
652 0, STREAM_TOSERVER, 0 },
653 { (const uint8_t *)"This is dummy message body2",
654 0, STREAM_TOSERVER, 1 },
655 { NULL, 0, 0, 0 },
656 };
657
658 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:15; http_client_body; sid:1;)";
659 return RunTest(steps, sig, NULL);
660 }
661
DetectEngineHttpClientBodyTest26(void)662 static int DetectEngineHttpClientBodyTest26(void)
663 {
664 struct TestSteps steps[] = {
665 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
666 "Host: www.openinfosecfoundation.org\r\n"
667 "Content-Type: text/html\r\n"
668 "Content-Length: 46\r\n"
669 "\r\n"
670 "This is dummy body1",
671 0, STREAM_TOSERVER, 0 },
672 { (const uint8_t *)"This is dummy message body2",
673 0, STREAM_TOSERVER, 0 },
674 { NULL, 0, 0, 0 },
675 };
676
677 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:10; http_client_body; sid:1;)";
678 return RunTest(steps, sig, NULL);
679 }
680
DetectEngineHttpClientBodyTest27(void)681 static int DetectEngineHttpClientBodyTest27(void)
682 {
683 struct TestSteps steps[] = {
684 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
685 "Host: www.openinfosecfoundation.org\r\n"
686 "Content-Type: text/html\r\n"
687 "Content-Length: 46\r\n"
688 "\r\n"
689 "This is dummy body1",
690 0, STREAM_TOSERVER, 0 },
691 { (const uint8_t *)"This is dummy message body2",
692 0, STREAM_TOSERVER, 1 },
693 { NULL, 0, 0, 0 },
694 };
695
696 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:8; http_client_body; sid:1;)";
697 return RunTest(steps, sig, NULL);
698 }
699
DetectEngineHttpClientBodyTest28(void)700 static int DetectEngineHttpClientBodyTest28(void)
701 {
702 struct TestSteps steps[] = {
703 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
704 "Host: www.openinfosecfoundation.org\r\n"
705 "Content-Type: text/html\r\n"
706 "Content-Length: 46\r\n"
707 "\r\n"
708 "This is dummy body1",
709 0, STREAM_TOSERVER, 0 },
710 { (const uint8_t *)"This is dummy message body2",
711 0, STREAM_TOSERVER, 0 },
712 { NULL, 0, 0, 0 },
713 };
714
715 const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:14; http_client_body; sid:1;)";
716 return RunTest(steps, sig, NULL);
717 }
718
DetectEngineHttpClientBodyTest29(void)719 static int DetectEngineHttpClientBodyTest29(void)
720 {
721 const char *request_buffer = "GET /one HTTP/1.0\r\n"
722 "Host: localhost\r\n\r\n";
723 #define TOTAL_REQUESTS 45
724 uint8_t *http_buf = SCMalloc(TOTAL_REQUESTS * strlen(request_buffer));
725 if (unlikely(http_buf == NULL))
726 return 0;
727 for (int i = 0; i < TOTAL_REQUESTS; i++) {
728 memcpy(http_buf + i * strlen(request_buffer), request_buffer,
729 strlen(request_buffer));
730 }
731 uint32_t http_buf_len = TOTAL_REQUESTS * strlen(request_buffer);
732 #undef TOTAL_REQUESTS
733
734 struct TestSteps steps[] = {
735 { (const uint8_t *)http_buf,
736 (size_t)http_buf_len, STREAM_TOSERVER, 0 },
737
738 { (const uint8_t *)"HTTP/1.0 200 ok\r\n"
739 "Content-Type: text/html\r\n"
740 "Content-Length: 5\r\n"
741 "\r\n"
742 "dummy",
743 0, STREAM_TOCLIENT, 0 },
744
745 { NULL, 0, 0, 0 },
746 };
747
748 const char *sig = "alert http any any -> any any (content:\"dummyone\"; fast_pattern:0,3; http_server_body; sid:1;)";
749 int result = RunTest(steps, sig, NULL);
750 SCFree(http_buf);
751 return result;
752 }
753
DetectEngineHttpClientBodyTest30(void)754 static int DetectEngineHttpClientBodyTest30(void)
755 {
756 const char yaml[] = "\
757 %YAML 1.1\n\
758 ---\n\
759 libhtp:\n\
760 \n\
761 default-config:\n\
762 personality: IDS\n\
763 request-body-limit: 0\n\
764 response-body-limit: 0\n\
765 \n\
766 request-body-inspect-window: 0\n\
767 response-body-inspect-window: 0\n\
768 request-body-minimal-inspect-size: 0\n\
769 response-body-minimal-inspect-size: 0\n\
770 ";
771 struct TestSteps steps[] = {
772 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
773 "Host: www.openinfosecfoundation.org\r\n"
774 "Content-Type: text/html\r\n"
775 "Content-Length: 46\r\n"
776 "\r\n"
777 "This is dummy body1",
778 0, STREAM_TOSERVER, 0 },
779 { (const uint8_t *)"This is dummy message body2",
780 0, STREAM_TOSERVER, 0 },
781 { NULL, 0, 0, 0 },
782 };
783
784 const char *sig = "alert http any any -> any any (content:\"bags\"; within:4; http_client_body; sid:1;)";
785 return RunTest(steps, sig, yaml);
786 }
787
DetectEngineHttpClientBodyTest31(void)788 static int DetectEngineHttpClientBodyTest31(void)
789 {
790 const char yaml[] = "\
791 %YAML 1.1\n\
792 ---\n\
793 libhtp:\n\
794 \n\
795 default-config:\n\
796 personality: IDS\n\
797 request-body-limit: 0\n\
798 response-body-limit: 0\n\
799 \n\
800 request-body-inspect-window: 0\n\
801 response-body-inspect-window: 0\n\
802 request-body-minimal-inspect-size: 0\n\
803 response-body-minimal-inspect-size: 0\n\
804 ";
805
806 struct TestSteps steps[] = {
807 { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
808 "Host: www.openinfosecfoundation.org\r\n"
809 "Content-Type: text/html\r\n"
810 "Content-Length: 46\r\n"
811 "\r\n"
812 "This is dummy body1",
813 0, STREAM_TOSERVER, 0 },
814 { (const uint8_t *)"This is dummy message body2",
815 0, STREAM_TOSERVER, 0 },
816 { NULL, 0, 0, 0 },
817 };
818
819 const char *sig = "alert http any any -> any any (content:\"bags\"; depth:4; http_client_body; sid:1;)";
820 return RunTest(steps, sig, yaml);
821 }
822
823 /**
824 * \test Test that a signature containting a http_client_body is correctly parsed
825 * and the keyword is registered.
826 */
DetectHttpClientBodyTest01(void)827 static int DetectHttpClientBodyTest01(void)
828 {
829 DetectEngineCtx *de_ctx = NULL;
830 int result = 0;
831 SigMatch *sm = NULL;
832
833 de_ctx = DetectEngineCtxInit();
834 if (de_ctx == NULL)
835 goto end;
836
837 de_ctx->flags |= DE_QUIET;
838 de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
839 "(msg:\"Testing http_client_body\"; "
840 "content:\"one\"; http_client_body; sid:1;)");
841 if (de_ctx->sig_list != NULL) {
842 result = 1;
843 } else {
844 goto end;
845 }
846
847 sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH];
848 if (sm != NULL) {
849 result &= (sm->type == DETECT_CONTENT);
850 result &= (sm->next == NULL);
851 }
852
853 end:
854 DetectEngineCtxFree(de_ctx);
855
856 return result;
857 }
858
859 /**
860 * \test Test that a signature containing an valid http_client_body entry is
861 * parsed.
862 */
DetectHttpClientBodyTest02(void)863 static int DetectHttpClientBodyTest02(void)
864 {
865 DetectEngineCtx *de_ctx = NULL;
866 int result = 0;
867
868 de_ctx = DetectEngineCtxInit();
869 if (de_ctx == NULL)
870 goto end;
871
872 de_ctx->flags |= DE_QUIET;
873 de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
874 "(msg:\"Testing http_client_body\"; "
875 "content:\"one\"; http_client_body:; sid:1;)");
876 if (de_ctx->sig_list != NULL)
877 result = 1;
878
879 end:
880 DetectEngineCtxFree(de_ctx);
881
882 return result;
883 }
884
885 /**
886 * \test Test that an invalid signature containing no content but a http_client_body
887 * is invalidated.
888 */
DetectHttpClientBodyTest03(void)889 static int DetectHttpClientBodyTest03(void)
890 {
891 DetectEngineCtx *de_ctx = NULL;
892 int result = 0;
893
894 de_ctx = DetectEngineCtxInit();
895 if (de_ctx == NULL)
896 goto end;
897
898 de_ctx->flags |= DE_QUIET;
899 de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
900 "(msg:\"Testing http_client_body\"; "
901 "http_client_body; sid:1;)");
902 if (de_ctx->sig_list == NULL)
903 result = 1;
904
905 end:
906 DetectEngineCtxFree(de_ctx);
907
908 return result;
909 }
910
911 /**
912 * \test Test that an invalid signature containing a rawbytes along with a
913 * http_client_body is invalidated.
914 */
DetectHttpClientBodyTest04(void)915 static int DetectHttpClientBodyTest04(void)
916 {
917 DetectEngineCtx *de_ctx = NULL;
918 int result = 0;
919
920 de_ctx = DetectEngineCtxInit();
921 if (de_ctx == NULL)
922 goto end;
923
924 de_ctx->flags |= DE_QUIET;
925 de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
926 "(msg:\"Testing http_client_body\"; "
927 "content:\"one\"; rawbytes; http_client_body; sid:1;)");
928 if (de_ctx->sig_list == NULL)
929 result = 1;
930
931 end:
932 DetectEngineCtxFree(de_ctx);
933
934 return result;
935 }
936
937 /**
938 * \test Test that an invalid signature containing a rawbytes along with a
939 * http_client_body is invalidated.
940 */
DetectHttpClientBodyTest05(void)941 static int DetectHttpClientBodyTest05(void)
942 {
943 DetectEngineCtx *de_ctx = NULL;
944 int result = 0;
945
946 de_ctx = DetectEngineCtxInit();
947 if (de_ctx == NULL)
948 goto end;
949
950 de_ctx->flags |= DE_QUIET;
951 de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
952 "(msg:\"Testing http_client_body\"; "
953 "content:\"one\"; http_client_body; nocase; sid:1;)");
954 if (de_ctx->sig_list != NULL)
955 result = 1;
956
957 end:
958 DetectEngineCtxFree(de_ctx);
959
960 return result;
961 }
962
963 /**
964 *\test Test that the http_client_body content matches against a http request
965 * which holds the content.
966 */
DetectHttpClientBodyTest06(void)967 static int DetectHttpClientBodyTest06(void)
968 {
969 TcpSession ssn;
970 Packet *p = NULL;
971 ThreadVars th_v;
972 DetectEngineCtx *de_ctx = NULL;
973 DetectEngineThreadCtx *det_ctx = NULL;
974 HtpState *http_state = NULL;
975 Flow f;
976 uint8_t http_buf[] =
977 "GET /index.html HTTP/1.0\r\n"
978 "Host: www.openinfosecfoundation.org\r\n"
979 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
980 "Content-Type: text/html\r\n"
981 "Content-Length: 26\r\n"
982 "\r\n"
983 "This is dummy message body";
984 uint32_t http_len = sizeof(http_buf) - 1;
985 int result = 0;
986 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
987
988 memset(&th_v, 0, sizeof(th_v));
989 memset(&f, 0, sizeof(f));
990 memset(&ssn, 0, sizeof(ssn));
991
992 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
993
994 FLOW_INITIALIZE(&f);
995 f.protoctx = (void *)&ssn;
996 f.proto = IPPROTO_TCP;
997 f.flags |= FLOW_IPV4;
998
999 p->flow = &f;
1000 p->flowflags |= FLOW_PKT_TOSERVER;
1001 p->flowflags |= FLOW_PKT_ESTABLISHED;
1002 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1003 f.alproto = ALPROTO_HTTP;
1004
1005 StreamTcpInitConfig(TRUE);
1006
1007 de_ctx = DetectEngineCtxInit();
1008 if (de_ctx == NULL)
1009 goto end;
1010
1011 de_ctx->flags |= DE_QUIET;
1012
1013 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1014 "(msg:\"http client body test\"; "
1015 "content:\"message\"; http_client_body; "
1016 "sid:1;)");
1017 if (de_ctx->sig_list == NULL)
1018 goto end;
1019
1020 SigGroupBuild(de_ctx);
1021 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1022
1023 FLOWLOCK_WRLOCK(&f);
1024 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1025 STREAM_TOSERVER, http_buf, http_len);
1026 if (r != 0) {
1027 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1028 result = 0;
1029 FLOWLOCK_UNLOCK(&f);
1030 goto end;
1031 }
1032 FLOWLOCK_UNLOCK(&f);
1033
1034 http_state = f.alstate;
1035 if (http_state == NULL) {
1036 printf("no http state: \n");
1037 result = 0;
1038 goto end;
1039 }
1040
1041 /* do detect */
1042 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1043
1044 if (!(PacketAlertCheck(p, 1))) {
1045 printf("sid 1 didn't match but should have\n");
1046 goto end;
1047 }
1048
1049 result = 1;
1050 end:
1051 if (alp_tctx != NULL)
1052 AppLayerParserThreadCtxFree(alp_tctx);
1053 if (de_ctx != NULL)
1054 DetectEngineCtxFree(de_ctx);
1055
1056 StreamTcpFreeConfig(TRUE);
1057 FLOW_DESTROY(&f);
1058 UTHFreePackets(&p, 1);
1059 return result;
1060 }
1061
1062 /**
1063 *\test Test that the http_client_body content matches against a http request
1064 * which holds the content.
1065 */
DetectHttpClientBodyTest07(void)1066 static int DetectHttpClientBodyTest07(void)
1067 {
1068 TcpSession ssn;
1069 Packet *p1 = NULL;
1070 Packet *p2 = NULL;
1071 ThreadVars th_v;
1072 DetectEngineCtx *de_ctx = NULL;
1073 DetectEngineThreadCtx *det_ctx = NULL;
1074 HtpState *http_state = NULL;
1075 Flow f;
1076 uint8_t http1_buf[] =
1077 "GET /index.html HTTP/1.0\r\n"
1078 "Host: www.openinfosecfoundation.org\r\n"
1079 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1080 "Content-Type: text/html\r\n"
1081 "Content-Length: 54\r\n"
1082 "\r\n"
1083 "This is dummy message body1";
1084 uint8_t http2_buf[] =
1085 "This is dummy message body2";
1086 uint32_t http1_len = sizeof(http1_buf) - 1;
1087 uint32_t http2_len = sizeof(http2_buf) - 1;
1088 int result = 0;
1089 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1090
1091 memset(&th_v, 0, sizeof(th_v));
1092 memset(&f, 0, sizeof(f));
1093 memset(&ssn, 0, sizeof(ssn));
1094
1095 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1096 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1097
1098 FLOW_INITIALIZE(&f);
1099 f.protoctx = (void *)&ssn;
1100 f.proto = IPPROTO_TCP;
1101 f.flags |= FLOW_IPV4;
1102
1103 p1->flow = &f;
1104 p1->flowflags |= FLOW_PKT_TOSERVER;
1105 p1->flowflags |= FLOW_PKT_ESTABLISHED;
1106 p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1107 p2->flow = &f;
1108 p2->flowflags |= FLOW_PKT_TOSERVER;
1109 p2->flowflags |= FLOW_PKT_ESTABLISHED;
1110 p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1111 f.alproto = ALPROTO_HTTP;
1112
1113 StreamTcpInitConfig(TRUE);
1114
1115 de_ctx = DetectEngineCtxInit();
1116 if (de_ctx == NULL)
1117 goto end;
1118
1119 de_ctx->flags |= DE_QUIET;
1120
1121 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1122 "(msg:\"http client body test\"; "
1123 "content:\"message\"; http_client_body; "
1124 "sid:1;)");
1125 if (de_ctx->sig_list == NULL)
1126 goto end;
1127
1128 SigGroupBuild(de_ctx);
1129 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1130
1131 FLOWLOCK_WRLOCK(&f);
1132 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1133 STREAM_TOSERVER, http1_buf, http1_len);
1134 if (r != 0) {
1135 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1136 result = 0;
1137 FLOWLOCK_UNLOCK(&f);
1138 goto end;
1139 }
1140 FLOWLOCK_UNLOCK(&f);
1141
1142 http_state = f.alstate;
1143 if (http_state == NULL) {
1144 printf("no http state: ");
1145 goto end;
1146 }
1147
1148 /* do detect */
1149 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1150
1151 if (PacketAlertCheck(p1, 1)) {
1152 printf("sid 1 matched on p1 but shouldn't have: ");
1153 goto end;
1154 }
1155
1156 FLOWLOCK_WRLOCK(&f);
1157 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1158 STREAM_TOSERVER, http2_buf, http2_len);
1159 if (r != 0) {
1160 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1161 FLOWLOCK_UNLOCK(&f);
1162 goto end;
1163 }
1164 FLOWLOCK_UNLOCK(&f);
1165
1166 /* do detect */
1167 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1168 if (!(PacketAlertCheck(p2, 1))) {
1169 printf("sid 1 didn't match on p2 but should have: ");
1170 goto end;
1171 }
1172
1173 result = 1;
1174 end:
1175 if (alp_tctx != NULL)
1176 AppLayerParserThreadCtxFree(alp_tctx);
1177 if (de_ctx != NULL)
1178 DetectEngineCtxFree(de_ctx);
1179
1180 StreamTcpFreeConfig(TRUE);
1181 FLOW_DESTROY(&f);
1182 UTHFreePackets(&p1, 1);
1183 UTHFreePackets(&p2, 1);
1184 return result;
1185 }
1186
1187 /**
1188 *\test Test that the http_client_body content matches against a http request
1189 * which holds the content.
1190 */
DetectHttpClientBodyTest08(void)1191 static int DetectHttpClientBodyTest08(void)
1192 {
1193 TcpSession ssn;
1194 Packet *p1 = NULL;
1195 Packet *p2 = NULL;
1196 ThreadVars th_v;
1197 DetectEngineCtx *de_ctx = NULL;
1198 DetectEngineThreadCtx *det_ctx = NULL;
1199 HtpState *http_state = NULL;
1200 Flow f;
1201 uint8_t http1_buf[] =
1202 "GET /index.html HTTP/1.0\r\n"
1203 "Host: www.openinfosecfoundation.org\r\n"
1204 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1205 "Content-Type: text/html\r\n"
1206 "Content-Length: 46\r\n"
1207 "\r\n"
1208 "This is dummy body1";
1209 uint8_t http2_buf[] =
1210 "This is dummy message body2";
1211 uint32_t http1_len = sizeof(http1_buf) - 1;
1212 uint32_t http2_len = sizeof(http2_buf) - 1;
1213 int result = 0;
1214 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1215
1216 memset(&th_v, 0, sizeof(th_v));
1217 memset(&f, 0, sizeof(f));
1218 memset(&ssn, 0, sizeof(ssn));
1219
1220 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1221 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1222
1223 FLOW_INITIALIZE(&f);
1224 f.protoctx = (void *)&ssn;
1225 f.proto = IPPROTO_TCP;
1226 f.flags |= FLOW_IPV4;
1227
1228 p1->flow = &f;
1229 p1->flowflags |= FLOW_PKT_TOSERVER;
1230 p1->flowflags |= FLOW_PKT_ESTABLISHED;
1231 p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1232 p2->flow = &f;
1233 p2->flowflags |= FLOW_PKT_TOSERVER;
1234 p2->flowflags |= FLOW_PKT_ESTABLISHED;
1235 p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1236 f.alproto = ALPROTO_HTTP;
1237
1238 StreamTcpInitConfig(TRUE);
1239
1240 de_ctx = DetectEngineCtxInit();
1241 if (de_ctx == NULL)
1242 goto end;
1243
1244 de_ctx->flags |= DE_QUIET;
1245
1246 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1247 "(msg:\"http client body test\"; "
1248 "content:\"message\"; http_client_body; "
1249 "sid:1;)");
1250 if (de_ctx->sig_list == NULL)
1251 goto end;
1252
1253 SigGroupBuild(de_ctx);
1254 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1255
1256 FLOWLOCK_WRLOCK(&f);
1257 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1258 STREAM_TOSERVER, http1_buf, http1_len);
1259 if (r != 0) {
1260 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1261 result = 0;
1262 FLOWLOCK_UNLOCK(&f);
1263 goto end;
1264 }
1265 FLOWLOCK_UNLOCK(&f);
1266
1267 http_state = f.alstate;
1268 if (http_state == NULL) {
1269 printf("no http state: ");
1270 result = 0;
1271 goto end;
1272 }
1273
1274 /* do detect */
1275 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1276
1277 if ((PacketAlertCheck(p1, 1))) {
1278 printf("sid 1 didn't match but should have");
1279 goto end;
1280 }
1281
1282 FLOWLOCK_WRLOCK(&f);
1283 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1284 STREAM_TOSERVER, http2_buf, http2_len);
1285 if (r != 0) {
1286 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1287 result = 0;
1288 FLOWLOCK_UNLOCK(&f);
1289 goto end;
1290 }
1291 FLOWLOCK_UNLOCK(&f);
1292
1293 /* do detect */
1294 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1295
1296 if (!(PacketAlertCheck(p2, 1))) {
1297 printf("sid 1 didn't match but should have");
1298 goto end;
1299 }
1300
1301 result = 1;
1302 end:
1303 if (alp_tctx != NULL)
1304 AppLayerParserThreadCtxFree(alp_tctx);
1305 if (de_ctx != NULL)
1306 DetectEngineCtxFree(de_ctx);
1307
1308 StreamTcpFreeConfig(TRUE);
1309 FLOW_DESTROY(&f);
1310 UTHFreePackets(&p1, 1);
1311 UTHFreePackets(&p2, 1);
1312 return result;
1313 }
1314
1315 /**
1316 *\test Test that the http_client_body content matches against a http request
1317 * which holds the content, against a cross boundary present pattern.
1318 */
DetectHttpClientBodyTest09(void)1319 static int DetectHttpClientBodyTest09(void)
1320 {
1321 TcpSession ssn;
1322 Packet *p1 = NULL;
1323 Packet *p2 = NULL;
1324 ThreadVars th_v;
1325 DetectEngineCtx *de_ctx = NULL;
1326 DetectEngineThreadCtx *det_ctx = NULL;
1327 HtpState *http_state = NULL;
1328 Flow f;
1329 uint8_t http1_buf[] =
1330 "GET /index.html HTTP/1.0\r\n"
1331 "Host: www.openinfosecfoundation.org\r\n"
1332 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1333 "Content-Type: text/html\r\n"
1334 "Content-Length: 46\r\n"
1335 "\r\n"
1336 "This is dummy body1";
1337 uint8_t http2_buf[] =
1338 "This is dummy message body2";
1339 uint32_t http1_len = sizeof(http1_buf) - 1;
1340 uint32_t http2_len = sizeof(http2_buf) - 1;
1341 int result = 0;
1342 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1343
1344 memset(&th_v, 0, sizeof(th_v));
1345 memset(&f, 0, sizeof(f));
1346 memset(&ssn, 0, sizeof(ssn));
1347
1348 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1349 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1350
1351 FLOW_INITIALIZE(&f);
1352 f.protoctx = (void *)&ssn;
1353 f.proto = IPPROTO_TCP;
1354 f.flags |= FLOW_IPV4;
1355
1356 p1->flow = &f;
1357 p1->flowflags |= FLOW_PKT_TOSERVER;
1358 p1->flowflags |= FLOW_PKT_ESTABLISHED;
1359 p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1360 p2->flow = &f;
1361 p2->flowflags |= FLOW_PKT_TOSERVER;
1362 p2->flowflags |= FLOW_PKT_ESTABLISHED;
1363 p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1364 f.alproto = ALPROTO_HTTP;
1365
1366 StreamTcpInitConfig(TRUE);
1367
1368 de_ctx = DetectEngineCtxInit();
1369 if (de_ctx == NULL)
1370 goto end;
1371
1372 de_ctx->flags |= DE_QUIET;
1373
1374 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1375 "(msg:\"http client body test\"; "
1376 "content:\"body1This\"; http_client_body; "
1377 "sid:1;)");
1378 if (de_ctx->sig_list == NULL)
1379 goto end;
1380
1381 SigGroupBuild(de_ctx);
1382 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1383
1384 FLOWLOCK_WRLOCK(&f);
1385 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1386 STREAM_TOSERVER, http1_buf, http1_len);
1387 if (r != 0) {
1388 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1389 result = 0;
1390 FLOWLOCK_UNLOCK(&f);
1391 goto end;
1392 }
1393 FLOWLOCK_UNLOCK(&f);
1394
1395 http_state = f.alstate;
1396 if (http_state == NULL) {
1397 printf("no http state: ");
1398 result = 0;
1399 goto end;
1400 }
1401
1402 /* do detect */
1403 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1404
1405 if ((PacketAlertCheck(p1, 1))) {
1406 printf("sid 1 didn't match but should have");
1407 goto end;
1408 }
1409
1410 FLOWLOCK_WRLOCK(&f);
1411 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1412 STREAM_TOSERVER, http2_buf, http2_len);
1413 if (r != 0) {
1414 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1415 result = 0;
1416 FLOWLOCK_UNLOCK(&f);
1417 goto end;
1418 }
1419 FLOWLOCK_UNLOCK(&f);
1420
1421 /* do detect */
1422 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1423
1424 if (!(PacketAlertCheck(p2, 1))) {
1425 printf("sid 1 didn't match but should have");
1426 goto end;
1427 }
1428
1429 result = 1;
1430 end:
1431 if (alp_tctx != NULL)
1432 AppLayerParserThreadCtxFree(alp_tctx);
1433 if (de_ctx != NULL)
1434 DetectEngineCtxFree(de_ctx);
1435
1436 StreamTcpFreeConfig(TRUE);
1437 FLOW_DESTROY(&f);
1438 UTHFreePackets(&p1, 1);
1439 UTHFreePackets(&p2, 1);
1440 return result;
1441 }
1442
1443 /**
1444 *\test Test that the http_client_body content matches against a http request
1445 * against a case insensitive pattern.
1446 */
DetectHttpClientBodyTest10(void)1447 static int DetectHttpClientBodyTest10(void)
1448 {
1449 TcpSession ssn;
1450 Packet *p1 = NULL;
1451 Packet *p2 = NULL;
1452 ThreadVars th_v;
1453 DetectEngineCtx *de_ctx = NULL;
1454 DetectEngineThreadCtx *det_ctx = NULL;
1455 HtpState *http_state = NULL;
1456 Flow f;
1457 uint8_t http1_buf[] =
1458 "GET /index.html HTTP/1.0\r\n"
1459 "Host: www.openinfosecfoundation.org\r\n"
1460 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1461 "Content-Type: text/html\r\n"
1462 "Content-Length: 46\r\n"
1463 "\r\n"
1464 "This is dummy bodY1";
1465 uint8_t http2_buf[] =
1466 "This is dummy message body2";
1467 uint32_t http1_len = sizeof(http1_buf) - 1;
1468 uint32_t http2_len = sizeof(http2_buf) - 1;
1469 int result = 0;
1470 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1471
1472 memset(&th_v, 0, sizeof(th_v));
1473 memset(&f, 0, sizeof(f));
1474 memset(&ssn, 0, sizeof(ssn));
1475
1476 p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1477 p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1478
1479 FLOW_INITIALIZE(&f);
1480 f.protoctx = (void *)&ssn;
1481 f.proto = IPPROTO_TCP;
1482 f.flags |= FLOW_IPV4;
1483
1484 p1->flow = &f;
1485 p1->flowflags |= FLOW_PKT_TOSERVER;
1486 p1->flowflags |= FLOW_PKT_ESTABLISHED;
1487 p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1488 p2->flow = &f;
1489 p2->flowflags |= FLOW_PKT_TOSERVER;
1490 p2->flowflags |= FLOW_PKT_ESTABLISHED;
1491 p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1492 f.alproto = ALPROTO_HTTP;
1493
1494 StreamTcpInitConfig(TRUE);
1495
1496 de_ctx = DetectEngineCtxInit();
1497 if (de_ctx == NULL)
1498 goto end;
1499
1500 de_ctx->flags |= DE_QUIET;
1501
1502 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1503 "(msg:\"http client body test\"; "
1504 "content:\"body1This\"; http_client_body; nocase;"
1505 "sid:1;)");
1506 if (de_ctx->sig_list == NULL)
1507 goto end;
1508
1509 SigGroupBuild(de_ctx);
1510 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1511
1512 FLOWLOCK_WRLOCK(&f);
1513 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1514 STREAM_TOSERVER, http1_buf, http1_len);
1515 if (r != 0) {
1516 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1517 result = 0;
1518 FLOWLOCK_UNLOCK(&f);
1519 goto end;
1520 }
1521 FLOWLOCK_UNLOCK(&f);
1522
1523 http_state = f.alstate;
1524 if (http_state == NULL) {
1525 printf("no http state: \n");
1526 result = 0;
1527 goto end;
1528 }
1529
1530 /* do detect */
1531 SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1532
1533 if ((PacketAlertCheck(p1, 1))) {
1534 printf("sid 1 didn't match but should have\n");
1535 goto end;
1536 }
1537
1538 FLOWLOCK_WRLOCK(&f);
1539 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1540 STREAM_TOSERVER, http2_buf, http2_len);
1541 if (r != 0) {
1542 printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1543 result = 0;
1544 FLOWLOCK_UNLOCK(&f);
1545 goto end;
1546 }
1547 FLOWLOCK_UNLOCK(&f);
1548
1549 /* do detect */
1550 SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1551
1552 if (!(PacketAlertCheck(p2, 1))) {
1553 printf("sid 1 didn't match but should have");
1554 goto end;
1555 }
1556
1557 result = 1;
1558 end:
1559 if (alp_tctx != NULL)
1560 AppLayerParserThreadCtxFree(alp_tctx);
1561 if (de_ctx != NULL)
1562 DetectEngineCtxFree(de_ctx);
1563
1564 StreamTcpFreeConfig(TRUE);
1565 FLOW_DESTROY(&f);
1566 UTHFreePackets(&p1, 1);
1567 UTHFreePackets(&p2, 1);
1568 return result;
1569 }
1570
1571 /**
1572 *\test Test that the negated http_client_body content matches against a
1573 * http request which doesn't hold the content.
1574 */
DetectHttpClientBodyTest11(void)1575 static int DetectHttpClientBodyTest11(void)
1576 {
1577 TcpSession ssn;
1578 Packet *p = NULL;
1579 ThreadVars th_v;
1580 DetectEngineCtx *de_ctx = NULL;
1581 DetectEngineThreadCtx *det_ctx = NULL;
1582 HtpState *http_state = NULL;
1583 Flow f;
1584 uint8_t http_buf[] =
1585 "GET /index.html HTTP/1.0\r\n"
1586 "Host: www.openinfosecfoundation.org\r\n"
1587 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1588 "Content-Type: text/html\r\n"
1589 "Content-Length: 26\r\n"
1590 "\r\n"
1591 "This is dummy message body";
1592 uint32_t http_len = sizeof(http_buf) - 1;
1593 int result = 0;
1594 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1595
1596 memset(&th_v, 0, sizeof(th_v));
1597 memset(&f, 0, sizeof(f));
1598 memset(&ssn, 0, sizeof(ssn));
1599
1600 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1601
1602 FLOW_INITIALIZE(&f);
1603 f.protoctx = (void *)&ssn;
1604 f.proto = IPPROTO_TCP;
1605 f.flags |= FLOW_IPV4;
1606
1607 p->flow = &f;
1608 p->flowflags |= FLOW_PKT_TOSERVER;
1609 p->flowflags |= FLOW_PKT_ESTABLISHED;
1610 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1611 f.alproto = ALPROTO_HTTP;
1612
1613 StreamTcpInitConfig(TRUE);
1614
1615 de_ctx = DetectEngineCtxInit();
1616 if (de_ctx == NULL)
1617 goto end;
1618
1619 de_ctx->flags |= DE_QUIET;
1620
1621 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1622 "(msg:\"http client body test\"; "
1623 "content:!\"message1\"; http_client_body; "
1624 "sid:1;)");
1625 if (de_ctx->sig_list == NULL)
1626 goto end;
1627
1628 SigGroupBuild(de_ctx);
1629 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1630
1631 FLOWLOCK_WRLOCK(&f);
1632 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1633 STREAM_TOSERVER, http_buf, http_len);
1634 if (r != 0) {
1635 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1636 result = 0;
1637 FLOWLOCK_UNLOCK(&f);
1638 goto end;
1639 }
1640 FLOWLOCK_UNLOCK(&f);
1641
1642 http_state = f.alstate;
1643 if (http_state == NULL) {
1644 printf("no http state: ");
1645 result = 0;
1646 goto end;
1647 }
1648
1649 /* do detect */
1650 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1651
1652 if (!(PacketAlertCheck(p, 1))) {
1653 printf("sid 1 didn't match but should have");
1654 goto end;
1655 }
1656
1657 result = 1;
1658 end:
1659 if (alp_tctx != NULL)
1660 AppLayerParserThreadCtxFree(alp_tctx);
1661 if (de_ctx != NULL)
1662 DetectEngineCtxFree(de_ctx);
1663
1664 StreamTcpFreeConfig(TRUE);
1665 FLOW_DESTROY(&f);
1666 UTHFreePackets(&p, 1);
1667 return result;
1668 }
1669
1670 /**
1671 *\test Negative test that the negated http_client_body content matches against a
1672 * http request which holds hold the content.
1673 */
DetectHttpClientBodyTest12(void)1674 static int DetectHttpClientBodyTest12(void)
1675 {
1676 TcpSession ssn;
1677 Packet *p = NULL;
1678 ThreadVars th_v;
1679 DetectEngineCtx *de_ctx = NULL;
1680 DetectEngineThreadCtx *det_ctx = NULL;
1681 HtpState *http_state = NULL;
1682 Flow f;
1683 uint8_t http_buf[] =
1684 "GET /index.html HTTP/1.0\r\n"
1685 "Host: www.openinfosecfoundation.org\r\n"
1686 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1687 "Content-Type: text/html\r\n"
1688 "Content-Length: 26\r\n"
1689 "\r\n"
1690 "This is dummy message body";
1691 uint32_t http_len = sizeof(http_buf) - 1;
1692 int result = 0;
1693 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1694
1695 memset(&th_v, 0, sizeof(th_v));
1696 memset(&f, 0, sizeof(f));
1697 memset(&ssn, 0, sizeof(ssn));
1698
1699 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1700
1701 FLOW_INITIALIZE(&f);
1702 f.protoctx = (void *)&ssn;
1703 f.proto = IPPROTO_TCP;
1704 f.flags |= FLOW_IPV4;
1705
1706 p->flow = &f;
1707 p->flowflags |= FLOW_PKT_TOSERVER;
1708 p->flowflags |= FLOW_PKT_ESTABLISHED;
1709 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1710 f.alproto = ALPROTO_HTTP;
1711
1712 StreamTcpInitConfig(TRUE);
1713
1714 de_ctx = DetectEngineCtxInit();
1715 if (de_ctx == NULL)
1716 goto end;
1717
1718 de_ctx->flags |= DE_QUIET;
1719
1720 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1721 "(msg:\"http client body test\"; "
1722 "content:!\"message\"; http_client_body; "
1723 "sid:1;)");
1724 if (de_ctx->sig_list == NULL)
1725 goto end;
1726
1727 SigGroupBuild(de_ctx);
1728 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1729
1730 FLOWLOCK_WRLOCK(&f);
1731 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1732 STREAM_TOSERVER, http_buf, http_len);
1733 if (r != 0) {
1734 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1735 result = 0;
1736 FLOWLOCK_UNLOCK(&f);
1737 goto end;
1738 }
1739 FLOWLOCK_UNLOCK(&f);
1740
1741 http_state = f.alstate;
1742 if (http_state == NULL) {
1743 printf("no http state: ");
1744 result = 0;
1745 goto end;
1746 }
1747
1748 /* do detect */
1749 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1750
1751 if ((PacketAlertCheck(p, 1))) {
1752 printf("sid 1 didn't match but should have");
1753 goto end;
1754 }
1755
1756 result = 1;
1757 end:
1758 if (alp_tctx != NULL)
1759 AppLayerParserThreadCtxFree(alp_tctx);
1760 if (de_ctx != NULL)
1761 DetectEngineCtxFree(de_ctx);
1762
1763 StreamTcpFreeConfig(TRUE);
1764 FLOW_DESTROY(&f);
1765 UTHFreePackets(&p, 1);
1766 return result;
1767 }
1768
1769 /**
1770 *\test Test that the http_client_body content matches against a http request
1771 * which holds the content.
1772 */
DetectHttpClientBodyTest13(void)1773 static int DetectHttpClientBodyTest13(void)
1774 {
1775 TcpSession ssn;
1776 Packet *p = NULL;
1777 ThreadVars th_v;
1778 DetectEngineCtx *de_ctx = NULL;
1779 DetectEngineThreadCtx *det_ctx = NULL;
1780 HtpState *http_state = NULL;
1781 Flow f;
1782 uint8_t http_buf[] =
1783 "GET /index.html HTTP/1.0\r\n"
1784 "Host: www.openinfosecfoundation.org\r\n"
1785 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1786 "Content-Type: text/html\r\n"
1787 "Content-Length: 55\r\n"
1788 "\r\n"
1789 "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend";
1790 uint32_t http_len = sizeof(http_buf) - 1;
1791 int result = 0;
1792 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1793
1794 memset(&th_v, 0, sizeof(th_v));
1795 memset(&f, 0, sizeof(f));
1796 memset(&ssn, 0, sizeof(ssn));
1797
1798 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1799
1800 FLOW_INITIALIZE(&f);
1801 f.protoctx = (void *)&ssn;
1802 f.proto = IPPROTO_TCP;
1803 f.flags |= FLOW_IPV4;
1804
1805 p->flow = &f;
1806 p->flowflags |= FLOW_PKT_TOSERVER;
1807 p->flowflags |= FLOW_PKT_ESTABLISHED;
1808 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1809 f.alproto = ALPROTO_HTTP;
1810
1811 StreamTcpInitConfig(TRUE);
1812
1813 de_ctx = DetectEngineCtxInit();
1814 if (de_ctx == NULL)
1815 goto end;
1816
1817 de_ctx->flags |= DE_QUIET;
1818
1819 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1820 "(msg:\"http client body test\"; "
1821 "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_client_body; "
1822 "sid:1;)");
1823 if (de_ctx->sig_list == NULL)
1824 goto end;
1825
1826 SigGroupBuild(de_ctx);
1827 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1828
1829 FLOWLOCK_WRLOCK(&f);
1830 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1831 STREAM_TOSERVER, http_buf, http_len);
1832 if (r != 0) {
1833 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1834 result = 0;
1835 FLOWLOCK_UNLOCK(&f);
1836 goto end;
1837 }
1838 FLOWLOCK_UNLOCK(&f);
1839
1840 http_state = f.alstate;
1841 if (http_state == NULL) {
1842 printf("no http state: ");
1843 result = 0;
1844 goto end;
1845 }
1846
1847 /* do detect */
1848 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1849
1850 if (!(PacketAlertCheck(p, 1))) {
1851 printf("sid 1 didn't match but should have");
1852 goto end;
1853 }
1854
1855 result = 1;
1856 end:
1857 if (alp_tctx != NULL)
1858 AppLayerParserThreadCtxFree(alp_tctx);
1859 if (de_ctx != NULL)
1860 DetectEngineCtxFree(de_ctx);
1861
1862 StreamTcpFreeConfig(TRUE);
1863 FLOW_DESTROY(&f);
1864 UTHFreePackets(&p, 1);
1865 return result;
1866 }
1867
1868 /** \test multiple http transactions and body chunks of request handling */
DetectHttpClientBodyTest14(void)1869 static int DetectHttpClientBodyTest14(void)
1870 {
1871 int result = 0;
1872 Signature *s = NULL;
1873 DetectEngineThreadCtx *det_ctx = NULL;
1874 ThreadVars th_v;
1875 Flow f;
1876 TcpSession ssn;
1877 Packet *p = NULL;
1878 uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
1879 uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1880 uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
1881 uint8_t httpbuf4[] = "Body one!!";
1882 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1883 uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1884 uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1885 uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1886 uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
1887 uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
1888 uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1889 uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
1890 uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
1891 uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
1892 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1893
1894 memset(&th_v, 0, sizeof(th_v));
1895 memset(&f, 0, sizeof(f));
1896 memset(&ssn, 0, sizeof(ssn));
1897
1898 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1899
1900 FLOW_INITIALIZE(&f);
1901 f.protoctx = (void *)&ssn;
1902 f.proto = IPPROTO_TCP;
1903 f.flags |= FLOW_IPV4;
1904
1905 p->flow = &f;
1906 p->flowflags |= FLOW_PKT_TOSERVER;
1907 p->flowflags |= FLOW_PKT_ESTABLISHED;
1908 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1909 f.alproto = ALPROTO_HTTP;
1910
1911 StreamTcpInitConfig(TRUE);
1912
1913 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1914 if (de_ctx == NULL) {
1915 goto end;
1916 }
1917
1918 de_ctx->flags |= DE_QUIET;
1919
1920 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)");
1921 if (s == NULL) {
1922 printf("sig parse failed: ");
1923 goto end;
1924 }
1925 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)");
1926 if (s == NULL) {
1927 printf("sig2 parse failed: ");
1928 goto end;
1929 }
1930
1931 SigGroupBuild(de_ctx);
1932 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1933
1934 FLOWLOCK_WRLOCK(&f);
1935 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1936 STREAM_TOSERVER, httpbuf1, httplen1);
1937 if (r != 0) {
1938 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1939 FLOWLOCK_UNLOCK(&f);
1940 goto end;
1941 }
1942 FLOWLOCK_UNLOCK(&f);
1943
1944 /* do detect */
1945 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1946 if (PacketAlertCheck(p, 1)) {
1947 printf("sig 1 alerted: ");
1948 goto end;
1949 }
1950 p->alerts.cnt = 0;
1951
1952 FLOWLOCK_WRLOCK(&f);
1953 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1954 STREAM_TOSERVER, httpbuf2, httplen2);
1955 if (r != 0) {
1956 printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
1957 FLOWLOCK_UNLOCK(&f);
1958 goto end;
1959 }
1960 FLOWLOCK_UNLOCK(&f);
1961
1962 /* do detect */
1963 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1964 if (PacketAlertCheck(p, 1)) {
1965 printf("sig 1 alerted (2): ");
1966 FLOWLOCK_UNLOCK(&f);
1967 goto end;
1968 }
1969 p->alerts.cnt = 0;
1970
1971 FLOWLOCK_WRLOCK(&f);
1972 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1973 STREAM_TOSERVER, httpbuf3, httplen3);
1974 if (r != 0) {
1975 printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
1976 FLOWLOCK_UNLOCK(&f);
1977 goto end;
1978 }
1979 FLOWLOCK_UNLOCK(&f);
1980
1981 /* do detect */
1982 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1983 if (PacketAlertCheck(p, 1)) {
1984 printf("signature matched, but shouldn't have: ");
1985 goto end;
1986 }
1987 p->alerts.cnt = 0;
1988
1989 FLOWLOCK_WRLOCK(&f);
1990 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1991 STREAM_TOSERVER, httpbuf4, httplen4);
1992 if (r != 0) {
1993 printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
1994 result = 0;
1995 FLOWLOCK_UNLOCK(&f);
1996 goto end;
1997 }
1998 FLOWLOCK_UNLOCK(&f);
1999
2000 /* do detect */
2001 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2002 if (!(PacketAlertCheck(p, 1))) {
2003 printf("sig 1 didn't alert: ");
2004 goto end;
2005 }
2006 p->alerts.cnt = 0;
2007
2008 FLOWLOCK_WRLOCK(&f);
2009 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2010 STREAM_TOSERVER, httpbuf5, httplen5);
2011 if (r != 0) {
2012 printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2013 FLOWLOCK_UNLOCK(&f);
2014 goto end;
2015 }
2016 FLOWLOCK_UNLOCK(&f);
2017
2018 /* do detect */
2019 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2020 if (PacketAlertCheck(p, 1)) {
2021 printf("sig 1 alerted (5): ");
2022 goto end;
2023 }
2024 p->alerts.cnt = 0;
2025
2026 FLOWLOCK_WRLOCK(&f);
2027 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2028 STREAM_TOSERVER, httpbuf6, httplen6);
2029 if (r != 0) {
2030 printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2031 FLOWLOCK_UNLOCK(&f);
2032 goto end;
2033 }
2034 FLOWLOCK_UNLOCK(&f);
2035
2036 /* do detect */
2037 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2038 if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2039 printf("sig 1 alerted (request 2, chunk 6): ");
2040 goto end;
2041 }
2042 p->alerts.cnt = 0;
2043
2044 SCLogDebug("sending data chunk 7");
2045
2046 FLOWLOCK_WRLOCK(&f);
2047 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2048 STREAM_TOSERVER, httpbuf7, httplen7);
2049 if (r != 0) {
2050 printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2051 FLOWLOCK_UNLOCK(&f);
2052 goto end;
2053 }
2054 FLOWLOCK_UNLOCK(&f);
2055
2056 /* do detect */
2057 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2058 if (!(PacketAlertCheck(p, 2))) {
2059 printf("signature 2 didn't match, but should have: ");
2060 goto end;
2061 }
2062 p->alerts.cnt = 0;
2063
2064 HtpState *htp_state = f.alstate;
2065 if (htp_state == NULL) {
2066 printf("no http state: ");
2067 result = 0;
2068 goto end;
2069 }
2070
2071 if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2072 printf("The http app layer doesn't have 2 transactions, but it should: ");
2073 goto end;
2074 }
2075
2076 result = 1;
2077 end:
2078 if (alp_tctx != NULL)
2079 AppLayerParserThreadCtxFree(alp_tctx);
2080 if (det_ctx != NULL) {
2081 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2082 }
2083 if (de_ctx != NULL) {
2084 DetectEngineCtxFree(de_ctx);
2085 }
2086
2087 StreamTcpFreeConfig(TRUE);
2088 FLOW_DESTROY(&f);
2089 UTHFreePacket(p);
2090 return result;
2091 }
2092
2093 /** \test multiple http transactions and body chunks of request handling */
DetectHttpClientBodyTest15(void)2094 static int DetectHttpClientBodyTest15(void)
2095 {
2096 int result = 0;
2097 Signature *s = NULL;
2098 DetectEngineThreadCtx *det_ctx = NULL;
2099 ThreadVars th_v;
2100 Flow f;
2101 TcpSession ssn;
2102 Packet *p = NULL;
2103 uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
2104 uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2105 uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
2106 uint8_t httpbuf4[] = "Body one!!";
2107 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2108 uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2109 uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2110 uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2111 uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
2112 uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
2113 uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2114 uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2115 uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2116 uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
2117 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2118
2119 memset(&th_v, 0, sizeof(th_v));
2120 memset(&f, 0, sizeof(f));
2121 memset(&ssn, 0, sizeof(ssn));
2122
2123 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2124
2125 FLOW_INITIALIZE(&f);
2126 f.protoctx = (void *)&ssn;
2127 f.proto = IPPROTO_TCP;
2128 f.flags |= FLOW_IPV4;
2129
2130 p->flow = &f;
2131 p->flowflags |= FLOW_PKT_TOSERVER;
2132 p->flowflags |= FLOW_PKT_ESTABLISHED;
2133 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2134 f.alproto = ALPROTO_HTTP;
2135
2136 StreamTcpInitConfig(TRUE);
2137
2138 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2139 if (de_ctx == NULL) {
2140 goto end;
2141 }
2142
2143 de_ctx->flags |= DE_QUIET;
2144
2145 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)");
2146 if (s == NULL) {
2147 printf("sig parse failed: ");
2148 goto end;
2149 }
2150 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)");
2151 if (s == NULL) {
2152 printf("sig2 parse failed: ");
2153 goto end;
2154 }
2155
2156 SigGroupBuild(de_ctx);
2157 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2158
2159 FLOWLOCK_WRLOCK(&f);
2160 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2161 STREAM_TOSERVER, httpbuf1, httplen1);
2162 if (r != 0) {
2163 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2164 FLOWLOCK_UNLOCK(&f);
2165 goto end;
2166 }
2167 FLOWLOCK_UNLOCK(&f);
2168
2169 /* do detect */
2170 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2171 if (PacketAlertCheck(p, 1)) {
2172 printf("sig 1 alerted: ");
2173 goto end;
2174 }
2175 p->alerts.cnt = 0;
2176
2177 FLOWLOCK_WRLOCK(&f);
2178 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2179 STREAM_TOSERVER, httpbuf2, httplen2);
2180 if (r != 0) {
2181 printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
2182 FLOWLOCK_UNLOCK(&f);
2183 goto end;
2184 }
2185 FLOWLOCK_UNLOCK(&f);
2186
2187 /* do detect */
2188 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2189 if (PacketAlertCheck(p, 1)) {
2190 printf("sig 1 alerted (2): ");
2191 goto end;
2192 }
2193 p->alerts.cnt = 0;
2194
2195 FLOWLOCK_WRLOCK(&f);
2196 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2197 STREAM_TOSERVER, httpbuf3, httplen3);
2198 if (r != 0) {
2199 printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
2200 FLOWLOCK_UNLOCK(&f);
2201 goto end;
2202 }
2203 FLOWLOCK_UNLOCK(&f);
2204
2205 /* do detect */
2206 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2207 if (PacketAlertCheck(p, 1)) {
2208 printf("signature matched, but shouldn't have: ");
2209 goto end;
2210 }
2211 p->alerts.cnt = 0;
2212
2213 FLOWLOCK_WRLOCK(&f);
2214 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2215 STREAM_TOSERVER, httpbuf4, httplen4);
2216 if (r != 0) {
2217 printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
2218 result = 0;
2219 FLOWLOCK_UNLOCK(&f);
2220 goto end;
2221 }
2222 FLOWLOCK_UNLOCK(&f);
2223
2224 /* do detect */
2225 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2226 if (!(PacketAlertCheck(p, 1))) {
2227 printf("sig 1 didn't alert: ");
2228 goto end;
2229 }
2230 p->alerts.cnt = 0;
2231
2232 FLOWLOCK_WRLOCK(&f);
2233 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2234 STREAM_TOSERVER, httpbuf5, httplen5);
2235 if (r != 0) {
2236 printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2237 FLOWLOCK_UNLOCK(&f);
2238 goto end;
2239 }
2240 FLOWLOCK_UNLOCK(&f);
2241
2242 /* do detect */
2243 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2244 if (PacketAlertCheck(p, 1)) {
2245 printf("sig 1 alerted (5): ");
2246 goto end;
2247 }
2248 p->alerts.cnt = 0;
2249
2250 FLOWLOCK_WRLOCK(&f);
2251 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2252 STREAM_TOSERVER, httpbuf6, httplen6);
2253 if (r != 0) {
2254 printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2255 FLOWLOCK_UNLOCK(&f);
2256 goto end;
2257 }
2258 FLOWLOCK_UNLOCK(&f);
2259
2260 /* do detect */
2261 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2262 if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2263 printf("sig 1 alerted (request 2, chunk 6): ");
2264 goto end;
2265 }
2266 p->alerts.cnt = 0;
2267
2268 SCLogDebug("sending data chunk 7");
2269
2270 FLOWLOCK_WRLOCK(&f);
2271 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2272 STREAM_TOSERVER, httpbuf7, httplen7);
2273 if (r != 0) {
2274 printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2275 FLOWLOCK_UNLOCK(&f);
2276 goto end;
2277 }
2278 FLOWLOCK_UNLOCK(&f);
2279
2280 /* do detect */
2281 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2282 if (!(PacketAlertCheck(p, 2))) {
2283 printf("signature 2 didn't match, but should have: ");
2284 goto end;
2285 }
2286 p->alerts.cnt = 0;
2287
2288 HtpState *htp_state = f.alstate;
2289 if (htp_state == NULL) {
2290 printf("no http state: ");
2291 result = 0;
2292 goto end;
2293 }
2294
2295 /* hardcoded check of the transactions and it's client body chunks */
2296 if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2297 printf("The http app layer doesn't have 2 transactions, but it should: ");
2298 goto end;
2299 }
2300
2301 htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0);
2302 htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1);
2303
2304 HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2305
2306 HtpBodyChunk *cur = htud->request_body.first;
2307 if (htud->request_body.first == NULL) {
2308 SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2309 goto end;
2310 }
2311
2312 if (StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg,
2313 (uint8_t *)"Body one!!", 10) != 1)
2314 {
2315 SCLogDebug("Body data in t1 is not correctly set: ");
2316 goto end;
2317 }
2318
2319 htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2320
2321 cur = htud->request_body.first;
2322 if (htud->request_body.first == NULL) {
2323 SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2324 goto end;
2325 }
2326
2327 if (StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg,
2328 (uint8_t *)"Body two!!", 10) != 1)
2329 {
2330 SCLogDebug("Body data in t1 is not correctly set: ");
2331 goto end;
2332 }
2333
2334 result = 1;
2335 end:
2336 if (alp_tctx != NULL)
2337 AppLayerParserThreadCtxFree(alp_tctx);
2338 if (det_ctx != NULL) {
2339 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2340 }
2341 if (de_ctx != NULL) {
2342 DetectEngineCtxFree(de_ctx);
2343 }
2344
2345 StreamTcpFreeConfig(TRUE);
2346 FLOW_DESTROY(&f);
2347 UTHFreePacket(p);
2348 return result;
2349 }
2350
DetectHttpClientBodyTest22(void)2351 static int DetectHttpClientBodyTest22(void)
2352 {
2353 DetectEngineCtx *de_ctx = NULL;
2354 int result = 0;
2355
2356 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2357 goto end;
2358
2359 de_ctx->flags |= DE_QUIET;
2360 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2361 "(content:\"one\"; content:\"two\"; http_client_body; "
2362 "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2363 if (de_ctx->sig_list == NULL) {
2364 printf("de_ctx->sig_list == NULL\n");
2365 goto end;
2366 }
2367
2368 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2369 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2370 goto end;
2371 }
2372
2373 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2374 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2375 goto end;
2376 }
2377
2378 DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2379 DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2380 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2381 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2382 if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 ||
2383 cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2384 hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2385 memcmp(hcbd1->content, "two", hcbd1->content_len) != 0 ||
2386 hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2387 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2388 goto end;
2389 }
2390
2391 if (!DETECT_CONTENT_IS_SINGLE(cd1) ||
2392 !DETECT_CONTENT_IS_SINGLE(cd2) ||
2393 DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2394 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2395 goto end;
2396 }
2397
2398 result = 1;
2399
2400 end:
2401 DetectEngineCtxFree(de_ctx);
2402 return result;
2403 }
2404
DetectHttpClientBodyTest23(void)2405 static int DetectHttpClientBodyTest23(void)
2406 {
2407 DetectEngineCtx *de_ctx = NULL;
2408 int result = 0;
2409
2410 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2411 goto end;
2412
2413 de_ctx->flags |= DE_QUIET;
2414 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2415 "(content:\"one\"; http_client_body; pcre:/two/; "
2416 "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2417 if (de_ctx->sig_list == NULL) {
2418 printf("de_ctx->sig_list == NULL\n");
2419 goto end;
2420 }
2421
2422 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2423 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2424 goto end;
2425 }
2426
2427 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2428 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2429 goto end;
2430 }
2431
2432 DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2433 DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2434 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2435 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2436 if (pd1->flags != 0 ||
2437 cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2438 hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2439 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2440 hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2441 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2442 goto end;
2443 }
2444
2445 if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
2446 DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2447 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2448 goto end;
2449 }
2450
2451 result = 1;
2452
2453 end:
2454 DetectEngineCtxFree(de_ctx);
2455 return result;
2456 }
2457
DetectHttpClientBodyTest24(void)2458 static int DetectHttpClientBodyTest24(void)
2459 {
2460 DetectEngineCtx *de_ctx = NULL;
2461 int result = 0;
2462
2463 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2464 goto end;
2465
2466 de_ctx->flags |= DE_QUIET;
2467 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2468 "(content:\"one\"; http_client_body; pcre:/two/; "
2469 "content:\"three\"; distance:10; within:15; http_client_body; content:\"four\"; sid:1;)");
2470 if (de_ctx->sig_list == NULL) {
2471 printf("de_ctx->sig_list == NULL\n");
2472 goto end;
2473 }
2474
2475 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2476 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2477 goto end;
2478 }
2479
2480 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2481 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2482 goto end;
2483 }
2484
2485 DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2486 DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2487 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2488 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2489 if (pd1->flags != 0 ||
2490 cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2491 hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2492 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2493 hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
2494 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2495 goto end;
2496 }
2497
2498 if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
2499 DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2500 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2501 goto end;
2502 }
2503
2504 result = 1;
2505
2506 end:
2507 DetectEngineCtxFree(de_ctx);
2508 return result;
2509 }
2510
DetectHttpClientBodyTest25(void)2511 static int DetectHttpClientBodyTest25(void)
2512 {
2513 DetectEngineCtx *de_ctx = NULL;
2514 int result = 0;
2515
2516 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2517 goto end;
2518
2519 de_ctx->flags |= DE_QUIET;
2520 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2521 "(content:\"one\"; http_client_body; pcre:/two/; "
2522 "content:\"three\"; distance:10; http_client_body; "
2523 "content:\"four\"; distance:10; sid:1;)");
2524 if (de_ctx->sig_list == NULL) {
2525 printf("de_ctx->sig_list == NULL\n");
2526 goto end;
2527 }
2528
2529 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2530 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2531 goto end;
2532 }
2533
2534 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2535 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2536 goto end;
2537 }
2538
2539 DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2540 DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2541 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2542 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2543 if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT ||
2544 cd2->flags != DETECT_CONTENT_DISTANCE ||
2545 memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2546 hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2547 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2548 hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2549 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2550 goto end;
2551 }
2552
2553 if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2554 DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2555 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2556 goto end;
2557 }
2558
2559 result = 1;
2560
2561 end:
2562 DetectEngineCtxFree(de_ctx);
2563 return result;
2564 }
2565
DetectHttpClientBodyTest26(void)2566 static int DetectHttpClientBodyTest26(void)
2567 {
2568 DetectEngineCtx *de_ctx = NULL;
2569 int result = 0;
2570
2571 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2572 goto end;
2573
2574 de_ctx->flags |= DE_QUIET;
2575 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2576 "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2577 "content:\"three\"; distance:10; http_client_body; within:10; "
2578 "content:\"four\"; distance:10; sid:1;)");
2579 if (de_ctx->sig_list == NULL) {
2580 printf("de_ctx->sig_list == NULL\n");
2581 goto end;
2582 }
2583
2584 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2585 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2586 goto end;
2587 }
2588
2589 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2590 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2591 goto end;
2592 }
2593
2594 DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2595 DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2596 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2597 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2598 if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2599 cd2->flags != DETECT_CONTENT_DISTANCE ||
2600 memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2601 hcbd1->flags != (DETECT_CONTENT_RELATIVE_NEXT | DETECT_CONTENT_OFFSET) ||
2602 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2603 hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
2604 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2605 printf ("failed: http_client_body incorrect flags");
2606 goto end;
2607 }
2608
2609 if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2610 DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2611 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2612 goto end;
2613 }
2614
2615 result = 1;
2616
2617 end:
2618 DetectEngineCtxFree(de_ctx);
2619 return result;
2620 }
2621
DetectHttpClientBodyTest27(void)2622 static int DetectHttpClientBodyTest27(void)
2623 {
2624 DetectEngineCtx *de_ctx = NULL;
2625 int result = 0;
2626
2627 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2628 goto end;
2629
2630 de_ctx->flags |= DE_QUIET;
2631 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2632 "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2633 "content:\"three\"; distance:10; http_client_body; within:10; "
2634 "content:\"four\"; distance:10; sid:1;)");
2635 if (de_ctx->sig_list == NULL) {
2636 printf("de_ctx->sig_list == NULL\n");
2637 goto end;
2638 }
2639
2640 result = 1;
2641
2642 end:
2643 DetectEngineCtxFree(de_ctx);
2644 return result;
2645 }
2646
DetectHttpClientBodyTest28(void)2647 static int DetectHttpClientBodyTest28(void)
2648 {
2649 DetectEngineCtx *de_ctx = NULL;
2650 int result = 0;
2651
2652 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2653 goto end;
2654
2655 de_ctx->flags |= DE_QUIET;
2656 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2657 "(content:\"one\"; http_client_body; pcre:/two/; "
2658 "content:\"three\"; http_client_body; depth:10; "
2659 "content:\"four\"; distance:10; sid:1;)");
2660 if (de_ctx->sig_list == NULL) {
2661 printf("de_ctx->sig_list == NULL\n");
2662 goto end;
2663 }
2664
2665 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2666 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2667 goto end;
2668 }
2669
2670 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2671 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2672 goto end;
2673 }
2674
2675 DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2676 DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2677 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2678 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2679 if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2680 cd2->flags != DETECT_CONTENT_DISTANCE ||
2681 memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2682 hcbd1->flags != 0 ||
2683 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2684 hcbd2->flags != DETECT_CONTENT_DEPTH ||
2685 memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2686 goto end;
2687 }
2688
2689 if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2690 !DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2691 DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2692 goto end;
2693 }
2694
2695 result = 1;
2696
2697 end:
2698 DetectEngineCtxFree(de_ctx);
2699 return result;
2700 }
2701
DetectHttpClientBodyTest29(void)2702 static int DetectHttpClientBodyTest29(void)
2703 {
2704 DetectEngineCtx *de_ctx = NULL;
2705 int result = 0;
2706
2707 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2708 goto end;
2709
2710 de_ctx->flags |= DE_QUIET;
2711 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2712 "(content:\"one\"; http_client_body; "
2713 "content:\"two\"; distance:0; http_client_body; sid:1;)");
2714 if (de_ctx->sig_list == NULL) {
2715 printf("de_ctx->sig_list == NULL\n");
2716 goto end;
2717 }
2718
2719 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2720 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2721 goto end;
2722 }
2723
2724 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2725 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2726 goto end;
2727 }
2728
2729 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2730 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2731 if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2732 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2733 hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2734 memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2735 goto end;
2736 }
2737
2738 result = 1;
2739
2740 end:
2741 DetectEngineCtxFree(de_ctx);
2742 return result;
2743 }
2744
DetectHttpClientBodyTest30(void)2745 static int DetectHttpClientBodyTest30(void)
2746 {
2747 DetectEngineCtx *de_ctx = NULL;
2748 int result = 0;
2749
2750 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2751 goto end;
2752
2753 de_ctx->flags |= DE_QUIET;
2754 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2755 "(content:\"one\"; http_client_body; "
2756 "content:\"two\"; within:5; http_client_body; sid:1;)");
2757 if (de_ctx->sig_list == NULL) {
2758 printf("de_ctx->sig_list == NULL\n");
2759 goto end;
2760 }
2761
2762 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2763 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2764 goto end;
2765 }
2766
2767 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2768 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2769 goto end;
2770 }
2771
2772 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2773 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2774 if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2775 memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2776 hcbd2->flags != DETECT_CONTENT_WITHIN ||
2777 memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2778 goto end;
2779 }
2780
2781 result = 1;
2782
2783 end:
2784 DetectEngineCtxFree(de_ctx);
2785 return result;
2786 }
2787
DetectHttpClientBodyTest31(void)2788 static int DetectHttpClientBodyTest31(void)
2789 {
2790 DetectEngineCtx *de_ctx = NULL;
2791 int result = 0;
2792
2793 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2794 goto end;
2795
2796 de_ctx->flags |= DE_QUIET;
2797 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2798 "(content:\"one\"; within:5; http_client_body; sid:1;)");
2799 if (de_ctx->sig_list == NULL) {
2800 printf("de_ctx->sig_list == NULL\n");
2801 goto end;
2802 }
2803
2804 result = 1;
2805
2806 end:
2807 DetectEngineCtxFree(de_ctx);
2808 return result;
2809 }
2810
DetectHttpClientBodyTest32(void)2811 static int DetectHttpClientBodyTest32(void)
2812 {
2813 DetectEngineCtx *de_ctx = NULL;
2814 int result = 0;
2815
2816 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2817 goto end;
2818
2819 de_ctx->flags |= DE_QUIET;
2820 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2821 "(content:\"one\"; http_client_body; within:5; sid:1;)");
2822 if (de_ctx->sig_list == NULL) {
2823 printf("de_ctx->sig_list != NULL\n");
2824 goto end;
2825 }
2826
2827 result = 1;
2828
2829 end:
2830 DetectEngineCtxFree(de_ctx);
2831 return result;
2832 }
2833
DetectHttpClientBodyTest33(void)2834 static int DetectHttpClientBodyTest33(void)
2835 {
2836 DetectEngineCtx *de_ctx = NULL;
2837 int result = 0;
2838
2839 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2840 goto end;
2841
2842 de_ctx->flags |= DE_QUIET;
2843 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2844 "(content:\"one\"; within:5; sid:1;)");
2845 if (de_ctx->sig_list == NULL) {
2846 printf("de_ctx->sig_list == NULL\n");
2847 goto end;
2848 }
2849
2850 result = 1;
2851
2852 end:
2853 DetectEngineCtxFree(de_ctx);
2854 return result;
2855 }
2856
DetectHttpClientBodyTest34(void)2857 static int DetectHttpClientBodyTest34(void)
2858 {
2859 DetectEngineCtx *de_ctx = NULL;
2860 int result = 0;
2861
2862 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2863 goto end;
2864
2865 de_ctx->flags |= DE_QUIET;
2866 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2867 "(pcre:/one/P; "
2868 "content:\"two\"; within:5; http_client_body; sid:1;)");
2869 if (de_ctx->sig_list == NULL) {
2870 printf("de_ctx->sig_list == NULL\n");
2871 goto end;
2872 }
2873
2874 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2875 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2876 goto end;
2877 }
2878
2879 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2880 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2881 goto end;
2882 }
2883
2884 if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2885 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_CONTENT ||
2886 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2887 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_PCRE) {
2888
2889 goto end;
2890 }
2891
2892 DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2893 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2894 if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2895 hcbd2->flags != DETECT_CONTENT_WITHIN ||
2896 memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2897 goto end;
2898 }
2899
2900 result = 1;
2901
2902 end:
2903 DetectEngineCtxFree(de_ctx);
2904 return result;
2905 }
2906
DetectHttpClientBodyTest35(void)2907 static int DetectHttpClientBodyTest35(void)
2908 {
2909 DetectEngineCtx *de_ctx = NULL;
2910 int result = 0;
2911
2912 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2913 goto end;
2914
2915 de_ctx->flags |= DE_QUIET;
2916 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2917 "(content:\"two\"; http_client_body; "
2918 "pcre:/one/PR; sid:1;)");
2919 if (de_ctx->sig_list == NULL) {
2920 printf("de_ctx->sig_list == NULL\n");
2921 goto end;
2922 }
2923
2924 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2925 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2926 goto end;
2927 }
2928
2929 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2930 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2931 goto end;
2932 }
2933
2934 if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2935 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_PCRE ||
2936 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2937 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_CONTENT) {
2938
2939 goto end;
2940 }
2941
2942 DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2943 DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2944 if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
2945 hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2946 memcmp(hcbd1->content, "two", hcbd1->content_len) != 0) {
2947 goto end;
2948 }
2949
2950 result = 1;
2951
2952 end:
2953 DetectEngineCtxFree(de_ctx);
2954 return result;
2955 }
2956
DetectHttpClientBodyTest36(void)2957 static int DetectHttpClientBodyTest36(void)
2958 {
2959 DetectEngineCtx *de_ctx = NULL;
2960 int result = 0;
2961
2962 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2963 goto end;
2964
2965 de_ctx->flags |= DE_QUIET;
2966 de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2967 "(pcre:/one/P; "
2968 "content:\"two\"; distance:5; http_client_body; sid:1;)");
2969 if (de_ctx->sig_list == NULL) {
2970 printf("de_ctx->sig_list == NULL\n");
2971 goto end;
2972 }
2973
2974 if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2975 printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2976 goto end;
2977 }
2978
2979 if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2980 printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2981 goto end;
2982 }
2983
2984 if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2985 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_CONTENT ||
2986 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2987 de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_PCRE) {
2988
2989 goto end;
2990 }
2991
2992 DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2993 DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2994 if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2995 hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2996 memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2997 goto end;
2998 }
2999
3000 result = 1;
3001
3002 end:
3003 DetectEngineCtxFree(de_ctx);
3004 return result;
3005 }
3006
DetectHttpClientBodyIsdataatParseTest(void)3007 static int DetectHttpClientBodyIsdataatParseTest(void)
3008 {
3009 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3010 FAIL_IF_NULL(de_ctx);
3011 de_ctx->flags |= DE_QUIET;
3012
3013 Signature *s = DetectEngineAppendSig(de_ctx,
3014 "alert tcp any any -> any any ("
3015 "content:\"one\"; http_client_body; "
3016 "isdataat:!4,relative; sid:1;)");
3017 FAIL_IF_NULL(s);
3018
3019 SigMatch *sm = s->init_data->smlists_tail[g_http_client_body_buffer_id];
3020 FAIL_IF_NULL(sm);
3021 FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
3022
3023 DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
3024 FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
3025 FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
3026 FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
3027
3028 DetectEngineCtxFree(de_ctx);
3029 PASS;
3030 }
3031
DetectHttpClientBodyRegisterTests(void)3032 void DetectHttpClientBodyRegisterTests(void)
3033 {
3034 UtRegisterTest("DetectHttpClientBodyParserTest01", DetectHttpClientBodyParserTest01);
3035 UtRegisterTest("DetectHttpClientBodyParserTest02", DetectHttpClientBodyParserTest02);
3036 UtRegisterTest("DetectHttpClientBodyTest01", DetectHttpClientBodyTest01);
3037 UtRegisterTest("DetectHttpClientBodyTest02", DetectHttpClientBodyTest02);
3038 UtRegisterTest("DetectHttpClientBodyTest03", DetectHttpClientBodyTest03);
3039 UtRegisterTest("DetectHttpClientBodyTest04", DetectHttpClientBodyTest04);
3040 UtRegisterTest("DetectHttpClientBodyTest05", DetectHttpClientBodyTest05);
3041 UtRegisterTest("DetectHttpClientBodyTest06", DetectHttpClientBodyTest06);
3042 UtRegisterTest("DetectHttpClientBodyTest07", DetectHttpClientBodyTest07);
3043 UtRegisterTest("DetectHttpClientBodyTest08", DetectHttpClientBodyTest08);
3044 UtRegisterTest("DetectHttpClientBodyTest09", DetectHttpClientBodyTest09);
3045 UtRegisterTest("DetectHttpClientBodyTest10", DetectHttpClientBodyTest10);
3046 UtRegisterTest("DetectHttpClientBodyTest11", DetectHttpClientBodyTest11);
3047 UtRegisterTest("DetectHttpClientBodyTest12", DetectHttpClientBodyTest12);
3048 UtRegisterTest("DetectHttpClientBodyTest13", DetectHttpClientBodyTest13);
3049 UtRegisterTest("DetectHttpClientBodyTest14", DetectHttpClientBodyTest14);
3050 UtRegisterTest("DetectHttpClientBodyTest15", DetectHttpClientBodyTest15);
3051
3052 UtRegisterTest("DetectHttpClientBodyTest22", DetectHttpClientBodyTest22);
3053 UtRegisterTest("DetectHttpClientBodyTest23", DetectHttpClientBodyTest23);
3054 UtRegisterTest("DetectHttpClientBodyTest24", DetectHttpClientBodyTest24);
3055 UtRegisterTest("DetectHttpClientBodyTest25", DetectHttpClientBodyTest25);
3056 UtRegisterTest("DetectHttpClientBodyTest26", DetectHttpClientBodyTest26);
3057 UtRegisterTest("DetectHttpClientBodyTest27", DetectHttpClientBodyTest27);
3058 UtRegisterTest("DetectHttpClientBodyTest28", DetectHttpClientBodyTest28);
3059 UtRegisterTest("DetectHttpClientBodyTest29", DetectHttpClientBodyTest29);
3060 UtRegisterTest("DetectHttpClientBodyTest30", DetectHttpClientBodyTest30);
3061 UtRegisterTest("DetectHttpClientBodyTest31", DetectHttpClientBodyTest31);
3062 UtRegisterTest("DetectHttpClientBodyTest32", DetectHttpClientBodyTest32);
3063 UtRegisterTest("DetectHttpClientBodyTest33", DetectHttpClientBodyTest33);
3064 UtRegisterTest("DetectHttpClientBodyTest34", DetectHttpClientBodyTest34);
3065 UtRegisterTest("DetectHttpClientBodyTest35", DetectHttpClientBodyTest35);
3066 UtRegisterTest("DetectHttpClientBodyTest36", DetectHttpClientBodyTest36);
3067
3068 UtRegisterTest("DetectHttpClientBodyIsdataatParseTest",
3069 DetectHttpClientBodyIsdataatParseTest);
3070
3071 UtRegisterTest("DetectEngineHttpClientBodyTest01",
3072 DetectEngineHttpClientBodyTest01);
3073 UtRegisterTest("DetectEngineHttpClientBodyTest02",
3074 DetectEngineHttpClientBodyTest02);
3075 UtRegisterTest("DetectEngineHttpClientBodyTest03",
3076 DetectEngineHttpClientBodyTest03);
3077 UtRegisterTest("DetectEngineHttpClientBodyTest04",
3078 DetectEngineHttpClientBodyTest04);
3079 UtRegisterTest("DetectEngineHttpClientBodyTest05",
3080 DetectEngineHttpClientBodyTest05);
3081 UtRegisterTest("DetectEngineHttpClientBodyTest06",
3082 DetectEngineHttpClientBodyTest06);
3083 UtRegisterTest("DetectEngineHttpClientBodyTest07",
3084 DetectEngineHttpClientBodyTest07);
3085 UtRegisterTest("DetectEngineHttpClientBodyTest08",
3086 DetectEngineHttpClientBodyTest08);
3087 UtRegisterTest("DetectEngineHttpClientBodyTest09",
3088 DetectEngineHttpClientBodyTest09);
3089 UtRegisterTest("DetectEngineHttpClientBodyTest10",
3090 DetectEngineHttpClientBodyTest10);
3091 UtRegisterTest("DetectEngineHttpClientBodyTest11",
3092 DetectEngineHttpClientBodyTest11);
3093 UtRegisterTest("DetectEngineHttpClientBodyTest12",
3094 DetectEngineHttpClientBodyTest12);
3095 UtRegisterTest("DetectEngineHttpClientBodyTest13",
3096 DetectEngineHttpClientBodyTest13);
3097 UtRegisterTest("DetectEngineHttpClientBodyTest14",
3098 DetectEngineHttpClientBodyTest14);
3099 UtRegisterTest("DetectEngineHttpClientBodyTest15",
3100 DetectEngineHttpClientBodyTest15);
3101 UtRegisterTest("DetectEngineHttpClientBodyTest16",
3102 DetectEngineHttpClientBodyTest16);
3103 UtRegisterTest("DetectEngineHttpClientBodyTest17",
3104 DetectEngineHttpClientBodyTest17);
3105 UtRegisterTest("DetectEngineHttpClientBodyTest18",
3106 DetectEngineHttpClientBodyTest18);
3107 UtRegisterTest("DetectEngineHttpClientBodyTest19",
3108 DetectEngineHttpClientBodyTest19);
3109 UtRegisterTest("DetectEngineHttpClientBodyTest20",
3110 DetectEngineHttpClientBodyTest20);
3111 UtRegisterTest("DetectEngineHttpClientBodyTest21",
3112 DetectEngineHttpClientBodyTest21);
3113 UtRegisterTest("DetectEngineHttpClientBodyTest22",
3114 DetectEngineHttpClientBodyTest22);
3115 UtRegisterTest("DetectEngineHttpClientBodyTest23",
3116 DetectEngineHttpClientBodyTest23);
3117 UtRegisterTest("DetectEngineHttpClientBodyTest24",
3118 DetectEngineHttpClientBodyTest24);
3119 UtRegisterTest("DetectEngineHttpClientBodyTest25",
3120 DetectEngineHttpClientBodyTest25);
3121 UtRegisterTest("DetectEngineHttpClientBodyTest26",
3122 DetectEngineHttpClientBodyTest26);
3123 UtRegisterTest("DetectEngineHttpClientBodyTest27",
3124 DetectEngineHttpClientBodyTest27);
3125 UtRegisterTest("DetectEngineHttpClientBodyTest28",
3126 DetectEngineHttpClientBodyTest28);
3127 UtRegisterTest("DetectEngineHttpClientBodyTest29",
3128 DetectEngineHttpClientBodyTest29);
3129
3130 UtRegisterTest("DetectEngineHttpClientBodyTest30",
3131 DetectEngineHttpClientBodyTest30);
3132 UtRegisterTest("DetectEngineHttpClientBodyTest31",
3133 DetectEngineHttpClientBodyTest31);
3134 }
3135
3136 #endif
3137
3138 /**
3139 * @}
3140 */
3141