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 #include "../detect-engine-build.h"
42 #include "../detect-engine-alert.h"
43 
44 static int DetectEngineHttpStatCodeTest01(void)
45 {
46  TcpSession ssn;
47  ThreadVars th_v;
48  DetectEngineThreadCtx *det_ctx = NULL;
49  Flow f;
50  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
51  "Host: www.openinfosecfoundation.org\r\n"
52  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
53  "Gecko/20091221 Firefox/3.5.7\r\n"
54  "\r\n";
55  uint32_t http_len1 = sizeof(http_buf1) - 1;
56  uint8_t http_buf2[] = "HTTP/1.0 200 message\r\n"
57  "Content-Type: text/html\r\n"
58  "Content-Length: 7\r\n"
59  "\r\n"
60  "message";
61  uint32_t http_len2 = sizeof(http_buf2) - 1;
63 
64  memset(&th_v, 0, sizeof(th_v));
65  StatsThreadInit(&th_v.stats);
66  memset(&f, 0, sizeof(f));
67  memset(&ssn, 0, sizeof(ssn));
68 
69  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
70  Packet *p2 = 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 
77  p1->flow = &f;
81  p2->flow = &f;
86 
87  StreamTcpInitConfig(true);
88 
91  de_ctx->flags |= DE_QUIET;
92 
93  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
94  "(msg:\"http stat code test\"; "
95  "content:\"200\"; http_stat_code; "
96  "sid:1;)");
97  FAIL_IF_NULL(s);
98 
100  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
101 
102  int r = AppLayerParserParse(
103  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
104  FAIL_IF_NOT(r == 0);
105 
106  HtpState *http_state = f.alstate;
107  FAIL_IF_NULL(http_state);
108 
109  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
110  FAIL_IF((PacketAlertCheck(p1, 1)));
111 
113  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
114  FAIL_IF_NOT(r == 0);
115 
116  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
117  FAIL_IF(!(PacketAlertCheck(p2, 1)));
118 
119  UTHFreePackets(&p1, 1);
120  UTHFreePackets(&p2, 1);
121  FLOW_DESTROY(&f);
123  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
125  StreamTcpFreeConfig(true);
126  StatsThreadCleanup(&th_v.stats);
127  PASS;
128 }
129 
130 static int DetectEngineHttpStatCodeTest02(void)
131 {
132  TcpSession ssn;
133  ThreadVars th_v;
134  DetectEngineThreadCtx *det_ctx = NULL;
135  Flow f;
136  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
137  "Host: www.openinfosecfoundation.org\r\n"
138  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
139  "Gecko/20091221 Firefox/3.5.7\r\n"
140  "\r\n";
141  uint32_t http_len1 = sizeof(http_buf1) - 1;
142  uint8_t http_buf2[] = "HTTP/1.0 2000123 xxxxABC\r\n"
143  "Content-Type: text/html\r\n"
144  "Content-Length: 7\r\n"
145  "\r\n"
146  "xxxxABC";
147  uint32_t http_len2 = sizeof(http_buf2) - 1;
149 
150  memset(&th_v, 0, sizeof(th_v));
151  StatsThreadInit(&th_v.stats);
152  memset(&f, 0, sizeof(f));
153  memset(&ssn, 0, sizeof(ssn));
154 
155  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
156 
157  FLOW_INITIALIZE(&f);
158  f.protoctx = (void *)&ssn;
159  f.proto = IPPROTO_TCP;
160  f.flags |= FLOW_IPV4;
161 
162  p1->flow = &f;
167 
168  StreamTcpInitConfig(true);
169 
172  de_ctx->flags |= DE_QUIET;
173 
174  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
175  "(msg:\"http stat code test\"; "
176  "content:\"123\"; http_stat_code; offset:4; "
177  "sid:1;)");
178  FAIL_IF_NULL(s);
179 
181  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
182 
183  int r = AppLayerParserParse(
184  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
185  FAIL_IF_NOT(r == 0);
186 
188  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
189  FAIL_IF_NOT(r == 0);
190 
191  HtpState *http_state = f.alstate;
192  FAIL_IF_NULL(http_state);
193 
194  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
195  FAIL_IF(!(PacketAlertCheck(p1, 1)));
196 
197  UTHFreePackets(&p1, 1);
198  FLOW_DESTROY(&f);
200  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
202  StreamTcpFreeConfig(true);
203  StatsThreadCleanup(&th_v.stats);
204  PASS;
205 }
206 
207 static int DetectEngineHttpStatCodeTest03(void)
208 {
209  TcpSession ssn;
210  ThreadVars th_v;
211  DetectEngineThreadCtx *det_ctx = NULL;
212  Flow f;
213  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
214  "Host: www.openinfosecfoundation.org\r\n"
215  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
216  "Gecko/20091221 Firefox/3.5.7\r\n"
217  "\r\n";
218  uint32_t http_len1 = sizeof(http_buf1) - 1;
219  uint8_t http_buf2[] = "HTTP/1.0 123";
220  uint32_t http_len2 = sizeof(http_buf2) - 1;
221  uint8_t http_buf3[] = "456789\r\n"
222  "Content-Type: text/html\r\n"
223  "Content-Length: 17\r\n"
224  "\r\n"
225  "12345678901234ABC";
226  uint32_t http_len3 = sizeof(http_buf3) - 1;
228 
229  memset(&th_v, 0, sizeof(th_v));
230  StatsThreadInit(&th_v.stats);
231  memset(&f, 0, sizeof(f));
232  memset(&ssn, 0, sizeof(ssn));
233 
234  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
235  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
236 
237  FLOW_INITIALIZE(&f);
238  f.protoctx = (void *)&ssn;
239  f.proto = IPPROTO_TCP;
240  f.flags |= FLOW_IPV4;
241 
242  p1->flow = &f;
246  p2->flow = &f;
251 
252  StreamTcpInitConfig(true);
253 
256  de_ctx->flags |= DE_QUIET;
257 
258  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
259  "(msg:\"http stat code test\"; "
260  "content:\"789\"; http_stat_code; offset:5; "
261  "sid:1;)");
262  FAIL_IF_NULL(s);
263 
265  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
266 
267  int r = AppLayerParserParse(
268  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
269  FAIL_IF_NOT(r == 0);
270 
271  HtpState *http_state = f.alstate;
272  FAIL_IF_NULL(http_state);
273 
274  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
275  FAIL_IF(PacketAlertCheck(p1, 1));
276 
278  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
279  FAIL_IF_NOT(r == 0);
280 
282  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf3, http_len3);
283  FAIL_IF_NOT(r == 0);
284 
285  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
286  FAIL_IF(!(PacketAlertCheck(p2, 1)));
287 
288  UTHFreePackets(&p1, 1);
289  UTHFreePackets(&p2, 1);
290  FLOW_DESTROY(&f);
292  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
294  StreamTcpFreeConfig(true);
295  StatsThreadCleanup(&th_v.stats);
296  PASS;
297 }
298 
299 static int DetectEngineHttpStatCodeTest04(void)
300 {
301  TcpSession ssn;
302  ThreadVars th_v;
303  DetectEngineThreadCtx *det_ctx = NULL;
304  Flow f;
305  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
306  "Host: www.openinfosecfoundation.org\r\n"
307  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
308  "Gecko/20091221 Firefox/3.5.7\r\n"
309  "\r\n";
310  uint32_t http_len1 = sizeof(http_buf1) - 1;
311  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
312  "Content-Type: text/html\r\n"
313  "Content-Length: 6\r\n"
314  "\r\n"
315  "abcdef";
316  uint32_t http_len2 = sizeof(http_buf2) - 1;
318 
319  memset(&th_v, 0, sizeof(th_v));
320  StatsThreadInit(&th_v.stats);
321  memset(&f, 0, sizeof(f));
322  memset(&ssn, 0, sizeof(ssn));
323 
324  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
325  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
326 
327  FLOW_INITIALIZE(&f);
328  f.protoctx = (void *)&ssn;
329  f.proto = IPPROTO_TCP;
330  f.flags |= FLOW_IPV4;
331 
332  p1->flow = &f;
336  p2->flow = &f;
341 
342  StreamTcpInitConfig(true);
343 
346  de_ctx->flags |= DE_QUIET;
347 
348  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
349  "(msg:\"http stat code test\"; "
350  "content:!\"200\"; http_stat_code; offset:3; "
351  "sid:1;)");
352  FAIL_IF_NULL(s);
353 
355  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
356 
357  int r = AppLayerParserParse(
358  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
359  FAIL_IF_NOT(r == 0);
360 
361  HtpState *http_state = f.alstate;
362  FAIL_IF_NULL(http_state);
363 
364  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
365  FAIL_IF(PacketAlertCheck(p1, 1));
366 
368  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
369  FAIL_IF_NOT(r == 0);
370 
371  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
372  FAIL_IF(!PacketAlertCheck(p2, 1));
373 
374  UTHFreePackets(&p1, 1);
375  UTHFreePackets(&p2, 1);
376  FLOW_DESTROY(&f);
378  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
380  StreamTcpFreeConfig(true);
381  StatsThreadCleanup(&th_v.stats);
382  PASS;
383 }
384 
385 static int DetectEngineHttpStatCodeTest05(void)
386 {
387  TcpSession ssn;
388  ThreadVars th_v;
389  DetectEngineThreadCtx *det_ctx = NULL;
390  Flow f;
391  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
392  "Host: www.openinfosecfoundation.org\r\n"
393  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
394  "Gecko/20091221 Firefox/3.5.7\r\n"
395  "\r\n";
396  uint32_t http_len1 = sizeof(http_buf1) - 1;
397  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
398  "Content-Type: text/html\r\n"
399  "Content-Length: 6\r\n"
400  "\r\n"
401  "abcdef";
402  uint32_t http_len2 = sizeof(http_buf2) - 1;
404 
405  memset(&th_v, 0, sizeof(th_v));
406  StatsThreadInit(&th_v.stats);
407  memset(&f, 0, sizeof(f));
408  memset(&ssn, 0, sizeof(ssn));
409 
410  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
411  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
412 
413  FLOW_INITIALIZE(&f);
414  f.protoctx = (void *)&ssn;
415  f.proto = IPPROTO_TCP;
416  f.flags |= FLOW_IPV4;
417 
418  p1->flow = &f;
422  p2->flow = &f;
427 
428  StreamTcpInitConfig(true);
429 
432  de_ctx->flags |= DE_QUIET;
433 
434  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
435  "(msg:\"http stat code test\"; "
436  "content:\"200\"; http_stat_code; depth:3; "
437  "sid:1;)");
438  FAIL_IF_NULL(s);
439 
441  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
442 
443  int r = AppLayerParserParse(
444  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
445  FAIL_IF_NOT(r == 0);
446 
447  HtpState *http_state = f.alstate;
448  FAIL_IF_NULL(http_state);
449 
450  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
451  FAIL_IF(PacketAlertCheck(p1, 1));
452 
454  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
455  FAIL_IF_NOT(r == 0);
456 
457  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
458  FAIL_IF(!PacketAlertCheck(p2, 1));
459 
460  UTHFreePackets(&p1, 1);
461  UTHFreePackets(&p2, 1);
462  FLOW_DESTROY(&f);
464  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
466  StreamTcpFreeConfig(true);
467  StatsThreadCleanup(&th_v.stats);
468  PASS;
469 }
470 
471 static int DetectEngineHttpStatCodeTest06(void)
472 {
473  TcpSession ssn;
474  ThreadVars th_v;
475  DetectEngineThreadCtx *det_ctx = NULL;
476  Flow f;
477  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
478  "Host: www.openinfosecfoundation.org\r\n"
479  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
480  "Gecko/20091221 Firefox/3.5.7\r\n"
481  "\r\n";
482  uint32_t http_len1 = sizeof(http_buf1) - 1;
483  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
484  "Content-Type: text/html\r\n"
485  "Content-Length: 6\r\n"
486  "\r\n"
487  "abcdef";
488  uint32_t http_len2 = sizeof(http_buf2) - 1;
490 
491  memset(&th_v, 0, sizeof(th_v));
492  StatsThreadInit(&th_v.stats);
493  memset(&f, 0, sizeof(f));
494  memset(&ssn, 0, sizeof(ssn));
495 
496  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
497  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
498 
499  FLOW_INITIALIZE(&f);
500  f.protoctx = (void *)&ssn;
501  f.proto = IPPROTO_TCP;
502  f.flags |= FLOW_IPV4;
503 
504  p1->flow = &f;
508  p2->flow = &f;
513 
514  StreamTcpInitConfig(true);
515 
518  de_ctx->flags |= DE_QUIET;
519 
520  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
521  "(msg:\"http stat code test\"; "
522  "content:!\"123\"; http_stat_code; depth:3; "
523  "sid:1;)");
524  FAIL_IF_NULL(s);
525 
527  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
528 
529  int r = AppLayerParserParse(
530  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
531  FAIL_IF_NOT(r == 0);
532 
533  HtpState *http_state = f.alstate;
534  FAIL_IF_NULL(http_state);
535 
536  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
537  FAIL_IF(PacketAlertCheck(p1, 1));
538 
540  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
541  FAIL_IF_NOT(r == 0);
542 
543  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
544  FAIL_IF(!PacketAlertCheck(p2, 1));
545 
546  UTHFreePackets(&p1, 1);
547  UTHFreePackets(&p2, 1);
548  FLOW_DESTROY(&f);
550  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
552  StreamTcpFreeConfig(true);
553  StatsThreadCleanup(&th_v.stats);
554  PASS;
555 }
556 
557 static int DetectEngineHttpStatCodeTest07(void)
558 {
559  TcpSession ssn;
560  ThreadVars th_v;
561  DetectEngineThreadCtx *det_ctx = NULL;
562  Flow f;
563  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
564  "Host: www.openinfosecfoundation.org\r\n"
565  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
566  "Gecko/20091221 Firefox/3.5.7\r\n"
567  "\r\n";
568  uint32_t http_len1 = sizeof(http_buf1) - 1;
569  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
570  "Content-Type: text/html\r\n"
571  "Content-Length: 6\r\n"
572  "\r\n"
573  "abcdef";
574  uint32_t http_len2 = sizeof(http_buf2) - 1;
576 
577  memset(&th_v, 0, sizeof(th_v));
578  StatsThreadInit(&th_v.stats);
579  memset(&f, 0, sizeof(f));
580  memset(&ssn, 0, sizeof(ssn));
581 
582  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
583  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
584 
585  FLOW_INITIALIZE(&f);
586  f.protoctx = (void *)&ssn;
587  f.proto = IPPROTO_TCP;
588  f.flags |= FLOW_IPV4;
589 
590  p1->flow = &f;
594  p2->flow = &f;
599 
600  StreamTcpInitConfig(true);
601 
604  de_ctx->flags |= DE_QUIET;
605 
606  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
607  "(msg:\"http stat code test\"; "
608  "content:!\"123\"; http_stat_code; offset:3; "
609  "sid:1;)");
610  FAIL_IF_NULL(s);
611 
613  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
614 
615  int r = AppLayerParserParse(
616  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
617  FAIL_IF_NOT(r == 0);
618 
619  HtpState *http_state = f.alstate;
620  FAIL_IF_NULL(http_state);
621 
622  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
623  FAIL_IF(PacketAlertCheck(p1, 1));
624 
626  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
627  FAIL_IF_NOT(r == 0);
628 
629  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
630  FAIL_IF(PacketAlertCheck(p2, 1));
631 
632  UTHFreePackets(&p1, 1);
633  UTHFreePackets(&p2, 1);
634  FLOW_DESTROY(&f);
636  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
638  StreamTcpFreeConfig(true);
639  StatsThreadCleanup(&th_v.stats);
640  PASS;
641 }
642 
643 static int DetectEngineHttpStatCodeTest08(void)
644 {
645  TcpSession ssn;
646  ThreadVars th_v;
647  DetectEngineThreadCtx *det_ctx = NULL;
648  Flow f;
649  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
650  "Host: www.openinfosecfoundation.org\r\n"
651  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
652  "Gecko/20091221 Firefox/3.5.7\r\n"
653  "\r\n";
654  uint32_t http_len1 = sizeof(http_buf1) - 1;
655  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
656  "Content-Type: text/html\r\n"
657  "Content-Length: 6\r\n"
658  "\r\n"
659  "abcdef";
660  uint32_t http_len2 = sizeof(http_buf2) - 1;
662 
663  memset(&th_v, 0, sizeof(th_v));
664  StatsThreadInit(&th_v.stats);
665  memset(&f, 0, sizeof(f));
666  memset(&ssn, 0, sizeof(ssn));
667 
668  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
669  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
670 
671  FLOW_INITIALIZE(&f);
672  f.protoctx = (void *)&ssn;
673  f.proto = IPPROTO_TCP;
674  f.flags |= FLOW_IPV4;
675 
676  p1->flow = &f;
680  p2->flow = &f;
685 
686  StreamTcpInitConfig(true);
687 
690  de_ctx->flags |= DE_QUIET;
691 
692  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
693  "(msg:\"http stat code test\"; "
694  "content:!\"200\"; http_stat_code; depth:3; "
695  "sid:1;)");
696  FAIL_IF_NULL(s);
697 
699  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
700 
701  int r = AppLayerParserParse(
702  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
703  FAIL_IF_NOT(r == 0);
704 
705  HtpState *http_state = f.alstate;
706  FAIL_IF_NULL(http_state);
707 
708  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
709  FAIL_IF(PacketAlertCheck(p1, 1));
710 
712  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
713  FAIL_IF_NOT(r == 0);
714 
715  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
716  FAIL_IF(PacketAlertCheck(p2, 1));
717 
718  UTHFreePackets(&p1, 1);
719  UTHFreePackets(&p2, 1);
720  FLOW_DESTROY(&f);
722  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
724  StreamTcpFreeConfig(true);
725  StatsThreadCleanup(&th_v.stats);
726  PASS;
727 }
728 
729 static int DetectEngineHttpStatCodeTest09(void)
730 {
731  TcpSession ssn;
732  ThreadVars th_v;
733  DetectEngineThreadCtx *det_ctx = NULL;
734  Flow f;
735  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
736  "Host: www.openinfosecfoundation.org\r\n"
737  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
738  "Gecko/20091221 Firefox/3.5.7\r\n"
739  "\r\n";
740  uint32_t http_len1 = sizeof(http_buf1) - 1;
741  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
742  "Content-Type: text/html\r\n"
743  "Content-Length: 6\r\n"
744  "\r\n"
745  "abcdef";
746  uint32_t http_len2 = sizeof(http_buf2) - 1;
748 
749  memset(&th_v, 0, sizeof(th_v));
750  StatsThreadInit(&th_v.stats);
751  memset(&f, 0, sizeof(f));
752  memset(&ssn, 0, sizeof(ssn));
753 
754  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
755  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
756 
757  FLOW_INITIALIZE(&f);
758  f.protoctx = (void *)&ssn;
759  f.proto = IPPROTO_TCP;
760  f.flags |= FLOW_IPV4;
761 
762  p1->flow = &f;
766  p2->flow = &f;
771 
772  StreamTcpInitConfig(true);
773 
776  de_ctx->flags |= DE_QUIET;
777 
778  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
779  "(msg:\"http stat code test\"; "
780  "content:\"200\"; http_stat_code; depth:3; "
781  "content:\"123\"; http_stat_code; within:3; "
782  "sid:1;)");
783  FAIL_IF_NULL(s);
784 
786  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
787 
788  int r = AppLayerParserParse(
789  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
790  FAIL_IF_NOT(r == 0);
791 
792  HtpState *http_state = f.alstate;
793  FAIL_IF_NULL(http_state);
794 
795  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
796  FAIL_IF(PacketAlertCheck(p1, 1));
797 
799  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
800  FAIL_IF_NOT(r == 0);
801 
802  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
803  FAIL_IF(!PacketAlertCheck(p2, 1));
804 
805  UTHFreePackets(&p1, 1);
806  UTHFreePackets(&p2, 1);
807  FLOW_DESTROY(&f);
809  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
811  StreamTcpFreeConfig(true);
812  StatsThreadCleanup(&th_v.stats);
813  PASS;
814 }
815 
816 static int DetectEngineHttpStatCodeTest10(void)
817 {
818  TcpSession ssn;
819  ThreadVars th_v;
820  DetectEngineThreadCtx *det_ctx = NULL;
821  Flow f;
822  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
823  "Host: www.openinfosecfoundation.org\r\n"
824  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
825  "Gecko/20091221 Firefox/3.5.7\r\n"
826  "\r\n";
827  uint32_t http_len1 = sizeof(http_buf1) - 1;
828  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
829  "Content-Type: text/html\r\n"
830  "Content-Length: 6\r\n"
831  "\r\n"
832  "abcdef";
833  uint32_t http_len2 = sizeof(http_buf2) - 1;
835 
836  memset(&th_v, 0, sizeof(th_v));
837  StatsThreadInit(&th_v.stats);
838  memset(&f, 0, sizeof(f));
839  memset(&ssn, 0, sizeof(ssn));
840 
841  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
842  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
843 
844  FLOW_INITIALIZE(&f);
845  f.protoctx = (void *)&ssn;
846  f.proto = IPPROTO_TCP;
847  f.flags |= FLOW_IPV4;
848 
849  p1->flow = &f;
853  p2->flow = &f;
858 
859  StreamTcpInitConfig(true);
860 
863  de_ctx->flags |= DE_QUIET;
864 
865  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
866  "(msg:\"http stat code test\"; "
867  "content:\"200\"; http_stat_code; depth:3; "
868  "content:!\"124\"; http_stat_code; within:3; "
869  "sid:1;)");
870  FAIL_IF_NULL(s);
871 
873  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
874 
875  int r = AppLayerParserParse(
876  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
877  FAIL_IF_NOT(r == 0);
878 
879  HtpState *http_state = f.alstate;
880  FAIL_IF_NULL(http_state);
881 
882  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
883  FAIL_IF(PacketAlertCheck(p1, 1));
884 
886  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
887  FAIL_IF_NOT(r == 0);
888 
889  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
890  FAIL_IF(!PacketAlertCheck(p2, 1));
891 
892  UTHFreePackets(&p1, 1);
893  UTHFreePackets(&p2, 1);
894  FLOW_DESTROY(&f);
896  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
898  StreamTcpFreeConfig(true);
899  StatsThreadCleanup(&th_v.stats);
900  PASS;
901 }
902 
903 static int DetectEngineHttpStatCodeTest11(void)
904 {
905  TcpSession ssn;
906  ThreadVars th_v;
907  DetectEngineThreadCtx *det_ctx = NULL;
908  Flow f;
909  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
910  "Host: www.openinfosecfoundation.org\r\n"
911  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
912  "Gecko/20091221 Firefox/3.5.7\r\n"
913  "\r\n";
914  uint32_t http_len1 = sizeof(http_buf1) - 1;
915  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
916  "Content-Type: text/html\r\n"
917  "Content-Length: 6\r\n"
918  "\r\n"
919  "abcdef";
920  uint32_t http_len2 = sizeof(http_buf2) - 1;
922 
923  memset(&th_v, 0, sizeof(th_v));
924  StatsThreadInit(&th_v.stats);
925  memset(&f, 0, sizeof(f));
926  memset(&ssn, 0, sizeof(ssn));
927 
928  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
929  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
930 
931  FLOW_INITIALIZE(&f);
932  f.protoctx = (void *)&ssn;
933  f.proto = IPPROTO_TCP;
934  f.flags |= FLOW_IPV4;
935 
936  p1->flow = &f;
940  p2->flow = &f;
945 
946  StreamTcpInitConfig(true);
947 
950  de_ctx->flags |= DE_QUIET;
951 
952  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
953  "(msg:\"http stat code test\"; "
954  "content:\"200\"; http_stat_code; depth:3; "
955  "content:\"124\"; http_stat_code; within:3; "
956  "sid:1;)");
957  FAIL_IF_NULL(s);
958 
960  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
961 
962  int r = AppLayerParserParse(
963  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
964  FAIL_IF_NOT(r == 0);
965 
966  HtpState *http_state = f.alstate;
967  FAIL_IF_NULL(http_state);
968 
969  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
970  FAIL_IF(PacketAlertCheck(p1, 1));
971 
973  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
974  FAIL_IF_NOT(r == 0);
975 
976  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
977  FAIL_IF(PacketAlertCheck(p2, 1));
978 
979  UTHFreePackets(&p1, 1);
980  UTHFreePackets(&p2, 1);
981  FLOW_DESTROY(&f);
983  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
985  StreamTcpFreeConfig(true);
986  StatsThreadCleanup(&th_v.stats);
987  PASS;
988 }
989 
990 static int DetectEngineHttpStatCodeTest12(void)
991 {
992  TcpSession ssn;
993  ThreadVars th_v;
994  DetectEngineThreadCtx *det_ctx = NULL;
995  Flow f;
996  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
997  "Host: www.openinfosecfoundation.org\r\n"
998  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
999  "Gecko/20091221 Firefox/3.5.7\r\n"
1000  "\r\n";
1001  uint32_t http_len1 = sizeof(http_buf1) - 1;
1002  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
1003  "Content-Type: text/html\r\n"
1004  "Content-Length: 6\r\n"
1005  "\r\n"
1006  "abcdef";
1007  uint32_t http_len2 = sizeof(http_buf2) - 1;
1009 
1010  memset(&th_v, 0, sizeof(th_v));
1011  StatsThreadInit(&th_v.stats);
1012  memset(&f, 0, sizeof(f));
1013  memset(&ssn, 0, sizeof(ssn));
1014 
1015  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1016  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1017 
1018  FLOW_INITIALIZE(&f);
1019  f.protoctx = (void *)&ssn;
1020  f.proto = IPPROTO_TCP;
1021  f.flags |= FLOW_IPV4;
1022 
1023  p1->flow = &f;
1027  p2->flow = &f;
1031  f.alproto = ALPROTO_HTTP1;
1032 
1033  StreamTcpInitConfig(true);
1034 
1037  de_ctx->flags |= DE_QUIET;
1038 
1039  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1040  "(msg:\"http stat code test\"; "
1041  "content:\"20\"; http_stat_code; depth:2; "
1042  "content:\"23\"; http_stat_code; distance:2; "
1043  "sid:1;)");
1044  FAIL_IF_NULL(s);
1045 
1047  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1048 
1049  int r = AppLayerParserParse(
1050  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
1051  FAIL_IF_NOT(r == 0);
1052 
1053  HtpState *http_state = f.alstate;
1054  FAIL_IF_NULL(http_state);
1055 
1056  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1057  FAIL_IF(PacketAlertCheck(p1, 1));
1058 
1059  r = AppLayerParserParse(
1060  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
1061  FAIL_IF_NOT(r == 0);
1062 
1063  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1064  FAIL_IF(!PacketAlertCheck(p2, 1));
1065 
1066  UTHFreePackets(&p1, 1);
1067  UTHFreePackets(&p2, 1);
1068  FLOW_DESTROY(&f);
1070  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1072  StreamTcpFreeConfig(true);
1073  StatsThreadCleanup(&th_v.stats);
1074  PASS;
1075 }
1076 
1077 static int DetectEngineHttpStatCodeTest13(void)
1078 {
1079  TcpSession ssn;
1080  ThreadVars th_v;
1081  DetectEngineThreadCtx *det_ctx = NULL;
1082  Flow f;
1083  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
1084  "Host: www.openinfosecfoundation.org\r\n"
1085  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
1086  "Gecko/20091221 Firefox/3.5.7\r\n"
1087  "\r\n";
1088  uint32_t http_len1 = sizeof(http_buf1) - 1;
1089  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
1090  "Content-Type: text/html\r\n"
1091  "Content-Length: 6\r\n"
1092  "\r\n"
1093  "abcdef";
1094  uint32_t http_len2 = sizeof(http_buf2) - 1;
1096 
1097  memset(&th_v, 0, sizeof(th_v));
1098  StatsThreadInit(&th_v.stats);
1099  memset(&f, 0, sizeof(f));
1100  memset(&ssn, 0, sizeof(ssn));
1101 
1102  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1103  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1104 
1105  FLOW_INITIALIZE(&f);
1106  f.protoctx = (void *)&ssn;
1107  f.proto = IPPROTO_TCP;
1108  f.flags |= FLOW_IPV4;
1109 
1110  p1->flow = &f;
1114  p2->flow = &f;
1118  f.alproto = ALPROTO_HTTP1;
1119 
1120  StreamTcpInitConfig(true);
1121 
1124  de_ctx->flags |= DE_QUIET;
1125 
1126  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1127  "(msg:\"http stat code test\"; "
1128  "content:\"20\"; http_stat_code; depth:3; "
1129  "content:!\"25\"; http_stat_code; distance:2; "
1130  "sid:1;)");
1131  FAIL_IF_NULL(s);
1132 
1134  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1135 
1136  int r = AppLayerParserParse(
1137  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
1138  FAIL_IF_NOT(r == 0);
1139 
1140  HtpState *http_state = f.alstate;
1141  FAIL_IF_NULL(http_state);
1142 
1143  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1144  FAIL_IF(PacketAlertCheck(p1, 1));
1145 
1146  r = AppLayerParserParse(
1147  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
1148  FAIL_IF_NOT(r == 0);
1149 
1150  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1151  FAIL_IF(!PacketAlertCheck(p2, 1));
1152 
1153  UTHFreePackets(&p1, 1);
1154  UTHFreePackets(&p2, 1);
1155  FLOW_DESTROY(&f);
1157  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1159  StreamTcpFreeConfig(true);
1160  StatsThreadCleanup(&th_v.stats);
1161  PASS;
1162 }
1163 
1164 static int DetectEngineHttpStatCodeTest14(void)
1165 {
1166  TcpSession ssn;
1167  ThreadVars th_v;
1168  DetectEngineThreadCtx *det_ctx = NULL;
1169  Flow f;
1170  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
1171  "Host: www.openinfosecfoundation.org\r\n"
1172  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
1173  "Gecko/20091221 Firefox/3.5.7\r\n"
1174  "\r\n";
1175  uint32_t http_len1 = sizeof(http_buf1) - 1;
1176  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
1177  "Content-Type: text/html\r\n"
1178  "Content-Length: 6\r\n"
1179  "\r\n"
1180  "abcdef";
1181  uint32_t http_len2 = sizeof(http_buf2) - 1;
1183 
1184  memset(&th_v, 0, sizeof(th_v));
1185  StatsThreadInit(&th_v.stats);
1186  memset(&f, 0, sizeof(f));
1187  memset(&ssn, 0, sizeof(ssn));
1188 
1189  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1190  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1191 
1192  FLOW_INITIALIZE(&f);
1193  f.protoctx = (void *)&ssn;
1194  f.proto = IPPROTO_TCP;
1195  f.flags |= FLOW_IPV4;
1196 
1197  p1->flow = &f;
1201  p2->flow = &f;
1205  f.alproto = ALPROTO_HTTP1;
1206 
1207  StreamTcpInitConfig(true);
1208 
1211  de_ctx->flags |= DE_QUIET;
1212 
1213  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1214  "(msg:\"http stat code test\"; "
1215  "pcre:/20/S; "
1216  "content:\"23\"; http_stat_code; distance:2; "
1217  "sid:1;)");
1218  FAIL_IF_NULL(s);
1219 
1221  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1222 
1223  int r = AppLayerParserParse(
1224  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
1225  FAIL_IF_NOT(r == 0);
1226 
1227  HtpState *http_state = f.alstate;
1228  FAIL_IF_NULL(http_state);
1229 
1230  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1231  FAIL_IF(PacketAlertCheck(p1, 1));
1232 
1233  r = AppLayerParserParse(
1234  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
1235  FAIL_IF_NOT(r == 0);
1236 
1237  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1238  FAIL_IF(!PacketAlertCheck(p2, 1));
1239 
1240  UTHFreePackets(&p1, 1);
1241  UTHFreePackets(&p2, 1);
1242  FLOW_DESTROY(&f);
1244  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1246  StreamTcpFreeConfig(true);
1247  StatsThreadCleanup(&th_v.stats);
1248  PASS;
1249 }
1250 
1251 static int DetectEngineHttpStatCodeTest15(void)
1252 {
1253  TcpSession ssn;
1254  ThreadVars th_v;
1255  DetectEngineThreadCtx *det_ctx = NULL;
1256  Flow f;
1257  uint8_t http_buf1[] = "GET /index.html HTTP/1.0\r\n"
1258  "Host: www.openinfosecfoundation.org\r\n"
1259  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) "
1260  "Gecko/20091221 Firefox/3.5.7\r\n"
1261  "\r\n";
1262  uint32_t http_len1 = sizeof(http_buf1) - 1;
1263  uint8_t http_buf2[] = "HTTP/1.0 200123 abcdef\r\n"
1264  "Content-Type: text/html\r\n"
1265  "Content-Length: 6\r\n"
1266  "\r\n"
1267  "abcdef";
1268  uint32_t http_len2 = sizeof(http_buf2) - 1;
1270 
1271  memset(&th_v, 0, sizeof(th_v));
1272  StatsThreadInit(&th_v.stats);
1273  memset(&f, 0, sizeof(f));
1274  memset(&ssn, 0, sizeof(ssn));
1275 
1276  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1277  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1278 
1279  FLOW_INITIALIZE(&f);
1280  f.protoctx = (void *)&ssn;
1281  f.proto = IPPROTO_TCP;
1282  f.flags |= FLOW_IPV4;
1283 
1284  p1->flow = &f;
1288  p2->flow = &f;
1292  f.alproto = ALPROTO_HTTP1;
1293 
1294  StreamTcpInitConfig(true);
1295 
1298  de_ctx->flags |= DE_QUIET;
1299 
1300  Signature *s =
1301  DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1302  "(msg:\"http stat code test\"; "
1303  "pcre:/200/S; "
1304  "content:!\"124\"; http_stat_code; distance:0; within:3; "
1305  "sid:1;)");
1306  FAIL_IF_NULL(s);
1307 
1309  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1310 
1311  int r = AppLayerParserParse(
1312  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_len1);
1313  FAIL_IF_NOT(r == 0);
1314 
1315  HtpState *http_state = f.alstate;
1316  FAIL_IF_NULL(http_state);
1317 
1318  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1319  FAIL_IF(PacketAlertCheck(p1, 1));
1320 
1321  r = AppLayerParserParse(
1322  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_len2);
1323  FAIL_IF_NOT(r == 0);
1324 
1325  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1326  FAIL_IF(!PacketAlertCheck(p2, 1));
1327 
1328  UTHFreePackets(&p1, 1);
1329  UTHFreePackets(&p2, 1);
1330  FLOW_DESTROY(&f);
1332  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1334  StreamTcpFreeConfig(true);
1335  StatsThreadCleanup(&th_v.stats);
1336  PASS;
1337 }
1338 
1339 /** \test Check the signature working to alert when http_stat_code is matched . */
1340 static int DetectHttpStatCodeSigTest01(void)
1341 {
1342  Flow f;
1343  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
1344  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1345  uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n";
1346  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1347  TcpSession ssn;
1348  ThreadVars th_v;
1349  DetectEngineThreadCtx *det_ctx = NULL;
1351 
1352  memset(&th_v, 0, sizeof(th_v));
1353  StatsThreadInit(&th_v.stats);
1354  memset(&f, 0, sizeof(f));
1355  memset(&ssn, 0, sizeof(ssn));
1356 
1357  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1358 
1359  FLOW_INITIALIZE(&f);
1360  f.protoctx = (void *)&ssn;
1361  f.proto = IPPROTO_TCP;
1362  f.flags |= FLOW_IPV4;
1363 
1364  p->flow = &f;
1368  f.alproto = ALPROTO_HTTP1;
1369 
1370  StreamTcpInitConfig(true);
1371 
1374  de_ctx->flags |= DE_QUIET;
1375 
1377  "alert http any any -> any any (msg:"
1378  "\"HTTP status code\"; content:\"200\"; http_stat_code; sid:1;)");
1379  FAIL_IF_NULL(s);
1380 
1382  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1383 
1384  int r = AppLayerParserParse(
1385  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1386  FAIL_IF_NOT(r == 0);
1387 
1388  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, httpbuf2, httplen2);
1389  FAIL_IF_NOT(r == 0);
1390 
1391  HtpState *http_state = f.alstate;
1392  FAIL_IF_NULL(http_state);
1393 
1394  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1395  FAIL_IF(!(PacketAlertCheck(p, 1)));
1396 
1397  UTHFreePackets(&p, 1);
1398  FLOW_DESTROY(&f);
1400  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1402  StreamTcpFreeConfig(true);
1403  StatsThreadCleanup(&th_v.stats);
1404  PASS;
1405 }
1406 
1407 /** \test Check the signature working to alert when http_stat_code is not matched . */
1408 static int DetectHttpStatCodeSigTest02(void)
1409 {
1410  Flow f;
1411  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
1412  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1413  uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n";
1414  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1415  TcpSession ssn;
1416  ThreadVars th_v;
1417  DetectEngineThreadCtx *det_ctx = NULL;
1419 
1420  memset(&th_v, 0, sizeof(th_v));
1421  StatsThreadInit(&th_v.stats);
1422  memset(&f, 0, sizeof(f));
1423  memset(&ssn, 0, sizeof(ssn));
1424 
1425  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1426 
1427  FLOW_INITIALIZE(&f);
1428  f.protoctx = (void *)&ssn;
1429  f.proto = IPPROTO_TCP;
1430  f.flags |= FLOW_IPV4;
1431 
1432  p->flow = &f;
1436  f.alproto = ALPROTO_HTTP1;
1437 
1438  StreamTcpInitConfig(true);
1439 
1442  de_ctx->flags |= DE_QUIET;
1443 
1444  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (msg:"
1445  "\"HTTP status code\"; content:\"no\"; "
1446  "http_stat_code; sid:1;)");
1447  FAIL_IF_NULL(s);
1448 
1449  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (msg:\"HTTP "
1450  "Status code\"; content:\"100\";"
1451  "http_stat_code; sid:2;)");
1452  FAIL_IF_NULL(s);
1453 
1455  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1456 
1457  int r = AppLayerParserParse(
1458  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1459  FAIL_IF_NOT(r == 0);
1460 
1461  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, httpbuf2, httplen2);
1462  FAIL_IF_NOT(r == 0);
1463 
1464  HtpState *http_state = f.alstate;
1465  FAIL_IF_NULL(http_state);
1466 
1467  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1468  FAIL_IF(PacketAlertCheck(p, 1));
1469  FAIL_IF((PacketAlertCheck(p, 2)));
1470 
1471  UTHFreePackets(&p, 1);
1472  FLOW_DESTROY(&f);
1474  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1476  StreamTcpFreeConfig(true);
1477  StatsThreadCleanup(&th_v.stats);
1478  PASS;
1479 }
1480 
1481 /** \test Check the signature working to alert when http_stat_code is matched for
1482  * for nocase or not */
1483 static int DetectHttpStatCodeSigTest03(void)
1484 {
1485  Flow f;
1486  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
1487  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1488  uint8_t httpbuf2[] = "HTTP/1.0 FAIL OK\r\n\r\n";
1489  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1490  TcpSession ssn;
1491  ThreadVars th_v;
1492  DetectEngineThreadCtx *det_ctx = NULL;
1494 
1495  memset(&th_v, 0, sizeof(th_v));
1496  StatsThreadInit(&th_v.stats);
1497  memset(&f, 0, sizeof(f));
1498  memset(&ssn, 0, sizeof(ssn));
1499 
1500  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1501 
1502  FLOW_INITIALIZE(&f);
1503  f.protoctx = (void *)&ssn;
1504  f.proto = IPPROTO_TCP;
1505  f.flags |= FLOW_IPV4;
1506 
1507  p->flow = &f;
1511  f.alproto = ALPROTO_HTTP1;
1512 
1513  StreamTcpInitConfig(true);
1514 
1517  de_ctx->flags |= DE_QUIET;
1518 
1519  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (msg:"
1520  "\"HTTP status code\"; content:\"FAIL\"; "
1521  "http_stat_code; sid:1;)");
1522  FAIL_IF_NULL(s);
1523 
1524  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (msg:\"HTTP "
1525  "Status code nocase\"; content:\"fail\"; nocase; "
1526  "http_stat_code; sid:2;)");
1527  FAIL_IF_NULL(s);
1528 
1530  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1531 
1532  int r = AppLayerParserParse(
1533  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1534  FAIL_IF_NOT(r == 0);
1535 
1536  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, httpbuf2, httplen2);
1537  FAIL_IF_NOT(r == 0);
1538 
1539  HtpState *http_state = f.alstate;
1540  FAIL_IF_NULL(http_state);
1541 
1542  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1543  FAIL_IF(!(PacketAlertCheck(p, 1)));
1544  FAIL_IF(!(PacketAlertCheck(p, 2)));
1545 
1546  UTHFreePackets(&p, 1);
1547  FLOW_DESTROY(&f);
1549  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1551  StreamTcpFreeConfig(true);
1552  StatsThreadCleanup(&th_v.stats);
1553  PASS;
1554 }
1555 
1556 /** \test Check the signature working to alert when http_stat_code is matched for
1557  * for negation or not */
1558 static int DetectHttpStatCodeSigTest04(void)
1559 {
1560  Flow f;
1561  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n";
1562  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1563  uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n";
1564  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1565  TcpSession ssn;
1566  ThreadVars th_v;
1567  DetectEngineThreadCtx *det_ctx = NULL;
1569 
1570  memset(&th_v, 0, sizeof(th_v));
1571  StatsThreadInit(&th_v.stats);
1572  memset(&f, 0, sizeof(f));
1573  memset(&ssn, 0, sizeof(ssn));
1574 
1575  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1576 
1577  FLOW_INITIALIZE(&f);
1578  f.protoctx = (void *)&ssn;
1579  f.proto = IPPROTO_TCP;
1580  f.flags |= FLOW_IPV4;
1581 
1582  p->flow = &f;
1586  f.alproto = ALPROTO_HTTP1;
1587 
1588  StreamTcpInitConfig(true);
1589 
1592  de_ctx->flags |= DE_QUIET;
1593 
1594  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (msg:"
1595  "\"HTTP status code\"; content:\"200\"; "
1596  "http_stat_code; sid:1;)");
1597  FAIL_IF_NULL(s);
1598 
1599  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (msg:\"HTTP "
1600  "Status code negation\"; content:!\"100\"; nocase; "
1601  "http_stat_code; sid:2;)");
1602  FAIL_IF_NULL(s);
1603 
1605  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1606 
1607  int r = AppLayerParserParse(
1608  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1609  FAIL_IF_NOT(r == 0);
1610 
1611  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, httpbuf2, httplen2);
1612  FAIL_IF_NOT(r == 0);
1613 
1614  HtpState *http_state = f.alstate;
1615  FAIL_IF_NULL(http_state);
1616 
1617  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1618 
1619  FAIL_IF(!(PacketAlertCheck(p, 1)));
1620  FAIL_IF(!(PacketAlertCheck(p, 2)));
1621 
1622  UTHFreePackets(&p, 1);
1623  FLOW_DESTROY(&f);
1625  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1627  StreamTcpFreeConfig(true);
1628  StatsThreadCleanup(&th_v.stats);
1629  PASS;
1630 }
1631 
1632 /**
1633  * \brief Register the UNITTESTS for the http_stat_code keyword
1634  */
1636 {
1637  UtRegisterTest("DetectEngineHttpStatCodeTest01", DetectEngineHttpStatCodeTest01);
1638  UtRegisterTest("DetectEngineHttpStatCodeTest02", DetectEngineHttpStatCodeTest02);
1639  UtRegisterTest("DetectEngineHttpStatCodeTest03", DetectEngineHttpStatCodeTest03);
1640  UtRegisterTest("DetectEngineHttpStatCodeTest04", DetectEngineHttpStatCodeTest04);
1641  UtRegisterTest("DetectEngineHttpStatCodeTest05", DetectEngineHttpStatCodeTest05);
1642  UtRegisterTest("DetectEngineHttpStatCodeTest06", DetectEngineHttpStatCodeTest06);
1643  UtRegisterTest("DetectEngineHttpStatCodeTest07", DetectEngineHttpStatCodeTest07);
1644  UtRegisterTest("DetectEngineHttpStatCodeTest08", DetectEngineHttpStatCodeTest08);
1645  UtRegisterTest("DetectEngineHttpStatCodeTest09", DetectEngineHttpStatCodeTest09);
1646  UtRegisterTest("DetectEngineHttpStatCodeTest10", DetectEngineHttpStatCodeTest10);
1647  UtRegisterTest("DetectEngineHttpStatCodeTest11", DetectEngineHttpStatCodeTest11);
1648  UtRegisterTest("DetectEngineHttpStatCodeTest12", DetectEngineHttpStatCodeTest12);
1649  UtRegisterTest("DetectEngineHttpStatCodeTest13", DetectEngineHttpStatCodeTest13);
1650  UtRegisterTest("DetectEngineHttpStatCodeTest14", DetectEngineHttpStatCodeTest14);
1651  UtRegisterTest("DetectEngineHttpStatCodeTest15", DetectEngineHttpStatCodeTest15);
1652 
1653  UtRegisterTest("DetectHttpStatCodeSigTest01", DetectHttpStatCodeSigTest01);
1654  UtRegisterTest("DetectHttpStatCodeSigTest02", DetectHttpStatCodeSigTest02);
1655  UtRegisterTest("DetectHttpStatCodeSigTest03", DetectHttpStatCodeSigTest03);
1656  UtRegisterTest("DetectHttpStatCodeSigTest04", DetectHttpStatCodeSigTest04);
1657 }
1658 
1659 /**
1660  * @}
1661  */
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1268
DetectHttpStatCodeRegisterTests
void DetectHttpStatCodeRegisterTests(void)
Register the UNITTESTS for the http_stat_code keyword.
Definition: detect-http-stat-code.c:1635
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Flow_::proto
uint8_t proto
Definition: flow.h:370
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:142
Packet_::flags
uint32_t flags
Definition: decode.h:544
Flow_
Flow data structure.
Definition: flow.h:348
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:933
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2634
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:324
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:225
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
UTHBuildPacket
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.
Definition: util-unittest-helper.c:365
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2418
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3447
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:532
Flow_::protoctx
void * protoctx
Definition: flow.h:433
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:100
HtpState_
Definition: app-layer-htp.h:181
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:496
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1245
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:23
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3364
Packet_
Definition: decode.h:501
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:226
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2194
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1258
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:297
Packet_::flow
struct Flow_ * flow
Definition: decode.h:546
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:867
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1277
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3601
Flow_::alstate
void * alstate
Definition: flow.h:471
Flow_::flags
uint32_t flags
Definition: flow.h:413
Signature_
Signature container.
Definition: detect.h:668
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:227
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2595
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:935
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:60
TcpSession_
Definition: stream-tcp-private.h:283
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:442
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1354
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1264
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:456