suricata
detect-http-user-agent.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2016 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \ingroup httplayer
20  *
21  * @{
22  */
23 
24 
25 /** \file
26  *
27  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
28  * \author Victor Julien <victor@inliniac.net>
29  *
30  * \brief Handle HTTP user agent match
31  *
32  */
33 
34 #include "suricata-common.h"
35 #include "suricata.h"
36 #include "flow-util.h"
37 #include "flow.h"
38 #include "app-layer-parser.h"
39 #include "util-unittest.h"
40 #include "util-unittest-helper.h"
41 #include "app-layer.h"
42 #include "app-layer-htp.h"
43 #include "app-layer-protos.h"
44 
45 /**
46  * \test Test that the http_user_agent content matches against a http request
47  * which holds the content.
48  */
49 static int DetectEngineHttpUATest01(void)
50 {
51  TcpSession ssn;
52  Packet *p = NULL;
53  ThreadVars th_v;
54  DetectEngineCtx *de_ctx = NULL;
55  DetectEngineThreadCtx *det_ctx = NULL;
56  HtpState *http_state = NULL;
57  Flow f;
58  uint8_t http_buf[] =
59  "GET /index.html HTTP/1.0\r\n"
60  "User-Agent: CONNECT\r\n"
61  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
62  uint32_t http_len = sizeof(http_buf) - 1;
63  int result = 0;
65 
66  memset(&th_v, 0, sizeof(th_v));
67  memset(&f, 0, sizeof(f));
68  memset(&ssn, 0, sizeof(ssn));
69 
70  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
71 
72  FLOW_INITIALIZE(&f);
73  f.protoctx = (void *)&ssn;
74  f.proto = IPPROTO_TCP;
75  f.flags |= FLOW_IPV4;
76  p->flow = &f;
81 
83 
84  de_ctx = DetectEngineCtxInit();
85  if (de_ctx == NULL)
86  goto end;
87 
88  de_ctx->flags |= DE_QUIET;
89 
90  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
91  "(msg:\"http user agent test\"; "
92  "content:\"CONNECT\"; http_user_agent; "
93  "sid:1;)");
94  if (de_ctx->sig_list == NULL)
95  goto end;
96 
97  SigGroupBuild(de_ctx);
98  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
99 
100  FLOWLOCK_WRLOCK(&f);
101  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
102  STREAM_TOSERVER, http_buf, http_len);
103  if (r != 0) {
104  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
105  result = 0;
106  FLOWLOCK_UNLOCK(&f);
107  goto end;
108  }
109  FLOWLOCK_UNLOCK(&f);
110 
111  http_state = f.alstate;
112  if (http_state == NULL) {
113  printf("no http state: ");
114  result = 0;
115  goto end;
116  }
117 
118  /* do detect */
119  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
120 
121  if (!(PacketAlertCheck(p, 1))) {
122  printf("sid 1 didn't match but should have: ");
123  goto end;
124  }
125 
126  result = 1;
127 
128 end:
129  if (alp_tctx != NULL)
130  AppLayerParserThreadCtxFree(alp_tctx);
131  if (de_ctx != NULL)
132  SigGroupCleanup(de_ctx);
133  if (de_ctx != NULL)
134  SigCleanSignatures(de_ctx);
135  if (de_ctx != NULL)
136  DetectEngineCtxFree(de_ctx);
137 
139  FLOW_DESTROY(&f);
140  UTHFreePackets(&p, 1);
141  return result;
142 }
143 
144 /**
145  * \test Test that the http_user_agent content matches against a http request
146  * which holds the content.
147  */
148 static int DetectEngineHttpUATest02(void)
149 {
150  TcpSession ssn;
151  Packet *p = NULL;
152  ThreadVars th_v;
153  DetectEngineCtx *de_ctx = NULL;
154  DetectEngineThreadCtx *det_ctx = NULL;
155  HtpState *http_state = NULL;
156  Flow f;
157  uint8_t http_buf[] =
158  "CONNECT /index.html HTTP/1.0\r\n"
159  "User-Agent: CONNECT\r\n"
160  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
161  uint32_t http_len = sizeof(http_buf) - 1;
162  int result = 0;
164 
165  memset(&th_v, 0, sizeof(th_v));
166  memset(&f, 0, sizeof(f));
167  memset(&ssn, 0, sizeof(ssn));
168 
169  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
170 
171  FLOW_INITIALIZE(&f);
172  f.protoctx = (void *)&ssn;
173  f.proto = IPPROTO_TCP;
174  f.flags |= FLOW_IPV4;
175  p->flow = &f;
179  f.alproto = ALPROTO_HTTP;
180 
182 
183  de_ctx = DetectEngineCtxInit();
184  if (de_ctx == NULL)
185  goto end;
186 
187  de_ctx->flags |= DE_QUIET;
188 
189  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
190  "(msg:\"http user agent test\"; "
191  "content:\"CO\"; depth:4; http_user_agent; "
192  "sid:1;)");
193  if (de_ctx->sig_list == NULL)
194  goto end;
195 
196  SigGroupBuild(de_ctx);
197  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
198 
199  FLOWLOCK_WRLOCK(&f);
200  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
201  STREAM_TOSERVER, http_buf, http_len);
202  if (r != 0) {
203  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
204  result = 0;
205  FLOWLOCK_UNLOCK(&f);
206  goto end;
207  }
208  FLOWLOCK_UNLOCK(&f);
209 
210  http_state = f.alstate;
211  if (http_state == NULL) {
212  printf("no http state: ");
213  result = 0;
214  goto end;
215  }
216 
217  /* do detect */
218  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
219 
220  if (!(PacketAlertCheck(p, 1))) {
221  printf("sid 1 didn't match but should have: ");
222  goto end;
223  }
224 
225  result = 1;
226 
227 end:
228  if (alp_tctx != NULL)
229  AppLayerParserThreadCtxFree(alp_tctx);
230  if (de_ctx != NULL)
231  SigGroupCleanup(de_ctx);
232  if (de_ctx != NULL)
233  SigCleanSignatures(de_ctx);
234  if (de_ctx != NULL)
235  DetectEngineCtxFree(de_ctx);
236 
238  FLOW_DESTROY(&f);
239  UTHFreePackets(&p, 1);
240  return result;
241 }
242 
243 /**
244  * \test Test that the http_user_agent content matches against a http request
245  * which holds the content.
246  */
247 static int DetectEngineHttpUATest03(void)
248 {
249  TcpSession ssn;
250  Packet *p = NULL;
251  ThreadVars th_v;
252  DetectEngineCtx *de_ctx = NULL;
253  DetectEngineThreadCtx *det_ctx = NULL;
254  HtpState *http_state = NULL;
255  Flow f;
256  uint8_t http_buf[] =
257  "CONNECT /index.html HTTP/1.0\r\n"
258  "User-Agent: CONNECT\r\n"
259  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
260  uint32_t http_len = sizeof(http_buf) - 1;
261  int result = 0;
263 
264  memset(&th_v, 0, sizeof(th_v));
265  memset(&f, 0, sizeof(f));
266  memset(&ssn, 0, sizeof(ssn));
267 
268  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
269 
270  FLOW_INITIALIZE(&f);
271  f.protoctx = (void *)&ssn;
272  f.proto = IPPROTO_TCP;
273  f.flags |= FLOW_IPV4;
274  p->flow = &f;
278  f.alproto = ALPROTO_HTTP;
279 
281 
282  de_ctx = DetectEngineCtxInit();
283  if (de_ctx == NULL)
284  goto end;
285 
286  de_ctx->flags |= DE_QUIET;
287 
288  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
289  "(msg:\"http_user_agent test\"; "
290  "content:!\"ECT\"; depth:4; http_user_agent; "
291  "sid:1;)");
292  if (de_ctx->sig_list == NULL)
293  goto end;
294 
295  SigGroupBuild(de_ctx);
296  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
297 
298  FLOWLOCK_WRLOCK(&f);
299  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
300  STREAM_TOSERVER, http_buf, http_len);
301  if (r != 0) {
302  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
303  result = 0;
304  FLOWLOCK_UNLOCK(&f);
305  goto end;
306  }
307  FLOWLOCK_UNLOCK(&f);
308 
309  http_state = f.alstate;
310  if (http_state == NULL) {
311  printf("no http state: ");
312  result = 0;
313  goto end;
314  }
315 
316  /* do detect */
317  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
318 
319  if (!(PacketAlertCheck(p, 1))) {
320  printf("sid 1 didn't match but should have: ");
321  goto end;
322  }
323 
324  result = 1;
325 
326 end:
327  if (alp_tctx != NULL)
328  AppLayerParserThreadCtxFree(alp_tctx);
329  if (de_ctx != NULL)
330  SigGroupCleanup(de_ctx);
331  if (de_ctx != NULL)
332  SigCleanSignatures(de_ctx);
333  if (de_ctx != NULL)
334  DetectEngineCtxFree(de_ctx);
335 
337  FLOW_DESTROY(&f);
338  UTHFreePackets(&p, 1);
339  return result;
340 }
341 
342 /**
343  * \test Test that the http_user_agent content matches against a http request
344  * which holds the content.
345  */
346 static int DetectEngineHttpUATest04(void)
347 {
348  TcpSession ssn;
349  Packet *p = NULL;
350  ThreadVars th_v;
351  DetectEngineCtx *de_ctx = NULL;
352  DetectEngineThreadCtx *det_ctx = NULL;
353  HtpState *http_state = NULL;
354  Flow f;
355  uint8_t http_buf[] =
356  "CONNECT /index.html HTTP/1.0\r\n"
357  "User-Agent: CONNECT\r\n"
358  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
359  uint32_t http_len = sizeof(http_buf) - 1;
360  int result = 0;
362 
363  memset(&th_v, 0, sizeof(th_v));
364  memset(&f, 0, sizeof(f));
365  memset(&ssn, 0, sizeof(ssn));
366 
367  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
368 
369  FLOW_INITIALIZE(&f);
370  f.protoctx = (void *)&ssn;
371  f.proto = IPPROTO_TCP;
372  f.flags |= FLOW_IPV4;
373  p->flow = &f;
377  f.alproto = ALPROTO_HTTP;
378 
380 
381  de_ctx = DetectEngineCtxInit();
382  if (de_ctx == NULL)
383  goto end;
384 
385  de_ctx->flags |= DE_QUIET;
386 
387  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
388  "(msg:\"http user agent test\"; "
389  "content:\"ECT\"; depth:4; http_user_agent; "
390  "sid:1;)");
391  if (de_ctx->sig_list == NULL)
392  goto end;
393 
394  SigGroupBuild(de_ctx);
395  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
396 
397  FLOWLOCK_WRLOCK(&f);
398  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
399  STREAM_TOSERVER, http_buf, http_len);
400  if (r != 0) {
401  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
402  result = 0;
403  FLOWLOCK_UNLOCK(&f);
404  goto end;
405  }
406  FLOWLOCK_UNLOCK(&f);
407 
408  http_state = f.alstate;
409  if (http_state == NULL) {
410  printf("no http state: ");
411  result = 0;
412  goto end;
413  }
414 
415  /* do detect */
416  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
417 
418  if (PacketAlertCheck(p, 1)) {
419  printf("sid 1 matched but shouldn't have: ");
420  goto end;
421  }
422 
423  result = 1;
424 
425 end:
426  if (alp_tctx != NULL)
427  AppLayerParserThreadCtxFree(alp_tctx);
428  if (de_ctx != NULL)
429  SigGroupCleanup(de_ctx);
430  if (de_ctx != NULL)
431  SigCleanSignatures(de_ctx);
432  if (de_ctx != NULL)
433  DetectEngineCtxFree(de_ctx);
434 
436  FLOW_DESTROY(&f);
437  UTHFreePackets(&p, 1);
438  return result;
439 }
440 
441 /**
442  * \test Test that the http_user_agent content matches against a http request
443  * which holds the content.
444  */
445 static int DetectEngineHttpUATest05(void)
446 {
447  TcpSession ssn;
448  Packet *p = NULL;
449  ThreadVars th_v;
450  DetectEngineCtx *de_ctx = NULL;
451  DetectEngineThreadCtx *det_ctx = NULL;
452  HtpState *http_state = NULL;
453  Flow f;
454  uint8_t http_buf[] =
455  "CONNECT /index.html HTTP/1.0\r\n"
456  "User-Agent: CONNECT\r\n"
457  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
458  uint32_t http_len = sizeof(http_buf) - 1;
459  int result = 0;
461 
462  memset(&th_v, 0, sizeof(th_v));
463  memset(&f, 0, sizeof(f));
464  memset(&ssn, 0, sizeof(ssn));
465 
466  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
467 
468  FLOW_INITIALIZE(&f);
469  f.protoctx = (void *)&ssn;
470  f.proto = IPPROTO_TCP;
471  f.flags |= FLOW_IPV4;
472  p->flow = &f;
476  f.alproto = ALPROTO_HTTP;
477 
479 
480  de_ctx = DetectEngineCtxInit();
481  if (de_ctx == NULL)
482  goto end;
483 
484  de_ctx->flags |= DE_QUIET;
485 
486  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
487  "(msg:\"http user agent test\"; "
488  "content:!\"CON\"; depth:4; http_user_agent; "
489  "sid:1;)");
490  if (de_ctx->sig_list == NULL)
491  goto end;
492 
493  SigGroupBuild(de_ctx);
494  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
495 
496  FLOWLOCK_WRLOCK(&f);
497  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
498  STREAM_TOSERVER, http_buf, http_len);
499  if (r != 0) {
500  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
501  result = 0;
502  FLOWLOCK_UNLOCK(&f);
503  goto end;
504  }
505  FLOWLOCK_UNLOCK(&f);
506 
507  http_state = f.alstate;
508  if (http_state == NULL) {
509  printf("no http state: ");
510  result = 0;
511  goto end;
512  }
513 
514  /* do detect */
515  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
516 
517  if (PacketAlertCheck(p, 1)) {
518  printf("sid 1 matched but shouldn't have: ");
519  goto end;
520  }
521 
522  result = 1;
523 
524 end:
525  if (alp_tctx != NULL)
526  AppLayerParserThreadCtxFree(alp_tctx);
527  if (de_ctx != NULL)
528  SigGroupCleanup(de_ctx);
529  if (de_ctx != NULL)
530  SigCleanSignatures(de_ctx);
531  if (de_ctx != NULL)
532  DetectEngineCtxFree(de_ctx);
533 
535  FLOW_DESTROY(&f);
536  UTHFreePackets(&p, 1);
537  return result;
538 }
539 
540 /**
541  * \test Test that the http_user_agent content matches against a http request
542  * which holds the content.
543  */
544 static int DetectEngineHttpUATest06(void)
545 {
546  TcpSession ssn;
547  Packet *p = NULL;
548  ThreadVars th_v;
549  DetectEngineCtx *de_ctx = NULL;
550  DetectEngineThreadCtx *det_ctx = NULL;
551  HtpState *http_state = NULL;
552  Flow f;
553  uint8_t http_buf[] =
554  "CONNECT /index.html HTTP/1.0\r\n"
555  "User-Agent: CONNECT\r\n"
556  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
557  uint32_t http_len = sizeof(http_buf) - 1;
558  int result = 0;
560 
561  memset(&th_v, 0, sizeof(th_v));
562  memset(&f, 0, sizeof(f));
563  memset(&ssn, 0, sizeof(ssn));
564 
565  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
566 
567  FLOW_INITIALIZE(&f);
568  f.protoctx = (void *)&ssn;
569  f.proto = IPPROTO_TCP;
570  f.flags |= FLOW_IPV4;
571  p->flow = &f;
575  f.alproto = ALPROTO_HTTP;
576 
578 
579  de_ctx = DetectEngineCtxInit();
580  if (de_ctx == NULL)
581  goto end;
582 
583  de_ctx->flags |= DE_QUIET;
584 
585  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
586  "(msg:\"http user agent test\"; "
587  "content:\"ECT\"; offset:3; http_user_agent; "
588  "sid:1;)");
589  if (de_ctx->sig_list == NULL)
590  goto end;
591 
592  SigGroupBuild(de_ctx);
593  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
594 
595  FLOWLOCK_WRLOCK(&f);
596  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
597  STREAM_TOSERVER, http_buf, http_len);
598  if (r != 0) {
599  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
600  result = 0;
601  FLOWLOCK_UNLOCK(&f);
602  goto end;
603  }
604  FLOWLOCK_UNLOCK(&f);
605 
606  http_state = f.alstate;
607  if (http_state == NULL) {
608  printf("no http state: ");
609  result = 0;
610  goto end;
611  }
612 
613  /* do detect */
614  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
615 
616  if (!(PacketAlertCheck(p, 1))) {
617  printf("sid 1 didn't match but should have: ");
618  goto end;
619  }
620 
621  result = 1;
622 
623 end:
624  if (alp_tctx != NULL)
625  AppLayerParserThreadCtxFree(alp_tctx);
626  if (de_ctx != NULL)
627  SigGroupCleanup(de_ctx);
628  if (de_ctx != NULL)
629  SigCleanSignatures(de_ctx);
630  if (de_ctx != NULL)
631  DetectEngineCtxFree(de_ctx);
632 
634  FLOW_DESTROY(&f);
635  UTHFreePackets(&p, 1);
636  return result;
637 }
638 
639 /**
640  * \test Test that the http_user_agent content matches against a http request
641  * which holds the content.
642  */
643 static int DetectEngineHttpUATest07(void)
644 {
645  TcpSession ssn;
646  Packet *p = NULL;
647  ThreadVars th_v;
648  DetectEngineCtx *de_ctx = NULL;
649  DetectEngineThreadCtx *det_ctx = NULL;
650  HtpState *http_state = NULL;
651  Flow f;
652  uint8_t http_buf[] =
653  "CONNECT /index.html HTTP/1.0\r\n"
654  "User-Agent: CONNECT\r\n"
655  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
656  uint32_t http_len = sizeof(http_buf) - 1;
657  int result = 0;
659 
660  memset(&th_v, 0, sizeof(th_v));
661  memset(&f, 0, sizeof(f));
662  memset(&ssn, 0, sizeof(ssn));
663 
664  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
665 
666  FLOW_INITIALIZE(&f);
667  f.protoctx = (void *)&ssn;
668  f.proto = IPPROTO_TCP;
669  f.flags |= FLOW_IPV4;
670  p->flow = &f;
674  f.alproto = ALPROTO_HTTP;
675 
677 
678  de_ctx = DetectEngineCtxInit();
679  if (de_ctx == NULL)
680  goto end;
681 
682  de_ctx->flags |= DE_QUIET;
683 
684  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
685  "(msg:\"http user agent test\"; "
686  "content:!\"CO\"; offset:3; http_user_agent; "
687  "sid:1;)");
688  if (de_ctx->sig_list == NULL)
689  goto end;
690 
691  SigGroupBuild(de_ctx);
692  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
693 
694  FLOWLOCK_WRLOCK(&f);
695  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
696  STREAM_TOSERVER, http_buf, http_len);
697  if (r != 0) {
698  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
699  result = 0;
700  FLOWLOCK_UNLOCK(&f);
701  goto end;
702  }
703  FLOWLOCK_UNLOCK(&f);
704 
705  http_state = f.alstate;
706  if (http_state == NULL) {
707  printf("no http state: ");
708  result = 0;
709  goto end;
710  }
711 
712  /* do detect */
713  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
714 
715  if (!(PacketAlertCheck(p, 1))) {
716  printf("sid 1 didn't match but should have: ");
717  goto end;
718  }
719 
720  result = 1;
721 
722 end:
723  if (alp_tctx != NULL)
724  AppLayerParserThreadCtxFree(alp_tctx);
725  if (de_ctx != NULL)
726  SigGroupCleanup(de_ctx);
727  if (de_ctx != NULL)
728  SigCleanSignatures(de_ctx);
729  if (de_ctx != NULL)
730  DetectEngineCtxFree(de_ctx);
731 
733  FLOW_DESTROY(&f);
734  UTHFreePackets(&p, 1);
735  return result;
736 }
737 
738 /**
739  * \test Test that the http_user_agent content matches against a http request
740  * which holds the content.
741  */
742 static int DetectEngineHttpUATest08(void)
743 {
744  TcpSession ssn;
745  Packet *p = NULL;
746  ThreadVars th_v;
747  DetectEngineCtx *de_ctx = NULL;
748  DetectEngineThreadCtx *det_ctx = NULL;
749  HtpState *http_state = NULL;
750  Flow f;
751  uint8_t http_buf[] =
752  "CONNECT /index.html HTTP/1.0\r\n"
753  "User-Agent: CONNECT\r\n"
754  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
755  uint32_t http_len = sizeof(http_buf) - 1;
756  int result = 0;
758 
759  memset(&th_v, 0, sizeof(th_v));
760  memset(&f, 0, sizeof(f));
761  memset(&ssn, 0, sizeof(ssn));
762 
763  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
764 
765  FLOW_INITIALIZE(&f);
766  f.protoctx = (void *)&ssn;
767  f.proto = IPPROTO_TCP;
768  f.flags |= FLOW_IPV4;
769  p->flow = &f;
773  f.alproto = ALPROTO_HTTP;
774 
776 
777  de_ctx = DetectEngineCtxInit();
778  if (de_ctx == NULL)
779  goto end;
780 
781  de_ctx->flags |= DE_QUIET;
782 
783  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
784  "(msg:\"http user agent test\"; "
785  "content:!\"ECT\"; offset:3; http_user_agent; "
786  "sid:1;)");
787  if (de_ctx->sig_list == NULL)
788  goto end;
789 
790  SigGroupBuild(de_ctx);
791  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
792 
793  FLOWLOCK_WRLOCK(&f);
794  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
795  STREAM_TOSERVER, http_buf, http_len);
796  if (r != 0) {
797  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
798  result = 0;
799  FLOWLOCK_UNLOCK(&f);
800  goto end;
801  }
802  FLOWLOCK_UNLOCK(&f);
803 
804  http_state = f.alstate;
805  if (http_state == NULL) {
806  printf("no http state: ");
807  result = 0;
808  goto end;
809  }
810 
811  /* do detect */
812  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
813 
814  if (PacketAlertCheck(p, 1)) {
815  printf("sid 1 matched but shouldn't have: ");
816  goto end;
817  }
818 
819  result = 1;
820 
821 end:
822  if (alp_tctx != NULL)
823  AppLayerParserThreadCtxFree(alp_tctx);
824  if (de_ctx != NULL)
825  SigGroupCleanup(de_ctx);
826  if (de_ctx != NULL)
827  SigCleanSignatures(de_ctx);
828  if (de_ctx != NULL)
829  DetectEngineCtxFree(de_ctx);
830 
832  FLOW_DESTROY(&f);
833  UTHFreePackets(&p, 1);
834  return result;
835 }
836 
837 /**
838  * \test Test that the http_user_agent content matches against a http request
839  * which holds the content.
840  */
841 static int DetectEngineHttpUATest09(void)
842 {
843  TcpSession ssn;
844  Packet *p = NULL;
845  ThreadVars th_v;
846  DetectEngineCtx *de_ctx = NULL;
847  DetectEngineThreadCtx *det_ctx = NULL;
848  HtpState *http_state = NULL;
849  Flow f;
850  uint8_t http_buf[] =
851  "CONNECT /index.html HTTP/1.0\r\n"
852  "User-Agent: CONNECT\r\n"
853  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
854  uint32_t http_len = sizeof(http_buf) - 1;
855  int result = 0;
857 
858  memset(&th_v, 0, sizeof(th_v));
859  memset(&f, 0, sizeof(f));
860  memset(&ssn, 0, sizeof(ssn));
861 
862  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
863 
864  FLOW_INITIALIZE(&f);
865  f.protoctx = (void *)&ssn;
866  f.proto = IPPROTO_TCP;
867  f.flags |= FLOW_IPV4;
868  p->flow = &f;
872  f.alproto = ALPROTO_HTTP;
873 
875 
876  de_ctx = DetectEngineCtxInit();
877  if (de_ctx == NULL)
878  goto end;
879 
880  de_ctx->flags |= DE_QUIET;
881 
882  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
883  "(msg:\"http user agent test\"; "
884  "content:\"CON\"; offset:3; http_user_agent; "
885  "sid:1;)");
886  if (de_ctx->sig_list == NULL)
887  goto end;
888 
889  SigGroupBuild(de_ctx);
890  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
891 
892  FLOWLOCK_WRLOCK(&f);
893  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
894  STREAM_TOSERVER, http_buf, http_len);
895  if (r != 0) {
896  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
897  result = 0;
898  FLOWLOCK_UNLOCK(&f);
899  goto end;
900  }
901  FLOWLOCK_UNLOCK(&f);
902 
903  http_state = f.alstate;
904  if (http_state == NULL) {
905  printf("no http state: ");
906  result = 0;
907  goto end;
908  }
909 
910  /* do detect */
911  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
912 
913  if (PacketAlertCheck(p, 1)) {
914  printf("sid 1 matched but shouldn't have: ");
915  goto end;
916  }
917 
918  result = 1;
919 
920 end:
921  if (alp_tctx != NULL)
922  AppLayerParserThreadCtxFree(alp_tctx);
923  if (de_ctx != NULL)
924  SigGroupCleanup(de_ctx);
925  if (de_ctx != NULL)
926  SigCleanSignatures(de_ctx);
927  if (de_ctx != NULL)
928  DetectEngineCtxFree(de_ctx);
929 
931  FLOW_DESTROY(&f);
932  UTHFreePackets(&p, 1);
933  return result;
934 }
935 
936 /**
937  * \test Test that the http_user_agent content matches against a http request
938  * which holds the content.
939  */
940 static int DetectEngineHttpUATest10(void)
941 {
942  TcpSession ssn;
943  Packet *p = NULL;
944  ThreadVars th_v;
945  DetectEngineCtx *de_ctx = NULL;
946  DetectEngineThreadCtx *det_ctx = NULL;
947  HtpState *http_state = NULL;
948  Flow f;
949  uint8_t http_buf[] =
950  "CONNECT /index.html HTTP/1.0\r\n"
951  "User-Agent: CONNECT\r\n"
952  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
953  uint32_t http_len = sizeof(http_buf) - 1;
954  int result = 0;
956 
957  memset(&th_v, 0, sizeof(th_v));
958  memset(&f, 0, sizeof(f));
959  memset(&ssn, 0, sizeof(ssn));
960 
961  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
962 
963  FLOW_INITIALIZE(&f);
964  f.protoctx = (void *)&ssn;
965  f.proto = IPPROTO_TCP;
966  f.flags |= FLOW_IPV4;
967  p->flow = &f;
971  f.alproto = ALPROTO_HTTP;
972 
974 
975  de_ctx = DetectEngineCtxInit();
976  if (de_ctx == NULL)
977  goto end;
978 
979  de_ctx->flags |= DE_QUIET;
980 
981  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
982  "(msg:\"http_user_agent test\"; "
983  "content:\"CO\"; http_user_agent; "
984  "content:\"EC\"; within:4; http_user_agent; "
985  "sid:1;)");
986  if (de_ctx->sig_list == NULL)
987  goto end;
988 
989  SigGroupBuild(de_ctx);
990  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
991 
992  FLOWLOCK_WRLOCK(&f);
993  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
994  STREAM_TOSERVER, http_buf, http_len);
995  if (r != 0) {
996  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
997  result = 0;
998  FLOWLOCK_UNLOCK(&f);
999  goto end;
1000  }
1001  FLOWLOCK_UNLOCK(&f);
1002 
1003  http_state = f.alstate;
1004  if (http_state == NULL) {
1005  printf("no http state: ");
1006  result = 0;
1007  goto end;
1008  }
1009 
1010  /* do detect */
1011  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1012 
1013  if (!PacketAlertCheck(p, 1)) {
1014  printf("sid 1 didn't match but should have: ");
1015  goto end;
1016  }
1017 
1018  result = 1;
1019 
1020 end:
1021  if (alp_tctx != NULL)
1022  AppLayerParserThreadCtxFree(alp_tctx);
1023  if (de_ctx != NULL)
1024  SigGroupCleanup(de_ctx);
1025  if (de_ctx != NULL)
1026  SigCleanSignatures(de_ctx);
1027  if (de_ctx != NULL)
1028  DetectEngineCtxFree(de_ctx);
1029 
1031  FLOW_DESTROY(&f);
1032  UTHFreePackets(&p, 1);
1033  return result;
1034 }
1035 
1036 /**
1037  * \test Test that the http_user_agent content matches against a http request
1038  * which holds the content.
1039  */
1040 static int DetectEngineHttpUATest11(void)
1041 {
1042  TcpSession ssn;
1043  Packet *p = NULL;
1044  ThreadVars th_v;
1045  DetectEngineCtx *de_ctx = NULL;
1046  DetectEngineThreadCtx *det_ctx = NULL;
1047  HtpState *http_state = NULL;
1048  Flow f;
1049  uint8_t http_buf[] =
1050  "CONNECT /index.html HTTP/1.0\r\n"
1051  "User-Agent: CONNECT\r\n"
1052  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1053  uint32_t http_len = sizeof(http_buf) - 1;
1054  int result = 0;
1056 
1057  memset(&th_v, 0, sizeof(th_v));
1058  memset(&f, 0, sizeof(f));
1059  memset(&ssn, 0, sizeof(ssn));
1060 
1061  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1062 
1063  FLOW_INITIALIZE(&f);
1064  f.protoctx = (void *)&ssn;
1065  f.proto = IPPROTO_TCP;
1066  f.flags |= FLOW_IPV4;
1067  p->flow = &f;
1071  f.alproto = ALPROTO_HTTP;
1072 
1074 
1075  de_ctx = DetectEngineCtxInit();
1076  if (de_ctx == NULL)
1077  goto end;
1078 
1079  de_ctx->flags |= DE_QUIET;
1080 
1081  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1082  "(msg:\"http user agent test\"; "
1083  "content:\"CO\"; http_user_agent; "
1084  "content:!\"EC\"; within:3; http_user_agent; "
1085  "sid:1;)");
1086  if (de_ctx->sig_list == NULL)
1087  goto end;
1088 
1089  SigGroupBuild(de_ctx);
1090  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1091 
1092  FLOWLOCK_WRLOCK(&f);
1093  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1094  STREAM_TOSERVER, http_buf, http_len);
1095  if (r != 0) {
1096  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1097  result = 0;
1098  FLOWLOCK_UNLOCK(&f);
1099  goto end;
1100  }
1101  FLOWLOCK_UNLOCK(&f);
1102 
1103  http_state = f.alstate;
1104  if (http_state == NULL) {
1105  printf("no http state: ");
1106  result = 0;
1107  goto end;
1108  }
1109 
1110  /* do detect */
1111  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1112 
1113  if (!PacketAlertCheck(p, 1)) {
1114  printf("sid 1 didn't match but should have: ");
1115  goto end;
1116  }
1117 
1118  result = 1;
1119 
1120 end:
1121  if (alp_tctx != NULL)
1122  AppLayerParserThreadCtxFree(alp_tctx);
1123  if (de_ctx != NULL)
1124  SigGroupCleanup(de_ctx);
1125  if (de_ctx != NULL)
1126  SigCleanSignatures(de_ctx);
1127  if (de_ctx != NULL)
1128  DetectEngineCtxFree(de_ctx);
1129 
1131  FLOW_DESTROY(&f);
1132  UTHFreePackets(&p, 1);
1133  return result;
1134 }
1135 
1136 /**
1137  * \test Test that the http_user_agent content matches against a http request
1138  * which holds the content.
1139  */
1140 static int DetectEngineHttpUATest12(void)
1141 {
1142  TcpSession ssn;
1143  Packet *p = NULL;
1144  ThreadVars th_v;
1145  DetectEngineCtx *de_ctx = NULL;
1146  DetectEngineThreadCtx *det_ctx = NULL;
1147  HtpState *http_state = NULL;
1148  Flow f;
1149  uint8_t http_buf[] =
1150  "CONNECT /index.html HTTP/1.0\r\n"
1151  "User-Agent: CONNECT\r\n"
1152  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1153  uint32_t http_len = sizeof(http_buf) - 1;
1154  int result = 0;
1156 
1157  memset(&th_v, 0, sizeof(th_v));
1158  memset(&f, 0, sizeof(f));
1159  memset(&ssn, 0, sizeof(ssn));
1160 
1161  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1162 
1163  FLOW_INITIALIZE(&f);
1164  f.protoctx = (void *)&ssn;
1165  f.proto = IPPROTO_TCP;
1166  f.flags |= FLOW_IPV4;
1167  p->flow = &f;
1171  f.alproto = ALPROTO_HTTP;
1172 
1174 
1175  de_ctx = DetectEngineCtxInit();
1176  if (de_ctx == NULL)
1177  goto end;
1178 
1179  de_ctx->flags |= DE_QUIET;
1180 
1181  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1182  "(msg:\"http_user_agent test\"; "
1183  "content:\"CO\"; http_user_agent; "
1184  "content:\"EC\"; within:3; http_user_agent; "
1185  "sid:1;)");
1186  if (de_ctx->sig_list == NULL)
1187  goto end;
1188 
1189  SigGroupBuild(de_ctx);
1190  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1191 
1192  FLOWLOCK_WRLOCK(&f);
1193  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1194  STREAM_TOSERVER, http_buf, http_len);
1195  if (r != 0) {
1196  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1197  result = 0;
1198  FLOWLOCK_UNLOCK(&f);
1199  goto end;
1200  }
1201  FLOWLOCK_UNLOCK(&f);
1202 
1203  http_state = f.alstate;
1204  if (http_state == NULL) {
1205  printf("no http state: ");
1206  result = 0;
1207  goto end;
1208  }
1209 
1210  /* do detect */
1211  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1212 
1213  if (PacketAlertCheck(p, 1)) {
1214  printf("sid 1 matched but shouldn't have: ");
1215  goto end;
1216  }
1217 
1218  result = 1;
1219 
1220 end:
1221  if (alp_tctx != NULL)
1222  AppLayerParserThreadCtxFree(alp_tctx);
1223  if (de_ctx != NULL)
1224  SigGroupCleanup(de_ctx);
1225  if (de_ctx != NULL)
1226  SigCleanSignatures(de_ctx);
1227  if (de_ctx != NULL)
1228  DetectEngineCtxFree(de_ctx);
1229 
1231  FLOW_DESTROY(&f);
1232  UTHFreePackets(&p, 1);
1233  return result;
1234 }
1235 
1236 /**
1237  * \test Test that the http_user_agent content matches against a http request
1238  * which holds the content.
1239  */
1240 static int DetectEngineHttpUATest13(void)
1241 {
1242  TcpSession ssn;
1243  Packet *p = NULL;
1244  ThreadVars th_v;
1245  DetectEngineCtx *de_ctx = NULL;
1246  DetectEngineThreadCtx *det_ctx = NULL;
1247  HtpState *http_state = NULL;
1248  Flow f;
1249  uint8_t http_buf[] =
1250  "CONNECT /index.html HTTP/1.0\r\n"
1251  "User-Agent: CONNECT\r\n"
1252  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1253  uint32_t http_len = sizeof(http_buf) - 1;
1254  int result = 0;
1256 
1257  memset(&th_v, 0, sizeof(th_v));
1258  memset(&f, 0, sizeof(f));
1259  memset(&ssn, 0, sizeof(ssn));
1260 
1261  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1262 
1263  FLOW_INITIALIZE(&f);
1264  f.protoctx = (void *)&ssn;
1265  f.proto = IPPROTO_TCP;
1266  f.flags |= FLOW_IPV4;
1267  p->flow = &f;
1271  f.alproto = ALPROTO_HTTP;
1272 
1274 
1275  de_ctx = DetectEngineCtxInit();
1276  if (de_ctx == NULL)
1277  goto end;
1278 
1279  de_ctx->flags |= DE_QUIET;
1280 
1281  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1282  "(msg:\"http user agent test\"; "
1283  "content:\"CO\"; http_user_agent; "
1284  "content:!\"EC\"; within:4; http_user_agent; "
1285  "sid:1;)");
1286  if (de_ctx->sig_list == NULL)
1287  goto end;
1288 
1289  SigGroupBuild(de_ctx);
1290  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1291 
1292  FLOWLOCK_WRLOCK(&f);
1293  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1294  STREAM_TOSERVER, http_buf, http_len);
1295  if (r != 0) {
1296  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1297  result = 0;
1298  FLOWLOCK_UNLOCK(&f);
1299  goto end;
1300  }
1301  FLOWLOCK_UNLOCK(&f);
1302 
1303  http_state = f.alstate;
1304  if (http_state == NULL) {
1305  printf("no http state: ");
1306  result = 0;
1307  goto end;
1308  }
1309 
1310  /* do detect */
1311  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1312 
1313  if (PacketAlertCheck(p, 1)) {
1314  printf("sid 1 matched but shouldn't have: ");
1315  goto end;
1316  }
1317 
1318  result = 1;
1319 
1320 end:
1321  if (alp_tctx != NULL)
1322  AppLayerParserThreadCtxFree(alp_tctx);
1323  if (de_ctx != NULL)
1324  SigGroupCleanup(de_ctx);
1325  if (de_ctx != NULL)
1326  SigCleanSignatures(de_ctx);
1327  if (de_ctx != NULL)
1328  DetectEngineCtxFree(de_ctx);
1329 
1331  FLOW_DESTROY(&f);
1332  UTHFreePackets(&p, 1);
1333  return result;
1334 }
1335 
1336 /**
1337  * \test Test that the http_user_agent content matches against a http request
1338  * which holds the content.
1339  */
1340 static int DetectEngineHttpUATest14(void)
1341 {
1342  TcpSession ssn;
1343  Packet *p = NULL;
1344  ThreadVars th_v;
1345  DetectEngineCtx *de_ctx = NULL;
1346  DetectEngineThreadCtx *det_ctx = NULL;
1347  HtpState *http_state = NULL;
1348  Flow f;
1349  uint8_t http_buf[] =
1350  "CONNECT /index.html HTTP/1.0\r\n"
1351  "User-Agent: CONNECT\r\n"
1352  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1353  uint32_t http_len = sizeof(http_buf) - 1;
1354  int result = 0;
1356 
1357  memset(&th_v, 0, sizeof(th_v));
1358  memset(&f, 0, sizeof(f));
1359  memset(&ssn, 0, sizeof(ssn));
1360 
1361  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1362 
1363  FLOW_INITIALIZE(&f);
1364  f.protoctx = (void *)&ssn;
1365  f.proto = IPPROTO_TCP;
1366  f.flags |= FLOW_IPV4;
1367  p->flow = &f;
1371  f.alproto = ALPROTO_HTTP;
1372 
1374 
1375  de_ctx = DetectEngineCtxInit();
1376  if (de_ctx == NULL)
1377  goto end;
1378 
1379  de_ctx->flags |= DE_QUIET;
1380 
1381  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1382  "(msg:\"http_user_agent test\"; "
1383  "content:\"CO\"; http_user_agent; "
1384  "content:\"EC\"; distance:2; http_user_agent; "
1385  "sid:1;)");
1386  if (de_ctx->sig_list == NULL)
1387  goto end;
1388 
1389  SigGroupBuild(de_ctx);
1390  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1391 
1392  FLOWLOCK_WRLOCK(&f);
1393  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1394  STREAM_TOSERVER, http_buf, http_len);
1395  if (r != 0) {
1396  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1397  result = 0;
1398  FLOWLOCK_UNLOCK(&f);
1399  goto end;
1400  }
1401  FLOWLOCK_UNLOCK(&f);
1402 
1403  http_state = f.alstate;
1404  if (http_state == NULL) {
1405  printf("no http state: ");
1406  result = 0;
1407  goto end;
1408  }
1409 
1410  /* do detect */
1411  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1412 
1413  if (!PacketAlertCheck(p, 1)) {
1414  printf("sid 1 didn't match but should have: ");
1415  goto end;
1416  }
1417 
1418  result = 1;
1419 
1420 end:
1421  if (alp_tctx != NULL)
1422  AppLayerParserThreadCtxFree(alp_tctx);
1423  if (de_ctx != NULL)
1424  SigGroupCleanup(de_ctx);
1425  if (de_ctx != NULL)
1426  SigCleanSignatures(de_ctx);
1427  if (de_ctx != NULL)
1428  DetectEngineCtxFree(de_ctx);
1429 
1431  FLOW_DESTROY(&f);
1432  UTHFreePackets(&p, 1);
1433  return result;
1434 }
1435 
1436 /**
1437  * \test Test that the http_user_agent content matches against a http request
1438  * which holds the content.
1439  */
1440 static int DetectEngineHttpUATest15(void)
1441 {
1442  TcpSession ssn;
1443  Packet *p = NULL;
1444  ThreadVars th_v;
1445  DetectEngineCtx *de_ctx = NULL;
1446  DetectEngineThreadCtx *det_ctx = NULL;
1447  HtpState *http_state = NULL;
1448  Flow f;
1449  uint8_t http_buf[] =
1450  "CONNECT /index.html HTTP/1.0\r\n"
1451  "User-Agent: CONNECT\r\n"
1452  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1453  uint32_t http_len = sizeof(http_buf) - 1;
1454  int result = 0;
1456 
1457  memset(&th_v, 0, sizeof(th_v));
1458  memset(&f, 0, sizeof(f));
1459  memset(&ssn, 0, sizeof(ssn));
1460 
1461  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1462 
1463  FLOW_INITIALIZE(&f);
1464  f.protoctx = (void *)&ssn;
1465  f.proto = IPPROTO_TCP;
1466  f.flags |= FLOW_IPV4;
1467  p->flow = &f;
1471  f.alproto = ALPROTO_HTTP;
1472 
1474 
1475  de_ctx = DetectEngineCtxInit();
1476  if (de_ctx == NULL)
1477  goto end;
1478 
1479  de_ctx->flags |= DE_QUIET;
1480 
1481  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1482  "(msg:\"http user agent test\"; "
1483  "content:\"CO\"; http_user_agent; "
1484  "content:!\"EC\"; distance:3; http_user_agent; "
1485  "sid:1;)");
1486  if (de_ctx->sig_list == NULL)
1487  goto end;
1488 
1489  SigGroupBuild(de_ctx);
1490  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1491 
1492  FLOWLOCK_WRLOCK(&f);
1493  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1494  STREAM_TOSERVER, http_buf, http_len);
1495  if (r != 0) {
1496  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1497  result = 0;
1498  FLOWLOCK_UNLOCK(&f);
1499  goto end;
1500  }
1501  FLOWLOCK_UNLOCK(&f);
1502 
1503  http_state = f.alstate;
1504  if (http_state == NULL) {
1505  printf("no http state: ");
1506  result = 0;
1507  goto end;
1508  }
1509 
1510  /* do detect */
1511  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1512 
1513  if (!PacketAlertCheck(p, 1)) {
1514  printf("sid 1 didn't match but should have: ");
1515  goto end;
1516  }
1517 
1518  result = 1;
1519 
1520 end:
1521  if (alp_tctx != NULL)
1522  AppLayerParserThreadCtxFree(alp_tctx);
1523  if (de_ctx != NULL)
1524  SigGroupCleanup(de_ctx);
1525  if (de_ctx != NULL)
1526  SigCleanSignatures(de_ctx);
1527  if (de_ctx != NULL)
1528  DetectEngineCtxFree(de_ctx);
1529 
1531  FLOW_DESTROY(&f);
1532  UTHFreePackets(&p, 1);
1533  return result;
1534 }
1535 
1536 /**
1537  * \test Test that the http_user_agent content matches against a http request
1538  * which holds the content.
1539  */
1540 static int DetectEngineHttpUATest16(void)
1541 {
1542  TcpSession ssn;
1543  Packet *p = NULL;
1544  ThreadVars th_v;
1545  DetectEngineCtx *de_ctx = NULL;
1546  DetectEngineThreadCtx *det_ctx = NULL;
1547  HtpState *http_state = NULL;
1548  Flow f;
1549  uint8_t http_buf[] =
1550  "CONNECT /index.html HTTP/1.0\r\n"
1551  "User-Agent: CONNECT\r\n"
1552  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1553  uint32_t http_len = sizeof(http_buf) - 1;
1554  int result = 0;
1556 
1557  memset(&th_v, 0, sizeof(th_v));
1558  memset(&f, 0, sizeof(f));
1559  memset(&ssn, 0, sizeof(ssn));
1560 
1561  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1562 
1563  FLOW_INITIALIZE(&f);
1564  f.protoctx = (void *)&ssn;
1565  f.proto = IPPROTO_TCP;
1566  f.flags |= FLOW_IPV4;
1567  p->flow = &f;
1571  f.alproto = ALPROTO_HTTP;
1572 
1574 
1575  de_ctx = DetectEngineCtxInit();
1576  if (de_ctx == NULL)
1577  goto end;
1578 
1579  de_ctx->flags |= DE_QUIET;
1580 
1581  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1582  "(msg:\"http user agent test\"; "
1583  "content:\"CO\"; http_user_agent; "
1584  "content:\"EC\"; distance:3; http_user_agent; "
1585  "sid:1;)");
1586  if (de_ctx->sig_list == NULL)
1587  goto end;
1588 
1589  SigGroupBuild(de_ctx);
1590  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1591 
1592  FLOWLOCK_WRLOCK(&f);
1593  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1594  STREAM_TOSERVER, http_buf, http_len);
1595  if (r != 0) {
1596  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1597  result = 0;
1598  FLOWLOCK_UNLOCK(&f);
1599  goto end;
1600  }
1601  FLOWLOCK_UNLOCK(&f);
1602 
1603  http_state = f.alstate;
1604  if (http_state == NULL) {
1605  printf("no http state: ");
1606  result = 0;
1607  goto end;
1608  }
1609 
1610  /* do detect */
1611  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1612 
1613  if (PacketAlertCheck(p, 1)) {
1614  printf("sid 1 matched but shouldn't have: ");
1615  goto end;
1616  }
1617 
1618  result = 1;
1619 
1620 end:
1621  if (alp_tctx != NULL)
1622  AppLayerParserThreadCtxFree(alp_tctx);
1623  if (de_ctx != NULL)
1624  SigGroupCleanup(de_ctx);
1625  if (de_ctx != NULL)
1626  SigCleanSignatures(de_ctx);
1627  if (de_ctx != NULL)
1628  DetectEngineCtxFree(de_ctx);
1629 
1631  FLOW_DESTROY(&f);
1632  UTHFreePackets(&p, 1);
1633  return result;
1634 }
1635 
1636 /**
1637  * \test Test that the http_user_agent content matches against a http request
1638  * which holds the content.
1639  */
1640 static int DetectEngineHttpUATest17(void)
1641 {
1642  TcpSession ssn;
1643  Packet *p = NULL;
1644  ThreadVars th_v;
1645  DetectEngineCtx *de_ctx = NULL;
1646  DetectEngineThreadCtx *det_ctx = NULL;
1647  HtpState *http_state = NULL;
1648  Flow f;
1649  uint8_t http_buf[] =
1650  "CONNECT /index.html HTTP/1.0\r\n"
1651  "User-Agent: CONNECT\r\n"
1652  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1653  uint32_t http_len = sizeof(http_buf) - 1;
1654  int result = 0;
1656 
1657  memset(&th_v, 0, sizeof(th_v));
1658  memset(&f, 0, sizeof(f));
1659  memset(&ssn, 0, sizeof(ssn));
1660 
1661  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1662 
1663  FLOW_INITIALIZE(&f);
1664  f.protoctx = (void *)&ssn;
1665  f.proto = IPPROTO_TCP;
1666  f.flags |= FLOW_IPV4;
1667  p->flow = &f;
1671  f.alproto = ALPROTO_HTTP;
1672 
1674 
1675  de_ctx = DetectEngineCtxInit();
1676  if (de_ctx == NULL)
1677  goto end;
1678 
1679  de_ctx->flags |= DE_QUIET;
1680 
1681  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1682  "(msg:\"http_user_agent test\"; "
1683  "content:\"CO\"; http_user_agent; "
1684  "content:!\"EC\"; distance:2; http_user_agent; "
1685  "sid:1;)");
1686  if (de_ctx->sig_list == NULL)
1687  goto end;
1688 
1689  SigGroupBuild(de_ctx);
1690  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1691 
1692  FLOWLOCK_WRLOCK(&f);
1693  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1694  STREAM_TOSERVER, http_buf, http_len);
1695  if (r != 0) {
1696  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1697  result = 0;
1698  FLOWLOCK_UNLOCK(&f);
1699  goto end;
1700  }
1701  FLOWLOCK_UNLOCK(&f);
1702 
1703  http_state = f.alstate;
1704  if (http_state == NULL) {
1705  printf("no http state: ");
1706  result = 0;
1707  goto end;
1708  }
1709 
1710  /* do detect */
1711  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1712 
1713  if (PacketAlertCheck(p, 1)) {
1714  printf("sid 1 matched but shouldn't have: ");
1715  goto end;
1716  }
1717 
1718  result = 1;
1719 
1720 end:
1721  if (alp_tctx != NULL)
1722  AppLayerParserThreadCtxFree(alp_tctx);
1723  if (de_ctx != NULL)
1724  SigGroupCleanup(de_ctx);
1725  if (de_ctx != NULL)
1726  SigCleanSignatures(de_ctx);
1727  if (de_ctx != NULL)
1728  DetectEngineCtxFree(de_ctx);
1729 
1731  FLOW_DESTROY(&f);
1732  UTHFreePackets(&p, 1);
1733  return result;
1734 }
1735 
1736 /**
1737  * \test Test that a signature containting a http_user_agent is correctly parsed
1738  * and the keyword is registered.
1739  */
1740 static int DetectHttpUATest01(void)
1741 {
1742  DetectEngineCtx *de_ctx = NULL;
1743  int result = 0;
1744 
1745  de_ctx = DetectEngineCtxInit();
1746  if (de_ctx == NULL)
1747  goto end;
1748 
1749  de_ctx->flags |= DE_QUIET;
1750  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1751  "(msg:\"Testing http_user_agent\"; "
1752  "content:\"one\"; http_user_agent; sid:1;)");
1753  if (de_ctx->sig_list != NULL) {
1754  result = 1;
1755  } else {
1756  goto end;
1757  }
1758 
1759  end:
1760  DetectEngineCtxFree(de_ctx);
1761 
1762  return result;
1763 }
1764 
1765 /**
1766  * \test Test that a signature containing an valid http_user_agent entry is
1767  * parsed.
1768  */
1769 static int DetectHttpUATest02(void)
1770 {
1771  DetectEngineCtx *de_ctx = NULL;
1772  int result = 0;
1773 
1774  de_ctx = DetectEngineCtxInit();
1775  if (de_ctx == NULL)
1776  goto end;
1777 
1778  de_ctx->flags |= DE_QUIET;
1779  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1780  "(msg:\"Testing http_user_agent\"; "
1781  "content:\"one\"; http_user_agent:; sid:1;)");
1782  if (de_ctx->sig_list != NULL)
1783  result = 1;
1784 
1785  end:
1786  DetectEngineCtxFree(de_ctx);
1787 
1788  return result;
1789 }
1790 
1791 /**
1792  * \test Test that an invalid signature containing no content but a
1793  * http_user_agent is invalidated.
1794  */
1795 static int DetectHttpUATest03(void)
1796 {
1797  DetectEngineCtx *de_ctx = NULL;
1798  int result = 0;
1799 
1800  de_ctx = DetectEngineCtxInit();
1801  if (de_ctx == NULL)
1802  goto end;
1803 
1804  de_ctx->flags |= DE_QUIET;
1805  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1806  "(msg:\"Testing http_user_agent\"; "
1807  "http_user_agent; sid:1;)");
1808  if (de_ctx->sig_list == NULL)
1809  result = 1;
1810 
1811  end:
1812  DetectEngineCtxFree(de_ctx);
1813 
1814  return result;
1815 }
1816 
1817 /**
1818  * \test Test that an invalid signature containing a rawbytes along with a
1819  * http_user_agent is invalidated.
1820  */
1821 static int DetectHttpUATest04(void)
1822 {
1823  DetectEngineCtx *de_ctx = NULL;
1824  int result = 0;
1825 
1826  de_ctx = DetectEngineCtxInit();
1827  if (de_ctx == NULL)
1828  goto end;
1829 
1830  de_ctx->flags |= DE_QUIET;
1831  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1832  "(msg:\"Testing http_user_agent\"; "
1833  "content:\"one\"; rawbytes; http_user_agent; sid:1;)");
1834  if (de_ctx->sig_list == NULL)
1835  result = 1;
1836 
1837  end:
1838  DetectEngineCtxFree(de_ctx);
1839 
1840  return result;
1841 }
1842 
1843 /**
1844  * \test Test that a http_user_agent with nocase is parsed.
1845  */
1846 static int DetectHttpUATest05(void)
1847 {
1848  DetectEngineCtx *de_ctx = NULL;
1849  int result = 0;
1850 
1851  de_ctx = DetectEngineCtxInit();
1852  if (de_ctx == NULL)
1853  goto end;
1854 
1855  de_ctx->flags |= DE_QUIET;
1856  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1857  "(msg:\"Testing http_user_agent\"; "
1858  "content:\"one\"; http_user_agent; nocase; sid:1;)");
1859  if (de_ctx->sig_list != NULL)
1860  result = 1;
1861 
1862  end:
1863  DetectEngineCtxFree(de_ctx);
1864 
1865  return result;
1866 }
1867 
1868 /**
1869  *\test Test that the http_user_agent content matches against a http request
1870  * which holds the content.
1871  */
1872 static int DetectHttpUATest06(void)
1873 {
1874  TcpSession ssn;
1875  Packet *p = NULL;
1876  ThreadVars th_v;
1877  DetectEngineCtx *de_ctx = NULL;
1878  DetectEngineThreadCtx *det_ctx = NULL;
1879  HtpState *http_state = NULL;
1880  Flow f;
1881  uint8_t http_buf[] =
1882  "GET /index.html HTTP/1.0\r\n"
1883  "Host: www.openinfosecfoundation.org\r\n"
1884  "User-Agent: This is dummy message body\r\n"
1885  "Content-Type: text/html\r\n"
1886  "\r\n";
1887  uint32_t http_len = sizeof(http_buf) - 1;
1888  int result = 0;
1890 
1891  memset(&th_v, 0, sizeof(th_v));
1892  memset(&f, 0, sizeof(f));
1893  memset(&ssn, 0, sizeof(ssn));
1894 
1895  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1896 
1897  FLOW_INITIALIZE(&f);
1898  f.protoctx = (void *)&ssn;
1899  f.proto = IPPROTO_TCP;
1900  f.flags |= FLOW_IPV4;
1901 
1902  p->flow = &f;
1906  f.alproto = ALPROTO_HTTP;
1907 
1909 
1910  de_ctx = DetectEngineCtxInit();
1911  if (de_ctx == NULL)
1912  goto end;
1913 
1914  de_ctx->flags |= DE_QUIET;
1915 
1916  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1917  "(msg:\"http user agent test\"; "
1918  "content:\"message\"; http_user_agent; "
1919  "sid:1;)");
1920  if (de_ctx->sig_list == NULL)
1921  goto end;
1922 
1923  SigGroupBuild(de_ctx);
1924  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1925 
1926  FLOWLOCK_WRLOCK(&f);
1927  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1928  STREAM_TOSERVER, http_buf, http_len);
1929  if (r != 0) {
1930  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1931  result = 0;
1932  FLOWLOCK_UNLOCK(&f);
1933  goto end;
1934  }
1935  FLOWLOCK_UNLOCK(&f);
1936 
1937  http_state = f.alstate;
1938  if (http_state == NULL) {
1939  printf("no http state: \n");
1940  result = 0;
1941  goto end;
1942  }
1943 
1944  /* do detect */
1945  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1946 
1947  if (!(PacketAlertCheck(p, 1))) {
1948  printf("sid 1 didn't match but should have\n");
1949  goto end;
1950  }
1951 
1952  result = 1;
1953 end:
1954  if (alp_tctx != NULL)
1955  AppLayerParserThreadCtxFree(alp_tctx);
1956  if (de_ctx != NULL)
1957  DetectEngineCtxFree(de_ctx);
1958 
1960  FLOW_DESTROY(&f);
1961  UTHFreePackets(&p, 1);
1962  return result;
1963 }
1964 
1965 /**
1966  *\test Test that the http_user_agent content matches against a http request
1967  * which holds the content.
1968  */
1969 static int DetectHttpUATest07(void)
1970 {
1971  TcpSession ssn;
1972  Packet *p1 = NULL;
1973  Packet *p2 = NULL;
1974  ThreadVars th_v;
1975  DetectEngineCtx *de_ctx = NULL;
1976  DetectEngineThreadCtx *det_ctx = NULL;
1977  HtpState *http_state = NULL;
1978  Flow f;
1979  uint8_t http1_buf[] =
1980  "GET /index.html HTTP/1.0\r\n"
1981  "Host: www.openinfosecfoundation.org\r\n"
1982  "User-Agent: This is dummy message";
1983  uint8_t http2_buf[] =
1984  "body1\r\n\r\n";
1985  uint32_t http1_len = sizeof(http1_buf) - 1;
1986  uint32_t http2_len = sizeof(http2_buf) - 1;
1987  int result = 0;
1989 
1990  memset(&th_v, 0, sizeof(th_v));
1991  memset(&f, 0, sizeof(f));
1992  memset(&ssn, 0, sizeof(ssn));
1993 
1994  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1995  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1996 
1997  FLOW_INITIALIZE(&f);
1998  f.protoctx = (void *)&ssn;
1999  f.proto = IPPROTO_TCP;
2000  f.flags |= FLOW_IPV4;
2001 
2002  p1->flow = &f;
2006  p2->flow = &f;
2010  f.alproto = ALPROTO_HTTP;
2011 
2013 
2014  de_ctx = DetectEngineCtxInit();
2015  if (de_ctx == NULL)
2016  goto end;
2017 
2018  de_ctx->flags |= DE_QUIET;
2019 
2020  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2021  "(msg:\"http user agent test\"; "
2022  "content:\"message\"; http_user_agent; "
2023  "sid:1;)");
2024  if (de_ctx->sig_list == NULL)
2025  goto end;
2026 
2027  SigGroupBuild(de_ctx);
2028  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2029 
2030  FLOWLOCK_WRLOCK(&f);
2031  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2032  STREAM_TOSERVER, http1_buf, http1_len);
2033  if (r != 0) {
2034  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2035  result = 0;
2036  FLOWLOCK_UNLOCK(&f);
2037  goto end;
2038  }
2039  FLOWLOCK_UNLOCK(&f);
2040 
2041  http_state = f.alstate;
2042  if (http_state == NULL) {
2043  printf("no http state: ");
2044  goto end;
2045  }
2046 
2047  /* do detect */
2048  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2049 
2050  if (PacketAlertCheck(p1, 1)) {
2051  printf("sid 1 matched on p1 but shouldn't have: ");
2052  goto end;
2053  }
2054 
2055  FLOWLOCK_WRLOCK(&f);
2056  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2057  STREAM_TOSERVER, http2_buf, http2_len);
2058  if (r != 0) {
2059  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2060  FLOWLOCK_UNLOCK(&f);
2061  goto end;
2062  }
2063  FLOWLOCK_UNLOCK(&f);
2064 
2065  /* do detect */
2066  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2067  if (!(PacketAlertCheck(p2, 1))) {
2068  printf("sid 1 didn't match on p2 but should have: ");
2069  goto end;
2070  }
2071 
2072  result = 1;
2073 end:
2074  if (alp_tctx != NULL)
2075  AppLayerParserThreadCtxFree(alp_tctx);
2076  if (de_ctx != NULL)
2077  DetectEngineCtxFree(de_ctx);
2078 
2080  FLOW_DESTROY(&f);
2081  UTHFreePackets(&p1, 1);
2082  UTHFreePackets(&p2, 1);
2083  return result;
2084 }
2085 
2086 /**
2087  *\test Test that the http_user_agent content matches against a http request
2088  * which holds the content.
2089  */
2090 static int DetectHttpUATest08(void)
2091 {
2092  TcpSession ssn;
2093  Packet *p1 = NULL;
2094  Packet *p2 = NULL;
2095  ThreadVars th_v;
2096  DetectEngineCtx *de_ctx = NULL;
2097  DetectEngineThreadCtx *det_ctx = NULL;
2098  HtpState *http_state = NULL;
2099  Flow f;
2100  uint8_t http1_buf[] =
2101  "GET /index.html HTTP/1.0\r\n"
2102  "Host: www.openinfosecfoundation.org\r\n"
2103  "User-Agent: This is dummy mess";
2104  uint8_t http2_buf[] =
2105  "age body\r\n\r\n";
2106  uint32_t http1_len = sizeof(http1_buf) - 1;
2107  uint32_t http2_len = sizeof(http2_buf) - 1;
2108  int result = 0;
2110 
2111  memset(&th_v, 0, sizeof(th_v));
2112  memset(&f, 0, sizeof(f));
2113  memset(&ssn, 0, sizeof(ssn));
2114 
2115  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2116  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2117 
2118  FLOW_INITIALIZE(&f);
2119  f.protoctx = (void *)&ssn;
2120  f.proto = IPPROTO_TCP;
2121  f.flags |= FLOW_IPV4;
2122 
2123  p1->flow = &f;
2127  p2->flow = &f;
2131  f.alproto = ALPROTO_HTTP;
2132 
2134 
2135  de_ctx = DetectEngineCtxInit();
2136  if (de_ctx == NULL)
2137  goto end;
2138 
2139  de_ctx->flags |= DE_QUIET;
2140 
2141  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2142  "(msg:\"http user agent test\"; "
2143  "content:\"message\"; http_user_agent; "
2144  "sid:1;)");
2145  if (de_ctx->sig_list == NULL)
2146  goto end;
2147 
2148  SigGroupBuild(de_ctx);
2149  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2150 
2151  FLOWLOCK_WRLOCK(&f);
2152  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2153  STREAM_TOSERVER, http1_buf, http1_len);
2154  if (r != 0) {
2155  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2156  result = 0;
2157  FLOWLOCK_UNLOCK(&f);
2158  goto end;
2159  }
2160  FLOWLOCK_UNLOCK(&f);
2161 
2162  http_state = f.alstate;
2163  if (http_state == NULL) {
2164  printf("no http state: ");
2165  result = 0;
2166  goto end;
2167  }
2168 
2169  /* do detect */
2170  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2171 
2172  if ((PacketAlertCheck(p1, 1))) {
2173  printf("sid 1 didn't match but should have");
2174  goto end;
2175  }
2176 
2177  FLOWLOCK_WRLOCK(&f);
2178  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2179  STREAM_TOSERVER, http2_buf, http2_len);
2180  if (r != 0) {
2181  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2182  result = 0;
2183  FLOWLOCK_UNLOCK(&f);
2184  goto end;
2185  }
2186  FLOWLOCK_UNLOCK(&f);
2187 
2188  /* do detect */
2189  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2190 
2191  if (!(PacketAlertCheck(p2, 1))) {
2192  printf("sid 1 didn't match but should have");
2193  goto end;
2194  }
2195 
2196  result = 1;
2197 end:
2198  if (alp_tctx != NULL)
2199  AppLayerParserThreadCtxFree(alp_tctx);
2200  if (de_ctx != NULL)
2201  DetectEngineCtxFree(de_ctx);
2202 
2204  FLOW_DESTROY(&f);
2205  UTHFreePackets(&p1, 1);
2206  UTHFreePackets(&p2, 1);
2207  return result;
2208 }
2209 
2210 /**
2211  *\test Test that the http_user_agent content matches against a http request
2212  * which holds the content, against a cross boundary present pattern.
2213  */
2214 static int DetectHttpUATest09(void)
2215 {
2216  TcpSession ssn;
2217  Packet *p1 = NULL;
2218  Packet *p2 = NULL;
2219  ThreadVars th_v;
2220  DetectEngineCtx *de_ctx = NULL;
2221  DetectEngineThreadCtx *det_ctx = NULL;
2222  HtpState *http_state = NULL;
2223  Flow f;
2224  uint8_t http1_buf[] =
2225  "GET /index.html HTTP/1.0\r\n"
2226  "Host: www.openinfosecfoundation.org\r\n"
2227  "User-Agent: This is dummy body1";
2228  uint8_t http2_buf[] =
2229  "This is dummy message body2\r\n"
2230  "Content-Type: text/html\r\n"
2231  "Content-Length: 46\r\n"
2232  "\r\n"
2233  "This is dummy body1";
2234  uint32_t http1_len = sizeof(http1_buf) - 1;
2235  uint32_t http2_len = sizeof(http2_buf) - 1;
2236  int result = 0;
2238 
2239  memset(&th_v, 0, sizeof(th_v));
2240  memset(&f, 0, sizeof(f));
2241  memset(&ssn, 0, sizeof(ssn));
2242 
2243  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2244  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2245 
2246  FLOW_INITIALIZE(&f);
2247  f.protoctx = (void *)&ssn;
2248  f.proto = IPPROTO_TCP;
2249  f.flags |= FLOW_IPV4;
2250 
2251  p1->flow = &f;
2255  p2->flow = &f;
2259  f.alproto = ALPROTO_HTTP;
2260 
2262 
2263  de_ctx = DetectEngineCtxInit();
2264  if (de_ctx == NULL)
2265  goto end;
2266 
2267  de_ctx->flags |= DE_QUIET;
2268 
2269  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2270  "(msg:\"http user agent test\"; "
2271  "content:\"body1This\"; http_user_agent; "
2272  "sid:1;)");
2273  if (de_ctx->sig_list == NULL)
2274  goto end;
2275 
2276  SigGroupBuild(de_ctx);
2277  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2278 
2279  FLOWLOCK_WRLOCK(&f);
2280  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2281  STREAM_TOSERVER, http1_buf, http1_len);
2282  if (r != 0) {
2283  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2284  result = 0;
2285  FLOWLOCK_UNLOCK(&f);
2286  goto end;
2287  }
2288  FLOWLOCK_UNLOCK(&f);
2289 
2290  http_state = f.alstate;
2291  if (http_state == NULL) {
2292  printf("no http state: ");
2293  result = 0;
2294  goto end;
2295  }
2296 
2297  /* do detect */
2298  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2299 
2300  if ((PacketAlertCheck(p1, 1))) {
2301  printf("sid 1 didn't match but should have");
2302  goto end;
2303  }
2304 
2305  FLOWLOCK_WRLOCK(&f);
2306  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2307  STREAM_TOSERVER, http2_buf, http2_len);
2308  if (r != 0) {
2309  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2310  result = 0;
2311  FLOWLOCK_UNLOCK(&f);
2312  goto end;
2313  }
2314  FLOWLOCK_UNLOCK(&f);
2315 
2316  /* do detect */
2317  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2318 
2319  if (!(PacketAlertCheck(p2, 1))) {
2320  printf("sid 1 didn't match but should have");
2321  goto end;
2322  }
2323 
2324  result = 1;
2325 end:
2326  if (alp_tctx != NULL)
2327  AppLayerParserThreadCtxFree(alp_tctx);
2328  if (de_ctx != NULL)
2329  DetectEngineCtxFree(de_ctx);
2330 
2332  FLOW_DESTROY(&f);
2333  UTHFreePackets(&p1, 1);
2334  UTHFreePackets(&p2, 1);
2335  return result;
2336 }
2337 
2338 /**
2339  *\test Test that the http_user_agent content matches against a http request
2340  * against a case insensitive pattern.
2341  */
2342 static int DetectHttpUATest10(void)
2343 {
2344  TcpSession ssn;
2345  Packet *p1 = NULL;
2346  Packet *p2 = NULL;
2347  ThreadVars th_v;
2348  DetectEngineCtx *de_ctx = NULL;
2349  DetectEngineThreadCtx *det_ctx = NULL;
2350  HtpState *http_state = NULL;
2351  Flow f;
2352  uint8_t http1_buf[] =
2353  "GET /index.html HTTP/1.0\r\n"
2354  "Host: www.openinfosecfoundation.org\r\n"
2355  "User-Agent: This is dummy bodY1";
2356  uint8_t http2_buf[] =
2357  "This is dummy message body2\r\n"
2358  "Content-Type: text/html\r\n"
2359  "Content-Length: 46\r\n"
2360  "\r\n"
2361  "This is dummy bodY1";
2362  uint32_t http1_len = sizeof(http1_buf) - 1;
2363  uint32_t http2_len = sizeof(http2_buf) - 1;
2364  int result = 0;
2366 
2367  memset(&th_v, 0, sizeof(th_v));
2368  memset(&f, 0, sizeof(f));
2369  memset(&ssn, 0, sizeof(ssn));
2370 
2371  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2372  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2373 
2374  FLOW_INITIALIZE(&f);
2375  f.protoctx = (void *)&ssn;
2376  f.proto = IPPROTO_TCP;
2377  f.flags |= FLOW_IPV4;
2378 
2379  p1->flow = &f;
2383  p2->flow = &f;
2387  f.alproto = ALPROTO_HTTP;
2388 
2390 
2391  de_ctx = DetectEngineCtxInit();
2392  if (de_ctx == NULL)
2393  goto end;
2394 
2395  de_ctx->flags |= DE_QUIET;
2396 
2397  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2398  "(msg:\"http user agent test\"; "
2399  "content:\"body1this\"; http_user_agent; nocase;"
2400  "sid:1;)");
2401  if (de_ctx->sig_list == NULL)
2402  goto end;
2403 
2404  SigGroupBuild(de_ctx);
2405  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2406 
2407  FLOWLOCK_WRLOCK(&f);
2408  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2409  STREAM_TOSERVER, http1_buf, http1_len);
2410  if (r != 0) {
2411  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2412  result = 0;
2413  FLOWLOCK_UNLOCK(&f);
2414  goto end;
2415  }
2416  FLOWLOCK_UNLOCK(&f);
2417 
2418  http_state = f.alstate;
2419  if (http_state == NULL) {
2420  printf("no http state: \n");
2421  result = 0;
2422  goto end;
2423  }
2424 
2425  /* do detect */
2426  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2427 
2428  if ((PacketAlertCheck(p1, 1))) {
2429  printf("sid 1 didn't match but should have\n");
2430  goto end;
2431  }
2432 
2433  FLOWLOCK_WRLOCK(&f);
2434  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2435  STREAM_TOSERVER, http2_buf, http2_len);
2436  if (r != 0) {
2437  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
2438  result = 0;
2439  FLOWLOCK_UNLOCK(&f);
2440  goto end;
2441  }
2442  FLOWLOCK_UNLOCK(&f);
2443 
2444  /* do detect */
2445  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2446 
2447  if (!(PacketAlertCheck(p2, 1))) {
2448  printf("sid 1 didn't match but should have");
2449  goto end;
2450  }
2451 
2452  result = 1;
2453 end:
2454  if (alp_tctx != NULL)
2455  AppLayerParserThreadCtxFree(alp_tctx);
2456  if (de_ctx != NULL)
2457  DetectEngineCtxFree(de_ctx);
2458 
2460  FLOW_DESTROY(&f);
2461  UTHFreePackets(&p1, 1);
2462  UTHFreePackets(&p2, 1);
2463  return result;
2464 }
2465 
2466 /**
2467  *\test Test that the negated http_user_agent content matches against a
2468  * http request which doesn't hold the content.
2469  */
2470 static int DetectHttpUATest11(void)
2471 {
2472  TcpSession ssn;
2473  Packet *p = NULL;
2474  ThreadVars th_v;
2475  DetectEngineCtx *de_ctx = NULL;
2476  DetectEngineThreadCtx *det_ctx = NULL;
2477  HtpState *http_state = NULL;
2478  Flow f;
2479  uint8_t http_buf[] =
2480  "GET /index.html HTTP/1.0\r\n"
2481  "Host: www.openinfosecfoundation.org\r\n"
2482  "User-Agent: This is dummy message body\r\n"
2483  "Content-Type: text/html\r\n"
2484  "\r\n";
2485  uint32_t http_len = sizeof(http_buf) - 1;
2486  int result = 0;
2488 
2489  memset(&th_v, 0, sizeof(th_v));
2490  memset(&f, 0, sizeof(f));
2491  memset(&ssn, 0, sizeof(ssn));
2492 
2493  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2494 
2495  FLOW_INITIALIZE(&f);
2496  f.protoctx = (void *)&ssn;
2497  f.proto = IPPROTO_TCP;
2498  f.flags |= FLOW_IPV4;
2499 
2500  p->flow = &f;
2504  f.alproto = ALPROTO_HTTP;
2505 
2507 
2508  de_ctx = DetectEngineCtxInit();
2509  if (de_ctx == NULL)
2510  goto end;
2511 
2512  de_ctx->flags |= DE_QUIET;
2513 
2514  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2515  "(msg:\"http user agent test\"; "
2516  "content:!\"message\"; http_user_agent; "
2517  "sid:1;)");
2518  if (de_ctx->sig_list == NULL)
2519  goto end;
2520 
2521  SigGroupBuild(de_ctx);
2522  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2523 
2524  FLOWLOCK_WRLOCK(&f);
2525  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2526  STREAM_TOSERVER, http_buf, http_len);
2527  if (r != 0) {
2528  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2529  result = 0;
2530  FLOWLOCK_UNLOCK(&f);
2531  goto end;
2532  }
2533  FLOWLOCK_UNLOCK(&f);
2534 
2535  http_state = f.alstate;
2536  if (http_state == NULL) {
2537  printf("no http state: ");
2538  result = 0;
2539  goto end;
2540  }
2541 
2542  /* do detect */
2543  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2544 
2545  if (PacketAlertCheck(p, 1)) {
2546  printf("sid 1 matched but shouldn't have");
2547  goto end;
2548  }
2549 
2550  result = 1;
2551 end:
2552  if (alp_tctx != NULL)
2553  AppLayerParserThreadCtxFree(alp_tctx);
2554  if (de_ctx != NULL)
2555  DetectEngineCtxFree(de_ctx);
2556 
2558  FLOW_DESTROY(&f);
2559  UTHFreePackets(&p, 1);
2560  return result;
2561 }
2562 
2563 /**
2564  *\test Negative test that the negated http_user_agent content matches against a
2565  * http request which holds hold the content.
2566  */
2567 static int DetectHttpUATest12(void)
2568 {
2569  TcpSession ssn;
2570  Packet *p = NULL;
2571  ThreadVars th_v;
2572  DetectEngineCtx *de_ctx = NULL;
2573  DetectEngineThreadCtx *det_ctx = NULL;
2574  HtpState *http_state = NULL;
2575  Flow f;
2576  uint8_t http_buf[] =
2577  "GET /index.html HTTP/1.0\r\n"
2578  "Host: www.openinfosecfoundation.org\r\n"
2579  "User-Agent: This is dummy body\r\n"
2580  "\r\n";
2581  uint32_t http_len = sizeof(http_buf) - 1;
2582  int result = 0;
2584 
2585  memset(&th_v, 0, sizeof(th_v));
2586  memset(&f, 0, sizeof(f));
2587  memset(&ssn, 0, sizeof(ssn));
2588 
2589  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2590 
2591  FLOW_INITIALIZE(&f);
2592  f.protoctx = (void *)&ssn;
2593  f.proto = IPPROTO_TCP;
2594  f.flags |= FLOW_IPV4;
2595 
2596  p->flow = &f;
2600  f.alproto = ALPROTO_HTTP;
2601 
2603 
2604  de_ctx = DetectEngineCtxInit();
2605  if (de_ctx == NULL)
2606  goto end;
2607 
2608  de_ctx->flags |= DE_QUIET;
2609 
2610  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2611  "(msg:\"http user agent test\"; "
2612  "content:!\"message\"; http_user_agent; "
2613  "sid:1;)");
2614  if (de_ctx->sig_list == NULL)
2615  goto end;
2616 
2617  SigGroupBuild(de_ctx);
2618  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2619 
2620  FLOWLOCK_WRLOCK(&f);
2621  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2622  STREAM_TOSERVER, http_buf, http_len);
2623  if (r != 0) {
2624  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2625  result = 0;
2626  FLOWLOCK_UNLOCK(&f);
2627  goto end;
2628  }
2629  FLOWLOCK_UNLOCK(&f);
2630 
2631  http_state = f.alstate;
2632  if (http_state == NULL) {
2633  printf("no http state: ");
2634  result = 0;
2635  goto end;
2636  }
2637 
2638  /* do detect */
2639  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2640 
2641  if (!(PacketAlertCheck(p, 1))) {
2642  printf("sid 1 didn't match but should have");
2643  goto end;
2644  }
2645 
2646  result = 1;
2647 end:
2648  if (alp_tctx != NULL)
2649  AppLayerParserThreadCtxFree(alp_tctx);
2650  if (de_ctx != NULL)
2651  DetectEngineCtxFree(de_ctx);
2652 
2654  FLOW_DESTROY(&f);
2655  UTHFreePackets(&p, 1);
2656  return result;
2657 }
2658 
2659 /**
2660  * \test Test that the http_user_agent content matches against a http request
2661  * which holds the content.
2662  */
2663 static int DetectHttpUATest13(void)
2664 {
2665  TcpSession ssn;
2666  Packet *p = NULL;
2667  ThreadVars th_v;
2668  DetectEngineCtx *de_ctx = NULL;
2669  DetectEngineThreadCtx *det_ctx = NULL;
2670  HtpState *http_state = NULL;
2671  Flow f;
2672  uint8_t http_buf[] =
2673  "GET /index.html HTTP/1.0\r\n"
2674  "Host: www.openinfosecfoundation.org\r\n"
2675  "User-Agent: longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n"
2676  "Content-Type: text/html\r\n"
2677  "\r\n";
2678  uint32_t http_len = sizeof(http_buf) - 1;
2679  int result = 0;
2681 
2682  memset(&th_v, 0, sizeof(th_v));
2683  memset(&f, 0, sizeof(f));
2684  memset(&ssn, 0, sizeof(ssn));
2685 
2686  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2687 
2688  FLOW_INITIALIZE(&f);
2689  f.protoctx = (void *)&ssn;
2690  f.proto = IPPROTO_TCP;
2691  f.flags |= FLOW_IPV4;
2692 
2693  p->flow = &f;
2697  f.alproto = ALPROTO_HTTP;
2698 
2700 
2701  de_ctx = DetectEngineCtxInit();
2702  if (de_ctx == NULL)
2703  goto end;
2704 
2705  de_ctx->flags |= DE_QUIET;
2706 
2707  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2708  "(msg:\"http user agent test\"; "
2709  "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_user_agent; "
2710  "sid:1;)");
2711  if (de_ctx->sig_list == NULL)
2712  goto end;
2713 
2714  SigGroupBuild(de_ctx);
2715  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2716 
2717  FLOWLOCK_WRLOCK(&f);
2718  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2719  STREAM_TOSERVER, http_buf, http_len);
2720  if (r != 0) {
2721  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2722  result = 0;
2723  FLOWLOCK_UNLOCK(&f);
2724  goto end;
2725  }
2726  FLOWLOCK_UNLOCK(&f);
2727 
2728  http_state = f.alstate;
2729  if (http_state == NULL) {
2730  printf("no http state: ");
2731  result = 0;
2732  goto end;
2733  }
2734 
2735  /* do detect */
2736  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2737 
2738  if (!(PacketAlertCheck(p, 1))) {
2739  printf("sid 1 didn't match but should have");
2740  goto end;
2741  }
2742 
2743  result = 1;
2744 end:
2745  if (alp_tctx != NULL)
2746  AppLayerParserThreadCtxFree(alp_tctx);
2747  if (de_ctx != NULL)
2748  DetectEngineCtxFree(de_ctx);
2749 
2751  FLOW_DESTROY(&f);
2752  UTHFreePackets(&p, 1);
2753  return result;
2754 }
2755 
2756 /**
2757  * \test multiple http transactions and body chunks of request handling
2758  */
2759 static int DetectHttpUATest14(void)
2760 {
2761  int result = 0;
2762  Signature *s = NULL;
2763  DetectEngineThreadCtx *det_ctx = NULL;
2764  ThreadVars th_v;
2765  Flow f;
2766  TcpSession ssn;
2767  Packet *p = NULL;
2768  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
2769  uint8_t httpbuf2[] = "Cookie: dummy1\r\n";
2770  uint8_t httpbuf3[] = "User-Agent: Body one!!\r\n\r\n";
2771  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2772  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2773  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2774  uint8_t httpbuf4[] = "GET /?var=val HTTP/1.1\r\n";
2775  uint8_t httpbuf5[] = "Cookie: dummy2\r\n";
2776  uint8_t httpbuf6[] = "User-Agent: Body two\r\n\r\n";
2777  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2778  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2779  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2781 
2782  memset(&th_v, 0, sizeof(th_v));
2783  memset(&f, 0, sizeof(f));
2784  memset(&ssn, 0, sizeof(ssn));
2785 
2786  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2787 
2788  FLOW_INITIALIZE(&f);
2789  f.protoctx = (void *)&ssn;
2790  f.proto = IPPROTO_TCP;
2791  f.flags |= FLOW_IPV4;
2792 
2793  p->flow = &f;
2797  f.alproto = ALPROTO_HTTP;
2798 
2800 
2802  if (de_ctx == NULL) {
2803  goto end;
2804  }
2805 
2806  de_ctx->flags |= DE_QUIET;
2807 
2808  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy1\"; http_cookie; content:\"Body one\"; http_user_agent; sid:1; rev:1;)");
2809  if (s == NULL) {
2810  printf("sig parse failed: ");
2811  goto end;
2812  }
2813  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"dummy2\"; http_cookie; content:\"Body two\"; http_user_agent; sid:2; rev:1;)");
2814  if (s == NULL) {
2815  printf("sig2 parse failed: ");
2816  goto end;
2817  }
2818 
2819  SigGroupBuild(de_ctx);
2820  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2821 
2822  FLOWLOCK_WRLOCK(&f);
2823  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2824  STREAM_TOSERVER, httpbuf1, httplen1);
2825  if (r != 0) {
2826  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2827  FLOWLOCK_UNLOCK(&f);
2828  goto end;
2829  }
2830  FLOWLOCK_UNLOCK(&f);
2831 
2832  /* do detect */
2833  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2834  if (PacketAlertCheck(p, 1)) {
2835  printf("sig 1 alerted: ");
2836  goto end;
2837  }
2838  p->alerts.cnt = 0;
2839 
2840  FLOWLOCK_WRLOCK(&f);
2841  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2842  STREAM_TOSERVER, httpbuf2, httplen2);
2843  if (r != 0) {
2844  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
2845  FLOWLOCK_UNLOCK(&f);
2846  goto end;
2847  }
2848  FLOWLOCK_UNLOCK(&f);
2849 
2850  /* do detect */
2851  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2852  if (PacketAlertCheck(p, 1)) {
2853  printf("sig 1 alerted (2): ");
2854  goto end;
2855  }
2856  p->alerts.cnt = 0;
2857 
2858  FLOWLOCK_WRLOCK(&f);
2859  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2860  STREAM_TOSERVER, httpbuf3, httplen3);
2861  if (r != 0) {
2862  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
2863  FLOWLOCK_UNLOCK(&f);
2864  goto end;
2865  }
2866  FLOWLOCK_UNLOCK(&f);
2867 
2868  /* do detect */
2869  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2870  if (!(PacketAlertCheck(p, 1))) {
2871  printf("sig 1 didn't alert: ");
2872  goto end;
2873  }
2874  p->alerts.cnt = 0;
2875 
2876  FLOWLOCK_WRLOCK(&f);
2877  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2878  STREAM_TOSERVER, httpbuf4, httplen4);
2879  if (r != 0) {
2880  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2881  FLOWLOCK_UNLOCK(&f);
2882  goto end;
2883  }
2884  FLOWLOCK_UNLOCK(&f);
2885 
2886  /* do detect */
2887  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2888  if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2)) {
2889  printf("sig 1 alerted (4): ");
2890  goto end;
2891  }
2892  p->alerts.cnt = 0;
2893 
2894  FLOWLOCK_WRLOCK(&f);
2895  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2896  STREAM_TOSERVER, httpbuf5, httplen5);
2897  if (r != 0) {
2898  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2899  FLOWLOCK_UNLOCK(&f);
2900  goto end;
2901  }
2902  FLOWLOCK_UNLOCK(&f);
2903 
2904  /* do detect */
2905  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2906  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2907  printf("sig 1 alerted (request 2, chunk 6): ");
2908  goto end;
2909  }
2910  p->alerts.cnt = 0;
2911 
2912  SCLogDebug("sending data chunk 7");
2913 
2914  FLOWLOCK_WRLOCK(&f);
2915  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2916  STREAM_TOSERVER, httpbuf6, httplen6);
2917  if (r != 0) {
2918  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2919  FLOWLOCK_UNLOCK(&f);
2920  goto end;
2921  }
2922  FLOWLOCK_UNLOCK(&f);
2923 
2924  /* do detect */
2925  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2926  if (PacketAlertCheck(p, 1) || !(PacketAlertCheck(p, 2))) {
2927  printf("signature 2 didn't match or sig 1 matched, but shouldn't have: ");
2928  goto end;
2929  }
2930  p->alerts.cnt = 0;
2931 
2932  HtpState *htp_state = f.alstate;
2933  if (htp_state == NULL) {
2934  printf("no http state: ");
2935  result = 0;
2936  goto end;
2937  }
2938 
2939  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2940  printf("The http app layer doesn't have 2 transactions, but it should: ");
2941  goto end;
2942  }
2943 
2944  result = 1;
2945 end:
2946  if (alp_tctx != NULL)
2947  AppLayerParserThreadCtxFree(alp_tctx);
2948  if (det_ctx != NULL) {
2949  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2950  }
2951  if (de_ctx != NULL) {
2952  DetectEngineCtxFree(de_ctx);
2953  }
2954 
2956  FLOW_DESTROY(&f);
2957  UTHFreePacket(p);
2958  return result;
2959 }
2960 
2961 static int DetectHttpUATest22(void)
2962 {
2963  DetectEngineCtx *de_ctx = NULL;
2964  int result = 0;
2965 
2966  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2967  goto end;
2968 
2969  de_ctx->flags |= DE_QUIET;
2970  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2971  "(content:\"one\"; content:\"two\"; http_user_agent; "
2972  "content:\"three\"; distance:10; http_user_agent; content:\"four\"; sid:1;)");
2973  if (de_ctx->sig_list == NULL) {
2974  printf("de_ctx->sig_list == NULL\n");
2975  goto end;
2976  }
2977 
2978  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2979  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2980  goto end;
2981  }
2982 
2983  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
2984  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
2985  goto end;
2986  }
2987 
2988  DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2989  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2990  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
2991  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
2992  if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 ||
2993  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2994  huad1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2995  memcmp(huad1->content, "two", huad1->content_len) != 0 ||
2996  huad2->flags != DETECT_CONTENT_DISTANCE ||
2997  memcmp(huad2->content, "three", huad1->content_len) != 0) {
2998  goto end;
2999  }
3000 
3001  if (!DETECT_CONTENT_IS_SINGLE(cd1) ||
3002  !DETECT_CONTENT_IS_SINGLE(cd2) ||
3003  DETECT_CONTENT_IS_SINGLE(huad1) ||
3004  DETECT_CONTENT_IS_SINGLE(huad2)) {
3005  goto end;
3006  }
3007 
3008  result = 1;
3009 
3010  end:
3011  DetectEngineCtxFree(de_ctx);
3012  return result;
3013 }
3014 
3015 static int DetectHttpUATest23(void)
3016 {
3017  DetectEngineCtx *de_ctx = NULL;
3018  int result = 0;
3019 
3020  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3021  goto end;
3022 
3023  de_ctx->flags |= DE_QUIET;
3024  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3025  "(content:\"one\"; http_user_agent; pcre:/two/; "
3026  "content:\"three\"; distance:10; http_user_agent; content:\"four\"; sid:1;)");
3027  if (de_ctx->sig_list == NULL) {
3028  printf("de_ctx->sig_list == NULL\n");
3029  goto end;
3030  }
3031 
3032  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3033  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3034  goto end;
3035  }
3036 
3037  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3038  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3039  goto end;
3040  }
3041 
3042  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3043  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3044  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3045  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3046  if (pd1->flags != 0 ||
3047  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3048  huad1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
3049  memcmp(huad1->content, "one", huad1->content_len) != 0 ||
3050  huad2->flags != DETECT_CONTENT_DISTANCE ||
3051  memcmp(huad2->content, "three", huad1->content_len) != 0) {
3052  goto end;
3053  }
3054 
3055  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
3056  DETECT_CONTENT_IS_SINGLE(huad1) ||
3057  DETECT_CONTENT_IS_SINGLE(huad2)) {
3058  goto end;
3059  }
3060 
3061  result = 1;
3062 
3063  end:
3064  DetectEngineCtxFree(de_ctx);
3065  return result;
3066 }
3067 
3068 static int DetectHttpUATest24(void)
3069 {
3070  DetectEngineCtx *de_ctx = NULL;
3071  int result = 0;
3072 
3073  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3074  goto end;
3075 
3076  de_ctx->flags |= DE_QUIET;
3077  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3078  "(content:\"one\"; http_user_agent; pcre:/two/; "
3079  "content:\"three\"; distance:10; within:15; http_user_agent; content:\"four\"; sid:1;)");
3080  if (de_ctx->sig_list == NULL) {
3081  printf("de_ctx->sig_list == NULL\n");
3082  goto end;
3083  }
3084 
3085  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3086  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3087  goto end;
3088  }
3089 
3090  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3091  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3092  goto end;
3093  }
3094 
3095  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3096  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3097  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3098  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3099  if (pd1->flags != 0 ||
3100  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3101  huad1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
3102  memcmp(huad1->content, "one", huad1->content_len) != 0 ||
3103  huad2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
3104  memcmp(huad2->content, "three", huad1->content_len) != 0) {
3105  goto end;
3106  }
3107 
3108  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
3109  DETECT_CONTENT_IS_SINGLE(huad1) ||
3110  DETECT_CONTENT_IS_SINGLE(huad2)) {
3111  goto end;
3112  }
3113 
3114  result = 1;
3115 
3116  end:
3117  DetectEngineCtxFree(de_ctx);
3118  return result;
3119 }
3120 
3121 static int DetectHttpUATest25(void)
3122 {
3123  DetectEngineCtx *de_ctx = NULL;
3124  int result = 0;
3125 
3126  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3127  goto end;
3128 
3129  de_ctx->flags |= DE_QUIET;
3130  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3131  "(content:\"one\"; http_user_agent; pcre:/two/; "
3132  "content:\"three\"; distance:10; http_user_agent; "
3133  "content:\"four\"; distance:10; sid:1;)");
3134  if (de_ctx->sig_list == NULL) {
3135  printf("de_ctx->sig_list == NULL\n");
3136  goto end;
3137  }
3138 
3139  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3140  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3141  goto end;
3142  }
3143 
3144  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3145  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3146  goto end;
3147  }
3148 
3149  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3150  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3151  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3152  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3153  if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT ||
3154  cd2->flags != DETECT_CONTENT_DISTANCE ||
3155  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3156  huad1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
3157  memcmp(huad1->content, "one", huad1->content_len) != 0 ||
3158  huad2->flags != DETECT_CONTENT_DISTANCE ||
3159  memcmp(huad2->content, "three", huad1->content_len) != 0) {
3160  goto end;
3161  }
3162 
3163  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
3164  DETECT_CONTENT_IS_SINGLE(huad1) ||
3165  DETECT_CONTENT_IS_SINGLE(huad2)) {
3166  goto end;
3167  }
3168 
3169  result = 1;
3170 
3171  end:
3172  DetectEngineCtxFree(de_ctx);
3173  return result;
3174 }
3175 
3176 static int DetectHttpUATest26(void)
3177 {
3178  DetectEngineCtx *de_ctx = NULL;
3179  int result = 0;
3180 
3181  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3182  goto end;
3183 
3184  de_ctx->flags |= DE_QUIET;
3185  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3186  "(content:\"one\"; offset:10; http_user_agent; pcre:/two/; "
3187  "content:\"three\"; distance:10; http_user_agent; within:10; "
3188  "content:\"four\"; distance:10; sid:1;)");
3189  if (de_ctx->sig_list == NULL) {
3190  printf("de_ctx->sig_list == NULL\n");
3191  goto end;
3192  }
3193 
3194  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3195  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3196  goto end;
3197  }
3198 
3199  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3200  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3201  goto end;
3202  }
3203 
3204  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3205  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3206  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3207  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3208  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
3209  cd2->flags != DETECT_CONTENT_DISTANCE ||
3210  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3212  memcmp(huad1->content, "one", huad1->content_len) != 0 ||
3213  huad2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
3214  memcmp(huad2->content, "three", huad1->content_len) != 0) {
3215  printf ("failed: http_user_agent incorrect flags");
3216  goto end;
3217  }
3218 
3219  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
3220  DETECT_CONTENT_IS_SINGLE(huad1) ||
3221  DETECT_CONTENT_IS_SINGLE(huad2)) {
3222  goto end;
3223  }
3224 
3225  result = 1;
3226 
3227  end:
3228  DetectEngineCtxFree(de_ctx);
3229  return result;
3230 }
3231 
3232 static int DetectHttpUATest27(void)
3233 {
3234  DetectEngineCtx *de_ctx = NULL;
3235  int result = 0;
3236 
3237  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3238  goto end;
3239 
3240  de_ctx->flags |= DE_QUIET;
3241  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3242  "(content:\"one\"; offset:10; http_user_agent; pcre:/two/; "
3243  "content:\"three\"; distance:10; http_user_agent; within:10; "
3244  "content:\"four\"; distance:10; sid:1;)");
3245  if (de_ctx->sig_list == NULL) {
3246  printf("de_ctx->sig_list == NULL\n");
3247  goto end;
3248  }
3249 
3250  result = 1;
3251 
3252  end:
3253  DetectEngineCtxFree(de_ctx);
3254  return result;
3255 }
3256 
3257 static int DetectHttpUATest28(void)
3258 {
3259  DetectEngineCtx *de_ctx = NULL;
3260  int result = 0;
3261 
3262  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3263  goto end;
3264 
3265  de_ctx->flags |= DE_QUIET;
3266  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3267  "(content:\"one\"; http_user_agent; pcre:/two/; "
3268  "content:\"three\"; http_user_agent; depth:10; "
3269  "content:\"four\"; distance:10; sid:1;)");
3270  if (de_ctx->sig_list == NULL) {
3271  printf("de_ctx->sig_list == NULL\n");
3272  goto end;
3273  }
3274 
3275  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
3276  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
3277  goto end;
3278  }
3279 
3280  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3281  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3282  goto end;
3283  }
3284 
3285  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
3286  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
3287  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3288  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3289  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
3290  cd2->flags != DETECT_CONTENT_DISTANCE ||
3291  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
3292  huad1->flags != 0 ||
3293  memcmp(huad1->content, "one", huad1->content_len) != 0 ||
3294  huad2->flags != DETECT_CONTENT_DEPTH ||
3295  memcmp(huad2->content, "three", huad1->content_len) != 0) {
3296  goto end;
3297  }
3298 
3299  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
3300  !DETECT_CONTENT_IS_SINGLE(huad1) ||
3301  DETECT_CONTENT_IS_SINGLE(huad2)) {
3302  goto end;
3303  }
3304 
3305  result = 1;
3306 
3307  end:
3308  DetectEngineCtxFree(de_ctx);
3309  return result;
3310 }
3311 
3312 static int DetectHttpUATest29(void)
3313 {
3314  DetectEngineCtx *de_ctx = NULL;
3315  int result = 0;
3316 
3317  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3318  goto end;
3319 
3320  de_ctx->flags |= DE_QUIET;
3321  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3322  "(content:\"one\"; http_user_agent; "
3323  "content:\"two\"; distance:0; http_user_agent; sid:1;)");
3324  if (de_ctx->sig_list == NULL) {
3325  printf("de_ctx->sig_list == NULL\n");
3326  goto end;
3327  }
3328 
3329  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
3330  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
3331  goto end;
3332  }
3333 
3334  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3335  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3336  goto end;
3337  }
3338 
3339  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3340  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3341  if (huad1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
3342  memcmp(huad1->content, "one", huad1->content_len) != 0 ||
3343  huad2->flags != DETECT_CONTENT_DISTANCE ||
3344  memcmp(huad2->content, "two", huad1->content_len) != 0) {
3345  goto end;
3346  }
3347 
3348  result = 1;
3349 
3350  end:
3351  DetectEngineCtxFree(de_ctx);
3352  return result;
3353 }
3354 
3355 static int DetectHttpUATest30(void)
3356 {
3357  DetectEngineCtx *de_ctx = NULL;
3358  int result = 0;
3359 
3360  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3361  goto end;
3362 
3363  de_ctx->flags |= DE_QUIET;
3364  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3365  "(content:\"one\"; http_user_agent; "
3366  "content:\"two\"; within:5; http_user_agent; sid:1;)");
3367  if (de_ctx->sig_list == NULL) {
3368  printf("de_ctx->sig_list == NULL\n");
3369  goto end;
3370  }
3371 
3372  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
3373  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
3374  goto end;
3375  }
3376 
3377  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3378  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3379  goto end;
3380  }
3381 
3382  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3383  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3384  if (huad1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
3385  memcmp(huad1->content, "one", huad1->content_len) != 0 ||
3386  huad2->flags != DETECT_CONTENT_WITHIN ||
3387  memcmp(huad2->content, "two", huad1->content_len) != 0) {
3388  goto end;
3389  }
3390 
3391  result = 1;
3392 
3393  end:
3394  DetectEngineCtxFree(de_ctx);
3395  return result;
3396 }
3397 
3398 static int DetectHttpUATest31(void)
3399 {
3400  DetectEngineCtx *de_ctx = NULL;
3401  int result = 0;
3402 
3403  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3404  goto end;
3405 
3406  de_ctx->flags |= DE_QUIET;
3407  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3408  "(content:\"one\"; within:5; http_user_agent; sid:1;)");
3409  if (de_ctx->sig_list == NULL) {
3410  printf("de_ctx->sig_list == NULL\n");
3411  goto end;
3412  }
3413 
3414  result = 1;
3415 
3416  end:
3417  DetectEngineCtxFree(de_ctx);
3418  return result;
3419 }
3420 
3421 static int DetectHttpUATest32(void)
3422 {
3423  DetectEngineCtx *de_ctx = NULL;
3424  int result = 0;
3425 
3426  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3427  goto end;
3428 
3429  de_ctx->flags |= DE_QUIET;
3430  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3431  "(content:\"one\"; http_user_agent; within:5; sid:1;)");
3432  if (de_ctx->sig_list == NULL) {
3433  printf("de_ctx->sig_list != NULL\n");
3434  goto end;
3435  }
3436 
3437  result = 1;
3438 
3439  end:
3440  DetectEngineCtxFree(de_ctx);
3441  return result;
3442 }
3443 
3444 static int DetectHttpUATest33(void)
3445 {
3446  DetectEngineCtx *de_ctx = NULL;
3447  int result = 0;
3448 
3449  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3450  goto end;
3451 
3452  de_ctx->flags |= DE_QUIET;
3453  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3454  "(content:\"one\"; within:5; sid:1;)");
3455  if (de_ctx->sig_list == NULL) {
3456  printf("de_ctx->sig_list == NULL\n");
3457  goto end;
3458  }
3459 
3460  result = 1;
3461 
3462  end:
3463  DetectEngineCtxFree(de_ctx);
3464  return result;
3465 }
3466 
3467 static int DetectHttpUATest34(void)
3468 {
3469  DetectEngineCtx *de_ctx = NULL;
3470  int result = 0;
3471 
3472  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3473  goto end;
3474 
3475  de_ctx->flags |= DE_QUIET;
3476  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3477  "(pcre:/one/V; "
3478  "content:\"two\"; within:5; http_user_agent; sid:1;)");
3479  if (de_ctx->sig_list == NULL) {
3480  printf("de_ctx->sig_list == NULL\n");
3481  goto end;
3482  }
3483 
3484  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
3485  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
3486  goto end;
3487  }
3488 
3489  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3490  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3491  goto end;
3492  }
3493 
3494  if (de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id] == NULL ||
3495  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->type != DETECT_CONTENT ||
3496  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev == NULL ||
3497  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->type != DETECT_PCRE) {
3498 
3499  goto end;
3500  }
3501 
3502  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3503  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3504  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
3505  huad2->flags != DETECT_CONTENT_WITHIN ||
3506  memcmp(huad2->content, "two", huad2->content_len) != 0) {
3507  goto end;
3508  }
3509 
3510  result = 1;
3511 
3512  end:
3513  DetectEngineCtxFree(de_ctx);
3514  return result;
3515 }
3516 
3517 static int DetectHttpUATest35(void)
3518 {
3519  DetectEngineCtx *de_ctx = NULL;
3520  int result = 0;
3521 
3522  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3523  goto end;
3524 
3525  de_ctx->flags |= DE_QUIET;
3526  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3527  "(content:\"two\"; http_user_agent; "
3528  "pcre:/one/VR; sid:1;)");
3529  if (de_ctx->sig_list == NULL) {
3530  printf("de_ctx->sig_list == NULL\n");
3531  goto end;
3532  }
3533 
3534  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
3535  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
3536  goto end;
3537  }
3538 
3539  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3540  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3541  goto end;
3542  }
3543 
3544  if (de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id] == NULL ||
3545  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->type != DETECT_PCRE ||
3546  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev == NULL ||
3547  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->type != DETECT_CONTENT) {
3548 
3549  goto end;
3550  }
3551 
3552  DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3553  DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3554  if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
3555  huad1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
3556  memcmp(huad1->content, "two", huad1->content_len) != 0) {
3557  goto end;
3558  }
3559 
3560  result = 1;
3561 
3562  end:
3563  DetectEngineCtxFree(de_ctx);
3564  return result;
3565 }
3566 
3567 static int DetectHttpUATest36(void)
3568 {
3569  DetectEngineCtx *de_ctx = NULL;
3570  int result = 0;
3571 
3572  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
3573  goto end;
3574 
3575  de_ctx->flags |= DE_QUIET;
3576  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3577  "(pcre:/one/V; "
3578  "content:\"two\"; distance:5; http_user_agent; sid:1;)");
3579  if (de_ctx->sig_list == NULL) {
3580  printf("de_ctx->sig_list == NULL\n");
3581  goto end;
3582  }
3583 
3584  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
3585  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
3586  goto end;
3587  }
3588 
3589  if (de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL) {
3590  printf("de_ctx->sig_list->sm_lists[g_http_ua_buffer_id] == NULL\n");
3591  goto end;
3592  }
3593 
3594  if (de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id] == NULL ||
3595  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->type != DETECT_CONTENT ||
3596  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev == NULL ||
3597  de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->type != DETECT_PCRE) {
3598 
3599  goto end;
3600  }
3601 
3602  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->prev->ctx;
3603  DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_ua_buffer_id]->ctx;
3604  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
3605  huad2->flags != DETECT_CONTENT_DISTANCE ||
3606  memcmp(huad2->content, "two", huad2->content_len) != 0) {
3607  goto end;
3608  }
3609 
3610  result = 1;
3611 
3612  end:
3613  DetectEngineCtxFree(de_ctx);
3614  return result;
3615 }
3616 
3617 static void DetectHttpUARegisterTests(void)
3618 {
3619  UtRegisterTest("DetectEngineHttpUATest01", DetectEngineHttpUATest01);
3620  UtRegisterTest("DetectEngineHttpUATest02", DetectEngineHttpUATest02);
3621  UtRegisterTest("DetectEngineHttpUATest03", DetectEngineHttpUATest03);
3622  UtRegisterTest("DetectEngineHttpUATest04", DetectEngineHttpUATest04);
3623  UtRegisterTest("DetectEngineHttpUATest05", DetectEngineHttpUATest05);
3624  UtRegisterTest("DetectEngineHttpUATest06", DetectEngineHttpUATest06);
3625  UtRegisterTest("DetectEngineHttpUATest07", DetectEngineHttpUATest07);
3626  UtRegisterTest("DetectEngineHttpUATest08", DetectEngineHttpUATest08);
3627  UtRegisterTest("DetectEngineHttpUATest09", DetectEngineHttpUATest09);
3628  UtRegisterTest("DetectEngineHttpUATest10", DetectEngineHttpUATest10);
3629  UtRegisterTest("DetectEngineHttpUATest11", DetectEngineHttpUATest11);
3630  UtRegisterTest("DetectEngineHttpUATest12", DetectEngineHttpUATest12);
3631  UtRegisterTest("DetectEngineHttpUATest13", DetectEngineHttpUATest13);
3632  UtRegisterTest("DetectEngineHttpUATest14", DetectEngineHttpUATest14);
3633  UtRegisterTest("DetectEngineHttpUATest15", DetectEngineHttpUATest15);
3634  UtRegisterTest("DetectEngineHttpUATest16", DetectEngineHttpUATest16);
3635  UtRegisterTest("DetectEngineHttpUATest17", DetectEngineHttpUATest17);
3636 
3637  UtRegisterTest("DetectHttpUATest01", DetectHttpUATest01);
3638  UtRegisterTest("DetectHttpUATest02", DetectHttpUATest02);
3639  UtRegisterTest("DetectHttpUATest03", DetectHttpUATest03);
3640  UtRegisterTest("DetectHttpUATest04", DetectHttpUATest04);
3641  UtRegisterTest("DetectHttpUATest05", DetectHttpUATest05);
3642  UtRegisterTest("DetectHttpUATest06", DetectHttpUATest06);
3643  UtRegisterTest("DetectHttpUATest07", DetectHttpUATest07);
3644  UtRegisterTest("DetectHttpUATest08", DetectHttpUATest08);
3645  UtRegisterTest("DetectHttpUATest09", DetectHttpUATest09);
3646  UtRegisterTest("DetectHttpUATest10", DetectHttpUATest10);
3647  UtRegisterTest("DetectHttpUATest11", DetectHttpUATest11);
3648  UtRegisterTest("DetectHttpUATest12", DetectHttpUATest12);
3649  UtRegisterTest("DetectHttpUATest13", DetectHttpUATest13);
3650  UtRegisterTest("DetectHttpUATest14", DetectHttpUATest14);
3651 
3652  UtRegisterTest("DetectHttpUATest22", DetectHttpUATest22);
3653  UtRegisterTest("DetectHttpUATest23", DetectHttpUATest23);
3654  UtRegisterTest("DetectHttpUATest24", DetectHttpUATest24);
3655  UtRegisterTest("DetectHttpUATest25", DetectHttpUATest25);
3656  UtRegisterTest("DetectHttpUATest26", DetectHttpUATest26);
3657  UtRegisterTest("DetectHttpUATest27", DetectHttpUATest27);
3658  UtRegisterTest("DetectHttpUATest28", DetectHttpUATest28);
3659  UtRegisterTest("DetectHttpUATest29", DetectHttpUATest29);
3660  UtRegisterTest("DetectHttpUATest30", DetectHttpUATest30);
3661  UtRegisterTest("DetectHttpUATest31", DetectHttpUATest31);
3662  UtRegisterTest("DetectHttpUATest32", DetectHttpUATest32);
3663  UtRegisterTest("DetectHttpUATest33", DetectHttpUATest33);
3664  UtRegisterTest("DetectHttpUATest34", DetectHttpUATest34);
3665  UtRegisterTest("DetectHttpUATest35", DetectHttpUATest35);
3666  UtRegisterTest("DetectHttpUATest36", DetectHttpUATest36);
3667 }
3668 
3669 /**
3670  * @}
3671  */
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
#define SCLogDebug(...)
Definition: util-debug.h:335
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:27
struct Flow_ * flow
Definition: decode.h:444
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:346
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:235
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Signature * sig_list
Definition: detect.h:726
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:195
void SigCleanSignatures(DetectEngineCtx *de_ctx)
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define DETECT_CONTENT_DISTANCE
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:232
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Signature container.
Definition: detect.h:492
#define DETECT_CONTENT_DEPTH
#define TRUE
void * protoctx
Definition: flow.h:398
uint16_t flags
Definition: detect-pcre.h:42
#define DETECT_CONTENT_IS_SINGLE(c)
main detection engine ctx
Definition: detect.h:720
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:436
#define DE_QUIET
Definition: detect.h:298
uint8_t flags
Definition: detect.h:721
#define FLOW_DESTROY(f)
Definition: flow-util.h:115
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1752
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
uint8_t flowflags
Definition: decode.h:438
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define FLOW_PKT_TOSERVER
Definition: flow.h:193
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
int SigGroupCleanup(DetectEngineCtx *de_ctx)
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
PacketAlerts alerts
Definition: decode.h:560
#define DETECT_CONTENT_WITHIN
#define PKT_HAS_FLOW
Definition: decode.h:1101
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
uint16_t cnt
Definition: decode.h:292
#define DETECT_CONTENT_RELATIVE_NEXT
Per thread variable structure.
Definition: threadvars.h:57
AppProto alproto
application level protocol
Definition: flow.h:407
uint32_t flags
Definition: decode.h:442
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...
#define DETECT_CONTENT_OFFSET
Flow data structure.
Definition: flow.h:327
#define FLOW_IPV4
Definition: flow.h:93
uint32_t flags
Definition: flow.h:377
#define PKT_STREAM_EST
Definition: decode.h:1099
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
DetectEngineCtx * DetectEngineCtxInit(void)