suricata
detect-http-method.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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  *
29  * \brief Handle HTTP method match
30  *
31  */
32 
33 #include "../suricata-common.h"
34 #include "../suricata.h"
35 #include "../flow-util.h"
36 #include "../flow.h"
37 #include "../app-layer-parser.h"
38 #include "../conf.h"
39 #include "../conf-yaml-loader.h"
40 #include "../util-unittest.h"
41 #include "../util-unittest-helper.h"
42 #include "../app-layer.h"
43 #include "../app-layer-htp.h"
44 #include "../app-layer-protos.h"
45 #include "../detect-isdataat.h"
46 #include "../detect-engine-build.h"
47 #include "../detect-engine-alert.h"
48 
49 struct TestSteps {
50  const uint8_t *input;
51  size_t input_size; /**< if 0 strlen will be used */
52  int direction; /**< STREAM_TOSERVER, STREAM_TOCLIENT */
53  int expect;
54 };
55 
56 static int RunTest(struct TestSteps *steps, const char *sig, const char *yaml)
57 {
58  TcpSession ssn;
59  Flow f;
60  ThreadVars th_v;
61  DetectEngineThreadCtx *det_ctx = NULL;
64 
65  memset(&th_v, 0, sizeof(th_v));
66  memset(&f, 0, sizeof(f));
67  memset(&ssn, 0, sizeof(ssn));
68 
69  if (yaml) {
71  SCConfInit();
73 
74  SCConfYamlLoadString(yaml, strlen(yaml));
75  HTPConfigure();
76  }
77 
78  StreamTcpInitConfig(true);
79 
82  de_ctx->flags |= DE_QUIET;
83 
84  FLOW_INITIALIZE(&f);
85  f.protoctx = (void *)&ssn;
86  f.proto = IPPROTO_TCP;
87  f.flags |= FLOW_IPV4;
89 
90  SCLogDebug("sig %s", sig);
91  Signature *s = DetectEngineAppendSig(de_ctx, (char *)sig);
92  FAIL_IF_NULL(s);
93 
95  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
96  FAIL_IF_NULL(det_ctx);
97 
98  struct TestSteps *b = steps;
99  int i = 0;
100  while (b->input != NULL) {
101  SCLogDebug("chunk %p %d", b, i);
102  (void)i;
103  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
104  FAIL_IF_NULL(p);
105  p->flow = &f;
106  p->flowflags = (b->direction == STREAM_TOSERVER) ? FLOW_PKT_TOSERVER : FLOW_PKT_TOCLIENT;
109 
110  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, b->direction,
111  (uint8_t *)b->input,
112  b->input_size ? b->input_size : strlen((const char *)b->input));
113  FAIL_IF_NOT(r == 0);
114 
115  /* do detect */
116  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
117 
118  int match = PacketAlertCheck(p, 1);
119  FAIL_IF_NOT(b->expect == match);
120 
121  UTHFreePackets(&p, 1);
122  b++;
123  i++;
124  }
125 
126  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
129 
130  StreamTcpFreeConfig(true);
131  FLOW_DESTROY(&f);
132 
133  if (yaml) {
134  HTPFreeConfig();
135  SCConfDeInit();
138  }
139  StatsThreadCleanup(&th_v);
140  PASS;
141 }
142 
143 static int DetectEngineHttpMethodTest01(void)
144 {
145  struct TestSteps steps[] = {
146  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
147  "Host: www.openinfosecfoundation.org\r\n"
148  "\r\n",
149  0, STREAM_TOSERVER, 1 },
150  { NULL, 0, 0, 0 },
151  };
152 
153  const char *sig = "alert http any any -> any any (content:\"GET\"; http_method; sid:1;)";
154  return RunTest(steps, sig, NULL);
155 }
156 
157 static int DetectEngineHttpMethodTest02(void)
158 {
159  struct TestSteps steps[] = {
160  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
161  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
162  0, STREAM_TOSERVER, 1 },
163  { NULL, 0, 0, 0 },
164  };
165 
166  const char *sig =
167  "alert http any any -> any any (content:\"CO\"; depth:4; http_method; sid:1;)";
168  return RunTest(steps, sig, NULL);
169 }
170 
171 static int DetectEngineHttpMethodTest03(void)
172 {
173  struct TestSteps steps[] = {
174  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
175  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
176  0, STREAM_TOSERVER, 1 },
177  { NULL, 0, 0, 0 },
178  };
179 
180  const char *sig =
181  "alert http any any -> any any (content:!\"ECT\"; depth:4; http_method; sid:1;)";
182  return RunTest(steps, sig, NULL);
183 }
184 
185 static int DetectEngineHttpMethodTest04(void)
186 {
187  struct TestSteps steps[] = {
188  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
189  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
190  0, STREAM_TOSERVER, 0 },
191  { NULL, 0, 0, 0 },
192  };
193 
194  const char *sig =
195  "alert http any any -> any any (content:\"ECT\"; depth:4; http_method; sid:1;)";
196  return RunTest(steps, sig, NULL);
197 }
198 
199 static int DetectEngineHttpMethodTest05(void)
200 {
201  struct TestSteps steps[] = {
202  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
203  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
204  0, STREAM_TOSERVER, 0 },
205  { NULL, 0, 0, 0 },
206  };
207 
208  const char *sig =
209  "alert http any any -> any any (content:!\"CON\"; depth:4; http_method; sid:1;)";
210  return RunTest(steps, sig, NULL);
211 }
212 
213 static int DetectEngineHttpMethodTest06(void)
214 {
215  struct TestSteps steps[] = {
216  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
217  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
218  0, STREAM_TOSERVER, 1 },
219  { NULL, 0, 0, 0 },
220  };
221 
222  const char *sig =
223  "alert http any any -> any any (content:\"ECT\"; offset:3; http_method; sid:1;)";
224  return RunTest(steps, sig, NULL);
225 }
226 
227 static int DetectEngineHttpMethodTest07(void)
228 {
229  struct TestSteps steps[] = {
230  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
231  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
232  0, STREAM_TOSERVER, 1 },
233  { NULL, 0, 0, 0 },
234  };
235 
236  const char *sig =
237  "alert http any any -> any any (content:!\"CO\"; offset:3; http_method; sid:1;)";
238  return RunTest(steps, sig, NULL);
239 }
240 
241 static int DetectEngineHttpMethodTest08(void)
242 {
243  struct TestSteps steps[] = {
244  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
245  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
246  0, STREAM_TOSERVER, 0 },
247  { NULL, 0, 0, 0 },
248  };
249 
250  const char *sig =
251  "alert http any any -> any any (content:!\"ECT\"; offset:3; http_method; sid:1;)";
252  return RunTest(steps, sig, NULL);
253 }
254 
255 static int DetectEngineHttpMethodTest09(void)
256 {
257  struct TestSteps steps[] = {
258  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
259  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
260  0, STREAM_TOSERVER, 0 },
261  { NULL, 0, 0, 0 },
262  };
263 
264  const char *sig =
265  "alert http any any -> any any (content:\"CON\"; offset:3; http_method; sid:1;)";
266  return RunTest(steps, sig, NULL);
267 }
268 
269 static int DetectEngineHttpMethodTest10(void)
270 {
271  struct TestSteps steps[] = {
272  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
273  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
274  0, STREAM_TOSERVER, 1 },
275  { NULL, 0, 0, 0 },
276  };
277 
278  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
279  "within:4; http_method; sid:1;)";
280  return RunTest(steps, sig, NULL);
281 }
282 
283 static int DetectEngineHttpMethodTest11(void)
284 {
285  struct TestSteps steps[] = {
286  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
287  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
288  0, STREAM_TOSERVER, 1 },
289  { NULL, 0, 0, 0 },
290  };
291 
292  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
293  "content:!\"EC\"; within:3; http_method; sid:1;)";
294  return RunTest(steps, sig, NULL);
295 }
296 
297 static int DetectEngineHttpMethodTest12(void)
298 {
299  struct TestSteps steps[] = {
300  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
301  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
302  0, STREAM_TOSERVER, 0 },
303  { NULL, 0, 0, 0 },
304  };
305 
306  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
307  "within:3; http_method; sid:1;)";
308  return RunTest(steps, sig, NULL);
309 }
310 
311 static int DetectEngineHttpMethodTest13(void)
312 {
313  struct TestSteps steps[] = {
314  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
315  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
316  0, STREAM_TOSERVER, 0 },
317  { NULL, 0, 0, 0 },
318  };
319 
320  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
321  "content:!\"EC\"; within:4; http_method; sid:1;)";
322  return RunTest(steps, sig, NULL);
323 }
324 
325 static int DetectEngineHttpMethodTest14(void)
326 {
327  struct TestSteps steps[] = {
328  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
329  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
330  0, STREAM_TOSERVER, 1 },
331  { NULL, 0, 0, 0 },
332  };
333 
334  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
335  "distance:2; http_method; sid:1;)";
336  return RunTest(steps, sig, NULL);
337 }
338 
339 static int DetectEngineHttpMethodTest15(void)
340 {
341  struct TestSteps steps[] = {
342  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
343  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
344  0, STREAM_TOSERVER, 1 },
345  { NULL, 0, 0, 0 },
346  };
347 
348  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
349  "content:!\"EC\"; distance:3; http_method; sid:1;)";
350  return RunTest(steps, sig, NULL);
351 }
352 
353 static int DetectEngineHttpMethodTest16(void)
354 {
355  struct TestSteps steps[] = {
356  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
357  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
358  0, STREAM_TOSERVER, 0 },
359  { NULL, 0, 0, 0 },
360  };
361 
362  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
363  "distance:3; http_method; sid:1;)";
364  return RunTest(steps, sig, NULL);
365 }
366 
367 static int DetectEngineHttpMethodTest17(void)
368 {
369  struct TestSteps steps[] = {
370  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
371  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
372  0, STREAM_TOSERVER, 0 },
373  { NULL, 0, 0, 0 },
374  };
375 
376  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
377  "content:!\"EC\"; distance:2; http_method; sid:1;)";
378  return RunTest(steps, sig, NULL);
379 }
380 
381 /** \test Check a signature with content */
382 static int DetectHttpMethodTest01(void)
383 {
386  de_ctx->flags |= DE_QUIET;
387  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
388  "(msg:\"Testing http_method\"; "
389  "content:\"GET\"; "
390  "http_method; sid:1;)");
391  FAIL_IF_NULL(s);
393  PASS;
394 }
395 
396 /** \test Check a signature without content (fail) */
397 static int DetectHttpMethodTest02(void)
398 {
401  de_ctx->flags |= DE_QUIET;
402  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
403  "(msg:\"Testing http_method\"; "
404  "http_method; sid:1;)");
405  FAIL_IF_NOT_NULL(s);
407  PASS;
408 }
409 
410 /** \test Check a signature with parameter (fail) */
411 static int DetectHttpMethodTest03(void)
412 {
415  de_ctx->flags |= DE_QUIET;
416  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
417  "(msg:\"Testing http_method\"; "
418  "content:\"foobar\"; "
419  "http_method:\"GET\"; sid:1;)");
420  FAIL_IF_NOT_NULL(s);
422  PASS;
423 }
424 
425 /** \test Check a signature with fast_pattern (should work) */
426 static int DetectHttpMethodTest04(void)
427 {
430  de_ctx->flags |= DE_QUIET;
431  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
432  "(msg:\"Testing http_method\"; "
433  "content:\"GET\"; "
434  "fast_pattern; "
435  "http_method; sid:1;)");
436  FAIL_IF_NULL(s);
438  PASS;
439 }
440 
441 /** \test Check a signature with rawbytes (fail) */
442 static int DetectHttpMethodTest05(void)
443 {
446  de_ctx->flags |= DE_QUIET;
447  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
448  "(msg:\"Testing http_method\"; "
449  "content:\"GET\"; "
450  "rawbytes; "
451  "http_method; sid:1;)");
452  FAIL_IF_NOT_NULL(s);
454  PASS;
455 }
456 
457 /** \test Check a signature with an known request method */
458 static int DetectHttpMethodSigTest01(void)
459 {
460  Flow f;
461  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
462  "Host: foo.bar.tld\r\n"
463  "\r\n";
464  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
465  TcpSession ssn;
466  ThreadVars th_v;
467  DetectEngineThreadCtx *det_ctx;
468  HtpState *http_state = NULL;
470 
471  memset(&th_v, 0, sizeof(th_v));
472  memset(&f, 0, sizeof(f));
473  memset(&ssn, 0, sizeof(ssn));
474 
475  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
476 
477  FLOW_INITIALIZE(&f);
478  f.protoctx = (void *)&ssn;
479  f.proto = IPPROTO_TCP;
480  f.flags |= FLOW_IPV4;
481 
482  p->flow = &f;
487 
488  StreamTcpInitConfig(true);
489 
492  de_ctx->flags |= DE_QUIET;
493 
494  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
495  "(msg:\"Testing http_method\"; "
496  "content:\"GET\"; "
497  "http_method; sid:1;)");
498  FAIL_IF_NULL(s);
499  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
500  "(msg:\"Testing http_method\"; "
501  "content:\"POST\"; "
502  "http_method; sid:2;)");
503  FAIL_IF_NULL(s);
504 
506  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
507 
508  int r = AppLayerParserParse(
509  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
510  FAIL_IF(r != 0);
511 
512  http_state = f.alstate;
513  FAIL_IF_NULL(http_state);
514 
515  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
516 
517  FAIL_IF(!(PacketAlertCheck(p, 1)));
518  FAIL_IF(PacketAlertCheck(p, 2));
519 
520  UTHFreePackets(&p, 1);
521  FLOW_DESTROY(&f);
522 
524  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
526  StreamTcpFreeConfig(true);
527  StatsThreadCleanup(&th_v);
528  PASS;
529 }
530 
531 /** \test Check a signature with an unknown request method */
532 static int DetectHttpMethodSigTest02(void)
533 {
534  Flow f;
535  uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n"
536  "Host: foo.bar.tld\r\n"
537  "\r\n";
538  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
539  TcpSession ssn;
540  ThreadVars th_v;
541  DetectEngineThreadCtx *det_ctx = NULL;
542  HtpState *http_state = NULL;
544 
545  memset(&th_v, 0, sizeof(th_v));
546  memset(&f, 0, sizeof(f));
547  memset(&ssn, 0, sizeof(ssn));
548 
549  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
550 
551  FLOW_INITIALIZE(&f);
552  f.protoctx = (void *)&ssn;
553  f.proto = IPPROTO_TCP;
554  f.flags |= FLOW_IPV4;
555 
556  p->flow = &f;
561 
562  StreamTcpInitConfig(true);
563 
566  de_ctx->flags |= DE_QUIET;
567 
568  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
569  "(msg:\"Testing http_method\"; "
570  "content:\"FOO\"; "
571  "http_method; sid:1;)");
572  FAIL_IF_NULL(s);
573  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
574  "(msg:\"Testing http_method\"; "
575  "content:\"BAR\"; "
576  "http_method; sid:2;)");
577  FAIL_IF_NULL(s);
578 
580  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
581 
582  int r = AppLayerParserParse(
583  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
584  FAIL_IF(r != 0);
585  http_state = f.alstate;
586  FAIL_IF_NULL(http_state);
587  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
588 
589  FAIL_IF(!(PacketAlertCheck(p, 1)));
590  FAIL_IF(PacketAlertCheck(p, 2));
591 
592  UTHFreePackets(&p, 1);
593  FLOW_DESTROY(&f);
594 
596  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
598  StreamTcpFreeConfig(true);
599  StatsThreadCleanup(&th_v);
600  PASS;
601 }
602 
603 /** \test Check a signature against an unparsable request */
604 static int DetectHttpMethodSigTest03(void)
605 {
606  Flow f;
607  uint8_t httpbuf1[] = " ";
608  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
609  TcpSession ssn;
610  Packet *p = NULL;
611  ThreadVars th_v;
612  DetectEngineThreadCtx *det_ctx;
613  HtpState *http_state = NULL;
615 
616  memset(&th_v, 0, sizeof(th_v));
617  memset(&f, 0, sizeof(f));
618  memset(&ssn, 0, sizeof(ssn));
619 
620  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
621 
622  FLOW_INITIALIZE(&f);
623  f.protoctx = (void *)&ssn;
624  f.proto = IPPROTO_TCP;
625  f.flags |= FLOW_IPV4;
626 
627  p->flow = &f;
632 
633  StreamTcpInitConfig(true);
634 
637  de_ctx->flags |= DE_QUIET;
638 
639  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
640  "(msg:\"Testing http_method\"; "
641  "content:\"GET\"; "
642  "http_method; sid:1;)");
643  FAIL_IF_NULL(s);
644 
646  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
647 
648  int r = AppLayerParserParse(
649  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
650  FAIL_IF(r != 0);
651  http_state = f.alstate;
652  FAIL_IF_NULL(http_state);
653 
654  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
655  FAIL_IF(PacketAlertCheck(p, 1));
656 
657  UTHFreePackets(&p, 1);
658  FLOW_DESTROY(&f);
660  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
662  StreamTcpFreeConfig(true);
663  StatsThreadCleanup(&th_v);
664  PASS;
665 }
666 
667 /** \test Check a signature with an request method and negation of the same */
668 static int DetectHttpMethodSigTest04(void)
669 {
670  Flow f;
671  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
672  "Host: foo.bar.tld\r\n"
673  "\r\n";
674  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
675  TcpSession ssn;
676  Packet *p = NULL;
677  ThreadVars th_v;
678  DetectEngineThreadCtx *det_ctx = NULL;
679  HtpState *http_state = NULL;
681 
682  memset(&th_v, 0, sizeof(th_v));
683  memset(&f, 0, sizeof(f));
684  memset(&ssn, 0, sizeof(ssn));
685 
686  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
687 
688  FLOW_INITIALIZE(&f);
689  f.protoctx = (void *)&ssn;
690  f.proto = IPPROTO_TCP;
691  f.flags |= FLOW_IPV4;
692 
693  p->flow = &f;
698 
699  StreamTcpInitConfig(true);
700 
703  de_ctx->flags |= DE_QUIET;
704 
706  "alert tcp any any -> any any (msg:\"Testing http_method\"; "
707  "content:\"GET\"; http_method; sid:1;)");
708  FAIL_IF_NULL(s);
709 
710  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"Testing http_method\"; "
711  "content:!\"GET\"; http_method; sid:2;)");
712  FAIL_IF_NULL(s);
713 
715  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
716 
717  int r = AppLayerParserParse(
718  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
719  FAIL_IF(r != 0);
720 
721  http_state = f.alstate;
722  FAIL_IF_NULL(http_state);
723 
724  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
725 
726  FAIL_IF(!(PacketAlertCheck(p, 1)));
727  FAIL_IF(PacketAlertCheck(p, 2));
728 
729  UTHFreePackets(&p, 1);
730  FLOW_DESTROY(&f);
732  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
734  StreamTcpFreeConfig(true);
735  StatsThreadCleanup(&th_v);
736  PASS;
737 }
738 
739 static int DetectHttpMethodIsdataatParseTest(void)
740 {
743  de_ctx->flags |= DE_QUIET;
744 
746  "alert tcp any any -> any any ("
747  "content:\"one\"; http_method; "
748  "isdataat:!4,relative; sid:1;)");
749  FAIL_IF_NULL(s);
750 
751  SigMatch *sm = DetectBufferGetLastSigMatch(s, g_http_method_buffer_id);
752  FAIL_IF_NULL(sm);
754 
759 
761  PASS;
762 }
763 
764 /**
765  * \brief this function registers unit tests for DetectHttpMethod
766  */
768 {
769  UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01);
770  UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02);
771  UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03);
772  UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04);
773  UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05);
774  UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01);
775  UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02);
776  UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03);
777  UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04);
778 
779  UtRegisterTest("DetectHttpMethodIsdataatParseTest",
780  DetectHttpMethodIsdataatParseTest);
781  UtRegisterTest("DetectEngineHttpMethodTest01",
782  DetectEngineHttpMethodTest01);
783  UtRegisterTest("DetectEngineHttpMethodTest02",
784  DetectEngineHttpMethodTest02);
785  UtRegisterTest("DetectEngineHttpMethodTest03",
786  DetectEngineHttpMethodTest03);
787  UtRegisterTest("DetectEngineHttpMethodTest04",
788  DetectEngineHttpMethodTest04);
789  UtRegisterTest("DetectEngineHttpMethodTest05",
790  DetectEngineHttpMethodTest05);
791  UtRegisterTest("DetectEngineHttpMethodTest06",
792  DetectEngineHttpMethodTest06);
793  UtRegisterTest("DetectEngineHttpMethodTest07",
794  DetectEngineHttpMethodTest07);
795  UtRegisterTest("DetectEngineHttpMethodTest08",
796  DetectEngineHttpMethodTest08);
797  UtRegisterTest("DetectEngineHttpMethodTest09",
798  DetectEngineHttpMethodTest09);
799  UtRegisterTest("DetectEngineHttpMethodTest10",
800  DetectEngineHttpMethodTest10);
801  UtRegisterTest("DetectEngineHttpMethodTest11",
802  DetectEngineHttpMethodTest11);
803  UtRegisterTest("DetectEngineHttpMethodTest12",
804  DetectEngineHttpMethodTest12);
805  UtRegisterTest("DetectEngineHttpMethodTest13",
806  DetectEngineHttpMethodTest13);
807  UtRegisterTest("DetectEngineHttpMethodTest14",
808  DetectEngineHttpMethodTest14);
809  UtRegisterTest("DetectEngineHttpMethodTest15",
810  DetectEngineHttpMethodTest15);
811  UtRegisterTest("DetectEngineHttpMethodTest16",
812  DetectEngineHttpMethodTest16);
813  UtRegisterTest("DetectEngineHttpMethodTest17",
814  DetectEngineHttpMethodTest17);
815 }
816 
817 /**
818  * @}
819  */
TestSteps
Definition: detect-http-client-body.c:107
SCConfYamlLoadString
int SCConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:523
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
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DetectIsdataatData_::flags
uint8_t flags
Definition: detect-isdataat.h:34
TestSteps::direction
int direction
Definition: detect-http-client-body.c:110
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
TestSteps::input
const uint8_t * input
Definition: detect-http-client-body.c:108
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:932
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:2416
DetectIsdataatData_
Definition: detect-isdataat.h:32
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3439
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
HTPConfigure
void HTPConfigure(void)
Definition: app-layer-htp.c:2351
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
SCConfInit
void SCConfInit(void)
Initialize the configuration system.
Definition: conf.c:120
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:488
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
TestSteps::expect
int expect
Definition: detect-http-client-body.c:111
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
HtpConfigCreateBackup
void HtpConfigCreateBackup(void)
Definition: app-layer-htp.c:2687
DetectBufferGetLastSigMatch
SigMatch * DetectBufferGetLastSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine-buffer.c:167
DetectEngineThreadCtx_
Definition: detect.h:1244
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
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:359
DetectHttpMethodRegisterTests
void DetectHttpMethodRegisterTests(void)
this function registers unit tests for DetectHttpMethod
Definition: detect-http-method.c:767
Packet_
Definition: decode.h:501
ISDATAAT_RELATIVE
#define ISDATAAT_RELATIVE
Definition: detect-isdataat.h:27
ISDATAAT_RAWBYTES
#define ISDATAAT_RAWBYTES
Definition: detect-isdataat.h:28
SCConfCreateContextBackup
void SCConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition: conf.c:684
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
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:859
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:1291
SigMatch_::type
uint16_t type
Definition: detect.h:357
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3596
SCConfDeInit
void SCConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:703
HtpConfigRestoreBackup
void HtpConfigRestoreBackup(void)
Definition: app-layer-htp.c:2692
ISDATAAT_NEGATED
#define ISDATAAT_NEGATED
Definition: detect-isdataat.h:29
Flow_::alstate
void * alstate
Definition: flow.h:471
Flow_::flags
uint32_t flags
Definition: flow.h:413
SCConfRestoreContextBackup
void SCConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:694
Signature_
Signature container.
Definition: detect.h:668
SigMatch_
a single match condition for a signature
Definition: detect.h:356
DETECT_ISDATAAT
@ DETECT_ISDATAAT
Definition: detect-engine-register.h:93
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:934
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:60
TcpSession_
Definition: stream-tcp-private.h:283
HTPFreeConfig
void HTPFreeConfig(void)
Clears the HTTP server configuration memory used by HTP library.
Definition: app-layer-htp.c:1591
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:442
StatsThreadCleanup
void StatsThreadCleanup(ThreadVars *tv)
Definition: counters.c:1324
TestSteps::input_size
size_t input_size
Definition: detect-http-client-body.c:109
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