suricata
detect-http-client-body.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \ingroup httplayer
20  *
21  * @{
22  */
23 
24 
25 /** \file
26  *
27  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
28  * \author Victor Julien <victor@inliniac.net>
29  *
30  * \brief Handle HTTP request body match corresponding to http_client_body
31  * keyword.
32  *
33  */
34 
35 #include "../suricata-common.h"
36 #include "../suricata.h"
37 #include "../decode.h"
38 
39 #include "detect.h"
40 #include "detect-engine.h"
41 #include "detect-engine-mpm.h"
42 #include "detect-parse.h"
43 #include "detect-engine-state.h"
46 #include "detect-isdataat.h"
47 #include "stream-tcp-reassemble.h"
48 #include "detect-engine-build.h"
49 
50 #include "flow-util.h"
51 #include "util-debug.h"
52 #include "util-print.h"
53 #include "flow.h"
54 
55 #include "app-layer-parser.h"
56 
57 #include "stream-tcp.h"
58 
59 #include "util-unittest.h"
60 #include "util-unittest-helper.h"
61 #include "app-layer.h"
62 #include "app-layer-htp.h"
63 #include "app-layer-protos.h"
64 
65 #include "conf.h"
66 #include "conf-yaml-loader.h"
67 
68 #include "util-validate.h"
69 
70 #ifdef UNITTESTS
71 
72 /**
73  * \test Test parser accepting valid rules and rejecting invalid rules
74  */
75 static int DetectHttpClientBodyParserTest01(void)
76 {
77  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; http_client_body; sid:1;)", true));
78  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; nocase; http_client_body; sid:1;)", true));
79  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; endswith; http_client_body; sid:1;)", true));
80  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; http_client_body; sid:1;)", true));
81  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; endswith; http_client_body; sid:1;)", true));
82 
83  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; rawbytes; http_client_body; sid:1;)", false));
84  FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http_client_body; sid:1;)", false));
85  FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; content:\"abc\"; http_client_body; sid:1;)", false));
86  PASS;
87 }
88 
89 /**
90  * \test Test parser accepting valid rules and rejecting invalid rules
91  */
92 static int DetectHttpClientBodyParserTest02(void)
93 {
94  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; sid:1;)", true));
95  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; nocase; sid:1;)", true));
96  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; endswith; sid:1;)", true));
97  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; startswith; sid:1;)", true));
98  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; startswith; endswith; sid:1;)", true));
99  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; bsize:10; sid:1;)", true));
100 
101  FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.request_body; content:\"abc\"; rawbytes; sid:1;)", false));
102  FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http.request_body; sid:1;)", false));
103  FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; http.request_body; content:\"abc\"; sid:1;)", false));
104  PASS;
105 }
106 
107 struct TestSteps {
108  const uint8_t *input;
109  size_t input_size; /**< if 0 strlen will be used */
110  int direction; /**< STREAM_TOSERVER, STREAM_TOCLIENT */
111  int expect;
112 };
113 
114 static int RunTest (struct TestSteps *steps, const char *sig, const char *yaml)
115 {
116  TcpSession ssn;
117  Flow f;
118  ThreadVars th_v;
119  DetectEngineThreadCtx *det_ctx = NULL;
122 
123  memset(&th_v, 0, sizeof(th_v));
124  memset(&f, 0, sizeof(f));
125  memset(&ssn, 0, sizeof(ssn));
126 
127  if (yaml) {
129  ConfInit();
131 
132  ConfYamlLoadString(yaml, strlen(yaml));
133  HTPConfigure();
134  }
135 
136  StreamTcpInitConfig(true);
137 
140  de_ctx->flags |= DE_QUIET;
141 
142  FLOW_INITIALIZE(&f);
143  f.protoctx = (void *)&ssn;
144  f.proto = IPPROTO_TCP;
145  f.flags |= FLOW_IPV4;
147 
148  SCLogDebug("sig %s", sig);
149  Signature *s = DetectEngineAppendSig(de_ctx, (char *)sig);
150  FAIL_IF_NULL(s);
151 
153  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
154  FAIL_IF_NULL(det_ctx);
155 
156  struct TestSteps *b = steps;
157  int i = 0;
158  while (b->input != NULL) {
159  SCLogDebug("chunk %p %d", b, i);
160  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
161  FAIL_IF_NULL(p);
162  p->flow = &f;
163  p->flowflags = (b->direction == STREAM_TOSERVER) ? FLOW_PKT_TOSERVER : FLOW_PKT_TOCLIENT;
166 
167  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, b->direction,
168  (uint8_t *)b->input,
169  b->input_size ? b->input_size : strlen((const char *)b->input));
170  FAIL_IF_NOT(r == 0);
171 
172  /* do detect */
173  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
174 
175  int match = PacketAlertCheck(p, 1);
176  FAIL_IF_NOT (b->expect == match);
177 
178  UTHFreePackets(&p, 1);
179  b++;
180  i++;
181  }
182 
183  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
186 
187  StreamTcpFreeConfig(true);
188  FLOW_DESTROY(&f);
189 
190  if (yaml) {
193  }
194  PASS;
195 }
196 
197 static int DetectEngineHttpClientBodyTest01(void)
198 {
199  struct TestSteps steps[] = {
200  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
201  "Host: www.openinfosecfoundation.org\r\n"
202  "Content-Type: text/html\r\n"
203  "Content-Length: 46\r\n"
204  "\r\n"
205  "This is dummy body1",
206  0, STREAM_TOSERVER, 0 },
207  { (const uint8_t *)"This is dummy message body2",
208  0, STREAM_TOSERVER, 1 },
209  { NULL, 0, 0, 0 },
210  };
211 
212  const char *sig = "alert http any any -> any any (content:\"body1This\"; http_client_body; sid:1;)";
213  return RunTest(steps, sig, NULL);
214 }
215 
216 static int DetectEngineHttpClientBodyTest02(void)
217 {
218  struct TestSteps steps[] = {
219  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
220  "Host: www.openinfosecfoundation.org\r\n"
221  "Content-Type: text/html\r\n"
222  "Content-Length: 19\r\n"
223  "\r\n"
224  "This is dummy body1",
225  0, STREAM_TOSERVER, 1 },
226  { NULL, 0, 0, 0 },
227  };
228 
229  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:5; sid:1;)";
230  return RunTest(steps, sig, NULL);
231 }
232 
233 static int DetectEngineHttpClientBodyTest03(void)
234 {
235  struct TestSteps steps[] = {
236  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
237  "Host: www.openinfosecfoundation.org\r\n"
238  "Content-Type: text/html\r\n"
239  "Content-Length: 46\r\n"
240  "\r\n"
241  "This is dummy body1",
242  0, STREAM_TOSERVER, 0 },
243  { (const uint8_t *)"This is dummy message body2",
244  0, STREAM_TOSERVER, 0 },
245  { NULL, 0, 0, 0 },
246  };
247 
248  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:16; sid:1;)";
249  return RunTest(steps, sig, NULL);
250 }
251 
252 static int DetectEngineHttpClientBodyTest04(void)
253 {
254  struct TestSteps steps[] = {
255  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
256  "Host: www.openinfosecfoundation.org\r\n"
257  "Content-Type: text/html\r\n"
258  "Content-Length: 46\r\n"
259  "\r\n"
260  "This is dummy body1",
261  0, STREAM_TOSERVER, 0 },
262  { (const uint8_t *)"This is dummy message body2",
263  0, STREAM_TOSERVER, 1 },
264  { NULL, 0, 0, 0 },
265  };
266 
267  const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; offset:16; sid:1;)";
268  return RunTest(steps, sig, NULL);
269 }
270 
271 static int DetectEngineHttpClientBodyTest05(void)
272 {
273  struct TestSteps steps[] = {
274  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
275  "Host: www.openinfosecfoundation.org\r\n"
276  "Content-Type: text/html\r\n"
277  "Content-Length: 46\r\n"
278  "\r\n"
279  "This is dummy body1",
280  0, STREAM_TOSERVER, 0 },
281  { (const uint8_t *)"This is dummy message body2",
282  0, STREAM_TOSERVER, 1 },
283  { NULL, 0, 0, 0 },
284  };
285 
286  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; depth:25; sid:1;)";
287  return RunTest(steps, sig, NULL);
288 }
289 
290 static int DetectEngineHttpClientBodyTest06(void)
291 {
292  struct TestSteps steps[] = {
293  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
294  "Host: www.openinfosecfoundation.org\r\n"
295  "Content-Type: text/html\r\n"
296  "Content-Length: 46\r\n"
297  "\r\n"
298  "This is dummy body1",
299  0, STREAM_TOSERVER, 0 },
300  { (const uint8_t *)"This is dummy message body2",
301  0, STREAM_TOSERVER, 0 },
302  { NULL, 0, 0, 0 },
303  };
304 
305  const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:25; sid:1;)";
306  return RunTest(steps, sig, NULL);
307 }
308 
309 static int DetectEngineHttpClientBodyTest07(void)
310 {
311  struct TestSteps steps[] = {
312  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
313  "Host: www.openinfosecfoundation.org\r\n"
314  "Content-Type: text/html\r\n"
315  "Content-Length: 46\r\n"
316  "\r\n"
317  "This is dummy body1",
318  0, STREAM_TOSERVER, 0 },
319  { (const uint8_t *)"This is dummy message body2",
320  0, STREAM_TOSERVER, 1 },
321  { NULL, 0, 0, 0 },
322  };
323 
324  const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:15; sid:1;)";
325  return RunTest(steps, sig, NULL);
326 }
327 
328 static int DetectEngineHttpClientBodyTest08(void)
329 {
330  struct TestSteps steps[] = {
331  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
332  "Host: www.openinfosecfoundation.org\r\n"
333  "Content-Type: text/html\r\n"
334  "Content-Length: 46\r\n"
335  "\r\n"
336  "This is dummy body1",
337  0, STREAM_TOSERVER, 0 },
338  { (const uint8_t *)"This is dummy message body2",
339  0, STREAM_TOSERVER, 1 },
340  { NULL, 0, 0, 0 },
341  };
342 
343  const char *sig = "alert http any any -> any any (content:\"This is dummy body1This is dummy message body2\"; http_client_body; sid:1;)";
344  return RunTest(steps, sig, NULL);
345 }
346 
347 static int DetectEngineHttpClientBodyTest09(void)
348 {
349  struct TestSteps steps[] = {
350  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
351  "Host: www.openinfosecfoundation.org\r\n"
352  "Content-Type: text/html\r\n"
353  "Content-Length: 46\r\n"
354  "\r\n"
355  "This is dummy body1",
356  0, STREAM_TOSERVER, 0 },
357  { (const uint8_t *)"This is dummy message body2",
358  0, STREAM_TOSERVER, 1 },
359  { NULL, 0, 0, 0 },
360  };
361 
362  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"This\"; http_client_body; within:5; sid:1;)";
363  return RunTest(steps, sig, NULL);
364 }
365 
366 static int DetectEngineHttpClientBodyTest10(void)
367 {
368  struct TestSteps steps[] = {
369  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
370  "Host: www.openinfosecfoundation.org\r\n"
371  "Content-Type: text/html\r\n"
372  "Content-Length: 46\r\n"
373  "\r\n"
374  "This is dummy body1",
375  0, STREAM_TOSERVER, 0 },
376  { (const uint8_t *)"This is dummy message body2",
377  0, STREAM_TOSERVER, 1 },
378  { NULL, 0, 0, 0 },
379  };
380 
381  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"boom\"; http_client_body; within:5; sid:1;)";
382  return RunTest(steps, sig, NULL);
383 }
384 
385 static int DetectEngineHttpClientBodyTest11(void)
386 {
387  struct TestSteps steps[] = {
388  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
389  "Host: www.openinfosecfoundation.org\r\n"
390  "Content-Type: text/html\r\n"
391  "Content-Length: 46\r\n"
392  "\r\n"
393  "This is dummy body1",
394  0, STREAM_TOSERVER, 0 },
395  { (const uint8_t *)"This is dummy message body2",
396  0, STREAM_TOSERVER, 0 },
397  { NULL, 0, 0, 0 },
398  };
399 
400  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"boom\"; http_client_body; within:5; sid:1;)";
401  return RunTest(steps, sig, NULL);
402 }
403 
404 static int DetectEngineHttpClientBodyTest12(void)
405 {
406  struct TestSteps steps[] = {
407  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
408  "Host: www.openinfosecfoundation.org\r\n"
409  "Content-Type: text/html\r\n"
410  "Content-Length: 46\r\n"
411  "\r\n"
412  "This is dummy body1",
413  0, STREAM_TOSERVER, 0 },
414  { (const uint8_t *)"This is dummy message body2",
415  0, STREAM_TOSERVER, 0 },
416  { NULL, 0, 0, 0 },
417  };
418 
419  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"This\"; http_client_body; within:5; sid:1;)";
420  return RunTest(steps, sig, NULL);
421 }
422 
423 static int DetectEngineHttpClientBodyTest13(void)
424 {
425  struct TestSteps steps[] = {
426  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
427  "Host: www.openinfosecfoundation.org\r\n"
428  "Content-Type: text/html\r\n"
429  "Content-Length: 46\r\n"
430  "\r\n"
431  "This is dummy body1",
432  0, STREAM_TOSERVER, 0 },
433  { (const uint8_t *)"This is dummy message body2",
434  0, STREAM_TOSERVER, 1 },
435  { NULL, 0, 0, 0 },
436  };
437 
438  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:5; sid:1;)";
439  return RunTest(steps, sig, NULL);
440 }
441 
442 static int DetectEngineHttpClientBodyTest14(void)
443 {
444  struct TestSteps steps[] = {
445  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
446  "Host: www.openinfosecfoundation.org\r\n"
447  "Content-Type: text/html\r\n"
448  "Content-Length: 46\r\n"
449  "\r\n"
450  "This is dummy body1",
451  0, STREAM_TOSERVER, 0 },
452  { (const uint8_t *)"This is dummy message body2",
453  0, STREAM_TOSERVER, 1 },
454  { NULL, 0, 0, 0 },
455  };
456 
457  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:10; sid:1;)";
458  return RunTest(steps, sig, NULL);
459 }
460 
461 static int DetectEngineHttpClientBodyTest15(void)
462 {
463  struct TestSteps steps[] = {
464  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
465  "Host: www.openinfosecfoundation.org\r\n"
466  "Content-Type: text/html\r\n"
467  "Content-Length: 46\r\n"
468  "\r\n"
469  "This is dummy body1",
470  0, STREAM_TOSERVER, 0 },
471  { (const uint8_t *)"This is dummy message body2",
472  0, STREAM_TOSERVER, 0 },
473  { NULL, 0, 0, 0 },
474  };
475 
476  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:10; sid:1;)";
477  return RunTest(steps, sig, NULL);
478 }
479 
480 static int DetectEngineHttpClientBodyTest16(void)
481 {
482  struct TestSteps steps[] = {
483  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
484  "Host: www.openinfosecfoundation.org\r\n"
485  "Content-Type: text/html\r\n"
486  "Content-Length: 46\r\n"
487  "\r\n"
488  "This is dummy body1",
489  0, STREAM_TOSERVER, 0 },
490  { (const uint8_t *)"This is dummy message body2",
491  0, STREAM_TOSERVER, 0 },
492  { NULL, 0, 0, 0 },
493  };
494 
495  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:5; sid:1;)";
496  return RunTest(steps, sig, NULL);
497 }
498 
499 static int DetectEngineHttpClientBodyTest17(void)
500 {
501  struct TestSteps steps[] = {
502  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
503  "Host: www.openinfosecfoundation.org\r\n"
504  "Content-Type: text/html\r\n"
505  "Content-Length: 19\r\n"
506  "\r\n"
507  "This is dummy body1",
508  0, STREAM_TOSERVER, 0 },
509  { NULL, 0, 0, 0 },
510  };
511 
512  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; sid:1;)";
513  return RunTest(steps, sig, NULL);
514 }
515 
516 static int DetectEngineHttpClientBodyTest18(void)
517 {
518  struct TestSteps steps[] = {
519  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
520  "Host: www.openinfosecfoundation.org\r\n"
521  "Content-Type: text/html\r\n"
522  "Content-Length: 19\r\n"
523  "\r\n"
524  "This is dummy body1",
525  0, STREAM_TOSERVER, 0 },
526  { NULL, 0, 0, 0 },
527  };
528 
529  const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; fast_pattern; sid:1;)";
530  return RunTest(steps, sig, NULL);
531 }
532 
533 static int DetectEngineHttpClientBodyTest19(void)
534 {
535  struct TestSteps steps[] = {
536  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
537  "Host: www.openinfosecfoundation.org\r\n"
538  "Content-Type: text/html\r\n"
539  "Content-Length: 19\r\n"
540  "\r\n"
541  "This is dummy body1",
542  0, STREAM_TOSERVER, 0 },
543  { NULL, 0, 0, 0 },
544  };
545 
546  const char *sig = "alert http any any -> any any (content:\"bambu\"; http_client_body; content:\"is\"; http_client_body; sid:1;)";
547  return RunTest(steps, sig, NULL);
548 }
549 
550 static int DetectEngineHttpClientBodyTest20(void)
551 {
552  struct TestSteps steps[] = {
553  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
554  "Host: www.openinfosecfoundation.org\r\n"
555  "Content-Type: text/html\r\n"
556  "Content-Length: 19\r\n"
557  "\r\n"
558  "This is dummy body1",
559  0, STREAM_TOSERVER, 1 },
560  { NULL, 0, 0, 0 },
561  };
562 
563  const char *sig = "alert http any any -> any any (content:\"is\"; http_client_body; fast_pattern; sid:1;)";
564  return RunTest(steps, sig, NULL);
565 }
566 
567 static int DetectEngineHttpClientBodyTest21(void)
568 {
569  struct TestSteps steps[] = {
570  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
571  "Host: www.openinfosecfoundation.org\r\n"
572  "Content-Type: text/html\r\n"
573  "Content-Length: 46\r\n"
574  "\r\n"
575  "This is dummy body1",
576  0, STREAM_TOSERVER, 0 },
577  { (const uint8_t *)"This is dummy message body2",
578  0, STREAM_TOSERVER, 1 },
579  { NULL, 0, 0, 0 },
580  };
581 
582  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; http_client_body; within:7; sid:1;)";
583  return RunTest(steps, sig, NULL);
584 }
585 
586 static int DetectEngineHttpClientBodyTest22(void)
587 {
588  struct TestSteps steps[] = {
589  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
590  "Host: www.openinfosecfoundation.org\r\n"
591  "Content-Type: text/html\r\n"
592  "Content-Length: 46\r\n"
593  "\r\n"
594  "This is dummy body1",
595  0, STREAM_TOSERVER, 0 },
596  { (const uint8_t *)"This is dummy message body2",
597  0, STREAM_TOSERVER, 1 },
598  { NULL, 0, 0, 0 },
599  };
600 
601  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; within:7; http_client_body; sid:1;)";
602  return RunTest(steps, sig, NULL);
603 }
604 
605 static int DetectEngineHttpClientBodyTest23(void)
606 {
607  struct TestSteps steps[] = {
608  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
609  "Host: www.openinfosecfoundation.org\r\n"
610  "Content-Type: text/html\r\n"
611  "Content-Length: 46\r\n"
612  "\r\n"
613  "This is dummy body1",
614  0, STREAM_TOSERVER, 0 },
615  { (const uint8_t *)"This is dummy message body2",
616  0, STREAM_TOSERVER, 0 },
617  { NULL, 0, 0, 0 },
618  };
619 
620  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:3; http_client_body; sid:1;)";
621  return RunTest(steps, sig, NULL);
622 }
623 
624 static int DetectEngineHttpClientBodyTest24(void)
625 {
626  struct TestSteps steps[] = {
627  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
628  "Host: www.openinfosecfoundation.org\r\n"
629  "Content-Type: text/html\r\n"
630  "Content-Length: 46\r\n"
631  "\r\n"
632  "This is dummy body1",
633  0, STREAM_TOSERVER, 0 },
634  { (const uint8_t *)"This is dummy message body2",
635  0, STREAM_TOSERVER, 1 },
636  { NULL, 0, 0, 0 },
637  };
638 
639  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:13; http_client_body; sid:1;)";
640  return RunTest(steps, sig, NULL);
641 }
642 
643 static int DetectEngineHttpClientBodyTest25(void)
644 {
645  struct TestSteps steps[] = {
646  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
647  "Host: www.openinfosecfoundation.org\r\n"
648  "Content-Type: text/html\r\n"
649  "Content-Length: 46\r\n"
650  "\r\n"
651  "This is dummy body1",
652  0, STREAM_TOSERVER, 0 },
653  { (const uint8_t *)"This is dummy message body2",
654  0, STREAM_TOSERVER, 1 },
655  { NULL, 0, 0, 0 },
656  };
657 
658  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:15; http_client_body; sid:1;)";
659  return RunTest(steps, sig, NULL);
660 }
661 
662 static int DetectEngineHttpClientBodyTest26(void)
663 {
664  struct TestSteps steps[] = {
665  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
666  "Host: www.openinfosecfoundation.org\r\n"
667  "Content-Type: text/html\r\n"
668  "Content-Length: 46\r\n"
669  "\r\n"
670  "This is dummy body1",
671  0, STREAM_TOSERVER, 0 },
672  { (const uint8_t *)"This is dummy message body2",
673  0, STREAM_TOSERVER, 0 },
674  { NULL, 0, 0, 0 },
675  };
676 
677  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:10; http_client_body; sid:1;)";
678  return RunTest(steps, sig, NULL);
679 }
680 
681 static int DetectEngineHttpClientBodyTest27(void)
682 {
683  struct TestSteps steps[] = {
684  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
685  "Host: www.openinfosecfoundation.org\r\n"
686  "Content-Type: text/html\r\n"
687  "Content-Length: 46\r\n"
688  "\r\n"
689  "This is dummy body1",
690  0, STREAM_TOSERVER, 0 },
691  { (const uint8_t *)"This is dummy message body2",
692  0, STREAM_TOSERVER, 1 },
693  { NULL, 0, 0, 0 },
694  };
695 
696  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:8; http_client_body; sid:1;)";
697  return RunTest(steps, sig, NULL);
698 }
699 
700 static int DetectEngineHttpClientBodyTest28(void)
701 {
702  struct TestSteps steps[] = {
703  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
704  "Host: www.openinfosecfoundation.org\r\n"
705  "Content-Type: text/html\r\n"
706  "Content-Length: 46\r\n"
707  "\r\n"
708  "This is dummy body1",
709  0, STREAM_TOSERVER, 0 },
710  { (const uint8_t *)"This is dummy message body2",
711  0, STREAM_TOSERVER, 0 },
712  { NULL, 0, 0, 0 },
713  };
714 
715  const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:14; http_client_body; sid:1;)";
716  return RunTest(steps, sig, NULL);
717 }
718 
719 static int DetectEngineHttpClientBodyTest29(void)
720 {
721  const char *request_buffer = "GET /one HTTP/1.0\r\n"
722  "Host: localhost\r\n\r\n";
723 #define TOTAL_REQUESTS 45
724  uint8_t *http_buf = SCMalloc(TOTAL_REQUESTS * strlen(request_buffer));
725  if (unlikely(http_buf == NULL))
726  return 0;
727  for (int i = 0; i < TOTAL_REQUESTS; i++) {
728  memcpy(http_buf + i * strlen(request_buffer), request_buffer,
729  strlen(request_buffer));
730  }
731  uint32_t http_buf_len = TOTAL_REQUESTS * strlen(request_buffer);
732 #undef TOTAL_REQUESTS
733 
734  struct TestSteps steps[] = {
735  { (const uint8_t *)http_buf,
736  (size_t)http_buf_len, STREAM_TOSERVER, 0 },
737 
738  { (const uint8_t *)"HTTP/1.0 200 ok\r\n"
739  "Content-Type: text/html\r\n"
740  "Content-Length: 5\r\n"
741  "\r\n"
742  "dummy",
743  0, STREAM_TOCLIENT, 0 },
744 
745  { NULL, 0, 0, 0 },
746  };
747 
748  const char *sig = "alert http any any -> any any (content:\"dummyone\"; fast_pattern:0,3; http_server_body; sid:1;)";
749  int result = RunTest(steps, sig, NULL);
750  SCFree(http_buf);
751  return result;
752 }
753 
754 static int DetectEngineHttpClientBodyTest30(void)
755 {
756  const char yaml[] = "\
757 %YAML 1.1\n\
758 ---\n\
759 libhtp:\n\
760 \n\
761  default-config:\n\
762  personality: IDS\n\
763  request-body-limit: 0\n\
764  response-body-limit: 0\n\
765 \n\
766  request-body-inspect-window: 0\n\
767  response-body-inspect-window: 0\n\
768  request-body-minimal-inspect-size: 0\n\
769  response-body-minimal-inspect-size: 0\n\
770 ";
771  struct TestSteps steps[] = {
772  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
773  "Host: www.openinfosecfoundation.org\r\n"
774  "Content-Type: text/html\r\n"
775  "Content-Length: 46\r\n"
776  "\r\n"
777  "This is dummy body1",
778  0, STREAM_TOSERVER, 0 },
779  { (const uint8_t *)"This is dummy message body2",
780  0, STREAM_TOSERVER, 0 },
781  { NULL, 0, 0, 0 },
782  };
783 
784  const char *sig = "alert http any any -> any any (content:\"bags\"; within:4; http_client_body; sid:1;)";
785  return RunTest(steps, sig, yaml);
786 }
787 
788 static int DetectEngineHttpClientBodyTest31(void)
789 {
790  const char yaml[] = "\
791 %YAML 1.1\n\
792 ---\n\
793 libhtp:\n\
794 \n\
795  default-config:\n\
796  personality: IDS\n\
797  request-body-limit: 0\n\
798  response-body-limit: 0\n\
799 \n\
800  request-body-inspect-window: 0\n\
801  response-body-inspect-window: 0\n\
802  request-body-minimal-inspect-size: 0\n\
803  response-body-minimal-inspect-size: 0\n\
804 ";
805 
806  struct TestSteps steps[] = {
807  { (const uint8_t *)"GET /index.html HTTP/1.1\r\n"
808  "Host: www.openinfosecfoundation.org\r\n"
809  "Content-Type: text/html\r\n"
810  "Content-Length: 46\r\n"
811  "\r\n"
812  "This is dummy body1",
813  0, STREAM_TOSERVER, 0 },
814  { (const uint8_t *)"This is dummy message body2",
815  0, STREAM_TOSERVER, 0 },
816  { NULL, 0, 0, 0 },
817  };
818 
819  const char *sig = "alert http any any -> any any (content:\"bags\"; depth:4; http_client_body; sid:1;)";
820  return RunTest(steps, sig, yaml);
821 }
822 
823 /**
824  * \test Test that a signature containing a http_client_body is correctly parsed
825  * and the keyword is registered.
826  */
827 static int DetectHttpClientBodyTest01(void)
828 {
831  de_ctx->flags |= DE_QUIET;
832 
833  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
834  "(msg:\"Testing http_client_body\"; "
835  "content:\"one\"; http_client_body; sid:1;)");
836  FAIL_IF_NULL(s);
837 
839  FAIL_IF_NOT_NULL(sm);
840 
842  PASS;
843 }
844 
845 /**
846  * \test Test that a signature containing an valid http_client_body entry is
847  * parsed.
848  * \todo error in sig 'http_client_body:;'
849  */
850 static int DetectHttpClientBodyTest02(void)
851 {
854  de_ctx->flags |= DE_QUIET;
855 
856  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
857  "(msg:\"Testing http_client_body\"; "
858  "content:\"one\"; http_client_body:; sid:1;)");
859  FAIL_IF_NULL(s);
860 
862  PASS;
863 }
864 
865 /**
866  * \test Test invalid signatures
867  */
868 static int DetectHttpClientBodyTest03(void)
869 {
872  de_ctx->flags |= DE_QUIET;
873 
874  const char *sigs[] = {
875  "alert tcp any any -> any any (http_client_body; sid:1;)",
876  "alert tcp any any -> any any "
877  "(msg:\"Testing http_client_body\"; "
878  "content:\"one\"; rawbytes; http_client_body; sid:2;)",
879  NULL,
880  };
881 
882  for (uint32_t i = 0; sigs[i] != NULL; i++) {
883  Signature *s = DetectEngineAppendSig(de_ctx, sigs[i]);
884  FAIL_IF_NOT_NULL(s);
885  }
887  PASS;
888 }
889 
890 /**
891  * \test Test that an invalid signature containing a rawbytes along with a
892  * http_client_body is invalidated.
893  */
894 static int DetectHttpClientBodyTest05(void)
895 {
898  de_ctx->flags |= DE_QUIET;
899 
900  const char *sigs[] = {
901  "alert tcp any any -> any any (content:\"one\"; http_client_body; nocase; sid:1;)",
902  NULL,
903  };
904 
905  for (uint32_t i = 0; sigs[i] != NULL; i++) {
906  Signature *s = DetectEngineAppendSig(de_ctx, sigs[i]);
907  FAIL_IF_NULL(s);
908  }
910  PASS;
911 }
912 
913 /**
914  *\test Test that the http_client_body content matches against a http request
915  * which holds the content.
916  */
917 static int DetectHttpClientBodyTest06(void)
918 {
919  TcpSession ssn;
920  Packet *p = NULL;
921  ThreadVars th_v;
922  DetectEngineCtx *de_ctx = NULL;
923  DetectEngineThreadCtx *det_ctx = NULL;
924  HtpState *http_state = NULL;
925  Flow f;
926  uint8_t http_buf[] =
927  "GET /index.html HTTP/1.0\r\n"
928  "Host: www.openinfosecfoundation.org\r\n"
929  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
930  "Content-Type: text/html\r\n"
931  "Content-Length: 26\r\n"
932  "\r\n"
933  "This is dummy message body";
934  uint32_t http_len = sizeof(http_buf) - 1;
935  int result = 0;
937 
938  memset(&th_v, 0, sizeof(th_v));
939  memset(&f, 0, sizeof(f));
940  memset(&ssn, 0, sizeof(ssn));
941 
942  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
943 
944  FLOW_INITIALIZE(&f);
945  f.protoctx = (void *)&ssn;
946  f.proto = IPPROTO_TCP;
947  f.flags |= FLOW_IPV4;
948 
949  p->flow = &f;
954 
955  StreamTcpInitConfig(true);
956 
958  if (de_ctx == NULL)
959  goto end;
960 
961  de_ctx->flags |= DE_QUIET;
962 
963  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
964  "(msg:\"http client body test\"; "
965  "content:\"message\"; http_client_body; "
966  "sid:1;)");
967  FAIL_IF_NULL(s);
968 
970  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
971 
972  int r = AppLayerParserParse(
973  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
974  if (r != 0) {
975  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
976  result = 0;
977  goto end;
978  }
979 
980  http_state = f.alstate;
981  if (http_state == NULL) {
982  printf("no http state: \n");
983  result = 0;
984  goto end;
985  }
986 
987  /* do detect */
988  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
989 
990  if (!(PacketAlertCheck(p, 1))) {
991  printf("sid 1 didn't match but should have\n");
992  goto end;
993  }
994 
995  result = 1;
996 end:
997  if (alp_tctx != NULL)
999  if (de_ctx != NULL)
1001 
1002  StreamTcpFreeConfig(true);
1003  FLOW_DESTROY(&f);
1004  UTHFreePackets(&p, 1);
1005  return result;
1006 }
1007 
1008 /**
1009  *\test Test that the http_client_body content matches against a http request
1010  * which holds the content.
1011  */
1012 static int DetectHttpClientBodyTest07(void)
1013 {
1014  TcpSession ssn;
1015  Packet *p1 = NULL;
1016  Packet *p2 = NULL;
1017  ThreadVars th_v;
1018  DetectEngineCtx *de_ctx = NULL;
1019  DetectEngineThreadCtx *det_ctx = NULL;
1020  HtpState *http_state = NULL;
1021  Flow f;
1022  uint8_t http1_buf[] =
1023  "GET /index.html HTTP/1.0\r\n"
1024  "Host: www.openinfosecfoundation.org\r\n"
1025  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1026  "Content-Type: text/html\r\n"
1027  "Content-Length: 54\r\n"
1028  "\r\n"
1029  "This is dummy message body1";
1030  uint8_t http2_buf[] =
1031  "This is dummy message body2";
1032  uint32_t http1_len = sizeof(http1_buf) - 1;
1033  uint32_t http2_len = sizeof(http2_buf) - 1;
1034  int result = 0;
1036 
1037  memset(&th_v, 0, sizeof(th_v));
1038  memset(&f, 0, sizeof(f));
1039  memset(&ssn, 0, sizeof(ssn));
1040 
1041  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1042  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1043 
1044  FLOW_INITIALIZE(&f);
1045  f.protoctx = (void *)&ssn;
1046  f.proto = IPPROTO_TCP;
1047  f.flags |= FLOW_IPV4;
1048 
1049  p1->flow = &f;
1053  p2->flow = &f;
1057  f.alproto = ALPROTO_HTTP1;
1058 
1059  StreamTcpInitConfig(true);
1060 
1062  if (de_ctx == NULL)
1063  goto end;
1064 
1065  de_ctx->flags |= DE_QUIET;
1066 
1067  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1068  "(msg:\"http client body test\"; "
1069  "content:\"message\"; http_client_body; "
1070  "sid:1;)");
1071  FAIL_IF_NULL(s);
1072 
1074  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1075 
1076  int r = AppLayerParserParse(
1077  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1078  if (r != 0) {
1079  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1080  result = 0;
1081  goto end;
1082  }
1083 
1084  http_state = f.alstate;
1085  if (http_state == NULL) {
1086  printf("no http state: ");
1087  goto end;
1088  }
1089 
1090  /* do detect */
1091  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1092 
1093  if (PacketAlertCheck(p1, 1)) {
1094  printf("sid 1 matched on p1 but shouldn't have: ");
1095  goto end;
1096  }
1097 
1098  r = AppLayerParserParse(
1099  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1100  if (r != 0) {
1101  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1102  goto end;
1103  }
1104 
1105  /* do detect */
1106  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1107  if (!(PacketAlertCheck(p2, 1))) {
1108  printf("sid 1 didn't match on p2 but should have: ");
1109  goto end;
1110  }
1111 
1112  result = 1;
1113 end:
1114  if (alp_tctx != NULL)
1116  if (de_ctx != NULL)
1118 
1119  StreamTcpFreeConfig(true);
1120  FLOW_DESTROY(&f);
1121  UTHFreePackets(&p1, 1);
1122  UTHFreePackets(&p2, 1);
1123  return result;
1124 }
1125 
1126 /**
1127  *\test Test that the http_client_body content matches against a http request
1128  * which holds the content.
1129  */
1130 static int DetectHttpClientBodyTest08(void)
1131 {
1132  TcpSession ssn;
1133  Packet *p1 = NULL;
1134  Packet *p2 = NULL;
1135  ThreadVars th_v;
1136  DetectEngineCtx *de_ctx = NULL;
1137  DetectEngineThreadCtx *det_ctx = NULL;
1138  HtpState *http_state = NULL;
1139  Flow f;
1140  uint8_t http1_buf[] =
1141  "GET /index.html HTTP/1.0\r\n"
1142  "Host: www.openinfosecfoundation.org\r\n"
1143  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1144  "Content-Type: text/html\r\n"
1145  "Content-Length: 46\r\n"
1146  "\r\n"
1147  "This is dummy body1";
1148  uint8_t http2_buf[] =
1149  "This is dummy message body2";
1150  uint32_t http1_len = sizeof(http1_buf) - 1;
1151  uint32_t http2_len = sizeof(http2_buf) - 1;
1152  int result = 0;
1154 
1155  memset(&th_v, 0, sizeof(th_v));
1156  memset(&f, 0, sizeof(f));
1157  memset(&ssn, 0, sizeof(ssn));
1158 
1159  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1160  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1161 
1162  FLOW_INITIALIZE(&f);
1163  f.protoctx = (void *)&ssn;
1164  f.proto = IPPROTO_TCP;
1165  f.flags |= FLOW_IPV4;
1166 
1167  p1->flow = &f;
1171  p2->flow = &f;
1175  f.alproto = ALPROTO_HTTP1;
1176 
1177  StreamTcpInitConfig(true);
1178 
1180  if (de_ctx == NULL)
1181  goto end;
1182 
1183  de_ctx->flags |= DE_QUIET;
1184 
1185  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1186  "(msg:\"http client body test\"; "
1187  "content:\"message\"; http_client_body; "
1188  "sid:1;)");
1189  FAIL_IF_NULL(s);
1190 
1192  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1193 
1194  int r = AppLayerParserParse(
1195  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1196  if (r != 0) {
1197  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1198  result = 0;
1199  goto end;
1200  }
1201 
1202  http_state = f.alstate;
1203  if (http_state == NULL) {
1204  printf("no http state: ");
1205  result = 0;
1206  goto end;
1207  }
1208 
1209  /* do detect */
1210  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1211 
1212  if ((PacketAlertCheck(p1, 1))) {
1213  printf("sid 1 didn't match but should have");
1214  goto end;
1215  }
1216 
1217  r = AppLayerParserParse(
1218  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1219  if (r != 0) {
1220  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1221  result = 0;
1222  goto end;
1223  }
1224 
1225  /* do detect */
1226  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1227 
1228  if (!(PacketAlertCheck(p2, 1))) {
1229  printf("sid 1 didn't match but should have");
1230  goto end;
1231  }
1232 
1233  result = 1;
1234 end:
1235  if (alp_tctx != NULL)
1237  if (de_ctx != NULL)
1239 
1240  StreamTcpFreeConfig(true);
1241  FLOW_DESTROY(&f);
1242  UTHFreePackets(&p1, 1);
1243  UTHFreePackets(&p2, 1);
1244  return result;
1245 }
1246 
1247 /**
1248  *\test Test that the http_client_body content matches against a http request
1249  * which holds the content, against a cross boundary present pattern.
1250  */
1251 static int DetectHttpClientBodyTest09(void)
1252 {
1253  TcpSession ssn;
1254  Packet *p1 = NULL;
1255  Packet *p2 = NULL;
1256  ThreadVars th_v;
1257  DetectEngineCtx *de_ctx = NULL;
1258  DetectEngineThreadCtx *det_ctx = NULL;
1259  HtpState *http_state = NULL;
1260  Flow f;
1261  uint8_t http1_buf[] =
1262  "GET /index.html HTTP/1.0\r\n"
1263  "Host: www.openinfosecfoundation.org\r\n"
1264  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1265  "Content-Type: text/html\r\n"
1266  "Content-Length: 46\r\n"
1267  "\r\n"
1268  "This is dummy body1";
1269  uint8_t http2_buf[] =
1270  "This is dummy message body2";
1271  uint32_t http1_len = sizeof(http1_buf) - 1;
1272  uint32_t http2_len = sizeof(http2_buf) - 1;
1273  int result = 0;
1275 
1276  memset(&th_v, 0, sizeof(th_v));
1277  memset(&f, 0, sizeof(f));
1278  memset(&ssn, 0, sizeof(ssn));
1279 
1280  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1281  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1282 
1283  FLOW_INITIALIZE(&f);
1284  f.protoctx = (void *)&ssn;
1285  f.proto = IPPROTO_TCP;
1286  f.flags |= FLOW_IPV4;
1287 
1288  p1->flow = &f;
1292  p2->flow = &f;
1296  f.alproto = ALPROTO_HTTP1;
1297 
1298  StreamTcpInitConfig(true);
1299 
1301  if (de_ctx == NULL)
1302  goto end;
1303 
1304  de_ctx->flags |= DE_QUIET;
1305 
1306  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1307  "(msg:\"http client body test\"; "
1308  "content:\"body1This\"; http_client_body; "
1309  "sid:1;)");
1310  FAIL_IF_NULL(s);
1311 
1313  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1314 
1315  int r = AppLayerParserParse(
1316  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1317  if (r != 0) {
1318  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1319  result = 0;
1320  goto end;
1321  }
1322 
1323  http_state = f.alstate;
1324  if (http_state == NULL) {
1325  printf("no http state: ");
1326  result = 0;
1327  goto end;
1328  }
1329 
1330  /* do detect */
1331  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1332 
1333  if ((PacketAlertCheck(p1, 1))) {
1334  printf("sid 1 didn't match but should have");
1335  goto end;
1336  }
1337 
1338  r = AppLayerParserParse(
1339  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1340  if (r != 0) {
1341  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1342  result = 0;
1343  goto end;
1344  }
1345 
1346  /* do detect */
1347  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1348 
1349  if (!(PacketAlertCheck(p2, 1))) {
1350  printf("sid 1 didn't match but should have");
1351  goto end;
1352  }
1353 
1354  result = 1;
1355 end:
1356  if (alp_tctx != NULL)
1358  if (de_ctx != NULL)
1360 
1361  StreamTcpFreeConfig(true);
1362  FLOW_DESTROY(&f);
1363  UTHFreePackets(&p1, 1);
1364  UTHFreePackets(&p2, 1);
1365  return result;
1366 }
1367 
1368 /**
1369  *\test Test that the http_client_body content matches against a http request
1370  * against a case insensitive pattern.
1371  */
1372 static int DetectHttpClientBodyTest10(void)
1373 {
1374  TcpSession ssn;
1375  Packet *p1 = NULL;
1376  Packet *p2 = NULL;
1377  ThreadVars th_v;
1378  DetectEngineCtx *de_ctx = NULL;
1379  DetectEngineThreadCtx *det_ctx = NULL;
1380  HtpState *http_state = NULL;
1381  Flow f;
1382  uint8_t http1_buf[] =
1383  "GET /index.html HTTP/1.0\r\n"
1384  "Host: www.openinfosecfoundation.org\r\n"
1385  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1386  "Content-Type: text/html\r\n"
1387  "Content-Length: 46\r\n"
1388  "\r\n"
1389  "This is dummy bodY1";
1390  uint8_t http2_buf[] =
1391  "This is dummy message body2";
1392  uint32_t http1_len = sizeof(http1_buf) - 1;
1393  uint32_t http2_len = sizeof(http2_buf) - 1;
1394  int result = 0;
1396 
1397  memset(&th_v, 0, sizeof(th_v));
1398  memset(&f, 0, sizeof(f));
1399  memset(&ssn, 0, sizeof(ssn));
1400 
1401  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1402  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1403 
1404  FLOW_INITIALIZE(&f);
1405  f.protoctx = (void *)&ssn;
1406  f.proto = IPPROTO_TCP;
1407  f.flags |= FLOW_IPV4;
1408 
1409  p1->flow = &f;
1413  p2->flow = &f;
1417  f.alproto = ALPROTO_HTTP1;
1418 
1419  StreamTcpInitConfig(true);
1420 
1422  if (de_ctx == NULL)
1423  goto end;
1424 
1425  de_ctx->flags |= DE_QUIET;
1426 
1427  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1428  "(msg:\"http client body test\"; "
1429  "content:\"body1This\"; http_client_body; nocase;"
1430  "sid:1;)");
1431  FAIL_IF_NULL(s);
1432 
1434  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1435 
1436  int r = AppLayerParserParse(
1437  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1438  if (r != 0) {
1439  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1440  result = 0;
1441  goto end;
1442  }
1443 
1444  http_state = f.alstate;
1445  if (http_state == NULL) {
1446  printf("no http state: \n");
1447  result = 0;
1448  goto end;
1449  }
1450 
1451  /* do detect */
1452  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1453 
1454  if ((PacketAlertCheck(p1, 1))) {
1455  printf("sid 1 didn't match but should have\n");
1456  goto end;
1457  }
1458 
1459  r = AppLayerParserParse(
1460  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1461  if (r != 0) {
1462  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1463  result = 0;
1464  goto end;
1465  }
1466 
1467  /* do detect */
1468  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1469 
1470  if (!(PacketAlertCheck(p2, 1))) {
1471  printf("sid 1 didn't match but should have");
1472  goto end;
1473  }
1474 
1475  result = 1;
1476 end:
1477  if (alp_tctx != NULL)
1479  if (de_ctx != NULL)
1481 
1482  StreamTcpFreeConfig(true);
1483  FLOW_DESTROY(&f);
1484  UTHFreePackets(&p1, 1);
1485  UTHFreePackets(&p2, 1);
1486  return result;
1487 }
1488 
1489 /**
1490  *\test Test that the negated http_client_body content matches against a
1491  * http request which doesn't hold the content.
1492  */
1493 static int DetectHttpClientBodyTest11(void)
1494 {
1495  TcpSession ssn;
1496  Packet *p = NULL;
1497  ThreadVars th_v;
1498  DetectEngineCtx *de_ctx = NULL;
1499  DetectEngineThreadCtx *det_ctx = NULL;
1500  HtpState *http_state = NULL;
1501  Flow f;
1502  uint8_t http_buf[] =
1503  "GET /index.html HTTP/1.0\r\n"
1504  "Host: www.openinfosecfoundation.org\r\n"
1505  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1506  "Content-Type: text/html\r\n"
1507  "Content-Length: 26\r\n"
1508  "\r\n"
1509  "This is dummy message body";
1510  uint32_t http_len = sizeof(http_buf) - 1;
1511  int result = 0;
1513 
1514  memset(&th_v, 0, sizeof(th_v));
1515  memset(&f, 0, sizeof(f));
1516  memset(&ssn, 0, sizeof(ssn));
1517 
1518  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1519 
1520  FLOW_INITIALIZE(&f);
1521  f.protoctx = (void *)&ssn;
1522  f.proto = IPPROTO_TCP;
1523  f.flags |= FLOW_IPV4;
1524 
1525  p->flow = &f;
1529  f.alproto = ALPROTO_HTTP1;
1530 
1531  StreamTcpInitConfig(true);
1532 
1534  if (de_ctx == NULL)
1535  goto end;
1536 
1537  de_ctx->flags |= DE_QUIET;
1538 
1539  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1540  "(msg:\"http client body test\"; "
1541  "content:!\"message1\"; http_client_body; "
1542  "sid:1;)");
1543  FAIL_IF_NULL(s);
1544 
1546  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1547 
1548  int r = AppLayerParserParse(
1549  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1550  if (r != 0) {
1551  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1552  result = 0;
1553  goto end;
1554  }
1555 
1556  http_state = f.alstate;
1557  if (http_state == NULL) {
1558  printf("no http state: ");
1559  result = 0;
1560  goto end;
1561  }
1562 
1563  /* do detect */
1564  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1565 
1566  if (!(PacketAlertCheck(p, 1))) {
1567  printf("sid 1 didn't match but should have");
1568  goto end;
1569  }
1570 
1571  result = 1;
1572 end:
1573  if (alp_tctx != NULL)
1575  if (de_ctx != NULL)
1577 
1578  StreamTcpFreeConfig(true);
1579  FLOW_DESTROY(&f);
1580  UTHFreePackets(&p, 1);
1581  return result;
1582 }
1583 
1584 /**
1585  *\test Negative test that the negated http_client_body content matches against a
1586  * http request which holds hold the content.
1587  */
1588 static int DetectHttpClientBodyTest12(void)
1589 {
1590  TcpSession ssn;
1591  Packet *p = NULL;
1592  ThreadVars th_v;
1593  DetectEngineCtx *de_ctx = NULL;
1594  DetectEngineThreadCtx *det_ctx = NULL;
1595  HtpState *http_state = NULL;
1596  Flow f;
1597  uint8_t http_buf[] =
1598  "GET /index.html HTTP/1.0\r\n"
1599  "Host: www.openinfosecfoundation.org\r\n"
1600  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1601  "Content-Type: text/html\r\n"
1602  "Content-Length: 26\r\n"
1603  "\r\n"
1604  "This is dummy message body";
1605  uint32_t http_len = sizeof(http_buf) - 1;
1606  int result = 0;
1608 
1609  memset(&th_v, 0, sizeof(th_v));
1610  memset(&f, 0, sizeof(f));
1611  memset(&ssn, 0, sizeof(ssn));
1612 
1613  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1614 
1615  FLOW_INITIALIZE(&f);
1616  f.protoctx = (void *)&ssn;
1617  f.proto = IPPROTO_TCP;
1618  f.flags |= FLOW_IPV4;
1619 
1620  p->flow = &f;
1624  f.alproto = ALPROTO_HTTP1;
1625 
1626  StreamTcpInitConfig(true);
1627 
1629  if (de_ctx == NULL)
1630  goto end;
1631 
1632  de_ctx->flags |= DE_QUIET;
1633 
1634  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1635  "(msg:\"http client body test\"; "
1636  "content:!\"message\"; http_client_body; "
1637  "sid:1;)");
1638  FAIL_IF_NULL(s);
1639 
1641  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1642 
1643  int r = AppLayerParserParse(
1644  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1645  if (r != 0) {
1646  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1647  result = 0;
1648  goto end;
1649  }
1650 
1651  http_state = f.alstate;
1652  if (http_state == NULL) {
1653  printf("no http state: ");
1654  result = 0;
1655  goto end;
1656  }
1657 
1658  /* do detect */
1659  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1660 
1661  if ((PacketAlertCheck(p, 1))) {
1662  printf("sid 1 didn't match but should have");
1663  goto end;
1664  }
1665 
1666  result = 1;
1667 end:
1668  if (alp_tctx != NULL)
1670  if (de_ctx != NULL)
1672 
1673  StreamTcpFreeConfig(true);
1674  FLOW_DESTROY(&f);
1675  UTHFreePackets(&p, 1);
1676  return result;
1677 }
1678 
1679 /**
1680  *\test Test that the http_client_body content matches against a http request
1681  * which holds the content.
1682  */
1683 static int DetectHttpClientBodyTest13(void)
1684 {
1685  TcpSession ssn;
1686  Packet *p = NULL;
1687  ThreadVars th_v;
1688  DetectEngineCtx *de_ctx = NULL;
1689  DetectEngineThreadCtx *det_ctx = NULL;
1690  HtpState *http_state = NULL;
1691  Flow f;
1692  uint8_t http_buf[] =
1693  "GET /index.html HTTP/1.0\r\n"
1694  "Host: www.openinfosecfoundation.org\r\n"
1695  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1696  "Content-Type: text/html\r\n"
1697  "Content-Length: 55\r\n"
1698  "\r\n"
1699  "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend";
1700  uint32_t http_len = sizeof(http_buf) - 1;
1701  int result = 0;
1703 
1704  memset(&th_v, 0, sizeof(th_v));
1705  memset(&f, 0, sizeof(f));
1706  memset(&ssn, 0, sizeof(ssn));
1707 
1708  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1709 
1710  FLOW_INITIALIZE(&f);
1711  f.protoctx = (void *)&ssn;
1712  f.proto = IPPROTO_TCP;
1713  f.flags |= FLOW_IPV4;
1714 
1715  p->flow = &f;
1719  f.alproto = ALPROTO_HTTP1;
1720 
1721  StreamTcpInitConfig(true);
1722 
1724  if (de_ctx == NULL)
1725  goto end;
1726 
1727  de_ctx->flags |= DE_QUIET;
1728 
1730  "alert http any any -> any any "
1731  "(msg:\"http client body test\"; "
1732  "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_client_body; "
1733  "sid:1;)");
1734  FAIL_IF_NULL(s);
1735 
1737  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1738 
1739  int r = AppLayerParserParse(
1740  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1741  if (r != 0) {
1742  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1743  result = 0;
1744  goto end;
1745  }
1746 
1747  http_state = f.alstate;
1748  if (http_state == NULL) {
1749  printf("no http state: ");
1750  result = 0;
1751  goto end;
1752  }
1753 
1754  /* do detect */
1755  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1756 
1757  if (!(PacketAlertCheck(p, 1))) {
1758  printf("sid 1 didn't match but should have");
1759  goto end;
1760  }
1761 
1762  result = 1;
1763 end:
1764  if (alp_tctx != NULL)
1766  if (de_ctx != NULL)
1768 
1769  StreamTcpFreeConfig(true);
1770  FLOW_DESTROY(&f);
1771  UTHFreePackets(&p, 1);
1772  return result;
1773 }
1774 
1775 /** \test multiple http transactions and body chunks of request handling */
1776 static int DetectHttpClientBodyTest14(void)
1777 {
1778  int result = 0;
1779  Signature *s = NULL;
1780  DetectEngineThreadCtx *det_ctx = NULL;
1781  ThreadVars th_v;
1782  Flow f;
1783  TcpSession ssn;
1784  Packet *p = NULL;
1785  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
1786  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1787  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
1788  uint8_t httpbuf4[] = "Body one!!";
1789  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1790  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1791  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1792  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1793  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
1794  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
1795  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1796  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
1797  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
1798  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
1800 
1801  memset(&th_v, 0, sizeof(th_v));
1802  memset(&f, 0, sizeof(f));
1803  memset(&ssn, 0, sizeof(ssn));
1804 
1805  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1806 
1807  FLOW_INITIALIZE(&f);
1808  f.protoctx = (void *)&ssn;
1809  f.proto = IPPROTO_TCP;
1810  f.flags |= FLOW_IPV4;
1811 
1812  p->flow = &f;
1816  f.alproto = ALPROTO_HTTP1;
1817 
1818  StreamTcpInitConfig(true);
1819 
1821  if (de_ctx == NULL) {
1822  goto end;
1823  }
1824 
1825  de_ctx->flags |= DE_QUIET;
1826 
1827  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)");
1828  if (s == NULL) {
1829  printf("sig parse failed: ");
1830  goto end;
1831  }
1832  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)");
1833  if (s == NULL) {
1834  printf("sig2 parse failed: ");
1835  goto end;
1836  }
1837 
1839  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1840 
1841  int r = AppLayerParserParse(
1842  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1843  if (r != 0) {
1844  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1845  goto end;
1846  }
1847 
1848  /* do detect */
1849  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1850  if (PacketAlertCheck(p, 1)) {
1851  printf("sig 1 alerted: ");
1852  goto end;
1853  }
1854  p->alerts.cnt = 0;
1855 
1856  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1857  if (r != 0) {
1858  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
1859  goto end;
1860  }
1861 
1862  /* do detect */
1863  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1864  if (PacketAlertCheck(p, 1)) {
1865  printf("sig 1 alerted (2): ");
1866  goto end;
1867  }
1868  p->alerts.cnt = 0;
1869 
1870  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1871  if (r != 0) {
1872  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
1873  goto end;
1874  }
1875 
1876  /* do detect */
1877  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1878  if (PacketAlertCheck(p, 1)) {
1879  printf("signature matched, but shouldn't have: ");
1880  goto end;
1881  }
1882  p->alerts.cnt = 0;
1883 
1884  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
1885  if (r != 0) {
1886  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
1887  result = 0;
1888  goto end;
1889  }
1890 
1891  /* do detect */
1892  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1893  if (!(PacketAlertCheck(p, 1))) {
1894  printf("sig 1 didn't alert: ");
1895  goto end;
1896  }
1897  p->alerts.cnt = 0;
1898 
1899  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
1900  if (r != 0) {
1901  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
1902  goto end;
1903  }
1904 
1905  /* do detect */
1906  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1907  if (PacketAlertCheck(p, 1)) {
1908  printf("sig 1 alerted (5): ");
1909  goto end;
1910  }
1911  p->alerts.cnt = 0;
1912 
1913  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
1914  if (r != 0) {
1915  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
1916  goto end;
1917  }
1918 
1919  /* do detect */
1920  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1921  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
1922  printf("sig 1 alerted (request 2, chunk 6): ");
1923  goto end;
1924  }
1925  p->alerts.cnt = 0;
1926 
1927  SCLogDebug("sending data chunk 7");
1928 
1929  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
1930  if (r != 0) {
1931  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
1932  goto end;
1933  }
1934 
1935  /* do detect */
1936  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1937  if (!(PacketAlertCheck(p, 2))) {
1938  printf("signature 2 didn't match, but should have: ");
1939  goto end;
1940  }
1941  p->alerts.cnt = 0;
1942 
1943  HtpState *htp_state = f.alstate;
1944  if (htp_state == NULL) {
1945  printf("no http state: ");
1946  result = 0;
1947  goto end;
1948  }
1949 
1950  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
1951  printf("The http app layer doesn't have 2 transactions, but it should: ");
1952  goto end;
1953  }
1954 
1955  result = 1;
1956 end:
1957  if (alp_tctx != NULL)
1959  if (det_ctx != NULL) {
1960  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1961  }
1962  if (de_ctx != NULL) {
1964  }
1965 
1966  StreamTcpFreeConfig(true);
1967  FLOW_DESTROY(&f);
1968  UTHFreePacket(p);
1969  return result;
1970 }
1971 
1972 /** \test multiple http transactions and body chunks of request handling */
1973 static int DetectHttpClientBodyTest15(void)
1974 {
1975  int result = 0;
1976  Signature *s = NULL;
1977  DetectEngineThreadCtx *det_ctx = NULL;
1978  ThreadVars th_v;
1979  Flow f;
1980  TcpSession ssn;
1981  Packet *p = NULL;
1982  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
1983  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1984  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
1985  uint8_t httpbuf4[] = "Body one!!";
1986  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1987  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1988  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1989  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1990  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
1991  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
1992  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1993  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
1994  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
1995  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
1997 
1998  memset(&th_v, 0, sizeof(th_v));
1999  memset(&f, 0, sizeof(f));
2000  memset(&ssn, 0, sizeof(ssn));
2001 
2002  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2003 
2004  FLOW_INITIALIZE(&f);
2005  f.protoctx = (void *)&ssn;
2006  f.proto = IPPROTO_TCP;
2007  f.flags |= FLOW_IPV4;
2008 
2009  p->flow = &f;
2013  f.alproto = ALPROTO_HTTP1;
2014 
2015  StreamTcpInitConfig(true);
2016 
2018  if (de_ctx == NULL) {
2019  goto end;
2020  }
2021 
2022  de_ctx->flags |= DE_QUIET;
2023 
2024  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)");
2025  if (s == NULL) {
2026  printf("sig parse failed: ");
2027  goto end;
2028  }
2029  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)");
2030  if (s == NULL) {
2031  printf("sig2 parse failed: ");
2032  goto end;
2033  }
2034 
2036  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2037 
2038  int r = AppLayerParserParse(
2039  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2040  if (r != 0) {
2041  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2042  goto end;
2043  }
2044 
2045  /* do detect */
2046  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2047  if (PacketAlertCheck(p, 1)) {
2048  printf("sig 1 alerted: ");
2049  goto end;
2050  }
2051  p->alerts.cnt = 0;
2052 
2053  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2054  if (r != 0) {
2055  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
2056  goto end;
2057  }
2058 
2059  /* do detect */
2060  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2061  if (PacketAlertCheck(p, 1)) {
2062  printf("sig 1 alerted (2): ");
2063  goto end;
2064  }
2065  p->alerts.cnt = 0;
2066 
2067  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
2068  if (r != 0) {
2069  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
2070  goto end;
2071  }
2072 
2073  /* do detect */
2074  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2075  if (PacketAlertCheck(p, 1)) {
2076  printf("signature matched, but shouldn't have: ");
2077  goto end;
2078  }
2079  p->alerts.cnt = 0;
2080 
2081  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
2082  if (r != 0) {
2083  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
2084  result = 0;
2085  goto end;
2086  }
2087 
2088  /* do detect */
2089  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2090  if (!(PacketAlertCheck(p, 1))) {
2091  printf("sig 1 didn't alert: ");
2092  goto end;
2093  }
2094  p->alerts.cnt = 0;
2095 
2096  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
2097  if (r != 0) {
2098  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2099  goto end;
2100  }
2101 
2102  /* do detect */
2103  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2104  if (PacketAlertCheck(p, 1)) {
2105  printf("sig 1 alerted (5): ");
2106  goto end;
2107  }
2108  p->alerts.cnt = 0;
2109 
2110  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
2111  if (r != 0) {
2112  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2113  goto end;
2114  }
2115 
2116  /* do detect */
2117  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2118  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2119  printf("sig 1 alerted (request 2, chunk 6): ");
2120  goto end;
2121  }
2122  p->alerts.cnt = 0;
2123 
2124  SCLogDebug("sending data chunk 7");
2125 
2126  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
2127  if (r != 0) {
2128  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2129  goto end;
2130  }
2131 
2132  /* do detect */
2133  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2134  if (!(PacketAlertCheck(p, 2))) {
2135  printf("signature 2 didn't match, but should have: ");
2136  goto end;
2137  }
2138  p->alerts.cnt = 0;
2139 
2140  HtpState *htp_state = f.alstate;
2141  if (htp_state == NULL) {
2142  printf("no http state: ");
2143  result = 0;
2144  goto end;
2145  }
2146 
2147  /* hardcoded check of the transactions and it's client body chunks */
2148  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2149  printf("The http app layer doesn't have 2 transactions, but it should: ");
2150  goto end;
2151  }
2152 
2153  htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 0);
2154  htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 1);
2155 
2156  HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2157 
2158  HtpBodyChunk *cur = htud->request_body.first;
2159  if (htud->request_body.first == NULL) {
2160  SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2161  goto end;
2162  }
2163 
2165  (uint8_t *)"Body one!!", 10) != 1)
2166  {
2167  SCLogDebug("Body data in t1 is not correctly set: ");
2168  goto end;
2169  }
2170 
2171  htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2172 
2173  cur = htud->request_body.first;
2174  if (htud->request_body.first == NULL) {
2175  SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2176  goto end;
2177  }
2178 
2180  (uint8_t *)"Body two!!", 10) != 1)
2181  {
2182  SCLogDebug("Body data in t1 is not correctly set: ");
2183  goto end;
2184  }
2185 
2186  result = 1;
2187 end:
2188  if (alp_tctx != NULL)
2190  if (det_ctx != NULL) {
2191  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2192  }
2193  if (de_ctx != NULL) {
2195  }
2196 
2197  StreamTcpFreeConfig(true);
2198  FLOW_DESTROY(&f);
2199  UTHFreePacket(p);
2200  return result;
2201 }
2202 
2203 static int DetectHttpClientBodyTest22(void)
2204 {
2207  de_ctx->flags |= DE_QUIET;
2209  "alert icmp any any -> any any "
2210  "(content:\"one\"; content:\"two\"; http_client_body; "
2211  "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2212  FAIL_IF_NULL(s);
2214  FAIL_IF(DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL);
2215  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id);
2216  FAIL_IF_NULL(sm);
2217 
2218  DetectContentData *cd1 =
2220  DetectContentData *cd2 =
2222  DetectContentData *hcbd1 =
2223  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2224  ->prev->ctx;
2225  DetectContentData *hcbd2 =
2226  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2227  FAIL_IF(cd1->flags != 0);
2228  FAIL_IF(memcmp(cd1->content, "one", cd1->content_len) != 0);
2229  FAIL_IF(cd2->flags != 0);
2230  FAIL_IF(memcmp(cd2->content, "four", cd2->content_len) != 0);
2232  FAIL_IF(memcmp(hcbd1->content, "two", hcbd1->content_len) != 0);
2234  FAIL_IF(memcmp(hcbd2->content, "three", hcbd1->content_len) != 0);
2235 
2240 
2242  PASS;
2243 }
2244 
2245 static int DetectHttpClientBodyTest23(void)
2246 {
2249  de_ctx->flags |= DE_QUIET;
2250 
2252  "alert icmp any any -> any any "
2253  "(content:\"one\"; http_client_body; pcre:/two/; "
2254  "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2255  FAIL_IF_NULL(s);
2257  FAIL_IF_NULL(DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id));
2258 
2259  DetectPcreData *pd1 =
2261  ->prev->ctx;
2262  DetectContentData *cd2 =
2264  ->ctx;
2265  DetectContentData *hcbd1 =
2266  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2267  ->prev->ctx;
2268  DetectContentData *hcbd2 =
2269  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2270  FAIL_IF(pd1->flags != 0);
2271  FAIL_IF(cd2->flags != 0);
2272  FAIL_IF(memcmp(cd2->content, "four", cd2->content_len) != 0);
2274  FAIL_IF(memcmp(hcbd1->content, "one", hcbd1->content_len) != 0);
2276  FAIL_IF(memcmp(hcbd2->content, "three", hcbd1->content_len) != 0);
2280 
2282  PASS;
2283 }
2284 
2285 static int DetectHttpClientBodyTest24(void)
2286 {
2287  DetectEngineCtx *de_ctx = NULL;
2288  int result = 0;
2289 
2290  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2291  goto end;
2292 
2293  de_ctx->flags |= DE_QUIET;
2294  Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2295  "(content:\"one\"; http_client_body; pcre:/two/; "
2296  "content:\"three\"; distance:10; within:15; "
2297  "http_client_body; content:\"four\"; sid:1;)");
2298  if (de_ctx->sig_list == NULL) {
2299  printf("de_ctx->sig_list == NULL\n");
2300  goto end;
2301  }
2302 
2304  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL\n");
2305  goto end;
2306  }
2307 
2308  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2309  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2310  goto end;
2311  }
2312 
2313  DetectPcreData *pd1 =
2315  ->prev->ctx;
2316  DetectContentData *cd2 =
2318  ->ctx;
2319  DetectContentData *hcbd1 =
2320  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2321  ->prev->ctx;
2322  DetectContentData *hcbd2 =
2323  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2324  if (pd1->flags != 0 ||
2325  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2326  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2327  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2329  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2330  goto end;
2331  }
2332 
2333  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
2334  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2335  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2336  goto end;
2337  }
2338 
2339  result = 1;
2340 
2341  end:
2343  return result;
2344 }
2345 
2346 static int DetectHttpClientBodyTest25(void)
2347 {
2348  DetectEngineCtx *de_ctx = NULL;
2349  int result = 0;
2350 
2351  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2352  goto end;
2353 
2354  de_ctx->flags |= DE_QUIET;
2355  Signature *s =
2356  DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2357  "(content:\"one\"; http_client_body; pcre:/two/; "
2358  "content:\"three\"; distance:10; http_client_body; "
2359  "content:\"four\"; distance:10; sid:1;)");
2360  if (de_ctx->sig_list == NULL) {
2361  printf("de_ctx->sig_list == NULL\n");
2362  goto end;
2363  }
2364 
2366  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL\n");
2367  goto end;
2368  }
2369 
2370  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2371  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2372  goto end;
2373  }
2374 
2375  DetectPcreData *pd1 =
2377  ->prev->ctx;
2378  DetectContentData *cd2 =
2380  ->ctx;
2381  DetectContentData *hcbd1 =
2382  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2383  ->prev->ctx;
2384  DetectContentData *hcbd2 =
2385  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2386  if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT ||
2387  cd2->flags != DETECT_CONTENT_DISTANCE ||
2388  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2389  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2390  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2391  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2392  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2393  goto end;
2394  }
2395 
2396  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2397  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2398  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2399  goto end;
2400  }
2401 
2402  result = 1;
2403 
2404  end:
2406  return result;
2407 }
2408 
2409 static int DetectHttpClientBodyTest26(void)
2410 {
2411  DetectEngineCtx *de_ctx = NULL;
2412  int result = 0;
2413 
2414  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2415  goto end;
2416 
2417  de_ctx->flags |= DE_QUIET;
2419  "alert icmp any any -> any any "
2420  "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2421  "content:\"three\"; distance:10; http_client_body; within:10; "
2422  "content:\"four\"; distance:10; sid:1;)");
2423  if (de_ctx->sig_list == NULL) {
2424  printf("de_ctx->sig_list == NULL\n");
2425  goto end;
2426  }
2427 
2429  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL\n");
2430  goto end;
2431  }
2432 
2433  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2434  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2435  goto end;
2436  }
2437 
2438  DetectPcreData *pd1 =
2440  ->prev->ctx;
2441  DetectContentData *cd2 =
2443  ->ctx;
2444  DetectContentData *hcbd1 =
2445  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2446  ->prev->ctx;
2447  DetectContentData *hcbd2 =
2448  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2449  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2450  cd2->flags != DETECT_CONTENT_DISTANCE ||
2451  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2453  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2455  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2456  printf ("failed: http_client_body incorrect flags");
2457  goto end;
2458  }
2459 
2460  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2461  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2462  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2463  goto end;
2464  }
2465 
2466  result = 1;
2467 
2468  end:
2470  return result;
2471 }
2472 
2473 static int DetectHttpClientBodyTest27(void)
2474 {
2475  DetectEngineCtx *de_ctx = NULL;
2476  int result = 0;
2477 
2478  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2479  goto end;
2480 
2481  de_ctx->flags |= DE_QUIET;
2483  "alert icmp any any -> any any "
2484  "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2485  "content:\"three\"; distance:10; http_client_body; within:10; "
2486  "content:\"four\"; distance:10; sid:1;)");
2487  FAIL_IF_NULL(s);
2488 
2489  result = 1;
2490 
2491  end:
2493  return result;
2494 }
2495 
2496 static int DetectHttpClientBodyTest28(void)
2497 {
2498  DetectEngineCtx *de_ctx = NULL;
2499  int result = 0;
2500 
2501  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2502  goto end;
2503 
2504  de_ctx->flags |= DE_QUIET;
2505  Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2506  "(content:\"one\"; http_client_body; pcre:/two/; "
2507  "content:\"three\"; http_client_body; depth:10; "
2508  "content:\"four\"; distance:10; sid:1;)");
2509  if (de_ctx->sig_list == NULL) {
2510  printf("de_ctx->sig_list == NULL\n");
2511  goto end;
2512  }
2513 
2515  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL\n");
2516  goto end;
2517  }
2518 
2519  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2520  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2521  goto end;
2522  }
2523 
2524  DetectPcreData *pd1 =
2526  ->prev->ctx;
2527  DetectContentData *cd2 =
2529  ->ctx;
2530  DetectContentData *hcbd1 =
2531  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2532  ->prev->ctx;
2533  DetectContentData *hcbd2 =
2534  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2535  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2536  cd2->flags != DETECT_CONTENT_DISTANCE ||
2537  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2538  hcbd1->flags != 0 ||
2539  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2540  hcbd2->flags != DETECT_CONTENT_DEPTH ||
2541  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2542  goto end;
2543  }
2544 
2545  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2546  !DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2547  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2548  goto end;
2549  }
2550 
2551  result = 1;
2552 
2553  end:
2555  return result;
2556 }
2557 
2558 static int DetectHttpClientBodyTest29(void)
2559 {
2560  DetectEngineCtx *de_ctx = NULL;
2561  int result = 0;
2562 
2563  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2564  goto end;
2565 
2566  de_ctx->flags |= DE_QUIET;
2567  Signature *s =
2568  DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2569  "(content:\"one\"; http_client_body; "
2570  "content:\"two\"; distance:0; http_client_body; sid:1;)");
2571  if (de_ctx->sig_list == NULL) {
2572  printf("de_ctx->sig_list == NULL\n");
2573  goto end;
2574  }
2575 
2577  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2578  goto end;
2579  }
2580 
2581  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2582  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2583  goto end;
2584  }
2585 
2586  DetectContentData *hcbd1 =
2587  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2588  ->prev->ctx;
2589  DetectContentData *hcbd2 =
2590  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2591  if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2592  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2593  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2594  memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2595  goto end;
2596  }
2597 
2598  result = 1;
2599 
2600  end:
2602  return result;
2603 }
2604 
2605 static int DetectHttpClientBodyTest30(void)
2606 {
2607  DetectEngineCtx *de_ctx = NULL;
2608  int result = 0;
2609 
2610  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2611  goto end;
2612 
2613  de_ctx->flags |= DE_QUIET;
2614  Signature *s =
2615  DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2616  "(content:\"one\"; http_client_body; "
2617  "content:\"two\"; within:5; http_client_body; sid:1;)");
2618  if (de_ctx->sig_list == NULL) {
2619  printf("de_ctx->sig_list == NULL\n");
2620  goto end;
2621  }
2622 
2624  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2625  goto end;
2626  }
2627 
2628  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2629  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2630  goto end;
2631  }
2632 
2633  DetectContentData *hcbd1 =
2634  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2635  ->prev->ctx;
2636  DetectContentData *hcbd2 =
2637  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2638  if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2639  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2640  hcbd2->flags != DETECT_CONTENT_WITHIN ||
2641  memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2642  goto end;
2643  }
2644 
2645  result = 1;
2646 
2647  end:
2649  return result;
2650 }
2651 
2652 static int DetectHttpClientBodyTest31(void)
2653 {
2654  DetectEngineCtx *de_ctx = NULL;
2655  int result = 0;
2656 
2657  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2658  goto end;
2659 
2660  de_ctx->flags |= DE_QUIET;
2661  Signature *s =
2662  DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2663  "(content:\"one\"; within:5; http_client_body; sid:1;)");
2664  FAIL_IF_NULL(s);
2665 
2666  result = 1;
2667 
2668  end:
2670  return result;
2671 }
2672 
2673 static int DetectHttpClientBodyTest32(void)
2674 {
2675  DetectEngineCtx *de_ctx = NULL;
2676  int result = 0;
2677 
2678  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2679  goto end;
2680 
2681  de_ctx->flags |= DE_QUIET;
2682  Signature *s =
2683  DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2684  "(content:\"one\"; http_client_body; within:5; sid:1;)");
2685  FAIL_IF_NULL(s);
2686 
2687  result = 1;
2688 
2689  end:
2691  return result;
2692 }
2693 
2694 static int DetectHttpClientBodyTest33(void)
2695 {
2696  DetectEngineCtx *de_ctx = NULL;
2697  int result = 0;
2698 
2699  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2700  goto end;
2701 
2702  de_ctx->flags |= DE_QUIET;
2703  Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2704  "(content:\"one\"; within:5; sid:1;)");
2705  FAIL_IF_NULL(s);
2706 
2707  result = 1;
2708 
2709  end:
2711  return result;
2712 }
2713 
2714 static int DetectHttpClientBodyTest34(void)
2715 {
2716  DetectEngineCtx *de_ctx = NULL;
2717  int result = 0;
2718 
2719  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2720  goto end;
2721 
2722  de_ctx->flags |= DE_QUIET;
2723  Signature *s =
2724  DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2725  "(pcre:/one/P; "
2726  "content:\"two\"; within:5; http_client_body; sid:1;)");
2727  if (de_ctx->sig_list == NULL) {
2728  printf("de_ctx->sig_list == NULL\n");
2729  goto end;
2730  }
2731 
2733  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2734  goto end;
2735  }
2736 
2737  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2738  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2739  goto end;
2740  }
2741 
2742  if (DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id) == NULL ||
2743  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->type != DETECT_CONTENT ||
2744  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev == NULL ||
2745  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev->type !=
2746  DETECT_PCRE) {
2747 
2748  goto end;
2749  }
2750 
2751  DetectPcreData *pd1 =
2752  (DetectPcreData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2753  ->prev->ctx;
2754  DetectContentData *hcbd2 =
2755  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2756  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2757  hcbd2->flags != DETECT_CONTENT_WITHIN ||
2758  memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2759  goto end;
2760  }
2761 
2762  result = 1;
2763 
2764  end:
2766  return result;
2767 }
2768 
2769 static int DetectHttpClientBodyTest35(void)
2770 {
2771  DetectEngineCtx *de_ctx = NULL;
2772  int result = 0;
2773 
2774  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2775  goto end;
2776 
2777  de_ctx->flags |= DE_QUIET;
2778  Signature *s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2779  "(content:\"two\"; http_client_body; "
2780  "pcre:/one/PR; sid:1;)");
2781  if (de_ctx->sig_list == NULL) {
2782  printf("de_ctx->sig_list == NULL\n");
2783  goto end;
2784  }
2785 
2787  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2788  goto end;
2789  }
2790 
2791  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2792  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2793  goto end;
2794  }
2795 
2796  if (DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id) == NULL ||
2797  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->type != DETECT_PCRE ||
2798  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev == NULL ||
2799  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev->type !=
2800  DETECT_CONTENT) {
2801 
2802  goto end;
2803  }
2804 
2805  DetectContentData *hcbd1 =
2806  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2807  ->prev->ctx;
2808  DetectPcreData *pd2 =
2809  (DetectPcreData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2810  if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
2811  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2812  memcmp(hcbd1->content, "two", hcbd1->content_len) != 0) {
2813  goto end;
2814  }
2815 
2816  result = 1;
2817 
2818  end:
2820  return result;
2821 }
2822 
2823 static int DetectHttpClientBodyTest36(void)
2824 {
2825  DetectEngineCtx *de_ctx = NULL;
2826  int result = 0;
2827 
2828  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2829  goto end;
2830 
2831  de_ctx->flags |= DE_QUIET;
2832  Signature *s =
2833  DetectEngineAppendSig(de_ctx, "alert icmp any any -> any any "
2834  "(pcre:/one/P; "
2835  "content:\"two\"; distance:5; http_client_body; sid:1;)");
2836  if (de_ctx->sig_list == NULL) {
2837  printf("de_ctx->sig_list == NULL\n");
2838  goto end;
2839  }
2840 
2842  printf("de_ctx->sig_list->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL\n");
2843  goto end;
2844  }
2845 
2846  if (DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL) {
2847  printf("DetectBufferGetFirstSigMatch(s, g_http_client_body_buffer_id) == NULL\n");
2848  goto end;
2849  }
2850 
2851  if (DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id) == NULL ||
2852  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->type != DETECT_CONTENT ||
2853  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev == NULL ||
2854  DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->prev->type !=
2855  DETECT_PCRE) {
2856 
2857  goto end;
2858  }
2859 
2860  DetectPcreData *pd1 =
2861  (DetectPcreData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)
2862  ->prev->ctx;
2863  DetectContentData *hcbd2 =
2864  (DetectContentData *)DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id)->ctx;
2865  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2866  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2867  memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2868  goto end;
2869  }
2870 
2871  result = 1;
2872 
2873  end:
2875  return result;
2876 }
2877 
2878 static int DetectHttpClientBodyIsdataatParseTest(void)
2879 {
2882  de_ctx->flags |= DE_QUIET;
2883 
2885  "alert tcp any any -> any any ("
2886  "content:\"one\"; http_client_body; "
2887  "isdataat:!4,relative; sid:1;)");
2888  FAIL_IF_NULL(s);
2889 
2890  SigMatch *sm = DetectBufferGetLastSigMatch(s, g_http_client_body_buffer_id);
2891  FAIL_IF_NULL(sm);
2893 
2894  DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
2897  FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
2898 
2900  PASS;
2901 }
2902 
2904 {
2905  UtRegisterTest("DetectHttpClientBodyParserTest01", DetectHttpClientBodyParserTest01);
2906  UtRegisterTest("DetectHttpClientBodyParserTest02", DetectHttpClientBodyParserTest02);
2907  UtRegisterTest("DetectHttpClientBodyTest01", DetectHttpClientBodyTest01);
2908  UtRegisterTest("DetectHttpClientBodyTest02", DetectHttpClientBodyTest02);
2909  UtRegisterTest("DetectHttpClientBodyTest03", DetectHttpClientBodyTest03);
2910  UtRegisterTest("DetectHttpClientBodyTest05", DetectHttpClientBodyTest05);
2911  UtRegisterTest("DetectHttpClientBodyTest06", DetectHttpClientBodyTest06);
2912  UtRegisterTest("DetectHttpClientBodyTest07", DetectHttpClientBodyTest07);
2913  UtRegisterTest("DetectHttpClientBodyTest08", DetectHttpClientBodyTest08);
2914  UtRegisterTest("DetectHttpClientBodyTest09", DetectHttpClientBodyTest09);
2915  UtRegisterTest("DetectHttpClientBodyTest10", DetectHttpClientBodyTest10);
2916  UtRegisterTest("DetectHttpClientBodyTest11", DetectHttpClientBodyTest11);
2917  UtRegisterTest("DetectHttpClientBodyTest12", DetectHttpClientBodyTest12);
2918  UtRegisterTest("DetectHttpClientBodyTest13", DetectHttpClientBodyTest13);
2919  UtRegisterTest("DetectHttpClientBodyTest14", DetectHttpClientBodyTest14);
2920  UtRegisterTest("DetectHttpClientBodyTest15", DetectHttpClientBodyTest15);
2921 
2922  UtRegisterTest("DetectHttpClientBodyTest22", DetectHttpClientBodyTest22);
2923  UtRegisterTest("DetectHttpClientBodyTest23", DetectHttpClientBodyTest23);
2924  UtRegisterTest("DetectHttpClientBodyTest24", DetectHttpClientBodyTest24);
2925  UtRegisterTest("DetectHttpClientBodyTest25", DetectHttpClientBodyTest25);
2926  UtRegisterTest("DetectHttpClientBodyTest26", DetectHttpClientBodyTest26);
2927  UtRegisterTest("DetectHttpClientBodyTest27", DetectHttpClientBodyTest27);
2928  UtRegisterTest("DetectHttpClientBodyTest28", DetectHttpClientBodyTest28);
2929  UtRegisterTest("DetectHttpClientBodyTest29", DetectHttpClientBodyTest29);
2930  UtRegisterTest("DetectHttpClientBodyTest30", DetectHttpClientBodyTest30);
2931  UtRegisterTest("DetectHttpClientBodyTest31", DetectHttpClientBodyTest31);
2932  UtRegisterTest("DetectHttpClientBodyTest32", DetectHttpClientBodyTest32);
2933  UtRegisterTest("DetectHttpClientBodyTest33", DetectHttpClientBodyTest33);
2934  UtRegisterTest("DetectHttpClientBodyTest34", DetectHttpClientBodyTest34);
2935  UtRegisterTest("DetectHttpClientBodyTest35", DetectHttpClientBodyTest35);
2936  UtRegisterTest("DetectHttpClientBodyTest36", DetectHttpClientBodyTest36);
2937 
2938  UtRegisterTest("DetectHttpClientBodyIsdataatParseTest",
2939  DetectHttpClientBodyIsdataatParseTest);
2940 
2941  UtRegisterTest("DetectEngineHttpClientBodyTest01",
2942  DetectEngineHttpClientBodyTest01);
2943  UtRegisterTest("DetectEngineHttpClientBodyTest02",
2944  DetectEngineHttpClientBodyTest02);
2945  UtRegisterTest("DetectEngineHttpClientBodyTest03",
2946  DetectEngineHttpClientBodyTest03);
2947  UtRegisterTest("DetectEngineHttpClientBodyTest04",
2948  DetectEngineHttpClientBodyTest04);
2949  UtRegisterTest("DetectEngineHttpClientBodyTest05",
2950  DetectEngineHttpClientBodyTest05);
2951  UtRegisterTest("DetectEngineHttpClientBodyTest06",
2952  DetectEngineHttpClientBodyTest06);
2953  UtRegisterTest("DetectEngineHttpClientBodyTest07",
2954  DetectEngineHttpClientBodyTest07);
2955  UtRegisterTest("DetectEngineHttpClientBodyTest08",
2956  DetectEngineHttpClientBodyTest08);
2957  UtRegisterTest("DetectEngineHttpClientBodyTest09",
2958  DetectEngineHttpClientBodyTest09);
2959  UtRegisterTest("DetectEngineHttpClientBodyTest10",
2960  DetectEngineHttpClientBodyTest10);
2961  UtRegisterTest("DetectEngineHttpClientBodyTest11",
2962  DetectEngineHttpClientBodyTest11);
2963  UtRegisterTest("DetectEngineHttpClientBodyTest12",
2964  DetectEngineHttpClientBodyTest12);
2965  UtRegisterTest("DetectEngineHttpClientBodyTest13",
2966  DetectEngineHttpClientBodyTest13);
2967  UtRegisterTest("DetectEngineHttpClientBodyTest14",
2968  DetectEngineHttpClientBodyTest14);
2969  UtRegisterTest("DetectEngineHttpClientBodyTest15",
2970  DetectEngineHttpClientBodyTest15);
2971  UtRegisterTest("DetectEngineHttpClientBodyTest16",
2972  DetectEngineHttpClientBodyTest16);
2973  UtRegisterTest("DetectEngineHttpClientBodyTest17",
2974  DetectEngineHttpClientBodyTest17);
2975  UtRegisterTest("DetectEngineHttpClientBodyTest18",
2976  DetectEngineHttpClientBodyTest18);
2977  UtRegisterTest("DetectEngineHttpClientBodyTest19",
2978  DetectEngineHttpClientBodyTest19);
2979  UtRegisterTest("DetectEngineHttpClientBodyTest20",
2980  DetectEngineHttpClientBodyTest20);
2981  UtRegisterTest("DetectEngineHttpClientBodyTest21",
2982  DetectEngineHttpClientBodyTest21);
2983  UtRegisterTest("DetectEngineHttpClientBodyTest22",
2984  DetectEngineHttpClientBodyTest22);
2985  UtRegisterTest("DetectEngineHttpClientBodyTest23",
2986  DetectEngineHttpClientBodyTest23);
2987  UtRegisterTest("DetectEngineHttpClientBodyTest24",
2988  DetectEngineHttpClientBodyTest24);
2989  UtRegisterTest("DetectEngineHttpClientBodyTest25",
2990  DetectEngineHttpClientBodyTest25);
2991  UtRegisterTest("DetectEngineHttpClientBodyTest26",
2992  DetectEngineHttpClientBodyTest26);
2993  UtRegisterTest("DetectEngineHttpClientBodyTest27",
2994  DetectEngineHttpClientBodyTest27);
2995  UtRegisterTest("DetectEngineHttpClientBodyTest28",
2996  DetectEngineHttpClientBodyTest28);
2997  UtRegisterTest("DetectEngineHttpClientBodyTest29",
2998  DetectEngineHttpClientBodyTest29);
2999 
3000  UtRegisterTest("DetectEngineHttpClientBodyTest30",
3001  DetectEngineHttpClientBodyTest30);
3002  UtRegisterTest("DetectEngineHttpClientBodyTest31",
3003  DetectEngineHttpClientBodyTest31);
3004 }
3005 
3006 #endif
3007 
3008 /**
3009  * @}
3010  */
TestSteps
Definition: detect-http-client-body.c:107
DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_RELATIVE_NEXT
Definition: detect-content.h:66
SigMatch_::prev
struct SigMatch_ * prev
Definition: detect.h:352
UTHParseSignature
int UTHParseSignature(const char *str, bool expect)
parser a sig and see if the expected result is correct
Definition: util-unittest-helper.c:909
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:113
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:578
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1018
flow-util.h
SignatureInitData_::smlists_tail
struct SigMatch_ * smlists_tail[DETECT_SM_LIST_MAX]
Definition: detect.h:580
stream-tcp.h
DetectHttpClientBodyRegisterTests
void DetectHttpClientBodyRegisterTests(void)
Definition: detect-http-client-body.c:2903
HtpBody_::sb
StreamingBuffer * sb
Definition: app-layer-htp.h:190
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
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
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:62
TestSteps::direction
int direction
Definition: detect-http-client-body.c:110
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
detect-isdataat.h
TestSteps::input
const uint8_t * input
Definition: detect-http-client-body.c:108
Flow_::proto
uint8_t proto
Definition: flow.h:372
PacketAlerts_::cnt
uint16_t cnt
Definition: decode.h:289
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:141
Packet_::flags
uint32_t flags
Definition: decode.h:473
Flow_
Flow data structure.
Definition: flow.h:350
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:836
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2580
HtpTxUserData_::request_body
HtpBody request_body
Definition: app-layer-htp.h:222
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:312
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:222
DE_QUIET
#define DE_QUIET
Definition: detect.h:321
stream-tcp-reassemble.h
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:338
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1884
DetectIsdataatData_
Definition: detect-isdataat.h:32
DetectContentData_
Definition: detect-content.h:93
DetectPcreData_::flags
uint16_t flags
Definition: detect-pcre.h:46
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2620
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:467
StreamingBufferSegmentCompareRawData
int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t *rawdata, uint32_t rawdata_len)
Definition: util-streaming-buffer.c:1738
Flow_::protoctx
void * protoctx
Definition: flow.h:440
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:96
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:601
detect-engine-prefilter.h
util-unittest.h
HTPConfigure
void HTPConfigure(void)
Definition: app-layer-htp.c:2977
HtpBody_::first
HtpBodyChunk * first
Definition: app-layer-htp.h:187
HtpState_
Definition: app-layer-htp.h:244
util-unittest-helper.h
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:359
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
app-layer-htp.h
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
util-debug.h
type
uint8_t type
Definition: decode-icmpv4.h:0
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
TOTAL_REQUESTS
#define TOTAL_REQUESTS
DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_DISTANCE
Definition: detect-content.h:30
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
HtpConfigCreateBackup
void HtpConfigCreateBackup(void)
Definition: app-layer-htp.c:3299
DetectEngineThreadCtx_
Definition: detect.h:1092
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_DEPTH
Definition: detect-content.h:33
util-print.h
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DETECT_CONTENT_IS_SINGLE
#define DETECT_CONTENT_IS_SINGLE(c)
Definition: detect-content.h:68
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:511
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:111
app-layer-parser.h
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:350
Packet_
Definition: decode.h:436
detect-engine-build.h
conf-yaml-loader.h
ISDATAAT_RELATIVE
#define ISDATAAT_RELATIVE
Definition: detect-isdataat.h:27
conf.h
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:104
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:662
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
ISDATAAT_RAWBYTES
#define ISDATAAT_RAWBYTES
Definition: detect-isdataat.h:28
ConfCreateContextBackup
void ConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition: conf.c:670
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:223
DETECT_PCRE
@ DETECT_PCRE
Definition: detect-engine-register.h:64
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1125
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2149
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:291
detect-engine-content-inspection.h
Packet_::flow
struct Flow_ * flow
Definition: decode.h:475
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3291
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:690
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:1303
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3501
SigMatch_::type
uint16_t type
Definition: detect.h:348
HtpBodyChunk_
Definition: app-layer-htp.h:178
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine.c:1351
DetectContentData_::content
uint8_t * content
Definition: detect-content.h:94
ConfRestoreContextBackup
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:682
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:844
HtpTxUserData_
Definition: app-layer-htp.h:207
DetectBufferGetLastSigMatch
SigMatch * DetectBufferGetLastSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine.c:1361
util-validate.h
HtpConfigRestoreBackup
void HtpConfigRestoreBackup(void)
Definition: app-layer-htp.c:3306
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
ConfInit
void ConfInit(void)
Initialize the configuration system.
Definition: conf.c:120
ISDATAAT_NEGATED
#define ISDATAAT_NEGATED
Definition: detect-isdataat.h:29
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:486
Flow_::alstate
void * alstate
Definition: flow.h:475
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
Flow_::flags
uint32_t flags
Definition: flow.h:420
detect-parse.h
Signature_
Signature container.
Definition: detect.h:593
SigMatch_
a single match condition for a signature
Definition: detect.h:347
DETECT_ISDATAAT
@ DETECT_ISDATAAT
Definition: detect-engine-register.h:82
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:224
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2541
DETECT_PCRE_RELATIVE_NEXT
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:34
app-layer-protos.h
DetectPcreData_
Definition: detect-pcre.h:42
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h:95
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:838
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:65
DETECT_PCRE_RELATIVE
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:29
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:449
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1118
HtpBodyChunk_::sbseg
StreamingBufferSegment sbseg
Definition: app-layer-htp.h:181
TestSteps::input_size
size_t input_size
Definition: detect-http-client-body.c:109
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1015
app-layer.h
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:469