suricata
detect-http-header.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 /**
26  * \file
27  *
28  * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
29  *
30  * Implements support for http_header keyword.
31  */
32 
33 #include "../suricata-common.h"
34 #include "../flow.h"
35 #include "../flow-var.h"
36 #include "../flow-util.h"
37 
38 #include "../app-layer.h"
39 #include "../app-layer-parser.h"
40 
41 #include "../app-layer-htp.h"
42 #include "../detect-http-header.h"
43 #include "../detect-http-header-common.h"
44 
45 #include "../detect-isdataat.h"
46 
47 #include "../stream-tcp.h"
48 
49 #include "../util-unittest.h"
50 #include "../util-unittest-helper.h"
51 
52 /**
53  * \test Test parser accepting valid rules and rejecting invalid rules
54  */
55 static int DetectHttpHeaderParserTest01(void)
56 {
57  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; http_header; sid:1;)", true));
58  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; nocase; http_header; sid:1;)", true));
59  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; endswith; http_header; sid:1;)", true));
60  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; startswith; http_header; sid:1;)", true));
61  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; startswith; endswith; http_header; sid:1;)", true));
62 
63  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; rawbytes; http_header; sid:1;)", false));
64  FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (http_header; sid:1;)", false));
65  FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (content:\"abc\"; http_header; sid:1;)", false));
66  PASS;
67 }
68 
69 /**
70  * \test Test parser accepting valid rules and rejecting invalid rules
71  */
72 static int DetectHttpHeaderParserTest02(void)
73 {
74  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; sid:1;)", true));
75  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; nocase; sid:1;)", true));
76  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; endswith; sid:1;)", true));
77  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; startswith; sid:1;)", true));
78  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; startswith; endswith; sid:1;)", true));
79  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; bsize:10; sid:1;)", true));
80 
81  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; rawbytes; sid:1;)", false));
82  FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (http.header; sid:1;)", false));
83  FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (http.header; content:\"abc\"; sid:1;)", false));
84  PASS;
85 }
86 
87 /**
88  * \test Test that a signature containting a http_header is correctly parsed
89  * and the keyword is registered.
90  */
91 static int DetectHttpHeaderTest01(void)
92 {
93  DetectEngineCtx *de_ctx = NULL;
94  int result = 0;
95  SigMatch *sm = NULL;
96 
97  de_ctx = DetectEngineCtxInit();
98  if (de_ctx == NULL)
99  goto end;
100 
101  de_ctx->flags |= DE_QUIET;
102  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
103  "(msg:\"Testing http_header\"; "
104  "content:\"one\"; http_header; sid:1;)");
105  if (de_ctx->sig_list != NULL) {
106  result = 1;
107  } else {
108  printf("Error parsing signature: ");
109  goto end;
110  }
111 
112  sm = de_ctx->sig_list->sm_lists[g_http_header_buffer_id];
113  if (sm != NULL) {
114  result &= (sm->type == DETECT_CONTENT);
115  result &= (sm->next == NULL);
116  } else {
117  result = 0;
118  printf("Error updating content pattern to http_header pattern: ");
119  }
120 
121 
122  end:
123  DetectEngineCtxFree(de_ctx);
124 
125  return result;
126 }
127 
128 /**
129  *\test Test that the http_header content matches against a http request
130  * which holds the content.
131  */
132 static int DetectHttpHeaderTest06(void)
133 {
134  TcpSession ssn;
135  Packet *p = NULL;
136  ThreadVars th_v;
137  DetectEngineCtx *de_ctx = NULL;
138  DetectEngineThreadCtx *det_ctx = NULL;
139  HtpState *http_state = NULL;
140  Flow f;
141  uint8_t http_buf[] =
142  "GET /index.html HTTP/1.0\r\n"
143  "Host: www.openinfosecfoundation.org\r\n"
144  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
145  "Content-Type: text/html\r\n"
146  "Content-Length: 26\r\n"
147  "\r\n"
148  "This is dummy message body\r\n";
149  uint32_t http_len = sizeof(http_buf) - 1;
150  int result = 0;
152 
153  memset(&th_v, 0, sizeof(th_v));
154  memset(&f, 0, sizeof(f));
155  memset(&ssn, 0, sizeof(ssn));
156 
157  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
158 
159  FLOW_INITIALIZE(&f);
160  f.protoctx = (void *)&ssn;
161  f.proto = IPPROTO_TCP;
162  f.flags |= FLOW_IPV4;
163  p->flow = &f;
167  f.alproto = ALPROTO_HTTP;
168 
170 
171  de_ctx = DetectEngineCtxInit();
172  if (de_ctx == NULL)
173  goto end;
174 
175  de_ctx->flags |= DE_QUIET;
176 
177  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
178  "(msg:\"http header test\"; "
179  "content:\"Content-Type: text/html\"; http_header; "
180  "sid:1;)");
181  if (de_ctx->sig_list == NULL)
182  goto end;
183 
184  SigGroupBuild(de_ctx);
185  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
186 
187  FLOWLOCK_WRLOCK(&f);
188  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
189  STREAM_TOSERVER, http_buf, http_len);
190  if (r != 0) {
191  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
192  result = 0;
193  FLOWLOCK_UNLOCK(&f);
194  goto end;
195  }
196  FLOWLOCK_UNLOCK(&f);
197 
198  http_state = f.alstate;
199  if (http_state == NULL) {
200  printf("no http state: ");
201  result = 0;
202  goto end;
203  }
204 
205  /* do detect */
206  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
207 
208  if (!(PacketAlertCheck(p, 1))) {
209  printf("sid 1 didn't match but should have: ");
210  goto end;
211  }
212 
213  result = 1;
214 end:
215  if (alp_tctx != NULL)
216  AppLayerParserThreadCtxFree(alp_tctx);
217  if (de_ctx != NULL)
218  DetectEngineCtxFree(de_ctx);
219 
221  FLOW_DESTROY(&f);
222  UTHFreePackets(&p, 1);
223  return result;
224 }
225 
226 /**
227  *\test Test that the http_header content matches against a http request
228  * which holds the content.
229  */
230 static int DetectHttpHeaderTest07(void)
231 {
232  TcpSession ssn;
233  Packet *p1 = NULL;
234  Packet *p2 = NULL;
235  ThreadVars th_v;
236  DetectEngineThreadCtx *det_ctx = NULL;
237  Flow f;
238  uint8_t http1_buf[] =
239  "GET /index.html HTTP/1.0\r\n"
240  "Host: www.openinfosecfoundation.org\r\n"
241  "User-Agent: Mozi";
242  uint8_t http2_buf[] =
243  "lla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\nContent-Type: text/html\r\n"
244  "Content-Length: 67\r\n"
245  "\r\n"
246  "This is dummy message body1";
247  uint32_t http1_len = sizeof(http1_buf) - 1;
248  uint32_t http2_len = sizeof(http2_buf) - 1;
249 
251  FAIL_IF_NULL(alp_tctx);
252 
253  memset(&th_v, 0, sizeof(th_v));
254  memset(&f, 0, sizeof(f));
255  memset(&ssn, 0, sizeof(ssn));
256 
257  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
258  FAIL_IF_NULL(p1);
259  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
260  FAIL_IF_NULL(p2);
261 
262  FLOW_INITIALIZE(&f);
263  f.protoctx = (void *)&ssn;
264  f.proto = IPPROTO_TCP;
265  f.flags |= FLOW_IPV4;
266  p1->flow = &f;
270  p2->flow = &f;
274  f.alproto = ALPROTO_HTTP;
275 
277 
279  FAIL_IF_NULL(de_ctx);
280  de_ctx->flags |= DE_QUIET;
281 
282  Signature *s = DetectEngineAppendSig(de_ctx,"alert http any any -> any any "
283  "(msg:\"http header test\"; "
284  "content:\"Mozilla\"; http_header; "
285  "sid:1;)");
286  FAIL_IF_NULL(s);
287 
288  SigGroupBuild(de_ctx);
289  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
290  FAIL_IF_NULL(det_ctx);
291 
292  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
293  STREAM_TOSERVER, http1_buf, http1_len);
294  FAIL_IF(r != 0);
295 
296  HtpState *http_state = f.alstate;
297  FAIL_IF_NULL(http_state);
298 
299  /* do detect */
300  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
301  FAIL_IF( (PacketAlertCheck(p1, 1)));
302 
303  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
304  STREAM_TOSERVER, http2_buf, http2_len);
305  FAIL_IF(r != 0);
306 
307  /* do detect */
308  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
309 
310  FAIL_IF(!(PacketAlertCheck(p2, 1)));
311 
312  AppLayerParserThreadCtxFree(alp_tctx);
313  DetectEngineCtxFree(de_ctx);
314 
316  FLOW_DESTROY(&f);
317  UTHFreePackets(&p1, 1);
318  UTHFreePackets(&p2, 1);
319  PASS;
320 }
321 
322 /**
323  *\test Test that the http_header content matches against a http request
324  * which holds the content.
325  */
326 static int DetectHttpHeaderTest08(void)
327 {
328  TcpSession ssn;
329  Packet *p1 = NULL;
330  Packet *p2 = NULL;
331  ThreadVars th_v;
332  DetectEngineCtx *de_ctx = NULL;
333  DetectEngineThreadCtx *det_ctx = NULL;
334  HtpState *http_state = NULL;
335  Flow f;
336  uint8_t http1_buf[] =
337  "GET /index.html HTTP/1.0\r\n"
338  "Host: www.openinfosecfoundation.org\r\n";
339  uint8_t http2_buf[] =
340  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
341  "Content-Type: text/html\r\n"
342  "Content-Length: 67\r\n"
343  "\r\n";
344  uint32_t http1_len = sizeof(http1_buf) - 1;
345  uint32_t http2_len = sizeof(http2_buf) - 1;
346  int result = 0;
348 
349  memset(&th_v, 0, sizeof(th_v));
350  memset(&f, 0, sizeof(f));
351  memset(&ssn, 0, sizeof(ssn));
352 
353  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
354  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
355 
356  FLOW_INITIALIZE(&f);
357  f.protoctx = (void *)&ssn;
358  f.proto = IPPROTO_TCP;
359  f.flags |= FLOW_IPV4;
360  p1->flow = &f;
364  p2->flow = &f;
368  f.alproto = ALPROTO_HTTP;
369 
371 
372  de_ctx = DetectEngineCtxInit();
373  if (de_ctx == NULL)
374  goto end;
375 
376  de_ctx->flags |= DE_QUIET;
377 
378  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
379  "(msg:\"http header test\"; "
380  "content:\"Gecko/20091221 Firefox/3.5.7\"; http_header; "
381  "sid:1;)");
382  if (de_ctx->sig_list == NULL)
383  goto end;
384 
385  SigGroupBuild(de_ctx);
386  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
387 
388  FLOWLOCK_WRLOCK(&f);
389  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
390  STREAM_TOSERVER, http1_buf, http1_len);
391  if (r != 0) {
392  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
393  result = 0;
394  FLOWLOCK_UNLOCK(&f);
395  goto end;
396  }
397  FLOWLOCK_UNLOCK(&f);
398 
399  http_state = f.alstate;
400  if (http_state == NULL) {
401  printf("no http state: ");
402  result = 0;
403  goto end;
404  }
405 
406  /* do detect */
407  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
408 
409  if ((PacketAlertCheck(p1, 1))) {
410  printf("sid 1 didn't match but should have: ");
411  goto end;
412  }
413 
414  FLOWLOCK_WRLOCK(&f);
415  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
416  STREAM_TOSERVER, http2_buf, http2_len);
417  if (r != 0) {
418  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
419  result = 0;
420  FLOWLOCK_UNLOCK(&f);
421  goto end;
422  }
423  FLOWLOCK_UNLOCK(&f);
424 
425  /* do detect */
426  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
427 
428  if (!(PacketAlertCheck(p2, 1))) {
429  printf("sid 1 didn't match but should have: ");
430  goto end;
431  }
432 
433  result = 1;
434 end:
435  if (alp_tctx != NULL)
436  AppLayerParserThreadCtxFree(alp_tctx);
437  if (de_ctx != NULL)
438  DetectEngineCtxFree(de_ctx);
439 
441  FLOW_DESTROY(&f);
442  UTHFreePackets(&p1, 1);
443  UTHFreePackets(&p2, 1);
444  return result;
445 }
446 
447 /**
448  *\test Test that the http_header content matches against a http request
449  * which holds the content, against a cross boundary present pattern.
450  */
451 static int DetectHttpHeaderTest09(void)
452 {
453  TcpSession ssn;
454  Packet *p1 = NULL;
455  Packet *p2 = NULL;
456  ThreadVars th_v;
457  DetectEngineCtx *de_ctx = NULL;
458  DetectEngineThreadCtx *det_ctx = NULL;
459  HtpState *http_state = NULL;
460  Flow f;
461  uint8_t http1_buf[] =
462  "GET /index.html HTTP/1.0\r\n"
463  "Host: www.openinfosecfoundation.org\r\n"
464  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n";
465  uint8_t http2_buf[] =
466  "Content-Type: text/html\r\n"
467  "Content-Length: 67\r\n"
468  "\r\n"
469  "This is dummy body\r\n";
470  uint32_t http1_len = sizeof(http1_buf) - 1;
471  uint32_t http2_len = sizeof(http2_buf) - 1;
472  int result = 0;
474 
475  memset(&th_v, 0, sizeof(th_v));
476  memset(&f, 0, sizeof(f));
477  memset(&ssn, 0, sizeof(ssn));
478 
479  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
480  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
481 
482  FLOW_INITIALIZE(&f);
483  f.protoctx = (void *)&ssn;
484  f.proto = IPPROTO_TCP;
485  f.flags |= FLOW_IPV4;
486  p1->flow = &f;
490  p2->flow = &f;
494  f.alproto = ALPROTO_HTTP;
495 
497 
498  de_ctx = DetectEngineCtxInit();
499  if (de_ctx == NULL)
500  goto end;
501 
502  de_ctx->flags |= DE_QUIET;
504 
505  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
506  "(msg:\"http header test\"; "
507  "content:\"Firefox/3.5.7|0D 0A|Content\"; http_header; "
508  "sid:1;)");
509  if (de_ctx->sig_list == NULL)
510  goto end;
511 
512  SigGroupBuild(de_ctx);
513  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
514 
515  FLOWLOCK_WRLOCK(&f);
516  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
517  STREAM_TOSERVER, http1_buf, http1_len);
518  if (r != 0) {
519  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
520  result = 0;
521  FLOWLOCK_UNLOCK(&f);
522  goto end;
523  }
524  FLOWLOCK_UNLOCK(&f);
525 
526  http_state = f.alstate;
527  if (http_state == NULL) {
528  printf("no http state: ");
529  result = 0;
530  goto end;
531  }
532 
533  /* do detect */
534  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
535 
536  if ((PacketAlertCheck(p1, 1))) {
537  printf("sid 1 matched but shouldn't have: ");
538  goto end;
539  }
540 
541  FLOWLOCK_WRLOCK(&f);
542  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
543  STREAM_TOSERVER, http2_buf, http2_len);
544  if (r != 0) {
545  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
546  result = 0;
547  FLOWLOCK_UNLOCK(&f);
548  goto end;
549  }
550  FLOWLOCK_UNLOCK(&f);
551 
552  /* do detect */
553  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
554 
555  if (!(PacketAlertCheck(p2, 1))) {
556  printf("sid 1 didn't match but should have: ");
557  goto end;
558  }
559 
560  result = 1;
561 end:
562  if (alp_tctx != NULL)
563  AppLayerParserThreadCtxFree(alp_tctx);
564  if (de_ctx != NULL)
565  DetectEngineCtxFree(de_ctx);
566 
568  FLOW_DESTROY(&f);
569  UTHFreePackets(&p1, 1);
570  UTHFreePackets(&p2, 1);
571  return result;
572 }
573 
574 /**
575  *\test Test that the http_header content matches against a http request
576  * against a case insensitive pattern.
577  */
578 static int DetectHttpHeaderTest10(void)
579 {
580  TcpSession ssn;
581  Packet *p1 = NULL;
582  Packet *p2 = NULL;
583  ThreadVars th_v;
584  DetectEngineCtx *de_ctx = NULL;
585  DetectEngineThreadCtx *det_ctx = NULL;
586  HtpState *http_state = NULL;
587  Flow f;
588  uint8_t http1_buf[] =
589  "GET /index.html HTTP/1.0\r\n"
590  "Host: www.openinfosecfoundation.org\r\n"
591  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n";
592  uint8_t http2_buf[] =
593  "Content-Type: text/html\r\n"
594  "Content-Length: 67\r\n"
595  "\r\n"
596  "This is dummy body";
597  uint32_t http1_len = sizeof(http1_buf) - 1;
598  uint32_t http2_len = sizeof(http2_buf) - 1;
599  int result = 0;
601 
602  memset(&th_v, 0, sizeof(th_v));
603  memset(&f, 0, sizeof(f));
604  memset(&ssn, 0, sizeof(ssn));
605 
606  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
607  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
608 
609  FLOW_INITIALIZE(&f);
610  f.protoctx = (void *)&ssn;
611  f.proto = IPPROTO_TCP;
612  f.flags |= FLOW_IPV4;
613  p1->flow = &f;
617  p2->flow = &f;
621  f.alproto = ALPROTO_HTTP;
622 
624 
625  de_ctx = DetectEngineCtxInit();
626  if (de_ctx == NULL)
627  goto end;
628 
629  de_ctx->flags |= DE_QUIET;
630 
631  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
632  "(msg:\"http header test\"; "
633  "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_header;"
634  "sid:1;)");
635  if (de_ctx->sig_list == NULL)
636  goto end;
637 
638  SigGroupBuild(de_ctx);
639  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
640 
641  FLOWLOCK_WRLOCK(&f);
642  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
643  STREAM_TOSERVER, http1_buf, http1_len);
644  if (r != 0) {
645  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
646  result = 0;
647  FLOWLOCK_UNLOCK(&f);
648  goto end;
649  }
650  FLOWLOCK_UNLOCK(&f);
651 
652  http_state = f.alstate;
653  if (http_state == NULL) {
654  printf("no http state: ");
655  result = 0;
656  goto end;
657  }
658 
659  /* do detect */
660  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
661 
662  if ((PacketAlertCheck(p1, 1))) {
663  printf("sid 1 didn't match but should have: ");
664  goto end;
665  }
666 
667  FLOWLOCK_WRLOCK(&f);
668  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
669  STREAM_TOSERVER, http2_buf, http2_len);
670  if (r != 0) {
671  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
672  result = 0;
673  FLOWLOCK_UNLOCK(&f);
674  goto end;
675  }
676  FLOWLOCK_UNLOCK(&f);
677 
678  /* do detect */
679  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
680 
681  if (!(PacketAlertCheck(p2, 1))) {
682  printf("sid 1 didn't match but should have: ");
683  goto end;
684  }
685 
686  result = 1;
687 end:
688  if (alp_tctx != NULL)
689  AppLayerParserThreadCtxFree(alp_tctx);
690  if (de_ctx != NULL)
691  DetectEngineCtxFree(de_ctx);
692 
694  FLOW_DESTROY(&f);
695  UTHFreePackets(&p1, 1);
696  UTHFreePackets(&p2, 1);
697  return result;
698 }
699 
700 /**
701  *\test Test that the negated http_header content matches against a
702  * http request which doesn't hold the content.
703  */
704 static int DetectHttpHeaderTest11(void)
705 {
706  TcpSession ssn;
707  Packet *p = NULL;
708  ThreadVars th_v;
709  DetectEngineCtx *de_ctx = NULL;
710  DetectEngineThreadCtx *det_ctx = NULL;
711  HtpState *http_state = NULL;
712  Flow f;
713  uint8_t http_buf[] =
714  "GET /index.html HTTP/1.0\r\n"
715  "Host: www.openinfosecfoundation.org\r\n"
716  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
717  "Content-Type: text/html\r\n"
718  "Content-Length: 26\r\n"
719  "\r\n"
720  "This is dummy message body\r\n";
721  uint32_t http_len = sizeof(http_buf) - 1;
722  int result = 0;
724 
725  memset(&th_v, 0, sizeof(th_v));
726  memset(&f, 0, sizeof(f));
727  memset(&ssn, 0, sizeof(ssn));
728 
729  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
730 
731  FLOW_INITIALIZE(&f);
732  f.protoctx = (void *)&ssn;
733  f.proto = IPPROTO_TCP;
734  f.flags |= FLOW_IPV4;
735  p->flow = &f;
739  f.alproto = ALPROTO_HTTP;
740 
742 
743  de_ctx = DetectEngineCtxInit();
744  if (de_ctx == NULL)
745  goto end;
746 
747  de_ctx->flags |= DE_QUIET;
748 
749  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
750  "(msg:\"http header test\"; "
751  "content:!\"lalalalala\"; http_header; "
752  "sid:1;)");
753  if (de_ctx->sig_list == NULL)
754  goto end;
755 
756  SigGroupBuild(de_ctx);
757  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
758 
759  FLOWLOCK_WRLOCK(&f);
760  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
761  STREAM_TOSERVER, http_buf, http_len);
762  if (r != 0) {
763  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
764  result = 0;
765  FLOWLOCK_UNLOCK(&f);
766  goto end;
767  }
768  FLOWLOCK_UNLOCK(&f);
769 
770  http_state = f.alstate;
771  if (http_state == NULL) {
772  printf("no http state: ");
773  result = 0;
774  goto end;
775  }
776 
777  /* do detect */
778  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
779 
780  if (!(PacketAlertCheck(p, 1))) {
781  printf("sid 1 didn't match but should have: ");
782  goto end;
783  }
784 
785  result = 1;
786 end:
787  if (alp_tctx != NULL)
788  AppLayerParserThreadCtxFree(alp_tctx);
789  if (de_ctx != NULL)
790  DetectEngineCtxFree(de_ctx);
791 
793  FLOW_DESTROY(&f);
794  UTHFreePackets(&p, 1);
795  return result;
796 }
797 
798 /**
799  *\test Negative test that the negated http_header content matches against a
800  * http request which holds hold the content.
801  */
802 static int DetectHttpHeaderTest12(void)
803 {
804  TcpSession ssn;
805  Packet *p = NULL;
806  ThreadVars th_v;
807  DetectEngineCtx *de_ctx = NULL;
808  DetectEngineThreadCtx *det_ctx = NULL;
809  HtpState *http_state = NULL;
810  Flow f;
811  uint8_t http_buf[] =
812  "GET /index.html HTTP/1.0\r\n"
813  "Host: www.openinfosecfoundation.org\r\n"
814  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
815  "Content-Type: text/html\r\n"
816  "Content-Length: 26\r\n"
817  "\r\n"
818  "This is dummy message body\r\n";
819  uint32_t http_len = sizeof(http_buf) - 1;
820  int result = 0;
822 
823  memset(&th_v, 0, sizeof(th_v));
824  memset(&f, 0, sizeof(f));
825  memset(&ssn, 0, sizeof(ssn));
826 
827  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
828 
829  FLOW_INITIALIZE(&f);
830  f.protoctx = (void *)&ssn;
831  f.proto = IPPROTO_TCP;
832  f.flags |= FLOW_IPV4;
833  p->flow = &f;
837  f.alproto = ALPROTO_HTTP;
838 
840 
841  de_ctx = DetectEngineCtxInit();
842  if (de_ctx == NULL)
843  goto end;
844 
845  de_ctx->flags |= DE_QUIET;
846 
847  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
848  "(msg:\"http header test\"; "
849  "content:!\"User-Agent: Mozilla/5.0 \"; http_header; "
850  "sid:1;)");
851  if (de_ctx->sig_list == NULL)
852  goto end;
853 
854  SigGroupBuild(de_ctx);
855  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
856 
857  FLOWLOCK_WRLOCK(&f);
858  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
859  STREAM_TOSERVER, http_buf, http_len);
860  if (r != 0) {
861  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
862  result = 0;
863  FLOWLOCK_UNLOCK(&f);
864  goto end;
865  }
866  FLOWLOCK_UNLOCK(&f);
867 
868  http_state = f.alstate;
869  if (http_state == NULL) {
870  printf("no http state: ");
871  result = 0;
872  goto end;
873  }
874 
875  /* do detect */
876  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
877 
878  if ((PacketAlertCheck(p, 1))) {
879  printf("sid 1 didn't match but should have: ");
880  goto end;
881  }
882 
883  result = 1;
884 end:
885  if (alp_tctx != NULL)
886  AppLayerParserThreadCtxFree(alp_tctx);
887  if (de_ctx != NULL)
888  DetectEngineCtxFree(de_ctx);
889 
891  FLOW_DESTROY(&f);
892  UTHFreePackets(&p, 1);
893  return result;
894 }
895 
896 /**
897  *\test Test that the http_header content matches against a http request
898  * which holds the content.
899  */
900 static int DetectHttpHeaderTest13(void)
901 {
902  TcpSession ssn;
903  Packet *p = NULL;
904  ThreadVars th_v;
905  DetectEngineCtx *de_ctx = NULL;
906  DetectEngineThreadCtx *det_ctx = NULL;
907  HtpState *http_state = NULL;
908  Flow f;
909  uint8_t http_buf[] =
910  "GET /index.html HTTP/1.0\r\n"
911  "Host: www.openinfosecfoundation.org\r\n"
912  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
913  "Content-Type: text/html\r\n"
914  "Content-Length: 100\r\n"
915  "\r\n"
916  "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n";
917  uint32_t http_len = sizeof(http_buf) - 1;
918  int result = 0;
920 
921  memset(&th_v, 0, sizeof(th_v));
922  memset(&f, 0, sizeof(f));
923  memset(&ssn, 0, sizeof(ssn));
924 
925  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
926 
927  FLOW_INITIALIZE(&f);
928  f.protoctx = (void *)&ssn;
929  f.proto = IPPROTO_TCP;
930  f.flags |= FLOW_IPV4;
931 
932  p->flow = &f;
936  f.alproto = ALPROTO_HTTP;
937 
939 
940  de_ctx = DetectEngineCtxInit();
941  if (de_ctx == NULL)
942  goto end;
943 
944  de_ctx->flags |= DE_QUIET;
945 
946  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
947  "(msg:\"http header test\"; "
948  "content:\"Host: www.openinfosecfoundation.org\"; http_header; "
949  "sid:1;)");
950  if (de_ctx->sig_list == NULL)
951  goto end;
952 
953  SigGroupBuild(de_ctx);
954  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
955 
956  FLOWLOCK_WRLOCK(&f);
957  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
958  STREAM_TOSERVER, http_buf, http_len);
959  if (r != 0) {
960  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
961  result = 0;
962  FLOWLOCK_UNLOCK(&f);
963  goto end;
964  }
965  FLOWLOCK_UNLOCK(&f);
966 
967  http_state = f.alstate;
968  if (http_state == NULL) {
969  printf("no http state: ");
970  result = 0;
971  goto end;
972  }
973 
974  /* do detect */
975  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
976 
977  if (!(PacketAlertCheck(p, 1))) {
978  printf("sid 1 didn't match but should have: ");
979  goto end;
980  }
981 
982  result = 1;
983 end:
984  if (alp_tctx != NULL)
985  AppLayerParserThreadCtxFree(alp_tctx);
986  if (de_ctx != NULL)
987  DetectEngineCtxFree(de_ctx);
988 
990  FLOW_DESTROY(&f);
991  UTHFreePackets(&p, 1);
992  return result;
993 }
994 
995 static int DetectHttpHeaderTest20(void)
996 {
997  DetectEngineCtx *de_ctx = NULL;
998  int result = 0;
999 
1000  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1001  goto end;
1002 
1003  de_ctx->flags |= DE_QUIET;
1004  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1005  "(content:\"one\"; http_header; "
1006  "content:\"two\"; distance:0; http_header; sid:1;)");
1007  if (de_ctx->sig_list == NULL) {
1008  printf("de_ctx->sig_list == NULL\n");
1009  goto end;
1010  }
1011 
1012  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1013  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1014  goto end;
1015  }
1016 
1017  if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1018  printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1019  goto end;
1020  }
1021 
1022  DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1023  DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1024  if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
1025  memcmp(hhd1->content, "one", hhd1->content_len) != 0 ||
1026  hhd2->flags != DETECT_CONTENT_DISTANCE ||
1027  memcmp(hhd2->content, "two", hhd1->content_len) != 0) {
1028  goto end;
1029  }
1030 
1031  result = 1;
1032 
1033  end:
1034  DetectEngineCtxFree(de_ctx);
1035  return result;
1036 }
1037 
1038 static int DetectHttpHeaderTest21(void)
1039 {
1040  DetectEngineCtx *de_ctx = NULL;
1041  int result = 0;
1042 
1043  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1044  goto end;
1045 
1046  de_ctx->flags |= DE_QUIET;
1047  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1048  "(content:\"one\"; http_header; "
1049  "content:\"two\"; within:5; http_header; sid:1;)");
1050  if (de_ctx->sig_list == NULL) {
1051  printf("de_ctx->sig_list == NULL\n");
1052  goto end;
1053  }
1054 
1055  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1056  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1057  goto end;
1058  }
1059 
1060  if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1061  printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1062  goto end;
1063  }
1064 
1065  DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1066  DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1067  if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
1068  memcmp(hhd1->content, "one", hhd1->content_len) != 0 ||
1069  hhd2->flags != DETECT_CONTENT_WITHIN ||
1070  memcmp(hhd2->content, "two", hhd1->content_len) != 0) {
1071  goto end;
1072  }
1073 
1074  result = 1;
1075 
1076  end:
1077  DetectEngineCtxFree(de_ctx);
1078  return result;
1079 }
1080 
1081 static int DetectHttpHeaderTest22(void)
1082 {
1083  DetectEngineCtx *de_ctx = NULL;
1084  int result = 0;
1085 
1086  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1087  goto end;
1088 
1089  de_ctx->flags |= DE_QUIET;
1090  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1091  "(content:\"one\"; within:5; http_header; sid:1;)");
1092  if (de_ctx->sig_list == NULL) {
1093  printf("de_ctx->sig_list == NULL\n");
1094  goto end;
1095  }
1096 
1097  result = 1;
1098 
1099  end:
1100  DetectEngineCtxFree(de_ctx);
1101  return result;
1102 }
1103 
1104 static int DetectHttpHeaderTest23(void)
1105 {
1106  DetectEngineCtx *de_ctx = NULL;
1107  int result = 0;
1108 
1109  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1110  goto end;
1111 
1112  de_ctx->flags |= DE_QUIET;
1113  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1114  "(content:\"one\"; http_header; within:5; sid:1;)");
1115  if (de_ctx->sig_list == NULL) {
1116  printf("de_ctx->sig_list == NULL\n");
1117  goto end;
1118  }
1119 
1120  result = 1;
1121 
1122  end:
1123  DetectEngineCtxFree(de_ctx);
1124  return result;
1125 }
1126 
1127 static int DetectHttpHeaderTest24(void)
1128 {
1129  DetectEngineCtx *de_ctx = NULL;
1130  int result = 0;
1131 
1132  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1133  goto end;
1134 
1135  de_ctx->flags |= DE_QUIET;
1136  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1137  "(content:\"one\"; within:5; sid:1;)");
1138  if (de_ctx->sig_list == NULL) {
1139  printf("de_ctx->sig_list == NULL\n");
1140  goto end;
1141  }
1142 
1143  result = 1;
1144 
1145  end:
1146  DetectEngineCtxFree(de_ctx);
1147  return result;
1148 }
1149 
1150 static int DetectHttpHeaderTest25(void)
1151 {
1152  DetectEngineCtx *de_ctx = NULL;
1153  int result = 0;
1154 
1155  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1156  goto end;
1157 
1158  de_ctx->flags |= DE_QUIET;
1159  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1160  "(pcre:/one/H; "
1161  "content:\"two\"; within:5; http_header; sid:1;)");
1162  if (de_ctx->sig_list == NULL) {
1163  printf("de_ctx->sig_list == NULL\n");
1164  goto end;
1165  }
1166 
1167  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1168  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1169  goto end;
1170  }
1171 
1172  if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1173  printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1174  goto end;
1175  }
1176 
1177  if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL ||
1178  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT ||
1179  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL ||
1180  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) {
1181 
1182  goto end;
1183  }
1184 
1185  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1186  DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1187  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
1188  hhd2->flags != DETECT_CONTENT_WITHIN ||
1189  memcmp(hhd2->content, "two", hhd2->content_len) != 0) {
1190  goto end;
1191  }
1192 
1193  result = 1;
1194 
1195  end:
1196  DetectEngineCtxFree(de_ctx);
1197  return result;
1198 }
1199 
1200 static int DetectHttpHeaderTest26(void)
1201 {
1202  DetectEngineCtx *de_ctx = NULL;
1203  int result = 0;
1204 
1205  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1206  goto end;
1207 
1208  de_ctx->flags |= DE_QUIET;
1209  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1210  "(content:\"two\"; http_header; "
1211  "pcre:/one/HR; sid:1;)");
1212  if (de_ctx->sig_list == NULL) {
1213  printf("de_ctx->sig_list == NULL\n");
1214  goto end;
1215  }
1216 
1217  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1218  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1219  goto end;
1220  }
1221 
1222  if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1223  printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1224  goto end;
1225  }
1226 
1227  if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL ||
1228  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_PCRE ||
1229  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL ||
1230  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_CONTENT) {
1231 
1232  goto end;
1233  }
1234 
1235  DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1236  DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1237  if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
1239  memcmp(hhd1->content, "two", hhd1->content_len) != 0) {
1240  goto end;
1241  }
1242 
1243  result = 1;
1244 
1245  end:
1246  DetectEngineCtxFree(de_ctx);
1247  return result;
1248 }
1249 
1250 static int DetectHttpHeaderTest27(void)
1251 {
1252  DetectEngineCtx *de_ctx = NULL;
1253  int result = 0;
1254 
1255  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1256  goto end;
1257 
1258  de_ctx->flags |= DE_QUIET;
1259  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1260  "(pcre:/one/H; "
1261  "content:\"two\"; distance:5; http_header; sid:1;)");
1262  if (de_ctx->sig_list == NULL) {
1263  printf("de_ctx->sig_list == NULL\n");
1264  goto end;
1265  }
1266 
1267  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1268  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1269  goto end;
1270  }
1271 
1272  if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1273  printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1274  goto end;
1275  }
1276 
1277  if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL ||
1278  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT ||
1279  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL ||
1280  de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) {
1281 
1282  goto end;
1283  }
1284 
1285  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1286  DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1287  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
1288  hhd2->flags != DETECT_CONTENT_DISTANCE ||
1289  memcmp(hhd2->content, "two", hhd2->content_len) != 0) {
1290  goto end;
1291  }
1292 
1293  result = 1;
1294 
1295  end:
1296  DetectEngineCtxFree(de_ctx);
1297  return result;
1298 }
1299 
1300 /** \test app-layer-event:http.host_header_ambiguous should not be set
1301  * \bug 640*/
1302 static int DetectHttpHeaderTest28(void)
1303 {
1304  TcpSession ssn;
1305  Packet *p = NULL;
1306  ThreadVars th_v;
1307  DetectEngineCtx *de_ctx = NULL;
1308  DetectEngineThreadCtx *det_ctx = NULL;
1309  Flow f;
1310  uint8_t http_buf[] =
1311  "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n"
1312  "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n"
1313  "Host: xxx.intranet.local:8000\r\n"
1314  "\r\n";
1315  uint32_t http_len = sizeof(http_buf) - 1;
1316  int result = 0;
1318 
1319  memset(&th_v, 0, sizeof(th_v));
1320  memset(&f, 0, sizeof(f));
1321  memset(&ssn, 0, sizeof(ssn));
1322 
1323  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1324 
1325  FLOW_INITIALIZE(&f);
1326  f.protoctx = (void *)&ssn;
1327  f.proto = IPPROTO_TCP;
1328  f.flags |= FLOW_IPV4;
1329  p->flow = &f;
1333  f.alproto = ALPROTO_HTTP;
1334 
1336 
1337  de_ctx = DetectEngineCtxInit();
1338  if (de_ctx == NULL)
1339  goto end;
1340 
1341  de_ctx->flags |= DE_QUIET;
1342 
1343  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1344  "(app-layer-event:http.host_header_ambiguous; "
1345  "sid:1;)");
1346  if (de_ctx->sig_list == NULL)
1347  goto end;
1348 
1349  SigGroupBuild(de_ctx);
1350  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1351 
1352  FLOWLOCK_WRLOCK(&f);
1353  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1354  STREAM_TOSERVER, http_buf, http_len);
1355  if (r != 0) {
1356  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1357  result = 0;
1358  FLOWLOCK_UNLOCK(&f);
1359  goto end;
1360  }
1361  FLOWLOCK_UNLOCK(&f);
1362 
1363  /* do detect */
1364  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1365 
1366  if (PacketAlertCheck(p, 1)) {
1367  printf("sid 1 matched but shouldnt have: ");
1368  goto end;
1369  }
1370 
1371  result = 1;
1372  end:
1373  if (alp_tctx != NULL)
1374  AppLayerParserThreadCtxFree(alp_tctx);
1375  if (de_ctx != NULL)
1376  DetectEngineCtxFree(de_ctx);
1377 
1379  FLOW_DESTROY(&f);
1380  UTHFreePackets(&p, 1);
1381  return result;
1382 }
1383 
1384 /** \test app-layer-event:http.host_header_ambiguous should be set
1385  * \bug 640*/
1386 static int DetectHttpHeaderTest29(void)
1387 {
1388  TcpSession ssn;
1389  Packet *p = NULL;
1390  ThreadVars th_v;
1391  DetectEngineCtx *de_ctx = NULL;
1392  DetectEngineThreadCtx *det_ctx = NULL;
1393  Flow f;
1394  uint8_t http_buf[] =
1395  "POST http://xxx.intranet.local:8001/xxx HTTP/1.1\r\n"
1396  "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n"
1397  "Host: xxx.intranet.local:8000\r\n"
1398  "\r\n";
1399  uint32_t http_len = sizeof(http_buf) - 1;
1400  int result = 0;
1402 
1403  memset(&th_v, 0, sizeof(th_v));
1404  memset(&f, 0, sizeof(f));
1405  memset(&ssn, 0, sizeof(ssn));
1406 
1407  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1408 
1409  FLOW_INITIALIZE(&f);
1410  f.protoctx = (void *)&ssn;
1411  f.proto = IPPROTO_TCP;
1412  f.flags |= FLOW_IPV4;
1413  p->flow = &f;
1417  f.alproto = ALPROTO_HTTP;
1418 
1420 
1421  de_ctx = DetectEngineCtxInit();
1422  if (de_ctx == NULL)
1423  goto end;
1424 
1425  de_ctx->flags |= DE_QUIET;
1426 
1427  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1428  "(app-layer-event:http.host_header_ambiguous; "
1429  "sid:1;)");
1430  if (de_ctx->sig_list == NULL)
1431  goto end;
1432 
1433  SigGroupBuild(de_ctx);
1434  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1435 
1436  FLOWLOCK_WRLOCK(&f);
1437  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1438  STREAM_TOSERVER, http_buf, http_len);
1439  if (r != 0) {
1440  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1441  result = 0;
1442  FLOWLOCK_UNLOCK(&f);
1443  goto end;
1444  }
1445  FLOWLOCK_UNLOCK(&f);
1446 
1447  /* do detect */
1448  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1449 
1450  if (!(PacketAlertCheck(p, 1))) {
1451  printf("sid 1 didn't match but should have: ");
1452  goto end;
1453  }
1454 
1455  result = 1;
1456  end:
1457  if (alp_tctx != NULL)
1458  AppLayerParserThreadCtxFree(alp_tctx);
1459  if (de_ctx != NULL)
1460  DetectEngineCtxFree(de_ctx);
1461 
1463  FLOW_DESTROY(&f);
1464  UTHFreePackets(&p, 1);
1465  return result;
1466 }
1467 
1468 /** \test app-layer-event:http.host_header_ambiguous should be set
1469  * \bug 640*/
1470 static int DetectHttpHeaderTest30(void)
1471 {
1472  TcpSession ssn;
1473  Packet *p = NULL;
1474  ThreadVars th_v;
1475  DetectEngineCtx *de_ctx = NULL;
1476  DetectEngineThreadCtx *det_ctx = NULL;
1477  Flow f;
1478  uint8_t http_buf[] =
1479  "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n"
1480  "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n"
1481  "Host: xyz.intranet.local:8000\r\n"
1482  "\r\n";
1483  uint32_t http_len = sizeof(http_buf) - 1;
1484  int result = 0;
1486 
1487  memset(&th_v, 0, sizeof(th_v));
1488  memset(&f, 0, sizeof(f));
1489  memset(&ssn, 0, sizeof(ssn));
1490 
1491  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1492 
1493  FLOW_INITIALIZE(&f);
1494  f.protoctx = (void *)&ssn;
1495  f.proto = IPPROTO_TCP;
1496  f.flags |= FLOW_IPV4;
1497  p->flow = &f;
1501  f.alproto = ALPROTO_HTTP;
1502 
1504 
1505  de_ctx = DetectEngineCtxInit();
1506  if (de_ctx == NULL)
1507  goto end;
1508 
1509  de_ctx->flags |= DE_QUIET;
1510 
1511  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1512  "(app-layer-event:http.host_header_ambiguous; "
1513  "sid:1;)");
1514  if (de_ctx->sig_list == NULL)
1515  goto end;
1516 
1517  SigGroupBuild(de_ctx);
1518  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1519 
1520  FLOWLOCK_WRLOCK(&f);
1521  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1522  STREAM_TOSERVER, http_buf, http_len);
1523  if (r != 0) {
1524  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1525  result = 0;
1526  FLOWLOCK_UNLOCK(&f);
1527  goto end;
1528  }
1529  FLOWLOCK_UNLOCK(&f);
1530 
1531  /* do detect */
1532  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1533 
1534  if (!(PacketAlertCheck(p, 1))) {
1535  printf("sid 1 didn't match but should have: ");
1536  goto end;
1537  }
1538 
1539  result = 1;
1540  end:
1541  if (alp_tctx != NULL)
1542  AppLayerParserThreadCtxFree(alp_tctx);
1543  if (de_ctx != NULL)
1544  DetectEngineCtxFree(de_ctx);
1545 
1547  FLOW_DESTROY(&f);
1548  UTHFreePackets(&p, 1);
1549  return result;
1550 }
1551 
1552 static int DetectHttpHeaderIsdataatParseTest(void)
1553 {
1555  FAIL_IF_NULL(de_ctx);
1556  de_ctx->flags |= DE_QUIET;
1557 
1558  Signature *s = DetectEngineAppendSig(de_ctx,
1559  "alert tcp any any -> any any ("
1560  "flow:to_server; "
1561  "content:\"one\"; http_header; "
1562  "isdataat:!4,relative; sid:1;)");
1563  FAIL_IF_NULL(s);
1564 
1565  SigMatch *sm = s->init_data->smlists_tail[g_http_header_buffer_id];
1566  FAIL_IF_NULL(sm);
1568 
1569  DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
1572  FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
1573 
1574  DetectEngineCtxFree(de_ctx);
1575  PASS;
1576 }
1577 
1578 /**
1579  *\test Test that the http_header content matches against a http request
1580  * which holds the content.
1581  */
1582 static int DetectEngineHttpHeaderTest01(void)
1583 {
1584  TcpSession ssn;
1585  Packet *p = NULL;
1586  ThreadVars th_v;
1587  DetectEngineCtx *de_ctx = NULL;
1588  DetectEngineThreadCtx *det_ctx = NULL;
1589  HtpState *http_state = NULL;
1590  Flow f;
1591  uint8_t http_buf[] =
1592  "GET /index.html HTTP/1.0\r\n"
1593  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1594  uint32_t http_len = sizeof(http_buf) - 1;
1595  int result = 0;
1597 
1598  memset(&th_v, 0, sizeof(th_v));
1599  memset(&f, 0, sizeof(f));
1600  memset(&ssn, 0, sizeof(ssn));
1601 
1602  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1603 
1604  FLOW_INITIALIZE(&f);
1605  f.protoctx = (void *)&ssn;
1606  f.proto = IPPROTO_TCP;
1607  f.flags |= FLOW_IPV4;
1608  p->flow = &f;
1612  f.alproto = ALPROTO_HTTP;
1613 
1615 
1616  de_ctx = DetectEngineCtxInit();
1617  if (de_ctx == NULL)
1618  goto end;
1619 
1620  de_ctx->flags |= DE_QUIET;
1621 
1622  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1623  "(msg:\"http header test\"; "
1624  "content:\"one\"; http_header; "
1625  "sid:1;)");
1626  if (de_ctx->sig_list == NULL)
1627  goto end;
1628 
1629  SigGroupBuild(de_ctx);
1630  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1631 
1632  FLOWLOCK_WRLOCK(&f);
1633  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1634  STREAM_TOSERVER, http_buf, http_len);
1635  if (r != 0) {
1636  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1637  result = 0;
1638  FLOWLOCK_UNLOCK(&f);
1639  goto end;
1640  }
1641  FLOWLOCK_UNLOCK(&f);
1642 
1643  http_state = f.alstate;
1644  if (http_state == NULL) {
1645  printf("no http state: ");
1646  result = 0;
1647  goto end;
1648  }
1649 
1650  /* do detect */
1651  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1652 
1653  if (!(PacketAlertCheck(p, 1))) {
1654  printf("sid 1 didn't match but should have: ");
1655  goto end;
1656  }
1657 
1658  result = 1;
1659 end:
1660  if (alp_tctx != NULL)
1661  AppLayerParserThreadCtxFree(alp_tctx);
1662  if (de_ctx != NULL)
1663  DetectEngineCtxFree(de_ctx);
1664 
1666  FLOW_DESTROY(&f);
1667  UTHFreePackets(&p, 1);
1668  return result;
1669 }
1670 
1671 /**
1672  *\test Test that the http_header content matches against a http request
1673  * which holds the content.
1674  */
1675 static int DetectEngineHttpHeaderTest02(void)
1676 {
1677  TcpSession ssn;
1678  Packet *p = NULL;
1679  ThreadVars th_v;
1680  DetectEngineCtx *de_ctx = NULL;
1681  DetectEngineThreadCtx *det_ctx = NULL;
1682  HtpState *http_state = NULL;
1683  Flow f;
1684  uint8_t http_buf[] =
1685  "GET /index.html HTTP/1.0\r\n"
1686  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1687  uint32_t http_len = sizeof(http_buf) - 1;
1688  int result = 0;
1690 
1691  memset(&th_v, 0, sizeof(th_v));
1692  memset(&f, 0, sizeof(f));
1693  memset(&ssn, 0, sizeof(ssn));
1694 
1695  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1696 
1697  FLOW_INITIALIZE(&f);
1698  f.protoctx = (void *)&ssn;
1699  f.proto = IPPROTO_TCP;
1700  f.flags |= FLOW_IPV4;
1701  p->flow = &f;
1705  f.alproto = ALPROTO_HTTP;
1706 
1708 
1709  de_ctx = DetectEngineCtxInit();
1710  if (de_ctx == NULL)
1711  goto end;
1712 
1713  de_ctx->flags |= DE_QUIET;
1714 
1715  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1716  "(msg:\"http header test\"; "
1717  "content:\"one\"; depth:15; http_header; "
1718  "sid:1;)");
1719  if (de_ctx->sig_list == NULL)
1720  goto end;
1721 
1722  SigGroupBuild(de_ctx);
1723  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1724 
1725  FLOWLOCK_WRLOCK(&f);
1726  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1727  STREAM_TOSERVER, http_buf, http_len);
1728  if (r != 0) {
1729  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1730  result = 0;
1731  FLOWLOCK_UNLOCK(&f);
1732  goto end;
1733  }
1734  FLOWLOCK_UNLOCK(&f);
1735 
1736  http_state = f.alstate;
1737  if (http_state == NULL) {
1738  printf("no http state: ");
1739  result = 0;
1740  goto end;
1741  }
1742 
1743  /* do detect */
1744  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1745 
1746  if (!(PacketAlertCheck(p, 1))) {
1747  printf("sid 1 didn't match but should have: ");
1748  goto end;
1749  }
1750 
1751  result = 1;
1752 end:
1753  if (alp_tctx != NULL)
1754  AppLayerParserThreadCtxFree(alp_tctx);
1755  if (de_ctx != NULL)
1756  DetectEngineCtxFree(de_ctx);
1757 
1759  FLOW_DESTROY(&f);
1760  UTHFreePackets(&p, 1);
1761  return result;
1762 }
1763 
1764 /**
1765  *\test Test that the http_header content matches against a http request
1766  * which holds the content.
1767  */
1768 static int DetectEngineHttpHeaderTest03(void)
1769 {
1770  TcpSession ssn;
1771  Packet *p = NULL;
1772  ThreadVars th_v;
1773  DetectEngineCtx *de_ctx = NULL;
1774  DetectEngineThreadCtx *det_ctx = NULL;
1775  HtpState *http_state = NULL;
1776  Flow f;
1777  uint8_t http_buf[] =
1778  "GET /index.html HTTP/1.0\r\n"
1779  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1780  uint32_t http_len = sizeof(http_buf) - 1;
1781  int result = 0;
1783 
1784  memset(&th_v, 0, sizeof(th_v));
1785  memset(&f, 0, sizeof(f));
1786  memset(&ssn, 0, sizeof(ssn));
1787 
1788  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1789 
1790  FLOW_INITIALIZE(&f);
1791  f.protoctx = (void *)&ssn;
1792  f.proto = IPPROTO_TCP;
1793  f.flags |= FLOW_IPV4;
1794  p->flow = &f;
1798  f.alproto = ALPROTO_HTTP;
1799 
1801 
1802  de_ctx = DetectEngineCtxInit();
1803  if (de_ctx == NULL)
1804  goto end;
1805 
1806  de_ctx->flags |= DE_QUIET;
1807 
1808  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1809  "(msg:\"http header test\"; "
1810  "content:!\"one\"; depth:5; http_header; "
1811  "sid:1;)");
1812  if (de_ctx->sig_list == NULL)
1813  goto end;
1814 
1815  SigGroupBuild(de_ctx);
1816  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1817 
1818  FLOWLOCK_WRLOCK(&f);
1819  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1820  STREAM_TOSERVER, http_buf, http_len);
1821  if (r != 0) {
1822  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1823  result = 0;
1824  FLOWLOCK_UNLOCK(&f);
1825  goto end;
1826  }
1827  FLOWLOCK_UNLOCK(&f);
1828 
1829  http_state = f.alstate;
1830  if (http_state == NULL) {
1831  printf("no http state: ");
1832  result = 0;
1833  goto end;
1834  }
1835 
1836  /* do detect */
1837  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1838 
1839  if (!(PacketAlertCheck(p, 1))) {
1840  printf("sid 1 didn't match but should have: ");
1841  goto end;
1842  }
1843 
1844  result = 1;
1845 end:
1846  if (alp_tctx != NULL)
1847  AppLayerParserThreadCtxFree(alp_tctx);
1848  if (de_ctx != NULL)
1849  DetectEngineCtxFree(de_ctx);
1850 
1852  FLOW_DESTROY(&f);
1853  UTHFreePackets(&p, 1);
1854  return result;
1855 }
1856 
1857 /**
1858  *\test Test that the http_header content matches against a http request
1859  * which holds the content.
1860  */
1861 static int DetectEngineHttpHeaderTest04(void)
1862 {
1863  TcpSession ssn;
1864  Packet *p = NULL;
1865  ThreadVars th_v;
1866  DetectEngineCtx *de_ctx = NULL;
1867  DetectEngineThreadCtx *det_ctx = NULL;
1868  HtpState *http_state = NULL;
1869  Flow f;
1870  uint8_t http_buf[] =
1871  "GET /index.html HTTP/1.0\r\n"
1872  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1873  uint32_t http_len = sizeof(http_buf) - 1;
1874  int result = 0;
1876 
1877  memset(&th_v, 0, sizeof(th_v));
1878  memset(&f, 0, sizeof(f));
1879  memset(&ssn, 0, sizeof(ssn));
1880 
1881  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1882 
1883  FLOW_INITIALIZE(&f);
1884  f.protoctx = (void *)&ssn;
1885  f.proto = IPPROTO_TCP;
1886  f.flags |= FLOW_IPV4;
1887  p->flow = &f;
1891  f.alproto = ALPROTO_HTTP;
1892 
1894 
1895  de_ctx = DetectEngineCtxInit();
1896  if (de_ctx == NULL)
1897  goto end;
1898 
1899  de_ctx->flags |= DE_QUIET;
1900 
1901  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1902  "(msg:\"http header test\"; "
1903  "content:\"one\"; depth:5; http_header; "
1904  "sid:1;)");
1905  if (de_ctx->sig_list == NULL)
1906  goto end;
1907 
1908  SigGroupBuild(de_ctx);
1909  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1910 
1911  FLOWLOCK_WRLOCK(&f);
1912  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1913  STREAM_TOSERVER, http_buf, http_len);
1914  if (r != 0) {
1915  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1916  result = 0;
1917  FLOWLOCK_UNLOCK(&f);
1918  goto end;
1919  }
1920  FLOWLOCK_UNLOCK(&f);
1921 
1922  http_state = f.alstate;
1923  if (http_state == NULL) {
1924  printf("no http state: ");
1925  result = 0;
1926  goto end;
1927  }
1928 
1929  /* do detect */
1930  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1931 
1932  if (PacketAlertCheck(p, 1)) {
1933  printf("sid 1 matched but shouldn't have: ");
1934  goto end;
1935  }
1936 
1937  result = 1;
1938 end:
1939  if (alp_tctx != NULL)
1940  AppLayerParserThreadCtxFree(alp_tctx);
1941  if (de_ctx != NULL)
1942  DetectEngineCtxFree(de_ctx);
1943 
1945  FLOW_DESTROY(&f);
1946  UTHFreePackets(&p, 1);
1947  return result;
1948 }
1949 
1950 /**
1951  *\test Test that the http_header content matches against a http request
1952  * which holds the content.
1953  */
1954 static int DetectEngineHttpHeaderTest05(void)
1955 {
1956  TcpSession ssn;
1957  Packet *p = NULL;
1958  ThreadVars th_v;
1959  DetectEngineCtx *de_ctx = NULL;
1960  DetectEngineThreadCtx *det_ctx = NULL;
1961  HtpState *http_state = NULL;
1962  Flow f;
1963  uint8_t http_buf[] =
1964  "GET /index.html HTTP/1.0\r\n"
1965  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1966  uint32_t http_len = sizeof(http_buf) - 1;
1967  int result = 0;
1969 
1970  memset(&th_v, 0, sizeof(th_v));
1971  memset(&f, 0, sizeof(f));
1972  memset(&ssn, 0, sizeof(ssn));
1973 
1974  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1975 
1976  FLOW_INITIALIZE(&f);
1977  f.protoctx = (void *)&ssn;
1978  f.proto = IPPROTO_TCP;
1979  f.flags |= FLOW_IPV4;
1980  p->flow = &f;
1984  f.alproto = ALPROTO_HTTP;
1985 
1987 
1988  de_ctx = DetectEngineCtxInit();
1989  if (de_ctx == NULL)
1990  goto end;
1991 
1992  de_ctx->flags |= DE_QUIET;
1993 
1994  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1995  "(msg:\"http header test\"; "
1996  "content:!\"one\"; depth:15; http_header; "
1997  "sid:1;)");
1998  if (de_ctx->sig_list == NULL)
1999  goto end;
2000 
2001  SigGroupBuild(de_ctx);
2002  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2003 
2004  FLOWLOCK_WRLOCK(&f);
2005  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2006  STREAM_TOSERVER, http_buf, http_len);
2007  if (r != 0) {
2008  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2009  result = 0;
2010  FLOWLOCK_UNLOCK(&f);
2011  goto end;
2012  }
2013  FLOWLOCK_UNLOCK(&f);
2014 
2015  http_state = f.alstate;
2016  if (http_state == NULL) {
2017  printf("no http state: ");
2018  result = 0;
2019  goto end;
2020  }
2021 
2022  /* do detect */
2023  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2024 
2025  if (PacketAlertCheck(p, 1)) {
2026  printf("sid 1 matched but shouldn't have: ");
2027  goto end;
2028  }
2029 
2030  result = 1;
2031 end:
2032  if (alp_tctx != NULL)
2033  AppLayerParserThreadCtxFree(alp_tctx);
2034  if (de_ctx != NULL)
2035  DetectEngineCtxFree(de_ctx);
2036 
2038  FLOW_DESTROY(&f);
2039  UTHFreePackets(&p, 1);
2040  return result;
2041 }
2042 
2043 /**
2044  *\test Test that the http_header content matches against a http request
2045  * which holds the content.
2046  */
2047 static int DetectEngineHttpHeaderTest06(void)
2048 {
2049  TcpSession ssn;
2050  Packet *p = NULL;
2051  ThreadVars th_v;
2052  DetectEngineCtx *de_ctx = NULL;
2053  DetectEngineThreadCtx *det_ctx = NULL;
2054  HtpState *http_state = NULL;
2055  Flow f;
2056  uint8_t http_buf[] =
2057  "GET /index.html HTTP/1.0\r\n"
2058  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2059  uint32_t http_len = sizeof(http_buf) - 1;
2060  int result = 0;
2062 
2063  memset(&th_v, 0, sizeof(th_v));
2064  memset(&f, 0, sizeof(f));
2065  memset(&ssn, 0, sizeof(ssn));
2066 
2067  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2068 
2069  FLOW_INITIALIZE(&f);
2070  f.protoctx = (void *)&ssn;
2071  f.proto = IPPROTO_TCP;
2072  f.flags |= FLOW_IPV4;
2073  p->flow = &f;
2077  f.alproto = ALPROTO_HTTP;
2078 
2080 
2081  de_ctx = DetectEngineCtxInit();
2082  if (de_ctx == NULL)
2083  goto end;
2084 
2085  de_ctx->flags |= DE_QUIET;
2086 
2087  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2088  "(msg:\"http header test\"; "
2089  "content:\"one\"; offset:10; http_header; "
2090  "sid:1;)");
2091  if (de_ctx->sig_list == NULL)
2092  goto end;
2093 
2094  SigGroupBuild(de_ctx);
2095  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2096 
2097  FLOWLOCK_WRLOCK(&f);
2098  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2099  STREAM_TOSERVER, http_buf, http_len);
2100  if (r != 0) {
2101  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2102  result = 0;
2103  FLOWLOCK_UNLOCK(&f);
2104  goto end;
2105  }
2106  FLOWLOCK_UNLOCK(&f);
2107 
2108  http_state = f.alstate;
2109  if (http_state == NULL) {
2110  printf("no http state: ");
2111  result = 0;
2112  goto end;
2113  }
2114 
2115  /* do detect */
2116  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2117 
2118  if (!(PacketAlertCheck(p, 1))) {
2119  printf("sid 1 didn't match but should have: ");
2120  goto end;
2121  }
2122 
2123  result = 1;
2124 end:
2125  if (alp_tctx != NULL)
2126  AppLayerParserThreadCtxFree(alp_tctx);
2127  if (de_ctx != NULL)
2128  DetectEngineCtxFree(de_ctx);
2129 
2131  FLOW_DESTROY(&f);
2132  UTHFreePackets(&p, 1);
2133  return result;
2134 }
2135 
2136 /**
2137  *\test Test that the http_header content matches against a http request
2138  * which holds the content.
2139  */
2140 static int DetectEngineHttpHeaderTest07(void)
2141 {
2142  TcpSession ssn;
2143  Packet *p = NULL;
2144  ThreadVars th_v;
2145  DetectEngineCtx *de_ctx = NULL;
2146  DetectEngineThreadCtx *det_ctx = NULL;
2147  HtpState *http_state = NULL;
2148  Flow f;
2149  uint8_t http_buf[] =
2150  "GET /index.html HTTP/1.0\r\n"
2151  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2152  uint32_t http_len = sizeof(http_buf) - 1;
2153  int result = 0;
2155 
2156  memset(&th_v, 0, sizeof(th_v));
2157  memset(&f, 0, sizeof(f));
2158  memset(&ssn, 0, sizeof(ssn));
2159 
2160  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2161 
2162  FLOW_INITIALIZE(&f);
2163  f.protoctx = (void *)&ssn;
2164  f.proto = IPPROTO_TCP;
2165  f.flags |= FLOW_IPV4;
2166  p->flow = &f;
2170  f.alproto = ALPROTO_HTTP;
2171 
2173 
2174  de_ctx = DetectEngineCtxInit();
2175  if (de_ctx == NULL)
2176  goto end;
2177 
2178  de_ctx->flags |= DE_QUIET;
2179 
2180  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2181  "(msg:\"http header test\"; "
2182  "content:!\"one\"; offset:15; http_header; "
2183  "sid:1;)");
2184  if (de_ctx->sig_list == NULL)
2185  goto end;
2186 
2187  SigGroupBuild(de_ctx);
2188  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2189 
2190  FLOWLOCK_WRLOCK(&f);
2191  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2192  STREAM_TOSERVER, http_buf, http_len);
2193  if (r != 0) {
2194  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2195  result = 0;
2196  FLOWLOCK_UNLOCK(&f);
2197  goto end;
2198  }
2199  FLOWLOCK_UNLOCK(&f);
2200 
2201  http_state = f.alstate;
2202  if (http_state == NULL) {
2203  printf("no http state: ");
2204  result = 0;
2205  goto end;
2206  }
2207 
2208  /* do detect */
2209  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2210 
2211  if (!(PacketAlertCheck(p, 1))) {
2212  printf("sid 1 didn't match but should have: ");
2213  goto end;
2214  }
2215 
2216  result = 1;
2217 end:
2218  if (alp_tctx != NULL)
2219  AppLayerParserThreadCtxFree(alp_tctx);
2220  if (de_ctx != NULL)
2221  DetectEngineCtxFree(de_ctx);
2222 
2224  FLOW_DESTROY(&f);
2225  UTHFreePackets(&p, 1);
2226  return result;
2227 }
2228 
2229 /**
2230  *\test Test that the http_header content matches against a http request
2231  * which holds the content.
2232  */
2233 static int DetectEngineHttpHeaderTest08(void)
2234 {
2235  TcpSession ssn;
2236  Packet *p = NULL;
2237  ThreadVars th_v;
2238  DetectEngineCtx *de_ctx = NULL;
2239  DetectEngineThreadCtx *det_ctx = NULL;
2240  HtpState *http_state = NULL;
2241  Flow f;
2242  uint8_t http_buf[] =
2243  "GET /index.html HTTP/1.0\r\n"
2244  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2245  uint32_t http_len = sizeof(http_buf) - 1;
2246  int result = 0;
2248 
2249  memset(&th_v, 0, sizeof(th_v));
2250  memset(&f, 0, sizeof(f));
2251  memset(&ssn, 0, sizeof(ssn));
2252 
2253  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2254 
2255  FLOW_INITIALIZE(&f);
2256  f.protoctx = (void *)&ssn;
2257  f.proto = IPPROTO_TCP;
2258  f.flags |= FLOW_IPV4;
2259  p->flow = &f;
2263  f.alproto = ALPROTO_HTTP;
2264 
2266 
2267  de_ctx = DetectEngineCtxInit();
2268  if (de_ctx == NULL)
2269  goto end;
2270 
2271  de_ctx->flags |= DE_QUIET;
2272 
2273  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2274  "(msg:\"http header test\"; "
2275  "content:\"one\"; offset:15; http_header; "
2276  "sid:1;)");
2277  if (de_ctx->sig_list == NULL)
2278  goto end;
2279 
2280  SigGroupBuild(de_ctx);
2281  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2282 
2283  FLOWLOCK_WRLOCK(&f);
2284  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2285  STREAM_TOSERVER, http_buf, http_len);
2286  if (r != 0) {
2287  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2288  result = 0;
2289  FLOWLOCK_UNLOCK(&f);
2290  goto end;
2291  }
2292  FLOWLOCK_UNLOCK(&f);
2293 
2294  http_state = f.alstate;
2295  if (http_state == NULL) {
2296  printf("no http state: ");
2297  result = 0;
2298  goto end;
2299  }
2300 
2301  /* do detect */
2302  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2303 
2304  if (PacketAlertCheck(p, 1)) {
2305  printf("sid 1 matched but shouldn't have: ");
2306  goto end;
2307  }
2308 
2309  result = 1;
2310 end:
2311  if (alp_tctx != NULL)
2312  AppLayerParserThreadCtxFree(alp_tctx);
2313  if (de_ctx != NULL)
2314  DetectEngineCtxFree(de_ctx);
2315 
2317  FLOW_DESTROY(&f);
2318  UTHFreePackets(&p, 1);
2319  return result;
2320 }
2321 
2322 /**
2323  *\test Test that the http_header content matches against a http request
2324  * which holds the content.
2325  */
2326 static int DetectEngineHttpHeaderTest09(void)
2327 {
2328  TcpSession ssn;
2329  Packet *p = NULL;
2330  ThreadVars th_v;
2331  DetectEngineCtx *de_ctx = NULL;
2332  DetectEngineThreadCtx *det_ctx = NULL;
2333  HtpState *http_state = NULL;
2334  Flow f;
2335  uint8_t http_buf[] =
2336  "GET /index.html HTTP/1.0\r\n"
2337  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2338  uint32_t http_len = sizeof(http_buf) - 1;
2339  int result = 0;
2341 
2342  memset(&th_v, 0, sizeof(th_v));
2343  memset(&f, 0, sizeof(f));
2344  memset(&ssn, 0, sizeof(ssn));
2345 
2346  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2347 
2348  FLOW_INITIALIZE(&f);
2349  f.protoctx = (void *)&ssn;
2350  f.proto = IPPROTO_TCP;
2351  f.flags |= FLOW_IPV4;
2352  p->flow = &f;
2356  f.alproto = ALPROTO_HTTP;
2357 
2359 
2360  de_ctx = DetectEngineCtxInit();
2361  if (de_ctx == NULL)
2362  goto end;
2363 
2364  de_ctx->flags |= DE_QUIET;
2365 
2366  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2367  "(msg:\"http header test\"; "
2368  "content:!\"one\"; offset:10; http_header; "
2369  "sid:1;)");
2370  if (de_ctx->sig_list == NULL)
2371  goto end;
2372 
2373  SigGroupBuild(de_ctx);
2374  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2375 
2376  FLOWLOCK_WRLOCK(&f);
2377  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2378  STREAM_TOSERVER, http_buf, http_len);
2379  if (r != 0) {
2380  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2381  result = 0;
2382  FLOWLOCK_UNLOCK(&f);
2383  goto end;
2384  }
2385  FLOWLOCK_UNLOCK(&f);
2386 
2387  http_state = f.alstate;
2388  if (http_state == NULL) {
2389  printf("no http state: ");
2390  result = 0;
2391  goto end;
2392  }
2393 
2394  /* do detect */
2395  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2396 
2397  if (PacketAlertCheck(p, 1)) {
2398  printf("sid 1 matched but shouldn't have: ");
2399  goto end;
2400  }
2401 
2402  result = 1;
2403 end:
2404  if (alp_tctx != NULL)
2405  AppLayerParserThreadCtxFree(alp_tctx);
2406  if (de_ctx != NULL)
2407  DetectEngineCtxFree(de_ctx);
2408 
2410  FLOW_DESTROY(&f);
2411  UTHFreePackets(&p, 1);
2412  return result;
2413 }
2414 
2415 /**
2416  *\test Test that the http_header content matches against a http request
2417  * which holds the content.
2418  */
2419 static int DetectEngineHttpHeaderTest10(void)
2420 {
2421  TcpSession ssn;
2422  Packet *p = NULL;
2423  ThreadVars th_v;
2424  DetectEngineCtx *de_ctx = NULL;
2425  DetectEngineThreadCtx *det_ctx = NULL;
2426  HtpState *http_state = NULL;
2427  Flow f;
2428  uint8_t http_buf[] =
2429  "GET /index.html HTTP/1.0\r\n"
2430  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2431  uint32_t http_len = sizeof(http_buf) - 1;
2432  int result = 0;
2434 
2435  memset(&th_v, 0, sizeof(th_v));
2436  memset(&f, 0, sizeof(f));
2437  memset(&ssn, 0, sizeof(ssn));
2438 
2439  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2440 
2441  FLOW_INITIALIZE(&f);
2442  f.protoctx = (void *)&ssn;
2443  f.proto = IPPROTO_TCP;
2444  f.flags |= FLOW_IPV4;
2445  p->flow = &f;
2449  f.alproto = ALPROTO_HTTP;
2450 
2452 
2453  de_ctx = DetectEngineCtxInit();
2454  if (de_ctx == NULL)
2455  goto end;
2456 
2457  de_ctx->flags |= DE_QUIET;
2458 
2459  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2460  "(msg:\"http header test\"; "
2461  "content:\"one\"; http_header; content:\"three\"; http_header; within:10; "
2462  "sid:1;)");
2463  if (de_ctx->sig_list == NULL)
2464  goto end;
2465 
2466  SigGroupBuild(de_ctx);
2467  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2468 
2469  FLOWLOCK_WRLOCK(&f);
2470  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2471  STREAM_TOSERVER, http_buf, http_len);
2472  if (r != 0) {
2473  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2474  result = 0;
2475  FLOWLOCK_UNLOCK(&f);
2476  goto end;
2477  }
2478  FLOWLOCK_UNLOCK(&f);
2479 
2480  http_state = f.alstate;
2481  if (http_state == NULL) {
2482  printf("no http state: ");
2483  result = 0;
2484  goto end;
2485  }
2486 
2487  /* do detect */
2488  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2489 
2490  if (!(PacketAlertCheck(p, 1))) {
2491  printf("sid 1 didn't match but should have: ");
2492  goto end;
2493  }
2494 
2495  result = 1;
2496 end:
2497  if (alp_tctx != NULL)
2498  AppLayerParserThreadCtxFree(alp_tctx);
2499  if (de_ctx != NULL)
2500  DetectEngineCtxFree(de_ctx);
2501 
2503  FLOW_DESTROY(&f);
2504  UTHFreePackets(&p, 1);
2505  return result;
2506 }
2507 
2508 /**
2509  *\test Test that the http_header content matches against a http request
2510  * which holds the content.
2511  */
2512 static int DetectEngineHttpHeaderTest11(void)
2513 {
2514  TcpSession ssn;
2515  Packet *p = NULL;
2516  ThreadVars th_v;
2517  DetectEngineCtx *de_ctx = NULL;
2518  DetectEngineThreadCtx *det_ctx = NULL;
2519  HtpState *http_state = NULL;
2520  Flow f;
2521  uint8_t http_buf[] =
2522  "GET /index.html HTTP/1.0\r\n"
2523  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2524  uint32_t http_len = sizeof(http_buf) - 1;
2525  int result = 0;
2527 
2528  memset(&th_v, 0, sizeof(th_v));
2529  memset(&f, 0, sizeof(f));
2530  memset(&ssn, 0, sizeof(ssn));
2531 
2532  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2533 
2534  FLOW_INITIALIZE(&f);
2535  f.protoctx = (void *)&ssn;
2536  f.proto = IPPROTO_TCP;
2537  f.flags |= FLOW_IPV4;
2538  p->flow = &f;
2542  f.alproto = ALPROTO_HTTP;
2543 
2545 
2546  de_ctx = DetectEngineCtxInit();
2547  if (de_ctx == NULL)
2548  goto end;
2549 
2550  de_ctx->flags |= DE_QUIET;
2551 
2552  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2553  "(msg:\"http header test\"; "
2554  "content:\"one\"; http_header; content:!\"three\"; http_header; within:5; "
2555  "sid:1;)");
2556  if (de_ctx->sig_list == NULL)
2557  goto end;
2558 
2559  SigGroupBuild(de_ctx);
2560  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2561 
2562  FLOWLOCK_WRLOCK(&f);
2563  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2564  STREAM_TOSERVER, http_buf, http_len);
2565  if (r != 0) {
2566  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2567  result = 0;
2568  FLOWLOCK_UNLOCK(&f);
2569  goto end;
2570  }
2571  FLOWLOCK_UNLOCK(&f);
2572 
2573  http_state = f.alstate;
2574  if (http_state == NULL) {
2575  printf("no http state: ");
2576  result = 0;
2577  goto end;
2578  }
2579 
2580  /* do detect */
2581  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2582 
2583  if (!(PacketAlertCheck(p, 1))) {
2584  printf("sid 1 didn't match but should have: ");
2585  goto end;
2586  }
2587 
2588  result = 1;
2589 end:
2590  if (alp_tctx != NULL)
2591  AppLayerParserThreadCtxFree(alp_tctx);
2592  if (de_ctx != NULL)
2593  DetectEngineCtxFree(de_ctx);
2594 
2596  FLOW_DESTROY(&f);
2597  UTHFreePackets(&p, 1);
2598  return result;
2599 }
2600 
2601 /**
2602  *\test Test that the http_header content matches against a http request
2603  * which holds the content.
2604  */
2605 static int DetectEngineHttpHeaderTest12(void)
2606 {
2607  TcpSession ssn;
2608  Packet *p = NULL;
2609  ThreadVars th_v;
2610  DetectEngineCtx *de_ctx = NULL;
2611  DetectEngineThreadCtx *det_ctx = NULL;
2612  HtpState *http_state = NULL;
2613  Flow f;
2614  uint8_t http_buf[] =
2615  "GET /index.html HTTP/1.0\r\n"
2616  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2617  uint32_t http_len = sizeof(http_buf) - 1;
2618  int result = 0;
2620 
2621  memset(&th_v, 0, sizeof(th_v));
2622  memset(&f, 0, sizeof(f));
2623  memset(&ssn, 0, sizeof(ssn));
2624 
2625  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2626 
2627  FLOW_INITIALIZE(&f);
2628  f.protoctx = (void *)&ssn;
2629  f.proto = IPPROTO_TCP;
2630  f.flags |= FLOW_IPV4;
2631  p->flow = &f;
2635  f.alproto = ALPROTO_HTTP;
2636 
2638 
2639  de_ctx = DetectEngineCtxInit();
2640  if (de_ctx == NULL)
2641  goto end;
2642 
2643  de_ctx->flags |= DE_QUIET;
2644 
2645  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2646  "(msg:\"http header test\"; "
2647  "content:\"one\"; http_header; content:!\"three\"; http_header; within:10; "
2648  "sid:1;)");
2649  if (de_ctx->sig_list == NULL)
2650  goto end;
2651 
2652  SigGroupBuild(de_ctx);
2653  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2654 
2655  FLOWLOCK_WRLOCK(&f);
2656  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2657  STREAM_TOSERVER, http_buf, http_len);
2658  if (r != 0) {
2659  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2660  result = 0;
2661  FLOWLOCK_UNLOCK(&f);
2662  goto end;
2663  }
2664  FLOWLOCK_UNLOCK(&f);
2665 
2666  http_state = f.alstate;
2667  if (http_state == NULL) {
2668  printf("no http state: ");
2669  result = 0;
2670  goto end;
2671  }
2672 
2673  /* do detect */
2674  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2675 
2676  if (PacketAlertCheck(p, 1)) {
2677  printf("sid 1 matched but shouldn't have: ");
2678  goto end;
2679  }
2680 
2681  result = 1;
2682 end:
2683  if (alp_tctx != NULL)
2684  AppLayerParserThreadCtxFree(alp_tctx);
2685  if (de_ctx != NULL)
2686  DetectEngineCtxFree(de_ctx);
2687 
2689  FLOW_DESTROY(&f);
2690  UTHFreePackets(&p, 1);
2691  return result;
2692 }
2693 
2694 /**
2695  *\test Test that the http_header content matches against a http request
2696  * which holds the content.
2697  */
2698 static int DetectEngineHttpHeaderTest13(void)
2699 {
2700  TcpSession ssn;
2701  Packet *p = NULL;
2702  ThreadVars th_v;
2703  DetectEngineCtx *de_ctx = NULL;
2704  DetectEngineThreadCtx *det_ctx = NULL;
2705  HtpState *http_state = NULL;
2706  Flow f;
2707  uint8_t http_buf[] =
2708  "GET /index.html HTTP/1.0\r\n"
2709  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2710  uint32_t http_len = sizeof(http_buf) - 1;
2711  int result = 0;
2713 
2714  memset(&th_v, 0, sizeof(th_v));
2715  memset(&f, 0, sizeof(f));
2716  memset(&ssn, 0, sizeof(ssn));
2717 
2718  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2719 
2720  FLOW_INITIALIZE(&f);
2721  f.protoctx = (void *)&ssn;
2722  f.proto = IPPROTO_TCP;
2723  f.flags |= FLOW_IPV4;
2724  p->flow = &f;
2728  f.alproto = ALPROTO_HTTP;
2729 
2731 
2732  de_ctx = DetectEngineCtxInit();
2733  if (de_ctx == NULL)
2734  goto end;
2735 
2736  de_ctx->flags |= DE_QUIET;
2737 
2738  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2739  "(msg:\"http header test\"; "
2740  "content:\"one\"; http_header; content:\"three\"; http_header; within:5; "
2741  "sid:1;)");
2742  if (de_ctx->sig_list == NULL)
2743  goto end;
2744 
2745  SigGroupBuild(de_ctx);
2746  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2747 
2748  FLOWLOCK_WRLOCK(&f);
2749  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2750  STREAM_TOSERVER, http_buf, http_len);
2751  if (r != 0) {
2752  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2753  result = 0;
2754  FLOWLOCK_UNLOCK(&f);
2755  goto end;
2756  }
2757  FLOWLOCK_UNLOCK(&f);
2758 
2759  http_state = f.alstate;
2760  if (http_state == NULL) {
2761  printf("no http state: ");
2762  result = 0;
2763  goto end;
2764  }
2765 
2766  /* do detect */
2767  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2768 
2769  if (PacketAlertCheck(p, 1)) {
2770  printf("sid 1 matched but shouldn't have: ");
2771  goto end;
2772  }
2773 
2774  result = 1;
2775 end:
2776  if (alp_tctx != NULL)
2777  AppLayerParserThreadCtxFree(alp_tctx);
2778  if (de_ctx != NULL)
2779  DetectEngineCtxFree(de_ctx);
2780 
2782  FLOW_DESTROY(&f);
2783  UTHFreePackets(&p, 1);
2784  return result;
2785 }
2786 
2787 /**
2788  *\test Test that the http_header content matches against a http request
2789  * which holds the content.
2790  */
2791 static int DetectEngineHttpHeaderTest14(void)
2792 {
2793  TcpSession ssn;
2794  Packet *p = NULL;
2795  ThreadVars th_v;
2796  DetectEngineCtx *de_ctx = NULL;
2797  DetectEngineThreadCtx *det_ctx = NULL;
2798  HtpState *http_state = NULL;
2799  Flow f;
2800  uint8_t http_buf[] =
2801  "GET /index.html HTTP/1.0\r\n"
2802  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2803  uint32_t http_len = sizeof(http_buf) - 1;
2804  int result = 0;
2806 
2807  memset(&th_v, 0, sizeof(th_v));
2808  memset(&f, 0, sizeof(f));
2809  memset(&ssn, 0, sizeof(ssn));
2810 
2811  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2812 
2813  FLOW_INITIALIZE(&f);
2814  f.protoctx = (void *)&ssn;
2815  f.proto = IPPROTO_TCP;
2816  f.flags |= FLOW_IPV4;
2817  p->flow = &f;
2821  f.alproto = ALPROTO_HTTP;
2822 
2824 
2825  de_ctx = DetectEngineCtxInit();
2826  if (de_ctx == NULL)
2827  goto end;
2828 
2829  de_ctx->flags |= DE_QUIET;
2830 
2831  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2832  "(msg:\"http header test\"; "
2833  "content:\"one\"; http_header; content:\"five\"; http_header; distance:7; "
2834  "sid:1;)");
2835  if (de_ctx->sig_list == NULL)
2836  goto end;
2837 
2838  SigGroupBuild(de_ctx);
2839  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2840 
2841  FLOWLOCK_WRLOCK(&f);
2842  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2843  STREAM_TOSERVER, http_buf, http_len);
2844  if (r != 0) {
2845  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2846  result = 0;
2847  FLOWLOCK_UNLOCK(&f);
2848  goto end;
2849  }
2850  FLOWLOCK_UNLOCK(&f);
2851 
2852  http_state = f.alstate;
2853  if (http_state == NULL) {
2854  printf("no http state: ");
2855  result = 0;
2856  goto end;
2857  }
2858 
2859  /* do detect */
2860  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2861 
2862  if (!(PacketAlertCheck(p, 1))) {
2863  printf("sid 1 didn't match but should have: ");
2864  goto end;
2865  }
2866 
2867  result = 1;
2868 end:
2869  if (alp_tctx != NULL)
2870  AppLayerParserThreadCtxFree(alp_tctx);
2871  if (de_ctx != NULL)
2872  DetectEngineCtxFree(de_ctx);
2873 
2875  FLOW_DESTROY(&f);
2876  UTHFreePackets(&p, 1);
2877  return result;
2878 }
2879 
2880 /**
2881  *\test Test that the http_header content matches against a http request
2882  * which holds the content.
2883  */
2884 static int DetectEngineHttpHeaderTest15(void)
2885 {
2886  TcpSession ssn;
2887  Packet *p = NULL;
2888  ThreadVars th_v;
2889  DetectEngineCtx *de_ctx = NULL;
2890  DetectEngineThreadCtx *det_ctx = NULL;
2891  HtpState *http_state = NULL;
2892  Flow f;
2893  uint8_t http_buf[] =
2894  "GET /index.html HTTP/1.0\r\n"
2895  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2896  uint32_t http_len = sizeof(http_buf) - 1;
2897  int result = 0;
2899 
2900  memset(&th_v, 0, sizeof(th_v));
2901  memset(&f, 0, sizeof(f));
2902  memset(&ssn, 0, sizeof(ssn));
2903 
2904  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2905 
2906  FLOW_INITIALIZE(&f);
2907  f.protoctx = (void *)&ssn;
2908  f.proto = IPPROTO_TCP;
2909  f.flags |= FLOW_IPV4;
2910  p->flow = &f;
2914  f.alproto = ALPROTO_HTTP;
2915 
2917 
2918  de_ctx = DetectEngineCtxInit();
2919  if (de_ctx == NULL)
2920  goto end;
2921 
2922  de_ctx->flags |= DE_QUIET;
2923 
2924  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2925  "(msg:\"http header test\"; "
2926  "content:\"one\"; http_header; content:!\"five\"; http_header; distance:15; "
2927  "sid:1;)");
2928  if (de_ctx->sig_list == NULL)
2929  goto end;
2930 
2931  SigGroupBuild(de_ctx);
2932  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2933 
2934  FLOWLOCK_WRLOCK(&f);
2935  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2936  STREAM_TOSERVER, http_buf, http_len);
2937  if (r != 0) {
2938  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2939  result = 0;
2940  FLOWLOCK_UNLOCK(&f);
2941  goto end;
2942  }
2943  FLOWLOCK_UNLOCK(&f);
2944 
2945  http_state = f.alstate;
2946  if (http_state == NULL) {
2947  printf("no http state: ");
2948  result = 0;
2949  goto end;
2950  }
2951 
2952  /* do detect */
2953  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2954 
2955  if (!(PacketAlertCheck(p, 1))) {
2956  printf("sid 1 didn't match but should have: ");
2957  goto end;
2958  }
2959 
2960  result = 1;
2961 end:
2962  if (alp_tctx != NULL)
2963  AppLayerParserThreadCtxFree(alp_tctx);
2964  if (de_ctx != NULL)
2965  DetectEngineCtxFree(de_ctx);
2966 
2968  FLOW_DESTROY(&f);
2969  UTHFreePackets(&p, 1);
2970  return result;
2971 }
2972 
2973 /**
2974  *\test Test that the http_header content matches against a http request
2975  * which holds the content.
2976  */
2977 static int DetectEngineHttpHeaderTest16(void)
2978 {
2979  TcpSession ssn;
2980  Packet *p = NULL;
2981  ThreadVars th_v;
2982  DetectEngineCtx *de_ctx = NULL;
2983  DetectEngineThreadCtx *det_ctx = NULL;
2984  HtpState *http_state = NULL;
2985  Flow f;
2986  uint8_t http_buf[] =
2987  "GET /index.html HTTP/1.0\r\n"
2988  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2989  uint32_t http_len = sizeof(http_buf) - 1;
2990  int result = 0;
2992 
2993  memset(&th_v, 0, sizeof(th_v));
2994  memset(&f, 0, sizeof(f));
2995  memset(&ssn, 0, sizeof(ssn));
2996 
2997  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2998 
2999  FLOW_INITIALIZE(&f);
3000  f.protoctx = (void *)&ssn;
3001  f.proto = IPPROTO_TCP;
3002  f.flags |= FLOW_IPV4;
3003  p->flow = &f;
3007  f.alproto = ALPROTO_HTTP;
3008 
3010 
3011  de_ctx = DetectEngineCtxInit();
3012  if (de_ctx == NULL)
3013  goto end;
3014 
3015  de_ctx->flags |= DE_QUIET;
3016 
3017  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3018  "(msg:\"http header test\"; "
3019  "content:\"one\"; http_header; content:!\"five\"; http_header; distance:7; "
3020  "sid:1;)");
3021  if (de_ctx->sig_list == NULL)
3022  goto end;
3023 
3024  SigGroupBuild(de_ctx);
3025  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3026 
3027  FLOWLOCK_WRLOCK(&f);
3028  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3029  STREAM_TOSERVER, http_buf, http_len);
3030  if (r != 0) {
3031  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3032  result = 0;
3033  FLOWLOCK_UNLOCK(&f);
3034  goto end;
3035  }
3036  FLOWLOCK_UNLOCK(&f);
3037 
3038  http_state = f.alstate;
3039  if (http_state == NULL) {
3040  printf("no http state: ");
3041  result = 0;
3042  goto end;
3043  }
3044 
3045  /* do detect */
3046  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3047 
3048  if (PacketAlertCheck(p, 1)) {
3049  printf("sid 1 matched but shouldn't have: ");
3050  goto end;
3051  }
3052 
3053  result = 1;
3054 end:
3055  if (alp_tctx != NULL)
3056  AppLayerParserThreadCtxFree(alp_tctx);
3057  if (de_ctx != NULL)
3058  DetectEngineCtxFree(de_ctx);
3059 
3061  FLOW_DESTROY(&f);
3062  UTHFreePackets(&p, 1);
3063  return result;
3064 }
3065 
3066 /**
3067  *\test Test that the http_header content matches against a http request
3068  * which holds the content.
3069  */
3070 static int DetectEngineHttpHeaderTest17(void)
3071 {
3072  TcpSession ssn;
3073  Packet *p = NULL;
3074  ThreadVars th_v;
3075  DetectEngineCtx *de_ctx = NULL;
3076  DetectEngineThreadCtx *det_ctx = NULL;
3077  HtpState *http_state = NULL;
3078  Flow f;
3079  uint8_t http_buf[] =
3080  "GET /index.html HTTP/1.0\r\n"
3081  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
3082  uint32_t http_len = sizeof(http_buf) - 1;
3083  int result = 0;
3085 
3086  memset(&th_v, 0, sizeof(th_v));
3087  memset(&f, 0, sizeof(f));
3088  memset(&ssn, 0, sizeof(ssn));
3089 
3090  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3091 
3092  FLOW_INITIALIZE(&f);
3093  f.protoctx = (void *)&ssn;
3094  f.proto = IPPROTO_TCP;
3095  f.flags |= FLOW_IPV4;
3096  p->flow = &f;
3100  f.alproto = ALPROTO_HTTP;
3101 
3103 
3104  de_ctx = DetectEngineCtxInit();
3105  if (de_ctx == NULL)
3106  goto end;
3107 
3108  de_ctx->flags |= DE_QUIET;
3109 
3110  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3111  "(msg:\"http header test\"; "
3112  "content:\"one\"; http_header; content:\"five\"; http_header; distance:15; "
3113  "sid:1;)");
3114  if (de_ctx->sig_list == NULL)
3115  goto end;
3116 
3117  SigGroupBuild(de_ctx);
3118  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3119 
3120  FLOWLOCK_WRLOCK(&f);
3121  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3122  STREAM_TOSERVER, http_buf, http_len);
3123  if (r != 0) {
3124  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3125  result = 0;
3126  FLOWLOCK_UNLOCK(&f);
3127  goto end;
3128  }
3129  FLOWLOCK_UNLOCK(&f);
3130 
3131  http_state = f.alstate;
3132  if (http_state == NULL) {
3133  printf("no http state: ");
3134  result = 0;
3135  goto end;
3136  }
3137 
3138  /* do detect */
3139  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3140 
3141  if (PacketAlertCheck(p, 1)) {
3142  printf("sid 1 matched but shouldn't have: ");
3143  goto end;
3144  }
3145 
3146  result = 1;
3147 end:
3148  if (alp_tctx != NULL)
3149  AppLayerParserThreadCtxFree(alp_tctx);
3150  if (de_ctx != NULL)
3151  DetectEngineCtxFree(de_ctx);
3152 
3154  FLOW_DESTROY(&f);
3155  UTHFreePackets(&p, 1);
3156  return result;
3157 }
3158 
3159 static int DetectEngineHttpHeaderTest20(void)
3160 {
3161  TcpSession ssn;
3162  Packet *p1 = NULL;
3163  Packet *p2 = NULL;
3164  ThreadVars th_v;
3165  DetectEngineCtx *de_ctx = NULL;
3166  DetectEngineThreadCtx *det_ctx = NULL;
3167  HtpState *http_state = NULL;
3168  Flow f;
3169  uint8_t http1_buf[] =
3170  "GET /index.html HTTP/1.0\r\n"
3171  "Host: This_is_dummy_body1";
3172  uint8_t http2_buf[] =
3173  "This_is_dummy_message_body2\r\n"
3174  "\r\n";
3175  uint32_t http1_len = sizeof(http1_buf) - 1;
3176  uint32_t http2_len = sizeof(http2_buf) - 1;
3177  int result = 0;
3179 
3180  memset(&th_v, 0, sizeof(th_v));
3181  memset(&f, 0, sizeof(f));
3182  memset(&ssn, 0, sizeof(ssn));
3183 
3184  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3185  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3186 
3187  FLOW_INITIALIZE(&f);
3188  f.protoctx = (void *)&ssn;
3189  f.proto = IPPROTO_TCP;
3190  f.flags |= FLOW_IPV4;
3191 
3192  p1->flow = &f;
3196  p2->flow = &f;
3200  f.alproto = ALPROTO_HTTP;
3201 
3203 
3204  de_ctx = DetectEngineCtxInit();
3205  if (de_ctx == NULL)
3206  goto end;
3207 
3208  de_ctx->flags |= DE_QUIET;
3209 
3210  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3211  "(msg:\"http client body test\"; "
3212  "pcre:/body1/H; "
3213  "content:!\"dummy\"; http_header; within:7; "
3214  "sid:1;)");
3215  if (de_ctx->sig_list == NULL)
3216  goto end;
3217 
3218  SigGroupBuild(de_ctx);
3219  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3220 
3221  FLOWLOCK_WRLOCK(&f);
3222  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3223  STREAM_TOSERVER, http1_buf, http1_len);
3224  if (r != 0) {
3225  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3226  result = 0;
3227  FLOWLOCK_UNLOCK(&f);
3228  goto end;
3229  }
3230  FLOWLOCK_UNLOCK(&f);
3231 
3232  http_state = f.alstate;
3233  if (http_state == NULL) {
3234  printf("no http state: \n");
3235  result = 0;
3236  goto end;
3237  }
3238 
3239  /* do detect */
3240  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3241 
3242  if (PacketAlertCheck(p1, 1)) {
3243  printf("sid 1 matched but shouldn't have\n");
3244  goto end;
3245  }
3246 
3247  FLOWLOCK_WRLOCK(&f);
3248  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3249  STREAM_TOSERVER, http2_buf, http2_len);
3250  if (r != 0) {
3251  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3252  result = 0;
3253  FLOWLOCK_UNLOCK(&f);
3254  goto end;
3255  }
3256  FLOWLOCK_UNLOCK(&f);
3257 
3258  /* do detect */
3259  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3260 
3261  if (!PacketAlertCheck(p2, 1)) {
3262  printf("sid 1 didn't match but shouldn't have");
3263  goto end;
3264  }
3265 
3266  result = 1;
3267 
3268 end:
3269  if (alp_tctx != NULL)
3270  AppLayerParserThreadCtxFree(alp_tctx);
3271  if (de_ctx != NULL)
3272  DetectEngineCtxFree(de_ctx);
3273 
3275  FLOW_DESTROY(&f);
3276  UTHFreePackets(&p1, 1);
3277  UTHFreePackets(&p2, 1);
3278  return result;
3279 }
3280 
3281 static int DetectEngineHttpHeaderTest21(void)
3282 {
3283  TcpSession ssn;
3284  Packet *p1 = NULL;
3285  Packet *p2 = NULL;
3286  ThreadVars th_v;
3287  DetectEngineCtx *de_ctx = NULL;
3288  DetectEngineThreadCtx *det_ctx = NULL;
3289  HtpState *http_state = NULL;
3290  Flow f;
3291  uint8_t http1_buf[] =
3292  "GET /index.html HTTP/1.0\r\n"
3293  "Host: This_is_dummy_body1";
3294  uint8_t http2_buf[] =
3295  "This_is_dummy_message_body2\r\n"
3296  "\r\n";
3297  uint32_t http1_len = sizeof(http1_buf) - 1;
3298  uint32_t http2_len = sizeof(http2_buf) - 1;
3299  int result = 0;
3301 
3302  memset(&th_v, 0, sizeof(th_v));
3303  memset(&f, 0, sizeof(f));
3304  memset(&ssn, 0, sizeof(ssn));
3305 
3306  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3307  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3308 
3309  FLOW_INITIALIZE(&f);
3310  f.protoctx = (void *)&ssn;
3311  f.proto = IPPROTO_TCP;
3312  f.flags |= FLOW_IPV4;
3313 
3314  p1->flow = &f;
3318  p2->flow = &f;
3322  f.alproto = ALPROTO_HTTP;
3323 
3325 
3326  de_ctx = DetectEngineCtxInit();
3327  if (de_ctx == NULL)
3328  goto end;
3329 
3330  de_ctx->flags |= DE_QUIET;
3331 
3332  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3333  "(msg:\"http client body test\"; "
3334  "pcre:/body1/H; "
3335  "content:!\"dummy\"; within:7; http_header; "
3336  "sid:1;)");
3337  if (de_ctx->sig_list == NULL)
3338  goto end;
3339 
3340  SigGroupBuild(de_ctx);
3341  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3342 
3343  FLOWLOCK_WRLOCK(&f);
3344  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3345  STREAM_TOSERVER, http1_buf, http1_len);
3346  if (r != 0) {
3347  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3348  result = 0;
3349  FLOWLOCK_UNLOCK(&f);
3350  goto end;
3351  }
3352  FLOWLOCK_UNLOCK(&f);
3353 
3354  http_state = f.alstate;
3355  if (http_state == NULL) {
3356  printf("no http state: \n");
3357  result = 0;
3358  goto end;
3359  }
3360 
3361  /* do detect */
3362  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3363 
3364  if (PacketAlertCheck(p1, 1)) {
3365  printf("sid 1 matched but shouldn't have\n");
3366  goto end;
3367  }
3368 
3369  FLOWLOCK_WRLOCK(&f);
3370  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3371  STREAM_TOSERVER, http2_buf, http2_len);
3372  if (r != 0) {
3373  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3374  result = 0;
3375  FLOWLOCK_UNLOCK(&f);
3376  goto end;
3377  }
3378  FLOWLOCK_UNLOCK(&f);
3379 
3380  /* do detect */
3381  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3382 
3383  if (!PacketAlertCheck(p2, 1)) {
3384  printf("sid 1 didn't match but shouldn't have");
3385  goto end;
3386  }
3387 
3388  result = 1;
3389 
3390 end:
3391  if (alp_tctx != NULL)
3392  AppLayerParserThreadCtxFree(alp_tctx);
3393  if (de_ctx != NULL)
3394  DetectEngineCtxFree(de_ctx);
3395 
3397  FLOW_DESTROY(&f);
3398  UTHFreePackets(&p1, 1);
3399  UTHFreePackets(&p2, 1);
3400  return result;
3401 }
3402 
3403 static int DetectEngineHttpHeaderTest22(void)
3404 {
3405  TcpSession ssn;
3406  Packet *p1 = NULL;
3407  Packet *p2 = NULL;
3408  ThreadVars th_v;
3409  DetectEngineCtx *de_ctx = NULL;
3410  DetectEngineThreadCtx *det_ctx = NULL;
3411  HtpState *http_state = NULL;
3412  Flow f;
3413  uint8_t http1_buf[] =
3414  "GET /index.html HTTP/1.0\r\n"
3415  "Host: This_is_dummy_body1";
3416  uint8_t http2_buf[] =
3417  "This_is_dummy_message_body2\r\n"
3418  "\r\n";
3419  uint32_t http1_len = sizeof(http1_buf) - 1;
3420  uint32_t http2_len = sizeof(http2_buf) - 1;
3421  int result = 0;
3423 
3424  memset(&th_v, 0, sizeof(th_v));
3425  memset(&f, 0, sizeof(f));
3426  memset(&ssn, 0, sizeof(ssn));
3427 
3428  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3429  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3430 
3431  FLOW_INITIALIZE(&f);
3432  f.protoctx = (void *)&ssn;
3433  f.proto = IPPROTO_TCP;
3434  f.flags |= FLOW_IPV4;
3435 
3436  p1->flow = &f;
3440  p2->flow = &f;
3444  f.alproto = ALPROTO_HTTP;
3445 
3447 
3448  de_ctx = DetectEngineCtxInit();
3449  if (de_ctx == NULL)
3450  goto end;
3451 
3452  de_ctx->flags |= DE_QUIET;
3453 
3454  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3455  "(msg:\"http client body test\"; "
3456  "pcre:/body1/H; "
3457  "content:!\"dummy\"; distance:3; http_header; "
3458  "sid:1;)");
3459  if (de_ctx->sig_list == NULL)
3460  goto end;
3461 
3462  SigGroupBuild(de_ctx);
3463  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3464 
3465  FLOWLOCK_WRLOCK(&f);
3466  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3467  STREAM_TOSERVER, http1_buf, http1_len);
3468  if (r != 0) {
3469  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3470  result = 0;
3471  FLOWLOCK_UNLOCK(&f);
3472  goto end;
3473  }
3474  FLOWLOCK_UNLOCK(&f);
3475 
3476  http_state = f.alstate;
3477  if (http_state == NULL) {
3478  printf("no http state: \n");
3479  result = 0;
3480  goto end;
3481  }
3482 
3483  /* do detect */
3484  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3485 
3486  if (PacketAlertCheck(p1, 1)) {
3487  printf("sid 1 matched but shouldn't have\n");
3488  goto end;
3489  }
3490 
3491  FLOWLOCK_WRLOCK(&f);
3492  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3493  STREAM_TOSERVER, http2_buf, http2_len);
3494  if (r != 0) {
3495  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3496  result = 0;
3497  FLOWLOCK_UNLOCK(&f);
3498  goto end;
3499  }
3500  FLOWLOCK_UNLOCK(&f);
3501 
3502  /* do detect */
3503  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3504 
3505  if (PacketAlertCheck(p2, 1)) {
3506  printf("sid 1 matched but shouldn't have");
3507  goto end;
3508  }
3509 
3510  result = 1;
3511 
3512 end:
3513  if (alp_tctx != NULL)
3514  AppLayerParserThreadCtxFree(alp_tctx);
3515  if (de_ctx != NULL)
3516  DetectEngineCtxFree(de_ctx);
3517 
3519  FLOW_DESTROY(&f);
3520  UTHFreePackets(&p1, 1);
3521  UTHFreePackets(&p2, 1);
3522  return result;
3523 }
3524 
3525 static int DetectEngineHttpHeaderTest23(void)
3526 {
3527  TcpSession ssn;
3528  Packet *p1 = NULL;
3529  Packet *p2 = NULL;
3530  ThreadVars th_v;
3531  DetectEngineCtx *de_ctx = NULL;
3532  DetectEngineThreadCtx *det_ctx = NULL;
3533  HtpState *http_state = NULL;
3534  Flow f;
3535  uint8_t http1_buf[] =
3536  "GET /index.html HTTP/1.0\r\n"
3537  "Host: This_is_dummy_body1";
3538  uint8_t http2_buf[] =
3539  "This_is_dummy_message_body2\r\n"
3540  "\r\n";
3541  uint32_t http1_len = sizeof(http1_buf) - 1;
3542  uint32_t http2_len = sizeof(http2_buf) - 1;
3543  int result = 0;
3545 
3546  memset(&th_v, 0, sizeof(th_v));
3547  memset(&f, 0, sizeof(f));
3548  memset(&ssn, 0, sizeof(ssn));
3549 
3550  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3551  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3552 
3553  FLOW_INITIALIZE(&f);
3554  f.protoctx = (void *)&ssn;
3555  f.proto = IPPROTO_TCP;
3556  f.flags |= FLOW_IPV4;
3557 
3558  p1->flow = &f;
3562  p2->flow = &f;
3566  f.alproto = ALPROTO_HTTP;
3567 
3569 
3570  de_ctx = DetectEngineCtxInit();
3571  if (de_ctx == NULL)
3572  goto end;
3573 
3574  de_ctx->flags |= DE_QUIET;
3575 
3576  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3577  "(msg:\"http client body test\"; "
3578  "pcre:/body1/H; "
3579  "content:!\"dummy\"; distance:13; http_header; "
3580  "sid:1;)");
3581  if (de_ctx->sig_list == NULL)
3582  goto end;
3583 
3584  SigGroupBuild(de_ctx);
3585  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3586 
3587  FLOWLOCK_WRLOCK(&f);
3588  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3589  STREAM_TOSERVER, http1_buf, http1_len);
3590  if (r != 0) {
3591  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3592  result = 0;
3593  FLOWLOCK_UNLOCK(&f);
3594  goto end;
3595  }
3596  FLOWLOCK_UNLOCK(&f);
3597 
3598  http_state = f.alstate;
3599  if (http_state == NULL) {
3600  printf("no http state: \n");
3601  result = 0;
3602  goto end;
3603  }
3604 
3605  /* do detect */
3606  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3607 
3608  if (PacketAlertCheck(p1, 1)) {
3609  printf("sid 1 matched but shouldn't have\n");
3610  goto end;
3611  }
3612 
3613  FLOWLOCK_WRLOCK(&f);
3614  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3615  STREAM_TOSERVER, http2_buf, http2_len);
3616  if (r != 0) {
3617  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3618  result = 0;
3619  FLOWLOCK_UNLOCK(&f);
3620  goto end;
3621  }
3622  FLOWLOCK_UNLOCK(&f);
3623 
3624  /* do detect */
3625  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3626 
3627  if (!PacketAlertCheck(p2, 1)) {
3628  printf("sid 1 didn't match but should have");
3629  goto end;
3630  }
3631 
3632  result = 1;
3633 
3634 end:
3635  if (alp_tctx != NULL)
3636  AppLayerParserThreadCtxFree(alp_tctx);
3637  if (de_ctx != NULL)
3638  DetectEngineCtxFree(de_ctx);
3639 
3641  FLOW_DESTROY(&f);
3642  UTHFreePackets(&p1, 1);
3643  UTHFreePackets(&p2, 1);
3644  return result;
3645 }
3646 
3647 static int DetectEngineHttpHeaderTest24(void)
3648 {
3649  TcpSession ssn;
3650  Packet *p1 = NULL;
3651  Packet *p2 = NULL;
3652  ThreadVars th_v;
3653  DetectEngineCtx *de_ctx = NULL;
3654  DetectEngineThreadCtx *det_ctx = NULL;
3655  HtpState *http_state = NULL;
3656  Flow f;
3657  uint8_t http1_buf[] =
3658  "GET /index.html HTTP/1.0\r\n"
3659  "Host: This_is_dummy_body1";
3660  uint8_t http2_buf[] =
3661  "This_is_dummy_message_body2\r\n"
3662  "\r\n";
3663  uint32_t http1_len = sizeof(http1_buf) - 1;
3664  uint32_t http2_len = sizeof(http2_buf) - 1;
3665  int result = 0;
3667 
3668  memset(&th_v, 0, sizeof(th_v));
3669  memset(&f, 0, sizeof(f));
3670  memset(&ssn, 0, sizeof(ssn));
3671 
3672  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3673  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3674 
3675  FLOW_INITIALIZE(&f);
3676  f.protoctx = (void *)&ssn;
3677  f.proto = IPPROTO_TCP;
3678  f.flags |= FLOW_IPV4;
3679 
3680  p1->flow = &f;
3684  p2->flow = &f;
3688  f.alproto = ALPROTO_HTTP;
3689 
3691 
3692  de_ctx = DetectEngineCtxInit();
3693  if (de_ctx == NULL)
3694  goto end;
3695 
3696  de_ctx->flags |= DE_QUIET;
3697 
3698  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3699  "(msg:\"http client body test\"; "
3700  "pcre:/body1/H; "
3701  "content:\"dummy\"; within:15; http_header; "
3702  "sid:1;)");
3703  if (de_ctx->sig_list == NULL)
3704  goto end;
3705 
3706  SigGroupBuild(de_ctx);
3707  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3708 
3709  FLOWLOCK_WRLOCK(&f);
3710  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3711  STREAM_TOSERVER, http1_buf, http1_len);
3712  if (r != 0) {
3713  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3714  result = 0;
3715  FLOWLOCK_UNLOCK(&f);
3716  goto end;
3717  }
3718  FLOWLOCK_UNLOCK(&f);
3719 
3720  http_state = f.alstate;
3721  if (http_state == NULL) {
3722  printf("no http state: \n");
3723  result = 0;
3724  goto end;
3725  }
3726 
3727  /* do detect */
3728  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3729 
3730  if (PacketAlertCheck(p1, 1)) {
3731  printf("sid 1 matched but shouldn't have\n");
3732  goto end;
3733  }
3734 
3735  FLOWLOCK_WRLOCK(&f);
3736  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3737  STREAM_TOSERVER, http2_buf, http2_len);
3738  if (r != 0) {
3739  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3740  result = 0;
3741  FLOWLOCK_UNLOCK(&f);
3742  goto end;
3743  }
3744  FLOWLOCK_UNLOCK(&f);
3745 
3746  /* do detect */
3747  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3748 
3749  if (!PacketAlertCheck(p2, 1)) {
3750  printf("sid 1 didn't match but should have");
3751  goto end;
3752  }
3753 
3754  result = 1;
3755 
3756 end:
3757  if (alp_tctx != NULL)
3758  AppLayerParserThreadCtxFree(alp_tctx);
3759  if (de_ctx != NULL)
3760  DetectEngineCtxFree(de_ctx);
3761 
3763  FLOW_DESTROY(&f);
3764  UTHFreePackets(&p1, 1);
3765  UTHFreePackets(&p2, 1);
3766  return result;
3767 }
3768 
3769 static int DetectEngineHttpHeaderTest25(void)
3770 {
3771  TcpSession ssn;
3772  Packet *p1 = NULL;
3773  Packet *p2 = NULL;
3774  ThreadVars th_v;
3775  DetectEngineCtx *de_ctx = NULL;
3776  DetectEngineThreadCtx *det_ctx = NULL;
3777  HtpState *http_state = NULL;
3778  Flow f;
3779  uint8_t http1_buf[] =
3780  "GET /index.html HTTP/1.0\r\n"
3781  "Host: This_is_dummy_body1";
3782  uint8_t http2_buf[] =
3783  "This_is_dummy_message_body2\r\n"
3784  "\r\n";
3785  uint32_t http1_len = sizeof(http1_buf) - 1;
3786  uint32_t http2_len = sizeof(http2_buf) - 1;
3787  int result = 0;
3789 
3790  memset(&th_v, 0, sizeof(th_v));
3791  memset(&f, 0, sizeof(f));
3792  memset(&ssn, 0, sizeof(ssn));
3793 
3794  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3795  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3796 
3797  FLOW_INITIALIZE(&f);
3798  f.protoctx = (void *)&ssn;
3799  f.proto = IPPROTO_TCP;
3800  f.flags |= FLOW_IPV4;
3801 
3802  p1->flow = &f;
3806  p2->flow = &f;
3810  f.alproto = ALPROTO_HTTP;
3811 
3813 
3814  de_ctx = DetectEngineCtxInit();
3815  if (de_ctx == NULL)
3816  goto end;
3817 
3818  de_ctx->flags |= DE_QUIET;
3819 
3820  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3821  "(msg:\"http client body test\"; "
3822  "pcre:/body1/H; "
3823  "content:\"dummy\"; within:10; http_header; "
3824  "sid:1;)");
3825  if (de_ctx->sig_list == NULL)
3826  goto end;
3827 
3828  SigGroupBuild(de_ctx);
3829  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3830 
3831  FLOWLOCK_WRLOCK(&f);
3832  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3833  STREAM_TOSERVER, http1_buf, http1_len);
3834  if (r != 0) {
3835  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3836  result = 0;
3837  FLOWLOCK_UNLOCK(&f);
3838  goto end;
3839  }
3840  FLOWLOCK_UNLOCK(&f);
3841 
3842  http_state = f.alstate;
3843  if (http_state == NULL) {
3844  printf("no http state: \n");
3845  result = 0;
3846  goto end;
3847  }
3848 
3849  /* do detect */
3850  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3851 
3852  if (PacketAlertCheck(p1, 1)) {
3853  printf("sid 1 matched but shouldn't have\n");
3854  goto end;
3855  }
3856 
3857  FLOWLOCK_WRLOCK(&f);
3858  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3859  STREAM_TOSERVER, http2_buf, http2_len);
3860  if (r != 0) {
3861  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3862  result = 0;
3863  FLOWLOCK_UNLOCK(&f);
3864  goto end;
3865  }
3866  FLOWLOCK_UNLOCK(&f);
3867 
3868  /* do detect */
3869  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3870 
3871  if (PacketAlertCheck(p2, 1)) {
3872  printf("sid 1 matched but shouldn't have");
3873  goto end;
3874  }
3875 
3876  result = 1;
3877 
3878 end:
3879  if (alp_tctx != NULL)
3880  AppLayerParserThreadCtxFree(alp_tctx);
3881  if (de_ctx != NULL)
3882  DetectEngineCtxFree(de_ctx);
3883 
3885  FLOW_DESTROY(&f);
3886  UTHFreePackets(&p1, 1);
3887  UTHFreePackets(&p2, 1);
3888  return result;
3889 }
3890 
3891 static int DetectEngineHttpHeaderTest26(void)
3892 {
3893  TcpSession ssn;
3894  Packet *p1 = NULL;
3895  Packet *p2 = NULL;
3896  ThreadVars th_v;
3897  DetectEngineCtx *de_ctx = NULL;
3898  DetectEngineThreadCtx *det_ctx = NULL;
3899  HtpState *http_state = NULL;
3900  Flow f;
3901  uint8_t http1_buf[] =
3902  "GET /index.html HTTP/1.0\r\n"
3903  "Host: This_is_dummy_body1";
3904  uint8_t http2_buf[] =
3905  "This_is_dummy_message_body2\r\n"
3906  "\r\n";
3907  uint32_t http1_len = sizeof(http1_buf) - 1;
3908  uint32_t http2_len = sizeof(http2_buf) - 1;
3909  int result = 0;
3911 
3912  memset(&th_v, 0, sizeof(th_v));
3913  memset(&f, 0, sizeof(f));
3914  memset(&ssn, 0, sizeof(ssn));
3915 
3916  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3917  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3918 
3919  FLOW_INITIALIZE(&f);
3920  f.protoctx = (void *)&ssn;
3921  f.proto = IPPROTO_TCP;
3922  f.flags |= FLOW_IPV4;
3923 
3924  p1->flow = &f;
3928  p2->flow = &f;
3932  f.alproto = ALPROTO_HTTP;
3933 
3935 
3936  de_ctx = DetectEngineCtxInit();
3937  if (de_ctx == NULL)
3938  goto end;
3939 
3940  de_ctx->flags |= DE_QUIET;
3941 
3942  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3943  "(msg:\"http client body test\"; "
3944  "pcre:/body1/H; "
3945  "content:\"dummy\"; distance:8; http_header; "
3946  "sid:1;)");
3947  if (de_ctx->sig_list == NULL)
3948  goto end;
3949 
3950  SigGroupBuild(de_ctx);
3951  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3952 
3953  FLOWLOCK_WRLOCK(&f);
3954  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3955  STREAM_TOSERVER, http1_buf, http1_len);
3956  if (r != 0) {
3957  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3958  result = 0;
3959  FLOWLOCK_UNLOCK(&f);
3960  goto end;
3961  }
3962  FLOWLOCK_UNLOCK(&f);
3963 
3964  http_state = f.alstate;
3965  if (http_state == NULL) {
3966  printf("no http state: \n");
3967  result = 0;
3968  goto end;
3969  }
3970 
3971  /* do detect */
3972  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3973 
3974  if (PacketAlertCheck(p1, 1)) {
3975  printf("sid 1 matched but shouldn't have\n");
3976  goto end;
3977  }
3978 
3979  FLOWLOCK_WRLOCK(&f);
3980  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3981  STREAM_TOSERVER, http2_buf, http2_len);
3982  if (r != 0) {
3983  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3984  result = 0;
3985  FLOWLOCK_UNLOCK(&f);
3986  goto end;
3987  }
3988  FLOWLOCK_UNLOCK(&f);
3989 
3990  /* do detect */
3991  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3992 
3993  if (!PacketAlertCheck(p2, 1)) {
3994  printf("sid 1 didn't match but should have");
3995  goto end;
3996  }
3997 
3998  result = 1;
3999 
4000 end:
4001  if (alp_tctx != NULL)
4002  AppLayerParserThreadCtxFree(alp_tctx);
4003  if (de_ctx != NULL)
4004  DetectEngineCtxFree(de_ctx);
4005 
4007  FLOW_DESTROY(&f);
4008  UTHFreePackets(&p1, 1);
4009  UTHFreePackets(&p2, 1);
4010  return result;
4011 }
4012 
4013 static int DetectEngineHttpHeaderTest27(void)
4014 {
4015  TcpSession ssn;
4016  Packet *p1 = NULL;
4017  Packet *p2 = NULL;
4018  ThreadVars th_v;
4019  DetectEngineCtx *de_ctx = NULL;
4020  DetectEngineThreadCtx *det_ctx = NULL;
4021  HtpState *http_state = NULL;
4022  Flow f;
4023  uint8_t http1_buf[] =
4024  "GET /index.html HTTP/1.0\r\n"
4025  "Host: This_is_dummy_body1";
4026  uint8_t http2_buf[] =
4027  "This_is_dummy_message_body2\r\n"
4028  "\r\n";
4029  uint32_t http1_len = sizeof(http1_buf) - 1;
4030  uint32_t http2_len = sizeof(http2_buf) - 1;
4031  int result = 0;
4033 
4034  memset(&th_v, 0, sizeof(th_v));
4035  memset(&f, 0, sizeof(f));
4036  memset(&ssn, 0, sizeof(ssn));
4037 
4038  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4039  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4040 
4041  FLOW_INITIALIZE(&f);
4042  f.protoctx = (void *)&ssn;
4043  f.proto = IPPROTO_TCP;
4044  f.flags |= FLOW_IPV4;
4045 
4046  p1->flow = &f;
4050  p2->flow = &f;
4054  f.alproto = ALPROTO_HTTP;
4055 
4057 
4058  de_ctx = DetectEngineCtxInit();
4059  if (de_ctx == NULL)
4060  goto end;
4061 
4062  de_ctx->flags |= DE_QUIET;
4063 
4064  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4065  "(msg:\"http client body test\"; "
4066  "pcre:/body1/H; "
4067  "content:\"dummy\"; distance:14; http_header; "
4068  "sid:1;)");
4069  if (de_ctx->sig_list == NULL)
4070  goto end;
4071 
4072  SigGroupBuild(de_ctx);
4073  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4074 
4075  FLOWLOCK_WRLOCK(&f);
4076  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4077  STREAM_TOSERVER, http1_buf, http1_len);
4078  if (r != 0) {
4079  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4080  result = 0;
4081  FLOWLOCK_UNLOCK(&f);
4082  goto end;
4083  }
4084  FLOWLOCK_UNLOCK(&f);
4085 
4086  http_state = f.alstate;
4087  if (http_state == NULL) {
4088  printf("no http state: \n");
4089  result = 0;
4090  goto end;
4091  }
4092 
4093  /* do detect */
4094  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4095 
4096  if (PacketAlertCheck(p1, 1)) {
4097  printf("sid 1 matched but shouldn't have\n");
4098  goto end;
4099  }
4100 
4101  FLOWLOCK_WRLOCK(&f);
4102  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4103  STREAM_TOSERVER, http2_buf, http2_len);
4104  if (r != 0) {
4105  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4106  result = 0;
4107  FLOWLOCK_UNLOCK(&f);
4108  goto end;
4109  }
4110  FLOWLOCK_UNLOCK(&f);
4111 
4112  /* do detect */
4113  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4114 
4115  if (PacketAlertCheck(p2, 1)) {
4116  printf("sid 1 matched but shouldn't have");
4117  goto end;
4118  }
4119 
4120  result = 1;
4121 
4122 end:
4123  if (alp_tctx != NULL)
4124  AppLayerParserThreadCtxFree(alp_tctx);
4125  if (de_ctx != NULL)
4126  DetectEngineCtxFree(de_ctx);
4127 
4129  FLOW_DESTROY(&f);
4130  UTHFreePackets(&p1, 1);
4131  UTHFreePackets(&p2, 1);
4132  return result;
4133 }
4134 
4135 static int DetectEngineHttpHeaderTest28(void)
4136 {
4137  TcpSession ssn;
4138  Packet *p1 = NULL;
4139  Packet *p2 = NULL;
4140  ThreadVars th_v;
4141  DetectEngineCtx *de_ctx = NULL;
4142  DetectEngineThreadCtx *det_ctx = NULL;
4143  HtpState *http_state = NULL;
4144  Flow f;
4145  uint8_t http_buf1[] =
4146  "GET /index.html HTTP/1.0\r\n"
4147  "Host: www.openinfosecfoundation.org\r\n"
4148  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
4149  "\r\n";
4150  uint32_t http_buf1_len = sizeof(http_buf1) - 1;
4151  uint8_t http_buf2[] =
4152  "HTTP/1.0 200 ok\r\n"
4153  "Content-Type: text/html\r\n"
4154  "Content-Length: 6\r\n"
4155  "\r\n"
4156  "abcdef";
4157  uint32_t http_buf2_len = sizeof(http_buf2) - 1;
4158  int result = 0;
4160 
4161  memset(&th_v, 0, sizeof(th_v));
4162  memset(&f, 0, sizeof(f));
4163  memset(&ssn, 0, sizeof(ssn));
4164 
4165  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4166  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4167 
4168  FLOW_INITIALIZE(&f);
4169  f.protoctx = (void *)&ssn;
4170  f.proto = IPPROTO_TCP;
4171  f.flags |= FLOW_IPV4;
4172 
4173  p1->flow = &f;
4177  p2->flow = &f;
4181  f.alproto = ALPROTO_HTTP;
4182 
4184 
4185  de_ctx = DetectEngineCtxInit();
4186  if (de_ctx == NULL)
4187  goto end;
4188 
4189  de_ctx->flags |= DE_QUIET;
4190 
4191  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4192  "(msg:\"http header test\"; "
4193  "content:\"Content-Length: 6\"; http_header; "
4194  "sid:1;)");
4195  if (de_ctx->sig_list == NULL)
4196  goto end;
4197 
4198  SigGroupBuild(de_ctx);
4199  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4200 
4201  FLOWLOCK_WRLOCK(&f);
4202  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4203  STREAM_TOSERVER, http_buf1, http_buf1_len);
4204  if (r != 0) {
4205  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4206  result = 0;
4207  FLOWLOCK_UNLOCK(&f);
4208  goto end;
4209  }
4210  FLOWLOCK_UNLOCK(&f);
4211 
4212  http_state = f.alstate;
4213  if (http_state == NULL) {
4214  printf("no http state: \n");
4215  result = 0;
4216  goto end;
4217  }
4218 
4219  /* do detect */
4220  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4221 
4222  if (PacketAlertCheck(p1, 1)) {
4223  printf("sid 1 matched but shouldn't have\n");
4224  goto end;
4225  }
4226 
4227  FLOWLOCK_WRLOCK(&f);
4228  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4229  STREAM_TOCLIENT, http_buf2, http_buf2_len);
4230  if (r != 0) {
4231  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4232  result = 0;
4233  FLOWLOCK_UNLOCK(&f);
4234  goto end;
4235  }
4236  FLOWLOCK_UNLOCK(&f);
4237 
4238  /* do detect */
4239  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4240 
4241  FAIL_IF(!PacketAlertCheck(p2, 1));
4242 
4243  result = 1;
4244 
4245 end:
4246  if (alp_tctx != NULL)
4247  AppLayerParserThreadCtxFree(alp_tctx);
4248  if (de_ctx != NULL)
4249  DetectEngineCtxFree(de_ctx);
4250 
4252  FLOW_DESTROY(&f);
4253  UTHFreePackets(&p1, 1);
4254  UTHFreePackets(&p2, 1);
4255  return result;
4256 }
4257 
4258 static int DetectEngineHttpHeaderTest29(void)
4259 {
4260  TcpSession ssn;
4261  Packet *p1 = NULL;
4262  Packet *p2 = NULL;
4263  ThreadVars th_v;
4264  DetectEngineCtx *de_ctx = NULL;
4265  DetectEngineThreadCtx *det_ctx = NULL;
4266  HtpState *http_state = NULL;
4267  Flow f;
4268  uint8_t http_buf1[] =
4269  "GET /index.html HTTP/1.0\r\n"
4270  "Host: www.openinfosecfoundation.org\r\n"
4271  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
4272  "\r\n";
4273  uint32_t http_buf1_len = sizeof(http_buf1) - 1;
4274  uint8_t http_buf2[] =
4275  "HTTP/1.0 200 ok\r\n"
4276  "Content-Type: text/html\r\n"
4277  "Content-Length: 6\r\n"
4278  "\r\n"
4279  "abcdef";
4280  uint32_t http_buf2_len = sizeof(http_buf2) - 1;
4281  int result = 0;
4283 
4284  memset(&th_v, 0, sizeof(th_v));
4285  memset(&f, 0, sizeof(f));
4286  memset(&ssn, 0, sizeof(ssn));
4287 
4288  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4289  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4290 
4291  FLOW_INITIALIZE(&f);
4292  f.protoctx = (void *)&ssn;
4293  f.proto = IPPROTO_TCP;
4294  f.flags |= FLOW_IPV4;
4295 
4296  p1->flow = &f;
4300  p2->flow = &f;
4304  f.alproto = ALPROTO_HTTP;
4305 
4307 
4308  de_ctx = DetectEngineCtxInit();
4309  if (de_ctx == NULL)
4310  goto end;
4311 
4312  de_ctx->flags |= DE_QUIET;
4313 
4314  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4315  "(msg:\"http header test\"; "
4316  "content:\"Content-Length: 7\"; http_header; "
4317  "sid:1;)");
4318  if (de_ctx->sig_list == NULL)
4319  goto end;
4320 
4321  SigGroupBuild(de_ctx);
4322  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4323 
4324  FLOWLOCK_WRLOCK(&f);
4325  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4326  STREAM_TOSERVER, http_buf1, http_buf1_len);
4327  if (r != 0) {
4328  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4329  result = 0;
4330  FLOWLOCK_UNLOCK(&f);
4331  goto end;
4332  }
4333  FLOWLOCK_UNLOCK(&f);
4334 
4335  http_state = f.alstate;
4336  if (http_state == NULL) {
4337  printf("no http state: \n");
4338  result = 0;
4339  goto end;
4340  }
4341 
4342  /* do detect */
4343  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4344 
4345  if (PacketAlertCheck(p1, 1)) {
4346  printf("sid 1 matched but shouldn't have\n");
4347  goto end;
4348  }
4349 
4350  FLOWLOCK_WRLOCK(&f);
4351  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4352  STREAM_TOCLIENT, http_buf2, http_buf2_len);
4353  if (r != 0) {
4354  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4355  result = 0;
4356  FLOWLOCK_UNLOCK(&f);
4357  goto end;
4358  }
4359  FLOWLOCK_UNLOCK(&f);
4360 
4361  /* do detect */
4362  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4363 
4364  if (PacketAlertCheck(p2, 1)) {
4365  printf("sid 1 matched but shouldn't have");
4366  goto end;
4367  }
4368 
4369  result = 1;
4370 
4371 end:
4372  if (alp_tctx != NULL)
4373  AppLayerParserThreadCtxFree(alp_tctx);
4374  if (de_ctx != NULL)
4375  DetectEngineCtxFree(de_ctx);
4376 
4378  FLOW_DESTROY(&f);
4379  UTHFreePackets(&p1, 1);
4380  UTHFreePackets(&p2, 1);
4381  return result;
4382 }
4383 
4384 #if 0
4385 
4386 static int DetectEngineHttpHeaderTest30(void)
4387 {
4388  int result = 0;
4390 
4391  if (de_ctx == NULL) {
4392  goto end;
4393  }
4394 
4395  de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
4396  "(msg:\"http header test\"; "
4397  "content:\"Content-Length: 6\"; http_header; "
4398  "content:\"User-Agent: Mozilla\"; http_header; "
4399  "sid:1;)");
4400  if (de_ctx->sig_list != NULL) {
4401  goto end;
4402  }
4403 
4404  result = 1;
4405 
4406  end:
4407  if (de_ctx != NULL)
4408  DetectEngineCtxFree(de_ctx);
4409  return result;
4410 }
4411 
4412 #endif /* #if 0 */
4413 
4414 static int DetectEngineHttpHeaderTest30(void)
4415 {
4416  TcpSession ssn;
4417  Packet *p1 = NULL;
4418  Packet *p2 = NULL;
4419  ThreadVars th_v;
4420  DetectEngineCtx *de_ctx = NULL;
4421  DetectEngineThreadCtx *det_ctx = NULL;
4422  HtpState *http_state = NULL;
4423  Flow f;
4424  uint8_t http_buf1[] =
4425  "GET /index.html HTTP/1.0\r\n"
4426  "Host: www.openinfosecfoundation.org\r\n"
4427  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
4428  "\r\n";
4429  uint32_t http_buf1_len = sizeof(http_buf1) - 1;
4430  uint8_t http_buf2[] =
4431  "HTTP/1.0 200 ok\r\n"
4432  "Set-Cookie: dummycookieset\r\n"
4433  "Content-Type: text/html\r\n"
4434  "Content-Length: 6\r\n"
4435  "\r\n"
4436  "abcdef";
4437  uint32_t http_buf2_len = sizeof(http_buf2) - 1;
4438  int result = 0;
4440 
4441  memset(&th_v, 0, sizeof(th_v));
4442  memset(&f, 0, sizeof(f));
4443  memset(&ssn, 0, sizeof(ssn));
4444 
4445  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4446  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4447 
4448  FLOW_INITIALIZE(&f);
4449  f.protoctx = (void *)&ssn;
4450  f.proto = IPPROTO_TCP;
4451  f.flags |= FLOW_IPV4;
4452 
4453  p1->flow = &f;
4457  p2->flow = &f;
4461  f.alproto = ALPROTO_HTTP;
4462 
4464 
4465  de_ctx = DetectEngineCtxInit();
4466  if (de_ctx == NULL)
4467  goto end;
4468 
4469  de_ctx->flags |= DE_QUIET;
4470 
4471  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4472  "(msg:\"http header test\"; "
4473  "content:\"dummycookieset\"; http_header; "
4474  "sid:1;)");
4475  if (de_ctx->sig_list == NULL)
4476  goto end;
4477 
4478  SigGroupBuild(de_ctx);
4479  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4480 
4481  FLOWLOCK_WRLOCK(&f);
4482  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4483  STREAM_TOSERVER, http_buf1, http_buf1_len);
4484  if (r != 0) {
4485  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4486  result = 0;
4487  FLOWLOCK_UNLOCK(&f);
4488  goto end;
4489  }
4490  FLOWLOCK_UNLOCK(&f);
4491 
4492  http_state = f.alstate;
4493  if (http_state == NULL) {
4494  printf("no http state: \n");
4495  result = 0;
4496  goto end;
4497  }
4498 
4499  /* do detect */
4500  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4501 
4502  if (PacketAlertCheck(p1, 1)) {
4503  printf("sid 1 matched but shouldn't have\n");
4504  goto end;
4505  }
4506 
4507  FLOWLOCK_WRLOCK(&f);
4508  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4509  STREAM_TOCLIENT, http_buf2, http_buf2_len);
4510  if (r != 0) {
4511  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4512  result = 0;
4513  FLOWLOCK_UNLOCK(&f);
4514  goto end;
4515  }
4516  FLOWLOCK_UNLOCK(&f);
4517 
4518  /* do detect */
4519  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4520 
4521  if (PacketAlertCheck(p2, 1)) {
4522  printf("sid 1 matched but shouldn't have\n");
4523  goto end;
4524  }
4525 
4526  result = 1;
4527 
4528 end:
4529  if (alp_tctx != NULL)
4530  AppLayerParserThreadCtxFree(alp_tctx);
4531  if (de_ctx != NULL)
4532  DetectEngineCtxFree(de_ctx);
4533 
4535  FLOW_DESTROY(&f);
4536  UTHFreePackets(&p1, 1);
4537  UTHFreePackets(&p2, 1);
4538  return result;
4539 }
4540 
4541 /** \test reassembly bug where headers with names of length 6 were
4542  * skipped
4543  */
4544 static int DetectEngineHttpHeaderTest31(void)
4545 {
4546  TcpSession ssn;
4547  Packet *p1 = NULL;
4548  ThreadVars th_v;
4549  DetectEngineCtx *de_ctx = NULL;
4550  DetectEngineThreadCtx *det_ctx = NULL;
4551  HtpState *http_state = NULL;
4552  Flow f;
4553  uint8_t http1_buf[] =
4554  "GET /index.html HTTP/1.0\r\n"
4555  "Accept: blah\r\n"
4556  "Cookie: blah\r\n"
4557  "Crazy6: blah\r\n"
4558  "SixZix: blah\r\n\r\n";
4559  uint32_t http1_len = sizeof(http1_buf) - 1;
4560  int result = 0;
4562 
4563  memset(&th_v, 0, sizeof(th_v));
4564  memset(&f, 0, sizeof(f));
4565  memset(&ssn, 0, sizeof(ssn));
4566 
4567  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4568 
4569  FLOW_INITIALIZE(&f);
4570  f.protoctx = (void *)&ssn;
4571  f.proto = IPPROTO_TCP;
4572  f.flags |= FLOW_IPV4;
4573 
4574  p1->flow = &f;
4578  f.alproto = ALPROTO_HTTP;
4579 
4581 
4582  de_ctx = DetectEngineCtxInit();
4583  if (de_ctx == NULL)
4584  goto end;
4585 
4586  de_ctx->flags |= DE_QUIET;
4587 
4588  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4589  "(content:\"Accept|3a|\"; http_header; "
4590  "content:!\"Cookie|3a|\"; http_header; "
4591  "content:\"Crazy6|3a|\"; http_header; "
4592  "content:\"SixZix|3a|\"; http_header; "
4593  "sid:1;)");
4594  if (de_ctx->sig_list == NULL)
4595  goto end;
4596 
4597  SigGroupBuild(de_ctx);
4598  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4599 
4600  FLOWLOCK_WRLOCK(&f);
4601  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4602  STREAM_TOSERVER, http1_buf, http1_len);
4603  if (r != 0) {
4604  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4605  result = 0;
4606  FLOWLOCK_UNLOCK(&f);
4607  goto end;
4608  }
4609  FLOWLOCK_UNLOCK(&f);
4610 
4611  http_state = f.alstate;
4612  if (http_state == NULL) {
4613  printf("no http state: \n");
4614  result = 0;
4615  goto end;
4616  }
4617 
4618  /* do detect */
4619  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4620 
4621  if (!(PacketAlertCheck(p1, 1))) {
4622  printf("sid 1 didn't match but should have: ");
4623  goto end;
4624  }
4625 
4626  result = 1;
4627 
4628 end:
4629  if (alp_tctx != NULL)
4630  AppLayerParserThreadCtxFree(alp_tctx);
4631  if (de_ctx != NULL)
4632  DetectEngineCtxFree(de_ctx);
4633 
4635  FLOW_DESTROY(&f);
4636  UTHFreePackets(&p1, 1);
4637  return result;
4638 }
4639 
4640 /**
4641  * \test Trailing headers.
4642  */
4643 static int DetectEngineHttpHeaderTest32(void)
4644 {
4645  TcpSession ssn;
4646  Packet *p1 = NULL;
4647  ThreadVars th_v;
4648  DetectEngineCtx *de_ctx = NULL;
4649  DetectEngineThreadCtx *det_ctx = NULL;
4650  HtpState *http_state = NULL;
4651  Flow f;
4652  uint8_t http1_buf[] =
4653  "GET /index.html HTTP/1.0\r\n"
4654  "host: boom\r\n"
4655  "Transfer-Encoding: chunked\r\n"
4656  "\r\n"
4657  "13\r\n"
4658  "This is dummy body1\r\n"
4659  "0\r\n"
4660  "Dummy-Header: kaboom\r\n"
4661  "\r\n";
4662  uint32_t http1_len = sizeof(http1_buf) - 1;
4663  int result = 0;
4665 
4666  memset(&th_v, 0, sizeof(th_v));
4667  memset(&f, 0, sizeof(f));
4668  memset(&ssn, 0, sizeof(ssn));
4669 
4670  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4671 
4672  FLOW_INITIALIZE(&f);
4673  f.protoctx = (void *)&ssn;
4674  f.proto = IPPROTO_TCP;
4675  f.flags |= FLOW_IPV4;
4676 
4677  p1->flow = &f;
4681  f.alproto = ALPROTO_HTTP;
4682 
4684 
4685  de_ctx = DetectEngineCtxInit();
4686  if (de_ctx == NULL)
4687  goto end;
4688 
4689  de_ctx->flags |= DE_QUIET;
4690 
4691  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4692  "(content:\"Dummy\"; http_header; "
4693  "sid:1;)");
4694  if (de_ctx->sig_list == NULL)
4695  goto end;
4696 
4697  SigGroupBuild(de_ctx);
4698  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4699 
4700  FLOWLOCK_WRLOCK(&f);
4701  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4702  STREAM_TOSERVER, http1_buf, http1_len);
4703  if (r != 0) {
4704  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4705  result = 0;
4706  FLOWLOCK_UNLOCK(&f);
4707  goto end;
4708  }
4709  FLOWLOCK_UNLOCK(&f);
4710 
4711  http_state = f.alstate;
4712  if (http_state == NULL) {
4713  printf("no http state: \n");
4714  result = 0;
4715  goto end;
4716  }
4717 
4718  /* do detect */
4719  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4720 
4721  if (!(PacketAlertCheck(p1, 1))) {
4722  printf("sid 1 didn't match but should have: ");
4723  goto end;
4724  }
4725 
4726  result = 1;
4727 
4728 end:
4729  if (alp_tctx != NULL)
4730  AppLayerParserThreadCtxFree(alp_tctx);
4731  if (de_ctx != NULL)
4732  DetectEngineCtxFree(de_ctx);
4733 
4735  FLOW_DESTROY(&f);
4736  UTHFreePackets(&p1, 1);
4737  return result;
4738 }
4739 
4740 /**
4741  * \test Trailing headers.
4742  */
4743 static int DetectEngineHttpHeaderTest33(void)
4744 {
4745  TcpSession ssn;
4746  Packet *p1 = NULL;
4747  Packet *p2 = NULL;
4748  ThreadVars th_v;
4749  DetectEngineCtx *de_ctx = NULL;
4750  DetectEngineThreadCtx *det_ctx = NULL;
4751  HtpState *http_state = NULL;
4752  Flow f;
4753  uint8_t http1_buf[] =
4754  "GET /index.html HTTP/1.0\r\n"
4755  "host: boom\r\n"
4756  "Transfer-Encoding: chunked\r\n"
4757  "\r\n"
4758  "13\r\n"
4759  "This is dummy body1\r\n"
4760  "0\r\n";
4761  uint8_t http2_buf[] =
4762  "Dummy-Header: kaboom\r\n"
4763  "\r\n";
4764  uint32_t http1_len = sizeof(http1_buf) - 1;
4765  uint32_t http2_len = sizeof(http2_buf) - 1;
4766 
4768  FAIL_IF_NULL(alp_tctx);
4769 
4770  memset(&th_v, 0, sizeof(th_v));
4771  memset(&f, 0, sizeof(f));
4772  memset(&ssn, 0, sizeof(ssn));
4773 
4774  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4775  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4776 
4777  FLOW_INITIALIZE(&f);
4778  f.protoctx = (void *)&ssn;
4779  f.proto = IPPROTO_TCP;
4780  f.flags |= FLOW_IPV4;
4781 
4782  p1->flow = &f;
4786  p2->flow = &f;
4790  f.alproto = ALPROTO_HTTP;
4791 
4793 
4794  de_ctx = DetectEngineCtxInit();
4795  FAIL_IF(de_ctx == NULL);
4796  de_ctx->flags |= DE_QUIET;
4797 
4798  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4799  "(content:\"Dummy\"; http_header; "
4800  "sid:1;)");
4801  FAIL_IF(de_ctx->sig_list == NULL);
4802 
4803  SigGroupBuild(de_ctx);
4804  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4805 
4806  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4807  STREAM_TOSERVER, http1_buf, http1_len);
4808  FAIL_IF_NOT(r == 0);
4809 
4810  http_state = f.alstate;
4811  FAIL_IF(http_state == NULL);
4812 
4813  /* do detect */
4814  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4815 
4816  FAIL_IF(PacketAlertCheck(p1, 1));
4817 
4818  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4819  STREAM_TOSERVER, http2_buf, http2_len);
4820  FAIL_IF_NOT(r == 0);
4821 
4822  /* do detect */
4823  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4824 
4825  FAIL_IF(!PacketAlertCheck(p2, 1));
4826 
4827  AppLayerParserThreadCtxFree(alp_tctx);
4828  DetectEngineCtxFree(de_ctx);
4829 
4831  FLOW_DESTROY(&f);
4832  UTHFreePackets(&p1, 1);
4833  UTHFreePackets(&p2, 1);
4834  PASS;
4835 }
4836 
4837 /**
4838  * \test Trailing headers.
4839  */
4840 static int DetectEngineHttpHeaderTest34(void)
4841 {
4842  TcpSession ssn;
4843  ThreadVars th_v;
4844  DetectEngineCtx *de_ctx = NULL;
4845  DetectEngineThreadCtx *det_ctx = NULL;
4846  HtpState *http_state = NULL;
4847  Flow f;
4848  uint8_t http1_buf[] =
4849  "GET /index.html HTTP/1.0\r\n"
4850  "host: boom\r\n"
4851  "Dummy-Header1: blah\r\n"
4852  "Transfer-Encoding: chunked\r\n"
4853  "\r\n";
4854  uint8_t http2_buf[] =
4855  "13\r\n"
4856  "This is dummy body1\r\n"
4857  "0\r\n";
4858  uint8_t http3_buf[] =
4859  "Dummy-Header2: kaboom\r\n"
4860  "\r\n";
4861  uint32_t http1_len = sizeof(http1_buf) - 1;
4862  uint32_t http2_len = sizeof(http2_buf) - 1;
4863  uint32_t http3_len = sizeof(http3_buf) - 1;
4864 
4866  FAIL_IF_NULL(alp_tctx);
4867 
4868  memset(&th_v, 0, sizeof(th_v));
4869  memset(&f, 0, sizeof(f));
4870  memset(&ssn, 0, sizeof(ssn));
4871 
4872  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4873  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4874  Packet *p3 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4875 
4876  FLOW_INITIALIZE(&f);
4877  f.protoctx = (void *)&ssn;
4878  f.proto = IPPROTO_TCP;
4879  f.flags |= FLOW_IPV4;
4880 
4881  p1->flow = &f;
4885  p1->pcap_cnt = 1;
4886  p2->flow = &f;
4890  p2->pcap_cnt = 2;
4891  p3->flow = &f;
4895  p3->pcap_cnt = 3;
4896  f.alproto = ALPROTO_HTTP;
4897 
4899 
4900  de_ctx = DetectEngineCtxInit();
4901  FAIL_IF(de_ctx == NULL);
4902  de_ctx->flags |= DE_QUIET;
4903 
4904  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4905  "(content:\"Dummy\"; http_header; content:\"Header2\"; http_header; within:8; "
4906  "sid:1;)");
4907  FAIL_IF(de_ctx->sig_list == NULL);
4908 
4909  SigGroupBuild(de_ctx);
4910  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4911 
4912  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4913  STREAM_TOSERVER, http1_buf, http1_len);
4914  FAIL_IF_NOT(r == 0);
4915 
4916  http_state = f.alstate;
4917  FAIL_IF(http_state == NULL);
4918 
4919  /* do detect */
4920  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4921  FAIL_IF(PacketAlertCheck(p1, 1));
4922 
4923  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4924  STREAM_TOSERVER, http2_buf, http2_len);
4925  FAIL_IF_NOT(r == 0);
4926 
4927  /* do detect */
4928  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4929  FAIL_IF(PacketAlertCheck(p2, 1));
4930 
4931  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4932  STREAM_TOSERVER, http3_buf, http3_len);
4933  FAIL_IF_NOT(r == 0);
4934 
4935  /* do detect */
4936  SigMatchSignatures(&th_v, de_ctx, det_ctx, p3);
4937  FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */
4938 
4939  AppLayerParserThreadCtxFree(alp_tctx);
4940  DetectEngineCtxFree(de_ctx);
4941 
4943  FLOW_DESTROY(&f);
4944  UTHFreePackets(&p1, 1);
4945  UTHFreePackets(&p2, 1);
4946  UTHFreePackets(&p3, 1);
4947  PASS;
4948 }
4949 
4950 /**
4951  * \test Trailing headers.
4952  */
4953 static int DetectEngineHttpHeaderTest35(void)
4954 {
4955  TcpSession ssn;
4956  ThreadVars th_v;
4957  DetectEngineCtx *de_ctx = NULL;
4958  DetectEngineThreadCtx *det_ctx = NULL;
4959  HtpState *http_state = NULL;
4960  Flow f;
4961  uint8_t http1_buf[] =
4962  "GET /index.html HTTP/1.0\r\n"
4963  "host: boom\r\n"
4964  "Dummy-Header1: blah\r\n"
4965  "Transfer-Encoding: chunked\r\n"
4966  "\r\n";
4967  uint8_t http2_buf[] =
4968  "13\r\n"
4969  "This is dummy body1\r\n"
4970  "0\r\n";
4971  uint8_t http3_buf[] =
4972  "Dummy-Header2: kaboom\r\n"
4973  "\r\n";
4974  uint32_t http1_len = sizeof(http1_buf) - 1;
4975  uint32_t http2_len = sizeof(http2_buf) - 1;
4976  uint32_t http3_len = sizeof(http3_buf) - 1;
4977 
4979  FAIL_IF_NULL(alp_tctx);
4980 
4981  memset(&th_v, 0, sizeof(th_v));
4982  memset(&f, 0, sizeof(f));
4983  memset(&ssn, 0, sizeof(ssn));
4984 
4985  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4986  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4987  Packet *p3 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4988 
4989  FLOW_INITIALIZE(&f);
4990  f.protoctx = (void *)&ssn;
4991  f.proto = IPPROTO_TCP;
4992  f.flags |= FLOW_IPV4;
4993 
4994  p1->flow = &f;
4998  p1->pcap_cnt = 1;
4999  p2->flow = &f;
5003  p2->pcap_cnt = 2;
5004  p3->flow = &f;
5008  p3->pcap_cnt = 3;
5009  f.alproto = ALPROTO_HTTP;
5010 
5012 
5013  de_ctx = DetectEngineCtxInit();
5014  FAIL_IF(de_ctx == NULL);
5015  de_ctx->flags |= DE_QUIET;
5016 
5017  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
5018  "(content:\"Dummy\"; http_header; fast_pattern; content:\"Header2\"; http_header; within:8; "
5019  "sid:1;)");
5020  FAIL_IF(de_ctx->sig_list == NULL);
5021 
5022  SigGroupBuild(de_ctx);
5023  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
5024 
5025  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5026  STREAM_TOSERVER, http1_buf, http1_len);
5027  FAIL_IF_NOT(r == 0);
5028 
5029  http_state = f.alstate;
5030  FAIL_IF(http_state == NULL);
5031 
5032  /* do detect */
5033  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
5034  FAIL_IF(PacketAlertCheck(p1, 1));
5035 
5036  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5037  STREAM_TOSERVER, http2_buf, http2_len);
5038  FAIL_IF_NOT(r == 0);
5039 
5040  /* do detect */
5041  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
5042  FAIL_IF(PacketAlertCheck(p2, 1));
5043 
5044  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5045  STREAM_TOSERVER, http3_buf, http3_len);
5046  FAIL_IF_NOT(r == 0);
5047 
5048  /* do detect */
5049  SigMatchSignatures(&th_v, de_ctx, det_ctx, p3);
5050  FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */
5051 
5052  AppLayerParserThreadCtxFree(alp_tctx);
5053  DetectEngineCtxFree(de_ctx);
5054 
5056  FLOW_DESTROY(&f);
5057  UTHFreePackets(&p1, 1);
5058  UTHFreePackets(&p2, 1);
5059  UTHFreePackets(&p3, 1);
5060  PASS;
5061 }
5062 
5064 {
5065  UtRegisterTest("DetectHttpHeaderParserTest01", DetectHttpHeaderParserTest01);
5066  UtRegisterTest("DetectHttpHeaderParserTest02", DetectHttpHeaderParserTest02);
5067 
5068  UtRegisterTest("DetectHttpHeaderTest01", DetectHttpHeaderTest01);
5069  UtRegisterTest("DetectHttpHeaderTest06", DetectHttpHeaderTest06);
5070  UtRegisterTest("DetectHttpHeaderTest07", DetectHttpHeaderTest07);
5071  UtRegisterTest("DetectHttpHeaderTest08", DetectHttpHeaderTest08);
5072  UtRegisterTest("DetectHttpHeaderTest09", DetectHttpHeaderTest09);
5073  UtRegisterTest("DetectHttpHeaderTest10", DetectHttpHeaderTest10);
5074  UtRegisterTest("DetectHttpHeaderTest11", DetectHttpHeaderTest11);
5075  UtRegisterTest("DetectHttpHeaderTest12", DetectHttpHeaderTest12);
5076  UtRegisterTest("DetectHttpHeaderTest13", DetectHttpHeaderTest13);
5077  UtRegisterTest("DetectHttpHeaderTest20", DetectHttpHeaderTest20);
5078  UtRegisterTest("DetectHttpHeaderTest21", DetectHttpHeaderTest21);
5079  UtRegisterTest("DetectHttpHeaderTest22", DetectHttpHeaderTest22);
5080  UtRegisterTest("DetectHttpHeaderTest23", DetectHttpHeaderTest23);
5081  UtRegisterTest("DetectHttpHeaderTest24", DetectHttpHeaderTest24);
5082  UtRegisterTest("DetectHttpHeaderTest25", DetectHttpHeaderTest25);
5083  UtRegisterTest("DetectHttpHeaderTest26", DetectHttpHeaderTest26);
5084  UtRegisterTest("DetectHttpHeaderTest27", DetectHttpHeaderTest27);
5085  UtRegisterTest("DetectHttpHeaderTest28", DetectHttpHeaderTest28);
5086  UtRegisterTest("DetectHttpHeaderTest29", DetectHttpHeaderTest29);
5087  UtRegisterTest("DetectHttpHeaderTest30", DetectHttpHeaderTest30);
5088 
5089  UtRegisterTest("DetectHttpHeaderIsdataatParseTest",
5090  DetectHttpHeaderIsdataatParseTest);
5091 
5092  UtRegisterTest("DetectEngineHttpHeaderTest01",
5093  DetectEngineHttpHeaderTest01);
5094  UtRegisterTest("DetectEngineHttpHeaderTest02",
5095  DetectEngineHttpHeaderTest02);
5096  UtRegisterTest("DetectEngineHttpHeaderTest03",
5097  DetectEngineHttpHeaderTest03);
5098  UtRegisterTest("DetectEngineHttpHeaderTest04",
5099  DetectEngineHttpHeaderTest04);
5100  UtRegisterTest("DetectEngineHttpHeaderTest05",
5101  DetectEngineHttpHeaderTest05);
5102  UtRegisterTest("DetectEngineHttpHeaderTest06",
5103  DetectEngineHttpHeaderTest06);
5104  UtRegisterTest("DetectEngineHttpHeaderTest07",
5105  DetectEngineHttpHeaderTest07);
5106  UtRegisterTest("DetectEngineHttpHeaderTest08",
5107  DetectEngineHttpHeaderTest08);
5108  UtRegisterTest("DetectEngineHttpHeaderTest09",
5109  DetectEngineHttpHeaderTest09);
5110  UtRegisterTest("DetectEngineHttpHeaderTest10",
5111  DetectEngineHttpHeaderTest10);
5112  UtRegisterTest("DetectEngineHttpHeaderTest11",
5113  DetectEngineHttpHeaderTest11);
5114  UtRegisterTest("DetectEngineHttpHeaderTest12",
5115  DetectEngineHttpHeaderTest12);
5116  UtRegisterTest("DetectEngineHttpHeaderTest13",
5117  DetectEngineHttpHeaderTest13);
5118  UtRegisterTest("DetectEngineHttpHeaderTest14",
5119  DetectEngineHttpHeaderTest14);
5120  UtRegisterTest("DetectEngineHttpHeaderTest15",
5121  DetectEngineHttpHeaderTest15);
5122  UtRegisterTest("DetectEngineHttpHeaderTest16",
5123  DetectEngineHttpHeaderTest16);
5124  UtRegisterTest("DetectEngineHttpHeaderTest17",
5125  DetectEngineHttpHeaderTest17);
5126  UtRegisterTest("DetectEngineHttpHeaderTest20",
5127  DetectEngineHttpHeaderTest20);
5128  UtRegisterTest("DetectEngineHttpHeaderTest21",
5129  DetectEngineHttpHeaderTest21);
5130  UtRegisterTest("DetectEngineHttpHeaderTest22",
5131  DetectEngineHttpHeaderTest22);
5132  UtRegisterTest("DetectEngineHttpHeaderTest23",
5133  DetectEngineHttpHeaderTest23);
5134  UtRegisterTest("DetectEngineHttpHeaderTest24",
5135  DetectEngineHttpHeaderTest24);
5136  UtRegisterTest("DetectEngineHttpHeaderTest25",
5137  DetectEngineHttpHeaderTest25);
5138  UtRegisterTest("DetectEngineHttpHeaderTest26",
5139  DetectEngineHttpHeaderTest26);
5140  UtRegisterTest("DetectEngineHttpHeaderTest27",
5141  DetectEngineHttpHeaderTest27);
5142  UtRegisterTest("DetectEngineHttpHeaderTest28",
5143  DetectEngineHttpHeaderTest28);
5144  UtRegisterTest("DetectEngineHttpHeaderTest29",
5145  DetectEngineHttpHeaderTest29);
5146  UtRegisterTest("DetectEngineHttpHeaderTest30",
5147  DetectEngineHttpHeaderTest30);
5148  UtRegisterTest("DetectEngineHttpHeaderTest31",
5149  DetectEngineHttpHeaderTest31);
5150 #if 0
5151  UtRegisterTest("DetectEngineHttpHeaderTest30",
5152  DetectEngineHttpHeaderTest30, 1);
5153 #endif
5154  UtRegisterTest("DetectEngineHttpHeaderTest32",
5155  DetectEngineHttpHeaderTest32);
5156  UtRegisterTest("DetectEngineHttpHeaderTest33 -- Trailer",
5157  DetectEngineHttpHeaderTest33);
5158  UtRegisterTest("DetectEngineHttpHeaderTest34 -- Trailer",
5159  DetectEngineHttpHeaderTest34);
5160  UtRegisterTest("DetectEngineHttpHeaderTest35 -- Trailer",
5161  DetectEngineHttpHeaderTest35);
5162 }
5163 
5164 /**
5165  * @}
5166  */
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SignatureInitData * init_data
Definition: detect.h:591
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:27
struct Flow_ * flow
Definition: decode.h:445
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint8_t proto
Definition: flow.h:344
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:243
#define PASS
Pass the test.
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
int UTHParseSignature(const char *str, bool expect)
parser a sig and see if the expected result is correct
Signature * sig_list
Definition: detect.h:767
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:203
#define ISDATAAT_RELATIVE
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define DETECT_CONTENT_DISTANCE
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
uint64_t pcap_cnt
Definition: decode.h:561
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
#define ISDATAAT_RAWBYTES
Signature container.
Definition: detect.h:522
#define TRUE
void * protoctx
Definition: flow.h:400
uint16_t flags
Definition: detect-pcre.h:42
struct SigMatch_ * next
Definition: detect.h:322
main detection engine ctx
Definition: detect.h:761
void * alstate
Definition: flow.h:438
#define DE_QUIET
Definition: detect.h:292
uint8_t flags
Definition: detect.h:762
#define ISDATAAT_NEGATED
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
uint16_t mpm_matcher
Definition: detect.h:810
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1669
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
uint8_t flowflags
Definition: decode.h:439
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
struct SigMatch_ ** smlists_tail
Definition: detect.h:518
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
uint8_t type
Definition: detect.h:319
SigMatchCtx * ctx
Definition: detect.h:321
int mpm_default_matcher
Definition: util-mpm.h:170
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
void DetectHttpHeaderRegisterTests(void)
#define DETECT_CONTENT_WITHIN
#define PKT_HAS_FLOW
Definition: decode.h:1093
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
#define DETECT_CONTENT_RELATIVE_NEXT
Per thread variable structure.
Definition: threadvars.h:57
#define FLOW_PKT_TOCLIENT
Definition: flow.h:202
AppProto alproto
application level protocol
Definition: flow.h:409
uint32_t flags
Definition: decode.h:443
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
Flow data structure.
Definition: flow.h:325
#define FLOW_IPV4
Definition: flow.h:94
uint32_t flags
Definition: flow.h:379
#define PKT_STREAM_EST
Definition: decode.h:1091
a single match condition for a signature
Definition: detect.h:318
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
DetectEngineCtx * DetectEngineCtxInit(void)