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  StatsThreadInit(&th_v.stats);
67  memset(&f, 0, sizeof(f));
68  memset(&ssn, 0, sizeof(ssn));
69 
70  if (yaml) {
72  SCConfInit();
74 
75  SCConfYamlLoadString(yaml, strlen(yaml));
76  HTPConfigure();
77  }
78 
79  StreamTcpInitConfig(true);
80 
83  de_ctx->flags |= DE_QUIET;
84 
85  FLOW_INITIALIZE(&f);
86  f.protoctx = (void *)&ssn;
87  f.proto = IPPROTO_TCP;
88  f.flags |= FLOW_IPV4;
90 
91  SCLogDebug("sig %s", sig);
92  Signature *s = DetectEngineAppendSig(de_ctx, (char *)sig);
93  FAIL_IF_NULL(s);
94 
96  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
97  FAIL_IF_NULL(det_ctx);
98 
99  struct TestSteps *b = steps;
100  int i = 0;
101  while (b->input != NULL) {
102  SCLogDebug("chunk %p %d", b, i);
103  (void)i;
104  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
105  FAIL_IF_NULL(p);
106  p->flow = &f;
107  p->flowflags = (b->direction == STREAM_TOSERVER) ? FLOW_PKT_TOSERVER : FLOW_PKT_TOCLIENT;
110 
111  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, b->direction,
112  (uint8_t *)b->input,
113  b->input_size ? b->input_size : strlen((const char *)b->input));
114  FAIL_IF_NOT(r == 0);
115 
116  /* do detect */
117  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
118 
119  int match = PacketAlertCheck(p, 1);
120  FAIL_IF_NOT(b->expect == match);
121 
122  UTHFreePackets(&p, 1);
123  b++;
124  i++;
125  }
126 
127  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
130 
131  StreamTcpFreeConfig(true);
132  FLOW_DESTROY(&f);
133 
134  if (yaml) {
135  HTPFreeConfig();
136  SCConfDeInit();
139  }
140  StatsThreadCleanup(&th_v.stats);
141  PASS;
142 }
143 
144 static int DetectEngineHttpMethodTest01(void)
145 {
146  struct TestSteps steps[] = {
147  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
148  "Host: www.openinfosecfoundation.org\r\n"
149  "\r\n",
150  0, STREAM_TOSERVER, 1 },
151  { NULL, 0, 0, 0 },
152  };
153 
154  const char *sig = "alert http any any -> any any (content:\"GET\"; http_method; sid:1;)";
155  return RunTest(steps, sig, NULL);
156 }
157 
158 static int DetectEngineHttpMethodTest02(void)
159 {
160  struct TestSteps steps[] = {
161  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
162  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
163  0, STREAM_TOSERVER, 1 },
164  { NULL, 0, 0, 0 },
165  };
166 
167  const char *sig =
168  "alert http any any -> any any (content:\"CO\"; depth:4; http_method; sid:1;)";
169  return RunTest(steps, sig, NULL);
170 }
171 
172 static int DetectEngineHttpMethodTest03(void)
173 {
174  struct TestSteps steps[] = {
175  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
176  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
177  0, STREAM_TOSERVER, 1 },
178  { NULL, 0, 0, 0 },
179  };
180 
181  const char *sig =
182  "alert http any any -> any any (content:!\"ECT\"; depth:4; http_method; sid:1;)";
183  return RunTest(steps, sig, NULL);
184 }
185 
186 static int DetectEngineHttpMethodTest04(void)
187 {
188  struct TestSteps steps[] = {
189  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
190  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
191  0, STREAM_TOSERVER, 0 },
192  { NULL, 0, 0, 0 },
193  };
194 
195  const char *sig =
196  "alert http any any -> any any (content:\"ECT\"; depth:4; http_method; sid:1;)";
197  return RunTest(steps, sig, NULL);
198 }
199 
200 static int DetectEngineHttpMethodTest05(void)
201 {
202  struct TestSteps steps[] = {
203  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
204  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
205  0, STREAM_TOSERVER, 0 },
206  { NULL, 0, 0, 0 },
207  };
208 
209  const char *sig =
210  "alert http any any -> any any (content:!\"CON\"; depth:4; http_method; sid:1;)";
211  return RunTest(steps, sig, NULL);
212 }
213 
214 static int DetectEngineHttpMethodTest06(void)
215 {
216  struct TestSteps steps[] = {
217  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
218  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
219  0, STREAM_TOSERVER, 1 },
220  { NULL, 0, 0, 0 },
221  };
222 
223  const char *sig =
224  "alert http any any -> any any (content:\"ECT\"; offset:3; http_method; sid:1;)";
225  return RunTest(steps, sig, NULL);
226 }
227 
228 static int DetectEngineHttpMethodTest07(void)
229 {
230  struct TestSteps steps[] = {
231  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
232  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
233  0, STREAM_TOSERVER, 1 },
234  { NULL, 0, 0, 0 },
235  };
236 
237  const char *sig =
238  "alert http any any -> any any (content:!\"CO\"; offset:3; http_method; sid:1;)";
239  return RunTest(steps, sig, NULL);
240 }
241 
242 static int DetectEngineHttpMethodTest08(void)
243 {
244  struct TestSteps steps[] = {
245  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
246  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
247  0, STREAM_TOSERVER, 0 },
248  { NULL, 0, 0, 0 },
249  };
250 
251  const char *sig =
252  "alert http any any -> any any (content:!\"ECT\"; offset:3; http_method; sid:1;)";
253  return RunTest(steps, sig, NULL);
254 }
255 
256 static int DetectEngineHttpMethodTest09(void)
257 {
258  struct TestSteps steps[] = {
259  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
260  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
261  0, STREAM_TOSERVER, 0 },
262  { NULL, 0, 0, 0 },
263  };
264 
265  const char *sig =
266  "alert http any any -> any any (content:\"CON\"; offset:3; http_method; sid:1;)";
267  return RunTest(steps, sig, NULL);
268 }
269 
270 static int DetectEngineHttpMethodTest10(void)
271 {
272  struct TestSteps steps[] = {
273  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
274  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
275  0, STREAM_TOSERVER, 1 },
276  { NULL, 0, 0, 0 },
277  };
278 
279  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
280  "within:4; http_method; sid:1;)";
281  return RunTest(steps, sig, NULL);
282 }
283 
284 static int DetectEngineHttpMethodTest11(void)
285 {
286  struct TestSteps steps[] = {
287  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
288  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
289  0, STREAM_TOSERVER, 1 },
290  { NULL, 0, 0, 0 },
291  };
292 
293  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
294  "content:!\"EC\"; within:3; http_method; sid:1;)";
295  return RunTest(steps, sig, NULL);
296 }
297 
298 static int DetectEngineHttpMethodTest12(void)
299 {
300  struct TestSteps steps[] = {
301  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
302  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
303  0, STREAM_TOSERVER, 0 },
304  { NULL, 0, 0, 0 },
305  };
306 
307  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
308  "within:3; http_method; sid:1;)";
309  return RunTest(steps, sig, NULL);
310 }
311 
312 static int DetectEngineHttpMethodTest13(void)
313 {
314  struct TestSteps steps[] = {
315  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
316  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
317  0, STREAM_TOSERVER, 0 },
318  { NULL, 0, 0, 0 },
319  };
320 
321  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
322  "content:!\"EC\"; within:4; http_method; sid:1;)";
323  return RunTest(steps, sig, NULL);
324 }
325 
326 static int DetectEngineHttpMethodTest14(void)
327 {
328  struct TestSteps steps[] = {
329  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
330  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
331  0, STREAM_TOSERVER, 1 },
332  { NULL, 0, 0, 0 },
333  };
334 
335  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
336  "distance:2; http_method; sid:1;)";
337  return RunTest(steps, sig, NULL);
338 }
339 
340 static int DetectEngineHttpMethodTest15(void)
341 {
342  struct TestSteps steps[] = {
343  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
344  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
345  0, STREAM_TOSERVER, 1 },
346  { NULL, 0, 0, 0 },
347  };
348 
349  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
350  "content:!\"EC\"; distance:3; http_method; sid:1;)";
351  return RunTest(steps, sig, NULL);
352 }
353 
354 static int DetectEngineHttpMethodTest16(void)
355 {
356  struct TestSteps steps[] = {
357  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
358  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
359  0, STREAM_TOSERVER, 0 },
360  { NULL, 0, 0, 0 },
361  };
362 
363  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; content:\"EC\"; "
364  "distance:3; http_method; sid:1;)";
365  return RunTest(steps, sig, NULL);
366 }
367 
368 static int DetectEngineHttpMethodTest17(void)
369 {
370  struct TestSteps steps[] = {
371  { (const uint8_t *)"CONNECT /index.html HTTP/1.0\r\n"
372  "Host: www.onetwothreefourfivesixseven.org\r\n\r\n",
373  0, STREAM_TOSERVER, 0 },
374  { NULL, 0, 0, 0 },
375  };
376 
377  const char *sig = "alert http any any -> any any (content:\"CO\"; http_method; "
378  "content:!\"EC\"; distance:2; http_method; sid:1;)";
379  return RunTest(steps, sig, NULL);
380 }
381 
382 /** \test Check a signature with content */
383 static int DetectHttpMethodTest01(void)
384 {
387  de_ctx->flags |= DE_QUIET;
388  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
389  "(msg:\"Testing http_method\"; "
390  "content:\"GET\"; "
391  "http_method; sid:1;)");
392  FAIL_IF_NULL(s);
394  PASS;
395 }
396 
397 /** \test Check a signature without content (fail) */
398 static int DetectHttpMethodTest02(void)
399 {
402  de_ctx->flags |= DE_QUIET;
403  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
404  "(msg:\"Testing http_method\"; "
405  "http_method; sid:1;)");
406  FAIL_IF_NOT_NULL(s);
408  PASS;
409 }
410 
411 /** \test Check a signature with parameter (fail) */
412 static int DetectHttpMethodTest03(void)
413 {
416  de_ctx->flags |= DE_QUIET;
417  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
418  "(msg:\"Testing http_method\"; "
419  "content:\"foobar\"; "
420  "http_method:\"GET\"; sid:1;)");
421  FAIL_IF_NOT_NULL(s);
423  PASS;
424 }
425 
426 /** \test Check a signature with fast_pattern (should work) */
427 static int DetectHttpMethodTest04(void)
428 {
431  de_ctx->flags |= DE_QUIET;
432  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
433  "(msg:\"Testing http_method\"; "
434  "content:\"GET\"; "
435  "fast_pattern; "
436  "http_method; sid:1;)");
437  FAIL_IF_NULL(s);
439  PASS;
440 }
441 
442 /** \test Check a signature with rawbytes (fail) */
443 static int DetectHttpMethodTest05(void)
444 {
447  de_ctx->flags |= DE_QUIET;
448  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
449  "(msg:\"Testing http_method\"; "
450  "content:\"GET\"; "
451  "rawbytes; "
452  "http_method; sid:1;)");
453  FAIL_IF_NOT_NULL(s);
455  PASS;
456 }
457 
458 /** \test Check a signature with an known request method */
459 static int DetectHttpMethodSigTest01(void)
460 {
461  Flow f;
462  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
463  "Host: foo.bar.tld\r\n"
464  "\r\n";
465  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
466  TcpSession ssn;
467  ThreadVars th_v;
468  DetectEngineThreadCtx *det_ctx;
469  HtpState *http_state = NULL;
471 
472  memset(&th_v, 0, sizeof(th_v));
473  StatsThreadInit(&th_v.stats);
474  memset(&f, 0, sizeof(f));
475  memset(&ssn, 0, sizeof(ssn));
476 
477  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
478 
479  FLOW_INITIALIZE(&f);
480  f.protoctx = (void *)&ssn;
481  f.proto = IPPROTO_TCP;
482  f.flags |= FLOW_IPV4;
483 
484  p->flow = &f;
489 
490  StreamTcpInitConfig(true);
491 
494  de_ctx->flags |= DE_QUIET;
495 
496  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
497  "(msg:\"Testing http_method\"; "
498  "content:\"GET\"; "
499  "http_method; sid:1;)");
500  FAIL_IF_NULL(s);
501  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
502  "(msg:\"Testing http_method\"; "
503  "content:\"POST\"; "
504  "http_method; sid:2;)");
505  FAIL_IF_NULL(s);
506 
508  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
509 
510  int r = AppLayerParserParse(
511  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
512  FAIL_IF(r != 0);
513 
514  http_state = f.alstate;
515  FAIL_IF_NULL(http_state);
516 
517  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
518 
519  FAIL_IF(!(PacketAlertCheck(p, 1)));
520  FAIL_IF(PacketAlertCheck(p, 2));
521 
522  UTHFreePackets(&p, 1);
523  FLOW_DESTROY(&f);
524 
526  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
528  StreamTcpFreeConfig(true);
529  StatsThreadCleanup(&th_v.stats);
530  PASS;
531 }
532 
533 /** \test Check a signature with an unknown request method */
534 static int DetectHttpMethodSigTest02(void)
535 {
536  Flow f;
537  uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n"
538  "Host: foo.bar.tld\r\n"
539  "\r\n";
540  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
541  TcpSession ssn;
542  ThreadVars th_v;
543  DetectEngineThreadCtx *det_ctx = NULL;
544  HtpState *http_state = NULL;
546 
547  memset(&th_v, 0, sizeof(th_v));
548  StatsThreadInit(&th_v.stats);
549  memset(&f, 0, sizeof(f));
550  memset(&ssn, 0, sizeof(ssn));
551 
552  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
553 
554  FLOW_INITIALIZE(&f);
555  f.protoctx = (void *)&ssn;
556  f.proto = IPPROTO_TCP;
557  f.flags |= FLOW_IPV4;
558 
559  p->flow = &f;
564 
565  StreamTcpInitConfig(true);
566 
569  de_ctx->flags |= DE_QUIET;
570 
571  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
572  "(msg:\"Testing http_method\"; "
573  "content:\"FOO\"; "
574  "http_method; sid:1;)");
575  FAIL_IF_NULL(s);
576  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
577  "(msg:\"Testing http_method\"; "
578  "content:\"BAR\"; "
579  "http_method; sid:2;)");
580  FAIL_IF_NULL(s);
581 
583  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
584 
585  int r = AppLayerParserParse(
586  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
587  FAIL_IF(r != 0);
588  http_state = f.alstate;
589  FAIL_IF_NULL(http_state);
590  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
591 
592  FAIL_IF(!(PacketAlertCheck(p, 1)));
593  FAIL_IF(PacketAlertCheck(p, 2));
594 
595  UTHFreePackets(&p, 1);
596  FLOW_DESTROY(&f);
597 
599  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
601  StreamTcpFreeConfig(true);
602  StatsThreadCleanup(&th_v.stats);
603  PASS;
604 }
605 
606 /** \test Check a signature against an unparsable request */
607 static int DetectHttpMethodSigTest03(void)
608 {
609  Flow f;
610  uint8_t httpbuf1[] = " ";
611  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
612  TcpSession ssn;
613  Packet *p = NULL;
614  ThreadVars th_v;
615  DetectEngineThreadCtx *det_ctx;
616  HtpState *http_state = NULL;
618 
619  memset(&th_v, 0, sizeof(th_v));
620  StatsThreadInit(&th_v.stats);
621  memset(&f, 0, sizeof(f));
622  memset(&ssn, 0, sizeof(ssn));
623 
624  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
625 
626  FLOW_INITIALIZE(&f);
627  f.protoctx = (void *)&ssn;
628  f.proto = IPPROTO_TCP;
629  f.flags |= FLOW_IPV4;
630 
631  p->flow = &f;
636 
637  StreamTcpInitConfig(true);
638 
641  de_ctx->flags |= DE_QUIET;
642 
643  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
644  "(msg:\"Testing http_method\"; "
645  "content:\"GET\"; "
646  "http_method; sid:1;)");
647  FAIL_IF_NULL(s);
648 
650  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
651 
652  int r = AppLayerParserParse(
653  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
654  FAIL_IF(r != 0);
655  http_state = f.alstate;
656  FAIL_IF_NULL(http_state);
657 
658  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
659  FAIL_IF(PacketAlertCheck(p, 1));
660 
661  UTHFreePackets(&p, 1);
662  FLOW_DESTROY(&f);
664  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
666  StreamTcpFreeConfig(true);
667  StatsThreadCleanup(&th_v.stats);
668  PASS;
669 }
670 
671 /** \test Check a signature with an request method and negation of the same */
672 static int DetectHttpMethodSigTest04(void)
673 {
674  Flow f;
675  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
676  "Host: foo.bar.tld\r\n"
677  "\r\n";
678  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
679  TcpSession ssn;
680  Packet *p = NULL;
681  ThreadVars th_v;
682  DetectEngineThreadCtx *det_ctx = NULL;
683  HtpState *http_state = NULL;
685 
686  memset(&th_v, 0, sizeof(th_v));
687  StatsThreadInit(&th_v.stats);
688  memset(&f, 0, sizeof(f));
689  memset(&ssn, 0, sizeof(ssn));
690 
691  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
692 
693  FLOW_INITIALIZE(&f);
694  f.protoctx = (void *)&ssn;
695  f.proto = IPPROTO_TCP;
696  f.flags |= FLOW_IPV4;
697 
698  p->flow = &f;
703 
704  StreamTcpInitConfig(true);
705 
708  de_ctx->flags |= DE_QUIET;
709 
711  "alert tcp any any -> any any (msg:\"Testing http_method\"; "
712  "content:\"GET\"; http_method; sid:1;)");
713  FAIL_IF_NULL(s);
714 
715  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"Testing http_method\"; "
716  "content:!\"GET\"; http_method; sid:2;)");
717  FAIL_IF_NULL(s);
718 
720  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
721 
722  int r = AppLayerParserParse(
723  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
724  FAIL_IF(r != 0);
725 
726  http_state = f.alstate;
727  FAIL_IF_NULL(http_state);
728 
729  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
730 
731  FAIL_IF(!(PacketAlertCheck(p, 1)));
732  FAIL_IF(PacketAlertCheck(p, 2));
733 
734  UTHFreePackets(&p, 1);
735  FLOW_DESTROY(&f);
737  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
739  StreamTcpFreeConfig(true);
740  StatsThreadCleanup(&th_v.stats);
741  PASS;
742 }
743 
744 static int DetectHttpMethodIsdataatParseTest(void)
745 {
748  de_ctx->flags |= DE_QUIET;
749 
751  "alert tcp any any -> any any ("
752  "content:\"one\"; http_method; "
753  "isdataat:!4,relative; sid:1;)");
754  FAIL_IF_NULL(s);
755 
756  SigMatch *sm = DetectBufferGetLastSigMatch(s, g_http_method_buffer_id);
757  FAIL_IF_NULL(sm);
759 
764 
766  PASS;
767 }
768 
769 /**
770  * \brief this function registers unit tests for DetectHttpMethod
771  */
773 {
774  UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01);
775  UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02);
776  UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03);
777  UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04);
778  UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05);
779  UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01);
780  UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02);
781  UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03);
782  UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04);
783 
784  UtRegisterTest("DetectHttpMethodIsdataatParseTest",
785  DetectHttpMethodIsdataatParseTest);
786  UtRegisterTest("DetectEngineHttpMethodTest01",
787  DetectEngineHttpMethodTest01);
788  UtRegisterTest("DetectEngineHttpMethodTest02",
789  DetectEngineHttpMethodTest02);
790  UtRegisterTest("DetectEngineHttpMethodTest03",
791  DetectEngineHttpMethodTest03);
792  UtRegisterTest("DetectEngineHttpMethodTest04",
793  DetectEngineHttpMethodTest04);
794  UtRegisterTest("DetectEngineHttpMethodTest05",
795  DetectEngineHttpMethodTest05);
796  UtRegisterTest("DetectEngineHttpMethodTest06",
797  DetectEngineHttpMethodTest06);
798  UtRegisterTest("DetectEngineHttpMethodTest07",
799  DetectEngineHttpMethodTest07);
800  UtRegisterTest("DetectEngineHttpMethodTest08",
801  DetectEngineHttpMethodTest08);
802  UtRegisterTest("DetectEngineHttpMethodTest09",
803  DetectEngineHttpMethodTest09);
804  UtRegisterTest("DetectEngineHttpMethodTest10",
805  DetectEngineHttpMethodTest10);
806  UtRegisterTest("DetectEngineHttpMethodTest11",
807  DetectEngineHttpMethodTest11);
808  UtRegisterTest("DetectEngineHttpMethodTest12",
809  DetectEngineHttpMethodTest12);
810  UtRegisterTest("DetectEngineHttpMethodTest13",
811  DetectEngineHttpMethodTest13);
812  UtRegisterTest("DetectEngineHttpMethodTest14",
813  DetectEngineHttpMethodTest14);
814  UtRegisterTest("DetectEngineHttpMethodTest15",
815  DetectEngineHttpMethodTest15);
816  UtRegisterTest("DetectEngineHttpMethodTest16",
817  DetectEngineHttpMethodTest16);
818  UtRegisterTest("DetectEngineHttpMethodTest17",
819  DetectEngineHttpMethodTest17);
820 }
821 
822 /**
823  * @}
824  */
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:535
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: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
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: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
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:496
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: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
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:359
DetectHttpMethodRegisterTests
void DetectHttpMethodRegisterTests(void)
this function registers unit tests for DetectHttpMethod
Definition: detect-http-method.c:772
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
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
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:3601
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:935
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
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1354
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