suricata
detect-http-method.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \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  */
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;
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;
81 
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 
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  */
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;
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;
174  f.alproto = ALPROTO_HTTP;
175 
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 
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  */
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;
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;
268  f.alproto = ALPROTO_HTTP;
269 
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 
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  */
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;
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;
362  f.alproto = ALPROTO_HTTP;
363 
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 
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  */
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;
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;
456  f.alproto = ALPROTO_HTTP;
457 
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 
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  */
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;
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;
550  f.alproto = ALPROTO_HTTP;
551 
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 
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  */
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;
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;
644  f.alproto = ALPROTO_HTTP;
645 
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 
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  */
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;
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;
738  f.alproto = ALPROTO_HTTP;
739 
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 
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  */
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;
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;
832  f.alproto = ALPROTO_HTTP;
833 
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 
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  */
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;
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;
926  f.alproto = ALPROTO_HTTP;
927 
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 
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  */
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;
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;
1021  f.alproto = ALPROTO_HTTP;
1022 
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 
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  */
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;
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;
1116  f.alproto = ALPROTO_HTTP;
1117 
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 
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  */
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;
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;
1211  f.alproto = ALPROTO_HTTP;
1212 
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 
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  */
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;
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;
1306  f.alproto = ALPROTO_HTTP;
1307 
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 
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  */
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;
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;
1401  f.alproto = ALPROTO_HTTP;
1402 
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 
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  */
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;
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;
1496  f.alproto = ALPROTO_HTTP;
1497 
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 
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  */
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;
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;
1591  f.alproto = ALPROTO_HTTP;
1592 
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 
1647  FLOW_DESTROY(&f);
1648  UTHFreePackets(&p, 1);
1649  return result;
1650 }
1651 
1652 /** \test Check a signature with content */
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) */
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) */
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) */
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) */
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 */
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) */
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) */
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) */
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 */
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;
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;
1943  f.alproto = ALPROTO_HTTP;
1944 
1946 
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 
2009  FLOW_DESTROY(&f);
2010  UTHFreePackets(&p, 1);
2011  return result;
2012 }
2013 
2014 /** \test Check a signature with an unknown request method */
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;
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;
2046  f.alproto = ALPROTO_HTTP;
2047 
2049 
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 
2114  FLOW_DESTROY(&f);
2115  UTHFreePackets(&p, 1);
2116  return result;
2117 }
2118 
2119 /** \test Check a signature against an unparsable request */
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;
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;
2149  f.alproto = ALPROTO_HTTP;
2150 
2152 
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 
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 */
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;
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;
2241  f.alproto = ALPROTO_HTTP;
2242 
2244 
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 
2309  FLOW_DESTROY(&f);
2310  UTHFreePackets(&p, 1);
2311  return result;
2312 }
2313 
2314 static int DetectHttpMethodIsdataatParseTest(void)
2315 {
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);
2329 
2330  DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
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  */
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  */
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SignatureInitData * init_data
Definition: detect.h:591
#define SCLogDebug(...)
Definition: util-debug.h:335
struct Flow_ * flow
Definition: decode.h:445
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint8_t proto
Definition: flow.h:344
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:243
#define PASS
Pass the test.
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Signature * sig_list
Definition: detect.h:767
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:203
#define ISDATAAT_RELATIVE
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
#define ISDATAAT_RAWBYTES
Signature container.
Definition: detect.h:522
#define TRUE
void * protoctx
Definition: flow.h:400
main detection engine ctx
Definition: detect.h:761
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:438
#define DE_QUIET
Definition: detect.h:292
uint8_t flags
Definition: detect.h:762
#define ISDATAAT_NEGATED
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1669
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
uint8_t flowflags
Definition: decode.h:439
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
struct SigMatch_ ** smlists_tail
Definition: detect.h:518
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
struct Signature_ * next
Definition: detect.h:594
uint8_t type
Definition: detect.h:319
SigMatchCtx * ctx
Definition: detect.h:321
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
void DetectHttpMethodRegisterTests(void)
this function registers unit tests for DetectHttpMethod
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
#define PKT_HAS_FLOW
Definition: decode.h:1093
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define DETECT_CONTENT_NOCASE
Per thread variable structure.
Definition: threadvars.h:57
AppProto alproto
application level protocol
Definition: flow.h:409
uint32_t flags
Definition: decode.h:443
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
Flow data structure.
Definition: flow.h:325
#define FLOW_IPV4
Definition: flow.h:94
uint32_t flags
Definition: flow.h:379
#define PKT_STREAM_EST
Definition: decode.h:1091
a single match condition for a signature
Definition: detect.h:318
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
DetectEngineCtx * DetectEngineCtxInit(void)