suricata
detect-http-host.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2018 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \ingroup httplayer
20  *
21  * @{
22  */
23 
24 
25 /** \file
26  *
27  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
28  * \author Victor Julien <victor@inliniac.net>
29  *
30  * \brief Handle HTTP host header.
31  * HHHD - Http Host Header Data
32  *
33  */
34 
35 #include "suricata-common.h"
36 #include "suricata.h"
37 #include "flow-util.h"
38 #include "flow.h"
39 #include "app-layer-parser.h"
40 #include "util-unittest.h"
41 #include "util-unittest-helper.h"
42 #include "app-layer.h"
43 #include "app-layer-htp.h"
44 #include "app-layer-protos.h"
45 
46 /**
47  * \test Test that the http_host content matches against a http request
48  * which holds the content.
49  */
50 static int DetectEngineHttpHHTest01(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: CONNECT\r\n"
62  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
63  uint32_t http_len = sizeof(http_buf) - 1;
64  int result = 0;
66 
67  memset(&th_v, 0, sizeof(th_v));
68  memset(&f, 0, sizeof(f));
69  memset(&ssn, 0, sizeof(ssn));
70 
71  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
72 
73  FLOW_INITIALIZE(&f);
74  f.protoctx = (void *)&ssn;
75  f.proto = IPPROTO_TCP;
76  f.flags |= FLOW_IPV4;
77  p->flow = &f;
82 
84 
85  de_ctx = DetectEngineCtxInit();
86  if (de_ctx == NULL)
87  goto end;
88 
89  de_ctx->flags |= DE_QUIET;
90 
91  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
92  "(msg:\"http host header test\"; "
93  "content:\"connect\"; http_host; "
94  "sid:1;)");
95  if (de_ctx->sig_list == NULL)
96  goto end;
97 
98  SigGroupBuild(de_ctx);
99  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
100 
101  FLOWLOCK_WRLOCK(&f);
102  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
103  STREAM_TOSERVER, http_buf, http_len);
104  if (r != 0) {
105  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
106  result = 0;
107  FLOWLOCK_UNLOCK(&f);
108  goto end;
109  }
110  FLOWLOCK_UNLOCK(&f);
111 
112  http_state = f.alstate;
113  if (http_state == NULL) {
114  printf("no http state: ");
115  result = 0;
116  goto end;
117  }
118 
119  /* do detect */
120  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
121 
122  if (!(PacketAlertCheck(p, 1))) {
123  printf("sid 1 didn't match but should have: ");
124  goto end;
125  }
126 
127  result = 1;
128 
129 end:
130  if (alp_tctx != NULL)
131  AppLayerParserThreadCtxFree(alp_tctx);
132  if (de_ctx != NULL)
133  SigGroupCleanup(de_ctx);
134  if (de_ctx != NULL)
135  SigCleanSignatures(de_ctx);
136  if (de_ctx != NULL)
137  DetectEngineCtxFree(de_ctx);
138 
140  FLOW_DESTROY(&f);
141  UTHFreePackets(&p, 1);
142  return result;
143 }
144 
145 /**
146  * \test Test that the http_host content matches against a http request
147  * which holds the content.
148  */
149 static int DetectEngineHttpHHTest02(void)
150 {
151  TcpSession ssn;
152  Packet *p = NULL;
153  ThreadVars th_v;
154  DetectEngineCtx *de_ctx = NULL;
155  DetectEngineThreadCtx *det_ctx = NULL;
156  HtpState *http_state = NULL;
157  Flow f;
158  uint8_t http_buf[] =
159  "GET /index.html HTTP/1.0\r\n"
160  "Host: CONNECT\r\n"
161  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
162  uint32_t http_len = sizeof(http_buf) - 1;
163  int result = 0;
165 
166  memset(&th_v, 0, sizeof(th_v));
167  memset(&f, 0, sizeof(f));
168  memset(&ssn, 0, sizeof(ssn));
169 
170  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
171 
172  FLOW_INITIALIZE(&f);
173  f.protoctx = (void *)&ssn;
174  f.proto = IPPROTO_TCP;
175  f.flags |= FLOW_IPV4;
176  p->flow = &f;
180  f.alproto = ALPROTO_HTTP;
181 
183 
184  de_ctx = DetectEngineCtxInit();
185  if (de_ctx == NULL)
186  goto end;
187 
188  de_ctx->flags |= DE_QUIET;
189 
190  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
191  "(msg:\"http host header test\"; "
192  "content:\"co\"; depth:4; http_host; "
193  "sid:1;)");
194  if (de_ctx->sig_list == NULL)
195  goto end;
196 
197  SigGroupBuild(de_ctx);
198  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
199 
200  FLOWLOCK_WRLOCK(&f);
201  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
202  STREAM_TOSERVER, http_buf, http_len);
203  if (r != 0) {
204  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
205  result = 0;
206  FLOWLOCK_UNLOCK(&f);
207  goto end;
208  }
209  FLOWLOCK_UNLOCK(&f);
210 
211  http_state = f.alstate;
212  if (http_state == NULL) {
213  printf("no http state: ");
214  result = 0;
215  goto end;
216  }
217 
218  /* do detect */
219  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
220 
221  if (!(PacketAlertCheck(p, 1))) {
222  printf("sid 1 didn't match but should have: ");
223  goto end;
224  }
225 
226  result = 1;
227 
228 end:
229  if (alp_tctx != NULL)
230  AppLayerParserThreadCtxFree(alp_tctx);
231  if (de_ctx != NULL)
232  SigGroupCleanup(de_ctx);
233  if (de_ctx != NULL)
234  SigCleanSignatures(de_ctx);
235  if (de_ctx != NULL)
236  DetectEngineCtxFree(de_ctx);
237 
239  FLOW_DESTROY(&f);
240  UTHFreePackets(&p, 1);
241  return result;
242 }
243 
244 /**
245  * \test Test that the http_host content matches against a http request
246  * which holds the content.
247  */
248 static int DetectEngineHttpHHTest03(void)
249 {
250  TcpSession ssn;
251  Packet *p = NULL;
252  ThreadVars th_v;
253  DetectEngineCtx *de_ctx = NULL;
254  DetectEngineThreadCtx *det_ctx = NULL;
255  HtpState *http_state = NULL;
256  Flow f;
257  uint8_t http_buf[] =
258  "GET /index.html HTTP/1.0\r\n"
259  "Host: CONNECT\r\n"
260  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
261  uint32_t http_len = sizeof(http_buf) - 1;
262  int result = 0;
264 
265  memset(&th_v, 0, sizeof(th_v));
266  memset(&f, 0, sizeof(f));
267  memset(&ssn, 0, sizeof(ssn));
268 
269  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
270 
271  FLOW_INITIALIZE(&f);
272  f.protoctx = (void *)&ssn;
273  f.proto = IPPROTO_TCP;
274  f.flags |= FLOW_IPV4;
275  p->flow = &f;
279  f.alproto = ALPROTO_HTTP;
280 
282 
283  de_ctx = DetectEngineCtxInit();
284  if (de_ctx == NULL)
285  goto end;
286 
287  de_ctx->flags |= DE_QUIET;
288 
289  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
290  "(msg:\"http_host header test\"; "
291  "content:!\"ect\"; depth:4; http_host; "
292  "sid:1;)");
293  if (de_ctx->sig_list == NULL)
294  goto end;
295 
296  SigGroupBuild(de_ctx);
297  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
298 
299  FLOWLOCK_WRLOCK(&f);
300  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
301  STREAM_TOSERVER, http_buf, http_len);
302  if (r != 0) {
303  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
304  result = 0;
305  FLOWLOCK_UNLOCK(&f);
306  goto end;
307  }
308  FLOWLOCK_UNLOCK(&f);
309 
310  http_state = f.alstate;
311  if (http_state == NULL) {
312  printf("no http state: ");
313  result = 0;
314  goto end;
315  }
316 
317  /* do detect */
318  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
319 
320  if (!(PacketAlertCheck(p, 1))) {
321  printf("sid 1 didn't match but should have: ");
322  goto end;
323  }
324 
325  result = 1;
326 
327 end:
328  if (alp_tctx != NULL)
329  AppLayerParserThreadCtxFree(alp_tctx);
330  if (de_ctx != NULL)
331  SigGroupCleanup(de_ctx);
332  if (de_ctx != NULL)
333  SigCleanSignatures(de_ctx);
334  if (de_ctx != NULL)
335  DetectEngineCtxFree(de_ctx);
336 
338  FLOW_DESTROY(&f);
339  UTHFreePackets(&p, 1);
340  return result;
341 }
342 
343 /**
344  * \test Test that the http_host content matches against a http request
345  * which holds the content.
346  */
347 static int DetectEngineHttpHHTest04(void)
348 {
349  TcpSession ssn;
350  Packet *p = NULL;
351  ThreadVars th_v;
352  DetectEngineCtx *de_ctx = NULL;
353  DetectEngineThreadCtx *det_ctx = NULL;
354  HtpState *http_state = NULL;
355  Flow f;
356  uint8_t http_buf[] =
357  "GET /index.html HTTP/1.0\r\n"
358  "Host: CONNECT\r\n"
359  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
360  uint32_t http_len = sizeof(http_buf) - 1;
361  int result = 0;
363 
364  memset(&th_v, 0, sizeof(th_v));
365  memset(&f, 0, sizeof(f));
366  memset(&ssn, 0, sizeof(ssn));
367 
368  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
369 
370  FLOW_INITIALIZE(&f);
371  f.protoctx = (void *)&ssn;
372  f.proto = IPPROTO_TCP;
373  f.flags |= FLOW_IPV4;
374  p->flow = &f;
378  f.alproto = ALPROTO_HTTP;
379 
381 
382  de_ctx = DetectEngineCtxInit();
383  if (de_ctx == NULL)
384  goto end;
385 
386  de_ctx->flags |= DE_QUIET;
387 
388  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
389  "(msg:\"http host header test\"; "
390  "content:\"ect\"; depth:4; http_host; "
391  "sid:1;)");
392  if (de_ctx->sig_list == NULL)
393  goto end;
394 
395  SigGroupBuild(de_ctx);
396  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
397 
398  FLOWLOCK_WRLOCK(&f);
399  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
400  STREAM_TOSERVER, http_buf, http_len);
401  if (r != 0) {
402  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
403  result = 0;
404  FLOWLOCK_UNLOCK(&f);
405  goto end;
406  }
407  FLOWLOCK_UNLOCK(&f);
408 
409  http_state = f.alstate;
410  if (http_state == NULL) {
411  printf("no http state: ");
412  result = 0;
413  goto end;
414  }
415 
416  /* do detect */
417  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
418 
419  if (PacketAlertCheck(p, 1)) {
420  printf("sid 1 matched but shouldn't have: ");
421  goto end;
422  }
423 
424  result = 1;
425 
426 end:
427  if (alp_tctx != NULL)
428  AppLayerParserThreadCtxFree(alp_tctx);
429  if (de_ctx != NULL)
430  SigGroupCleanup(de_ctx);
431  if (de_ctx != NULL)
432  SigCleanSignatures(de_ctx);
433  if (de_ctx != NULL)
434  DetectEngineCtxFree(de_ctx);
435 
437  FLOW_DESTROY(&f);
438  UTHFreePackets(&p, 1);
439  return result;
440 }
441 
442 /**
443  * \test Test that the http_host content matches against a http request
444  * which holds the content.
445  */
446 static int DetectEngineHttpHHTest05(void)
447 {
448  TcpSession ssn;
449  Packet *p = NULL;
450  ThreadVars th_v;
451  DetectEngineCtx *de_ctx = NULL;
452  DetectEngineThreadCtx *det_ctx = NULL;
453  HtpState *http_state = NULL;
454  Flow f;
455  uint8_t http_buf[] =
456  "GET /index.html HTTP/1.0\r\n"
457  "Host: CONNECT\r\n"
458  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
459  uint32_t http_len = sizeof(http_buf) - 1;
460  int result = 0;
462 
463  memset(&th_v, 0, sizeof(th_v));
464  memset(&f, 0, sizeof(f));
465  memset(&ssn, 0, sizeof(ssn));
466 
467  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
468 
469  FLOW_INITIALIZE(&f);
470  f.protoctx = (void *)&ssn;
471  f.proto = IPPROTO_TCP;
472  f.flags |= FLOW_IPV4;
473  p->flow = &f;
477  f.alproto = ALPROTO_HTTP;
478 
480 
481  de_ctx = DetectEngineCtxInit();
482  if (de_ctx == NULL)
483  goto end;
484 
485  de_ctx->flags |= DE_QUIET;
486 
487  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
488  "(msg:\"http host header test\"; "
489  "content:!\"con\"; depth:4; http_host; "
490  "sid:1;)");
491  if (de_ctx->sig_list == NULL)
492  goto end;
493 
494  SigGroupBuild(de_ctx);
495  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
496 
497  FLOWLOCK_WRLOCK(&f);
498  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
499  STREAM_TOSERVER, http_buf, http_len);
500  if (r != 0) {
501  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
502  result = 0;
503  FLOWLOCK_UNLOCK(&f);
504  goto end;
505  }
506  FLOWLOCK_UNLOCK(&f);
507 
508  http_state = f.alstate;
509  if (http_state == NULL) {
510  printf("no http state: ");
511  result = 0;
512  goto end;
513  }
514 
515  /* do detect */
516  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
517 
518  if (PacketAlertCheck(p, 1)) {
519  printf("sid 1 matched but shouldn't have: ");
520  goto end;
521  }
522 
523  result = 1;
524 
525 end:
526  if (alp_tctx != NULL)
527  AppLayerParserThreadCtxFree(alp_tctx);
528  if (de_ctx != NULL)
529  SigGroupCleanup(de_ctx);
530  if (de_ctx != NULL)
531  SigCleanSignatures(de_ctx);
532  if (de_ctx != NULL)
533  DetectEngineCtxFree(de_ctx);
534 
536  FLOW_DESTROY(&f);
537  UTHFreePackets(&p, 1);
538  return result;
539 }
540 
541 /**
542  * \test Test that the http_host header content matches against a http request
543  * which holds the content.
544  */
545 static int DetectEngineHttpHHTest06(void)
546 {
547  TcpSession ssn;
548  Packet *p = NULL;
549  ThreadVars th_v;
550  DetectEngineCtx *de_ctx = NULL;
551  DetectEngineThreadCtx *det_ctx = NULL;
552  HtpState *http_state = NULL;
553  Flow f;
554  uint8_t http_buf[] =
555  "GET /index.html HTTP/1.0\r\n"
556  "Host: CONNECT\r\n"
557  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
558  uint32_t http_len = sizeof(http_buf) - 1;
559  int result = 0;
561 
562  memset(&th_v, 0, sizeof(th_v));
563  memset(&f, 0, sizeof(f));
564  memset(&ssn, 0, sizeof(ssn));
565 
566  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
567 
568  FLOW_INITIALIZE(&f);
569  f.protoctx = (void *)&ssn;
570  f.proto = IPPROTO_TCP;
571  f.flags |= FLOW_IPV4;
572  p->flow = &f;
576  f.alproto = ALPROTO_HTTP;
577 
579 
580  de_ctx = DetectEngineCtxInit();
581  if (de_ctx == NULL)
582  goto end;
583 
584  de_ctx->flags |= DE_QUIET;
585 
586  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
587  "(msg:\"http host header test\"; "
588  "content:\"ect\"; offset:3; http_host; "
589  "sid:1;)");
590  if (de_ctx->sig_list == NULL)
591  goto end;
592 
593  SigGroupBuild(de_ctx);
594  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
595 
596  FLOWLOCK_WRLOCK(&f);
597  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
598  STREAM_TOSERVER, http_buf, http_len);
599  if (r != 0) {
600  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
601  result = 0;
602  FLOWLOCK_UNLOCK(&f);
603  goto end;
604  }
605  FLOWLOCK_UNLOCK(&f);
606 
607  http_state = f.alstate;
608  if (http_state == NULL) {
609  printf("no http state: ");
610  result = 0;
611  goto end;
612  }
613 
614  /* do detect */
615  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
616 
617  if (!(PacketAlertCheck(p, 1))) {
618  printf("sid 1 didn't match but should have: ");
619  goto end;
620  }
621 
622  result = 1;
623 
624 end:
625  if (alp_tctx != NULL)
626  AppLayerParserThreadCtxFree(alp_tctx);
627  if (de_ctx != NULL)
628  SigGroupCleanup(de_ctx);
629  if (de_ctx != NULL)
630  SigCleanSignatures(de_ctx);
631  if (de_ctx != NULL)
632  DetectEngineCtxFree(de_ctx);
633 
635  FLOW_DESTROY(&f);
636  UTHFreePackets(&p, 1);
637  return result;
638 }
639 
640 /**
641  * \test Test that the http_host content matches against a http request
642  * which holds the content.
643  */
644 static int DetectEngineHttpHHTest07(void)
645 {
646  TcpSession ssn;
647  Packet *p = NULL;
648  ThreadVars th_v;
649  DetectEngineCtx *de_ctx = NULL;
650  DetectEngineThreadCtx *det_ctx = NULL;
651  HtpState *http_state = NULL;
652  Flow f;
653  uint8_t http_buf[] =
654  "GET /index.html HTTP/1.0\r\n"
655  "Host: CONNECT\r\n"
656  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
657  uint32_t http_len = sizeof(http_buf) - 1;
658  int result = 0;
660 
661  memset(&th_v, 0, sizeof(th_v));
662  memset(&f, 0, sizeof(f));
663  memset(&ssn, 0, sizeof(ssn));
664 
665  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
666 
667  FLOW_INITIALIZE(&f);
668  f.protoctx = (void *)&ssn;
669  f.proto = IPPROTO_TCP;
670  f.flags |= FLOW_IPV4;
671  p->flow = &f;
675  f.alproto = ALPROTO_HTTP;
676 
678 
679  de_ctx = DetectEngineCtxInit();
680  if (de_ctx == NULL)
681  goto end;
682 
683  de_ctx->flags |= DE_QUIET;
684 
685  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
686  "(msg:\"http host header test\"; "
687  "content:!\"co\"; offset:3; http_host; "
688  "sid:1;)");
689  if (de_ctx->sig_list == NULL)
690  goto end;
691 
692  SigGroupBuild(de_ctx);
693  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
694 
695  FLOWLOCK_WRLOCK(&f);
696  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
697  STREAM_TOSERVER, http_buf, http_len);
698  if (r != 0) {
699  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
700  result = 0;
701  FLOWLOCK_UNLOCK(&f);
702  goto end;
703  }
704  FLOWLOCK_UNLOCK(&f);
705 
706  http_state = f.alstate;
707  if (http_state == NULL) {
708  printf("no http state: ");
709  result = 0;
710  goto end;
711  }
712 
713  /* do detect */
714  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
715 
716  if (!(PacketAlertCheck(p, 1))) {
717  printf("sid 1 didn't match but should have: ");
718  goto end;
719  }
720 
721  result = 1;
722 
723 end:
724  if (alp_tctx != NULL)
725  AppLayerParserThreadCtxFree(alp_tctx);
726  if (de_ctx != NULL)
727  SigGroupCleanup(de_ctx);
728  if (de_ctx != NULL)
729  SigCleanSignatures(de_ctx);
730  if (de_ctx != NULL)
731  DetectEngineCtxFree(de_ctx);
732 
734  FLOW_DESTROY(&f);
735  UTHFreePackets(&p, 1);
736  return result;
737 }
738 
739 /**
740  * \test Test that the http_host header content matches against a http request
741  * which holds the content.
742  */
743 static int DetectEngineHttpHHTest08(void)
744 {
745  TcpSession ssn;
746  Packet *p = NULL;
747  ThreadVars th_v;
748  DetectEngineCtx *de_ctx = NULL;
749  DetectEngineThreadCtx *det_ctx = NULL;
750  HtpState *http_state = NULL;
751  Flow f;
752  uint8_t http_buf[] =
753  "GET /index.html HTTP/1.0\r\n"
754  "Host: CONNECT\r\n"
755  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
756  uint32_t http_len = sizeof(http_buf) - 1;
757  int result = 0;
759 
760  memset(&th_v, 0, sizeof(th_v));
761  memset(&f, 0, sizeof(f));
762  memset(&ssn, 0, sizeof(ssn));
763 
764  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
765 
766  FLOW_INITIALIZE(&f);
767  f.protoctx = (void *)&ssn;
768  f.proto = IPPROTO_TCP;
769  f.flags |= FLOW_IPV4;
770  p->flow = &f;
774  f.alproto = ALPROTO_HTTP;
775 
777 
778  de_ctx = DetectEngineCtxInit();
779  if (de_ctx == NULL)
780  goto end;
781 
782  de_ctx->flags |= DE_QUIET;
783 
784  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
785  "(msg:\"http host header test\"; "
786  "content:!\"ect\"; offset:3; http_host; "
787  "sid:1;)");
788  if (de_ctx->sig_list == NULL)
789  goto end;
790 
791  SigGroupBuild(de_ctx);
792  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
793 
794  FLOWLOCK_WRLOCK(&f);
795  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
796  STREAM_TOSERVER, http_buf, http_len);
797  if (r != 0) {
798  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
799  result = 0;
800  FLOWLOCK_UNLOCK(&f);
801  goto end;
802  }
803  FLOWLOCK_UNLOCK(&f);
804 
805  http_state = f.alstate;
806  if (http_state == NULL) {
807  printf("no http state: ");
808  result = 0;
809  goto end;
810  }
811 
812  /* do detect */
813  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
814 
815  if (PacketAlertCheck(p, 1)) {
816  printf("sid 1 matched but shouldn't have: ");
817  goto end;
818  }
819 
820  result = 1;
821 
822 end:
823  if (alp_tctx != NULL)
824  AppLayerParserThreadCtxFree(alp_tctx);
825  if (de_ctx != NULL)
826  SigGroupCleanup(de_ctx);
827  if (de_ctx != NULL)
828  SigCleanSignatures(de_ctx);
829  if (de_ctx != NULL)
830  DetectEngineCtxFree(de_ctx);
831 
833  FLOW_DESTROY(&f);
834  UTHFreePackets(&p, 1);
835  return result;
836 }
837 
838 /**
839  * \test Test that the http_host header content matches against a http request
840  * which holds the content.
841  */
842 static int DetectEngineHttpHHTest09(void)
843 {
844  TcpSession ssn;
845  Packet *p = NULL;
846  ThreadVars th_v;
847  DetectEngineCtx *de_ctx = NULL;
848  DetectEngineThreadCtx *det_ctx = NULL;
849  HtpState *http_state = NULL;
850  Flow f;
851  uint8_t http_buf[] =
852  "GET /index.html HTTP/1.0\r\n"
853  "Host: CONNECT\r\n"
854  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
855  uint32_t http_len = sizeof(http_buf) - 1;
856  int result = 0;
858 
859  memset(&th_v, 0, sizeof(th_v));
860  memset(&f, 0, sizeof(f));
861  memset(&ssn, 0, sizeof(ssn));
862 
863  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
864 
865  FLOW_INITIALIZE(&f);
866  f.protoctx = (void *)&ssn;
867  f.proto = IPPROTO_TCP;
868  f.flags |= FLOW_IPV4;
869  p->flow = &f;
873  f.alproto = ALPROTO_HTTP;
874 
876 
877  de_ctx = DetectEngineCtxInit();
878  if (de_ctx == NULL)
879  goto end;
880 
881  de_ctx->flags |= DE_QUIET;
882 
883  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
884  "(msg:\"http host header test\"; "
885  "content:\"con\"; offset:3; http_host; "
886  "sid:1;)");
887  if (de_ctx->sig_list == NULL)
888  goto end;
889 
890  SigGroupBuild(de_ctx);
891  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
892 
893  FLOWLOCK_WRLOCK(&f);
894  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
895  STREAM_TOSERVER, http_buf, http_len);
896  if (r != 0) {
897  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
898  result = 0;
899  FLOWLOCK_UNLOCK(&f);
900  goto end;
901  }
902  FLOWLOCK_UNLOCK(&f);
903 
904  http_state = f.alstate;
905  if (http_state == NULL) {
906  printf("no http state: ");
907  result = 0;
908  goto end;
909  }
910 
911  /* do detect */
912  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
913 
914  if (PacketAlertCheck(p, 1)) {
915  printf("sid 1 matched but shouldn't have: ");
916  goto end;
917  }
918 
919  result = 1;
920 
921 end:
922  if (alp_tctx != NULL)
923  AppLayerParserThreadCtxFree(alp_tctx);
924  if (de_ctx != NULL)
925  SigGroupCleanup(de_ctx);
926  if (de_ctx != NULL)
927  SigCleanSignatures(de_ctx);
928  if (de_ctx != NULL)
929  DetectEngineCtxFree(de_ctx);
930 
932  FLOW_DESTROY(&f);
933  UTHFreePackets(&p, 1);
934  return result;
935 }
936 
937 /**
938  * \test Test that the http_host header content matches against a http request
939  * which holds the content.
940  */
941 static int DetectEngineHttpHHTest10(void)
942 {
943  TcpSession ssn;
944  Packet *p = NULL;
945  ThreadVars th_v;
946  DetectEngineCtx *de_ctx = NULL;
947  DetectEngineThreadCtx *det_ctx = NULL;
948  HtpState *http_state = NULL;
949  Flow f;
950  uint8_t http_buf[] =
951  "GET /index.html HTTP/1.0\r\n"
952  "Host: CONNECT\r\n"
953  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
954  uint32_t http_len = sizeof(http_buf) - 1;
955  int result = 0;
957 
958  memset(&th_v, 0, sizeof(th_v));
959  memset(&f, 0, sizeof(f));
960  memset(&ssn, 0, sizeof(ssn));
961 
962  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
963 
964  FLOW_INITIALIZE(&f);
965  f.protoctx = (void *)&ssn;
966  f.proto = IPPROTO_TCP;
967  f.flags |= FLOW_IPV4;
968  p->flow = &f;
972  f.alproto = ALPROTO_HTTP;
973 
975 
976  de_ctx = DetectEngineCtxInit();
977  if (de_ctx == NULL)
978  goto end;
979 
980  de_ctx->flags |= DE_QUIET;
981 
982  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
983  "(msg:\"http_host header test\"; "
984  "content:\"co\"; http_host; "
985  "content:\"ec\"; within:4; http_host; "
986  "sid:1;)");
987  if (de_ctx->sig_list == NULL)
988  goto end;
989 
990  SigGroupBuild(de_ctx);
991  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
992 
993  FLOWLOCK_WRLOCK(&f);
994  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
995  STREAM_TOSERVER, http_buf, http_len);
996  if (r != 0) {
997  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
998  result = 0;
999  FLOWLOCK_UNLOCK(&f);
1000  goto end;
1001  }
1002  FLOWLOCK_UNLOCK(&f);
1003 
1004  http_state = f.alstate;
1005  if (http_state == NULL) {
1006  printf("no http state: ");
1007  result = 0;
1008  goto end;
1009  }
1010 
1011  /* do detect */
1012  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1013 
1014  if (!PacketAlertCheck(p, 1)) {
1015  printf("sid 1 didn't match but should have: ");
1016  goto end;
1017  }
1018 
1019  result = 1;
1020 
1021 end:
1022  if (alp_tctx != NULL)
1023  AppLayerParserThreadCtxFree(alp_tctx);
1024  if (de_ctx != NULL)
1025  SigGroupCleanup(de_ctx);
1026  if (de_ctx != NULL)
1027  SigCleanSignatures(de_ctx);
1028  if (de_ctx != NULL)
1029  DetectEngineCtxFree(de_ctx);
1030 
1032  FLOW_DESTROY(&f);
1033  UTHFreePackets(&p, 1);
1034  return result;
1035 }
1036 
1037 /**
1038  * \test Test that the http_host header content matches against a http request
1039  * which holds the content.
1040  */
1041 static int DetectEngineHttpHHTest11(void)
1042 {
1043  TcpSession ssn;
1044  Packet *p = NULL;
1045  ThreadVars th_v;
1046  DetectEngineCtx *de_ctx = NULL;
1047  DetectEngineThreadCtx *det_ctx = NULL;
1048  HtpState *http_state = NULL;
1049  Flow f;
1050  uint8_t http_buf[] =
1051  "GET /index.html HTTP/1.0\r\n"
1052  "Host: CONNECT\r\n"
1053  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1054  uint32_t http_len = sizeof(http_buf) - 1;
1055  int result = 0;
1057 
1058  memset(&th_v, 0, sizeof(th_v));
1059  memset(&f, 0, sizeof(f));
1060  memset(&ssn, 0, sizeof(ssn));
1061 
1062  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1063 
1064  FLOW_INITIALIZE(&f);
1065  f.protoctx = (void *)&ssn;
1066  f.proto = IPPROTO_TCP;
1067  f.flags |= FLOW_IPV4;
1068  p->flow = &f;
1072  f.alproto = ALPROTO_HTTP;
1073 
1075 
1076  de_ctx = DetectEngineCtxInit();
1077  if (de_ctx == NULL)
1078  goto end;
1079 
1080  de_ctx->flags |= DE_QUIET;
1081 
1082  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1083  "(msg:\"http_host header test\"; "
1084  "content:\"co\"; http_host; "
1085  "content:!\"ec\"; within:3; http_host; "
1086  "sid:1;)");
1087  if (de_ctx->sig_list == NULL)
1088  goto end;
1089 
1090  SigGroupBuild(de_ctx);
1091  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1092 
1093  FLOWLOCK_WRLOCK(&f);
1094  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1095  STREAM_TOSERVER, http_buf, http_len);
1096  if (r != 0) {
1097  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1098  result = 0;
1099  FLOWLOCK_UNLOCK(&f);
1100  goto end;
1101  }
1102  FLOWLOCK_UNLOCK(&f);
1103 
1104  http_state = f.alstate;
1105  if (http_state == NULL) {
1106  printf("no http state: ");
1107  result = 0;
1108  goto end;
1109  }
1110 
1111  /* do detect */
1112  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1113 
1114  if (!PacketAlertCheck(p, 1)) {
1115  printf("sid 1 didn't match but should have: ");
1116  goto end;
1117  }
1118 
1119  result = 1;
1120 
1121 end:
1122  if (alp_tctx != NULL)
1123  AppLayerParserThreadCtxFree(alp_tctx);
1124  if (de_ctx != NULL)
1125  SigGroupCleanup(de_ctx);
1126  if (de_ctx != NULL)
1127  SigCleanSignatures(de_ctx);
1128  if (de_ctx != NULL)
1129  DetectEngineCtxFree(de_ctx);
1130 
1132  FLOW_DESTROY(&f);
1133  UTHFreePackets(&p, 1);
1134  return result;
1135 }
1136 
1137 /**
1138  * \test Test that the http_host header content matches against a http request
1139  * which holds the content.
1140  */
1141 static int DetectEngineHttpHHTest12(void)
1142 {
1143  TcpSession ssn;
1144  Packet *p = NULL;
1145  ThreadVars th_v;
1146  DetectEngineCtx *de_ctx = NULL;
1147  DetectEngineThreadCtx *det_ctx = NULL;
1148  HtpState *http_state = NULL;
1149  Flow f;
1150  uint8_t http_buf[] =
1151  "GET /index.html HTTP/1.0\r\n"
1152  "Host: CONNECT\r\n"
1153  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1154  uint32_t http_len = sizeof(http_buf) - 1;
1155  int result = 0;
1157 
1158  memset(&th_v, 0, sizeof(th_v));
1159  memset(&f, 0, sizeof(f));
1160  memset(&ssn, 0, sizeof(ssn));
1161 
1162  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1163 
1164  FLOW_INITIALIZE(&f);
1165  f.protoctx = (void *)&ssn;
1166  f.proto = IPPROTO_TCP;
1167  f.flags |= FLOW_IPV4;
1168  p->flow = &f;
1172  f.alproto = ALPROTO_HTTP;
1173 
1175 
1176  de_ctx = DetectEngineCtxInit();
1177  if (de_ctx == NULL)
1178  goto end;
1179 
1180  de_ctx->flags |= DE_QUIET;
1181 
1182  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1183  "(msg:\"http_host header test\"; "
1184  "content:\"co\"; http_host; "
1185  "content:\"ec\"; within:3; http_host; "
1186  "sid:1;)");
1187  if (de_ctx->sig_list == NULL)
1188  goto end;
1189 
1190  SigGroupBuild(de_ctx);
1191  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1192 
1193  FLOWLOCK_WRLOCK(&f);
1194  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1195  STREAM_TOSERVER, http_buf, http_len);
1196  if (r != 0) {
1197  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1198  result = 0;
1199  FLOWLOCK_UNLOCK(&f);
1200  goto end;
1201  }
1202  FLOWLOCK_UNLOCK(&f);
1203 
1204  http_state = f.alstate;
1205  if (http_state == NULL) {
1206  printf("no http state: ");
1207  result = 0;
1208  goto end;
1209  }
1210 
1211  /* do detect */
1212  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1213 
1214  if (PacketAlertCheck(p, 1)) {
1215  printf("sid 1 matched but shouldn't have: ");
1216  goto end;
1217  }
1218 
1219  result = 1;
1220 
1221 end:
1222  if (alp_tctx != NULL)
1223  AppLayerParserThreadCtxFree(alp_tctx);
1224  if (de_ctx != NULL)
1225  SigGroupCleanup(de_ctx);
1226  if (de_ctx != NULL)
1227  SigCleanSignatures(de_ctx);
1228  if (de_ctx != NULL)
1229  DetectEngineCtxFree(de_ctx);
1230 
1232  FLOW_DESTROY(&f);
1233  UTHFreePackets(&p, 1);
1234  return result;
1235 }
1236 
1237 /**
1238  * \test Test that the http_host header content matches against a http request
1239  * which holds the content.
1240  */
1241 static int DetectEngineHttpHHTest13(void)
1242 {
1243  TcpSession ssn;
1244  Packet *p = NULL;
1245  ThreadVars th_v;
1246  DetectEngineCtx *de_ctx = NULL;
1247  DetectEngineThreadCtx *det_ctx = NULL;
1248  HtpState *http_state = NULL;
1249  Flow f;
1250  uint8_t http_buf[] =
1251  "GET /index.html HTTP/1.0\r\n"
1252  "Host: CONNECT\r\n"
1253  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1254  uint32_t http_len = sizeof(http_buf) - 1;
1255  int result = 0;
1257 
1258  memset(&th_v, 0, sizeof(th_v));
1259  memset(&f, 0, sizeof(f));
1260  memset(&ssn, 0, sizeof(ssn));
1261 
1262  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1263 
1264  FLOW_INITIALIZE(&f);
1265  f.protoctx = (void *)&ssn;
1266  f.proto = IPPROTO_TCP;
1267  f.flags |= FLOW_IPV4;
1268  p->flow = &f;
1272  f.alproto = ALPROTO_HTTP;
1273 
1275 
1276  de_ctx = DetectEngineCtxInit();
1277  if (de_ctx == NULL)
1278  goto end;
1279 
1280  de_ctx->flags |= DE_QUIET;
1281 
1282  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1283  "(msg:\"http_host header test\"; "
1284  "content:\"co\"; http_host; "
1285  "content:!\"ec\"; within:4; http_host; "
1286  "sid:1;)");
1287  if (de_ctx->sig_list == NULL)
1288  goto end;
1289 
1290  SigGroupBuild(de_ctx);
1291  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1292 
1293  FLOWLOCK_WRLOCK(&f);
1294  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1295  STREAM_TOSERVER, http_buf, http_len);
1296  if (r != 0) {
1297  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1298  result = 0;
1299  FLOWLOCK_UNLOCK(&f);
1300  goto end;
1301  }
1302  FLOWLOCK_UNLOCK(&f);
1303 
1304  http_state = f.alstate;
1305  if (http_state == NULL) {
1306  printf("no http state: ");
1307  result = 0;
1308  goto end;
1309  }
1310 
1311  /* do detect */
1312  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1313 
1314  if (PacketAlertCheck(p, 1)) {
1315  printf("sid 1 matched but shouldn't have: ");
1316  goto end;
1317  }
1318 
1319  result = 1;
1320 
1321 end:
1322  if (alp_tctx != NULL)
1323  AppLayerParserThreadCtxFree(alp_tctx);
1324  if (de_ctx != NULL)
1325  SigGroupCleanup(de_ctx);
1326  if (de_ctx != NULL)
1327  SigCleanSignatures(de_ctx);
1328  if (de_ctx != NULL)
1329  DetectEngineCtxFree(de_ctx);
1330 
1332  FLOW_DESTROY(&f);
1333  UTHFreePackets(&p, 1);
1334  return result;
1335 }
1336 
1337 /**
1338  * \test Test that the http_host header content matches against a http request
1339  * which holds the content.
1340  */
1341 static int DetectEngineHttpHHTest14(void)
1342 {
1343  TcpSession ssn;
1344  Packet *p = NULL;
1345  ThreadVars th_v;
1346  DetectEngineCtx *de_ctx = NULL;
1347  DetectEngineThreadCtx *det_ctx = NULL;
1348  HtpState *http_state = NULL;
1349  Flow f;
1350  uint8_t http_buf[] =
1351  "GET /index.html HTTP/1.0\r\n"
1352  "Host: CONNECT\r\n"
1353  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1354  uint32_t http_len = sizeof(http_buf) - 1;
1355  int result = 0;
1357 
1358  memset(&th_v, 0, sizeof(th_v));
1359  memset(&f, 0, sizeof(f));
1360  memset(&ssn, 0, sizeof(ssn));
1361 
1362  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1363 
1364  FLOW_INITIALIZE(&f);
1365  f.protoctx = (void *)&ssn;
1366  f.proto = IPPROTO_TCP;
1367  f.flags |= FLOW_IPV4;
1368  p->flow = &f;
1372  f.alproto = ALPROTO_HTTP;
1373 
1375 
1376  de_ctx = DetectEngineCtxInit();
1377  if (de_ctx == NULL)
1378  goto end;
1379 
1380  de_ctx->flags |= DE_QUIET;
1381 
1382  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1383  "(msg:\"http_host header test\"; "
1384  "content:\"co\"; http_host; "
1385  "content:\"ec\"; distance:2; http_host; "
1386  "sid:1;)");
1387  if (de_ctx->sig_list == NULL)
1388  goto end;
1389 
1390  SigGroupBuild(de_ctx);
1391  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1392 
1393  FLOWLOCK_WRLOCK(&f);
1394  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1395  STREAM_TOSERVER, http_buf, http_len);
1396  if (r != 0) {
1397  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1398  result = 0;
1399  FLOWLOCK_UNLOCK(&f);
1400  goto end;
1401  }
1402  FLOWLOCK_UNLOCK(&f);
1403 
1404  http_state = f.alstate;
1405  if (http_state == NULL) {
1406  printf("no http state: ");
1407  result = 0;
1408  goto end;
1409  }
1410 
1411  /* do detect */
1412  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1413 
1414  if (!PacketAlertCheck(p, 1)) {
1415  printf("sid 1 didn't match but should have: ");
1416  goto end;
1417  }
1418 
1419  result = 1;
1420 
1421 end:
1422  if (alp_tctx != NULL)
1423  AppLayerParserThreadCtxFree(alp_tctx);
1424  if (de_ctx != NULL)
1425  SigGroupCleanup(de_ctx);
1426  if (de_ctx != NULL)
1427  SigCleanSignatures(de_ctx);
1428  if (de_ctx != NULL)
1429  DetectEngineCtxFree(de_ctx);
1430 
1432  FLOW_DESTROY(&f);
1433  UTHFreePackets(&p, 1);
1434  return result;
1435 }
1436 
1437 /**
1438  * \test Test that the http_host header content matches against a http request
1439  * which holds the content.
1440  */
1441 static int DetectEngineHttpHHTest15(void)
1442 {
1443  TcpSession ssn;
1444  Packet *p = NULL;
1445  ThreadVars th_v;
1446  DetectEngineCtx *de_ctx = NULL;
1447  DetectEngineThreadCtx *det_ctx = NULL;
1448  HtpState *http_state = NULL;
1449  Flow f;
1450  uint8_t http_buf[] =
1451  "GET /index.html HTTP/1.0\r\n"
1452  "Host: CONNECT\r\n"
1453  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1454  uint32_t http_len = sizeof(http_buf) - 1;
1455  int result = 0;
1457 
1458  memset(&th_v, 0, sizeof(th_v));
1459  memset(&f, 0, sizeof(f));
1460  memset(&ssn, 0, sizeof(ssn));
1461 
1462  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1463 
1464  FLOW_INITIALIZE(&f);
1465  f.protoctx = (void *)&ssn;
1466  f.proto = IPPROTO_TCP;
1467  f.flags |= FLOW_IPV4;
1468  p->flow = &f;
1472  f.alproto = ALPROTO_HTTP;
1473 
1475 
1476  de_ctx = DetectEngineCtxInit();
1477  if (de_ctx == NULL)
1478  goto end;
1479 
1480  de_ctx->flags |= DE_QUIET;
1481 
1482  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1483  "(msg:\"http_host header test\"; "
1484  "content:\"co\"; http_host; "
1485  "content:!\"ec\"; distance:3; http_host; "
1486  "sid:1;)");
1487  if (de_ctx->sig_list == NULL)
1488  goto end;
1489 
1490  SigGroupBuild(de_ctx);
1491  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1492 
1493  FLOWLOCK_WRLOCK(&f);
1494  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1495  STREAM_TOSERVER, http_buf, http_len);
1496  if (r != 0) {
1497  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1498  result = 0;
1499  FLOWLOCK_UNLOCK(&f);
1500  goto end;
1501  }
1502  FLOWLOCK_UNLOCK(&f);
1503 
1504  http_state = f.alstate;
1505  if (http_state == NULL) {
1506  printf("no http state: ");
1507  result = 0;
1508  goto end;
1509  }
1510 
1511  /* do detect */
1512  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1513 
1514  if (!PacketAlertCheck(p, 1)) {
1515  printf("sid 1 didn't match but should have: ");
1516  goto end;
1517  }
1518 
1519  result = 1;
1520 
1521 end:
1522  if (alp_tctx != NULL)
1523  AppLayerParserThreadCtxFree(alp_tctx);
1524  if (de_ctx != NULL)
1525  SigGroupCleanup(de_ctx);
1526  if (de_ctx != NULL)
1527  SigCleanSignatures(de_ctx);
1528  if (de_ctx != NULL)
1529  DetectEngineCtxFree(de_ctx);
1530 
1532  FLOW_DESTROY(&f);
1533  UTHFreePackets(&p, 1);
1534  return result;
1535 }
1536 
1537 /**
1538  * \test Test that the http_host header content matches against a http request
1539  * which holds the content.
1540  */
1541 static int DetectEngineHttpHHTest16(void)
1542 {
1543  TcpSession ssn;
1544  Packet *p = NULL;
1545  ThreadVars th_v;
1546  DetectEngineCtx *de_ctx = NULL;
1547  DetectEngineThreadCtx *det_ctx = NULL;
1548  HtpState *http_state = NULL;
1549  Flow f;
1550  uint8_t http_buf[] =
1551  "GET /index.html HTTP/1.0\r\n"
1552  "Host: CONNECT\r\n"
1553  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1554  uint32_t http_len = sizeof(http_buf) - 1;
1555  int result = 0;
1557 
1558  memset(&th_v, 0, sizeof(th_v));
1559  memset(&f, 0, sizeof(f));
1560  memset(&ssn, 0, sizeof(ssn));
1561 
1562  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1563 
1564  FLOW_INITIALIZE(&f);
1565  f.protoctx = (void *)&ssn;
1566  f.proto = IPPROTO_TCP;
1567  f.flags |= FLOW_IPV4;
1568  p->flow = &f;
1572  f.alproto = ALPROTO_HTTP;
1573 
1575 
1576  de_ctx = DetectEngineCtxInit();
1577  if (de_ctx == NULL)
1578  goto end;
1579 
1580  de_ctx->flags |= DE_QUIET;
1581 
1582  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1583  "(msg:\"http_host header test\"; "
1584  "content:\"co\"; http_host; "
1585  "content:\"ec\"; distance:3; http_host; "
1586  "sid:1;)");
1587  if (de_ctx->sig_list == NULL)
1588  goto end;
1589 
1590  SigGroupBuild(de_ctx);
1591  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1592 
1593  FLOWLOCK_WRLOCK(&f);
1594  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1595  STREAM_TOSERVER, http_buf, http_len);
1596  if (r != 0) {
1597  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1598  result = 0;
1599  FLOWLOCK_UNLOCK(&f);
1600  goto end;
1601  }
1602  FLOWLOCK_UNLOCK(&f);
1603 
1604  http_state = f.alstate;
1605  if (http_state == NULL) {
1606  printf("no http state: ");
1607  result = 0;
1608  goto end;
1609  }
1610 
1611  /* do detect */
1612  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1613 
1614  if (PacketAlertCheck(p, 1)) {
1615  printf("sid 1 matched but shouldn't have: ");
1616  goto end;
1617  }
1618 
1619  result = 1;
1620 
1621 end:
1622  if (alp_tctx != NULL)
1623  AppLayerParserThreadCtxFree(alp_tctx);
1624  if (de_ctx != NULL)
1625  SigGroupCleanup(de_ctx);
1626  if (de_ctx != NULL)
1627  SigCleanSignatures(de_ctx);
1628  if (de_ctx != NULL)
1629  DetectEngineCtxFree(de_ctx);
1630 
1632  FLOW_DESTROY(&f);
1633  UTHFreePackets(&p, 1);
1634  return result;
1635 }
1636 
1637 /**
1638  * \test Test that the http_host header content matches against a http request
1639  * which holds the content.
1640  */
1641 static int DetectEngineHttpHHTest17(void)
1642 {
1643  TcpSession ssn;
1644  Packet *p = NULL;
1645  ThreadVars th_v;
1646  DetectEngineCtx *de_ctx = NULL;
1647  DetectEngineThreadCtx *det_ctx = NULL;
1648  HtpState *http_state = NULL;
1649  Flow f;
1650  uint8_t http_buf[] =
1651  "GET /index.html HTTP/1.0\r\n"
1652  "Host: CONNECT\r\n"
1653  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1654  uint32_t http_len = sizeof(http_buf) - 1;
1655  int result = 0;
1657 
1658  memset(&th_v, 0, sizeof(th_v));
1659  memset(&f, 0, sizeof(f));
1660  memset(&ssn, 0, sizeof(ssn));
1661 
1662  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1663 
1664  FLOW_INITIALIZE(&f);
1665  f.protoctx = (void *)&ssn;
1666  f.proto = IPPROTO_TCP;
1667  f.flags |= FLOW_IPV4;
1668  p->flow = &f;
1672  f.alproto = ALPROTO_HTTP;
1673 
1675 
1676  de_ctx = DetectEngineCtxInit();
1677  if (de_ctx == NULL)
1678  goto end;
1679 
1680  de_ctx->flags |= DE_QUIET;
1681 
1682  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1683  "(msg:\"http_host header test\"; "
1684  "content:\"co\"; http_host; "
1685  "content:!\"ec\"; distance:2; http_host; "
1686  "sid:1;)");
1687  if (de_ctx->sig_list == NULL)
1688  goto end;
1689 
1690  SigGroupBuild(de_ctx);
1691  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1692 
1693  FLOWLOCK_WRLOCK(&f);
1694  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1695  STREAM_TOSERVER, http_buf, http_len);
1696  if (r != 0) {
1697  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1698  result = 0;
1699  FLOWLOCK_UNLOCK(&f);
1700  goto end;
1701  }
1702  FLOWLOCK_UNLOCK(&f);
1703 
1704  http_state = f.alstate;
1705  if (http_state == NULL) {
1706  printf("no http state: ");
1707  result = 0;
1708  goto end;
1709  }
1710 
1711  /* do detect */
1712  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1713 
1714  if (PacketAlertCheck(p, 1)) {
1715  printf("sid 1 matched but shouldn't have: ");
1716  goto end;
1717  }
1718 
1719  result = 1;
1720 
1721 end:
1722  if (alp_tctx != NULL)
1723  AppLayerParserThreadCtxFree(alp_tctx);
1724  if (de_ctx != NULL)
1725  SigGroupCleanup(de_ctx);
1726  if (de_ctx != NULL)
1727  SigCleanSignatures(de_ctx);
1728  if (de_ctx != NULL)
1729  DetectEngineCtxFree(de_ctx);
1730 
1732  FLOW_DESTROY(&f);
1733  UTHFreePackets(&p, 1);
1734  return result;
1735 }
1736 
1737 static int DetectEngineHttpHHTest18(void)
1738 {
1739  TcpSession ssn;
1740  Packet *p = NULL;
1741  ThreadVars th_v;
1742  DetectEngineCtx *de_ctx = NULL;
1743  DetectEngineThreadCtx *det_ctx = NULL;
1744  HtpState *http_state = NULL;
1745  Flow f;
1746  uint8_t http_buf[] =
1747  "GET /index.html HTTP/1.0\r\n"
1748  "Host: www.kaboom.com\r\n"
1749  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1750  uint32_t http_len = sizeof(http_buf) - 1;
1751  int result = 0;
1753 
1754  memset(&th_v, 0, sizeof(th_v));
1755  memset(&f, 0, sizeof(f));
1756  memset(&ssn, 0, sizeof(ssn));
1757 
1758  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1759 
1760  FLOW_INITIALIZE(&f);
1761  f.protoctx = (void *)&ssn;
1762  f.proto = IPPROTO_TCP;
1763  f.flags |= FLOW_IPV4;
1764  p->flow = &f;
1768  f.alproto = ALPROTO_HTTP;
1769 
1771 
1772  de_ctx = DetectEngineCtxInit();
1773  if (de_ctx == NULL)
1774  goto end;
1775 
1776  de_ctx->flags |= DE_QUIET;
1777 
1778  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1779  "(msg:\"http_host header test\"; "
1780  "content:\"kaboom\"; http_host; "
1781  "sid:1;)");
1782  if (de_ctx->sig_list == NULL)
1783  goto end;
1784 
1785  SigGroupBuild(de_ctx);
1786  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1787 
1788  FLOWLOCK_WRLOCK(&f);
1789  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1790  STREAM_TOSERVER, http_buf, http_len);
1791  if (r != 0) {
1792  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1793  result = 0;
1794  FLOWLOCK_UNLOCK(&f);
1795  goto end;
1796  }
1797  FLOWLOCK_UNLOCK(&f);
1798 
1799  http_state = f.alstate;
1800  if (http_state == NULL) {
1801  printf("no http state: ");
1802  result = 0;
1803  goto end;
1804  }
1805 
1806  /* do detect */
1807  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1808 
1809  if (!PacketAlertCheck(p, 1)) {
1810  printf("sid 1 didn't match but should have: ");
1811  goto end;
1812  }
1813 
1814  result = 1;
1815 
1816 end:
1817  if (alp_tctx != NULL)
1818  AppLayerParserThreadCtxFree(alp_tctx);
1819  if (de_ctx != NULL)
1820  SigGroupCleanup(de_ctx);
1821  if (de_ctx != NULL)
1822  SigCleanSignatures(de_ctx);
1823  if (de_ctx != NULL)
1824  DetectEngineCtxFree(de_ctx);
1825 
1827  FLOW_DESTROY(&f);
1828  UTHFreePackets(&p, 1);
1829  return result;
1830 }
1831 
1832 static int DetectEngineHttpHHTest19(void)
1833 {
1834  TcpSession ssn;
1835  Packet *p = NULL;
1836  ThreadVars th_v;
1837  DetectEngineCtx *de_ctx = NULL;
1838  DetectEngineThreadCtx *det_ctx = NULL;
1839  HtpState *http_state = NULL;
1840  Flow f;
1841  uint8_t http_buf[] =
1842  "GET /index.html HTTP/1.0\r\n"
1843  "Host: www.kaboom.com:8080\r\n"
1844  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1845  uint32_t http_len = sizeof(http_buf) - 1;
1846  int result = 0;
1848 
1849  memset(&th_v, 0, sizeof(th_v));
1850  memset(&f, 0, sizeof(f));
1851  memset(&ssn, 0, sizeof(ssn));
1852 
1853  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1854 
1855  FLOW_INITIALIZE(&f);
1856  f.protoctx = (void *)&ssn;
1857  f.proto = IPPROTO_TCP;
1858  f.flags |= FLOW_IPV4;
1859  p->flow = &f;
1863  f.alproto = ALPROTO_HTTP;
1864 
1866 
1867  de_ctx = DetectEngineCtxInit();
1868  if (de_ctx == NULL)
1869  goto end;
1870 
1871  de_ctx->flags |= DE_QUIET;
1872 
1873  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1874  "(msg:\"http_host header test\"; "
1875  "content:\"kaboom\"; http_host; "
1876  "sid:1;)");
1877  if (de_ctx->sig_list == NULL)
1878  goto end;
1879 
1880  SigGroupBuild(de_ctx);
1881  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1882 
1883  FLOWLOCK_WRLOCK(&f);
1884  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1885  STREAM_TOSERVER, http_buf, http_len);
1886  if (r != 0) {
1887  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1888  result = 0;
1889  FLOWLOCK_UNLOCK(&f);
1890  goto end;
1891  }
1892  FLOWLOCK_UNLOCK(&f);
1893 
1894  http_state = f.alstate;
1895  if (http_state == NULL) {
1896  printf("no http state: ");
1897  result = 0;
1898  goto end;
1899  }
1900 
1901  /* do detect */
1902  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1903 
1904  if (!PacketAlertCheck(p, 1)) {
1905  printf("sid 1 didn't match but should have: ");
1906  goto end;
1907  }
1908 
1909  result = 1;
1910 
1911 end:
1912  if (alp_tctx != NULL)
1913  AppLayerParserThreadCtxFree(alp_tctx);
1914  if (de_ctx != NULL)
1915  SigGroupCleanup(de_ctx);
1916  if (de_ctx != NULL)
1917  SigCleanSignatures(de_ctx);
1918  if (de_ctx != NULL)
1919  DetectEngineCtxFree(de_ctx);
1920 
1922  FLOW_DESTROY(&f);
1923  UTHFreePackets(&p, 1);
1924  return result;
1925 }
1926 
1927 static int DetectEngineHttpHHTest20(void)
1928 {
1929  TcpSession ssn;
1930  Packet *p = NULL;
1931  ThreadVars th_v;
1932  DetectEngineCtx *de_ctx = NULL;
1933  DetectEngineThreadCtx *det_ctx = NULL;
1934  HtpState *http_state = NULL;
1935  Flow f;
1936  uint8_t http_buf[] =
1937  "GET /index.html HTTP/1.0\r\n"
1938  "Host: www.kaboom.com:8080\r\n"
1939  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
1940  uint32_t http_len = sizeof(http_buf) - 1;
1941  int result = 0;
1943 
1944  memset(&th_v, 0, sizeof(th_v));
1945  memset(&f, 0, sizeof(f));
1946  memset(&ssn, 0, sizeof(ssn));
1947 
1948  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1949 
1950  FLOW_INITIALIZE(&f);
1951  f.protoctx = (void *)&ssn;
1952  f.proto = IPPROTO_TCP;
1953  f.flags |= FLOW_IPV4;
1954  p->flow = &f;
1958  f.alproto = ALPROTO_HTTP;
1959 
1961 
1962  de_ctx = DetectEngineCtxInit();
1963  if (de_ctx == NULL)
1964  goto end;
1965 
1966  de_ctx->flags |= DE_QUIET;
1967 
1968  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1969  "(msg:\"http_host header test\"; "
1970  "content:\"8080\"; http_host; "
1971  "sid:1;)");
1972  if (de_ctx->sig_list == NULL)
1973  goto end;
1974 
1975  SigGroupBuild(de_ctx);
1976  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1977 
1978  FLOWLOCK_WRLOCK(&f);
1979  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1980  STREAM_TOSERVER, http_buf, http_len);
1981  if (r != 0) {
1982  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1983  result = 0;
1984  FLOWLOCK_UNLOCK(&f);
1985  goto end;
1986  }
1987  FLOWLOCK_UNLOCK(&f);
1988 
1989  http_state = f.alstate;
1990  if (http_state == NULL) {
1991  printf("no http state: ");
1992  result = 0;
1993  goto end;
1994  }
1995 
1996  /* do detect */
1997  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1998 
1999  if (PacketAlertCheck(p, 1)) {
2000  printf("sid 1 matched but it shouldn't have: ");
2001  goto end;
2002  }
2003 
2004  result = 1;
2005 
2006 end:
2007  if (alp_tctx != NULL)
2008  AppLayerParserThreadCtxFree(alp_tctx);
2009  if (de_ctx != NULL)
2010  SigGroupCleanup(de_ctx);
2011  if (de_ctx != NULL)
2012  SigCleanSignatures(de_ctx);
2013  if (de_ctx != NULL)
2014  DetectEngineCtxFree(de_ctx);
2015 
2017  FLOW_DESTROY(&f);
2018  UTHFreePackets(&p, 1);
2019  return result;
2020 }
2021 
2022 static int DetectEngineHttpHHTest21(void)
2023 {
2024  TcpSession ssn;
2025  Packet *p = NULL;
2026  ThreadVars th_v;
2027  DetectEngineCtx *de_ctx = NULL;
2028  DetectEngineThreadCtx *det_ctx = NULL;
2029  HtpState *http_state = NULL;
2030  Flow f;
2031  uint8_t http_buf[] =
2032  "GET http://www.kaboom.com/index.html HTTP/1.0\r\n"
2033  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
2034  uint32_t http_len = sizeof(http_buf) - 1;
2035  int result = 0;
2037 
2038  memset(&th_v, 0, sizeof(th_v));
2039  memset(&f, 0, sizeof(f));
2040  memset(&ssn, 0, sizeof(ssn));
2041 
2042  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2043 
2044  FLOW_INITIALIZE(&f);
2045  f.protoctx = (void *)&ssn;
2046  f.proto = IPPROTO_TCP;
2047  f.flags |= FLOW_IPV4;
2048  p->flow = &f;
2052  f.alproto = ALPROTO_HTTP;
2053 
2055 
2056  de_ctx = DetectEngineCtxInit();
2057  if (de_ctx == NULL)
2058  goto end;
2059 
2060  de_ctx->flags |= DE_QUIET;
2061 
2062  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2063  "(msg:\"http_host header test\"; "
2064  "content:\"kaboom\"; http_host; "
2065  "sid:1;)");
2066  if (de_ctx->sig_list == NULL)
2067  goto end;
2068 
2069  SigGroupBuild(de_ctx);
2070  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2071 
2072  FLOWLOCK_WRLOCK(&f);
2073  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2074  STREAM_TOSERVER, http_buf, http_len);
2075  if (r != 0) {
2076  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2077  result = 0;
2078  FLOWLOCK_UNLOCK(&f);
2079  goto end;
2080  }
2081  FLOWLOCK_UNLOCK(&f);
2082 
2083  http_state = f.alstate;
2084  if (http_state == NULL) {
2085  printf("no http state: ");
2086  result = 0;
2087  goto end;
2088  }
2089 
2090  /* do detect */
2091  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2092 
2093  if (!PacketAlertCheck(p, 1)) {
2094  printf("sid 1 didn't match but should have: ");
2095  goto end;
2096  }
2097 
2098  result = 1;
2099 
2100 end:
2101  if (alp_tctx != NULL)
2102  AppLayerParserThreadCtxFree(alp_tctx);
2103  if (de_ctx != NULL)
2104  SigGroupCleanup(de_ctx);
2105  if (de_ctx != NULL)
2106  SigCleanSignatures(de_ctx);
2107  if (de_ctx != NULL)
2108  DetectEngineCtxFree(de_ctx);
2109 
2111  FLOW_DESTROY(&f);
2112  UTHFreePackets(&p, 1);
2113  return result;
2114 }
2115 
2116 static int DetectEngineHttpHHTest22(void)
2117 {
2118  TcpSession ssn;
2119  Packet *p = NULL;
2120  ThreadVars th_v;
2121  DetectEngineCtx *de_ctx = NULL;
2122  DetectEngineThreadCtx *det_ctx = NULL;
2123  HtpState *http_state = NULL;
2124  Flow f;
2125  uint8_t http_buf[] =
2126  "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n"
2127  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
2128  uint32_t http_len = sizeof(http_buf) - 1;
2129  int result = 0;
2131 
2132  memset(&th_v, 0, sizeof(th_v));
2133  memset(&f, 0, sizeof(f));
2134  memset(&ssn, 0, sizeof(ssn));
2135 
2136  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2137 
2138  FLOW_INITIALIZE(&f);
2139  f.protoctx = (void *)&ssn;
2140  f.proto = IPPROTO_TCP;
2141  f.flags |= FLOW_IPV4;
2142  p->flow = &f;
2146  f.alproto = ALPROTO_HTTP;
2147 
2149 
2150  de_ctx = DetectEngineCtxInit();
2151  if (de_ctx == NULL)
2152  goto end;
2153 
2154  de_ctx->flags |= DE_QUIET;
2155 
2156  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2157  "(msg:\"http_host header test\"; "
2158  "content:\"kaboom\"; http_host; "
2159  "sid:1;)");
2160  if (de_ctx->sig_list == NULL)
2161  goto end;
2162 
2163  SigGroupBuild(de_ctx);
2164  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2165 
2166  FLOWLOCK_WRLOCK(&f);
2167  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2168  STREAM_TOSERVER, http_buf, http_len);
2169  if (r != 0) {
2170  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2171  result = 0;
2172  FLOWLOCK_UNLOCK(&f);
2173  goto end;
2174  }
2175  FLOWLOCK_UNLOCK(&f);
2176 
2177  http_state = f.alstate;
2178  if (http_state == NULL) {
2179  printf("no http state: ");
2180  result = 0;
2181  goto end;
2182  }
2183 
2184  /* do detect */
2185  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2186 
2187  if (!PacketAlertCheck(p, 1)) {
2188  printf("sid 1 didn't match but should have: ");
2189  goto end;
2190  }
2191 
2192  result = 1;
2193 
2194 end:
2195  if (alp_tctx != NULL)
2196  AppLayerParserThreadCtxFree(alp_tctx);
2197  if (de_ctx != NULL)
2198  SigGroupCleanup(de_ctx);
2199  if (de_ctx != NULL)
2200  SigCleanSignatures(de_ctx);
2201  if (de_ctx != NULL)
2202  DetectEngineCtxFree(de_ctx);
2203 
2205  FLOW_DESTROY(&f);
2206  UTHFreePackets(&p, 1);
2207  return result;
2208 }
2209 
2210 static int DetectEngineHttpHHTest23(void)
2211 {
2212  TcpSession ssn;
2213  Packet *p = NULL;
2214  ThreadVars th_v;
2215  DetectEngineCtx *de_ctx = NULL;
2216  DetectEngineThreadCtx *det_ctx = NULL;
2217  HtpState *http_state = NULL;
2218  Flow f;
2219  uint8_t http_buf[] =
2220  "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n"
2221  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
2222  uint32_t http_len = sizeof(http_buf) - 1;
2223  int result = 0;
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  p->flow = &f;
2240  f.alproto = ALPROTO_HTTP;
2241 
2243 
2244  de_ctx = DetectEngineCtxInit();
2245  if (de_ctx == NULL)
2246  goto end;
2247 
2248  de_ctx->flags |= DE_QUIET;
2249 
2250  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2251  "(msg:\"http_host header test\"; "
2252  "content:\"8080\"; http_host; "
2253  "sid:1;)");
2254  if (de_ctx->sig_list == NULL)
2255  goto end;
2256 
2257  SigGroupBuild(de_ctx);
2258  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2259 
2260  FLOWLOCK_WRLOCK(&f);
2261  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2262  STREAM_TOSERVER, http_buf, http_len);
2263  if (r != 0) {
2264  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2265  result = 0;
2266  FLOWLOCK_UNLOCK(&f);
2267  goto end;
2268  }
2269  FLOWLOCK_UNLOCK(&f);
2270 
2271  http_state = f.alstate;
2272  if (http_state == NULL) {
2273  printf("no http state: ");
2274  result = 0;
2275  goto end;
2276  }
2277 
2278  /* do detect */
2279  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2280 
2281  if (PacketAlertCheck(p, 1)) {
2282  printf("sid 1 matched but it shouldn't have: ");
2283  goto end;
2284  }
2285 
2286  result = 1;
2287 
2288 end:
2289  if (alp_tctx != NULL)
2290  AppLayerParserThreadCtxFree(alp_tctx);
2291  if (de_ctx != NULL)
2292  SigGroupCleanup(de_ctx);
2293  if (de_ctx != NULL)
2294  SigCleanSignatures(de_ctx);
2295  if (de_ctx != NULL)
2296  DetectEngineCtxFree(de_ctx);
2297 
2299  FLOW_DESTROY(&f);
2300  UTHFreePackets(&p, 1);
2301  return result;
2302 }
2303 
2304 static int DetectEngineHttpHHTest24(void)
2305 {
2306  TcpSession ssn;
2307  Packet *p = NULL;
2308  ThreadVars th_v;
2309  DetectEngineCtx *de_ctx = NULL;
2310  DetectEngineThreadCtx *det_ctx = NULL;
2311  HtpState *http_state = NULL;
2312  Flow f;
2313  uint8_t http_buf[] =
2314  "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n"
2315  "Host: www.rabbit.com\r\n"
2316  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
2317  uint32_t http_len = sizeof(http_buf) - 1;
2318  int result = 0;
2320 
2321  memset(&th_v, 0, sizeof(th_v));
2322  memset(&f, 0, sizeof(f));
2323  memset(&ssn, 0, sizeof(ssn));
2324 
2325  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2326 
2327  FLOW_INITIALIZE(&f);
2328  f.protoctx = (void *)&ssn;
2329  f.proto = IPPROTO_TCP;
2330  f.flags |= FLOW_IPV4;
2331  p->flow = &f;
2335  f.alproto = ALPROTO_HTTP;
2336 
2338 
2339  de_ctx = DetectEngineCtxInit();
2340  if (de_ctx == NULL)
2341  goto end;
2342 
2343  de_ctx->flags |= DE_QUIET;
2344 
2345  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2346  "(msg:\"http_host header test\"; "
2347  "content:\"kaboom\"; http_host; "
2348  "sid:1;)");
2349  if (de_ctx->sig_list == NULL)
2350  goto end;
2351 
2352  SigGroupBuild(de_ctx);
2353  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2354 
2355  FLOWLOCK_WRLOCK(&f);
2356  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2357  STREAM_TOSERVER, http_buf, http_len);
2358  if (r != 0) {
2359  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2360  result = 0;
2361  FLOWLOCK_UNLOCK(&f);
2362  goto end;
2363  }
2364  FLOWLOCK_UNLOCK(&f);
2365 
2366  http_state = f.alstate;
2367  if (http_state == NULL) {
2368  printf("no http state: ");
2369  result = 0;
2370  goto end;
2371  }
2372 
2373  /* do detect */
2374  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2375 
2376  if (!PacketAlertCheck(p, 1)) {
2377  printf("sid 1 didn't match but it should have: ");
2378  goto end;
2379  }
2380 
2381  result = 1;
2382 
2383 end:
2384  if (alp_tctx != NULL)
2385  AppLayerParserThreadCtxFree(alp_tctx);
2386  if (de_ctx != NULL)
2387  SigGroupCleanup(de_ctx);
2388  if (de_ctx != NULL)
2389  SigCleanSignatures(de_ctx);
2390  if (de_ctx != NULL)
2391  DetectEngineCtxFree(de_ctx);
2392 
2394  FLOW_DESTROY(&f);
2395  UTHFreePackets(&p, 1);
2396  return result;
2397 }
2398 
2399 static int DetectEngineHttpHHTest25(void)
2400 {
2401  TcpSession ssn;
2402  Packet *p = NULL;
2403  ThreadVars th_v;
2404  DetectEngineCtx *de_ctx = NULL;
2405  DetectEngineThreadCtx *det_ctx = NULL;
2406  HtpState *http_state = NULL;
2407  Flow f;
2408  uint8_t http_buf[] =
2409  "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n"
2410  "Host: www.rabbit.com\r\n"
2411  "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n";
2412  uint32_t http_len = sizeof(http_buf) - 1;
2413  int result = 0;
2415 
2416  memset(&th_v, 0, sizeof(th_v));
2417  memset(&f, 0, sizeof(f));
2418  memset(&ssn, 0, sizeof(ssn));
2419 
2420  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2421 
2422  FLOW_INITIALIZE(&f);
2423  f.protoctx = (void *)&ssn;
2424  f.proto = IPPROTO_TCP;
2425  f.flags |= FLOW_IPV4;
2426  p->flow = &f;
2430  f.alproto = ALPROTO_HTTP;
2431 
2433 
2434  de_ctx = DetectEngineCtxInit();
2435  if (de_ctx == NULL)
2436  goto end;
2437 
2438  de_ctx->flags |= DE_QUIET;
2439 
2440  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2441  "(msg:\"http_host header test\"; "
2442  "content:\"rabbit\"; http_host; "
2443  "sid:1;)");
2444  if (de_ctx->sig_list == NULL)
2445  goto end;
2446 
2447  SigGroupBuild(de_ctx);
2448  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2449 
2450  FLOWLOCK_WRLOCK(&f);
2451  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2452  STREAM_TOSERVER, http_buf, http_len);
2453  if (r != 0) {
2454  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2455  result = 0;
2456  FLOWLOCK_UNLOCK(&f);
2457  goto end;
2458  }
2459  FLOWLOCK_UNLOCK(&f);
2460 
2461  http_state = f.alstate;
2462  if (http_state == NULL) {
2463  printf("no http state: ");
2464  result = 0;
2465  goto end;
2466  }
2467 
2468  /* do detect */
2469  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2470 
2471  if (PacketAlertCheck(p, 1)) {
2472  printf("sid 1 matched but it shouldn't have: ");
2473  goto end;
2474  }
2475 
2476  result = 1;
2477 
2478 end:
2479  if (alp_tctx != NULL)
2480  AppLayerParserThreadCtxFree(alp_tctx);
2481  if (de_ctx != NULL)
2482  SigGroupCleanup(de_ctx);
2483  if (de_ctx != NULL)
2484  SigCleanSignatures(de_ctx);
2485  if (de_ctx != NULL)
2486  DetectEngineCtxFree(de_ctx);
2487 
2489  FLOW_DESTROY(&f);
2490  UTHFreePackets(&p, 1);
2491  return result;
2492 }
2493 
2494 /**
2495  * \test Test that a signature containting a http_host is correctly parsed
2496  * and the keyword is registered.
2497  */
2498 static int DetectHttpHHTest01(void)
2499 {
2500  DetectEngineCtx *de_ctx = NULL;
2501  int result = 0;
2502 
2503  de_ctx = DetectEngineCtxInit();
2504  if (de_ctx == NULL)
2505  goto end;
2506 
2507  de_ctx->flags |= DE_QUIET;
2508  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2509  "(msg:\"Testing http_host\"; "
2510  "content:\"one\"; http_host; sid:1;)");
2511  if (de_ctx->sig_list != NULL) {
2512  result = 1;
2513  } else {
2514  goto end;
2515  }
2516 
2517  end:
2518  DetectEngineCtxFree(de_ctx);
2519 
2520  return result;
2521 }
2522 
2523 /**
2524  * \test Test that a signature containing an valid http_host entry is
2525  * parsed.
2526  */
2527 static int DetectHttpHHTest02(void)
2528 {
2529  DetectEngineCtx *de_ctx = NULL;
2530  int result = 0;
2531 
2532  de_ctx = DetectEngineCtxInit();
2533  if (de_ctx == NULL)
2534  goto end;
2535 
2536  de_ctx->flags |= DE_QUIET;
2537  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2538  "(msg:\"Testing http_host\"; "
2539  "content:\"one\"; http_host; sid:1;)");
2540  if (de_ctx->sig_list != NULL)
2541  result = 1;
2542 
2543  end:
2544  DetectEngineCtxFree(de_ctx);
2545 
2546  return result;
2547 }
2548 
2549 /**
2550  * \test Test that an invalid signature containing no content but a
2551  * http_host is invalidated.
2552  */
2553 static int DetectHttpHHTest03(void)
2554 {
2555  DetectEngineCtx *de_ctx = NULL;
2556  int result = 0;
2557 
2558  de_ctx = DetectEngineCtxInit();
2559  if (de_ctx == NULL)
2560  goto end;
2561 
2562  de_ctx->flags |= DE_QUIET;
2563  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2564  "(msg:\"Testing http_host\"; "
2565  "http_host; sid:1;)");
2566  if (de_ctx->sig_list == NULL)
2567  result = 1;
2568 
2569  end:
2570  DetectEngineCtxFree(de_ctx);
2571 
2572  return result;
2573 }
2574 
2575 /**
2576  * \test Test that an invalid signature containing a rawbytes along with a
2577  * http_host is invalidated.
2578  */
2579 static int DetectHttpHHTest04(void)
2580 {
2581  DetectEngineCtx *de_ctx = NULL;
2582  int result = 0;
2583 
2584  de_ctx = DetectEngineCtxInit();
2585  if (de_ctx == NULL)
2586  goto end;
2587 
2588  de_ctx->flags |= DE_QUIET;
2589  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2590  "(msg:\"Testing http_host\"; "
2591  "content:\"one\"; rawbytes; http_host; sid:1;)");
2592  if (de_ctx->sig_list == NULL)
2593  result = 1;
2594 
2595  end:
2596  DetectEngineCtxFree(de_ctx);
2597 
2598  return result;
2599 }
2600 
2601 /**
2602  * \test Test that a http_host with nocase is parsed.
2603  */
2604 static int DetectHttpHHTest05(void)
2605 {
2606  DetectEngineCtx *de_ctx = NULL;
2607  int result = 0;
2608 
2609  de_ctx = DetectEngineCtxInit();
2610  if (de_ctx == NULL)
2611  goto end;
2612 
2613  de_ctx->flags |= DE_QUIET;
2614  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2615  "(msg:\"Testing http_host\"; "
2616  "content:\"one\"; http_host; sid:1;)");
2617  if (de_ctx->sig_list != NULL)
2618  result = 1;
2619 
2620  end:
2621  DetectEngineCtxFree(de_ctx);
2622 
2623  return result;
2624 }
2625 
2626 /** \test invalid sig: uppercase content */
2627 static int DetectHttpHHTest05a(void)
2628 {
2630  FAIL_IF_NULL(de_ctx);
2631  de_ctx->flags |= DE_QUIET;
2632 
2633  Signature *s = DetectEngineAppendSig(de_ctx,
2634  "alert tcp any any -> any any "
2635  "(content:\"ABC\"; http_host; sid:1;)");
2636  FAIL_IF_NOT_NULL(s);
2637 
2638  DetectEngineCtxFree(de_ctx);
2639  PASS;
2640 }
2641 
2642 /**
2643  *\test Test that the http_host content matches against a http request
2644  * which holds the content.
2645  */
2646 static int DetectHttpHHTest06(void)
2647 {
2648  TcpSession ssn;
2649  Packet *p = NULL;
2650  ThreadVars th_v;
2651  DetectEngineCtx *de_ctx = NULL;
2652  DetectEngineThreadCtx *det_ctx = NULL;
2653  HtpState *http_state = NULL;
2654  Flow f;
2655  uint8_t http_buf[] =
2656  "GET /index.html HTTP/1.0\r\n"
2657  "User-Agent: www.openinfosecfoundation.org\r\n"
2658  "Host: This is dummy message body\r\n"
2659  "Content-Type: text/html\r\n"
2660  "\r\n";
2661  uint32_t http_len = sizeof(http_buf) - 1;
2662  int result = 0;
2664 
2665  memset(&th_v, 0, sizeof(th_v));
2666  memset(&f, 0, sizeof(f));
2667  memset(&ssn, 0, sizeof(ssn));
2668 
2669  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2670 
2671  FLOW_INITIALIZE(&f);
2672  f.protoctx = (void *)&ssn;
2673  f.proto = IPPROTO_TCP;
2674  f.flags |= FLOW_IPV4;
2675 
2676  p->flow = &f;
2680  f.alproto = ALPROTO_HTTP;
2681 
2683 
2684  de_ctx = DetectEngineCtxInit();
2685  if (de_ctx == NULL)
2686  goto end;
2687 
2688  de_ctx->flags |= DE_QUIET;
2689 
2690  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2691  "(msg:\"http host test\"; "
2692  "content:\"message\"; http_host; "
2693  "sid:1;)");
2694  if (de_ctx->sig_list == NULL)
2695  goto end;
2696 
2697  SigGroupBuild(de_ctx);
2698  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2699 
2700  FLOWLOCK_WRLOCK(&f);
2701  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2702  STREAM_TOSERVER, http_buf, http_len);
2703  if (r != 0) {
2704  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2705  result = 0;
2706  FLOWLOCK_UNLOCK(&f);
2707  goto end;
2708  }
2709  FLOWLOCK_UNLOCK(&f);
2710 
2711  http_state = f.alstate;
2712  if (http_state == NULL) {
2713  printf("no http state: \n");
2714  result = 0;
2715  goto end;
2716  }
2717 
2718  /* do detect */
2719  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2720 
2721  if (!(PacketAlertCheck(p, 1))) {
2722  printf("sid 1 didn't match but should have\n");
2723  goto end;
2724  }
2725 
2726  result = 1;
2727 end:
2728  if (alp_tctx != NULL)
2729  AppLayerParserThreadCtxFree(alp_tctx);
2730  if (de_ctx != NULL)
2731  DetectEngineCtxFree(de_ctx);
2732 
2734  FLOW_DESTROY(&f);
2735  UTHFreePackets(&p, 1);
2736  return result;
2737 }
2738 
2739 /**
2740  *\test Test that the http_host content matches against a http request
2741  * which holds the content.
2742  */
2743 static int DetectHttpHHTest07(void)
2744 {
2745  TcpSession ssn;
2746  Packet *p1 = NULL;
2747  Packet *p2 = NULL;
2748  ThreadVars th_v;
2749  DetectEngineCtx *de_ctx = NULL;
2750  DetectEngineThreadCtx *det_ctx = NULL;
2751  HtpState *http_state = NULL;
2752  Flow f;
2753  uint8_t http1_buf[] =
2754  "GET /index.html HTTP/1.0\r\n"
2755  "User-Agent: www.openinfosecfoundation.org\r\n"
2756  "Host: This is dummy message";
2757  uint8_t http2_buf[] =
2758  "body1\r\n\r\n";
2759  uint32_t http1_len = sizeof(http1_buf) - 1;
2760  uint32_t http2_len = sizeof(http2_buf) - 1;
2761  int result = 0;
2763 
2764  memset(&th_v, 0, sizeof(th_v));
2765  memset(&f, 0, sizeof(f));
2766  memset(&ssn, 0, sizeof(ssn));
2767 
2768  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2769  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2770 
2771  FLOW_INITIALIZE(&f);
2772  f.protoctx = (void *)&ssn;
2773  f.proto = IPPROTO_TCP;
2774  f.flags |= FLOW_IPV4;
2775 
2776  p1->flow = &f;
2780  p2->flow = &f;
2784  f.alproto = ALPROTO_HTTP;
2785 
2787 
2788  de_ctx = DetectEngineCtxInit();
2789  if (de_ctx == NULL)
2790  goto end;
2791 
2792  de_ctx->flags |= DE_QUIET;
2793 
2794  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2795  "(msg:\"http host test\"; "
2796  "content:\"message\"; http_host; "
2797  "sid:1;)");
2798  if (de_ctx->sig_list == NULL)
2799  goto end;
2800 
2801  SigGroupBuild(de_ctx);
2802  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2803 
2804  FLOWLOCK_WRLOCK(&f);
2805  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2806  STREAM_TOSERVER, http1_buf, http1_len);
2807  if (r != 0) {
2808  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2809  result = 0;
2810  FLOWLOCK_UNLOCK(&f);
2811  goto end;
2812  }
2813  FLOWLOCK_UNLOCK(&f);
2814 
2815  http_state = f.alstate;
2816  if (http_state == NULL) {
2817  printf("no http state: ");
2818  goto end;
2819  }
2820 
2821  /* do detect */
2822  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2823 
2824  if (PacketAlertCheck(p1, 1)) {
2825  printf("sid 1 matched on p1 but shouldn't have: ");
2826  goto end;
2827  }
2828 
2829  FLOWLOCK_WRLOCK(&f);
2830  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2831  STREAM_TOSERVER, http2_buf, http2_len);
2832  if (r != 0) {
2833  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2834  FLOWLOCK_UNLOCK(&f);
2835  goto end;
2836  }
2837  FLOWLOCK_UNLOCK(&f);
2838 
2839  /* do detect */
2840  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2841  if (!(PacketAlertCheck(p2, 1))) {
2842  printf("sid 1 didn't match on p2 but should have: ");
2843  goto end;
2844  }
2845 
2846  result = 1;
2847 end:
2848  if (alp_tctx != NULL)
2849  AppLayerParserThreadCtxFree(alp_tctx);
2850  if (de_ctx != NULL)
2851  DetectEngineCtxFree(de_ctx);
2852 
2854  FLOW_DESTROY(&f);
2855  UTHFreePackets(&p1, 1);
2856  UTHFreePackets(&p2, 1);
2857  return result;
2858 }
2859 
2860 /**
2861  *\test Test that the http_host content matches against a http request
2862  * which holds the content.
2863  */
2864 static int DetectHttpHHTest08(void)
2865 {
2866  TcpSession ssn;
2867  Packet *p1 = NULL;
2868  Packet *p2 = NULL;
2869  ThreadVars th_v;
2870  DetectEngineCtx *de_ctx = NULL;
2871  DetectEngineThreadCtx *det_ctx = NULL;
2872  HtpState *http_state = NULL;
2873  Flow f;
2874  uint8_t http1_buf[] =
2875  "GET /index.html HTTP/1.0\r\n"
2876  "User-Agent: www.openinfosecfoundation.org\r\n"
2877  "host: This is dummy mess";
2878  uint8_t http2_buf[] =
2879  "age body\r\n\r\n";
2880  uint32_t http1_len = sizeof(http1_buf) - 1;
2881  uint32_t http2_len = sizeof(http2_buf) - 1;
2882  int result = 0;
2884 
2885  memset(&th_v, 0, sizeof(th_v));
2886  memset(&f, 0, sizeof(f));
2887  memset(&ssn, 0, sizeof(ssn));
2888 
2889  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2890  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2891 
2892  FLOW_INITIALIZE(&f);
2893  f.protoctx = (void *)&ssn;
2894  f.proto = IPPROTO_TCP;
2895  f.flags |= FLOW_IPV4;
2896 
2897  p1->flow = &f;
2901  p2->flow = &f;
2905  f.alproto = ALPROTO_HTTP;
2906 
2908 
2909  de_ctx = DetectEngineCtxInit();
2910  if (de_ctx == NULL)
2911  goto end;
2912 
2913  de_ctx->flags |= DE_QUIET;
2914 
2915  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2916  "(msg:\"http host test\"; "
2917  "content:\"message\"; http_host; "
2918  "sid:1;)");
2919  if (de_ctx->sig_list == NULL)
2920  goto end;
2921 
2922  SigGroupBuild(de_ctx);
2923  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2924 
2925  FLOWLOCK_WRLOCK(&f);
2926  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2927  STREAM_TOSERVER, http1_buf, http1_len);
2928  if (r != 0) {
2929  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2930  result = 0;
2931  FLOWLOCK_UNLOCK(&f);
2932  goto end;
2933  }
2934  FLOWLOCK_UNLOCK(&f);
2935 
2936  http_state = f.alstate;
2937  if (http_state == NULL) {
2938  printf("no http state: ");
2939  result = 0;
2940  goto end;
2941  }
2942 
2943  /* do detect */
2944  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2945 
2946  if ((PacketAlertCheck(p1, 1))) {
2947  printf("sid 1 didn't match but should have");
2948  goto end;
2949  }
2950 
2951  FLOWLOCK_WRLOCK(&f);
2952  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2953  STREAM_TOSERVER, http2_buf, http2_len);
2954  if (r != 0) {
2955  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2956  result = 0;
2957  FLOWLOCK_UNLOCK(&f);
2958  goto end;
2959  }
2960  FLOWLOCK_UNLOCK(&f);
2961 
2962  /* do detect */
2963  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2964 
2965  if (!(PacketAlertCheck(p2, 1))) {
2966  printf("sid 1 didn't match but should have");
2967  goto end;
2968  }
2969 
2970  result = 1;
2971 end:
2972  if (alp_tctx != NULL)
2973  AppLayerParserThreadCtxFree(alp_tctx);
2974  if (de_ctx != NULL)
2975  DetectEngineCtxFree(de_ctx);
2976 
2978  FLOW_DESTROY(&f);
2979  UTHFreePackets(&p1, 1);
2980  UTHFreePackets(&p2, 1);
2981  return result;
2982 }
2983 
2984 /**
2985  *\test Test that the http_host content matches against a http request
2986  * which holds the content, against a cross boundary present pattern.
2987  */
2988 static int DetectHttpHHTest09(void)
2989 {
2990  TcpSession ssn;
2991  Packet *p1 = NULL;
2992  Packet *p2 = NULL;
2993  ThreadVars th_v;
2994  DetectEngineCtx *de_ctx = NULL;
2995  DetectEngineThreadCtx *det_ctx = NULL;
2996  HtpState *http_state = NULL;
2997  Flow f;
2998  uint8_t http1_buf[] =
2999  "GET /index.html HTTP/1.0\r\n"
3000  "User-Agent: www.openinfosecfoundation.org\r\n"
3001  "Host: This is dummy body1";
3002  uint8_t http2_buf[] =
3003  "This is dummy message body2\r\n"
3004  "Content-Type: text/html\r\n"
3005  "Content-Length: 46\r\n"
3006  "\r\n"
3007  "This is dummy body1";
3008  uint32_t http1_len = sizeof(http1_buf) - 1;
3009  uint32_t http2_len = sizeof(http2_buf) - 1;
3010  int result = 0;
3012 
3013  memset(&th_v, 0, sizeof(th_v));
3014  memset(&f, 0, sizeof(f));
3015  memset(&ssn, 0, sizeof(ssn));
3016 
3017  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3018  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3019 
3020  FLOW_INITIALIZE(&f);
3021  f.protoctx = (void *)&ssn;
3022  f.proto = IPPROTO_TCP;
3023  f.flags |= FLOW_IPV4;
3024 
3025  p1->flow = &f;
3029  p2->flow = &f;
3033  f.alproto = ALPROTO_HTTP;
3034 
3036 
3037  de_ctx = DetectEngineCtxInit();
3038  if (de_ctx == NULL)
3039  goto end;
3040 
3041  de_ctx->flags |= DE_QUIET;
3042 
3043  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3044  "(msg:\"http host test\"; "
3045  "content:\"body1this\"; http_host; "
3046  "sid:1;)");
3047  if (de_ctx->sig_list == NULL)
3048  goto end;
3049 
3050  SigGroupBuild(de_ctx);
3051  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3052 
3053  FLOWLOCK_WRLOCK(&f);
3054  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3055  STREAM_TOSERVER, http1_buf, http1_len);
3056  if (r != 0) {
3057  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3058  result = 0;
3059  FLOWLOCK_UNLOCK(&f);
3060  goto end;
3061  }
3062  FLOWLOCK_UNLOCK(&f);
3063 
3064  http_state = f.alstate;
3065  if (http_state == NULL) {
3066  printf("no http state: ");
3067  result = 0;
3068  goto end;
3069  }
3070 
3071  /* do detect */
3072  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3073 
3074  if ((PacketAlertCheck(p1, 1))) {
3075  printf("sid 1 didn't match but should have");
3076  goto end;
3077  }
3078 
3079  FLOWLOCK_WRLOCK(&f);
3080  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3081  STREAM_TOSERVER, http2_buf, http2_len);
3082  if (r != 0) {
3083  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3084  result = 0;
3085  FLOWLOCK_UNLOCK(&f);
3086  goto end;
3087  }
3088  FLOWLOCK_UNLOCK(&f);
3089 
3090  /* do detect */
3091  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3092 
3093  if (!(PacketAlertCheck(p2, 1))) {
3094  printf("sid 1 didn't match but should have");
3095  goto end;
3096  }
3097 
3098  result = 1;
3099 end:
3100  if (alp_tctx != NULL)
3101  AppLayerParserThreadCtxFree(alp_tctx);
3102  if (de_ctx != NULL)
3103  DetectEngineCtxFree(de_ctx);
3104 
3106  FLOW_DESTROY(&f);
3107  UTHFreePackets(&p1, 1);
3108  UTHFreePackets(&p2, 1);
3109  return result;
3110 }
3111 
3112 /**
3113  *\test Test that the http_host content matches against a http request
3114  * against a case insensitive pattern.
3115  */
3116 static int DetectHttpHHTest10(void)
3117 {
3118  TcpSession ssn;
3119  Packet *p1 = NULL;
3120  Packet *p2 = NULL;
3121  ThreadVars th_v;
3122  DetectEngineCtx *de_ctx = NULL;
3123  DetectEngineThreadCtx *det_ctx = NULL;
3124  HtpState *http_state = NULL;
3125  Flow f;
3126  uint8_t http1_buf[] =
3127  "GET /index.html HTTP/1.0\r\n"
3128  "User-Agent: www.openinfosecfoundation.org\r\n"
3129  "Host: This is dummy bodY1";
3130  uint8_t http2_buf[] =
3131  "This is dummy message body2\r\n"
3132  "Content-Type: text/html\r\n"
3133  "Content-Length: 46\r\n"
3134  "\r\n"
3135  "This is dummy bodY1";
3136  uint32_t http1_len = sizeof(http1_buf) - 1;
3137  uint32_t http2_len = sizeof(http2_buf) - 1;
3138  int result = 0;
3140 
3141  memset(&th_v, 0, sizeof(th_v));
3142  memset(&f, 0, sizeof(f));
3143  memset(&ssn, 0, sizeof(ssn));
3144 
3145  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3146  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3147 
3148  FLOW_INITIALIZE(&f);
3149  f.protoctx = (void *)&ssn;
3150  f.proto = IPPROTO_TCP;
3151  f.flags |= FLOW_IPV4;
3152 
3153  p1->flow = &f;
3157  p2->flow = &f;
3161  f.alproto = ALPROTO_HTTP;
3162 
3164 
3165  de_ctx = DetectEngineCtxInit();
3166  if (de_ctx == NULL)
3167  goto end;
3168 
3169  de_ctx->flags |= DE_QUIET;
3170 
3171  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3172  "(msg:\"http host test\"; "
3173  "content:\"body1this\"; http_host; "
3174  "sid:1;)");
3175  if (de_ctx->sig_list == NULL)
3176  goto end;
3177 
3178  SigGroupBuild(de_ctx);
3179  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3180 
3181  FLOWLOCK_WRLOCK(&f);
3182  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3183  STREAM_TOSERVER, http1_buf, http1_len);
3184  if (r != 0) {
3185  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3186  result = 0;
3187  FLOWLOCK_UNLOCK(&f);
3188  goto end;
3189  }
3190  FLOWLOCK_UNLOCK(&f);
3191 
3192  http_state = f.alstate;
3193  if (http_state == NULL) {
3194  printf("no http state: \n");
3195  result = 0;
3196  goto end;
3197  }
3198 
3199  /* do detect */
3200  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3201 
3202  if ((PacketAlertCheck(p1, 1))) {
3203  printf("sid 1 didn't match but should have\n");
3204  goto end;
3205  }
3206 
3207  FLOWLOCK_WRLOCK(&f);
3208  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3209  STREAM_TOSERVER, http2_buf, http2_len);
3210  if (r != 0) {
3211  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3212  result = 0;
3213  FLOWLOCK_UNLOCK(&f);
3214  goto end;
3215  }
3216  FLOWLOCK_UNLOCK(&f);
3217 
3218 
3219  /* do detect */
3220  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3221 
3222  if (!(PacketAlertCheck(p2, 1))) {
3223  printf("sid 1 didn't match but should have");
3224  goto end;
3225  }
3226 
3227  result = 1;
3228 end:
3229  if (alp_tctx != NULL)
3230  AppLayerParserThreadCtxFree(alp_tctx);
3231  if (de_ctx != NULL)
3232  DetectEngineCtxFree(de_ctx);
3233 
3235  FLOW_DESTROY(&f);
3236  UTHFreePackets(&p1, 1);
3237  UTHFreePackets(&p2, 1);
3238  return result;
3239 }
3240 
3241 /**
3242  *\test Test that the negated http_host content matches against a
3243  * http request which doesn't hold the content.
3244  */
3245 static int DetectHttpHHTest11(void)
3246 {
3247  TcpSession ssn;
3248  Packet *p = NULL;
3249  ThreadVars th_v;
3250  DetectEngineCtx *de_ctx = NULL;
3251  DetectEngineThreadCtx *det_ctx = NULL;
3252  HtpState *http_state = NULL;
3253  Flow f;
3254  uint8_t http_buf[] =
3255  "GET /index.html HTTP/1.0\r\n"
3256  "User-Agent: www.openinfosecfoundation.org\r\n"
3257  "Host: This is dummy message body\r\n"
3258  "Content-Type: text/html\r\n"
3259  "\r\n";
3260  uint32_t http_len = sizeof(http_buf) - 1;
3261  int result = 0;
3263 
3264  memset(&th_v, 0, sizeof(th_v));
3265  memset(&f, 0, sizeof(f));
3266  memset(&ssn, 0, sizeof(ssn));
3267 
3268  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3269 
3270  FLOW_INITIALIZE(&f);
3271  f.protoctx = (void *)&ssn;
3272  f.proto = IPPROTO_TCP;
3273  f.flags |= FLOW_IPV4;
3274 
3275  p->flow = &f;
3279  f.alproto = ALPROTO_HTTP;
3280 
3282 
3283  de_ctx = DetectEngineCtxInit();
3284  if (de_ctx == NULL)
3285  goto end;
3286 
3287  de_ctx->flags |= DE_QUIET;
3288 
3289  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3290  "(msg:\"http host test\"; "
3291  "content:!\"message\"; http_host; "
3292  "sid:1;)");
3293  if (de_ctx->sig_list == NULL)
3294  goto end;
3295 
3296  SigGroupBuild(de_ctx);
3297  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3298 
3299  FLOWLOCK_WRLOCK(&f);
3300  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3301  STREAM_TOSERVER, http_buf, http_len);
3302  if (r != 0) {
3303  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3304  result = 0;
3305  FLOWLOCK_UNLOCK(&f);
3306  goto end;
3307  }
3308  FLOWLOCK_UNLOCK(&f);
3309 
3310  http_state = f.alstate;
3311  if (http_state == NULL) {
3312  printf("no http state: ");
3313  result = 0;
3314  goto end;
3315  }
3316 
3317  /* do detect */
3318  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3319 
3320  if (PacketAlertCheck(p, 1)) {
3321  printf("sid 1 matched but shouldn't have");
3322  goto end;
3323  }
3324 
3325  result = 1;
3326 end:
3327  if (alp_tctx != NULL)
3328  AppLayerParserThreadCtxFree(alp_tctx);
3329  if (de_ctx != NULL)
3330  DetectEngineCtxFree(de_ctx);
3331 
3333  FLOW_DESTROY(&f);
3334  UTHFreePackets(&p, 1);
3335  return result;
3336 }
3337 
3338 /**
3339  *\test Negative test that the negated http_host content matches against a
3340  * http request which holds hold the content.
3341  */
3342 static int DetectHttpHHTest12(void)
3343 {
3344  TcpSession ssn;
3345  Packet *p = NULL;
3346  ThreadVars th_v;
3347  DetectEngineCtx *de_ctx = NULL;
3348  DetectEngineThreadCtx *det_ctx = NULL;
3349  HtpState *http_state = NULL;
3350  Flow f;
3351  uint8_t http_buf[] =
3352  "GET /index.html HTTP/1.0\r\n"
3353  "User-Agent: www.openinfosecfoundation.org\r\n"
3354  "Host: This is dummy body\r\n"
3355  "\r\n";
3356  uint32_t http_len = sizeof(http_buf) - 1;
3357  int result = 0;
3359 
3360  memset(&th_v, 0, sizeof(th_v));
3361  memset(&f, 0, sizeof(f));
3362  memset(&ssn, 0, sizeof(ssn));
3363 
3364  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3365 
3366  FLOW_INITIALIZE(&f);
3367  f.protoctx = (void *)&ssn;
3368  f.proto = IPPROTO_TCP;
3369  f.flags |= FLOW_IPV4;
3370 
3371  p->flow = &f;
3375  f.alproto = ALPROTO_HTTP;
3376 
3378 
3379  de_ctx = DetectEngineCtxInit();
3380  if (de_ctx == NULL)
3381  goto end;
3382 
3383  de_ctx->flags |= DE_QUIET;
3384 
3385  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3386  "(msg:\"http host test\"; "
3387  "content:!\"message\"; http_host; "
3388  "sid:1;)");
3389  if (de_ctx->sig_list == NULL)
3390  goto end;
3391 
3392  SigGroupBuild(de_ctx);
3393  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3394 
3395  FLOWLOCK_WRLOCK(&f);
3396  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3397  STREAM_TOSERVER, http_buf, http_len);
3398  if (r != 0) {
3399  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3400  result = 0;
3401  FLOWLOCK_UNLOCK(&f);
3402  goto end;
3403  }
3404  FLOWLOCK_UNLOCK(&f);
3405 
3406  http_state = f.alstate;
3407  if (http_state == NULL) {
3408  printf("no http state: ");
3409  result = 0;
3410  goto end;
3411  }
3412 
3413  /* do detect */
3414  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3415 
3416  if (!(PacketAlertCheck(p, 1))) {
3417  printf("sid 1 didn't match but should have");
3418  goto end;
3419  }
3420 
3421  result = 1;
3422 end:
3423  if (alp_tctx != NULL)
3424  AppLayerParserThreadCtxFree(alp_tctx);
3425  if (de_ctx != NULL)
3426  DetectEngineCtxFree(de_ctx);
3427 
3429  FLOW_DESTROY(&f);
3430  UTHFreePackets(&p, 1);
3431  return result;
3432 }
3433 
3434 /**
3435  * \test Test that the http_host content matches against a http request
3436  * which holds the content.
3437  */
3438 static int DetectHttpHHTest13(void)
3439 {
3440  TcpSession ssn;
3441  Packet *p = NULL;
3442  ThreadVars th_v;
3443  DetectEngineCtx *de_ctx = NULL;
3444  DetectEngineThreadCtx *det_ctx = NULL;
3445  HtpState *http_state = NULL;
3446  Flow f;
3447  uint8_t http_buf[] =
3448  "GET /index.html HTTP/1.0\r\n"
3449  "User-Agent: www.openinfosecfoundation.org\r\n"
3450  "Host: longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n"
3451  "Content-Type: text/html\r\n"
3452  "\r\n";
3453  uint32_t http_len = sizeof(http_buf) - 1;
3454  int result = 0;
3456 
3457  memset(&th_v, 0, sizeof(th_v));
3458  memset(&f, 0, sizeof(f));
3459  memset(&ssn, 0, sizeof(ssn));
3460 
3461  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3462 
3463  FLOW_INITIALIZE(&f);
3464  f.protoctx = (void *)&ssn;
3465  f.proto = IPPROTO_TCP;
3466  f.flags |= FLOW_IPV4;
3467 
3468  p->flow = &f;
3472  f.alproto = ALPROTO_HTTP;
3473 
3475 
3476  de_ctx = DetectEngineCtxInit();
3477  if (de_ctx == NULL)
3478  goto end;
3479 
3480  de_ctx->flags |= DE_QUIET;
3481 
3482  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3483  "(msg:\"http host test\"; "
3484  "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_host; "
3485  "sid:1;)");
3486  if (de_ctx->sig_list == NULL)
3487  goto end;
3488 
3489  SigGroupBuild(de_ctx);
3490  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3491 
3492  FLOWLOCK_WRLOCK(&f);
3493  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3494  STREAM_TOSERVER, http_buf, http_len);
3495  if (r != 0) {
3496  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3497  result = 0;
3498  FLOWLOCK_UNLOCK(&f);
3499  goto end;
3500  }
3501  FLOWLOCK_UNLOCK(&f);
3502 
3503  http_state = f.alstate;
3504  if (http_state == NULL) {
3505  printf("no http state: ");
3506  result = 0;
3507  goto end;
3508  }
3509 
3510  /* do detect */
3511  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3512 
3513  if (!(PacketAlertCheck(p, 1))) {
3514  printf("sid 1 didn't match but should have");
3515  goto end;
3516  }
3517 
3518  result = 1;
3519 end:
3520  if (alp_tctx != NULL)
3521  AppLayerParserThreadCtxFree(alp_tctx);
3522  if (de_ctx != NULL)
3523  DetectEngineCtxFree(de_ctx);
3524 
3526  FLOW_DESTROY(&f);
3527  UTHFreePackets(&p, 1);
3528  return result;
3529 }
3530 
3531 /**
3532  * \test multiple http transactions and body chunks of request handling
3533  */
3534 static int DetectHttpHHTest14(void)
3535 {
3536  int result = 0;
3537  Signature *s = NULL;
3538  DetectEngineThreadCtx *det_ctx = NULL;
3539  ThreadVars th_v;
3540  Flow f;
3541  TcpSession ssn;
3542  Packet *p = NULL;
3543  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
3544  uint8_t httpbuf2[] = "Cookie: dummy1\r\n";
3545  uint8_t httpbuf3[] = "Host: Body one!!\r\n\r\n";
3546  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3547  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
3548  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
3549  uint8_t httpbuf4[] = "GET /?var=val HTTP/1.1\r\n";
3550  uint8_t httpbuf5[] = "Cookie: dummy2\r\n";
3551  uint8_t httpbuf6[] = "Host: Body two\r\n\r\n";
3552  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
3553  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
3554  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
3556 
3557  memset(&th_v, 0, sizeof(th_v));
3558  memset(&f, 0, sizeof(f));
3559  memset(&ssn, 0, sizeof(ssn));
3560 
3561  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3562 
3563  FLOW_INITIALIZE(&f);
3564  f.protoctx = (void *)&ssn;
3565  f.proto = IPPROTO_TCP;
3566  f.flags |= FLOW_IPV4;
3567 
3568  p->flow = &f;
3572  f.alproto = ALPROTO_HTTP;
3573 
3575 
3577  if (de_ctx == NULL) {
3578  goto end;
3579  }
3580 
3581  de_ctx->flags |= DE_QUIET;
3582 
3583  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy1\"; http_cookie; content:\"body one\"; http_host; sid:1; rev:1;)");
3584  if (s == NULL) {
3585  printf("sig parse failed: ");
3586  goto end;
3587  }
3588  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"dummy2\"; http_cookie; content:\"body two\"; http_host; sid:2; rev:1;)");
3589  if (s == NULL) {
3590  printf("sig2 parse failed: ");
3591  goto end;
3592  }
3593 
3594  SigGroupBuild(de_ctx);
3595  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3596 
3597  FLOWLOCK_WRLOCK(&f);
3598  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3599  STREAM_TOSERVER, httpbuf1, httplen1);
3600  if (r != 0) {
3601  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3602  FLOWLOCK_UNLOCK(&f);
3603  goto end;
3604  }
3605  FLOWLOCK_UNLOCK(&f);
3606 
3607  /* do detect */
3608  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3609  if (PacketAlertCheck(p, 1)) {
3610  printf("sig 1 alerted: ");
3611  goto end;
3612  }
3613  p->alerts.cnt = 0;
3614 
3615  FLOWLOCK_WRLOCK(&f);
3616  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3617  STREAM_TOSERVER, httpbuf2, httplen2);
3618  if (r != 0) {
3619  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
3620  FLOWLOCK_UNLOCK(&f);
3621  goto end;
3622  }
3623  FLOWLOCK_UNLOCK(&f);
3624 
3625  /* do detect */
3626  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3627  if (PacketAlertCheck(p, 1)) {
3628  printf("sig 1 alerted (2): ");
3629  goto end;
3630  }
3631  p->alerts.cnt = 0;
3632 
3633  FLOWLOCK_WRLOCK(&f);
3634  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3635  STREAM_TOSERVER, httpbuf3, httplen3);
3636  if (r != 0) {
3637  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
3638  FLOWLOCK_UNLOCK(&f);
3639  goto end;
3640  }
3641  FLOWLOCK_UNLOCK(&f);
3642 
3643  /* do detect */
3644  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3645  if (!(PacketAlertCheck(p, 1))) {
3646  printf("sig 1 didn't alert: ");
3647  goto end;
3648  }
3649  p->alerts.cnt = 0;
3650 
3651  FLOWLOCK_WRLOCK(&f);
3652  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3653  STREAM_TOSERVER, httpbuf4, httplen4);
3654  if (r != 0) {
3655  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
3656  FLOWLOCK_UNLOCK(&f);
3657  goto end;
3658  }
3659  FLOWLOCK_UNLOCK(&f);
3660 
3661  /* do detect */
3662  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3663  if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2)) {
3664  printf("sig 1 alerted (4): ");
3665  goto end;
3666  }
3667  p->alerts.cnt = 0;
3668 
3669  FLOWLOCK_WRLOCK(&f);
3670  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3671  STREAM_TOSERVER, httpbuf5, httplen5);
3672  if (r != 0) {
3673  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
3674  FLOWLOCK_UNLOCK(&f);
3675  goto end;
3676  }
3677  FLOWLOCK_UNLOCK(&f);
3678 
3679  /* do detect */
3680  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3681  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
3682  printf("sig 1 alerted (request 2, chunk 6): ");
3683  goto end;
3684  }
3685  p->alerts.cnt = 0;
3686 
3687  SCLogDebug("sending data chunk 7");
3688 
3689  FLOWLOCK_WRLOCK(&f);
3690  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3691  STREAM_TOSERVER, httpbuf6, httplen6);
3692  if (r != 0) {
3693  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
3694  FLOWLOCK_UNLOCK(&f);
3695  goto end;
3696  }
3697  FLOWLOCK_UNLOCK(&f);
3698 
3699  /* do detect */
3700  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3701  if (PacketAlertCheck(p, 1) || !(PacketAlertCheck(p, 2))) {
3702  printf("signature 2 didn't match or sig 1 matched, but shouldn't have: ");
3703  goto end;
3704  }
3705  p->alerts.cnt = 0;
3706 
3707  HtpState *htp_state = f.alstate;
3708  if (htp_state == NULL) {
3709  printf("no http state: ");
3710  result = 0;
3711  goto end;
3712  }
3713 
3714  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
3715  printf("The http app layer doesn't have 2 transactions, but it should: ");
3716  goto end;
3717  }
3718 
3719  result = 1;
3720 end:
3721  if (alp_tctx != NULL)
3722  AppLayerParserThreadCtxFree(alp_tctx);
3723  if (det_ctx != NULL) {
3724  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
3725  }
3726  if (de_ctx != NULL) {
3727  DetectEngineCtxFree(de_ctx);
3728  }
3729 
3731  FLOW_DESTROY(&f);
3732  UTHFreePacket(p);
3733  return result;
3734 }
3735 
3736 static int DetectHttpHHTest22(void)
3737 {
3738  DetectEngineCtx *de_ctx = NULL;
3739  int result = 0;
3740 
3741  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3742  goto end;
3743 
3744  de_ctx->flags |= DE_QUIET;
3745  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3746  "(content:\"one\"; content:\"two\"; http_host; "
3747  "content:\"three\"; distance:10; http_host; content:\"four\"; sid:1;)");
3748  if (de_ctx->sig_list == NULL) {
3749  printf("de_ctx->sig_list == NULL\n");
3750  goto end;
3751  }
3752 
3753  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3754  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3755  goto end;
3756  }
3757 
3758  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
3759  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
3760  goto end;
3761  }
3762 
3763  DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3764  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3765  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
3766  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
3767  if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 ||
3768  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3769  hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
3770  memcmp(hhhd1->content, "two", hhhd1->content_len) != 0 ||
3771  hhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
3772  memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) {
3773  goto end;
3774  }
3775 
3776  if (!DETECT_CONTENT_IS_SINGLE(cd1) ||
3777  !DETECT_CONTENT_IS_SINGLE(cd2) ||
3778  DETECT_CONTENT_IS_SINGLE(hhhd1) ||
3779  DETECT_CONTENT_IS_SINGLE(hhhd2)) {
3780  goto end;
3781  }
3782 
3783  result = 1;
3784 
3785  end:
3786  DetectEngineCtxFree(de_ctx);
3787  return result;
3788 }
3789 
3790 static int DetectHttpHHTest23(void)
3791 {
3792  DetectEngineCtx *de_ctx = NULL;
3793  int result = 0;
3794 
3795  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3796  goto end;
3797 
3798  de_ctx->flags |= DE_QUIET;
3799  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3800  "(content:\"one\"; http_host; pcre:/two/; "
3801  "content:\"three\"; distance:10; http_host; content:\"four\"; sid:1;)");
3802  if (de_ctx->sig_list == NULL) {
3803  printf("de_ctx->sig_list == NULL\n");
3804  goto end;
3805  }
3806 
3807  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3808  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3809  goto end;
3810  }
3811 
3812  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
3813  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
3814  goto end;
3815  }
3816 
3817  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3818  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3819  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
3820  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
3821  if (pd1->flags != 0 ||
3822  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3823  hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
3824  memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 ||
3825  hhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
3826  memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) {
3827  goto end;
3828  }
3829 
3830  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
3831  DETECT_CONTENT_IS_SINGLE(hhhd1) ||
3832  DETECT_CONTENT_IS_SINGLE(hhhd2)) {
3833  goto end;
3834  }
3835 
3836  result = 1;
3837 
3838  end:
3839  DetectEngineCtxFree(de_ctx);
3840  return result;
3841 }
3842 
3843 static int DetectHttpHHTest24(void)
3844 {
3845  DetectEngineCtx *de_ctx = NULL;
3846  int result = 0;
3847 
3848  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3849  goto end;
3850 
3851  de_ctx->flags |= DE_QUIET;
3852  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3853  "(content:\"one\"; http_host; pcre:/two/; "
3854  "content:\"three\"; distance:10; within:15; http_host; content:\"four\"; sid:1;)");
3855  if (de_ctx->sig_list == NULL) {
3856  printf("de_ctx->sig_list == NULL\n");
3857  goto end;
3858  }
3859 
3860  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3861  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3862  goto end;
3863  }
3864 
3865  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
3866  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
3867  goto end;
3868  }
3869 
3870  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3871  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3872  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
3873  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
3874  if (pd1->flags != 0 ||
3875  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3876  hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
3877  memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 ||
3878  hhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
3879  memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) {
3880  goto end;
3881  }
3882 
3883  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
3884  DETECT_CONTENT_IS_SINGLE(hhhd1) ||
3885  DETECT_CONTENT_IS_SINGLE(hhhd2)) {
3886  goto end;
3887  }
3888 
3889  result = 1;
3890 
3891  end:
3892  DetectEngineCtxFree(de_ctx);
3893  return result;
3894 }
3895 
3896 static int DetectHttpHHTest25(void)
3897 {
3898  DetectEngineCtx *de_ctx = NULL;
3899  int result = 0;
3900 
3901  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3902  goto end;
3903 
3904  de_ctx->flags |= DE_QUIET;
3905  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3906  "(content:\"one\"; http_host; pcre:/two/; "
3907  "content:\"three\"; distance:10; http_host; "
3908  "content:\"four\"; distance:10; sid:1;)");
3909  if (de_ctx->sig_list == NULL) {
3910  printf("de_ctx->sig_list == NULL\n");
3911  goto end;
3912  }
3913 
3914  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3915  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3916  goto end;
3917  }
3918 
3919  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
3920  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
3921  goto end;
3922  }
3923 
3924  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3925  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3926  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
3927  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
3928  if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT ||
3929  cd2->flags != DETECT_CONTENT_DISTANCE ||
3930  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3931  hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
3932  memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 ||
3933  hhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
3934  memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) {
3935  goto end;
3936  }
3937 
3938  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
3939  DETECT_CONTENT_IS_SINGLE(hhhd1) ||
3940  DETECT_CONTENT_IS_SINGLE(hhhd2)) {
3941  goto end;
3942  }
3943 
3944  result = 1;
3945 
3946  end:
3947  DetectEngineCtxFree(de_ctx);
3948  return result;
3949 }
3950 
3951 static int DetectHttpHHTest26(void)
3952 {
3953  DetectEngineCtx *de_ctx = NULL;
3954  int result = 0;
3955 
3956  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3957  goto end;
3958 
3959  de_ctx->flags |= DE_QUIET;
3960  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3961  "(content:\"one\"; offset:10; http_host; pcre:/two/; "
3962  "content:\"three\"; distance:10; http_host; within:10; "
3963  "content:\"four\"; distance:10; sid:1;)");
3964  if (de_ctx->sig_list == NULL) {
3965  printf("de_ctx->sig_list == NULL\n");
3966  goto end;
3967  }
3968 
3969  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3970  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3971  goto end;
3972  }
3973 
3974  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
3975  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
3976  goto end;
3977  }
3978 
3979  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3980  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3981  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
3982  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
3983  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
3984  cd2->flags != DETECT_CONTENT_DISTANCE ||
3985  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3987  memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 ||
3988  hhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
3989  memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) {
3990  printf ("failed: http_host incorrect flags");
3991  goto end;
3992  }
3993 
3994  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
3995  DETECT_CONTENT_IS_SINGLE(hhhd1) ||
3996  DETECT_CONTENT_IS_SINGLE(hhhd2)) {
3997  goto end;
3998  }
3999 
4000  result = 1;
4001 
4002  end:
4003  DetectEngineCtxFree(de_ctx);
4004  return result;
4005 }
4006 
4007 static int DetectHttpHHTest27(void)
4008 {
4009  DetectEngineCtx *de_ctx = NULL;
4010  int result = 0;
4011 
4012  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4013  goto end;
4014 
4015  de_ctx->flags |= DE_QUIET;
4016  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4017  "(content:\"one\"; offset:10; http_host; pcre:/two/; "
4018  "content:\"three\"; distance:10; http_host; within:10; "
4019  "content:\"four\"; distance:10; sid:1;)");
4020  if (de_ctx->sig_list == NULL) {
4021  printf("de_ctx->sig_list == NULL\n");
4022  goto end;
4023  }
4024 
4025  result = 1;
4026 
4027  end:
4028  DetectEngineCtxFree(de_ctx);
4029  return result;
4030 }
4031 
4032 static int DetectHttpHHTest28(void)
4033 {
4034  DetectEngineCtx *de_ctx = NULL;
4035  int result = 0;
4036 
4037  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4038  goto end;
4039 
4040  de_ctx->flags |= DE_QUIET;
4041  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4042  "(content:\"one\"; http_host; pcre:/two/; "
4043  "content:\"three\"; http_host; depth:10; "
4044  "content:\"four\"; distance:10; sid:1;)");
4045  if (de_ctx->sig_list == NULL) {
4046  printf("de_ctx->sig_list == NULL\n");
4047  goto end;
4048  }
4049 
4050  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
4051  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
4052  goto end;
4053  }
4054 
4055  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
4056  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
4057  goto end;
4058  }
4059 
4060  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
4061  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
4062  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
4063  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
4064  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
4065  cd2->flags != DETECT_CONTENT_DISTANCE ||
4066  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
4067  hhhd1->flags != (0) ||
4068  memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 ||
4069  hhhd2->flags != (DETECT_CONTENT_DEPTH) ||
4070  memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) {
4071  goto end;
4072  }
4073 
4074  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
4075  !DETECT_CONTENT_IS_SINGLE(hhhd1) ||
4076  DETECT_CONTENT_IS_SINGLE(hhhd2)) {
4077  goto end;
4078  }
4079 
4080  result = 1;
4081 
4082  end:
4083  DetectEngineCtxFree(de_ctx);
4084  return result;
4085 }
4086 
4087 static int DetectHttpHHTest29(void)
4088 {
4089  DetectEngineCtx *de_ctx = NULL;
4090  int result = 0;
4091 
4092  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4093  goto end;
4094 
4095  de_ctx->flags |= DE_QUIET;
4096  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4097  "(content:\"one\"; http_host; "
4098  "content:\"two\"; distance:0; http_host; sid:1;)");
4099  if (de_ctx->sig_list == NULL) {
4100  printf("de_ctx->sig_list == NULL\n");
4101  goto end;
4102  }
4103 
4104  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
4105  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
4106  goto end;
4107  }
4108 
4109  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
4110  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
4111  goto end;
4112  }
4113 
4114  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
4115  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
4116  if (hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
4117  memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 ||
4118  hhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
4119  memcmp(hhhd2->content, "two", hhhd1->content_len) != 0) {
4120  goto end;
4121  }
4122 
4123  result = 1;
4124 
4125  end:
4126  DetectEngineCtxFree(de_ctx);
4127  return result;
4128 }
4129 
4130 static int DetectHttpHHTest30(void)
4131 {
4132  DetectEngineCtx *de_ctx = NULL;
4133  int result = 0;
4134 
4135  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4136  goto end;
4137 
4138  de_ctx->flags |= DE_QUIET;
4139  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4140  "(content:\"one\"; http_host; "
4141  "content:\"two\"; within:5; http_host; sid:1;)");
4142  if (de_ctx->sig_list == NULL) {
4143  printf("de_ctx->sig_list == NULL\n");
4144  goto end;
4145  }
4146 
4147  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
4148  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
4149  goto end;
4150  }
4151 
4152  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
4153  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
4154  goto end;
4155  }
4156 
4157  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
4158  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
4159  if (hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
4160  memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 ||
4161  hhhd2->flags != (DETECT_CONTENT_WITHIN) ||
4162  memcmp(hhhd2->content, "two", hhhd1->content_len) != 0) {
4163  goto end;
4164  }
4165 
4166  result = 1;
4167 
4168  end:
4169  DetectEngineCtxFree(de_ctx);
4170  return result;
4171 }
4172 
4173 static int DetectHttpHHTest31(void)
4174 {
4175  DetectEngineCtx *de_ctx = NULL;
4176  int result = 0;
4177 
4178  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4179  goto end;
4180 
4181  de_ctx->flags |= DE_QUIET;
4182  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4183  "(content:\"one\"; within:5; http_host; sid:1;)");
4184  if (de_ctx->sig_list == NULL) {
4185  printf("de_ctx->sig_list == NULL\n");
4186  goto end;
4187  }
4188 
4189  result = 1;
4190 
4191  end:
4192  DetectEngineCtxFree(de_ctx);
4193  return result;
4194 }
4195 
4196 static int DetectHttpHHTest32(void)
4197 {
4198  DetectEngineCtx *de_ctx = NULL;
4199  int result = 0;
4200 
4201  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4202  goto end;
4203 
4204  de_ctx->flags |= DE_QUIET;
4205  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4206  "(content:\"one\"; http_host; within:5; sid:1;)");
4207  if (de_ctx->sig_list == NULL) {
4208  printf("de_ctx->sig_list != NULL\n");
4209  goto end;
4210  }
4211 
4212  result = 1;
4213 
4214  end:
4215  DetectEngineCtxFree(de_ctx);
4216  return result;
4217 }
4218 
4219 static int DetectHttpHHTest33(void)
4220 {
4221  DetectEngineCtx *de_ctx = NULL;
4222  int result = 0;
4223 
4224  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4225  goto end;
4226 
4227  de_ctx->flags |= DE_QUIET;
4228  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4229  "(content:\"one\"; within:5; sid:1;)");
4230  if (de_ctx->sig_list == NULL) {
4231  printf("de_ctx->sig_list == NULL\n");
4232  goto end;
4233  }
4234 
4235  result = 1;
4236 
4237  end:
4238  DetectEngineCtxFree(de_ctx);
4239  return result;
4240 }
4241 
4242 static int DetectHttpHHTest34(void)
4243 {
4244  DetectEngineCtx *de_ctx = NULL;
4245  int result = 0;
4246 
4247  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4248  goto end;
4249 
4250  de_ctx->flags |= DE_QUIET;
4251  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4252  "(pcre:/one/W; "
4253  "content:\"two\"; within:5; http_host; sid:1;)");
4254  if (de_ctx->sig_list == NULL) {
4255  printf("de_ctx->sig_list == NULL\n");
4256  goto end;
4257  }
4258 
4259  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
4260  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
4261  goto end;
4262  }
4263 
4264  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
4265  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
4266  goto end;
4267  }
4268 
4269  if (de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id] == NULL ||
4270  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->type != DETECT_CONTENT ||
4271  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev == NULL ||
4272  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->type != DETECT_PCRE) {
4273 
4274  goto end;
4275  }
4276 
4277  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
4278  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
4279  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
4280  hhhd2->flags != (DETECT_CONTENT_WITHIN) ||
4281  memcmp(hhhd2->content, "two", hhhd2->content_len) != 0) {
4282  goto end;
4283  }
4284 
4285  result = 1;
4286 
4287  end:
4288  DetectEngineCtxFree(de_ctx);
4289  return result;
4290 }
4291 
4292 static int DetectHttpHHTest35(void)
4293 {
4294  DetectEngineCtx *de_ctx = NULL;
4295  int result = 0;
4296 
4297  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4298  goto end;
4299 
4300  de_ctx->flags |= DE_QUIET;
4301  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4302  "(content:\"two\"; http_host; "
4303  "pcre:/one/WR; sid:1;)");
4304  if (de_ctx->sig_list == NULL) {
4305  printf("de_ctx->sig_list == NULL\n");
4306  goto end;
4307  }
4308 
4309  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
4310  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
4311  goto end;
4312  }
4313 
4314  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
4315  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
4316  goto end;
4317  }
4318 
4319  if (de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id] == NULL ||
4320  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->type != DETECT_PCRE ||
4321  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev == NULL ||
4322  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->type != DETECT_CONTENT) {
4323 
4324  goto end;
4325  }
4326 
4327  DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
4328  DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
4329  if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
4330  hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
4331  memcmp(hhhd1->content, "two", hhhd1->content_len) != 0) {
4332  goto end;
4333  }
4334 
4335  result = 1;
4336 
4337  end:
4338  DetectEngineCtxFree(de_ctx);
4339  return result;
4340 }
4341 
4342 static int DetectHttpHHTest36(void)
4343 {
4344  DetectEngineCtx *de_ctx = NULL;
4345  int result = 0;
4346 
4347  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
4348  goto end;
4349 
4350  de_ctx->flags |= DE_QUIET;
4351  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4352  "(pcre:/one/W; "
4353  "content:\"two\"; distance:5; http_host; sid:1;)");
4354  if (de_ctx->sig_list == NULL) {
4355  printf("de_ctx->sig_list == NULL\n");
4356  goto end;
4357  }
4358 
4359  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
4360  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
4361  goto end;
4362  }
4363 
4364  if (de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL) {
4365  printf("de_ctx->sig_list->sm_lists[g_http_host_buffer_id] == NULL\n");
4366  goto end;
4367  }
4368 
4369  if (de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id] == NULL ||
4370  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->type != DETECT_CONTENT ||
4371  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev == NULL ||
4372  de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->type != DETECT_PCRE) {
4373 
4374  goto end;
4375  }
4376 
4377  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->prev->ctx;
4378  DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_host_buffer_id]->ctx;
4379  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
4380  hhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
4381  memcmp(hhhd2->content, "two", hhhd2->content_len) != 0) {
4382  goto end;
4383  }
4384 
4385  result = 1;
4386 
4387  end:
4388  DetectEngineCtxFree(de_ctx);
4389  return result;
4390 }
4391 
4392 /**
4393  * \test Test that a signature containting a http_raw_host is correctly parsed
4394  * and the keyword is registered.
4395  */
4396 static int DetectHttpHRHTest01(void)
4397 {
4398  DetectEngineCtx *de_ctx = NULL;
4399  int result = 0;
4400 
4401  de_ctx = DetectEngineCtxInit();
4402  if (de_ctx == NULL)
4403  goto end;
4404 
4405  de_ctx->flags |= DE_QUIET;
4406  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4407  "(msg:\"Testing http_raw_host\"; "
4408  "content:\"one\"; http_raw_host; sid:1;)");
4409  if (de_ctx->sig_list != NULL) {
4410  result = 1;
4411  } else {
4412  goto end;
4413  }
4414 
4415  end:
4416  DetectEngineCtxFree(de_ctx);
4417 
4418  return result;
4419 }
4420 
4421 /**
4422  * \test Test that a signature containing an valid http_raw_host entry is
4423  * parsed.
4424  */
4425 static int DetectHttpHRHTest02(void)
4426 {
4427  DetectEngineCtx *de_ctx = NULL;
4428  int result = 0;
4429 
4430  de_ctx = DetectEngineCtxInit();
4431  if (de_ctx == NULL)
4432  goto end;
4433 
4434  de_ctx->flags |= DE_QUIET;
4435  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4436  "(msg:\"Testing http_raw_host\"; "
4437  "content:\"one\"; http_raw_host; sid:1;)");
4438  if (de_ctx->sig_list != NULL)
4439  result = 1;
4440 
4441  end:
4442  DetectEngineCtxFree(de_ctx);
4443 
4444  return result;
4445 }
4446 
4447 /**
4448  * \test Test that an invalid signature containing no content but a
4449  * http_raw_host is invalidated.
4450  */
4451 static int DetectHttpHRHTest03(void)
4452 {
4453  DetectEngineCtx *de_ctx = NULL;
4454  int result = 0;
4455 
4456  de_ctx = DetectEngineCtxInit();
4457  if (de_ctx == NULL)
4458  goto end;
4459 
4460  de_ctx->flags |= DE_QUIET;
4461  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4462  "(msg:\"Testing http_raw_host\"; "
4463  "http_raw_host; sid:1;)");
4464  if (de_ctx->sig_list == NULL)
4465  result = 1;
4466 
4467  end:
4468  DetectEngineCtxFree(de_ctx);
4469 
4470  return result;
4471 }
4472 
4473 /**
4474  * \test Test that an invalid signature containing a rawbytes along with a
4475  * http_raw_host is invalidated.
4476  */
4477 static int DetectHttpHRHTest04(void)
4478 {
4479  DetectEngineCtx *de_ctx = NULL;
4480  int result = 0;
4481 
4482  de_ctx = DetectEngineCtxInit();
4483  if (de_ctx == NULL)
4484  goto end;
4485 
4486  de_ctx->flags |= DE_QUIET;
4487  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4488  "(msg:\"Testing http_raw_host\"; "
4489  "content:\"one\"; rawbytes; http_raw_host; sid:1;)");
4490  if (de_ctx->sig_list == NULL)
4491  result = 1;
4492 
4493  end:
4494  DetectEngineCtxFree(de_ctx);
4495 
4496  return result;
4497 }
4498 
4499 /**
4500  * \test Test that a http_raw_host with nocase is parsed.
4501  */
4502 static int DetectHttpHRHTest05(void)
4503 {
4504  DetectEngineCtx *de_ctx = NULL;
4505  int result = 0;
4506 
4507  de_ctx = DetectEngineCtxInit();
4508  if (de_ctx == NULL)
4509  goto end;
4510 
4511  de_ctx->flags |= DE_QUIET;
4512  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
4513  "(msg:\"Testing http_raw_host\"; "
4514  "content:\"one\"; http_raw_host; sid:1;)");
4515  if (de_ctx->sig_list != NULL)
4516  result = 1;
4517 
4518  end:
4519  DetectEngineCtxFree(de_ctx);
4520 
4521  return result;
4522 }
4523 
4524 /**
4525  *\test Test that the http_raw_host content matches against a http request
4526  * which holds the content.
4527  */
4528 static int DetectHttpHRHTest06(void)
4529 {
4530  TcpSession ssn;
4531  Packet *p = NULL;
4532  ThreadVars th_v;
4533  DetectEngineCtx *de_ctx = NULL;
4534  DetectEngineThreadCtx *det_ctx = NULL;
4535  HtpState *http_state = NULL;
4536  Flow f;
4537  uint8_t http_buf[] =
4538  "GET /index.html HTTP/1.0\r\n"
4539  "User-Agent: www.openinfosecfoundation.org\r\n"
4540  "Host: This is dummy message body\r\n"
4541  "Content-Type: text/html\r\n"
4542  "\r\n";
4543  uint32_t http_len = sizeof(http_buf) - 1;
4544  int result = 0;
4546 
4547  memset(&th_v, 0, sizeof(th_v));
4548  memset(&f, 0, sizeof(f));
4549  memset(&ssn, 0, sizeof(ssn));
4550 
4551  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4552 
4553  FLOW_INITIALIZE(&f);
4554  f.protoctx = (void *)&ssn;
4555  f.proto = IPPROTO_TCP;
4556  f.flags |= FLOW_IPV4;
4557 
4558  p->flow = &f;
4562  f.alproto = ALPROTO_HTTP;
4563 
4565 
4566  de_ctx = DetectEngineCtxInit();
4567  if (de_ctx == NULL)
4568  goto end;
4569 
4570  de_ctx->flags |= DE_QUIET;
4571 
4572  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4573  "(msg:\"http host test\"; "
4574  "content:\"message\"; http_raw_host; "
4575  "sid:1;)");
4576  if (de_ctx->sig_list == NULL)
4577  goto end;
4578 
4579  SigGroupBuild(de_ctx);
4580  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4581 
4582  FLOWLOCK_WRLOCK(&f);
4583  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4584  STREAM_TOSERVER, http_buf, http_len);
4585  if (r != 0) {
4586  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4587  result = 0;
4588  FLOWLOCK_UNLOCK(&f);
4589  goto end;
4590  }
4591  FLOWLOCK_UNLOCK(&f);
4592 
4593  http_state = f.alstate;
4594  if (http_state == NULL) {
4595  printf("no http state: \n");
4596  result = 0;
4597  goto end;
4598  }
4599 
4600  /* do detect */
4601  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
4602 
4603  if (!(PacketAlertCheck(p, 1))) {
4604  printf("sid 1 didn't match but should have\n");
4605  goto end;
4606  }
4607 
4608  result = 1;
4609 end:
4610  if (alp_tctx != NULL)
4611  AppLayerParserThreadCtxFree(alp_tctx);
4612  if (de_ctx != NULL)
4613  DetectEngineCtxFree(de_ctx);
4614 
4616  FLOW_DESTROY(&f);
4617  UTHFreePackets(&p, 1);
4618  return result;
4619 }
4620 
4621 /**
4622  *\test Test that the http_raw_host content matches against a http request
4623  * which holds the content.
4624  */
4625 static int DetectHttpHRHTest07(void)
4626 {
4627  TcpSession ssn;
4628  Packet *p1 = NULL;
4629  Packet *p2 = NULL;
4630  ThreadVars th_v;
4631  DetectEngineCtx *de_ctx = NULL;
4632  DetectEngineThreadCtx *det_ctx = NULL;
4633  HtpState *http_state = NULL;
4634  Flow f;
4635  uint8_t http1_buf[] =
4636  "GET /index.html HTTP/1.0\r\n"
4637  "User-Agent: www.openinfosecfoundation.org\r\n"
4638  "Host: This is dummy message";
4639  uint8_t http2_buf[] =
4640  "body1\r\n\r\n";
4641  uint32_t http1_len = sizeof(http1_buf) - 1;
4642  uint32_t http2_len = sizeof(http2_buf) - 1;
4643  int result = 0;
4645 
4646  memset(&th_v, 0, sizeof(th_v));
4647  memset(&f, 0, sizeof(f));
4648  memset(&ssn, 0, sizeof(ssn));
4649 
4650  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4651  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4652 
4653  FLOW_INITIALIZE(&f);
4654  f.protoctx = (void *)&ssn;
4655  f.proto = IPPROTO_TCP;
4656  f.flags |= FLOW_IPV4;
4657 
4658  p1->flow = &f;
4662  p2->flow = &f;
4666  f.alproto = ALPROTO_HTTP;
4667 
4669 
4670  de_ctx = DetectEngineCtxInit();
4671  if (de_ctx == NULL)
4672  goto end;
4673 
4674  de_ctx->flags |= DE_QUIET;
4675 
4676  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4677  "(msg:\"http host test\"; "
4678  "content:\"message\"; http_raw_host; "
4679  "sid:1;)");
4680  if (de_ctx->sig_list == NULL)
4681  goto end;
4682 
4683  SigGroupBuild(de_ctx);
4684  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4685 
4686  FLOWLOCK_WRLOCK(&f);
4687  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4688  STREAM_TOSERVER, http1_buf, http1_len);
4689  if (r != 0) {
4690  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4691  result = 0;
4692  FLOWLOCK_UNLOCK(&f);
4693  goto end;
4694  }
4695  FLOWLOCK_UNLOCK(&f);
4696 
4697  http_state = f.alstate;
4698  if (http_state == NULL) {
4699  printf("no http state: ");
4700  goto end;
4701  }
4702 
4703  /* do detect */
4704  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4705 
4706  if (PacketAlertCheck(p1, 1)) {
4707  printf("sid 1 matched on p1 but shouldn't have: ");
4708  goto end;
4709  }
4710 
4711  FLOWLOCK_WRLOCK(&f);
4712  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4713  STREAM_TOSERVER, http2_buf, http2_len);
4714  if (r != 0) {
4715  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4716  FLOWLOCK_UNLOCK(&f);
4717  goto end;
4718  }
4719  FLOWLOCK_UNLOCK(&f);
4720 
4721  /* do detect */
4722  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4723  if (!(PacketAlertCheck(p2, 1))) {
4724  printf("sid 1 didn't match on p2 but should have: ");
4725  goto end;
4726  }
4727 
4728  result = 1;
4729 end:
4730  if (alp_tctx != NULL)
4731  AppLayerParserThreadCtxFree(alp_tctx);
4732  if (de_ctx != NULL)
4733  DetectEngineCtxFree(de_ctx);
4734 
4736  FLOW_DESTROY(&f);
4737  UTHFreePackets(&p1, 1);
4738  UTHFreePackets(&p2, 1);
4739  return result;
4740 }
4741 
4742 /**
4743  *\test Test that the http_raw_host content matches against a http request
4744  * which holds the content.
4745  */
4746 static int DetectHttpHRHTest08(void)
4747 {
4748  TcpSession ssn;
4749  Packet *p1 = NULL;
4750  Packet *p2 = NULL;
4751  ThreadVars th_v;
4752  DetectEngineCtx *de_ctx = NULL;
4753  DetectEngineThreadCtx *det_ctx = NULL;
4754  HtpState *http_state = NULL;
4755  Flow f;
4756  uint8_t http1_buf[] =
4757  "GET /index.html HTTP/1.0\r\n"
4758  "User-Agent: www.openinfosecfoundation.org\r\n"
4759  "host: This is dummy mess";
4760  uint8_t http2_buf[] =
4761  "age body\r\n\r\n";
4762  uint32_t http1_len = sizeof(http1_buf) - 1;
4763  uint32_t http2_len = sizeof(http2_buf) - 1;
4764  int result = 0;
4766 
4767  memset(&th_v, 0, sizeof(th_v));
4768  memset(&f, 0, sizeof(f));
4769  memset(&ssn, 0, sizeof(ssn));
4770 
4771  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4772  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4773 
4774  FLOW_INITIALIZE(&f);
4775  f.protoctx = (void *)&ssn;
4776  f.proto = IPPROTO_TCP;
4777  f.flags |= FLOW_IPV4;
4778 
4779  p1->flow = &f;
4783  p2->flow = &f;
4787  f.alproto = ALPROTO_HTTP;
4788 
4790 
4791  de_ctx = DetectEngineCtxInit();
4792  if (de_ctx == NULL)
4793  goto end;
4794 
4795  de_ctx->flags |= DE_QUIET;
4796 
4797  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4798  "(msg:\"http host test\"; "
4799  "content:\"message\"; http_raw_host; "
4800  "sid:1;)");
4801  if (de_ctx->sig_list == NULL)
4802  goto end;
4803 
4804  SigGroupBuild(de_ctx);
4805  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4806 
4807  FLOWLOCK_WRLOCK(&f);
4808  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4809  STREAM_TOSERVER, http1_buf, http1_len);
4810  if (r != 0) {
4811  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4812  result = 0;
4813  FLOWLOCK_UNLOCK(&f);
4814  goto end;
4815  }
4816  FLOWLOCK_UNLOCK(&f);
4817 
4818  http_state = f.alstate;
4819  if (http_state == NULL) {
4820  printf("no http state: ");
4821  result = 0;
4822  goto end;
4823  }
4824 
4825  /* do detect */
4826  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4827 
4828  if ((PacketAlertCheck(p1, 1))) {
4829  printf("sid 1 didn't match but should have");
4830  goto end;
4831  }
4832 
4833  FLOWLOCK_WRLOCK(&f);
4834  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4835  STREAM_TOSERVER, http2_buf, http2_len);
4836  if (r != 0) {
4837  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4838  result = 0;
4839  FLOWLOCK_UNLOCK(&f);
4840  goto end;
4841  }
4842  FLOWLOCK_UNLOCK(&f);
4843 
4844  /* do detect */
4845  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4846 
4847  if (!(PacketAlertCheck(p2, 1))) {
4848  printf("sid 1 didn't match but should have");
4849  goto end;
4850  }
4851 
4852  result = 1;
4853 end:
4854  if (alp_tctx != NULL)
4855  AppLayerParserThreadCtxFree(alp_tctx);
4856  if (de_ctx != NULL)
4857  DetectEngineCtxFree(de_ctx);
4858 
4860  FLOW_DESTROY(&f);
4861  UTHFreePackets(&p1, 1);
4862  UTHFreePackets(&p2, 1);
4863  return result;
4864 }
4865 
4866 /**
4867  *\test Test that the http_raw_host content matches against a http request
4868  * which holds the content, against a cross boundary present pattern.
4869  */
4870 static int DetectHttpHRHTest09(void)
4871 {
4872  TcpSession ssn;
4873  Packet *p1 = NULL;
4874  Packet *p2 = NULL;
4875  ThreadVars th_v;
4876  DetectEngineCtx *de_ctx = NULL;
4877  DetectEngineThreadCtx *det_ctx = NULL;
4878  HtpState *http_state = NULL;
4879  Flow f;
4880  uint8_t http1_buf[] =
4881  "GET /index.html HTTP/1.0\r\n"
4882  "User-Agent: www.openinfosecfoundation.org\r\n"
4883  "Host: This is dummy body1";
4884  uint8_t http2_buf[] =
4885  "This is dummy message body2\r\n"
4886  "Content-Type: text/html\r\n"
4887  "Content-Length: 46\r\n"
4888  "\r\n"
4889  "This is dummy body1";
4890  uint32_t http1_len = sizeof(http1_buf) - 1;
4891  uint32_t http2_len = sizeof(http2_buf) - 1;
4892  int result = 0;
4894 
4895  memset(&th_v, 0, sizeof(th_v));
4896  memset(&f, 0, sizeof(f));
4897  memset(&ssn, 0, sizeof(ssn));
4898 
4899  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4900  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4901 
4902  FLOW_INITIALIZE(&f);
4903  f.protoctx = (void *)&ssn;
4904  f.proto = IPPROTO_TCP;
4905  f.flags |= FLOW_IPV4;
4906 
4907  p1->flow = &f;
4911  p2->flow = &f;
4915  f.alproto = ALPROTO_HTTP;
4916 
4918 
4919  de_ctx = DetectEngineCtxInit();
4920  if (de_ctx == NULL)
4921  goto end;
4922 
4923  de_ctx->flags |= DE_QUIET;
4924 
4925  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4926  "(msg:\"http host test\"; "
4927  "content:\"body1This\"; http_raw_host; "
4928  "sid:1;)");
4929  if (de_ctx->sig_list == NULL)
4930  goto end;
4931 
4932  SigGroupBuild(de_ctx);
4933  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4934 
4935  FLOWLOCK_WRLOCK(&f);
4936  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4937  STREAM_TOSERVER, http1_buf, http1_len);
4938  if (r != 0) {
4939  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4940  result = 0;
4941  FLOWLOCK_UNLOCK(&f);
4942  goto end;
4943  }
4944  FLOWLOCK_UNLOCK(&f);
4945 
4946  http_state = f.alstate;
4947  if (http_state == NULL) {
4948  printf("no http state: ");
4949  result = 0;
4950  goto end;
4951  }
4952 
4953  /* do detect */
4954  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4955 
4956  if ((PacketAlertCheck(p1, 1))) {
4957  printf("sid 1 didn't match but should have");
4958  goto end;
4959  }
4960 
4961  FLOWLOCK_WRLOCK(&f);
4962  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4963  STREAM_TOSERVER, http2_buf, http2_len);
4964  if (r != 0) {
4965  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4966  result = 0;
4967  FLOWLOCK_UNLOCK(&f);
4968  goto end;
4969  }
4970  FLOWLOCK_UNLOCK(&f);
4971 
4972  /* do detect */
4973  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4974 
4975  if (!(PacketAlertCheck(p2, 1))) {
4976  printf("sid 1 didn't match but should have");
4977  goto end;
4978  }
4979 
4980  result = 1;
4981 end:
4982  if (alp_tctx != NULL)
4983  AppLayerParserThreadCtxFree(alp_tctx);
4984  if (de_ctx != NULL)
4985  DetectEngineCtxFree(de_ctx);
4986 
4988  FLOW_DESTROY(&f);
4989  UTHFreePackets(&p1, 1);
4990  UTHFreePackets(&p2, 1);
4991  return result;
4992 }
4993 
4994 /**
4995  *\test Test that the http_raw_host content matches against a http request
4996  * against a case insensitive pattern.
4997  */
4998 static int DetectHttpHRHTest10(void)
4999 {
5000  TcpSession ssn;
5001  Packet *p1 = NULL;
5002  Packet *p2 = NULL;
5003  ThreadVars th_v;
5004  DetectEngineCtx *de_ctx = NULL;
5005  DetectEngineThreadCtx *det_ctx = NULL;
5006  HtpState *http_state = NULL;
5007  Flow f;
5008  uint8_t http1_buf[] =
5009  "GET /index.html HTTP/1.0\r\n"
5010  "User-Agent: www.openinfosecfoundation.org\r\n"
5011  "Host: This is dummy bodY1";
5012  uint8_t http2_buf[] =
5013  "This is dummy message body2\r\n"
5014  "Content-Type: text/html\r\n"
5015  "Content-Length: 46\r\n"
5016  "\r\n"
5017  "This is dummy bodY1";
5018  uint32_t http1_len = sizeof(http1_buf) - 1;
5019  uint32_t http2_len = sizeof(http2_buf) - 1;
5020  int result = 0;
5022 
5023  memset(&th_v, 0, sizeof(th_v));
5024  memset(&f, 0, sizeof(f));
5025  memset(&ssn, 0, sizeof(ssn));
5026 
5027  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
5028  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
5029 
5030  FLOW_INITIALIZE(&f);
5031  f.protoctx = (void *)&ssn;
5032  f.proto = IPPROTO_TCP;
5033  f.flags |= FLOW_IPV4;
5034 
5035  p1->flow = &f;
5039  p2->flow = &f;
5043  f.alproto = ALPROTO_HTTP;
5044 
5046 
5047  de_ctx = DetectEngineCtxInit();
5048  if (de_ctx == NULL)
5049  goto end;
5050 
5051  de_ctx->flags |= DE_QUIET;
5052 
5053  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
5054  "(msg:\"http host test\"; "
5055  "content:\"bodY1This\"; http_raw_host; "
5056  "sid:1;)");
5057  if (de_ctx->sig_list == NULL)
5058  goto end;
5059 
5060  SigGroupBuild(de_ctx);
5061  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
5062 
5063  FLOWLOCK_WRLOCK(&f);
5064  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5065  STREAM_TOSERVER, http1_buf, http1_len);
5066  if (r != 0) {
5067  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
5068  result = 0;
5069  FLOWLOCK_UNLOCK(&f);
5070  goto end;
5071  }
5072  FLOWLOCK_UNLOCK(&f);
5073 
5074  http_state = f.alstate;
5075  if (http_state == NULL) {
5076  printf("no http state: \n");
5077  result = 0;
5078  goto end;
5079  }
5080 
5081  /* do detect */
5082  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
5083 
5084  if ((PacketAlertCheck(p1, 1))) {
5085  printf("sid 1 didn't match but should have\n");
5086  goto end;
5087  }
5088 
5089  FLOWLOCK_WRLOCK(&f);
5090  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5091  STREAM_TOSERVER, http2_buf, http2_len);
5092  if (r != 0) {
5093  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
5094  result = 0;
5095  FLOWLOCK_UNLOCK(&f);
5096  goto end;
5097  }
5098  FLOWLOCK_UNLOCK(&f);
5099 
5100  /* do detect */
5101  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
5102 
5103  if (!(PacketAlertCheck(p2, 1))) {
5104  printf("sid 1 didn't match but should have");
5105  goto end;
5106  }
5107 
5108  result = 1;
5109 end:
5110  if (alp_tctx != NULL)
5111  AppLayerParserThreadCtxFree(alp_tctx);
5112  if (de_ctx != NULL)
5113  DetectEngineCtxFree(de_ctx);
5114 
5116  FLOW_DESTROY(&f);
5117  UTHFreePackets(&p1, 1);
5118  UTHFreePackets(&p2, 1);
5119  return result;
5120 }
5121 
5122 /**
5123  *\test Test that the negated http_raw_host content matches against a
5124  * http request which doesn't hold the content.
5125  */
5126 static int DetectHttpHRHTest11(void)
5127 {
5128  TcpSession ssn;
5129  Packet *p = NULL;
5130  ThreadVars th_v;
5131  DetectEngineCtx *de_ctx = NULL;
5132  DetectEngineThreadCtx *det_ctx = NULL;
5133  HtpState *http_state = NULL;
5134  Flow f;
5135  uint8_t http_buf[] =
5136  "GET /index.html HTTP/1.0\r\n"
5137  "User-Agent: www.openinfosecfoundation.org\r\n"
5138  "Host: This is dummy message body\r\n"
5139  "Content-Type: text/html\r\n"
5140  "\r\n";
5141  uint32_t http_len = sizeof(http_buf) - 1;
5142  int result = 0;
5144 
5145  memset(&th_v, 0, sizeof(th_v));
5146  memset(&f, 0, sizeof(f));
5147  memset(&ssn, 0, sizeof(ssn));
5148 
5149  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
5150 
5151  FLOW_INITIALIZE(&f);
5152  f.protoctx = (void *)&ssn;
5153  f.proto = IPPROTO_TCP;
5154  f.flags |= FLOW_IPV4;
5155 
5156  p->flow = &f;
5160  f.alproto = ALPROTO_HTTP;
5161 
5163 
5164  de_ctx = DetectEngineCtxInit();
5165  if (de_ctx == NULL)
5166  goto end;
5167 
5168  de_ctx->flags |= DE_QUIET;
5169 
5170  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
5171  "(msg:\"http host test\"; "
5172  "content:!\"message\"; http_raw_host; "
5173  "sid:1;)");
5174  if (de_ctx->sig_list == NULL)
5175  goto end;
5176 
5177  SigGroupBuild(de_ctx);
5178  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
5179 
5180  FLOWLOCK_WRLOCK(&f);
5181  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5182  STREAM_TOSERVER, http_buf, http_len);
5183  if (r != 0) {
5184  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
5185  result = 0;
5186  FLOWLOCK_UNLOCK(&f);
5187  goto end;
5188  }
5189  FLOWLOCK_UNLOCK(&f);
5190 
5191  http_state = f.alstate;
5192  if (http_state == NULL) {
5193  printf("no http state: ");
5194  result = 0;
5195  goto end;
5196  }
5197 
5198  /* do detect */
5199  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5200 
5201  if (PacketAlertCheck(p, 1)) {
5202  printf("sid 1 matched but shouldn't have");
5203  goto end;
5204  }
5205 
5206  result = 1;
5207 end:
5208  if (alp_tctx != NULL)
5209  AppLayerParserThreadCtxFree(alp_tctx);
5210  if (de_ctx != NULL)
5211  DetectEngineCtxFree(de_ctx);
5212 
5214  FLOW_DESTROY(&f);
5215  UTHFreePackets(&p, 1);
5216  return result;
5217 }
5218 
5219 /**
5220  *\test Negative test that the negated http_raw_host content matches against a
5221  * http request which holds hold the content.
5222  */
5223 static int DetectHttpHRHTest12(void)
5224 {
5225  TcpSession ssn;
5226  Packet *p = NULL;
5227  ThreadVars th_v;
5228  DetectEngineCtx *de_ctx = NULL;
5229  DetectEngineThreadCtx *det_ctx = NULL;
5230  HtpState *http_state = NULL;
5231  Flow f;
5232  uint8_t http_buf[] =
5233  "GET /index.html HTTP/1.0\r\n"
5234  "User-Agent: www.openinfosecfoundation.org\r\n"
5235  "Host: This is dummy body\r\n"
5236  "\r\n";
5237  uint32_t http_len = sizeof(http_buf) - 1;
5238  int result = 0;
5240 
5241  memset(&th_v, 0, sizeof(th_v));
5242  memset(&f, 0, sizeof(f));
5243  memset(&ssn, 0, sizeof(ssn));
5244 
5245  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
5246 
5247  FLOW_INITIALIZE(&f);
5248  f.protoctx = (void *)&ssn;
5249  f.proto = IPPROTO_TCP;
5250  f.flags |= FLOW_IPV4;
5251 
5252  p->flow = &f;
5256  f.alproto = ALPROTO_HTTP;
5257 
5259 
5260  de_ctx = DetectEngineCtxInit();
5261  if (de_ctx == NULL)
5262  goto end;
5263 
5264  de_ctx->flags |= DE_QUIET;
5265 
5266  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
5267  "(msg:\"http host test\"; "
5268  "content:!\"message\"; http_raw_host; "
5269  "sid:1;)");
5270  if (de_ctx->sig_list == NULL)
5271  goto end;
5272 
5273  SigGroupBuild(de_ctx);
5274  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
5275 
5276  FLOWLOCK_WRLOCK(&f);
5277  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5278  STREAM_TOSERVER, http_buf, http_len);
5279  if (r != 0) {
5280  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
5281  result = 0;
5282  FLOWLOCK_UNLOCK(&f);
5283  goto end;
5284  }
5285  FLOWLOCK_UNLOCK(&f);
5286 
5287  http_state = f.alstate;
5288  if (http_state == NULL) {
5289  printf("no http state: ");
5290  result = 0;
5291  goto end;
5292  }
5293 
5294  /* do detect */
5295  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5296 
5297  if (!(PacketAlertCheck(p, 1))) {
5298  printf("sid 1 didn't match but should have");
5299  goto end;
5300  }
5301 
5302  result = 1;
5303 end:
5304  if (alp_tctx != NULL)
5305  AppLayerParserThreadCtxFree(alp_tctx);
5306  if (de_ctx != NULL)
5307  DetectEngineCtxFree(de_ctx);
5308 
5310  FLOW_DESTROY(&f);
5311  UTHFreePackets(&p, 1);
5312  return result;
5313 }
5314 
5315 /**
5316  * \test Test that the http_raw_host content matches against a http request
5317  * which holds the content.
5318  */
5319 static int DetectHttpHRHTest13(void)
5320 {
5321  TcpSession ssn;
5322  Packet *p = NULL;
5323  ThreadVars th_v;
5324  DetectEngineCtx *de_ctx = NULL;
5325  DetectEngineThreadCtx *det_ctx = NULL;
5326  HtpState *http_state = NULL;
5327  Flow f;
5328  uint8_t http_buf[] =
5329  "GET /index.html HTTP/1.0\r\n"
5330  "User-Agent: www.openinfosecfoundation.org\r\n"
5331  "Host: longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n"
5332  "Content-Type: text/html\r\n"
5333  "\r\n";
5334  uint32_t http_len = sizeof(http_buf) - 1;
5335  int result = 0;
5337 
5338  memset(&th_v, 0, sizeof(th_v));
5339  memset(&f, 0, sizeof(f));
5340  memset(&ssn, 0, sizeof(ssn));
5341 
5342  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
5343 
5344  FLOW_INITIALIZE(&f);
5345  f.protoctx = (void *)&ssn;
5346  f.proto = IPPROTO_TCP;
5347  f.flags |= FLOW_IPV4;
5348 
5349  p->flow = &f;
5353  f.alproto = ALPROTO_HTTP;
5354 
5356 
5357  de_ctx = DetectEngineCtxInit();
5358  if (de_ctx == NULL)
5359  goto end;
5360 
5361  de_ctx->flags |= DE_QUIET;
5362 
5363  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
5364  "(msg:\"http host test\"; "
5365  "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_raw_host; "
5366  "sid:1;)");
5367  if (de_ctx->sig_list == NULL)
5368  goto end;
5369 
5370  SigGroupBuild(de_ctx);
5371  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
5372 
5373  FLOWLOCK_WRLOCK(&f);
5374  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5375  STREAM_TOSERVER, http_buf, http_len);
5376  if (r != 0) {
5377  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
5378  result = 0;
5379  FLOWLOCK_UNLOCK(&f);
5380  goto end;
5381  }
5382  FLOWLOCK_UNLOCK(&f);
5383 
5384  http_state = f.alstate;
5385  if (http_state == NULL) {
5386  printf("no http state: ");
5387  result = 0;
5388  goto end;
5389  }
5390 
5391  /* do detect */
5392  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5393 
5394  if (!(PacketAlertCheck(p, 1))) {
5395  printf("sid 1 didn't match but should have");
5396  goto end;
5397  }
5398 
5399  result = 1;
5400 end:
5401  if (alp_tctx != NULL)
5402  AppLayerParserThreadCtxFree(alp_tctx);
5403  if (de_ctx != NULL)
5404  DetectEngineCtxFree(de_ctx);
5405 
5407  FLOW_DESTROY(&f);
5408  UTHFreePackets(&p, 1);
5409  return result;
5410 }
5411 
5412 /**
5413  * \test multiple http transactions and body chunks of request handling
5414  */
5415 static int DetectHttpHRHTest14(void)
5416 {
5417  int result = 0;
5418  Signature *s = NULL;
5419  DetectEngineThreadCtx *det_ctx = NULL;
5420  ThreadVars th_v;
5421  Flow f;
5422  TcpSession ssn;
5423  Packet *p = NULL;
5424  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
5425  uint8_t httpbuf2[] = "Cookie: dummy1\r\n";
5426  uint8_t httpbuf3[] = "Host: Body one!!\r\n\r\n";
5427  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
5428  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
5429  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
5430  uint8_t httpbuf4[] = "GET /?var=val HTTP/1.1\r\n";
5431  uint8_t httpbuf5[] = "Cookie: dummy2\r\n";
5432  uint8_t httpbuf6[] = "Host: Body two\r\n\r\n";
5433  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
5434  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
5435  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
5437 
5438  memset(&th_v, 0, sizeof(th_v));
5439  memset(&f, 0, sizeof(f));
5440  memset(&ssn, 0, sizeof(ssn));
5441 
5442  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
5443 
5444  FLOW_INITIALIZE(&f);
5445  f.protoctx = (void *)&ssn;
5446  f.proto = IPPROTO_TCP;
5447  f.flags |= FLOW_IPV4;
5448 
5449  p->flow = &f;
5453  f.alproto = ALPROTO_HTTP;
5454 
5456 
5458  if (de_ctx == NULL) {
5459  goto end;
5460  }
5461 
5462  de_ctx->flags |= DE_QUIET;
5463 
5464  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy1\"; http_cookie; content:\"Body one\"; http_raw_host; sid:1; rev:1;)");
5465  if (s == NULL) {
5466  printf("sig parse failed: ");
5467  goto end;
5468  }
5469  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"dummy2\"; http_cookie; content:\"Body two\"; http_raw_host; sid:2; rev:1;)");
5470  if (s == NULL) {
5471  printf("sig2 parse failed: ");
5472  goto end;
5473  }
5474 
5475  SigGroupBuild(de_ctx);
5476  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
5477 
5478  FLOWLOCK_WRLOCK(&f);
5479  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5480  STREAM_TOSERVER, httpbuf1, httplen1);
5481  if (r != 0) {
5482  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
5483  FLOWLOCK_UNLOCK(&f);
5484  goto end;
5485  }
5486  FLOWLOCK_UNLOCK(&f);
5487 
5488  /* do detect */
5489  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5490  if (PacketAlertCheck(p, 1)) {
5491  printf("sig 1 alerted: ");
5492  goto end;
5493  }
5494  p->alerts.cnt = 0;
5495 
5496  FLOWLOCK_WRLOCK(&f);
5497  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5498  STREAM_TOSERVER, httpbuf2, httplen2);
5499  if (r != 0) {
5500  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
5501  FLOWLOCK_UNLOCK(&f);
5502  goto end;
5503  }
5504  FLOWLOCK_UNLOCK(&f);
5505 
5506  /* do detect */
5507  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5508  if (PacketAlertCheck(p, 1)) {
5509  printf("sig 1 alerted (2): ");
5510  goto end;
5511  }
5512  p->alerts.cnt = 0;
5513 
5514  FLOWLOCK_WRLOCK(&f);
5515  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5516  STREAM_TOSERVER, httpbuf3, httplen3);
5517  if (r != 0) {
5518  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
5519  FLOWLOCK_UNLOCK(&f);
5520  goto end;
5521  }
5522  FLOWLOCK_UNLOCK(&f);
5523 
5524  /* do detect */
5525  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5526  if (!(PacketAlertCheck(p, 1))) {
5527  printf("sig 1 didn't alert: ");
5528  goto end;
5529  }
5530  p->alerts.cnt = 0;
5531 
5532  FLOWLOCK_WRLOCK(&f);
5533  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5534  STREAM_TOSERVER, httpbuf4, httplen4);
5535  if (r != 0) {
5536  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
5537  FLOWLOCK_UNLOCK(&f);
5538  goto end;
5539  }
5540  FLOWLOCK_UNLOCK(&f);
5541 
5542  /* do detect */
5543  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5544  if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2)) {
5545  printf("sig 1 alerted (4): ");
5546  goto end;
5547  }
5548  p->alerts.cnt = 0;
5549 
5550  FLOWLOCK_WRLOCK(&f);
5551  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5552  STREAM_TOSERVER, httpbuf5, httplen5);
5553  if (r != 0) {
5554  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
5555  FLOWLOCK_UNLOCK(&f);
5556  goto end;
5557  }
5558  FLOWLOCK_UNLOCK(&f);
5559 
5560  /* do detect */
5561  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5562  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
5563  printf("sig 1 alerted (request 2, chunk 6): ");
5564  goto end;
5565  }
5566  p->alerts.cnt = 0;
5567 
5568  SCLogDebug("sending data chunk 7");
5569 
5570  FLOWLOCK_WRLOCK(&f);
5571  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5572  STREAM_TOSERVER, httpbuf6, httplen6);
5573  if (r != 0) {
5574  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
5575  FLOWLOCK_UNLOCK(&f);
5576  goto end;
5577  }
5578  FLOWLOCK_UNLOCK(&f);
5579 
5580  /* do detect */
5581  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
5582  if (PacketAlertCheck(p, 1) || !(PacketAlertCheck(p, 2))) {
5583  printf("signature 2 didn't match or sig 1 matched, but shouldn't have: ");
5584  goto end;
5585  }
5586  p->alerts.cnt = 0;
5587 
5588  HtpState *htp_state = f.alstate;
5589  if (htp_state == NULL) {
5590  printf("no http state: ");
5591  result = 0;
5592  goto end;
5593  }
5594 
5595  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
5596  printf("The http app layer doesn't have 2 transactions, but it should: ");
5597  goto end;
5598  }
5599 
5600  result = 1;
5601 end:
5602  if (alp_tctx != NULL)
5603  AppLayerParserThreadCtxFree(alp_tctx);
5604  if (det_ctx != NULL) {
5605  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
5606  }
5607  if (de_ctx != NULL) {
5608  DetectEngineCtxFree(de_ctx);
5609  }
5610 
5612  FLOW_DESTROY(&f);
5613  UTHFreePacket(p);
5614  return result;
5615 }
5616 
5617 static int DetectHttpHRHTest22(void)
5618 {
5619  DetectEngineCtx *de_ctx = NULL;
5620  int result = 0;
5621 
5622  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5623  goto end;
5624 
5625  de_ctx->flags |= DE_QUIET;
5626  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5627  "(content:\"one\"; content:\"two\"; http_raw_host; "
5628  "content:\"three\"; distance:10; http_raw_host; content:\"four\"; sid:1;)");
5629  if (de_ctx->sig_list == NULL) {
5630  printf("de_ctx->sig_list == NULL\n");
5631  goto end;
5632  }
5633 
5634  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
5635  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
5636  goto end;
5637  }
5638 
5639  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
5640  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
5641  goto end;
5642  }
5643 
5644  DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
5645  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
5646  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
5647  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
5648  if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 ||
5649  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
5650  hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
5651  memcmp(hrhhd1->content, "two", hrhhd1->content_len) != 0 ||
5652  hrhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
5653  memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) {
5654  goto end;
5655  }
5656 
5657  if (!DETECT_CONTENT_IS_SINGLE(cd1) ||
5658  !DETECT_CONTENT_IS_SINGLE(cd2) ||
5659  DETECT_CONTENT_IS_SINGLE(hrhhd1) ||
5660  DETECT_CONTENT_IS_SINGLE(hrhhd2)) {
5661  goto end;
5662  }
5663 
5664  result = 1;
5665 
5666  end:
5667  SigCleanSignatures(de_ctx);
5668  DetectEngineCtxFree(de_ctx);
5669  return result;
5670 }
5671 
5672 static int DetectHttpHRHTest23(void)
5673 {
5674  DetectEngineCtx *de_ctx = NULL;
5675  int result = 0;
5676 
5677  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5678  goto end;
5679 
5680  de_ctx->flags |= DE_QUIET;
5681  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5682  "(content:\"one\"; http_raw_host; pcre:/two/; "
5683  "content:\"three\"; distance:10; http_raw_host; content:\"four\"; sid:1;)");
5684  if (de_ctx->sig_list == NULL) {
5685  printf("de_ctx->sig_list == NULL\n");
5686  goto end;
5687  }
5688 
5689  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
5690  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
5691  goto end;
5692  }
5693 
5694  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
5695  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
5696  goto end;
5697  }
5698 
5699  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
5700  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
5701  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
5702  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
5703  if (pd1->flags != 0 ||
5704  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
5705  hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
5706  memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 ||
5707  hrhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
5708  memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) {
5709  goto end;
5710  }
5711 
5712  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
5713  DETECT_CONTENT_IS_SINGLE(hrhhd1) ||
5714  DETECT_CONTENT_IS_SINGLE(hrhhd2)) {
5715  goto end;
5716  }
5717 
5718  result = 1;
5719 
5720  end:
5721  SigCleanSignatures(de_ctx);
5722  DetectEngineCtxFree(de_ctx);
5723  return result;
5724 }
5725 
5726 static int DetectHttpHRHTest24(void)
5727 {
5728  DetectEngineCtx *de_ctx = NULL;
5729  int result = 0;
5730 
5731  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5732  goto end;
5733 
5734  de_ctx->flags |= DE_QUIET;
5735  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5736  "(content:\"one\"; http_raw_host; pcre:/two/; "
5737  "content:\"three\"; distance:10; within:15; http_raw_host; content:\"four\"; sid:1;)");
5738  if (de_ctx->sig_list == NULL) {
5739  printf("de_ctx->sig_list == NULL\n");
5740  goto end;
5741  }
5742 
5743  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
5744  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
5745  goto end;
5746  }
5747 
5748  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
5749  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
5750  goto end;
5751  }
5752 
5753  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
5754  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
5755  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
5756  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
5757  if (pd1->flags != 0 ||
5758  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
5759  hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
5760  memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 ||
5761  hrhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
5762  memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) {
5763  goto end;
5764  }
5765 
5766  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
5767  DETECT_CONTENT_IS_SINGLE(hrhhd1) ||
5768  DETECT_CONTENT_IS_SINGLE(hrhhd2)) {
5769  goto end;
5770  }
5771 
5772  result = 1;
5773 
5774  end:
5775  SigCleanSignatures(de_ctx);
5776  DetectEngineCtxFree(de_ctx);
5777  return result;
5778 }
5779 
5780 static int DetectHttpHRHTest25(void)
5781 {
5782  DetectEngineCtx *de_ctx = NULL;
5783  int result = 0;
5784 
5785  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5786  goto end;
5787 
5788  de_ctx->flags |= DE_QUIET;
5789  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5790  "(content:\"one\"; http_raw_host; pcre:/two/; "
5791  "content:\"three\"; distance:10; http_raw_host; "
5792  "content:\"four\"; distance:10; sid:1;)");
5793  if (de_ctx->sig_list == NULL) {
5794  printf("de_ctx->sig_list == NULL\n");
5795  goto end;
5796  }
5797 
5798  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
5799  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
5800  goto end;
5801  }
5802 
5803  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
5804  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
5805  goto end;
5806  }
5807 
5808  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
5809  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
5810  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
5811  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
5812  if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT ||
5813  cd2->flags != DETECT_CONTENT_DISTANCE ||
5814  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
5815  hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
5816  memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 ||
5817  hrhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
5818  memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) {
5819  goto end;
5820  }
5821 
5822  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
5823  DETECT_CONTENT_IS_SINGLE(hrhhd1) ||
5824  DETECT_CONTENT_IS_SINGLE(hrhhd2)) {
5825  goto end;
5826  }
5827 
5828  result = 1;
5829 
5830  end:
5831  SigCleanSignatures(de_ctx);
5832  DetectEngineCtxFree(de_ctx);
5833  return result;
5834 }
5835 
5836 static int DetectHttpHRHTest26(void)
5837 {
5838  DetectEngineCtx *de_ctx = NULL;
5839  int result = 0;
5840 
5841  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5842  goto end;
5843 
5844  de_ctx->flags |= DE_QUIET;
5845  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5846  "(content:\"one\"; offset:10; http_raw_host; pcre:/two/; "
5847  "content:\"three\"; distance:10; http_raw_host; within:10; "
5848  "content:\"four\"; distance:10; sid:1;)");
5849  if (de_ctx->sig_list == NULL) {
5850  printf("de_ctx->sig_list == NULL\n");
5851  goto end;
5852  }
5853 
5854  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
5855  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
5856  goto end;
5857  }
5858 
5859  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
5860  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
5861  goto end;
5862  }
5863 
5864  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
5865  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
5866  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
5867  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
5868  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
5869  cd2->flags != DETECT_CONTENT_DISTANCE ||
5870  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
5872  memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 ||
5873  hrhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
5874  memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) {
5875  printf ("failed: http_raw_host incorrect flags");
5876  goto end;
5877  }
5878 
5879  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
5880  DETECT_CONTENT_IS_SINGLE(hrhhd1) ||
5881  DETECT_CONTENT_IS_SINGLE(hrhhd2)) {
5882  goto end;
5883  }
5884 
5885  result = 1;
5886 
5887  end:
5888  SigCleanSignatures(de_ctx);
5889  DetectEngineCtxFree(de_ctx);
5890  return result;
5891 }
5892 
5893 static int DetectHttpHRHTest27(void)
5894 {
5895  DetectEngineCtx *de_ctx = NULL;
5896  int result = 0;
5897 
5898  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5899  goto end;
5900 
5901  de_ctx->flags |= DE_QUIET;
5902  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5903  "(content:\"one\"; offset:10; http_raw_host; pcre:/two/; "
5904  "content:\"three\"; distance:10; http_raw_host; within:10; "
5905  "content:\"four\"; distance:10; sid:1;)");
5906  if (de_ctx->sig_list == NULL) {
5907  printf("de_ctx->sig_list == NULL\n");
5908  goto end;
5909  }
5910 
5911  result = 1;
5912 
5913  end:
5914  SigCleanSignatures(de_ctx);
5915  DetectEngineCtxFree(de_ctx);
5916  return result;
5917 }
5918 
5919 static int DetectHttpHRHTest28(void)
5920 {
5921  DetectEngineCtx *de_ctx = NULL;
5922  int result = 0;
5923 
5924  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5925  goto end;
5926 
5927  de_ctx->flags |= DE_QUIET;
5928  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5929  "(content:\"one\"; http_raw_host; nocase; pcre:/two/; "
5930  "content:\"three\"; http_raw_host; depth:10; "
5931  "content:\"four\"; distance:10; sid:1;)");
5932  if (de_ctx->sig_list == NULL) {
5933  printf("de_ctx->sig_list == NULL\n");
5934  goto end;
5935  }
5936 
5937  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
5938  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
5939  goto end;
5940  }
5941 
5942  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
5943  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
5944  goto end;
5945  }
5946 
5947  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
5948  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
5949  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
5950  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
5951  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
5952  cd2->flags != DETECT_CONTENT_DISTANCE ||
5953  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
5954  hrhhd1->flags != (DETECT_CONTENT_NOCASE) ||
5955  memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 ||
5956  hrhhd2->flags != (DETECT_CONTENT_DEPTH) ||
5957  memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) {
5958  goto end;
5959  }
5960 
5961  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
5962  !DETECT_CONTENT_IS_SINGLE(hrhhd1) ||
5963  DETECT_CONTENT_IS_SINGLE(hrhhd2)) {
5964  goto end;
5965  }
5966 
5967  result = 1;
5968 
5969  end:
5970  SigCleanSignatures(de_ctx);
5971  DetectEngineCtxFree(de_ctx);
5972  return result;
5973 }
5974 
5975 static int DetectHttpHRHTest29(void)
5976 {
5977  DetectEngineCtx *de_ctx = NULL;
5978  int result = 0;
5979 
5980  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
5981  goto end;
5982 
5983  de_ctx->flags |= DE_QUIET;
5984  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
5985  "(content:\"one\"; http_raw_host; "
5986  "content:\"two\"; distance:0; http_raw_host; sid:1;)");
5987  if (de_ctx->sig_list == NULL) {
5988  printf("de_ctx->sig_list == NULL\n");
5989  goto end;
5990  }
5991 
5992  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
5993  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
5994  goto end;
5995  }
5996 
5997  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
5998  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
5999  goto end;
6000  }
6001 
6002  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
6003  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
6004  if (hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
6005  memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 ||
6006  hrhhd2->flags != (DETECT_CONTENT_DISTANCE) ||
6007  memcmp(hrhhd2->content, "two", hrhhd1->content_len) != 0) {
6008  goto end;
6009  }
6010 
6011  result = 1;
6012 
6013  end:
6014  SigCleanSignatures(de_ctx);
6015  DetectEngineCtxFree(de_ctx);
6016  return result;
6017 }
6018 
6019 static int DetectHttpHRHTest30(void)
6020 {
6021  DetectEngineCtx *de_ctx = NULL;
6022  int result = 0;
6023 
6024  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
6025  goto end;
6026 
6027  de_ctx->flags |= DE_QUIET;
6028  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
6029  "(content:\"one\"; http_raw_host; "
6030  "content:\"two\"; within:5; http_raw_host; sid:1;)");
6031  if (de_ctx->sig_list == NULL) {
6032  printf("de_ctx->sig_list == NULL\n");
6033  goto end;
6034  }
6035 
6036  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
6037  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
6038  goto end;
6039  }
6040 
6041  if (de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL) {
6042  printf("de_ctx->sig_list->sm_lists[g_http_raw_host_buffer_id] == NULL\n");
6043  goto end;
6044  }
6045 
6046  DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->prev->ctx;
6047  DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_host_buffer_id]->ctx;
6048  if (hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) ||
6049  memcmp(hrhhd1->content