1 /* Copyright (C) 2007-2010 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18 /**
19 * \ingroup httplayer
20 *
21 * @{
22 */
23
24
25 /** \file
26 *
27 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
28 *
29 * \brief Handle HTTP method match
30 *
31 */
32
33 #include "../suricata-common.h"
34 #include "../suricata.h"
35 #include "../flow-util.h"
36 #include "../flow.h"
37 #include "../app-layer-parser.h"
38
39 #include "../util-unittest.h"
40 #include "../util-unittest-helper.h"
41 #include "../app-layer.h"
42 #include "../app-layer-htp.h"
43 #include "../app-layer-protos.h"
44 #include "../detect-isdataat.h"
45
46 /**
47 * \test Test that the http_method content matches against a http request
48 * which holds the content.
49 */
DetectEngineHttpMethodTest01(void)50 static int DetectEngineHttpMethodTest01(void)
51 {
52 TcpSession ssn;
53 Packet *p = NULL;
54 ThreadVars th_v;
55 DetectEngineCtx *de_ctx = NULL;
56 DetectEngineThreadCtx *det_ctx = NULL;
57 HtpState *http_state = NULL;
58 Flow f;
59 uint8_t http_buf[] =
60 "GET /index.html HTTP/1.0\r\n"
61 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
62 uint32_t http_len = sizeof(http_buf) - 1;
63 int result = 0;
64 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
65
66 memset(&th_v, 0, sizeof(th_v));
67 memset(&f, 0, sizeof(f));
68 memset(&ssn, 0, sizeof(ssn));
69
70 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
71
72 FLOW_INITIALIZE(&f);
73 f.protoctx = (void *)&ssn;
74 f.proto = IPPROTO_TCP;
75 f.flags |= FLOW_IPV4;
76 p->flow = &f;
77 p->flowflags |= FLOW_PKT_TOSERVER;
78 p->flowflags |= FLOW_PKT_ESTABLISHED;
79 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
80 f.alproto = ALPROTO_HTTP;
81
82 StreamTcpInitConfig(TRUE);
83
84 de_ctx = DetectEngineCtxInit();
85 if (de_ctx == NULL)
86 goto end;
87
88 de_ctx->flags |= DE_QUIET;
89
90 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
91 "(msg:\"http header test\"; "
92 "content:\"GET\"; http_method; "
93 "sid:1;)");
94 if (de_ctx->sig_list == NULL)
95 goto end;
96
97 SigGroupBuild(de_ctx);
98 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
99
100 FLOWLOCK_WRLOCK(&f);
101 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
102 STREAM_TOSERVER, http_buf, http_len);
103 if (r != 0) {
104 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
105 result = 0;
106 FLOWLOCK_UNLOCK(&f);
107 goto end;
108 }
109 FLOWLOCK_UNLOCK(&f);
110
111 http_state = f.alstate;
112 if (http_state == NULL) {
113 printf("no http state: ");
114 result = 0;
115 goto end;
116 }
117
118 /* do detect */
119 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
120
121 if (!(PacketAlertCheck(p, 1))) {
122 printf("sid 1 didn't match but should have: ");
123 goto end;
124 }
125
126 result = 1;
127
128 end:
129 if (alp_tctx != NULL)
130 AppLayerParserThreadCtxFree(alp_tctx);
131 if (de_ctx != NULL)
132 DetectEngineCtxFree(de_ctx);
133
134 StreamTcpFreeConfig(TRUE);
135 FLOW_DESTROY(&f);
136 UTHFreePackets(&p, 1);
137 return result;
138 }
139
140 /**
141 * \test Test that the http_method content matches against a http request
142 * which holds the content.
143 */
DetectEngineHttpMethodTest02(void)144 static int DetectEngineHttpMethodTest02(void)
145 {
146 TcpSession ssn;
147 Packet *p = NULL;
148 ThreadVars th_v;
149 DetectEngineCtx *de_ctx = NULL;
150 DetectEngineThreadCtx *det_ctx = NULL;
151 HtpState *http_state = NULL;
152 Flow f;
153 uint8_t http_buf[] =
154 "CONNECT /index.html HTTP/1.0\r\n"
155 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
156 uint32_t http_len = sizeof(http_buf) - 1;
157 int result = 0;
158 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
159
160 memset(&th_v, 0, sizeof(th_v));
161 memset(&f, 0, sizeof(f));
162 memset(&ssn, 0, sizeof(ssn));
163
164 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
165
166 FLOW_INITIALIZE(&f);
167 f.protoctx = (void *)&ssn;
168 f.proto = IPPROTO_TCP;
169 f.flags |= FLOW_IPV4;
170 p->flow = &f;
171 p->flowflags |= FLOW_PKT_TOSERVER;
172 p->flowflags |= FLOW_PKT_ESTABLISHED;
173 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
174 f.alproto = ALPROTO_HTTP;
175
176 StreamTcpInitConfig(TRUE);
177
178 de_ctx = DetectEngineCtxInit();
179 if (de_ctx == NULL)
180 goto end;
181
182 de_ctx->flags |= DE_QUIET;
183
184 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
185 "(msg:\"http header test\"; "
186 "content:\"CO\"; depth:4; http_method; "
187 "sid:1;)");
188 if (de_ctx->sig_list == NULL)
189 goto end;
190
191 SigGroupBuild(de_ctx);
192 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
193
194 FLOWLOCK_WRLOCK(&f);
195 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
196 STREAM_TOSERVER, http_buf, http_len);
197 if (r != 0) {
198 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
199 result = 0;
200 FLOWLOCK_UNLOCK(&f);
201 goto end;
202 }
203 FLOWLOCK_UNLOCK(&f);
204
205 http_state = f.alstate;
206 if (http_state == NULL) {
207 printf("no http state: ");
208 result = 0;
209 goto end;
210 }
211
212 /* do detect */
213 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
214
215 if (!(PacketAlertCheck(p, 1))) {
216 printf("sid 1 didn't match but should have: ");
217 goto end;
218 }
219
220 result = 1;
221
222 end:
223 if (alp_tctx != NULL)
224 AppLayerParserThreadCtxFree(alp_tctx);
225 if (de_ctx != NULL)
226 DetectEngineCtxFree(de_ctx);
227
228 StreamTcpFreeConfig(TRUE);
229 FLOW_DESTROY(&f);
230 UTHFreePackets(&p, 1);
231 return result;
232 }
233
234 /**
235 * \test Test that the http_method content matches against a http request
236 * which holds the content.
237 */
DetectEngineHttpMethodTest03(void)238 static int DetectEngineHttpMethodTest03(void)
239 {
240 TcpSession ssn;
241 Packet *p = NULL;
242 ThreadVars th_v;
243 DetectEngineCtx *de_ctx = NULL;
244 DetectEngineThreadCtx *det_ctx = NULL;
245 HtpState *http_state = NULL;
246 Flow f;
247 uint8_t http_buf[] =
248 "CONNECT /index.html HTTP/1.0\r\n"
249 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
250 uint32_t http_len = sizeof(http_buf) - 1;
251 int result = 0;
252 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
253
254 memset(&th_v, 0, sizeof(th_v));
255 memset(&f, 0, sizeof(f));
256 memset(&ssn, 0, sizeof(ssn));
257
258 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
259
260 FLOW_INITIALIZE(&f);
261 f.protoctx = (void *)&ssn;
262 f.proto = IPPROTO_TCP;
263 f.flags |= FLOW_IPV4;
264 p->flow = &f;
265 p->flowflags |= FLOW_PKT_TOSERVER;
266 p->flowflags |= FLOW_PKT_ESTABLISHED;
267 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
268 f.alproto = ALPROTO_HTTP;
269
270 StreamTcpInitConfig(TRUE);
271
272 de_ctx = DetectEngineCtxInit();
273 if (de_ctx == NULL)
274 goto end;
275
276 de_ctx->flags |= DE_QUIET;
277
278 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
279 "(msg:\"http header test\"; "
280 "content:!\"ECT\"; depth:4; http_method; "
281 "sid:1;)");
282 if (de_ctx->sig_list == NULL)
283 goto end;
284
285 SigGroupBuild(de_ctx);
286 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
287
288 FLOWLOCK_WRLOCK(&f);
289 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
290 STREAM_TOSERVER, http_buf, http_len);
291 if (r != 0) {
292 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
293 result = 0;
294 FLOWLOCK_UNLOCK(&f);
295 goto end;
296 }
297 FLOWLOCK_UNLOCK(&f);
298
299 http_state = f.alstate;
300 if (http_state == NULL) {
301 printf("no http state: ");
302 result = 0;
303 goto end;
304 }
305
306 /* do detect */
307 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
308
309 if (!(PacketAlertCheck(p, 1))) {
310 printf("sid 1 didn't match but should have: ");
311 goto end;
312 }
313
314 result = 1;
315
316 end:
317 if (alp_tctx != NULL)
318 AppLayerParserThreadCtxFree(alp_tctx);
319 if (de_ctx != NULL)
320 DetectEngineCtxFree(de_ctx);
321
322 StreamTcpFreeConfig(TRUE);
323 FLOW_DESTROY(&f);
324 UTHFreePackets(&p, 1);
325 return result;
326 }
327
328 /**
329 * \test Test that the http_method content matches against a http request
330 * which holds the content.
331 */
DetectEngineHttpMethodTest04(void)332 static int DetectEngineHttpMethodTest04(void)
333 {
334 TcpSession ssn;
335 Packet *p = NULL;
336 ThreadVars th_v;
337 DetectEngineCtx *de_ctx = NULL;
338 DetectEngineThreadCtx *det_ctx = NULL;
339 HtpState *http_state = NULL;
340 Flow f;
341 uint8_t http_buf[] =
342 "CONNECT /index.html HTTP/1.0\r\n"
343 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
344 uint32_t http_len = sizeof(http_buf) - 1;
345 int result = 0;
346 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
347
348 memset(&th_v, 0, sizeof(th_v));
349 memset(&f, 0, sizeof(f));
350 memset(&ssn, 0, sizeof(ssn));
351
352 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
353
354 FLOW_INITIALIZE(&f);
355 f.protoctx = (void *)&ssn;
356 f.proto = IPPROTO_TCP;
357 f.flags |= FLOW_IPV4;
358 p->flow = &f;
359 p->flowflags |= FLOW_PKT_TOSERVER;
360 p->flowflags |= FLOW_PKT_ESTABLISHED;
361 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
362 f.alproto = ALPROTO_HTTP;
363
364 StreamTcpInitConfig(TRUE);
365
366 de_ctx = DetectEngineCtxInit();
367 if (de_ctx == NULL)
368 goto end;
369
370 de_ctx->flags |= DE_QUIET;
371
372 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
373 "(msg:\"http header test\"; "
374 "content:\"ECT\"; depth:4; http_method; "
375 "sid:1;)");
376 if (de_ctx->sig_list == NULL)
377 goto end;
378
379 SigGroupBuild(de_ctx);
380 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
381
382 FLOWLOCK_WRLOCK(&f);
383 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
384 STREAM_TOSERVER, http_buf, http_len);
385 if (r != 0) {
386 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
387 result = 0;
388 FLOWLOCK_UNLOCK(&f);
389 goto end;
390 }
391 FLOWLOCK_UNLOCK(&f);
392
393 http_state = f.alstate;
394 if (http_state == NULL) {
395 printf("no http state: ");
396 result = 0;
397 goto end;
398 }
399
400 /* do detect */
401 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
402
403 if (PacketAlertCheck(p, 1)) {
404 printf("sid 1 matched but shouldn't have: ");
405 goto end;
406 }
407
408 result = 1;
409
410 end:
411 if (alp_tctx != NULL)
412 AppLayerParserThreadCtxFree(alp_tctx);
413 if (de_ctx != NULL)
414 DetectEngineCtxFree(de_ctx);
415
416 StreamTcpFreeConfig(TRUE);
417 FLOW_DESTROY(&f);
418 UTHFreePackets(&p, 1);
419 return result;
420 }
421
422 /**
423 * \test Test that the http_method content matches against a http request
424 * which holds the content.
425 */
DetectEngineHttpMethodTest05(void)426 static int DetectEngineHttpMethodTest05(void)
427 {
428 TcpSession ssn;
429 Packet *p = NULL;
430 ThreadVars th_v;
431 DetectEngineCtx *de_ctx = NULL;
432 DetectEngineThreadCtx *det_ctx = NULL;
433 HtpState *http_state = NULL;
434 Flow f;
435 uint8_t http_buf[] =
436 "CONNECT /index.html HTTP/1.0\r\n"
437 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
438 uint32_t http_len = sizeof(http_buf) - 1;
439 int result = 0;
440 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
441
442 memset(&th_v, 0, sizeof(th_v));
443 memset(&f, 0, sizeof(f));
444 memset(&ssn, 0, sizeof(ssn));
445
446 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
447
448 FLOW_INITIALIZE(&f);
449 f.protoctx = (void *)&ssn;
450 f.proto = IPPROTO_TCP;
451 f.flags |= FLOW_IPV4;
452 p->flow = &f;
453 p->flowflags |= FLOW_PKT_TOSERVER;
454 p->flowflags |= FLOW_PKT_ESTABLISHED;
455 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
456 f.alproto = ALPROTO_HTTP;
457
458 StreamTcpInitConfig(TRUE);
459
460 de_ctx = DetectEngineCtxInit();
461 if (de_ctx == NULL)
462 goto end;
463
464 de_ctx->flags |= DE_QUIET;
465
466 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
467 "(msg:\"http header test\"; "
468 "content:!\"CON\"; depth:4; http_method; "
469 "sid:1;)");
470 if (de_ctx->sig_list == NULL)
471 goto end;
472
473 SigGroupBuild(de_ctx);
474 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
475
476 FLOWLOCK_WRLOCK(&f);
477 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
478 STREAM_TOSERVER, http_buf, http_len);
479 if (r != 0) {
480 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
481 result = 0;
482 FLOWLOCK_UNLOCK(&f);
483 goto end;
484 }
485 FLOWLOCK_UNLOCK(&f);
486
487 http_state = f.alstate;
488 if (http_state == NULL) {
489 printf("no http state: ");
490 result = 0;
491 goto end;
492 }
493
494 /* do detect */
495 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
496
497 if (PacketAlertCheck(p, 1)) {
498 printf("sid 1 matched but shouldn't have: ");
499 goto end;
500 }
501
502 result = 1;
503
504 end:
505 if (alp_tctx != NULL)
506 AppLayerParserThreadCtxFree(alp_tctx);
507 if (de_ctx != NULL)
508 DetectEngineCtxFree(de_ctx);
509
510 StreamTcpFreeConfig(TRUE);
511 FLOW_DESTROY(&f);
512 UTHFreePackets(&p, 1);
513 return result;
514 }
515
516 /**
517 * \test Test that the http_method content matches against a http request
518 * which holds the content.
519 */
DetectEngineHttpMethodTest06(void)520 static int DetectEngineHttpMethodTest06(void)
521 {
522 TcpSession ssn;
523 Packet *p = NULL;
524 ThreadVars th_v;
525 DetectEngineCtx *de_ctx = NULL;
526 DetectEngineThreadCtx *det_ctx = NULL;
527 HtpState *http_state = NULL;
528 Flow f;
529 uint8_t http_buf[] =
530 "CONNECT /index.html HTTP/1.0\r\n"
531 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
532 uint32_t http_len = sizeof(http_buf) - 1;
533 int result = 0;
534 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
535
536 memset(&th_v, 0, sizeof(th_v));
537 memset(&f, 0, sizeof(f));
538 memset(&ssn, 0, sizeof(ssn));
539
540 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
541
542 FLOW_INITIALIZE(&f);
543 f.protoctx = (void *)&ssn;
544 f.proto = IPPROTO_TCP;
545 f.flags |= FLOW_IPV4;
546 p->flow = &f;
547 p->flowflags |= FLOW_PKT_TOSERVER;
548 p->flowflags |= FLOW_PKT_ESTABLISHED;
549 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
550 f.alproto = ALPROTO_HTTP;
551
552 StreamTcpInitConfig(TRUE);
553
554 de_ctx = DetectEngineCtxInit();
555 if (de_ctx == NULL)
556 goto end;
557
558 de_ctx->flags |= DE_QUIET;
559
560 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
561 "(msg:\"http header test\"; "
562 "content:\"ECT\"; offset:3; http_method; "
563 "sid:1;)");
564 if (de_ctx->sig_list == NULL)
565 goto end;
566
567 SigGroupBuild(de_ctx);
568 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
569
570 FLOWLOCK_WRLOCK(&f);
571 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
572 STREAM_TOSERVER, http_buf, http_len);
573 if (r != 0) {
574 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
575 result = 0;
576 FLOWLOCK_UNLOCK(&f);
577 goto end;
578 }
579 FLOWLOCK_UNLOCK(&f);
580
581 http_state = f.alstate;
582 if (http_state == NULL) {
583 printf("no http state: ");
584 result = 0;
585 goto end;
586 }
587
588 /* do detect */
589 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
590
591 if (!(PacketAlertCheck(p, 1))) {
592 printf("sid 1 didn't match but should have: ");
593 goto end;
594 }
595
596 result = 1;
597
598 end:
599 if (alp_tctx != NULL)
600 AppLayerParserThreadCtxFree(alp_tctx);
601 if (de_ctx != NULL)
602 DetectEngineCtxFree(de_ctx);
603
604 StreamTcpFreeConfig(TRUE);
605 FLOW_DESTROY(&f);
606 UTHFreePackets(&p, 1);
607 return result;
608 }
609
610 /**
611 * \test Test that the http_method content matches against a http request
612 * which holds the content.
613 */
DetectEngineHttpMethodTest07(void)614 static int DetectEngineHttpMethodTest07(void)
615 {
616 TcpSession ssn;
617 Packet *p = NULL;
618 ThreadVars th_v;
619 DetectEngineCtx *de_ctx = NULL;
620 DetectEngineThreadCtx *det_ctx = NULL;
621 HtpState *http_state = NULL;
622 Flow f;
623 uint8_t http_buf[] =
624 "CONNECT /index.html HTTP/1.0\r\n"
625 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
626 uint32_t http_len = sizeof(http_buf) - 1;
627 int result = 0;
628 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
629
630 memset(&th_v, 0, sizeof(th_v));
631 memset(&f, 0, sizeof(f));
632 memset(&ssn, 0, sizeof(ssn));
633
634 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
635
636 FLOW_INITIALIZE(&f);
637 f.protoctx = (void *)&ssn;
638 f.proto = IPPROTO_TCP;
639 f.flags |= FLOW_IPV4;
640 p->flow = &f;
641 p->flowflags |= FLOW_PKT_TOSERVER;
642 p->flowflags |= FLOW_PKT_ESTABLISHED;
643 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
644 f.alproto = ALPROTO_HTTP;
645
646 StreamTcpInitConfig(TRUE);
647
648 de_ctx = DetectEngineCtxInit();
649 if (de_ctx == NULL)
650 goto end;
651
652 de_ctx->flags |= DE_QUIET;
653
654 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
655 "(msg:\"http header test\"; "
656 "content:!\"CO\"; offset:3; http_method; "
657 "sid:1;)");
658 if (de_ctx->sig_list == NULL)
659 goto end;
660
661 SigGroupBuild(de_ctx);
662 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
663
664 FLOWLOCK_WRLOCK(&f);
665 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
666 STREAM_TOSERVER, http_buf, http_len);
667 if (r != 0) {
668 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
669 result = 0;
670 FLOWLOCK_UNLOCK(&f);
671 goto end;
672 }
673 FLOWLOCK_UNLOCK(&f);
674
675 http_state = f.alstate;
676 if (http_state == NULL) {
677 printf("no http state: ");
678 result = 0;
679 goto end;
680 }
681
682 /* do detect */
683 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
684
685 if (!(PacketAlertCheck(p, 1))) {
686 printf("sid 1 didn't match but should have: ");
687 goto end;
688 }
689
690 result = 1;
691
692 end:
693 if (alp_tctx != NULL)
694 AppLayerParserThreadCtxFree(alp_tctx);
695 if (de_ctx != NULL)
696 DetectEngineCtxFree(de_ctx);
697
698 StreamTcpFreeConfig(TRUE);
699 FLOW_DESTROY(&f);
700 UTHFreePackets(&p, 1);
701 return result;
702 }
703
704 /**
705 * \test Test that the http_method content matches against a http request
706 * which holds the content.
707 */
DetectEngineHttpMethodTest08(void)708 static int DetectEngineHttpMethodTest08(void)
709 {
710 TcpSession ssn;
711 Packet *p = NULL;
712 ThreadVars th_v;
713 DetectEngineCtx *de_ctx = NULL;
714 DetectEngineThreadCtx *det_ctx = NULL;
715 HtpState *http_state = NULL;
716 Flow f;
717 uint8_t http_buf[] =
718 "CONNECT /index.html HTTP/1.0\r\n"
719 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
720 uint32_t http_len = sizeof(http_buf) - 1;
721 int result = 0;
722 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
723
724 memset(&th_v, 0, sizeof(th_v));
725 memset(&f, 0, sizeof(f));
726 memset(&ssn, 0, sizeof(ssn));
727
728 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
729
730 FLOW_INITIALIZE(&f);
731 f.protoctx = (void *)&ssn;
732 f.proto = IPPROTO_TCP;
733 f.flags |= FLOW_IPV4;
734 p->flow = &f;
735 p->flowflags |= FLOW_PKT_TOSERVER;
736 p->flowflags |= FLOW_PKT_ESTABLISHED;
737 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
738 f.alproto = ALPROTO_HTTP;
739
740 StreamTcpInitConfig(TRUE);
741
742 de_ctx = DetectEngineCtxInit();
743 if (de_ctx == NULL)
744 goto end;
745
746 de_ctx->flags |= DE_QUIET;
747
748 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
749 "(msg:\"http header test\"; "
750 "content:!\"ECT\"; offset:3; http_method; "
751 "sid:1;)");
752 if (de_ctx->sig_list == NULL)
753 goto end;
754
755 SigGroupBuild(de_ctx);
756 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
757
758 FLOWLOCK_WRLOCK(&f);
759 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
760 STREAM_TOSERVER, http_buf, http_len);
761 if (r != 0) {
762 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
763 result = 0;
764 FLOWLOCK_UNLOCK(&f);
765 goto end;
766 }
767 FLOWLOCK_UNLOCK(&f);
768
769 http_state = f.alstate;
770 if (http_state == NULL) {
771 printf("no http state: ");
772 result = 0;
773 goto end;
774 }
775
776 /* do detect */
777 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
778
779 if (PacketAlertCheck(p, 1)) {
780 printf("sid 1 matched but shouldn't have: ");
781 goto end;
782 }
783
784 result = 1;
785
786 end:
787 if (alp_tctx != NULL)
788 AppLayerParserThreadCtxFree(alp_tctx);
789 if (de_ctx != NULL)
790 DetectEngineCtxFree(de_ctx);
791
792 StreamTcpFreeConfig(TRUE);
793 FLOW_DESTROY(&f);
794 UTHFreePackets(&p, 1);
795 return result;
796 }
797
798 /**
799 * \test Test that the http_method content matches against a http request
800 * which holds the content.
801 */
DetectEngineHttpMethodTest09(void)802 static int DetectEngineHttpMethodTest09(void)
803 {
804 TcpSession ssn;
805 Packet *p = NULL;
806 ThreadVars th_v;
807 DetectEngineCtx *de_ctx = NULL;
808 DetectEngineThreadCtx *det_ctx = NULL;
809 HtpState *http_state = NULL;
810 Flow f;
811 uint8_t http_buf[] =
812 "CONNECT /index.html HTTP/1.0\r\n"
813 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
814 uint32_t http_len = sizeof(http_buf) - 1;
815 int result = 0;
816 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
817
818 memset(&th_v, 0, sizeof(th_v));
819 memset(&f, 0, sizeof(f));
820 memset(&ssn, 0, sizeof(ssn));
821
822 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
823
824 FLOW_INITIALIZE(&f);
825 f.protoctx = (void *)&ssn;
826 f.proto = IPPROTO_TCP;
827 f.flags |= FLOW_IPV4;
828 p->flow = &f;
829 p->flowflags |= FLOW_PKT_TOSERVER;
830 p->flowflags |= FLOW_PKT_ESTABLISHED;
831 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
832 f.alproto = ALPROTO_HTTP;
833
834 StreamTcpInitConfig(TRUE);
835
836 de_ctx = DetectEngineCtxInit();
837 if (de_ctx == NULL)
838 goto end;
839
840 de_ctx->flags |= DE_QUIET;
841
842 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
843 "(msg:\"http header test\"; "
844 "content:\"CON\"; offset:3; http_method; "
845 "sid:1;)");
846 if (de_ctx->sig_list == NULL)
847 goto end;
848
849 SigGroupBuild(de_ctx);
850 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
851
852 FLOWLOCK_WRLOCK(&f);
853 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
854 STREAM_TOSERVER, http_buf, http_len);
855 if (r != 0) {
856 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
857 result = 0;
858 FLOWLOCK_UNLOCK(&f);
859 goto end;
860 }
861 FLOWLOCK_UNLOCK(&f);
862
863 http_state = f.alstate;
864 if (http_state == NULL) {
865 printf("no http state: ");
866 result = 0;
867 goto end;
868 }
869
870 /* do detect */
871 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
872
873 if (PacketAlertCheck(p, 1)) {
874 printf("sid 1 matched but shouldn't have: ");
875 goto end;
876 }
877
878 result = 1;
879
880 end:
881 if (alp_tctx != NULL)
882 AppLayerParserThreadCtxFree(alp_tctx);
883 if (de_ctx != NULL)
884 DetectEngineCtxFree(de_ctx);
885
886 StreamTcpFreeConfig(TRUE);
887 FLOW_DESTROY(&f);
888 UTHFreePackets(&p, 1);
889 return result;
890 }
891
892 /**
893 * \test Test that the http_method content matches against a http request
894 * which holds the content.
895 */
DetectEngineHttpMethodTest10(void)896 static int DetectEngineHttpMethodTest10(void)
897 {
898 TcpSession ssn;
899 Packet *p = NULL;
900 ThreadVars th_v;
901 DetectEngineCtx *de_ctx = NULL;
902 DetectEngineThreadCtx *det_ctx = NULL;
903 HtpState *http_state = NULL;
904 Flow f;
905 uint8_t http_buf[] =
906 "CONNECT /index.html HTTP/1.0\r\n"
907 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
908 uint32_t http_len = sizeof(http_buf) - 1;
909 int result = 0;
910 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
911
912 memset(&th_v, 0, sizeof(th_v));
913 memset(&f, 0, sizeof(f));
914 memset(&ssn, 0, sizeof(ssn));
915
916 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
917
918 FLOW_INITIALIZE(&f);
919 f.protoctx = (void *)&ssn;
920 f.proto = IPPROTO_TCP;
921 f.flags |= FLOW_IPV4;
922 p->flow = &f;
923 p->flowflags |= FLOW_PKT_TOSERVER;
924 p->flowflags |= FLOW_PKT_ESTABLISHED;
925 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
926 f.alproto = ALPROTO_HTTP;
927
928 StreamTcpInitConfig(TRUE);
929
930 de_ctx = DetectEngineCtxInit();
931 if (de_ctx == NULL)
932 goto end;
933
934 de_ctx->flags |= DE_QUIET;
935
936 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
937 "(msg:\"http header test\"; "
938 "content:\"CO\"; http_method; "
939 "content:\"EC\"; within:4; http_method; "
940 "sid:1;)");
941 if (de_ctx->sig_list == NULL)
942 goto end;
943
944 SigGroupBuild(de_ctx);
945 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
946
947 FLOWLOCK_WRLOCK(&f);
948 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
949 STREAM_TOSERVER, http_buf, http_len);
950 if (r != 0) {
951 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
952 result = 0;
953 FLOWLOCK_UNLOCK(&f);
954 goto end;
955 }
956 FLOWLOCK_UNLOCK(&f);
957
958 http_state = f.alstate;
959 if (http_state == NULL) {
960 printf("no http state: ");
961 result = 0;
962 goto end;
963 }
964
965 /* do detect */
966 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
967
968 if (!PacketAlertCheck(p, 1)) {
969 printf("sid 1 didn't match but should have: ");
970 goto end;
971 }
972
973 result = 1;
974
975 end:
976 if (alp_tctx != NULL)
977 AppLayerParserThreadCtxFree(alp_tctx);
978 if (de_ctx != NULL)
979 DetectEngineCtxFree(de_ctx);
980
981 StreamTcpFreeConfig(TRUE);
982 FLOW_DESTROY(&f);
983 UTHFreePackets(&p, 1);
984 return result;
985 }
986
987 /**
988 * \test Test that the http_method content matches against a http request
989 * which holds the content.
990 */
DetectEngineHttpMethodTest11(void)991 static int DetectEngineHttpMethodTest11(void)
992 {
993 TcpSession ssn;
994 Packet *p = NULL;
995 ThreadVars th_v;
996 DetectEngineCtx *de_ctx = NULL;
997 DetectEngineThreadCtx *det_ctx = NULL;
998 HtpState *http_state = NULL;
999 Flow f;
1000 uint8_t http_buf[] =
1001 "CONNECT /index.html HTTP/1.0\r\n"
1002 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1003 uint32_t http_len = sizeof(http_buf) - 1;
1004 int result = 0;
1005 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1006
1007 memset(&th_v, 0, sizeof(th_v));
1008 memset(&f, 0, sizeof(f));
1009 memset(&ssn, 0, sizeof(ssn));
1010
1011 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1012
1013 FLOW_INITIALIZE(&f);
1014 f.protoctx = (void *)&ssn;
1015 f.proto = IPPROTO_TCP;
1016 f.flags |= FLOW_IPV4;
1017 p->flow = &f;
1018 p->flowflags |= FLOW_PKT_TOSERVER;
1019 p->flowflags |= FLOW_PKT_ESTABLISHED;
1020 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1021 f.alproto = ALPROTO_HTTP;
1022
1023 StreamTcpInitConfig(TRUE);
1024
1025 de_ctx = DetectEngineCtxInit();
1026 if (de_ctx == NULL)
1027 goto end;
1028
1029 de_ctx->flags |= DE_QUIET;
1030
1031 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1032 "(msg:\"http header test\"; "
1033 "content:\"CO\"; http_method; "
1034 "content:!\"EC\"; within:3; http_method; "
1035 "sid:1;)");
1036 if (de_ctx->sig_list == NULL)
1037 goto end;
1038
1039 SigGroupBuild(de_ctx);
1040 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1041
1042 FLOWLOCK_WRLOCK(&f);
1043 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1044 STREAM_TOSERVER, http_buf, http_len);
1045 if (r != 0) {
1046 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1047 result = 0;
1048 FLOWLOCK_UNLOCK(&f);
1049 goto end;
1050 }
1051 FLOWLOCK_UNLOCK(&f);
1052
1053 http_state = f.alstate;
1054 if (http_state == NULL) {
1055 printf("no http state: ");
1056 result = 0;
1057 goto end;
1058 }
1059
1060 /* do detect */
1061 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1062
1063 if (!PacketAlertCheck(p, 1)) {
1064 printf("sid 1 didn't match but should have: ");
1065 goto end;
1066 }
1067
1068 result = 1;
1069
1070 end:
1071 if (alp_tctx != NULL)
1072 AppLayerParserThreadCtxFree(alp_tctx);
1073 if (de_ctx != NULL)
1074 DetectEngineCtxFree(de_ctx);
1075
1076 StreamTcpFreeConfig(TRUE);
1077 FLOW_DESTROY(&f);
1078 UTHFreePackets(&p, 1);
1079 return result;
1080 }
1081
1082 /**
1083 * \test Test that the http_method content matches against a http request
1084 * which holds the content.
1085 */
DetectEngineHttpMethodTest12(void)1086 static int DetectEngineHttpMethodTest12(void)
1087 {
1088 TcpSession ssn;
1089 Packet *p = NULL;
1090 ThreadVars th_v;
1091 DetectEngineCtx *de_ctx = NULL;
1092 DetectEngineThreadCtx *det_ctx = NULL;
1093 HtpState *http_state = NULL;
1094 Flow f;
1095 uint8_t http_buf[] =
1096 "CONNECT /index.html HTTP/1.0\r\n"
1097 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1098 uint32_t http_len = sizeof(http_buf) - 1;
1099 int result = 0;
1100 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1101
1102 memset(&th_v, 0, sizeof(th_v));
1103 memset(&f, 0, sizeof(f));
1104 memset(&ssn, 0, sizeof(ssn));
1105
1106 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1107
1108 FLOW_INITIALIZE(&f);
1109 f.protoctx = (void *)&ssn;
1110 f.proto = IPPROTO_TCP;
1111 f.flags |= FLOW_IPV4;
1112 p->flow = &f;
1113 p->flowflags |= FLOW_PKT_TOSERVER;
1114 p->flowflags |= FLOW_PKT_ESTABLISHED;
1115 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1116 f.alproto = ALPROTO_HTTP;
1117
1118 StreamTcpInitConfig(TRUE);
1119
1120 de_ctx = DetectEngineCtxInit();
1121 if (de_ctx == NULL)
1122 goto end;
1123
1124 de_ctx->flags |= DE_QUIET;
1125
1126 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1127 "(msg:\"http header test\"; "
1128 "content:\"CO\"; http_method; "
1129 "content:\"EC\"; within:3; http_method; "
1130 "sid:1;)");
1131 if (de_ctx->sig_list == NULL)
1132 goto end;
1133
1134 SigGroupBuild(de_ctx);
1135 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1136
1137 FLOWLOCK_WRLOCK(&f);
1138 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1139 STREAM_TOSERVER, http_buf, http_len);
1140 if (r != 0) {
1141 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1142 result = 0;
1143 FLOWLOCK_UNLOCK(&f);
1144 goto end;
1145 }
1146 FLOWLOCK_UNLOCK(&f);
1147
1148 http_state = f.alstate;
1149 if (http_state == NULL) {
1150 printf("no http state: ");
1151 result = 0;
1152 goto end;
1153 }
1154
1155 /* do detect */
1156 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1157
1158 if (PacketAlertCheck(p, 1)) {
1159 printf("sid 1 matched but shouldn't have: ");
1160 goto end;
1161 }
1162
1163 result = 1;
1164
1165 end:
1166 if (alp_tctx != NULL)
1167 AppLayerParserThreadCtxFree(alp_tctx);
1168 if (de_ctx != NULL)
1169 DetectEngineCtxFree(de_ctx);
1170
1171 StreamTcpFreeConfig(TRUE);
1172 FLOW_DESTROY(&f);
1173 UTHFreePackets(&p, 1);
1174 return result;
1175 }
1176
1177 /**
1178 * \test Test that the http_method content matches against a http request
1179 * which holds the content.
1180 */
DetectEngineHttpMethodTest13(void)1181 static int DetectEngineHttpMethodTest13(void)
1182 {
1183 TcpSession ssn;
1184 Packet *p = NULL;
1185 ThreadVars th_v;
1186 DetectEngineCtx *de_ctx = NULL;
1187 DetectEngineThreadCtx *det_ctx = NULL;
1188 HtpState *http_state = NULL;
1189 Flow f;
1190 uint8_t http_buf[] =
1191 "CONNECT /index.html HTTP/1.0\r\n"
1192 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1193 uint32_t http_len = sizeof(http_buf) - 1;
1194 int result = 0;
1195 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1196
1197 memset(&th_v, 0, sizeof(th_v));
1198 memset(&f, 0, sizeof(f));
1199 memset(&ssn, 0, sizeof(ssn));
1200
1201 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1202
1203 FLOW_INITIALIZE(&f);
1204 f.protoctx = (void *)&ssn;
1205 f.proto = IPPROTO_TCP;
1206 f.flags |= FLOW_IPV4;
1207 p->flow = &f;
1208 p->flowflags |= FLOW_PKT_TOSERVER;
1209 p->flowflags |= FLOW_PKT_ESTABLISHED;
1210 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1211 f.alproto = ALPROTO_HTTP;
1212
1213 StreamTcpInitConfig(TRUE);
1214
1215 de_ctx = DetectEngineCtxInit();
1216 if (de_ctx == NULL)
1217 goto end;
1218
1219 de_ctx->flags |= DE_QUIET;
1220
1221 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1222 "(msg:\"http header test\"; "
1223 "content:\"CO\"; http_method; "
1224 "content:!\"EC\"; within:4; http_method; "
1225 "sid:1;)");
1226 if (de_ctx->sig_list == NULL)
1227 goto end;
1228
1229 SigGroupBuild(de_ctx);
1230 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1231
1232 FLOWLOCK_WRLOCK(&f);
1233 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1234 STREAM_TOSERVER, http_buf, http_len);
1235 if (r != 0) {
1236 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1237 result = 0;
1238 FLOWLOCK_UNLOCK(&f);
1239 goto end;
1240 }
1241 FLOWLOCK_UNLOCK(&f);
1242
1243 http_state = f.alstate;
1244 if (http_state == NULL) {
1245 printf("no http state: ");
1246 result = 0;
1247 goto end;
1248 }
1249
1250 /* do detect */
1251 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1252
1253 if (PacketAlertCheck(p, 1)) {
1254 printf("sid 1 matched but shouldn't have: ");
1255 goto end;
1256 }
1257
1258 result = 1;
1259
1260 end:
1261 if (alp_tctx != NULL)
1262 AppLayerParserThreadCtxFree(alp_tctx);
1263 if (de_ctx != NULL)
1264 DetectEngineCtxFree(de_ctx);
1265
1266 StreamTcpFreeConfig(TRUE);
1267 FLOW_DESTROY(&f);
1268 UTHFreePackets(&p, 1);
1269 return result;
1270 }
1271
1272 /**
1273 * \test Test that the http_method content matches against a http request
1274 * which holds the content.
1275 */
DetectEngineHttpMethodTest14(void)1276 static int DetectEngineHttpMethodTest14(void)
1277 {
1278 TcpSession ssn;
1279 Packet *p = NULL;
1280 ThreadVars th_v;
1281 DetectEngineCtx *de_ctx = NULL;
1282 DetectEngineThreadCtx *det_ctx = NULL;
1283 HtpState *http_state = NULL;
1284 Flow f;
1285 uint8_t http_buf[] =
1286 "CONNECT /index.html HTTP/1.0\r\n"
1287 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1288 uint32_t http_len = sizeof(http_buf) - 1;
1289 int result = 0;
1290 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1291
1292 memset(&th_v, 0, sizeof(th_v));
1293 memset(&f, 0, sizeof(f));
1294 memset(&ssn, 0, sizeof(ssn));
1295
1296 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1297
1298 FLOW_INITIALIZE(&f);
1299 f.protoctx = (void *)&ssn;
1300 f.proto = IPPROTO_TCP;
1301 f.flags |= FLOW_IPV4;
1302 p->flow = &f;
1303 p->flowflags |= FLOW_PKT_TOSERVER;
1304 p->flowflags |= FLOW_PKT_ESTABLISHED;
1305 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1306 f.alproto = ALPROTO_HTTP;
1307
1308 StreamTcpInitConfig(TRUE);
1309
1310 de_ctx = DetectEngineCtxInit();
1311 if (de_ctx == NULL)
1312 goto end;
1313
1314 de_ctx->flags |= DE_QUIET;
1315
1316 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1317 "(msg:\"http header test\"; "
1318 "content:\"CO\"; http_method; "
1319 "content:\"EC\"; distance:2; http_method; "
1320 "sid:1;)");
1321 if (de_ctx->sig_list == NULL)
1322 goto end;
1323
1324 SigGroupBuild(de_ctx);
1325 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1326
1327 FLOWLOCK_WRLOCK(&f);
1328 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1329 STREAM_TOSERVER, http_buf, http_len);
1330 if (r != 0) {
1331 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1332 result = 0;
1333 FLOWLOCK_UNLOCK(&f);
1334 goto end;
1335 }
1336 FLOWLOCK_UNLOCK(&f);
1337
1338 http_state = f.alstate;
1339 if (http_state == NULL) {
1340 printf("no http state: ");
1341 result = 0;
1342 goto end;
1343 }
1344
1345 /* do detect */
1346 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1347
1348 if (!PacketAlertCheck(p, 1)) {
1349 printf("sid 1 didn't match but should have: ");
1350 goto end;
1351 }
1352
1353 result = 1;
1354
1355 end:
1356 if (alp_tctx != NULL)
1357 AppLayerParserThreadCtxFree(alp_tctx);
1358 if (de_ctx != NULL)
1359 DetectEngineCtxFree(de_ctx);
1360
1361 StreamTcpFreeConfig(TRUE);
1362 FLOW_DESTROY(&f);
1363 UTHFreePackets(&p, 1);
1364 return result;
1365 }
1366
1367 /**
1368 * \test Test that the http_method content matches against a http request
1369 * which holds the content.
1370 */
DetectEngineHttpMethodTest15(void)1371 static int DetectEngineHttpMethodTest15(void)
1372 {
1373 TcpSession ssn;
1374 Packet *p = NULL;
1375 ThreadVars th_v;
1376 DetectEngineCtx *de_ctx = NULL;
1377 DetectEngineThreadCtx *det_ctx = NULL;
1378 HtpState *http_state = NULL;
1379 Flow f;
1380 uint8_t http_buf[] =
1381 "CONNECT /index.html HTTP/1.0\r\n"
1382 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1383 uint32_t http_len = sizeof(http_buf) - 1;
1384 int result = 0;
1385 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1386
1387 memset(&th_v, 0, sizeof(th_v));
1388 memset(&f, 0, sizeof(f));
1389 memset(&ssn, 0, sizeof(ssn));
1390
1391 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1392
1393 FLOW_INITIALIZE(&f);
1394 f.protoctx = (void *)&ssn;
1395 f.proto = IPPROTO_TCP;
1396 f.flags |= FLOW_IPV4;
1397 p->flow = &f;
1398 p->flowflags |= FLOW_PKT_TOSERVER;
1399 p->flowflags |= FLOW_PKT_ESTABLISHED;
1400 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1401 f.alproto = ALPROTO_HTTP;
1402
1403 StreamTcpInitConfig(TRUE);
1404
1405 de_ctx = DetectEngineCtxInit();
1406 if (de_ctx == NULL)
1407 goto end;
1408
1409 de_ctx->flags |= DE_QUIET;
1410
1411 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1412 "(msg:\"http header test\"; "
1413 "content:\"CO\"; http_method; "
1414 "content:!\"EC\"; distance:3; http_method; "
1415 "sid:1;)");
1416 if (de_ctx->sig_list == NULL)
1417 goto end;
1418
1419 SigGroupBuild(de_ctx);
1420 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1421
1422 FLOWLOCK_WRLOCK(&f);
1423 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1424 STREAM_TOSERVER, http_buf, http_len);
1425 if (r != 0) {
1426 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1427 result = 0;
1428 FLOWLOCK_UNLOCK(&f);
1429 goto end;
1430 }
1431 FLOWLOCK_UNLOCK(&f);
1432
1433 http_state = f.alstate;
1434 if (http_state == NULL) {
1435 printf("no http state: ");
1436 result = 0;
1437 goto end;
1438 }
1439
1440 /* do detect */
1441 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1442
1443 if (!PacketAlertCheck(p, 1)) {
1444 printf("sid 1 didn't match but should have: ");
1445 goto end;
1446 }
1447
1448 result = 1;
1449
1450 end:
1451 if (alp_tctx != NULL)
1452 AppLayerParserThreadCtxFree(alp_tctx);
1453 if (de_ctx != NULL)
1454 DetectEngineCtxFree(de_ctx);
1455
1456 StreamTcpFreeConfig(TRUE);
1457 FLOW_DESTROY(&f);
1458 UTHFreePackets(&p, 1);
1459 return result;
1460 }
1461
1462 /**
1463 * \test Test that the http_method content matches against a http request
1464 * which holds the content.
1465 */
DetectEngineHttpMethodTest16(void)1466 static int DetectEngineHttpMethodTest16(void)
1467 {
1468 TcpSession ssn;
1469 Packet *p = NULL;
1470 ThreadVars th_v;
1471 DetectEngineCtx *de_ctx = NULL;
1472 DetectEngineThreadCtx *det_ctx = NULL;
1473 HtpState *http_state = NULL;
1474 Flow f;
1475 uint8_t http_buf[] =
1476 "CONNECT /index.html HTTP/1.0\r\n"
1477 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1478 uint32_t http_len = sizeof(http_buf) - 1;
1479 int result = 0;
1480 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1481
1482 memset(&th_v, 0, sizeof(th_v));
1483 memset(&f, 0, sizeof(f));
1484 memset(&ssn, 0, sizeof(ssn));
1485
1486 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1487
1488 FLOW_INITIALIZE(&f);
1489 f.protoctx = (void *)&ssn;
1490 f.proto = IPPROTO_TCP;
1491 f.flags |= FLOW_IPV4;
1492 p->flow = &f;
1493 p->flowflags |= FLOW_PKT_TOSERVER;
1494 p->flowflags |= FLOW_PKT_ESTABLISHED;
1495 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1496 f.alproto = ALPROTO_HTTP;
1497
1498 StreamTcpInitConfig(TRUE);
1499
1500 de_ctx = DetectEngineCtxInit();
1501 if (de_ctx == NULL)
1502 goto end;
1503
1504 de_ctx->flags |= DE_QUIET;
1505
1506 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1507 "(msg:\"http header test\"; "
1508 "content:\"CO\"; http_method; "
1509 "content:\"EC\"; distance:3; http_method; "
1510 "sid:1;)");
1511 if (de_ctx->sig_list == NULL)
1512 goto end;
1513
1514 SigGroupBuild(de_ctx);
1515 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1516
1517 FLOWLOCK_WRLOCK(&f);
1518 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1519 STREAM_TOSERVER, http_buf, http_len);
1520 if (r != 0) {
1521 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1522 result = 0;
1523 FLOWLOCK_UNLOCK(&f);
1524 goto end;
1525 }
1526 FLOWLOCK_UNLOCK(&f);
1527
1528 http_state = f.alstate;
1529 if (http_state == NULL) {
1530 printf("no http state: ");
1531 result = 0;
1532 goto end;
1533 }
1534
1535 /* do detect */
1536 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1537
1538 if (PacketAlertCheck(p, 1)) {
1539 printf("sid 1 matched but shouldn't have: ");
1540 goto end;
1541 }
1542
1543 result = 1;
1544
1545 end:
1546 if (alp_tctx != NULL)
1547 AppLayerParserThreadCtxFree(alp_tctx);
1548 if (de_ctx != NULL)
1549 DetectEngineCtxFree(de_ctx);
1550
1551 StreamTcpFreeConfig(TRUE);
1552 FLOW_DESTROY(&f);
1553 UTHFreePackets(&p, 1);
1554 return result;
1555 }
1556
1557 /**
1558 * \test Test that the http_method content matches against a http request
1559 * which holds the content.
1560 */
DetectEngineHttpMethodTest17(void)1561 static int DetectEngineHttpMethodTest17(void)
1562 {
1563 TcpSession ssn;
1564 Packet *p = NULL;
1565 ThreadVars th_v;
1566 DetectEngineCtx *de_ctx = NULL;
1567 DetectEngineThreadCtx *det_ctx = NULL;
1568 HtpState *http_state = NULL;
1569 Flow f;
1570 uint8_t http_buf[] =
1571 "CONNECT /index.html HTTP/1.0\r\n"
1572 "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1573 uint32_t http_len = sizeof(http_buf) - 1;
1574 int result = 0;
1575 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1576
1577 memset(&th_v, 0, sizeof(th_v));
1578 memset(&f, 0, sizeof(f));
1579 memset(&ssn, 0, sizeof(ssn));
1580
1581 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1582
1583 FLOW_INITIALIZE(&f);
1584 f.protoctx = (void *)&ssn;
1585 f.proto = IPPROTO_TCP;
1586 f.flags |= FLOW_IPV4;
1587 p->flow = &f;
1588 p->flowflags |= FLOW_PKT_TOSERVER;
1589 p->flowflags |= FLOW_PKT_ESTABLISHED;
1590 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1591 f.alproto = ALPROTO_HTTP;
1592
1593 StreamTcpInitConfig(TRUE);
1594
1595 de_ctx = DetectEngineCtxInit();
1596 if (de_ctx == NULL)
1597 goto end;
1598
1599 de_ctx->flags |= DE_QUIET;
1600
1601 de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1602 "(msg:\"http header test\"; "
1603 "content:\"CO\"; http_method; "
1604 "content:!\"EC\"; distance:2; http_method; "
1605 "sid:1;)");
1606 if (de_ctx->sig_list == NULL)
1607 goto end;
1608
1609 SigGroupBuild(de_ctx);
1610 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1611
1612 FLOWLOCK_WRLOCK(&f);
1613 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1614 STREAM_TOSERVER, http_buf, http_len);
1615 if (r != 0) {
1616 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1617 result = 0;
1618 FLOWLOCK_UNLOCK(&f);
1619 goto end;
1620 }
1621 FLOWLOCK_UNLOCK(&f);
1622
1623 http_state = f.alstate;
1624 if (http_state == NULL) {
1625 printf("no http state: ");
1626 result = 0;
1627 goto end;
1628 }
1629
1630 /* do detect */
1631 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1632
1633 if (PacketAlertCheck(p, 1)) {
1634 printf("sid 1 matched but shouldn't have: ");
1635 goto end;
1636 }
1637
1638 result = 1;
1639
1640 end:
1641 if (alp_tctx != NULL)
1642 AppLayerParserThreadCtxFree(alp_tctx);
1643 if (de_ctx != NULL)
1644 DetectEngineCtxFree(de_ctx);
1645
1646 StreamTcpFreeConfig(TRUE);
1647 FLOW_DESTROY(&f);
1648 UTHFreePackets(&p, 1);
1649 return result;
1650 }
1651
1652 /** \test Check a signature with content */
DetectHttpMethodTest01(void)1653 static int DetectHttpMethodTest01(void)
1654 {
1655 DetectEngineCtx *de_ctx = NULL;
1656 int result = 0;
1657
1658 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1659 goto end;
1660
1661 de_ctx->flags |= DE_QUIET;
1662 de_ctx->sig_list = SigInit(de_ctx,
1663 "alert tcp any any -> any any "
1664 "(msg:\"Testing http_method\"; "
1665 "content:\"GET\"; "
1666 "http_method; sid:1;)");
1667
1668 if (de_ctx->sig_list != NULL) {
1669 result = 1;
1670 } else {
1671 printf("sig parse failed: ");
1672 }
1673
1674 end:
1675 if (de_ctx != NULL)
1676 DetectEngineCtxFree(de_ctx);
1677 return result;
1678 }
1679
1680 /** \test Check a signature without content (fail) */
DetectHttpMethodTest02(void)1681 static int DetectHttpMethodTest02(void)
1682 {
1683 DetectEngineCtx *de_ctx = NULL;
1684 int result = 0;
1685
1686 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1687 goto end;
1688
1689 de_ctx->flags |= DE_QUIET;
1690 de_ctx->sig_list = SigInit(de_ctx,
1691 "alert tcp any any -> any any "
1692 "(msg:\"Testing http_method\"; "
1693 "http_method; sid:1;)");
1694
1695 if (de_ctx->sig_list == NULL) {
1696 result = 1;
1697 }
1698
1699 end:
1700 if (de_ctx != NULL)
1701 DetectEngineCtxFree(de_ctx);
1702 return result;
1703 }
1704
1705 /** \test Check a signature with parameter (fail) */
DetectHttpMethodTest03(void)1706 static int DetectHttpMethodTest03(void)
1707 {
1708 DetectEngineCtx *de_ctx = NULL;
1709 int result = 0;
1710
1711 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1712 goto end;
1713
1714 de_ctx->flags |= DE_QUIET;
1715 de_ctx->sig_list = SigInit(de_ctx,
1716 "alert tcp any any -> any any "
1717 "(msg:\"Testing http_method\"; "
1718 "content:\"foobar\"; "
1719 "http_method:\"GET\"; sid:1;)");
1720
1721 if (de_ctx->sig_list == NULL) {
1722 result = 1;
1723 }
1724
1725 end:
1726 if (de_ctx != NULL)
1727 DetectEngineCtxFree(de_ctx);
1728 return result;
1729 }
1730
1731 /** \test Check a signature with fast_pattern (should work) */
DetectHttpMethodTest04(void)1732 static int DetectHttpMethodTest04(void)
1733 {
1734 DetectEngineCtx *de_ctx = NULL;
1735 int result = 0;
1736
1737 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1738 goto end;
1739
1740 de_ctx->flags |= DE_QUIET;
1741 de_ctx->sig_list = SigInit(de_ctx,
1742 "alert tcp any any -> any any "
1743 "(msg:\"Testing http_method\"; "
1744 "content:\"GET\"; "
1745 "fast_pattern; "
1746 "http_method; sid:1;)");
1747
1748 if (de_ctx->sig_list != NULL) {
1749 result = 1;
1750 }
1751
1752 end:
1753 if (de_ctx != NULL)
1754 DetectEngineCtxFree(de_ctx);
1755 return result;
1756 }
1757
1758 /** \test Check a signature with rawbytes (fail) */
DetectHttpMethodTest05(void)1759 static int DetectHttpMethodTest05(void)
1760 {
1761 DetectEngineCtx *de_ctx = NULL;
1762 int result = 0;
1763
1764 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1765 goto end;
1766
1767 de_ctx->flags |= DE_QUIET;
1768 de_ctx->sig_list = SigInit(de_ctx,
1769 "alert tcp any any -> any any "
1770 "(msg:\"Testing http_method\"; "
1771 "content:\"GET\"; "
1772 "rawbytes; "
1773 "http_method; sid:1;)");
1774
1775 if (de_ctx->sig_list == NULL) {
1776 result = 1;
1777 }
1778
1779 end:
1780 if (de_ctx != NULL)
1781 DetectEngineCtxFree(de_ctx);
1782 return result;
1783 }
1784
1785 /** \test setting the nocase flag */
DetectHttpMethodTest12(void)1786 static int DetectHttpMethodTest12(void)
1787 {
1788 DetectEngineCtx *de_ctx = NULL;
1789 int result = 0;
1790
1791 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1792 goto end;
1793
1794 de_ctx->flags |= DE_QUIET;
1795
1796 if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1797 "(content:\"one\"; http_method; nocase; sid:1;)") == NULL) {
1798 printf("DetectEngineAppend == NULL: ");
1799 goto end;
1800 }
1801 if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1802 "(content:\"one\"; nocase; http_method; sid:2;)") == NULL) {
1803 printf("DetectEngineAppend == NULL: ");
1804 goto end;
1805 }
1806
1807 if (de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL) {
1808 printf("de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL: ");
1809 goto end;
1810 }
1811
1812 DetectContentData *hmd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_method_buffer_id]->ctx;
1813 DetectContentData *hmd2 = (DetectContentData *)de_ctx->sig_list->next->sm_lists_tail[g_http_method_buffer_id]->ctx;
1814
1815 if (!(hmd1->flags & DETECT_CONTENT_NOCASE)) {
1816 printf("nocase flag not set on sig 1: ");
1817 goto end;
1818 }
1819
1820 if (!(hmd2->flags & DETECT_CONTENT_NOCASE)) {
1821 printf("nocase flag not set on sig 2: ");
1822 goto end;
1823 }
1824 result = 1;
1825
1826 end:
1827 DetectEngineCtxFree(de_ctx);
1828 return result;
1829 }
1830
1831 /** \test Check a signature with method + within and pcre with /M (should work) */
DetectHttpMethodTest13(void)1832 static int DetectHttpMethodTest13(void)
1833 {
1834 DetectEngineCtx *de_ctx = NULL;
1835 int result = 0;
1836
1837 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1838 goto end;
1839
1840 de_ctx->flags |= DE_QUIET;
1841 de_ctx->sig_list = SigInit(de_ctx,
1842 "alert tcp any any -> any any "
1843 "(msg:\"Testing http_method\"; "
1844 "pcre:\"/HE/M\"; "
1845 "content:\"AD\"; "
1846 "within:2; http_method; sid:1;)");
1847
1848 if (de_ctx->sig_list != NULL) {
1849 result = 1;
1850 }
1851
1852 end:
1853 if (de_ctx != NULL)
1854 DetectEngineCtxFree(de_ctx);
1855 return result;
1856 }
1857
1858 /** \test Check a signature with method + within and pcre without /M (should fail) */
DetectHttpMethodTest14(void)1859 static int DetectHttpMethodTest14(void)
1860 {
1861 DetectEngineCtx *de_ctx = NULL;
1862 int result = 0;
1863
1864 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1865 goto end;
1866
1867 de_ctx->flags |= DE_QUIET;
1868 de_ctx->sig_list = SigInit(de_ctx,
1869 "alert tcp any any -> any any "
1870 "(msg:\"Testing http_method\"; "
1871 "pcre:\"/HE/\"; "
1872 "content:\"AD\"; "
1873 "http_method; within:2; sid:1;)");
1874
1875 if (de_ctx->sig_list != NULL) {
1876 result = 1;
1877 }
1878
1879 end:
1880 if (de_ctx != NULL)
1881 DetectEngineCtxFree(de_ctx);
1882 return result;
1883 }
1884
1885 /** \test Check a signature with method + within and pcre with /M (should work) */
DetectHttpMethodTest15(void)1886 static int DetectHttpMethodTest15(void)
1887 {
1888 DetectEngineCtx *de_ctx = NULL;
1889 int result = 0;
1890
1891 if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1892 goto end;
1893
1894 de_ctx->flags |= DE_QUIET;
1895 de_ctx->sig_list = SigInit(de_ctx,
1896 "alert tcp any any -> any any "
1897 "(msg:\"Testing http_method\"; "
1898 "pcre:\"/HE/M\"; "
1899 "content:\"AD\"; "
1900 "http_method; within:2; sid:1;)");
1901
1902 if (de_ctx->sig_list != NULL) {
1903 result = 1;
1904 }
1905
1906 end:
1907 if (de_ctx != NULL)
1908 DetectEngineCtxFree(de_ctx);
1909 return result;
1910 }
1911 /** \test Check a signature with an known request method */
DetectHttpMethodSigTest01(void)1912 static int DetectHttpMethodSigTest01(void)
1913 {
1914 int result = 0;
1915 Flow f;
1916 uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
1917 "Host: foo.bar.tld\r\n"
1918 "\r\n";
1919 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1920 TcpSession ssn;
1921 Packet *p = NULL;
1922 Signature *s = NULL;
1923 ThreadVars th_v;
1924 DetectEngineThreadCtx *det_ctx;
1925 HtpState *http_state = NULL;
1926 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1927
1928 memset(&th_v, 0, sizeof(th_v));
1929 memset(&f, 0, sizeof(f));
1930 memset(&ssn, 0, sizeof(ssn));
1931
1932 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1933
1934 FLOW_INITIALIZE(&f);
1935 f.protoctx = (void *)&ssn;
1936 f.proto = IPPROTO_TCP;
1937 f.flags |= FLOW_IPV4;
1938
1939 p->flow = &f;
1940 p->flowflags |= FLOW_PKT_TOSERVER;
1941 p->flowflags |= FLOW_PKT_ESTABLISHED;
1942 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1943 f.alproto = ALPROTO_HTTP;
1944
1945 StreamTcpInitConfig(TRUE);
1946
1947 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1948 if (de_ctx == NULL) {
1949 goto end;
1950 }
1951
1952 de_ctx->flags |= DE_QUIET;
1953
1954 s = de_ctx->sig_list = SigInit(de_ctx,
1955 "alert tcp any any -> any any "
1956 "(msg:\"Testing http_method\"; "
1957 "content:\"GET\"; "
1958 "http_method; sid:1;)");
1959 if (s == NULL) {
1960 goto end;
1961 }
1962
1963 s = s->next = SigInit(de_ctx,
1964 "alert tcp any any -> any any "
1965 "(msg:\"Testing http_method\"; "
1966 "content:\"POST\"; "
1967 "http_method; sid:2;)");
1968 if (s == NULL) {
1969 goto end;
1970 }
1971
1972 SigGroupBuild(de_ctx);
1973 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1974
1975 FLOWLOCK_WRLOCK(&f);
1976 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1977 STREAM_TOSERVER, httpbuf1, httplen1);
1978 if (r != 0) {
1979 SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1980 FLOWLOCK_UNLOCK(&f);
1981 goto end;
1982 }
1983 FLOWLOCK_UNLOCK(&f);
1984
1985 http_state = f.alstate;
1986 if (http_state == NULL) {
1987 SCLogDebug("no http state: ");
1988 goto end;
1989 }
1990
1991 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1992
1993 if (!(PacketAlertCheck(p, 1))) {
1994 goto end;
1995 }
1996 if (PacketAlertCheck(p, 2)) {
1997 goto end;
1998 }
1999
2000 result = 1;
2001
2002 end:
2003 if (alp_tctx != NULL)
2004 AppLayerParserThreadCtxFree(alp_tctx);
2005 if (de_ctx != NULL)
2006 DetectEngineCtxFree(de_ctx);
2007
2008 StreamTcpFreeConfig(TRUE);
2009 FLOW_DESTROY(&f);
2010 UTHFreePackets(&p, 1);
2011 return result;
2012 }
2013
2014 /** \test Check a signature with an unknown request method */
DetectHttpMethodSigTest02(void)2015 static int DetectHttpMethodSigTest02(void)
2016 {
2017 int result = 0;
2018 Flow f;
2019 uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n"
2020 "Host: foo.bar.tld\r\n"
2021 "\r\n";
2022 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2023 TcpSession ssn;
2024 Packet *p = NULL;
2025 Signature *s = NULL;
2026 ThreadVars th_v;
2027 DetectEngineThreadCtx *det_ctx = NULL;
2028 HtpState *http_state = NULL;
2029 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2030
2031 memset(&th_v, 0, sizeof(th_v));
2032 memset(&f, 0, sizeof(f));
2033 memset(&ssn, 0, sizeof(ssn));
2034
2035 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2036
2037 FLOW_INITIALIZE(&f);
2038 f.protoctx = (void *)&ssn;
2039 f.proto = IPPROTO_TCP;
2040 f.flags |= FLOW_IPV4;
2041
2042 p->flow = &f;
2043 p->flowflags |= FLOW_PKT_TOSERVER;
2044 p->flowflags |= FLOW_PKT_ESTABLISHED;
2045 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2046 f.alproto = ALPROTO_HTTP;
2047
2048 StreamTcpInitConfig(TRUE);
2049
2050 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2051 if (de_ctx == NULL) {
2052 goto end;
2053 }
2054
2055 de_ctx->flags |= DE_QUIET;
2056
2057 s = de_ctx->sig_list = SigInit(de_ctx,
2058 "alert tcp any any -> any any "
2059 "(msg:\"Testing http_method\"; "
2060 "content:\"FOO\"; "
2061 "http_method; sid:1;)");
2062 if (s == NULL) {
2063 goto end;
2064 }
2065
2066 s = s->next = SigInit(de_ctx,
2067 "alert tcp any any -> any any "
2068 "(msg:\"Testing http_method\"; "
2069 "content:\"BAR\"; "
2070 "http_method; sid:2;)");
2071 if (s == NULL) {
2072 goto end;
2073 }
2074
2075 SigGroupBuild(de_ctx);
2076 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2077
2078 FLOWLOCK_WRLOCK(&f);
2079 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2080 STREAM_TOSERVER, httpbuf1, httplen1);
2081 if (r != 0) {
2082 SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2083 FLOWLOCK_UNLOCK(&f);
2084 goto end;
2085 }
2086 FLOWLOCK_UNLOCK(&f);
2087
2088 http_state = f.alstate;
2089 if (http_state == NULL) {
2090 SCLogDebug("no http state: ");
2091 goto end;
2092 }
2093
2094 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2095
2096 if (!(PacketAlertCheck(p, 1))) {
2097 goto end;
2098 }
2099 if (PacketAlertCheck(p, 2)) {
2100 goto end;
2101 }
2102
2103 result = 1;
2104
2105 end:
2106 if (alp_tctx != NULL)
2107 AppLayerParserThreadCtxFree(alp_tctx);
2108 if (det_ctx != NULL)
2109 DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
2110 if (de_ctx != NULL)
2111 DetectEngineCtxFree(de_ctx);
2112
2113 StreamTcpFreeConfig(TRUE);
2114 FLOW_DESTROY(&f);
2115 UTHFreePackets(&p, 1);
2116 return result;
2117 }
2118
2119 /** \test Check a signature against an unparsable request */
DetectHttpMethodSigTest03(void)2120 static int DetectHttpMethodSigTest03(void)
2121 {
2122 int result = 0;
2123 Flow f;
2124 uint8_t httpbuf1[] = " ";
2125 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2126 TcpSession ssn;
2127 Packet *p = NULL;
2128 Signature *s = NULL;
2129 ThreadVars th_v;
2130 DetectEngineThreadCtx *det_ctx;
2131 HtpState *http_state = NULL;
2132 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2133
2134 memset(&th_v, 0, sizeof(th_v));
2135 memset(&f, 0, sizeof(f));
2136 memset(&ssn, 0, sizeof(ssn));
2137
2138 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2139
2140 FLOW_INITIALIZE(&f);
2141 f.protoctx = (void *)&ssn;
2142 f.proto = IPPROTO_TCP;
2143 f.flags |= FLOW_IPV4;
2144
2145 p->flow = &f;
2146 p->flowflags |= FLOW_PKT_TOSERVER;
2147 p->flowflags |= FLOW_PKT_ESTABLISHED;
2148 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2149 f.alproto = ALPROTO_HTTP;
2150
2151 StreamTcpInitConfig(TRUE);
2152
2153 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2154 if (de_ctx == NULL) {
2155 goto end;
2156 }
2157
2158 de_ctx->flags |= DE_QUIET;
2159
2160 s = de_ctx->sig_list = SigInit(de_ctx,
2161 "alert tcp any any -> any any "
2162 "(msg:\"Testing http_method\"; "
2163 "content:\"GET\"; "
2164 "http_method; sid:1;)");
2165 if (s == NULL) {
2166 SCLogDebug("Bad signature");
2167 goto end;
2168 }
2169
2170 SigGroupBuild(de_ctx);
2171 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2172
2173 FLOWLOCK_WRLOCK(&f);
2174 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2175 STREAM_TOSERVER, httpbuf1, httplen1);
2176 if (r != 0) {
2177 SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2178 FLOWLOCK_UNLOCK(&f);
2179 goto end;
2180 }
2181 FLOWLOCK_UNLOCK(&f);
2182
2183 http_state = f.alstate;
2184 if (http_state == NULL) {
2185 SCLogDebug("no http state: ");
2186 goto end;
2187 }
2188
2189 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2190
2191 if (PacketAlertCheck(p, 1)) {
2192 goto end;
2193 }
2194
2195 result = 1;
2196
2197 end:
2198 if (alp_tctx != NULL)
2199 AppLayerParserThreadCtxFree(alp_tctx);
2200 if (de_ctx != NULL)
2201 DetectEngineCtxFree(de_ctx);
2202
2203 StreamTcpFreeConfig(TRUE);
2204 FLOW_DESTROY(&f);
2205 UTHFreePackets(&p, 1);
2206 return result;
2207 }
2208
2209 /** \test Check a signature with an request method and negation of the same */
DetectHttpMethodSigTest04(void)2210 static int DetectHttpMethodSigTest04(void)
2211 {
2212 int result = 0;
2213 Flow f;
2214 uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
2215 "Host: foo.bar.tld\r\n"
2216 "\r\n";
2217 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2218 TcpSession ssn;
2219 Packet *p = NULL;
2220 Signature *s = NULL;
2221 ThreadVars th_v;
2222 DetectEngineThreadCtx *det_ctx = NULL;
2223 HtpState *http_state = NULL;
2224 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2225
2226 memset(&th_v, 0, sizeof(th_v));
2227 memset(&f, 0, sizeof(f));
2228 memset(&ssn, 0, sizeof(ssn));
2229
2230 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2231
2232 FLOW_INITIALIZE(&f);
2233 f.protoctx = (void *)&ssn;
2234 f.proto = IPPROTO_TCP;
2235 f.flags |= FLOW_IPV4;
2236
2237 p->flow = &f;
2238 p->flowflags |= FLOW_PKT_TOSERVER;
2239 p->flowflags |= FLOW_PKT_ESTABLISHED;
2240 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2241 f.alproto = ALPROTO_HTTP;
2242
2243 StreamTcpInitConfig(TRUE);
2244
2245 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2246 if (de_ctx == NULL) {
2247 goto end;
2248 }
2249
2250 de_ctx->flags |= DE_QUIET;
2251
2252 s = de_ctx->sig_list = SigInit(de_ctx,
2253 "alert tcp any any -> any any (msg:\"Testing http_method\"; "
2254 "content:\"GET\"; http_method; sid:1;)");
2255 if (s == NULL) {
2256 goto end;
2257 }
2258
2259 s = s->next = SigInit(de_ctx,
2260 "alert tcp any any -> any any (msg:\"Testing http_method\"; "
2261 "content:!\"GET\"; http_method; sid:2;)");
2262 if (s == NULL) {
2263 goto end;
2264 }
2265
2266 SigGroupBuild(de_ctx);
2267 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2268
2269 FLOWLOCK_WRLOCK(&f);
2270 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2271 STREAM_TOSERVER, httpbuf1, httplen1);
2272 if (r != 0) {
2273 SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2274 FLOWLOCK_UNLOCK(&f);
2275 goto end;
2276 }
2277 FLOWLOCK_UNLOCK(&f);
2278
2279 http_state = f.alstate;
2280 if (http_state == NULL) {
2281 SCLogDebug("no http state: ");
2282 goto end;
2283 }
2284
2285 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2286
2287 if (!(PacketAlertCheck(p, 1))) {
2288 printf("sid 1 didn't match but should have: ");
2289 goto end;
2290 }
2291 if (PacketAlertCheck(p, 2)) {
2292 printf("sid 2 matched but shouldn't have: ");
2293 goto end;
2294 }
2295
2296 result = 1;
2297
2298 end:
2299 if (alp_tctx != NULL)
2300 AppLayerParserThreadCtxFree(alp_tctx);
2301 if (det_ctx != NULL) {
2302 DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
2303 }
2304 if (de_ctx != NULL) {
2305 DetectEngineCtxFree(de_ctx);
2306 }
2307
2308 StreamTcpFreeConfig(TRUE);
2309 FLOW_DESTROY(&f);
2310 UTHFreePackets(&p, 1);
2311 return result;
2312 }
2313
DetectHttpMethodIsdataatParseTest(void)2314 static int DetectHttpMethodIsdataatParseTest(void)
2315 {
2316 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2317 FAIL_IF_NULL(de_ctx);
2318 de_ctx->flags |= DE_QUIET;
2319
2320 Signature *s = DetectEngineAppendSig(de_ctx,
2321 "alert tcp any any -> any any ("
2322 "content:\"one\"; http_method; "
2323 "isdataat:!4,relative; sid:1;)");
2324 FAIL_IF_NULL(s);
2325
2326 SigMatch *sm = s->init_data->smlists_tail[g_http_method_buffer_id];
2327 FAIL_IF_NULL(sm);
2328 FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
2329
2330 DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
2331 FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
2332 FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
2333 FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
2334
2335 DetectEngineCtxFree(de_ctx);
2336 PASS;
2337 }
2338
2339 /**
2340 * \brief this function registers unit tests for DetectHttpMethod
2341 */
DetectHttpMethodRegisterTests(void)2342 void DetectHttpMethodRegisterTests(void)
2343 {
2344 UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01);
2345 UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02);
2346 UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03);
2347 UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04);
2348 UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05);
2349 UtRegisterTest("DetectHttpMethodTest12 -- nocase flag",
2350 DetectHttpMethodTest12);
2351 UtRegisterTest("DetectHttpMethodTest13", DetectHttpMethodTest13);
2352 UtRegisterTest("DetectHttpMethodTest14", DetectHttpMethodTest14);
2353 UtRegisterTest("DetectHttpMethodTest15", DetectHttpMethodTest15);
2354 UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01);
2355 UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02);
2356 UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03);
2357 UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04);
2358
2359 UtRegisterTest("DetectHttpMethodIsdataatParseTest",
2360 DetectHttpMethodIsdataatParseTest);
2361 UtRegisterTest("DetectEngineHttpMethodTest01",
2362 DetectEngineHttpMethodTest01);
2363 UtRegisterTest("DetectEngineHttpMethodTest02",
2364 DetectEngineHttpMethodTest02);
2365 UtRegisterTest("DetectEngineHttpMethodTest03",
2366 DetectEngineHttpMethodTest03);
2367 UtRegisterTest("DetectEngineHttpMethodTest04",
2368 DetectEngineHttpMethodTest04);
2369 UtRegisterTest("DetectEngineHttpMethodTest05",
2370 DetectEngineHttpMethodTest05);
2371 UtRegisterTest("DetectEngineHttpMethodTest06",
2372 DetectEngineHttpMethodTest06);
2373 UtRegisterTest("DetectEngineHttpMethodTest07",
2374 DetectEngineHttpMethodTest07);
2375 UtRegisterTest("DetectEngineHttpMethodTest08",
2376 DetectEngineHttpMethodTest08);
2377 UtRegisterTest("DetectEngineHttpMethodTest09",
2378 DetectEngineHttpMethodTest09);
2379 UtRegisterTest("DetectEngineHttpMethodTest10",
2380 DetectEngineHttpMethodTest10);
2381 UtRegisterTest("DetectEngineHttpMethodTest11",
2382 DetectEngineHttpMethodTest11);
2383 UtRegisterTest("DetectEngineHttpMethodTest12",
2384 DetectEngineHttpMethodTest12);
2385 UtRegisterTest("DetectEngineHttpMethodTest13",
2386 DetectEngineHttpMethodTest13);
2387 UtRegisterTest("DetectEngineHttpMethodTest14",
2388 DetectEngineHttpMethodTest14);
2389 UtRegisterTest("DetectEngineHttpMethodTest15",
2390 DetectEngineHttpMethodTest15);
2391 UtRegisterTest("DetectEngineHttpMethodTest16",
2392 DetectEngineHttpMethodTest16);
2393 UtRegisterTest("DetectEngineHttpMethodTest17",
2394 DetectEngineHttpMethodTest17);
2395 }
2396
2397 /**
2398 * @}
2399 */
2400