suricata
detect-http-stat-code.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 
31 #include "../suricata-common.h"
32 #include "../suricata.h"
33 #include "../flow-util.h"
34 #include "../flow.h"
35 #include "../app-layer-parser.h"
36 #include "../util-unittest.h"
37 #include "../util-unittest-helper.h"
38 #include "../app-layer.h"
39 #include "../app-layer-htp.h"
40 #include "../app-layer-protos.h"
41 
42 static int DetectEngineHttpStatCodeTest01(void)
43 {
44  TcpSession ssn;
45  Packet *p1 = NULL;
46  Packet *p2 = NULL;
47  ThreadVars th_v;
48  DetectEngineCtx *de_ctx = NULL;
49  DetectEngineThreadCtx *det_ctx = NULL;
50  HtpState *http_state = NULL;
51  Flow f;
52  uint8_t http_buf1[] =
53  "GET /index.html HTTP/1.0\r\n"
54  "Host: www.openinfosecfoundation.org\r\n"
55  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
56  "\r\n";
57  uint32_t http_len1 = sizeof(http_buf1) - 1;
58  uint8_t http_buf2[] =
59  "HTTP/1.0 200 message\r\n"
60  "Content-Type: text/html\r\n"
61  "Content-Length: 7\r\n"
62  "\r\n"
63  "message";
64  uint32_t http_len2 = sizeof(http_buf2) - 1;
65  int result = 0;
67 
68  memset(&th_v, 0, sizeof(th_v));
69  memset(&f, 0, sizeof(f));
70  memset(&ssn, 0, sizeof(ssn));
71 
72  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
73  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
74 
75  FLOW_INITIALIZE(&f);
76  f.protoctx = (void *)&ssn;
77  f.proto = IPPROTO_TCP;
78  f.flags |= FLOW_IPV4;
79 
80  p1->flow = &f;
84  p2->flow = &f;
89 
91 
92  de_ctx = DetectEngineCtxInit();
93  if (de_ctx == NULL)
94  goto end;
95 
96  de_ctx->flags |= DE_QUIET;
97 
98  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
99  "(msg:\"http stat code test\"; "
100  "content:\"200\"; http_stat_code; "
101  "sid:1;)");
102  if (de_ctx->sig_list == NULL)
103  goto end;
104 
105  SigGroupBuild(de_ctx);
106  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
107 
108  FLOWLOCK_WRLOCK(&f);
109  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
110  STREAM_TOSERVER, http_buf1, http_len1);
111  if (r != 0) {
112  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
113  result = 0;
114  FLOWLOCK_UNLOCK(&f);
115  goto end;
116  }
117  FLOWLOCK_UNLOCK(&f);
118 
119  http_state = f.alstate;
120  if (http_state == NULL) {
121  printf("no http state: \n");
122  result = 0;
123  goto end;
124  }
125 
126  /* do detect */
127  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
128 
129  if ((PacketAlertCheck(p1, 1))) {
130  printf("sid 1 matched but shouldn't have\n");
131  goto end;
132  }
133 
134  FLOWLOCK_WRLOCK(&f);
135  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
136  STREAM_TOCLIENT, http_buf2, http_len2);
137  if (r != 0) {
138  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
139  result = 0;
140  FLOWLOCK_UNLOCK(&f);
141  goto end;
142  }
143  FLOWLOCK_UNLOCK(&f);
144 
145  /* do detect */
146  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
147 
148  if (!(PacketAlertCheck(p2, 1))) {
149  printf("sid 1 didn't match but should have");
150  goto end;
151  }
152 
153  result = 1;
154 
155 end:
156  if (alp_tctx != NULL)
157  AppLayerParserThreadCtxFree(alp_tctx);
158  if (de_ctx != NULL)
159  DetectEngineCtxFree(de_ctx);
160 
162  FLOW_DESTROY(&f);
163  UTHFreePackets(&p1, 1);
164  UTHFreePackets(&p2, 1);
165  return result;
166 }
167 
168 static int DetectEngineHttpStatCodeTest02(void)
169 {
170  TcpSession ssn;
171  Packet *p1 = NULL;
172  ThreadVars th_v;
173  DetectEngineCtx *de_ctx = NULL;
174  DetectEngineThreadCtx *det_ctx = NULL;
175  HtpState *http_state = NULL;
176  Flow f;
177  uint8_t http_buf1[] =
178  "GET /index.html HTTP/1.0\r\n"
179  "Host: www.openinfosecfoundation.org\r\n"
180  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
181  "\r\n";
182  uint32_t http_len1 = sizeof(http_buf1) - 1;
183  uint8_t http_buf2[] =
184  "HTTP/1.0 2000123 xxxxABC\r\n"
185  "Content-Type: text/html\r\n"
186  "Content-Length: 7\r\n"
187  "\r\n"
188  "xxxxABC";
189  uint32_t http_len2 = sizeof(http_buf2) - 1;
190  int result = 0;
192 
193  memset(&th_v, 0, sizeof(th_v));
194  memset(&f, 0, sizeof(f));
195  memset(&ssn, 0, sizeof(ssn));
196 
197  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
198 
199  FLOW_INITIALIZE(&f);
200  f.protoctx = (void *)&ssn;
201  f.proto = IPPROTO_TCP;
202  f.flags |= FLOW_IPV4;
203 
204  p1->flow = &f;
208  f.alproto = ALPROTO_HTTP;
209 
211 
212  de_ctx = DetectEngineCtxInit();
213  if (de_ctx == NULL)
214  goto end;
215 
216  de_ctx->flags |= DE_QUIET;
217 
218  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
219  "(msg:\"http stat code test\"; "
220  "content:\"123\"; http_stat_code; offset:4; "
221  "sid:1;)");
222  if (de_ctx->sig_list == NULL)
223  goto end;
224 
225  SigGroupBuild(de_ctx);
226  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
227 
228  FLOWLOCK_WRLOCK(&f);
229  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
230  STREAM_TOSERVER, http_buf1, http_len1);
231  if (r != 0) {
232  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
233  result = 0;
234  FLOWLOCK_UNLOCK(&f);
235  goto end;
236  }
237  FLOWLOCK_UNLOCK(&f);
238 
239  FLOWLOCK_WRLOCK(&f);
240  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
241  STREAM_TOCLIENT, http_buf2, http_len2);
242  if (r != 0) {
243  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
244  result = 0;
245  FLOWLOCK_UNLOCK(&f);
246  goto end;
247  }
248  FLOWLOCK_UNLOCK(&f);
249 
250  http_state = f.alstate;
251  if (http_state == NULL) {
252  printf("no http state: \n");
253  result = 0;
254  goto end;
255  }
256 
257  /* do detect */
258  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
259 
260  if (!(PacketAlertCheck(p1, 1))) {
261  printf("sid 1 didn't match but should have\n");
262  goto end;
263  }
264 
265  result = 1;
266 
267 end:
268  if (alp_tctx != NULL)
269  AppLayerParserThreadCtxFree(alp_tctx);
270  if (de_ctx != NULL)
271  DetectEngineCtxFree(de_ctx);
272 
274  FLOW_DESTROY(&f);
275  UTHFreePackets(&p1, 1);
276  return result;
277 }
278 
279 static int DetectEngineHttpStatCodeTest03(void)
280 {
281  TcpSession ssn;
282  Packet *p1 = NULL;
283  Packet *p2 = NULL;
284  ThreadVars th_v;
285  DetectEngineCtx *de_ctx = NULL;
286  DetectEngineThreadCtx *det_ctx = NULL;
287  HtpState *http_state = NULL;
288  Flow f;
289  int result = 0;
290  uint8_t http_buf1[] =
291  "GET /index.html HTTP/1.0\r\n"
292  "Host: www.openinfosecfoundation.org\r\n"
293  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
294  "\r\n";
295  uint32_t http_len1 = sizeof(http_buf1) - 1;
296  uint8_t http_buf2[] =
297  "HTTP/1.0 123";
298  uint32_t http_len2 = sizeof(http_buf2) - 1;
299  uint8_t http_buf3[] =
300  "456789\r\n"
301  "Content-Type: text/html\r\n"
302  "Content-Length: 17\r\n"
303  "\r\n"
304  "12345678901234ABC";
305  uint32_t http_len3 = sizeof(http_buf3) - 1;
307 
308  memset(&th_v, 0, sizeof(th_v));
309  memset(&f, 0, sizeof(f));
310  memset(&ssn, 0, sizeof(ssn));
311 
312  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
313  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
314 
315  FLOW_INITIALIZE(&f);
316  f.protoctx = (void *)&ssn;
317  f.proto = IPPROTO_TCP;
318  f.flags |= FLOW_IPV4;
319 
320  p1->flow = &f;
324  p2->flow = &f;
328  f.alproto = ALPROTO_HTTP;
329 
331 
332  de_ctx = DetectEngineCtxInit();
333  if (de_ctx == NULL)
334  goto end;
335 
336  de_ctx->flags |= DE_QUIET;
337 
338  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
339  "(msg:\"http stat code test\"; "
340  "content:\"789\"; http_stat_code; offset:5; "
341  "sid:1;)");
342  if (de_ctx->sig_list == NULL)
343  goto end;
344 
345  SigGroupBuild(de_ctx);
346  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
347 
348  FLOWLOCK_WRLOCK(&f);
349  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
350  STREAM_TOSERVER, http_buf1, http_len1);
351  if (r != 0) {
352  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
353  result = 0;
354  FLOWLOCK_UNLOCK(&f);
355  goto end;
356  }
357  FLOWLOCK_UNLOCK(&f);
358 
359  http_state = f.alstate;
360  if (http_state == NULL) {
361  printf("no http state: \n");
362  result = 0;
363  goto end;
364  }
365 
366  /* do detect */
367  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
368 
369  if (PacketAlertCheck(p1, 1)) {
370  printf("sid 1 matched but shouldn't have\n");
371  goto end;
372  }
373 
374  FLOWLOCK_WRLOCK(&f);
375  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
376  STREAM_TOCLIENT, http_buf2, http_len2);
377  if (r != 0) {
378  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
379  result = 0;
380  FLOWLOCK_UNLOCK(&f);
381  goto end;
382  }
383  FLOWLOCK_UNLOCK(&f);
384 
385  FLOWLOCK_WRLOCK(&f);
386  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
387  STREAM_TOCLIENT, http_buf3, http_len3);
388  if (r != 0) {
389  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
390  result = 0;
391  FLOWLOCK_UNLOCK(&f);
392  goto end;
393  }
394  FLOWLOCK_UNLOCK(&f);
395 
396  /* do detect */
397  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
398 
399  if (!(PacketAlertCheck(p2, 1))) {
400  printf("sid 1 didn't match but should have");
401  goto end;
402  }
403 
404  result = 1;
405 
406 end:
407  if (alp_tctx != NULL)
408  AppLayerParserThreadCtxFree(alp_tctx);
409  if (de_ctx != NULL)
410  DetectEngineCtxFree(de_ctx);
411 
413  FLOW_DESTROY(&f);
414  UTHFreePackets(&p1, 1);
415  UTHFreePackets(&p2, 1);
416  return result;
417 }
418 
419 static int DetectEngineHttpStatCodeTest04(void)
420 {
421  TcpSession ssn;
422  Packet *p1 = NULL;
423  Packet *p2 = NULL;
424  ThreadVars th_v;
425  DetectEngineCtx *de_ctx = NULL;
426  DetectEngineThreadCtx *det_ctx = NULL;
427  HtpState *http_state = NULL;
428  Flow f;
429  uint8_t http_buf1[] =
430  "GET /index.html HTTP/1.0\r\n"
431  "Host: www.openinfosecfoundation.org\r\n"
432  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
433  "\r\n";
434  uint32_t http_len1 = sizeof(http_buf1) - 1;
435  uint8_t http_buf2[] =
436  "HTTP/1.0 200123 abcdef\r\n"
437  "Content-Type: text/html\r\n"
438  "Content-Length: 6\r\n"
439  "\r\n"
440  "abcdef";
441  uint32_t http_len2 = sizeof(http_buf2) - 1;
442  int result = 0;
444 
445  memset(&th_v, 0, sizeof(th_v));
446  memset(&f, 0, sizeof(f));
447  memset(&ssn, 0, sizeof(ssn));
448 
449  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
450  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
451 
452  FLOW_INITIALIZE(&f);
453  f.protoctx = (void *)&ssn;
454  f.proto = IPPROTO_TCP;
455  f.flags |= FLOW_IPV4;
456 
457  p1->flow = &f;
461  p2->flow = &f;
465  f.alproto = ALPROTO_HTTP;
466 
468 
469  de_ctx = DetectEngineCtxInit();
470  if (de_ctx == NULL)
471  goto end;
472 
473  de_ctx->flags |= DE_QUIET;
474 
475  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
476  "(msg:\"http stat code test\"; "
477  "content:!\"200\"; http_stat_code; offset:3; "
478  "sid:1;)");
479  if (de_ctx->sig_list == NULL)
480  goto end;
481 
482  SigGroupBuild(de_ctx);
483  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
484 
485  FLOWLOCK_WRLOCK(&f);
486  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
487  STREAM_TOSERVER, http_buf1, http_len1);
488  if (r != 0) {
489  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
490  result = 0;
491  FLOWLOCK_UNLOCK(&f);
492  goto end;
493  }
494  FLOWLOCK_UNLOCK(&f);
495 
496  http_state = f.alstate;
497  if (http_state == NULL) {
498  printf("no http state: \n");
499  result = 0;
500  goto end;
501  }
502 
503  /* do detect */
504  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
505 
506  if (PacketAlertCheck(p1, 1)) {
507  printf("sid 1 matched but shouldn't have: ");
508  goto end;
509  }
510 
511  FLOWLOCK_WRLOCK(&f);
512  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
513  STREAM_TOCLIENT, http_buf2, http_len2);
514  if (r != 0) {
515  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
516  result = 0;
517  FLOWLOCK_UNLOCK(&f);
518  goto end;
519  }
520  FLOWLOCK_UNLOCK(&f);
521 
522  /* do detect */
523  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
524 
525  if (!PacketAlertCheck(p2, 1)) {
526  printf("sid 1 didn't match but should have: ");
527  goto end;
528  }
529 
530  result = 1;
531 
532 end:
533  if (alp_tctx != NULL)
534  AppLayerParserThreadCtxFree(alp_tctx);
535  if (de_ctx != NULL)
536  DetectEngineCtxFree(de_ctx);
537 
539  FLOW_DESTROY(&f);
540  UTHFreePackets(&p1, 1);
541  UTHFreePackets(&p2, 1);
542  return result;
543 }
544 
545 static int DetectEngineHttpStatCodeTest05(void)
546 {
547  TcpSession ssn;
548  Packet *p1 = NULL;
549  Packet *p2 = NULL;
550  ThreadVars th_v;
551  DetectEngineCtx *de_ctx = NULL;
552  DetectEngineThreadCtx *det_ctx = NULL;
553  HtpState *http_state = NULL;
554  Flow f;
555  uint8_t http_buf1[] =
556  "GET /index.html HTTP/1.0\r\n"
557  "Host: www.openinfosecfoundation.org\r\n"
558  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
559  "\r\n";
560  uint32_t http_len1 = sizeof(http_buf1) - 1;
561  uint8_t http_buf2[] =
562  "HTTP/1.0 200123 abcdef\r\n"
563  "Content-Type: text/html\r\n"
564  "Content-Length: 6\r\n"
565  "\r\n"
566  "abcdef";
567  uint32_t http_len2 = sizeof(http_buf2) - 1;
568  int result = 0;
570 
571  memset(&th_v, 0, sizeof(th_v));
572  memset(&f, 0, sizeof(f));
573  memset(&ssn, 0, sizeof(ssn));
574 
575  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
576  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
577 
578  FLOW_INITIALIZE(&f);
579  f.protoctx = (void *)&ssn;
580  f.proto = IPPROTO_TCP;
581  f.flags |= FLOW_IPV4;
582 
583  p1->flow = &f;
587  p2->flow = &f;
591  f.alproto = ALPROTO_HTTP;
592 
594 
595  de_ctx = DetectEngineCtxInit();
596  if (de_ctx == NULL)
597  goto end;
598 
599  de_ctx->flags |= DE_QUIET;
600 
601  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
602  "(msg:\"http stat code test\"; "
603  "content:\"200\"; http_stat_code; depth:3; "
604  "sid:1;)");
605  if (de_ctx->sig_list == NULL)
606  goto end;
607 
608  SigGroupBuild(de_ctx);
609  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
610 
611  FLOWLOCK_WRLOCK(&f);
612  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
613  STREAM_TOSERVER, http_buf1, http_len1);
614  if (r != 0) {
615  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
616  result = 0;
617  FLOWLOCK_UNLOCK(&f);
618  goto end;
619  }
620  FLOWLOCK_UNLOCK(&f);
621 
622  http_state = f.alstate;
623  if (http_state == NULL) {
624  printf("no http state: \n");
625  result = 0;
626  goto end;
627  }
628 
629  /* do detect */
630  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
631 
632  if (PacketAlertCheck(p1, 1)) {
633  printf("sid 1 matched but shouldn't have: ");
634  goto end;
635  }
636 
637  FLOWLOCK_WRLOCK(&f);
638  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
639  STREAM_TOCLIENT, http_buf2, http_len2);
640  if (r != 0) {
641  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
642  result = 0;
643  FLOWLOCK_UNLOCK(&f);
644  goto end;
645  }
646  FLOWLOCK_UNLOCK(&f);
647 
648  /* do detect */
649  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
650 
651  if (!PacketAlertCheck(p2, 1)) {
652  printf("sid 1 didn't match but should have: ");
653  goto end;
654  }
655 
656  result = 1;
657 
658 end:
659  if (alp_tctx != NULL)
660  AppLayerParserThreadCtxFree(alp_tctx);
661  if (de_ctx != NULL)
662  DetectEngineCtxFree(de_ctx);
663 
665  FLOW_DESTROY(&f);
666  UTHFreePackets(&p1, 1);
667  UTHFreePackets(&p2, 1);
668  return result;
669 }
670 
671 static int DetectEngineHttpStatCodeTest06(void)
672 {
673  TcpSession ssn;
674  Packet *p1 = NULL;
675  Packet *p2 = NULL;
676  ThreadVars th_v;
677  DetectEngineCtx *de_ctx = NULL;
678  DetectEngineThreadCtx *det_ctx = NULL;
679  HtpState *http_state = NULL;
680  Flow f;
681  uint8_t http_buf1[] =
682  "GET /index.html HTTP/1.0\r\n"
683  "Host: www.openinfosecfoundation.org\r\n"
684  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
685  "\r\n";
686  uint32_t http_len1 = sizeof(http_buf1) - 1;
687  uint8_t http_buf2[] =
688  "HTTP/1.0 200123 abcdef\r\n"
689  "Content-Type: text/html\r\n"
690  "Content-Length: 6\r\n"
691  "\r\n"
692  "abcdef";
693  uint32_t http_len2 = sizeof(http_buf2) - 1;
694  int result = 0;
696 
697  memset(&th_v, 0, sizeof(th_v));
698  memset(&f, 0, sizeof(f));
699  memset(&ssn, 0, sizeof(ssn));
700 
701  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
702  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
703 
704  FLOW_INITIALIZE(&f);
705  f.protoctx = (void *)&ssn;
706  f.proto = IPPROTO_TCP;
707  f.flags |= FLOW_IPV4;
708 
709  p1->flow = &f;
713  p2->flow = &f;
717  f.alproto = ALPROTO_HTTP;
718 
720 
721  de_ctx = DetectEngineCtxInit();
722  if (de_ctx == NULL)
723  goto end;
724 
725  de_ctx->flags |= DE_QUIET;
726 
727  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
728  "(msg:\"http stat code test\"; "
729  "content:!\"123\"; http_stat_code; depth:3; "
730  "sid:1;)");
731  if (de_ctx->sig_list == NULL)
732  goto end;
733 
734  SigGroupBuild(de_ctx);
735  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
736 
737  FLOWLOCK_WRLOCK(&f);
738  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
739  STREAM_TOSERVER, http_buf1, http_len1);
740  if (r != 0) {
741  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
742  result = 0;
743  FLOWLOCK_UNLOCK(&f);
744  goto end;
745  }
746  FLOWLOCK_UNLOCK(&f);
747 
748  http_state = f.alstate;
749  if (http_state == NULL) {
750  printf("no http state: \n");
751  result = 0;
752  goto end;
753  }
754 
755  /* do detect */
756  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
757 
758  if (PacketAlertCheck(p1, 1)) {
759  printf("sid 1 matched but shouldn't have: ");
760  goto end;
761  }
762 
763  FLOWLOCK_WRLOCK(&f);
764  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
765  STREAM_TOCLIENT, http_buf2, http_len2);
766  if (r != 0) {
767  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
768  result = 0;
769  FLOWLOCK_UNLOCK(&f);
770  goto end;
771  }
772  FLOWLOCK_UNLOCK(&f);
773 
774  /* do detect */
775  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
776 
777  if (!PacketAlertCheck(p2, 1)) {
778  printf("sid 1 didn't match but should have: ");
779  goto end;
780  }
781 
782  result = 1;
783 
784 end:
785  if (alp_tctx != NULL)
786  AppLayerParserThreadCtxFree(alp_tctx);
787  if (de_ctx != NULL)
788  DetectEngineCtxFree(de_ctx);
789 
791  FLOW_DESTROY(&f);
792  UTHFreePackets(&p1, 1);
793  UTHFreePackets(&p2, 1);
794  return result;
795 }
796 
797 static int DetectEngineHttpStatCodeTest07(void)
798 {
799  TcpSession ssn;
800  Packet *p1 = NULL;
801  Packet *p2 = NULL;
802  ThreadVars th_v;
803  DetectEngineCtx *de_ctx = NULL;
804  DetectEngineThreadCtx *det_ctx = NULL;
805  HtpState *http_state = NULL;
806  Flow f;
807  uint8_t http_buf1[] =
808  "GET /index.html HTTP/1.0\r\n"
809  "Host: www.openinfosecfoundation.org\r\n"
810  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
811  "\r\n";
812  uint32_t http_len1 = sizeof(http_buf1) - 1;
813  uint8_t http_buf2[] =
814  "HTTP/1.0 200123 abcdef\r\n"
815  "Content-Type: text/html\r\n"
816  "Content-Length: 6\r\n"
817  "\r\n"
818  "abcdef";
819  uint32_t http_len2 = sizeof(http_buf2) - 1;
820  int result = 0;
822 
823  memset(&th_v, 0, sizeof(th_v));
824  memset(&f, 0, sizeof(f));
825  memset(&ssn, 0, sizeof(ssn));
826 
827  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
828  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
829 
830  FLOW_INITIALIZE(&f);
831  f.protoctx = (void *)&ssn;
832  f.proto = IPPROTO_TCP;
833  f.flags |= FLOW_IPV4;
834 
835  p1->flow = &f;
839  p2->flow = &f;
843  f.alproto = ALPROTO_HTTP;
844 
846 
847  de_ctx = DetectEngineCtxInit();
848  if (de_ctx == NULL)
849  goto end;
850 
851  de_ctx->flags |= DE_QUIET;
852 
853  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
854  "(msg:\"http stat code test\"; "
855  "content:!\"123\"; http_stat_code; offset:3; "
856  "sid:1;)");
857  if (de_ctx->sig_list == NULL)
858  goto end;
859 
860  SigGroupBuild(de_ctx);
861  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
862 
863  FLOWLOCK_WRLOCK(&f);
864  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
865  STREAM_TOSERVER, http_buf1, http_len1);
866  if (r != 0) {
867  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
868  result = 0;
869  FLOWLOCK_UNLOCK(&f);
870  goto end;
871  }
872  FLOWLOCK_UNLOCK(&f);
873 
874  http_state = f.alstate;
875  if (http_state == NULL) {
876  printf("no http state: \n");
877  result = 0;
878  goto end;
879  }
880 
881  /* do detect */
882  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
883 
884  if (PacketAlertCheck(p1, 1)) {
885  printf("sid 1 matched but shouldn't have: ");
886  goto end;
887  }
888 
889  FLOWLOCK_WRLOCK(&f);
890  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
891  STREAM_TOCLIENT, http_buf2, http_len2);
892  if (r != 0) {
893  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
894  result = 0;
895  FLOWLOCK_UNLOCK(&f);
896  goto end;
897  }
898  FLOWLOCK_UNLOCK(&f);
899 
900  /* do detect */
901  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
902 
903  if (PacketAlertCheck(p2, 1)) {
904  printf("sid 1 matched but shouldn't have: ");
905  goto end;
906  }
907 
908  result = 1;
909 
910 end:
911  if (alp_tctx != NULL)
912  AppLayerParserThreadCtxFree(alp_tctx);
913  if (de_ctx != NULL)
914  DetectEngineCtxFree(de_ctx);
915 
917  FLOW_DESTROY(&f);
918  UTHFreePackets(&p1, 1);
919  UTHFreePackets(&p2, 1);
920  return result;
921 }
922 
923 static int DetectEngineHttpStatCodeTest08(void)
924 {
925  TcpSession ssn;
926  Packet *p1 = NULL;
927  Packet *p2 = NULL;
928  ThreadVars th_v;
929  DetectEngineCtx *de_ctx = NULL;
930  DetectEngineThreadCtx *det_ctx = NULL;
931  HtpState *http_state = NULL;
932  Flow f;
933  uint8_t http_buf1[] =
934  "GET /index.html HTTP/1.0\r\n"
935  "Host: www.openinfosecfoundation.org\r\n"
936  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
937  "\r\n";
938  uint32_t http_len1 = sizeof(http_buf1) - 1;
939  uint8_t http_buf2[] =
940  "HTTP/1.0 200123 abcdef\r\n"
941  "Content-Type: text/html\r\n"
942  "Content-Length: 6\r\n"
943  "\r\n"
944  "abcdef";
945  uint32_t http_len2 = sizeof(http_buf2) - 1;
946  int result = 0;
948 
949  memset(&th_v, 0, sizeof(th_v));
950  memset(&f, 0, sizeof(f));
951  memset(&ssn, 0, sizeof(ssn));
952 
953  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
954  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
955 
956  FLOW_INITIALIZE(&f);
957  f.protoctx = (void *)&ssn;
958  f.proto = IPPROTO_TCP;
959  f.flags |= FLOW_IPV4;
960 
961  p1->flow = &f;
965  p2->flow = &f;
969  f.alproto = ALPROTO_HTTP;
970 
972 
973  de_ctx = DetectEngineCtxInit();
974  if (de_ctx == NULL)
975  goto end;
976 
977  de_ctx->flags |= DE_QUIET;
978 
979  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
980  "(msg:\"http stat code test\"; "
981  "content:!\"200\"; http_stat_code; depth:3; "
982  "sid:1;)");
983  if (de_ctx->sig_list == NULL)
984  goto end;
985 
986  SigGroupBuild(de_ctx);
987  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
988 
989  FLOWLOCK_WRLOCK(&f);
990  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
991  STREAM_TOSERVER, http_buf1, http_len1);
992  if (r != 0) {
993  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
994  result = 0;
995  FLOWLOCK_UNLOCK(&f);
996  goto end;
997  }
998  FLOWLOCK_UNLOCK(&f);
999 
1000  http_state = f.alstate;
1001  if (http_state == NULL) {
1002  printf("no http state: \n");
1003  result = 0;
1004  goto end;
1005  }
1006 
1007  /* do detect */
1008  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1009 
1010  if (PacketAlertCheck(p1, 1)) {
1011  printf("sid 1 matched but shouldn't have: ");
1012  goto end;
1013  }
1014 
1015  FLOWLOCK_WRLOCK(&f);
1016  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1017  STREAM_TOCLIENT, http_buf2, http_len2);
1018  if (r != 0) {
1019  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1020  result = 0;
1021  FLOWLOCK_UNLOCK(&f);
1022  goto end;
1023  }
1024  FLOWLOCK_UNLOCK(&f);
1025 
1026  /* do detect */
1027  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1028 
1029  if (PacketAlertCheck(p2, 1)) {
1030  printf("sid 1 matched but shouldn't have: ");
1031  goto end;
1032  }
1033 
1034  result = 1;
1035 
1036 end:
1037  if (alp_tctx != NULL)
1038  AppLayerParserThreadCtxFree(alp_tctx);
1039  if (de_ctx != NULL)
1040  DetectEngineCtxFree(de_ctx);
1041 
1043  FLOW_DESTROY(&f);
1044  UTHFreePackets(&p1, 1);
1045  UTHFreePackets(&p2, 1);
1046  return result;
1047 }
1048 
1049 static int DetectEngineHttpStatCodeTest09(void)
1050 {
1051  TcpSession ssn;
1052  Packet *p1 = NULL;
1053  Packet *p2 = NULL;
1054  ThreadVars th_v;
1055  DetectEngineCtx *de_ctx = NULL;
1056  DetectEngineThreadCtx *det_ctx = NULL;
1057  HtpState *http_state = NULL;
1058  Flow f;
1059  uint8_t http_buf1[] =
1060  "GET /index.html HTTP/1.0\r\n"
1061  "Host: www.openinfosecfoundation.org\r\n"
1062  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1063  "\r\n";
1064  uint32_t http_len1 = sizeof(http_buf1) - 1;
1065  uint8_t http_buf2[] =
1066  "HTTP/1.0 200123 abcdef\r\n"
1067  "Content-Type: text/html\r\n"
1068  "Content-Length: 6\r\n"
1069  "\r\n"
1070  "abcdef";
1071  uint32_t http_len2 = sizeof(http_buf2) - 1;
1072  int result = 0;
1074 
1075  memset(&th_v, 0, sizeof(th_v));
1076  memset(&f, 0, sizeof(f));
1077  memset(&ssn, 0, sizeof(ssn));
1078 
1079  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1080  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1081 
1082  FLOW_INITIALIZE(&f);
1083  f.protoctx = (void *)&ssn;
1084  f.proto = IPPROTO_TCP;
1085  f.flags |= FLOW_IPV4;
1086 
1087  p1->flow = &f;
1091  p2->flow = &f;
1095  f.alproto = ALPROTO_HTTP;
1096 
1098 
1099  de_ctx = DetectEngineCtxInit();
1100  if (de_ctx == NULL)
1101  goto end;
1102 
1103  de_ctx->flags |= DE_QUIET;
1104 
1105  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1106  "(msg:\"http stat code test\"; "
1107  "content:\"200\"; http_stat_code; depth:3; "
1108  "content:\"123\"; http_stat_code; within:3; "
1109  "sid:1;)");
1110  if (de_ctx->sig_list == NULL)
1111  goto end;
1112 
1113  SigGroupBuild(de_ctx);
1114  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1115 
1116  FLOWLOCK_WRLOCK(&f);
1117  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1118  STREAM_TOSERVER, http_buf1, http_len1);
1119  if (r != 0) {
1120  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1121  result = 0;
1122  FLOWLOCK_UNLOCK(&f);
1123  goto end;
1124  }
1125  FLOWLOCK_UNLOCK(&f);
1126 
1127  http_state = f.alstate;
1128  if (http_state == NULL) {
1129  printf("no http state: \n");
1130  result = 0;
1131  goto end;
1132  }
1133 
1134  /* do detect */
1135  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1136 
1137  if (PacketAlertCheck(p1, 1)) {
1138  printf("sid 1 matched but shouldn't have: ");
1139  goto end;
1140  }
1141 
1142  FLOWLOCK_WRLOCK(&f);
1143  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1144  STREAM_TOCLIENT, http_buf2, http_len2);
1145  if (r != 0) {
1146  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1147  result = 0;
1148  FLOWLOCK_UNLOCK(&f);
1149  goto end;
1150  }
1151  FLOWLOCK_UNLOCK(&f);
1152 
1153  /* do detect */
1154  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1155 
1156  if (!PacketAlertCheck(p2, 1)) {
1157  printf("sid 1 didn't match but should have: ");
1158  goto end;
1159  }
1160 
1161  result = 1;
1162 
1163 end:
1164  if (alp_tctx != NULL)
1165  AppLayerParserThreadCtxFree(alp_tctx);
1166  if (de_ctx != NULL)
1167  DetectEngineCtxFree(de_ctx);
1168 
1170  FLOW_DESTROY(&f);
1171  UTHFreePackets(&p1, 1);
1172  UTHFreePackets(&p2, 1);
1173  return result;
1174 }
1175 
1176 static int DetectEngineHttpStatCodeTest10(void)
1177 {
1178  TcpSession ssn;
1179  Packet *p1 = NULL;
1180  Packet *p2 = NULL;
1181  ThreadVars th_v;
1182  DetectEngineCtx *de_ctx = NULL;
1183  DetectEngineThreadCtx *det_ctx = NULL;
1184  HtpState *http_state = NULL;
1185  Flow f;
1186  uint8_t http_buf1[] =
1187  "GET /index.html HTTP/1.0\r\n"
1188  "Host: www.openinfosecfoundation.org\r\n"
1189  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1190  "\r\n";
1191  uint32_t http_len1 = sizeof(http_buf1) - 1;
1192  uint8_t http_buf2[] =
1193  "HTTP/1.0 200123 abcdef\r\n"
1194  "Content-Type: text/html\r\n"
1195  "Content-Length: 6\r\n"
1196  "\r\n"
1197  "abcdef";
1198  uint32_t http_len2 = sizeof(http_buf2) - 1;
1199  int result = 0;
1201 
1202  memset(&th_v, 0, sizeof(th_v));
1203  memset(&f, 0, sizeof(f));
1204  memset(&ssn, 0, sizeof(ssn));
1205 
1206  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1207  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1208 
1209  FLOW_INITIALIZE(&f);
1210  f.protoctx = (void *)&ssn;
1211  f.proto = IPPROTO_TCP;
1212  f.flags |= FLOW_IPV4;
1213 
1214  p1->flow = &f;
1218  p2->flow = &f;
1222  f.alproto = ALPROTO_HTTP;
1223 
1225 
1226  de_ctx = DetectEngineCtxInit();
1227  if (de_ctx == NULL)
1228  goto end;
1229 
1230  de_ctx->flags |= DE_QUIET;
1231 
1232  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1233  "(msg:\"http stat code test\"; "
1234  "content:\"200\"; http_stat_code; depth:3; "
1235  "content:!\"124\"; http_stat_code; within:3; "
1236  "sid:1;)");
1237  if (de_ctx->sig_list == NULL)
1238  goto end;
1239 
1240  SigGroupBuild(de_ctx);
1241  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1242 
1243  FLOWLOCK_WRLOCK(&f);
1244  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1245  STREAM_TOSERVER, http_buf1, http_len1);
1246  if (r != 0) {
1247  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1248  result = 0;
1249  FLOWLOCK_UNLOCK(&f);
1250  goto end;
1251  }
1252  FLOWLOCK_UNLOCK(&f);
1253 
1254  http_state = f.alstate;
1255  if (http_state == NULL) {
1256  printf("no http state: \n");
1257  result = 0;
1258  goto end;
1259  }
1260 
1261  /* do detect */
1262  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1263 
1264  if (PacketAlertCheck(p1, 1)) {
1265  printf("sid 1 matched but shouldn't have: ");
1266  goto end;
1267  }
1268 
1269  FLOWLOCK_WRLOCK(&f);
1270  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1271  STREAM_TOCLIENT, http_buf2, http_len2);
1272  if (r != 0) {
1273  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1274  result = 0;
1275  FLOWLOCK_UNLOCK(&f);
1276  goto end;
1277  }
1278  FLOWLOCK_UNLOCK(&f);
1279 
1280  /* do detect */
1281  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1282 
1283  if (!PacketAlertCheck(p2, 1)) {
1284  printf("sid 1 didn't match but should have: ");
1285  goto end;
1286  }
1287 
1288  result = 1;
1289 
1290 end:
1291  if (alp_tctx != NULL)
1292  AppLayerParserThreadCtxFree(alp_tctx);
1293  if (de_ctx != NULL)
1294  DetectEngineCtxFree(de_ctx);
1295 
1297  FLOW_DESTROY(&f);
1298  UTHFreePackets(&p1, 1);
1299  UTHFreePackets(&p2, 1);
1300  return result;
1301 }
1302 
1303 static int DetectEngineHttpStatCodeTest11(void)
1304 {
1305  TcpSession ssn;
1306  Packet *p1 = NULL;
1307  Packet *p2 = NULL;
1308  ThreadVars th_v;
1309  DetectEngineCtx *de_ctx = NULL;
1310  DetectEngineThreadCtx *det_ctx = NULL;
1311  HtpState *http_state = NULL;
1312  Flow f;
1313  uint8_t http_buf1[] =
1314  "GET /index.html HTTP/1.0\r\n"
1315  "Host: www.openinfosecfoundation.org\r\n"
1316  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1317  "\r\n";
1318  uint32_t http_len1 = sizeof(http_buf1) - 1;
1319  uint8_t http_buf2[] =
1320  "HTTP/1.0 200123 abcdef\r\n"
1321  "Content-Type: text/html\r\n"
1322  "Content-Length: 6\r\n"
1323  "\r\n"
1324  "abcdef";
1325  uint32_t http_len2 = sizeof(http_buf2) - 1;
1326  int result = 0;
1328 
1329  memset(&th_v, 0, sizeof(th_v));
1330  memset(&f, 0, sizeof(f));
1331  memset(&ssn, 0, sizeof(ssn));
1332 
1333  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1334  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1335 
1336  FLOW_INITIALIZE(&f);
1337  f.protoctx = (void *)&ssn;
1338  f.proto = IPPROTO_TCP;
1339  f.flags |= FLOW_IPV4;
1340 
1341  p1->flow = &f;
1345  p2->flow = &f;
1349  f.alproto = ALPROTO_HTTP;
1350 
1352 
1353  de_ctx = DetectEngineCtxInit();
1354  if (de_ctx == NULL)
1355  goto end;
1356 
1357  de_ctx->flags |= DE_QUIET;
1358 
1359  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1360  "(msg:\"http stat code test\"; "
1361  "content:\"200\"; http_stat_code; depth:3; "
1362  "content:\"124\"; http_stat_code; within:3; "
1363  "sid:1;)");
1364  if (de_ctx->sig_list == NULL)
1365  goto end;
1366 
1367  SigGroupBuild(de_ctx);
1368  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1369 
1370  FLOWLOCK_WRLOCK(&f);
1371  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1372  STREAM_TOSERVER, http_buf1, http_len1);
1373  if (r != 0) {
1374  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1375  result = 0;
1376  FLOWLOCK_UNLOCK(&f);
1377  goto end;
1378  }
1379  FLOWLOCK_UNLOCK(&f);
1380 
1381  http_state = f.alstate;
1382  if (http_state == NULL) {
1383  printf("no http state: \n");
1384  result = 0;
1385  goto end;
1386  }
1387 
1388  /* do detect */
1389  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1390 
1391  if (PacketAlertCheck(p1, 1)) {
1392  printf("sid 1 matched but shouldn't have: ");
1393  goto end;
1394  }
1395 
1396  FLOWLOCK_WRLOCK(&f);
1397  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1398  STREAM_TOCLIENT, http_buf2, http_len2);
1399  if (r != 0) {
1400  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1401  result = 0;
1402  FLOWLOCK_UNLOCK(&f);
1403  goto end;
1404  }
1405  FLOWLOCK_UNLOCK(&f);
1406 
1407  /* do detect */
1408  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1409 
1410  if (PacketAlertCheck(p2, 1)) {
1411  printf("sid 1 did match but should not have: ");
1412  goto end;
1413  }
1414 
1415  result = 1;
1416 
1417 end:
1418  if (alp_tctx != NULL)
1419  AppLayerParserThreadCtxFree(alp_tctx);
1420  if (de_ctx != NULL)
1421  DetectEngineCtxFree(de_ctx);
1422 
1424  FLOW_DESTROY(&f);
1425  UTHFreePackets(&p1, 1);
1426  UTHFreePackets(&p2, 1);
1427  return result;
1428 }
1429 
1430 static int DetectEngineHttpStatCodeTest12(void)
1431 {
1432  TcpSession ssn;
1433  Packet *p1 = NULL;
1434  Packet *p2 = NULL;
1435  ThreadVars th_v;
1436  DetectEngineCtx *de_ctx = NULL;
1437  DetectEngineThreadCtx *det_ctx = NULL;
1438  HtpState *http_state = NULL;
1439  Flow f;
1440  uint8_t http_buf1[] =
1441  "GET /index.html HTTP/1.0\r\n"
1442  "Host: www.openinfosecfoundation.org\r\n"
1443  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1444  "\r\n";
1445  uint32_t http_len1 = sizeof(http_buf1) - 1;
1446  uint8_t http_buf2[] =
1447  "HTTP/1.0 200123 abcdef\r\n"
1448  "Content-Type: text/html\r\n"
1449  "Content-Length: 6\r\n"
1450  "\r\n"
1451  "abcdef";
1452  uint32_t http_len2 = sizeof(http_buf2) - 1;
1453  int result = 0;
1455 
1456  memset(&th_v, 0, sizeof(th_v));
1457  memset(&f, 0, sizeof(f));
1458  memset(&ssn, 0, sizeof(ssn));
1459 
1460  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1461  p2 = 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 
1468  p1->flow = &f;
1472  p2->flow = &f;
1476  f.alproto = ALPROTO_HTTP;
1477 
1479 
1480  de_ctx = DetectEngineCtxInit();
1481  if (de_ctx == NULL)
1482  goto end;
1483 
1484  de_ctx->flags |= DE_QUIET;
1485 
1486  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1487  "(msg:\"http stat code test\"; "
1488  "content:\"20\"; http_stat_code; depth:2; "
1489  "content:\"23\"; http_stat_code; distance:2; "
1490  "sid:1;)");
1491  if (de_ctx->sig_list == NULL)
1492  goto end;
1493 
1494  SigGroupBuild(de_ctx);
1495  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1496 
1497  FLOWLOCK_WRLOCK(&f);
1498  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1499  STREAM_TOSERVER, http_buf1, http_len1);
1500  if (r != 0) {
1501  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1502  result = 0;
1503  FLOWLOCK_UNLOCK(&f);
1504  goto end;
1505  }
1506  FLOWLOCK_UNLOCK(&f);
1507 
1508  http_state = f.alstate;
1509  if (http_state == NULL) {
1510  printf("no http state: \n");
1511  result = 0;
1512  goto end;
1513  }
1514 
1515  /* do detect */
1516  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1517 
1518  if (PacketAlertCheck(p1, 1)) {
1519  printf("sid 1 matched but shouldn't have: ");
1520  goto end;
1521  }
1522 
1523  FLOWLOCK_WRLOCK(&f);
1524  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1525  STREAM_TOCLIENT, http_buf2, http_len2);
1526  if (r != 0) {
1527  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1528  result = 0;
1529  FLOWLOCK_UNLOCK(&f);
1530  goto end;
1531  }
1532  FLOWLOCK_UNLOCK(&f);
1533 
1534  /* do detect */
1535  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1536 
1537  if (!PacketAlertCheck(p2, 1)) {
1538  printf("sid 1 did not match but should have: ");
1539  goto end;
1540  }
1541 
1542  result = 1;
1543 
1544 end:
1545  if (alp_tctx != NULL)
1546  AppLayerParserThreadCtxFree(alp_tctx);
1547  if (de_ctx != NULL)
1548  DetectEngineCtxFree(de_ctx);
1549 
1551  FLOW_DESTROY(&f);
1552  UTHFreePackets(&p1, 1);
1553  UTHFreePackets(&p2, 1);
1554  return result;
1555 }
1556 
1557 static int DetectEngineHttpStatCodeTest13(void)
1558 {
1559  TcpSession ssn;
1560  Packet *p1 = NULL;
1561  Packet *p2 = NULL;
1562  ThreadVars th_v;
1563  DetectEngineCtx *de_ctx = NULL;
1564  DetectEngineThreadCtx *det_ctx = NULL;
1565  HtpState *http_state = NULL;
1566  Flow f;
1567  uint8_t http_buf1[] =
1568  "GET /index.html HTTP/1.0\r\n"
1569  "Host: www.openinfosecfoundation.org\r\n"
1570  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1571  "\r\n";
1572  uint32_t http_len1 = sizeof(http_buf1) - 1;
1573  uint8_t http_buf2[] =
1574  "HTTP/1.0 200123 abcdef\r\n"
1575  "Content-Type: text/html\r\n"
1576  "Content-Length: 6\r\n"
1577  "\r\n"
1578  "abcdef";
1579  uint32_t http_len2 = sizeof(http_buf2) - 1;
1580  int result = 0;
1582 
1583  memset(&th_v, 0, sizeof(th_v));
1584  memset(&f, 0, sizeof(f));
1585  memset(&ssn, 0, sizeof(ssn));
1586 
1587  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1588  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1589 
1590  FLOW_INITIALIZE(&f);
1591  f.protoctx = (void *)&ssn;
1592  f.proto = IPPROTO_TCP;
1593  f.flags |= FLOW_IPV4;
1594 
1595  p1->flow = &f;
1599  p2->flow = &f;
1603  f.alproto = ALPROTO_HTTP;
1604 
1606 
1607  de_ctx = DetectEngineCtxInit();
1608  if (de_ctx == NULL)
1609  goto end;
1610 
1611  de_ctx->flags |= DE_QUIET;
1612 
1613  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1614  "(msg:\"http stat code test\"; "
1615  "content:\"20\"; http_stat_code; depth:3; "
1616  "content:!\"25\"; http_stat_code; distance:2; "
1617  "sid:1;)");
1618  if (de_ctx->sig_list == NULL)
1619  goto end;
1620 
1621  SigGroupBuild(de_ctx);
1622  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1623 
1624  FLOWLOCK_WRLOCK(&f);
1625  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1626  STREAM_TOSERVER, http_buf1, http_len1);
1627  if (r != 0) {
1628  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1629  result = 0;
1630  FLOWLOCK_UNLOCK(&f);
1631  goto end;
1632  }
1633  FLOWLOCK_UNLOCK(&f);
1634 
1635  http_state = f.alstate;
1636  if (http_state == NULL) {
1637  printf("no http state: \n");
1638  result = 0;
1639  goto end;
1640  }
1641 
1642  /* do detect */
1643  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1644 
1645  if (PacketAlertCheck(p1, 1)) {
1646  printf("sid 1 matched but shouldn't have: ");
1647  goto end;
1648  }
1649 
1650  FLOWLOCK_WRLOCK(&f);
1651  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1652  STREAM_TOCLIENT, http_buf2, http_len2);
1653  if (r != 0) {
1654  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1655  result = 0;
1656  FLOWLOCK_UNLOCK(&f);
1657  goto end;
1658  }
1659  FLOWLOCK_UNLOCK(&f);
1660 
1661  /* do detect */
1662  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1663 
1664  if (!PacketAlertCheck(p2, 1)) {
1665  printf("sid 1 did not match but should have: ");
1666  goto end;
1667  }
1668 
1669  result = 1;
1670 
1671 end:
1672  if (alp_tctx != NULL)
1673  AppLayerParserThreadCtxFree(alp_tctx);
1674  if (de_ctx != NULL)
1675  DetectEngineCtxFree(de_ctx);
1676 
1678  FLOW_DESTROY(&f);
1679  UTHFreePackets(&p1, 1);
1680  UTHFreePackets(&p2, 1);
1681  return result;
1682 }
1683 
1684 static int DetectEngineHttpStatCodeTest14(void)
1685 {
1686  TcpSession ssn;
1687  Packet *p1 = NULL;
1688  Packet *p2 = NULL;
1689  ThreadVars th_v;
1690  DetectEngineCtx *de_ctx = NULL;
1691  DetectEngineThreadCtx *det_ctx = NULL;
1692  HtpState *http_state = NULL;
1693  Flow f;
1694  uint8_t http_buf1[] =
1695  "GET /index.html HTTP/1.0\r\n"
1696  "Host: www.openinfosecfoundation.org\r\n"
1697  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1698  "\r\n";
1699  uint32_t http_len1 = sizeof(http_buf1) - 1;
1700  uint8_t http_buf2[] =
1701  "HTTP/1.0 200123 abcdef\r\n"
1702  "Content-Type: text/html\r\n"
1703  "Content-Length: 6\r\n"
1704  "\r\n"
1705  "abcdef";
1706  uint32_t http_len2 = sizeof(http_buf2) - 1;
1707  int result = 0;
1709 
1710  memset(&th_v, 0, sizeof(th_v));
1711  memset(&f, 0, sizeof(f));
1712  memset(&ssn, 0, sizeof(ssn));
1713 
1714  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1715  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1716 
1717  FLOW_INITIALIZE(&f);
1718  f.protoctx = (void *)&ssn;
1719  f.proto = IPPROTO_TCP;
1720  f.flags |= FLOW_IPV4;
1721 
1722  p1->flow = &f;
1726  p2->flow = &f;
1730  f.alproto = ALPROTO_HTTP;
1731 
1733 
1734  de_ctx = DetectEngineCtxInit();
1735  if (de_ctx == NULL)
1736  goto end;
1737 
1738  de_ctx->flags |= DE_QUIET;
1739 
1740  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1741  "(msg:\"http stat code test\"; "
1742  "pcre:/20/S; "
1743  "content:\"23\"; http_stat_code; distance:2; "
1744  "sid:1;)");
1745  if (de_ctx->sig_list == NULL)
1746  goto end;
1747 
1748  SigGroupBuild(de_ctx);
1749  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1750 
1751  FLOWLOCK_WRLOCK(&f);
1752  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1753  STREAM_TOSERVER, http_buf1, http_len1);
1754  if (r != 0) {
1755  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1756  result = 0;
1757  FLOWLOCK_UNLOCK(&f);
1758  goto end;
1759  }
1760  FLOWLOCK_UNLOCK(&f);
1761 
1762  http_state = f.alstate;
1763  if (http_state == NULL) {
1764  printf("no http state: \n");
1765  result = 0;
1766  goto end;
1767  }
1768 
1769  /* do detect */
1770  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1771 
1772  if (PacketAlertCheck(p1, 1)) {
1773  printf("sid 1 matched but shouldn't have: ");
1774  goto end;
1775  }
1776 
1777  FLOWLOCK_WRLOCK(&f);
1778  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1779  STREAM_TOCLIENT, http_buf2, http_len2);
1780  if (r != 0) {
1781  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1782  result = 0;
1783  FLOWLOCK_UNLOCK(&f);
1784  goto end;
1785  }
1786  FLOWLOCK_UNLOCK(&f);
1787 
1788  /* do detect */
1789  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1790 
1791  if (!PacketAlertCheck(p2, 1)) {
1792  printf("sid 1 did not match but should have: ");
1793  goto end;
1794  }
1795 
1796  result = 1;
1797 
1798 end:
1799  if (alp_tctx != NULL)
1800  AppLayerParserThreadCtxFree(alp_tctx);
1801  if (de_ctx != NULL)
1802  DetectEngineCtxFree(de_ctx);
1803 
1805  FLOW_DESTROY(&f);
1806  UTHFreePackets(&p1, 1);
1807  UTHFreePackets(&p2, 1);
1808  return result;
1809 }
1810 
1811 static int DetectEngineHttpStatCodeTest15(void)
1812 {
1813  TcpSession ssn;
1814  Packet *p1 = NULL;
1815  Packet *p2 = NULL;
1816  ThreadVars th_v;
1817  DetectEngineCtx *de_ctx = NULL;
1818  DetectEngineThreadCtx *det_ctx = NULL;
1819  HtpState *http_state = NULL;
1820  Flow f;
1821  uint8_t http_buf1[] =
1822  "GET /index.html HTTP/1.0\r\n"
1823  "Host: www.openinfosecfoundation.org\r\n"
1824  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1825  "\r\n";
1826  uint32_t http_len1 = sizeof(http_buf1) - 1;
1827  uint8_t http_buf2[] =
1828  "HTTP/1.0 200123 abcdef\r\n"
1829  "Content-Type: text/html\r\n"
1830  "Content-Length: 6\r\n"
1831  "\r\n"
1832  "abcdef";
1833  uint32_t http_len2 = sizeof(http_buf2) - 1;
1834  int result = 0;
1836 
1837  memset(&th_v, 0, sizeof(th_v));
1838  memset(&f, 0, sizeof(f));
1839  memset(&ssn, 0, sizeof(ssn));
1840 
1841  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1842  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1843 
1844  FLOW_INITIALIZE(&f);
1845  f.protoctx = (void *)&ssn;
1846  f.proto = IPPROTO_TCP;
1847  f.flags |= FLOW_IPV4;
1848 
1849  p1->flow = &f;
1853  p2->flow = &f;
1857  f.alproto = ALPROTO_HTTP;
1858 
1860 
1861  de_ctx = DetectEngineCtxInit();
1862  if (de_ctx == NULL)
1863  goto end;
1864 
1865  de_ctx->flags |= DE_QUIET;
1866 
1867  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1868  "(msg:\"http stat code test\"; "
1869  "pcre:/200/S; "
1870  "content:!\"124\"; http_stat_code; distance:0; within:3; "
1871  "sid:1;)");
1872  if (de_ctx->sig_list == NULL)
1873  goto end;
1874 
1875  SigGroupBuild(de_ctx);
1876  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1877 
1878  FLOWLOCK_WRLOCK(&f);
1879  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1880  STREAM_TOSERVER, http_buf1, http_len1);
1881  if (r != 0) {
1882  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1883  result = 0;
1884  FLOWLOCK_UNLOCK(&f);
1885  goto end;
1886  }
1887  FLOWLOCK_UNLOCK(&f);
1888 
1889  http_state = f.alstate;
1890  if (http_state == NULL) {
1891  printf("no http state: \n");
1892  result = 0;
1893  goto end;
1894  }
1895 
1896  /* do detect */
1897  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1898 
1899  if (PacketAlertCheck(p1, 1)) {
1900  printf("sid 1 matched but shouldn't have: ");
1901  goto end;
1902  }
1903 
1904  FLOWLOCK_WRLOCK(&f);
1905  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1906  STREAM_TOCLIENT, http_buf2, http_len2);
1907  if (r != 0) {
1908  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1909  result = 0;
1910  FLOWLOCK_UNLOCK(&f);
1911  goto end;
1912  }
1913  FLOWLOCK_UNLOCK(&f);
1914 
1915  /* do detect */
1916  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1917 
1918  if (!PacketAlertCheck(p2, 1)) {
1919  printf("sid 1 did not match but should have: ");
1920  goto end;
1921  }
1922 
1923  result = 1;
1924 
1925 end:
1926  if (alp_tctx != NULL)
1927  AppLayerParserThreadCtxFree(alp_tctx);
1928  if (de_ctx != NULL)
1929  DetectEngineCtxFree(de_ctx);
1930 
1932  FLOW_DESTROY(&f);
1933  UTHFreePackets(&p1, 1);
1934  UTHFreePackets(&p2, 1);
1935  return result;
1936 }
1937 
1938 /**
1939  * \test Checks if a http_stat_code is registered in a Signature, if content is not
1940  * specified in the signature or rawbyes is specified or fast_pattern is
1941  * provided in the signature.
1942  */
1943 static int DetectHttpStatCodeTest01(void)
1944 {
1945  DetectEngineCtx *de_ctx = NULL;
1946  int result = 0;
1947 
1948  if ((de_ctx = DetectEngineCtxInit()) == NULL) {
1949  printf("DetectEngineCtxInit failed: ");
1950  goto end;
1951  }
1952 
1953  de_ctx->flags |= DE_QUIET;
1954  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1955  "(msg:\"Testing http_stat_code\"; http_stat_code; sid:1;)");
1956  if (de_ctx->sig_list != NULL) {
1957  printf("sid 1 parse failed to error out: ");
1958  goto end;
1959  }
1960 
1961  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1962  "(msg:\"Testing http_stat_code\"; content:\"|FF F1|\";"
1963  " rawbytes; http_stat_code; sid:2;)");
1964  if (de_ctx->sig_list != NULL) {
1965  printf("sid 2 parse failed to error out: ");
1966  goto end;
1967  }
1968 
1969  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1970  "(msg:\"Testing http_stat_code\"; content:\"100\";"
1971  "fast_pattern; http_stat_code; sid:3;)");
1972  if (de_ctx->sig_list == NULL) {
1973  printf("sid 3 parse failed: ");
1974  goto end;
1975  }
1976  if (!(((DetectContentData *)de_ctx->sig_list->sm_lists[g_http_stat_code_buffer_id]->ctx)->flags &
1978  {
1979  goto end;
1980  }
1981 
1982  result = 1;
1983 end:
1984  if (de_ctx != NULL)
1985  DetectEngineCtxFree(de_ctx);
1986  return result;
1987 }
1988 
1989 /**
1990  * \test Checks if a http_stat_code is registered in a Signature and also checks
1991  * the nocase
1992  */
1993 static int DetectHttpStatCodeTest02(void)
1994 {
1995  SigMatch *sm = NULL;
1996  DetectEngineCtx *de_ctx = NULL;
1997  int result = 0;
1998 
1999  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2000  goto end;
2001 
2002  de_ctx->flags |= DE_QUIET;
2003  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2004  "(msg:\"Testing http_stat_code\"; content:\"one\"; "
2005  "http_stat_code; content:\"200\"; http_stat_code; "
2006  "content:\"two hundred\"; nocase; http_stat_code; "
2007  "sid:1;)");
2008  if (de_ctx->sig_list == NULL) {
2009  printf("sig parse failed: ");
2010  goto end;
2011  }
2012 
2013  result = 0;
2014  sm = de_ctx->sig_list->sm_lists[g_http_stat_code_buffer_id];
2015  if (sm == NULL) {
2016  printf("no sigmatch(es): ");
2017  goto end;
2018  }
2019 
2020  SigMatch *prev = NULL;
2021  while (sm != NULL) {
2022  if (sm->type == DETECT_CONTENT) {
2023  result = 1;
2024  } else {
2025  printf("expected DETECT_CONTENT for http_stat_code, got %d: ", sm->type);
2026  goto end;
2027  }
2028  prev = sm;
2029  sm = sm->next;
2030  }
2031 
2032  if (! (((DetectContentData *)prev->ctx)->flags &
2034  {
2035  result = 0;
2036  }
2037 end:
2038  if (de_ctx != NULL)
2039  DetectEngineCtxFree(de_ctx);
2040  return result;
2041 }
2042 
2043 /** \test Check the signature working to alert when http_stat_code is matched . */
2044 static int DetectHttpStatCodeSigTest01(void)
2045 {
2046  int result = 0;
2047  Flow f;
2048  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
2049  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2050  uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n";
2051  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2052  TcpSession ssn;
2053  Packet *p = NULL;
2054  Signature *s = NULL;
2055  ThreadVars th_v;
2056  DetectEngineThreadCtx *det_ctx = NULL;
2057  HtpState *http_state = NULL;
2059 
2060  memset(&th_v, 0, sizeof(th_v));
2061  memset(&f, 0, sizeof(f));
2062  memset(&ssn, 0, sizeof(ssn));
2063 
2064  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2065 
2066  FLOW_INITIALIZE(&f);
2067  f.protoctx = (void *)&ssn;
2068  f.proto = IPPROTO_TCP;
2069  f.flags |= FLOW_IPV4;
2070 
2071  p->flow = &f;
2075  f.alproto = ALPROTO_HTTP;
2076 
2078 
2080  if (de_ctx == NULL) {
2081  printf("DetectEngineCtxInit failed: ");
2082  goto end;
2083  }
2084 
2085  de_ctx->flags |= DE_QUIET;
2086 
2087  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2088  "\"HTTP status code\"; content:\"200\"; http_stat_code; sid:1;)");
2089  if (s == NULL) {
2090  printf("sig parse failed: ");
2091  goto end;
2092  }
2093 
2094  SigGroupBuild(de_ctx);
2095  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2096 
2097  FLOWLOCK_WRLOCK(&f);
2098  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2099  STREAM_TOSERVER, httpbuf1, httplen1);
2100  if (r != 0) {
2101  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2102  FLOWLOCK_UNLOCK(&f);
2103  goto end;
2104  }
2105 
2106  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2107  STREAM_TOCLIENT, httpbuf2, httplen2);
2108  if (r != 0) {
2109  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
2110  FLOWLOCK_UNLOCK(&f);
2111  goto end;
2112  }
2113  FLOWLOCK_UNLOCK(&f);
2114 
2115  http_state = f.alstate;
2116  if (http_state == NULL) {
2117  printf("no http state: ");
2118  goto end;
2119  }
2120 
2121  /* do detect */
2122  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2123 
2124  if (!(PacketAlertCheck(p, 1))) {
2125  printf("sid 1 didn't match but should have: ");
2126  goto end;
2127  }
2128 
2129  result = 1;
2130 end:
2131  if (alp_tctx != NULL)
2132  AppLayerParserThreadCtxFree(alp_tctx);
2133  if (det_ctx != NULL) {
2134  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2135  }
2136  if (de_ctx != NULL) {
2137  DetectEngineCtxFree(de_ctx);
2138  }
2139 
2141 
2142  UTHFreePackets(&p, 1);
2143  return result;
2144 }
2145 
2146 /** \test Check the signature working to alert when http_stat_code is not matched . */
2147 static int DetectHttpStatCodeSigTest02(void)
2148 {
2149  int result = 0;
2150  Flow f;
2151  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
2152  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2153  uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n";
2154  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2155  TcpSession ssn;
2156  Packet *p = NULL;
2157  Signature *s = NULL;
2158  ThreadVars th_v;
2159  DetectEngineThreadCtx *det_ctx = NULL;
2160  HtpState *http_state = NULL;
2162 
2163  memset(&th_v, 0, sizeof(th_v));
2164  memset(&f, 0, sizeof(f));
2165  memset(&ssn, 0, sizeof(ssn));
2166 
2167  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2168 
2169  FLOW_INITIALIZE(&f);
2170  f.protoctx = (void *)&ssn;
2171  f.proto = IPPROTO_TCP;
2172  f.flags |= FLOW_IPV4;
2173 
2174  p->flow = &f;
2178  f.alproto = ALPROTO_HTTP;
2179 
2181 
2183  if (de_ctx == NULL) {
2184  goto end;
2185  }
2186 
2187  de_ctx->flags |= DE_QUIET;
2188 
2189  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2190  "\"HTTP status code\"; content:\"no\"; "
2191  "http_stat_code; sid:1;)");
2192  if (s == NULL) {
2193  goto end;
2194  }
2195 
2196  s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP "
2197  "Status code\"; content:\"100\";"
2198  "http_stat_code; sid:2;)");
2199  if (s->next == NULL) {
2200  goto end;
2201  }
2202 
2203  SigGroupBuild(de_ctx);
2204  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2205 
2206  FLOWLOCK_WRLOCK(&f);
2207  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2208  STREAM_TOSERVER, httpbuf1, httplen1);
2209  if (r != 0) {
2210  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2211  result = 0;
2212  FLOWLOCK_UNLOCK(&f);
2213  goto end;
2214  }
2215 
2216  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2217  STREAM_TOCLIENT, httpbuf2, httplen2);
2218  if (r != 0) {
2219  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
2220  result = 0;
2221  FLOWLOCK_UNLOCK(&f);
2222  goto end;
2223  }
2224  FLOWLOCK_UNLOCK(&f);
2225 
2226  http_state = f.alstate;
2227  if (http_state == NULL) {
2228  printf("no http state: ");
2229  result = 0;
2230  goto end;
2231  }
2232 
2233  /* do detect */
2234  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2235 
2236  if (PacketAlertCheck(p, 1)) {
2237  printf("sid 1 matched but shouldn't: ");
2238  goto end;
2239  }
2240  if ((PacketAlertCheck(p, 2))) {
2241  printf("sid 2 match but shouldn't have: ");
2242  goto end;
2243  }
2244 
2245  result = 1;
2246 end:
2247  if (alp_tctx != NULL)
2248  AppLayerParserThreadCtxFree(alp_tctx);
2249  if (det_ctx != NULL) {
2250  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2251  }
2252  if (de_ctx != NULL) {
2253  DetectEngineCtxFree(de_ctx);
2254  }
2255 
2257 
2258  UTHFreePackets(&p, 1);
2259  return result;
2260 }
2261 
2262 /** \test Check the signature working to alert when http_stat_code is matched for
2263  * for nocase or not */
2264 static int DetectHttpStatCodeSigTest03(void)
2265 {
2266  int result = 0;
2267  Flow f;
2268  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
2269  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2270  uint8_t httpbuf2[] = "HTTP/1.0 FAIL OK\r\n\r\n";
2271  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2272  TcpSession ssn;
2273  Packet *p = NULL;
2274  Signature *s = NULL;
2275  ThreadVars th_v;
2276  DetectEngineThreadCtx *det_ctx = NULL;
2277  HtpState *http_state = NULL;
2279 
2280  memset(&th_v, 0, sizeof(th_v));
2281  memset(&f, 0, sizeof(f));
2282  memset(&ssn, 0, sizeof(ssn));
2283 
2284  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2285 
2286  FLOW_INITIALIZE(&f);
2287  f.protoctx = (void *)&ssn;
2288  f.proto = IPPROTO_TCP;
2289  f.flags |= FLOW_IPV4;
2290 
2291  p->flow = &f;
2295  f.alproto = ALPROTO_HTTP;
2296 
2298 
2300  if (de_ctx == NULL) {
2301  goto end;
2302  }
2303 
2304  de_ctx->flags |= DE_QUIET;
2305 
2306  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2307  "\"HTTP status code\"; content:\"FAIL\"; "
2308  "http_stat_code; sid:1;)");
2309  if (s == NULL) {
2310  goto end;
2311  }
2312 
2313  s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP "
2314  "Status code nocase\"; content:\"fail\"; nocase; "
2315  "http_stat_code; sid:2;)");
2316  if (s->next == NULL) {
2317  goto end;
2318  }
2319 
2320  SigGroupBuild(de_ctx);
2321  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2322 
2323  FLOWLOCK_WRLOCK(&f);
2324  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2325  STREAM_TOSERVER, httpbuf1, httplen1);
2326  if (r != 0) {
2327  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2328  result = 0;
2329  FLOWLOCK_UNLOCK(&f);
2330  goto end;
2331  }
2332 
2333  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2334  STREAM_TOCLIENT, httpbuf2, httplen2);
2335  if (r != 0) {
2336  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
2337  result = 0;
2338  FLOWLOCK_UNLOCK(&f);
2339  goto end;
2340  }
2341  FLOWLOCK_UNLOCK(&f);
2342 
2343  http_state = f.alstate;
2344  if (http_state == NULL) {
2345  printf("no http state: ");
2346  result = 0;
2347  goto end;
2348  }
2349 
2350  /* do detect */
2351  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2352 
2353  if (!(PacketAlertCheck(p, 1))) {
2354  printf("sid 1 didn't match but should have: ");
2355  goto end;
2356  }
2357  if (!(PacketAlertCheck(p, 2))) {
2358  printf("sid 2 didn't match but should have: ");
2359  goto end;
2360  }
2361 
2362  result = 1;
2363 end:
2364  if (alp_tctx != NULL)
2365  AppLayerParserThreadCtxFree(alp_tctx);
2366  if (det_ctx != NULL) {
2367  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2368  }
2369  if (de_ctx != NULL) {
2370  DetectEngineCtxFree(de_ctx);
2371  }
2372 
2374 
2375  UTHFreePackets(&p, 1);
2376  return result;
2377 }
2378 
2379 /** \test Check the signature working to alert when http_stat_code is matched for
2380  * for negatoin or not */
2381 static int DetectHttpStatCodeSigTest04(void)
2382 {
2383  int result = 0;
2384  Flow f;
2385  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
2386  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2387  uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n";
2388  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2389  TcpSession ssn;
2390  Packet *p = NULL;
2391  Signature *s = NULL;
2392  ThreadVars th_v;
2393  DetectEngineThreadCtx *det_ctx = NULL;
2394  HtpState *http_state = NULL;
2396 
2397  memset(&th_v, 0, sizeof(th_v));
2398  memset(&f, 0, sizeof(f));
2399  memset(&ssn, 0, sizeof(ssn));
2400 
2401  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2402 
2403  FLOW_INITIALIZE(&f);
2404  f.protoctx = (void *)&ssn;
2405  f.proto = IPPROTO_TCP;
2406  f.flags |= FLOW_IPV4;
2407 
2408  p->flow = &f;
2412  f.alproto = ALPROTO_HTTP;
2413 
2415 
2417  if (de_ctx == NULL) {
2418  goto end;
2419  }
2420 
2421  de_ctx->flags |= DE_QUIET;
2422 
2423  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2424  "\"HTTP status code\"; content:\"200\"; "
2425  "http_stat_code; sid:1;)");
2426  if (s == NULL) {
2427  goto end;
2428  }
2429 
2430  s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP "
2431  "Status code negation\"; content:!\"100\"; nocase; "
2432  "http_stat_code; sid:2;)");
2433  if (s->next == NULL) {
2434  goto end;
2435  }
2436 
2437  SigGroupBuild(de_ctx);
2438  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2439 
2440  FLOWLOCK_WRLOCK(&f);
2441  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2442  STREAM_TOSERVER, httpbuf1, httplen1);
2443  if (r != 0) {
2444  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2445  result = 0;
2446  FLOWLOCK_UNLOCK(&f);
2447  goto end;
2448  }
2449 
2450  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2451  STREAM_TOCLIENT, httpbuf2, httplen2);
2452  if (r != 0) {
2453  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
2454  result = 0;
2455  FLOWLOCK_UNLOCK(&f);
2456  goto end;
2457  }
2458  FLOWLOCK_UNLOCK(&f);
2459 
2460  http_state = f.alstate;
2461  if (http_state == NULL) {
2462  printf("no http state: ");
2463  result = 0;
2464  goto end;
2465  }
2466 
2467  /* do detect */
2468  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2469 
2470  if (!(PacketAlertCheck(p, 1))) {
2471  printf("sid 1 didn't match but should have: ");
2472  goto end;
2473  }
2474  if (!(PacketAlertCheck(p, 2))) {
2475  printf("sid 2 didn't match but should have: ");
2476  goto end;
2477  }
2478 
2479  result = 1;
2480 end:
2481  if (alp_tctx != NULL)
2482  AppLayerParserThreadCtxFree(alp_tctx);
2483  if (det_ctx != NULL) {
2484  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2485  }
2486  if (de_ctx != NULL) {
2487  DetectEngineCtxFree(de_ctx);
2488  }
2489 
2491 
2492  UTHFreePackets(&p, 1);
2493  return result;
2494 }
2495 
2496 /**
2497  * \brief Register the UNITTESTS for the http_stat_code keyword
2498  */
2500 {
2501  UtRegisterTest("DetectEngineHttpStatCodeTest01",
2502  DetectEngineHttpStatCodeTest01);
2503  UtRegisterTest("DetectEngineHttpStatCodeTest02",
2504  DetectEngineHttpStatCodeTest02);
2505  UtRegisterTest("DetectEngineHttpStatCodeTest03",
2506  DetectEngineHttpStatCodeTest03);
2507  UtRegisterTest("DetectEngineHttpStatCodeTest04",
2508  DetectEngineHttpStatCodeTest04);
2509  UtRegisterTest("DetectEngineHttpStatCodeTest05",
2510  DetectEngineHttpStatCodeTest05);
2511  UtRegisterTest("DetectEngineHttpStatCodeTest06",
2512  DetectEngineHttpStatCodeTest06);
2513  UtRegisterTest("DetectEngineHttpStatCodeTest07",
2514  DetectEngineHttpStatCodeTest07);
2515  UtRegisterTest("DetectEngineHttpStatCodeTest08",
2516  DetectEngineHttpStatCodeTest08);
2517  UtRegisterTest("DetectEngineHttpStatCodeTest09",
2518  DetectEngineHttpStatCodeTest09);
2519  UtRegisterTest("DetectEngineHttpStatCodeTest10",
2520  DetectEngineHttpStatCodeTest10);
2521  UtRegisterTest("DetectEngineHttpStatCodeTest11",
2522  DetectEngineHttpStatCodeTest11);
2523  UtRegisterTest("DetectEngineHttpStatCodeTest12",
2524  DetectEngineHttpStatCodeTest12);
2525  UtRegisterTest("DetectEngineHttpStatCodeTest13",
2526  DetectEngineHttpStatCodeTest13);
2527  UtRegisterTest("DetectEngineHttpStatCodeTest14",
2528  DetectEngineHttpStatCodeTest14);
2529  UtRegisterTest("DetectEngineHttpStatCodeTest15",
2530  DetectEngineHttpStatCodeTest15);
2531 
2532  UtRegisterTest("DetectHttpStatCodeTest01", DetectHttpStatCodeTest01);
2533  UtRegisterTest("DetectHttpStatCodeTest02", DetectHttpStatCodeTest02);
2534  UtRegisterTest("DetectHttpStatCodeSigTest01", DetectHttpStatCodeSigTest01);
2535  UtRegisterTest("DetectHttpStatCodeSigTest02", DetectHttpStatCodeSigTest02);
2536  UtRegisterTest("DetectHttpStatCodeSigTest03", DetectHttpStatCodeSigTest03);
2537  UtRegisterTest("DetectHttpStatCodeSigTest04", DetectHttpStatCodeSigTest04);
2538 }
2539 
2540 /**
2541  * @}
2542  */
struct Flow_ * flow
Definition: decode.h:443
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint8_t proto
Definition: flow.h:344
#define DETECT_CONTENT_FAST_PATTERN
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:243
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Signature * sig_list
Definition: detect.h:749
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:203
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Signature container.
Definition: detect.h:514
#define TRUE
void * protoctx
Definition: flow.h:400
struct SigMatch_ * next
Definition: detect.h:327
main detection engine ctx
Definition: detect.h:743
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:438
#define DE_QUIET
Definition: detect.h:297
uint8_t flags
Definition: detect.h:744
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
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:1670
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
uint8_t flowflags
Definition: decode.h:437
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
struct Signature_ * next
Definition: detect.h:586
uint8_t type
Definition: detect.h:324
void DetectHttpStatCodeRegisterTests(void)
Register the UNITTESTS for the http_stat_code keyword.
SigMatchCtx * ctx
Definition: detect.h:326
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
#define PKT_HAS_FLOW
Definition: decode.h:1092
#define DETECT_CONTENT_NOCASE
Per thread variable structure.
Definition: threadvars.h:57
#define FLOW_PKT_TOCLIENT
Definition: flow.h:202
AppProto alproto
application level protocol
Definition: flow.h:409
uint32_t flags
Definition: decode.h:441
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
Flow data structure.
Definition: flow.h:325
#define FLOW_IPV4
Definition: flow.h:94
uint32_t flags
Definition: flow.h:379
#define PKT_STREAM_EST
Definition: decode.h:1090
a single match condition for a signature
Definition: detect.h:323
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
DetectEngineCtx * DetectEngineCtxInit(void)