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 containting a http_client_body is correctly parsed
825  * and the keyword is registered.
826  */
827 static int DetectHttpClientBodyTest01(void)
828 {
829  DetectEngineCtx *de_ctx = NULL;
830  int result = 0;
831  SigMatch *sm = NULL;
832 
834  if (de_ctx == NULL)
835  goto end;
836 
837  de_ctx->flags |= DE_QUIET;
838  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
839  "(msg:\"Testing http_client_body\"; "
840  "content:\"one\"; http_client_body; sid:1;)");
841  if (de_ctx->sig_list != NULL) {
842  result = 1;
843  } else {
844  goto end;
845  }
846 
847  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH];
848  if (sm != NULL) {
849  result &= (sm->type == DETECT_CONTENT);
850  result &= (sm->next == NULL);
851  }
852 
853  end:
855 
856  return result;
857 }
858 
859 /**
860  * \test Test that a signature containing an valid http_client_body entry is
861  * parsed.
862  */
863 static int DetectHttpClientBodyTest02(void)
864 {
865  DetectEngineCtx *de_ctx = NULL;
866  int result = 0;
867 
869  if (de_ctx == NULL)
870  goto end;
871 
872  de_ctx->flags |= DE_QUIET;
873  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
874  "(msg:\"Testing http_client_body\"; "
875  "content:\"one\"; http_client_body:; sid:1;)");
876  if (de_ctx->sig_list != NULL)
877  result = 1;
878 
879  end:
881 
882  return result;
883 }
884 
885 /**
886  * \test Test that an invalid signature containing no content but a http_client_body
887  * is invalidated.
888  */
889 static int DetectHttpClientBodyTest03(void)
890 {
891  DetectEngineCtx *de_ctx = NULL;
892  int result = 0;
893 
895  if (de_ctx == NULL)
896  goto end;
897 
898  de_ctx->flags |= DE_QUIET;
899  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
900  "(msg:\"Testing http_client_body\"; "
901  "http_client_body; sid:1;)");
902  if (de_ctx->sig_list == NULL)
903  result = 1;
904 
905  end:
907 
908  return result;
909 }
910 
911 /**
912  * \test Test that an invalid signature containing a rawbytes along with a
913  * http_client_body is invalidated.
914  */
915 static int DetectHttpClientBodyTest04(void)
916 {
917  DetectEngineCtx *de_ctx = NULL;
918  int result = 0;
919 
921  if (de_ctx == NULL)
922  goto end;
923 
924  de_ctx->flags |= DE_QUIET;
925  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
926  "(msg:\"Testing http_client_body\"; "
927  "content:\"one\"; rawbytes; http_client_body; sid:1;)");
928  if (de_ctx->sig_list == NULL)
929  result = 1;
930 
931  end:
933 
934  return result;
935 }
936 
937 /**
938  * \test Test that an invalid signature containing a rawbytes along with a
939  * http_client_body is invalidated.
940  */
941 static int DetectHttpClientBodyTest05(void)
942 {
943  DetectEngineCtx *de_ctx = NULL;
944  int result = 0;
945 
947  if (de_ctx == NULL)
948  goto end;
949 
950  de_ctx->flags |= DE_QUIET;
951  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
952  "(msg:\"Testing http_client_body\"; "
953  "content:\"one\"; http_client_body; nocase; sid:1;)");
954  if (de_ctx->sig_list != NULL)
955  result = 1;
956 
957  end:
959 
960  return result;
961 }
962 
963 /**
964  *\test Test that the http_client_body content matches against a http request
965  * which holds the content.
966  */
967 static int DetectHttpClientBodyTest06(void)
968 {
969  TcpSession ssn;
970  Packet *p = NULL;
971  ThreadVars th_v;
972  DetectEngineCtx *de_ctx = NULL;
973  DetectEngineThreadCtx *det_ctx = NULL;
974  HtpState *http_state = NULL;
975  Flow f;
976  uint8_t http_buf[] =
977  "GET /index.html HTTP/1.0\r\n"
978  "Host: www.openinfosecfoundation.org\r\n"
979  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
980  "Content-Type: text/html\r\n"
981  "Content-Length: 26\r\n"
982  "\r\n"
983  "This is dummy message body";
984  uint32_t http_len = sizeof(http_buf) - 1;
985  int result = 0;
987 
988  memset(&th_v, 0, sizeof(th_v));
989  memset(&f, 0, sizeof(f));
990  memset(&ssn, 0, sizeof(ssn));
991 
992  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
993 
994  FLOW_INITIALIZE(&f);
995  f.protoctx = (void *)&ssn;
996  f.proto = IPPROTO_TCP;
997  f.flags |= FLOW_IPV4;
998 
999  p->flow = &f;
1003  f.alproto = ALPROTO_HTTP1;
1004 
1005  StreamTcpInitConfig(true);
1006 
1008  if (de_ctx == NULL)
1009  goto end;
1010 
1011  de_ctx->flags |= DE_QUIET;
1012 
1013  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1014  "(msg:\"http client body test\"; "
1015  "content:\"message\"; http_client_body; "
1016  "sid:1;)");
1017  if (de_ctx->sig_list == NULL)
1018  goto end;
1019 
1021  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1022 
1023  int r = AppLayerParserParse(
1024  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1025  if (r != 0) {
1026  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1027  result = 0;
1028  goto end;
1029  }
1030 
1031  http_state = f.alstate;
1032  if (http_state == NULL) {
1033  printf("no http state: \n");
1034  result = 0;
1035  goto end;
1036  }
1037 
1038  /* do detect */
1039  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1040 
1041  if (!(PacketAlertCheck(p, 1))) {
1042  printf("sid 1 didn't match but should have\n");
1043  goto end;
1044  }
1045 
1046  result = 1;
1047 end:
1048  if (alp_tctx != NULL)
1050  if (de_ctx != NULL)
1052 
1053  StreamTcpFreeConfig(true);
1054  FLOW_DESTROY(&f);
1055  UTHFreePackets(&p, 1);
1056  return result;
1057 }
1058 
1059 /**
1060  *\test Test that the http_client_body content matches against a http request
1061  * which holds the content.
1062  */
1063 static int DetectHttpClientBodyTest07(void)
1064 {
1065  TcpSession ssn;
1066  Packet *p1 = NULL;
1067  Packet *p2 = NULL;
1068  ThreadVars th_v;
1069  DetectEngineCtx *de_ctx = NULL;
1070  DetectEngineThreadCtx *det_ctx = NULL;
1071  HtpState *http_state = NULL;
1072  Flow f;
1073  uint8_t http1_buf[] =
1074  "GET /index.html HTTP/1.0\r\n"
1075  "Host: www.openinfosecfoundation.org\r\n"
1076  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1077  "Content-Type: text/html\r\n"
1078  "Content-Length: 54\r\n"
1079  "\r\n"
1080  "This is dummy message body1";
1081  uint8_t http2_buf[] =
1082  "This is dummy message body2";
1083  uint32_t http1_len = sizeof(http1_buf) - 1;
1084  uint32_t http2_len = sizeof(http2_buf) - 1;
1085  int result = 0;
1087 
1088  memset(&th_v, 0, sizeof(th_v));
1089  memset(&f, 0, sizeof(f));
1090  memset(&ssn, 0, sizeof(ssn));
1091 
1092  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1093  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1094 
1095  FLOW_INITIALIZE(&f);
1096  f.protoctx = (void *)&ssn;
1097  f.proto = IPPROTO_TCP;
1098  f.flags |= FLOW_IPV4;
1099 
1100  p1->flow = &f;
1104  p2->flow = &f;
1108  f.alproto = ALPROTO_HTTP1;
1109 
1110  StreamTcpInitConfig(true);
1111 
1113  if (de_ctx == NULL)
1114  goto end;
1115 
1116  de_ctx->flags |= DE_QUIET;
1117 
1118  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1119  "(msg:\"http client body test\"; "
1120  "content:\"message\"; http_client_body; "
1121  "sid:1;)");
1122  if (de_ctx->sig_list == NULL)
1123  goto end;
1124 
1126  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1127 
1128  int r = AppLayerParserParse(
1129  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1130  if (r != 0) {
1131  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1132  result = 0;
1133  goto end;
1134  }
1135 
1136  http_state = f.alstate;
1137  if (http_state == NULL) {
1138  printf("no http state: ");
1139  goto end;
1140  }
1141 
1142  /* do detect */
1143  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1144 
1145  if (PacketAlertCheck(p1, 1)) {
1146  printf("sid 1 matched on p1 but shouldn't have: ");
1147  goto end;
1148  }
1149 
1150  r = AppLayerParserParse(
1151  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1152  if (r != 0) {
1153  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1154  goto end;
1155  }
1156 
1157  /* do detect */
1158  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1159  if (!(PacketAlertCheck(p2, 1))) {
1160  printf("sid 1 didn't match on p2 but should have: ");
1161  goto end;
1162  }
1163 
1164  result = 1;
1165 end:
1166  if (alp_tctx != NULL)
1168  if (de_ctx != NULL)
1170 
1171  StreamTcpFreeConfig(true);
1172  FLOW_DESTROY(&f);
1173  UTHFreePackets(&p1, 1);
1174  UTHFreePackets(&p2, 1);
1175  return result;
1176 }
1177 
1178 /**
1179  *\test Test that the http_client_body content matches against a http request
1180  * which holds the content.
1181  */
1182 static int DetectHttpClientBodyTest08(void)
1183 {
1184  TcpSession ssn;
1185  Packet *p1 = NULL;
1186  Packet *p2 = NULL;
1187  ThreadVars th_v;
1188  DetectEngineCtx *de_ctx = NULL;
1189  DetectEngineThreadCtx *det_ctx = NULL;
1190  HtpState *http_state = NULL;
1191  Flow f;
1192  uint8_t http1_buf[] =
1193  "GET /index.html HTTP/1.0\r\n"
1194  "Host: www.openinfosecfoundation.org\r\n"
1195  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1196  "Content-Type: text/html\r\n"
1197  "Content-Length: 46\r\n"
1198  "\r\n"
1199  "This is dummy body1";
1200  uint8_t http2_buf[] =
1201  "This is dummy message body2";
1202  uint32_t http1_len = sizeof(http1_buf) - 1;
1203  uint32_t http2_len = sizeof(http2_buf) - 1;
1204  int result = 0;
1206 
1207  memset(&th_v, 0, sizeof(th_v));
1208  memset(&f, 0, sizeof(f));
1209  memset(&ssn, 0, sizeof(ssn));
1210 
1211  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1212  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1213 
1214  FLOW_INITIALIZE(&f);
1215  f.protoctx = (void *)&ssn;
1216  f.proto = IPPROTO_TCP;
1217  f.flags |= FLOW_IPV4;
1218 
1219  p1->flow = &f;
1223  p2->flow = &f;
1227  f.alproto = ALPROTO_HTTP1;
1228 
1229  StreamTcpInitConfig(true);
1230 
1232  if (de_ctx == NULL)
1233  goto end;
1234 
1235  de_ctx->flags |= DE_QUIET;
1236 
1237  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1238  "(msg:\"http client body test\"; "
1239  "content:\"message\"; http_client_body; "
1240  "sid:1;)");
1241  if (de_ctx->sig_list == NULL)
1242  goto end;
1243 
1245  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1246 
1247  int r = AppLayerParserParse(
1248  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1249  if (r != 0) {
1250  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1251  result = 0;
1252  goto end;
1253  }
1254 
1255  http_state = f.alstate;
1256  if (http_state == NULL) {
1257  printf("no http state: ");
1258  result = 0;
1259  goto end;
1260  }
1261 
1262  /* do detect */
1263  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1264 
1265  if ((PacketAlertCheck(p1, 1))) {
1266  printf("sid 1 didn't match but should have");
1267  goto end;
1268  }
1269 
1270  r = AppLayerParserParse(
1271  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1272  if (r != 0) {
1273  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1274  result = 0;
1275  goto end;
1276  }
1277 
1278  /* do detect */
1279  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1280 
1281  if (!(PacketAlertCheck(p2, 1))) {
1282  printf("sid 1 didn't match but should have");
1283  goto end;
1284  }
1285 
1286  result = 1;
1287 end:
1288  if (alp_tctx != NULL)
1290  if (de_ctx != NULL)
1292 
1293  StreamTcpFreeConfig(true);
1294  FLOW_DESTROY(&f);
1295  UTHFreePackets(&p1, 1);
1296  UTHFreePackets(&p2, 1);
1297  return result;
1298 }
1299 
1300 /**
1301  *\test Test that the http_client_body content matches against a http request
1302  * which holds the content, against a cross boundary present pattern.
1303  */
1304 static int DetectHttpClientBodyTest09(void)
1305 {
1306  TcpSession ssn;
1307  Packet *p1 = NULL;
1308  Packet *p2 = NULL;
1309  ThreadVars th_v;
1310  DetectEngineCtx *de_ctx = NULL;
1311  DetectEngineThreadCtx *det_ctx = NULL;
1312  HtpState *http_state = NULL;
1313  Flow f;
1314  uint8_t http1_buf[] =
1315  "GET /index.html HTTP/1.0\r\n"
1316  "Host: www.openinfosecfoundation.org\r\n"
1317  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1318  "Content-Type: text/html\r\n"
1319  "Content-Length: 46\r\n"
1320  "\r\n"
1321  "This is dummy body1";
1322  uint8_t http2_buf[] =
1323  "This is dummy message body2";
1324  uint32_t http1_len = sizeof(http1_buf) - 1;
1325  uint32_t http2_len = sizeof(http2_buf) - 1;
1326  int result = 0;
1328 
1329  memset(&th_v, 0, sizeof(th_v));
1330  memset(&f, 0, sizeof(f));
1331  memset(&ssn, 0, sizeof(ssn));
1332 
1333  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1334  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1335 
1336  FLOW_INITIALIZE(&f);
1337  f.protoctx = (void *)&ssn;
1338  f.proto = IPPROTO_TCP;
1339  f.flags |= FLOW_IPV4;
1340 
1341  p1->flow = &f;
1345  p2->flow = &f;
1349  f.alproto = ALPROTO_HTTP1;
1350 
1351  StreamTcpInitConfig(true);
1352 
1354  if (de_ctx == NULL)
1355  goto end;
1356 
1357  de_ctx->flags |= DE_QUIET;
1358 
1359  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1360  "(msg:\"http client body test\"; "
1361  "content:\"body1This\"; http_client_body; "
1362  "sid:1;)");
1363  if (de_ctx->sig_list == NULL)
1364  goto end;
1365 
1367  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1368 
1369  int r = AppLayerParserParse(
1370  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1371  if (r != 0) {
1372  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1373  result = 0;
1374  goto end;
1375  }
1376 
1377  http_state = f.alstate;
1378  if (http_state == NULL) {
1379  printf("no http state: ");
1380  result = 0;
1381  goto end;
1382  }
1383 
1384  /* do detect */
1385  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1386 
1387  if ((PacketAlertCheck(p1, 1))) {
1388  printf("sid 1 didn't match but should have");
1389  goto end;
1390  }
1391 
1392  r = AppLayerParserParse(
1393  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1394  if (r != 0) {
1395  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1396  result = 0;
1397  goto end;
1398  }
1399 
1400  /* do detect */
1401  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1402 
1403  if (!(PacketAlertCheck(p2, 1))) {
1404  printf("sid 1 didn't match but should have");
1405  goto end;
1406  }
1407 
1408  result = 1;
1409 end:
1410  if (alp_tctx != NULL)
1412  if (de_ctx != NULL)
1414 
1415  StreamTcpFreeConfig(true);
1416  FLOW_DESTROY(&f);
1417  UTHFreePackets(&p1, 1);
1418  UTHFreePackets(&p2, 1);
1419  return result;
1420 }
1421 
1422 /**
1423  *\test Test that the http_client_body content matches against a http request
1424  * against a case insensitive pattern.
1425  */
1426 static int DetectHttpClientBodyTest10(void)
1427 {
1428  TcpSession ssn;
1429  Packet *p1 = NULL;
1430  Packet *p2 = NULL;
1431  ThreadVars th_v;
1432  DetectEngineCtx *de_ctx = NULL;
1433  DetectEngineThreadCtx *det_ctx = NULL;
1434  HtpState *http_state = NULL;
1435  Flow f;
1436  uint8_t http1_buf[] =
1437  "GET /index.html HTTP/1.0\r\n"
1438  "Host: www.openinfosecfoundation.org\r\n"
1439  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1440  "Content-Type: text/html\r\n"
1441  "Content-Length: 46\r\n"
1442  "\r\n"
1443  "This is dummy bodY1";
1444  uint8_t http2_buf[] =
1445  "This is dummy message body2";
1446  uint32_t http1_len = sizeof(http1_buf) - 1;
1447  uint32_t http2_len = sizeof(http2_buf) - 1;
1448  int result = 0;
1450 
1451  memset(&th_v, 0, sizeof(th_v));
1452  memset(&f, 0, sizeof(f));
1453  memset(&ssn, 0, sizeof(ssn));
1454 
1455  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1456  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1457 
1458  FLOW_INITIALIZE(&f);
1459  f.protoctx = (void *)&ssn;
1460  f.proto = IPPROTO_TCP;
1461  f.flags |= FLOW_IPV4;
1462 
1463  p1->flow = &f;
1467  p2->flow = &f;
1471  f.alproto = ALPROTO_HTTP1;
1472 
1473  StreamTcpInitConfig(true);
1474 
1476  if (de_ctx == NULL)
1477  goto end;
1478 
1479  de_ctx->flags |= DE_QUIET;
1480 
1481  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1482  "(msg:\"http client body test\"; "
1483  "content:\"body1This\"; http_client_body; nocase;"
1484  "sid:1;)");
1485  if (de_ctx->sig_list == NULL)
1486  goto end;
1487 
1489  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1490 
1491  int r = AppLayerParserParse(
1492  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
1493  if (r != 0) {
1494  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1495  result = 0;
1496  goto end;
1497  }
1498 
1499  http_state = f.alstate;
1500  if (http_state == NULL) {
1501  printf("no http state: \n");
1502  result = 0;
1503  goto end;
1504  }
1505 
1506  /* do detect */
1507  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1508 
1509  if ((PacketAlertCheck(p1, 1))) {
1510  printf("sid 1 didn't match but should have\n");
1511  goto end;
1512  }
1513 
1514  r = AppLayerParserParse(
1515  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
1516  if (r != 0) {
1517  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1518  result = 0;
1519  goto end;
1520  }
1521 
1522  /* do detect */
1523  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1524 
1525  if (!(PacketAlertCheck(p2, 1))) {
1526  printf("sid 1 didn't match but should have");
1527  goto end;
1528  }
1529 
1530  result = 1;
1531 end:
1532  if (alp_tctx != NULL)
1534  if (de_ctx != NULL)
1536 
1537  StreamTcpFreeConfig(true);
1538  FLOW_DESTROY(&f);
1539  UTHFreePackets(&p1, 1);
1540  UTHFreePackets(&p2, 1);
1541  return result;
1542 }
1543 
1544 /**
1545  *\test Test that the negated http_client_body content matches against a
1546  * http request which doesn't hold the content.
1547  */
1548 static int DetectHttpClientBodyTest11(void)
1549 {
1550  TcpSession ssn;
1551  Packet *p = NULL;
1552  ThreadVars th_v;
1553  DetectEngineCtx *de_ctx = NULL;
1554  DetectEngineThreadCtx *det_ctx = NULL;
1555  HtpState *http_state = NULL;
1556  Flow f;
1557  uint8_t http_buf[] =
1558  "GET /index.html HTTP/1.0\r\n"
1559  "Host: www.openinfosecfoundation.org\r\n"
1560  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1561  "Content-Type: text/html\r\n"
1562  "Content-Length: 26\r\n"
1563  "\r\n"
1564  "This is dummy message body";
1565  uint32_t http_len = sizeof(http_buf) - 1;
1566  int result = 0;
1568 
1569  memset(&th_v, 0, sizeof(th_v));
1570  memset(&f, 0, sizeof(f));
1571  memset(&ssn, 0, sizeof(ssn));
1572 
1573  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1574 
1575  FLOW_INITIALIZE(&f);
1576  f.protoctx = (void *)&ssn;
1577  f.proto = IPPROTO_TCP;
1578  f.flags |= FLOW_IPV4;
1579 
1580  p->flow = &f;
1584  f.alproto = ALPROTO_HTTP1;
1585 
1586  StreamTcpInitConfig(true);
1587 
1589  if (de_ctx == NULL)
1590  goto end;
1591 
1592  de_ctx->flags |= DE_QUIET;
1593 
1594  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1595  "(msg:\"http client body test\"; "
1596  "content:!\"message1\"; http_client_body; "
1597  "sid:1;)");
1598  if (de_ctx->sig_list == NULL)
1599  goto end;
1600 
1602  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1603 
1604  int r = AppLayerParserParse(
1605  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1606  if (r != 0) {
1607  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1608  result = 0;
1609  goto end;
1610  }
1611 
1612  http_state = f.alstate;
1613  if (http_state == NULL) {
1614  printf("no http state: ");
1615  result = 0;
1616  goto end;
1617  }
1618 
1619  /* do detect */
1620  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1621 
1622  if (!(PacketAlertCheck(p, 1))) {
1623  printf("sid 1 didn't match but should have");
1624  goto end;
1625  }
1626 
1627  result = 1;
1628 end:
1629  if (alp_tctx != NULL)
1631  if (de_ctx != NULL)
1633 
1634  StreamTcpFreeConfig(true);
1635  FLOW_DESTROY(&f);
1636  UTHFreePackets(&p, 1);
1637  return result;
1638 }
1639 
1640 /**
1641  *\test Negative test that the negated http_client_body content matches against a
1642  * http request which holds hold the content.
1643  */
1644 static int DetectHttpClientBodyTest12(void)
1645 {
1646  TcpSession ssn;
1647  Packet *p = NULL;
1648  ThreadVars th_v;
1649  DetectEngineCtx *de_ctx = NULL;
1650  DetectEngineThreadCtx *det_ctx = NULL;
1651  HtpState *http_state = NULL;
1652  Flow f;
1653  uint8_t http_buf[] =
1654  "GET /index.html HTTP/1.0\r\n"
1655  "Host: www.openinfosecfoundation.org\r\n"
1656  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1657  "Content-Type: text/html\r\n"
1658  "Content-Length: 26\r\n"
1659  "\r\n"
1660  "This is dummy message body";
1661  uint32_t http_len = sizeof(http_buf) - 1;
1662  int result = 0;
1664 
1665  memset(&th_v, 0, sizeof(th_v));
1666  memset(&f, 0, sizeof(f));
1667  memset(&ssn, 0, sizeof(ssn));
1668 
1669  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1670 
1671  FLOW_INITIALIZE(&f);
1672  f.protoctx = (void *)&ssn;
1673  f.proto = IPPROTO_TCP;
1674  f.flags |= FLOW_IPV4;
1675 
1676  p->flow = &f;
1680  f.alproto = ALPROTO_HTTP1;
1681 
1682  StreamTcpInitConfig(true);
1683 
1685  if (de_ctx == NULL)
1686  goto end;
1687 
1688  de_ctx->flags |= DE_QUIET;
1689 
1690  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1691  "(msg:\"http client body test\"; "
1692  "content:!\"message\"; http_client_body; "
1693  "sid:1;)");
1694  if (de_ctx->sig_list == NULL)
1695  goto end;
1696 
1698  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1699 
1700  int r = AppLayerParserParse(
1701  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1702  if (r != 0) {
1703  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1704  result = 0;
1705  goto end;
1706  }
1707 
1708  http_state = f.alstate;
1709  if (http_state == NULL) {
1710  printf("no http state: ");
1711  result = 0;
1712  goto end;
1713  }
1714 
1715  /* do detect */
1716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1717 
1718  if ((PacketAlertCheck(p, 1))) {
1719  printf("sid 1 didn't match but should have");
1720  goto end;
1721  }
1722 
1723  result = 1;
1724 end:
1725  if (alp_tctx != NULL)
1727  if (de_ctx != NULL)
1729 
1730  StreamTcpFreeConfig(true);
1731  FLOW_DESTROY(&f);
1732  UTHFreePackets(&p, 1);
1733  return result;
1734 }
1735 
1736 /**
1737  *\test Test that the http_client_body content matches against a http request
1738  * which holds the content.
1739  */
1740 static int DetectHttpClientBodyTest13(void)
1741 {
1742  TcpSession ssn;
1743  Packet *p = NULL;
1744  ThreadVars th_v;
1745  DetectEngineCtx *de_ctx = NULL;
1746  DetectEngineThreadCtx *det_ctx = NULL;
1747  HtpState *http_state = NULL;
1748  Flow f;
1749  uint8_t http_buf[] =
1750  "GET /index.html HTTP/1.0\r\n"
1751  "Host: www.openinfosecfoundation.org\r\n"
1752  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1753  "Content-Type: text/html\r\n"
1754  "Content-Length: 55\r\n"
1755  "\r\n"
1756  "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend";
1757  uint32_t http_len = sizeof(http_buf) - 1;
1758  int result = 0;
1760 
1761  memset(&th_v, 0, sizeof(th_v));
1762  memset(&f, 0, sizeof(f));
1763  memset(&ssn, 0, sizeof(ssn));
1764 
1765  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1766 
1767  FLOW_INITIALIZE(&f);
1768  f.protoctx = (void *)&ssn;
1769  f.proto = IPPROTO_TCP;
1770  f.flags |= FLOW_IPV4;
1771 
1772  p->flow = &f;
1776  f.alproto = ALPROTO_HTTP1;
1777 
1778  StreamTcpInitConfig(true);
1779 
1781  if (de_ctx == NULL)
1782  goto end;
1783 
1784  de_ctx->flags |= DE_QUIET;
1785 
1786  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1787  "(msg:\"http client body test\"; "
1788  "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_client_body; "
1789  "sid:1;)");
1790  if (de_ctx->sig_list == NULL)
1791  goto end;
1792 
1794  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1795 
1796  int r = AppLayerParserParse(
1797  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
1798  if (r != 0) {
1799  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1800  result = 0;
1801  goto end;
1802  }
1803 
1804  http_state = f.alstate;
1805  if (http_state == NULL) {
1806  printf("no http state: ");
1807  result = 0;
1808  goto end;
1809  }
1810 
1811  /* do detect */
1812  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1813 
1814  if (!(PacketAlertCheck(p, 1))) {
1815  printf("sid 1 didn't match but should have");
1816  goto end;
1817  }
1818 
1819  result = 1;
1820 end:
1821  if (alp_tctx != NULL)
1823  if (de_ctx != NULL)
1825 
1826  StreamTcpFreeConfig(true);
1827  FLOW_DESTROY(&f);
1828  UTHFreePackets(&p, 1);
1829  return result;
1830 }
1831 
1832 /** \test multiple http transactions and body chunks of request handling */
1833 static int DetectHttpClientBodyTest14(void)
1834 {
1835  int result = 0;
1836  Signature *s = NULL;
1837  DetectEngineThreadCtx *det_ctx = NULL;
1838  ThreadVars th_v;
1839  Flow f;
1840  TcpSession ssn;
1841  Packet *p = NULL;
1842  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
1843  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1844  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
1845  uint8_t httpbuf4[] = "Body one!!";
1846  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1847  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1848  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1849  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1850  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
1851  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
1852  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1853  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
1854  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
1855  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
1857 
1858  memset(&th_v, 0, sizeof(th_v));
1859  memset(&f, 0, sizeof(f));
1860  memset(&ssn, 0, sizeof(ssn));
1861 
1862  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1863 
1864  FLOW_INITIALIZE(&f);
1865  f.protoctx = (void *)&ssn;
1866  f.proto = IPPROTO_TCP;
1867  f.flags |= FLOW_IPV4;
1868 
1869  p->flow = &f;
1873  f.alproto = ALPROTO_HTTP1;
1874 
1875  StreamTcpInitConfig(true);
1876 
1878  if (de_ctx == NULL) {
1879  goto end;
1880  }
1881 
1882  de_ctx->flags |= DE_QUIET;
1883 
1884  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;)");
1885  if (s == NULL) {
1886  printf("sig parse failed: ");
1887  goto end;
1888  }
1889  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;)");
1890  if (s == NULL) {
1891  printf("sig2 parse failed: ");
1892  goto end;
1893  }
1894 
1896  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1897 
1898  int r = AppLayerParserParse(
1899  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1900  if (r != 0) {
1901  printf("toserver chunk 1 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: ");
1909  goto end;
1910  }
1911  p->alerts.cnt = 0;
1912 
1913  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1914  if (r != 0) {
1915  printf("toserver chunk 2 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)) {
1922  printf("sig 1 alerted (2): ");
1923  goto end;
1924  }
1925  p->alerts.cnt = 0;
1926 
1927  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1928  if (r != 0) {
1929  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
1930  goto end;
1931  }
1932 
1933  /* do detect */
1934  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1935  if (PacketAlertCheck(p, 1)) {
1936  printf("signature matched, but shouldn't have: ");
1937  goto end;
1938  }
1939  p->alerts.cnt = 0;
1940 
1941  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
1942  if (r != 0) {
1943  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
1944  result = 0;
1945  goto end;
1946  }
1947 
1948  /* do detect */
1949  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1950  if (!(PacketAlertCheck(p, 1))) {
1951  printf("sig 1 didn't alert: ");
1952  goto end;
1953  }
1954  p->alerts.cnt = 0;
1955 
1956  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
1957  if (r != 0) {
1958  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
1959  goto end;
1960  }
1961 
1962  /* do detect */
1963  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1964  if (PacketAlertCheck(p, 1)) {
1965  printf("sig 1 alerted (5): ");
1966  goto end;
1967  }
1968  p->alerts.cnt = 0;
1969 
1970  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
1971  if (r != 0) {
1972  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
1973  goto end;
1974  }
1975 
1976  /* do detect */
1977  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1978  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
1979  printf("sig 1 alerted (request 2, chunk 6): ");
1980  goto end;
1981  }
1982  p->alerts.cnt = 0;
1983 
1984  SCLogDebug("sending data chunk 7");
1985 
1986  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
1987  if (r != 0) {
1988  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
1989  goto end;
1990  }
1991 
1992  /* do detect */
1993  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1994  if (!(PacketAlertCheck(p, 2))) {
1995  printf("signature 2 didn't match, but should have: ");
1996  goto end;
1997  }
1998  p->alerts.cnt = 0;
1999 
2000  HtpState *htp_state = f.alstate;
2001  if (htp_state == NULL) {
2002  printf("no http state: ");
2003  result = 0;
2004  goto end;
2005  }
2006 
2007  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2008  printf("The http app layer doesn't have 2 transactions, but it should: ");
2009  goto end;
2010  }
2011 
2012  result = 1;
2013 end:
2014  if (alp_tctx != NULL)
2016  if (det_ctx != NULL) {
2017  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2018  }
2019  if (de_ctx != NULL) {
2021  }
2022 
2023  StreamTcpFreeConfig(true);
2024  FLOW_DESTROY(&f);
2025  UTHFreePacket(p);
2026  return result;
2027 }
2028 
2029 /** \test multiple http transactions and body chunks of request handling */
2030 static int DetectHttpClientBodyTest15(void)
2031 {
2032  int result = 0;
2033  Signature *s = NULL;
2034  DetectEngineThreadCtx *det_ctx = NULL;
2035  ThreadVars th_v;
2036  Flow f;
2037  TcpSession ssn;
2038  Packet *p = NULL;
2039  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
2040  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2041  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
2042  uint8_t httpbuf4[] = "Body one!!";
2043  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2044  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2045  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2046  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2047  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
2048  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
2049  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2050  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2051  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2052  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
2054 
2055  memset(&th_v, 0, sizeof(th_v));
2056  memset(&f, 0, sizeof(f));
2057  memset(&ssn, 0, sizeof(ssn));
2058 
2059  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2060 
2061  FLOW_INITIALIZE(&f);
2062  f.protoctx = (void *)&ssn;
2063  f.proto = IPPROTO_TCP;
2064  f.flags |= FLOW_IPV4;
2065 
2066  p->flow = &f;
2070  f.alproto = ALPROTO_HTTP1;
2071 
2072  StreamTcpInitConfig(true);
2073 
2075  if (de_ctx == NULL) {
2076  goto end;
2077  }
2078 
2079  de_ctx->flags |= DE_QUIET;
2080 
2081  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;)");
2082  if (s == NULL) {
2083  printf("sig parse failed: ");
2084  goto end;
2085  }
2086  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;)");
2087  if (s == NULL) {
2088  printf("sig2 parse failed: ");
2089  goto end;
2090  }
2091 
2093  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2094 
2095  int r = AppLayerParserParse(
2096  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2097  if (r != 0) {
2098  printf("toserver chunk 1 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: ");
2106  goto end;
2107  }
2108  p->alerts.cnt = 0;
2109 
2110  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2111  if (r != 0) {
2112  printf("toserver chunk 2 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)) {
2119  printf("sig 1 alerted (2): ");
2120  goto end;
2121  }
2122  p->alerts.cnt = 0;
2123 
2124  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
2125  if (r != 0) {
2126  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
2127  goto end;
2128  }
2129 
2130  /* do detect */
2131  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2132  if (PacketAlertCheck(p, 1)) {
2133  printf("signature matched, but shouldn't have: ");
2134  goto end;
2135  }
2136  p->alerts.cnt = 0;
2137 
2138  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
2139  if (r != 0) {
2140  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
2141  result = 0;
2142  goto end;
2143  }
2144 
2145  /* do detect */
2146  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2147  if (!(PacketAlertCheck(p, 1))) {
2148  printf("sig 1 didn't alert: ");
2149  goto end;
2150  }
2151  p->alerts.cnt = 0;
2152 
2153  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
2154  if (r != 0) {
2155  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2156  goto end;
2157  }
2158 
2159  /* do detect */
2160  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2161  if (PacketAlertCheck(p, 1)) {
2162  printf("sig 1 alerted (5): ");
2163  goto end;
2164  }
2165  p->alerts.cnt = 0;
2166 
2167  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
2168  if (r != 0) {
2169  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2170  goto end;
2171  }
2172 
2173  /* do detect */
2174  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2175  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2176  printf("sig 1 alerted (request 2, chunk 6): ");
2177  goto end;
2178  }
2179  p->alerts.cnt = 0;
2180 
2181  SCLogDebug("sending data chunk 7");
2182 
2183  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
2184  if (r != 0) {
2185  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2186  goto end;
2187  }
2188 
2189  /* do detect */
2190  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2191  if (!(PacketAlertCheck(p, 2))) {
2192  printf("signature 2 didn't match, but should have: ");
2193  goto end;
2194  }
2195  p->alerts.cnt = 0;
2196 
2197  HtpState *htp_state = f.alstate;
2198  if (htp_state == NULL) {
2199  printf("no http state: ");
2200  result = 0;
2201  goto end;
2202  }
2203 
2204  /* hardcoded check of the transactions and it's client body chunks */
2205  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2206  printf("The http app layer doesn't have 2 transactions, but it should: ");
2207  goto end;
2208  }
2209 
2210  htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 0);
2211  htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 1);
2212 
2213  HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2214 
2215  HtpBodyChunk *cur = htud->request_body.first;
2216  if (htud->request_body.first == NULL) {
2217  SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2218  goto end;
2219  }
2220 
2222  (uint8_t *)"Body one!!", 10) != 1)
2223  {
2224  SCLogDebug("Body data in t1 is not correctly set: ");
2225  goto end;
2226  }
2227 
2228  htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2229 
2230  cur = htud->request_body.first;
2231  if (htud->request_body.first == NULL) {
2232  SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2233  goto end;
2234  }
2235 
2237  (uint8_t *)"Body two!!", 10) != 1)
2238  {
2239  SCLogDebug("Body data in t1 is not correctly set: ");
2240  goto end;
2241  }
2242 
2243  result = 1;
2244 end:
2245  if (alp_tctx != NULL)
2247  if (det_ctx != NULL) {
2248  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2249  }
2250  if (de_ctx != NULL) {
2252  }
2253 
2254  StreamTcpFreeConfig(true);
2255  FLOW_DESTROY(&f);
2256  UTHFreePacket(p);
2257  return result;
2258 }
2259 
2260 static int DetectHttpClientBodyTest22(void)
2261 {
2262  DetectEngineCtx *de_ctx = NULL;
2263  int result = 0;
2264 
2265  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2266  goto end;
2267 
2268  de_ctx->flags |= DE_QUIET;
2269  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2270  "(content:\"one\"; content:\"two\"; http_client_body; "
2271  "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2272  if (de_ctx->sig_list == NULL) {
2273  printf("de_ctx->sig_list == NULL\n");
2274  goto end;
2275  }
2276 
2277  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2278  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2279  goto end;
2280  }
2281 
2282  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2283  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2284  goto end;
2285  }
2286 
2287  DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2289  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2290  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2291  if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 ||
2292  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2293  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2294  memcmp(hcbd1->content, "two", hcbd1->content_len) != 0 ||
2295  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2296  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2297  goto end;
2298  }
2299 
2300  if (!DETECT_CONTENT_IS_SINGLE(cd1) ||
2301  !DETECT_CONTENT_IS_SINGLE(cd2) ||
2302  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2303  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2304  goto end;
2305  }
2306 
2307  result = 1;
2308 
2309  end:
2311  return result;
2312 }
2313 
2314 static int DetectHttpClientBodyTest23(void)
2315 {
2316  DetectEngineCtx *de_ctx = NULL;
2317  int result = 0;
2318 
2319  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2320  goto end;
2321 
2322  de_ctx->flags |= DE_QUIET;
2323  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2324  "(content:\"one\"; http_client_body; pcre:/two/; "
2325  "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2326  if (de_ctx->sig_list == NULL) {
2327  printf("de_ctx->sig_list == NULL\n");
2328  goto end;
2329  }
2330 
2331  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2332  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2333  goto end;
2334  }
2335 
2336  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2337  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2338  goto end;
2339  }
2340 
2341  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2343  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2344  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2345  if (pd1->flags != 0 ||
2346  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2347  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2348  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2349  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2350  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2351  goto end;
2352  }
2353 
2354  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
2355  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2356  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2357  goto end;
2358  }
2359 
2360  result = 1;
2361 
2362  end:
2364  return result;
2365 }
2366 
2367 static int DetectHttpClientBodyTest24(void)
2368 {
2369  DetectEngineCtx *de_ctx = NULL;
2370  int result = 0;
2371 
2372  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2373  goto end;
2374 
2375  de_ctx->flags |= DE_QUIET;
2376  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2377  "(content:\"one\"; http_client_body; pcre:/two/; "
2378  "content:\"three\"; distance:10; within:15; http_client_body; content:\"four\"; sid:1;)");
2379  if (de_ctx->sig_list == NULL) {
2380  printf("de_ctx->sig_list == NULL\n");
2381  goto end;
2382  }
2383 
2384  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2385  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2386  goto end;
2387  }
2388 
2389  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2390  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2391  goto end;
2392  }
2393 
2394  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2396  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2397  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2398  if (pd1->flags != 0 ||
2399  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2400  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2401  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2402  hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
2403  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2404  goto end;
2405  }
2406 
2407  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
2408  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2409  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2410  goto end;
2411  }
2412 
2413  result = 1;
2414 
2415  end:
2417  return result;
2418 }
2419 
2420 static int DetectHttpClientBodyTest25(void)
2421 {
2422  DetectEngineCtx *de_ctx = NULL;
2423  int result = 0;
2424 
2425  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2426  goto end;
2427 
2428  de_ctx->flags |= DE_QUIET;
2429  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2430  "(content:\"one\"; http_client_body; pcre:/two/; "
2431  "content:\"three\"; distance:10; http_client_body; "
2432  "content:\"four\"; distance:10; sid:1;)");
2433  if (de_ctx->sig_list == NULL) {
2434  printf("de_ctx->sig_list == NULL\n");
2435  goto end;
2436  }
2437 
2438  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2439  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2440  goto end;
2441  }
2442 
2443  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2444  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2445  goto end;
2446  }
2447 
2448  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2450  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2451  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2452  if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT ||
2453  cd2->flags != DETECT_CONTENT_DISTANCE ||
2454  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2455  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2456  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2457  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2458  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2459  goto end;
2460  }
2461 
2462  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2463  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2464  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2465  goto end;
2466  }
2467 
2468  result = 1;
2469 
2470  end:
2472  return result;
2473 }
2474 
2475 static int DetectHttpClientBodyTest26(void)
2476 {
2477  DetectEngineCtx *de_ctx = NULL;
2478  int result = 0;
2479 
2480  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2481  goto end;
2482 
2483  de_ctx->flags |= DE_QUIET;
2484  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2485  "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2486  "content:\"three\"; distance:10; http_client_body; within:10; "
2487  "content:\"four\"; distance:10; sid:1;)");
2488  if (de_ctx->sig_list == NULL) {
2489  printf("de_ctx->sig_list == NULL\n");
2490  goto end;
2491  }
2492 
2493  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2494  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2495  goto end;
2496  }
2497 
2498  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2499  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2500  goto end;
2501  }
2502 
2503  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2505  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2506  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2507  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2508  cd2->flags != DETECT_CONTENT_DISTANCE ||
2509  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2511  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2512  hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
2513  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2514  printf ("failed: http_client_body incorrect flags");
2515  goto end;
2516  }
2517 
2518  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2519  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2520  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2521  goto end;
2522  }
2523 
2524  result = 1;
2525 
2526  end:
2528  return result;
2529 }
2530 
2531 static int DetectHttpClientBodyTest27(void)
2532 {
2533  DetectEngineCtx *de_ctx = NULL;
2534  int result = 0;
2535 
2536  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2537  goto end;
2538 
2539  de_ctx->flags |= DE_QUIET;
2540  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2541  "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2542  "content:\"three\"; distance:10; http_client_body; within:10; "
2543  "content:\"four\"; distance:10; sid:1;)");
2544  if (de_ctx->sig_list == NULL) {
2545  printf("de_ctx->sig_list == NULL\n");
2546  goto end;
2547  }
2548 
2549  result = 1;
2550 
2551  end:
2553  return result;
2554 }
2555 
2556 static int DetectHttpClientBodyTest28(void)
2557 {
2558  DetectEngineCtx *de_ctx = NULL;
2559  int result = 0;
2560 
2561  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2562  goto end;
2563 
2564  de_ctx->flags |= DE_QUIET;
2565  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2566  "(content:\"one\"; http_client_body; pcre:/two/; "
2567  "content:\"three\"; http_client_body; depth:10; "
2568  "content:\"four\"; distance:10; sid:1;)");
2569  if (de_ctx->sig_list == NULL) {
2570  printf("de_ctx->sig_list == NULL\n");
2571  goto end;
2572  }
2573 
2574  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2575  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2576  goto end;
2577  }
2578 
2579  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2580  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2581  goto end;
2582  }
2583 
2584  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2586  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2587  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2588  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2589  cd2->flags != DETECT_CONTENT_DISTANCE ||
2590  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2591  hcbd1->flags != 0 ||
2592  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2593  hcbd2->flags != DETECT_CONTENT_DEPTH ||
2594  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2595  goto end;
2596  }
2597 
2598  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2599  !DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2600  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2601  goto end;
2602  }
2603 
2604  result = 1;
2605 
2606  end:
2608  return result;
2609 }
2610 
2611 static int DetectHttpClientBodyTest29(void)
2612 {
2613  DetectEngineCtx *de_ctx = NULL;
2614  int result = 0;
2615 
2616  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2617  goto end;
2618 
2619  de_ctx->flags |= DE_QUIET;
2620  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2621  "(content:\"one\"; http_client_body; "
2622  "content:\"two\"; distance:0; http_client_body; sid:1;)");
2623  if (de_ctx->sig_list == NULL) {
2624  printf("de_ctx->sig_list == NULL\n");
2625  goto end;
2626  }
2627 
2628  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2629  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2630  goto end;
2631  }
2632 
2633  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2634  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2635  goto end;
2636  }
2637 
2638  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2639  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2640  if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2641  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2642  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2643  memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2644  goto end;
2645  }
2646 
2647  result = 1;
2648 
2649  end:
2651  return result;
2652 }
2653 
2654 static int DetectHttpClientBodyTest30(void)
2655 {
2656  DetectEngineCtx *de_ctx = NULL;
2657  int result = 0;
2658 
2659  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2660  goto end;
2661 
2662  de_ctx->flags |= DE_QUIET;
2663  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2664  "(content:\"one\"; http_client_body; "
2665  "content:\"two\"; within:5; http_client_body; sid:1;)");
2666  if (de_ctx->sig_list == NULL) {
2667  printf("de_ctx->sig_list == NULL\n");
2668  goto end;
2669  }
2670 
2671  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2672  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2673  goto end;
2674  }
2675 
2676  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2677  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2678  goto end;
2679  }
2680 
2681  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2682  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2683  if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2684  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2685  hcbd2->flags != DETECT_CONTENT_WITHIN ||
2686  memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2687  goto end;
2688  }
2689 
2690  result = 1;
2691 
2692  end:
2694  return result;
2695 }
2696 
2697 static int DetectHttpClientBodyTest31(void)
2698 {
2699  DetectEngineCtx *de_ctx = NULL;
2700  int result = 0;
2701 
2702  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2703  goto end;
2704 
2705  de_ctx->flags |= DE_QUIET;
2706  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2707  "(content:\"one\"; within:5; http_client_body; sid:1;)");
2708  if (de_ctx->sig_list == NULL) {
2709  printf("de_ctx->sig_list == NULL\n");
2710  goto end;
2711  }
2712 
2713  result = 1;
2714 
2715  end:
2717  return result;
2718 }
2719 
2720 static int DetectHttpClientBodyTest32(void)
2721 {
2722  DetectEngineCtx *de_ctx = NULL;
2723  int result = 0;
2724 
2725  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2726  goto end;
2727 
2728  de_ctx->flags |= DE_QUIET;
2729  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2730  "(content:\"one\"; http_client_body; within:5; sid:1;)");
2731  if (de_ctx->sig_list == NULL) {
2732  printf("de_ctx->sig_list != NULL\n");
2733  goto end;
2734  }
2735 
2736  result = 1;
2737 
2738  end:
2740  return result;
2741 }
2742 
2743 static int DetectHttpClientBodyTest33(void)
2744 {
2745  DetectEngineCtx *de_ctx = NULL;
2746  int result = 0;
2747 
2748  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2749  goto end;
2750 
2751  de_ctx->flags |= DE_QUIET;
2752  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2753  "(content:\"one\"; within:5; sid:1;)");
2754  if (de_ctx->sig_list == NULL) {
2755  printf("de_ctx->sig_list == NULL\n");
2756  goto end;
2757  }
2758 
2759  result = 1;
2760 
2761  end:
2763  return result;
2764 }
2765 
2766 static int DetectHttpClientBodyTest34(void)
2767 {
2768  DetectEngineCtx *de_ctx = NULL;
2769  int result = 0;
2770 
2771  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2772  goto end;
2773 
2774  de_ctx->flags |= DE_QUIET;
2775  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2776  "(pcre:/one/P; "
2777  "content:\"two\"; within:5; http_client_body; sid:1;)");
2778  if (de_ctx->sig_list == NULL) {
2779  printf("de_ctx->sig_list == NULL\n");
2780  goto end;
2781  }
2782 
2783  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2784  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2785  goto end;
2786  }
2787 
2788  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2789  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2790  goto end;
2791  }
2792 
2793  if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2794  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_CONTENT ||
2795  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2796  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_PCRE) {
2797 
2798  goto end;
2799  }
2800 
2801  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2802  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2803  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2804  hcbd2->flags != DETECT_CONTENT_WITHIN ||
2805  memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2806  goto end;
2807  }
2808 
2809  result = 1;
2810 
2811  end:
2813  return result;
2814 }
2815 
2816 static int DetectHttpClientBodyTest35(void)
2817 {
2818  DetectEngineCtx *de_ctx = NULL;
2819  int result = 0;
2820 
2821  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2822  goto end;
2823 
2824  de_ctx->flags |= DE_QUIET;
2825  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2826  "(content:\"two\"; http_client_body; "
2827  "pcre:/one/PR; sid:1;)");
2828  if (de_ctx->sig_list == NULL) {
2829  printf("de_ctx->sig_list == NULL\n");
2830  goto end;
2831  }
2832 
2833  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2834  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2835  goto end;
2836  }
2837 
2838  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2839  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2840  goto end;
2841  }
2842 
2843  if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2844  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_PCRE ||
2845  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2846  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_CONTENT) {
2847 
2848  goto end;
2849  }
2850 
2851  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2852  DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2853  if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
2854  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2855  memcmp(hcbd1->content, "two", hcbd1->content_len) != 0) {
2856  goto end;
2857  }
2858 
2859  result = 1;
2860 
2861  end:
2863  return result;
2864 }
2865 
2866 static int DetectHttpClientBodyTest36(void)
2867 {
2868  DetectEngineCtx *de_ctx = NULL;
2869  int result = 0;
2870 
2871  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2872  goto end;
2873 
2874  de_ctx->flags |= DE_QUIET;
2875  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2876  "(pcre:/one/P; "
2877  "content:\"two\"; distance:5; http_client_body; sid:1;)");
2878  if (de_ctx->sig_list == NULL) {
2879  printf("de_ctx->sig_list == NULL\n");
2880  goto end;
2881  }
2882 
2883  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2884  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2885  goto end;
2886  }
2887 
2888  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2889  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2890  goto end;
2891  }
2892 
2893  if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2894  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_CONTENT ||
2895  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2896  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_PCRE) {
2897 
2898  goto end;
2899  }
2900 
2901  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2902  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2903  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2904  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2905  memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2906  goto end;
2907  }
2908 
2909  result = 1;
2910 
2911  end:
2913  return result;
2914 }
2915 
2916 static int DetectHttpClientBodyIsdataatParseTest(void)
2917 {
2920  de_ctx->flags |= DE_QUIET;
2921 
2923  "alert tcp any any -> any any ("
2924  "content:\"one\"; http_client_body; "
2925  "isdataat:!4,relative; sid:1;)");
2926  FAIL_IF_NULL(s);
2927 
2928  SigMatch *sm = s->init_data->smlists_tail[g_http_client_body_buffer_id];
2929  FAIL_IF_NULL(sm);
2931 
2932  DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
2935  FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
2936 
2938  PASS;
2939 }
2940 
2942 {
2943  UtRegisterTest("DetectHttpClientBodyParserTest01", DetectHttpClientBodyParserTest01);
2944  UtRegisterTest("DetectHttpClientBodyParserTest02", DetectHttpClientBodyParserTest02);
2945  UtRegisterTest("DetectHttpClientBodyTest01", DetectHttpClientBodyTest01);
2946  UtRegisterTest("DetectHttpClientBodyTest02", DetectHttpClientBodyTest02);
2947  UtRegisterTest("DetectHttpClientBodyTest03", DetectHttpClientBodyTest03);
2948  UtRegisterTest("DetectHttpClientBodyTest04", DetectHttpClientBodyTest04);
2949  UtRegisterTest("DetectHttpClientBodyTest05", DetectHttpClientBodyTest05);
2950  UtRegisterTest("DetectHttpClientBodyTest06", DetectHttpClientBodyTest06);
2951  UtRegisterTest("DetectHttpClientBodyTest07", DetectHttpClientBodyTest07);
2952  UtRegisterTest("DetectHttpClientBodyTest08", DetectHttpClientBodyTest08);
2953  UtRegisterTest("DetectHttpClientBodyTest09", DetectHttpClientBodyTest09);
2954  UtRegisterTest("DetectHttpClientBodyTest10", DetectHttpClientBodyTest10);
2955  UtRegisterTest("DetectHttpClientBodyTest11", DetectHttpClientBodyTest11);
2956  UtRegisterTest("DetectHttpClientBodyTest12", DetectHttpClientBodyTest12);
2957  UtRegisterTest("DetectHttpClientBodyTest13", DetectHttpClientBodyTest13);
2958  UtRegisterTest("DetectHttpClientBodyTest14", DetectHttpClientBodyTest14);
2959  UtRegisterTest("DetectHttpClientBodyTest15", DetectHttpClientBodyTest15);
2960 
2961  UtRegisterTest("DetectHttpClientBodyTest22", DetectHttpClientBodyTest22);
2962  UtRegisterTest("DetectHttpClientBodyTest23", DetectHttpClientBodyTest23);
2963  UtRegisterTest("DetectHttpClientBodyTest24", DetectHttpClientBodyTest24);
2964  UtRegisterTest("DetectHttpClientBodyTest25", DetectHttpClientBodyTest25);
2965  UtRegisterTest("DetectHttpClientBodyTest26", DetectHttpClientBodyTest26);
2966  UtRegisterTest("DetectHttpClientBodyTest27", DetectHttpClientBodyTest27);
2967  UtRegisterTest("DetectHttpClientBodyTest28", DetectHttpClientBodyTest28);
2968  UtRegisterTest("DetectHttpClientBodyTest29", DetectHttpClientBodyTest29);
2969  UtRegisterTest("DetectHttpClientBodyTest30", DetectHttpClientBodyTest30);
2970  UtRegisterTest("DetectHttpClientBodyTest31", DetectHttpClientBodyTest31);
2971  UtRegisterTest("DetectHttpClientBodyTest32", DetectHttpClientBodyTest32);
2972  UtRegisterTest("DetectHttpClientBodyTest33", DetectHttpClientBodyTest33);
2973  UtRegisterTest("DetectHttpClientBodyTest34", DetectHttpClientBodyTest34);
2974  UtRegisterTest("DetectHttpClientBodyTest35", DetectHttpClientBodyTest35);
2975  UtRegisterTest("DetectHttpClientBodyTest36", DetectHttpClientBodyTest36);
2976 
2977  UtRegisterTest("DetectHttpClientBodyIsdataatParseTest",
2978  DetectHttpClientBodyIsdataatParseTest);
2979 
2980  UtRegisterTest("DetectEngineHttpClientBodyTest01",
2981  DetectEngineHttpClientBodyTest01);
2982  UtRegisterTest("DetectEngineHttpClientBodyTest02",
2983  DetectEngineHttpClientBodyTest02);
2984  UtRegisterTest("DetectEngineHttpClientBodyTest03",
2985  DetectEngineHttpClientBodyTest03);
2986  UtRegisterTest("DetectEngineHttpClientBodyTest04",
2987  DetectEngineHttpClientBodyTest04);
2988  UtRegisterTest("DetectEngineHttpClientBodyTest05",
2989  DetectEngineHttpClientBodyTest05);
2990  UtRegisterTest("DetectEngineHttpClientBodyTest06",
2991  DetectEngineHttpClientBodyTest06);
2992  UtRegisterTest("DetectEngineHttpClientBodyTest07",
2993  DetectEngineHttpClientBodyTest07);
2994  UtRegisterTest("DetectEngineHttpClientBodyTest08",
2995  DetectEngineHttpClientBodyTest08);
2996  UtRegisterTest("DetectEngineHttpClientBodyTest09",
2997  DetectEngineHttpClientBodyTest09);
2998  UtRegisterTest("DetectEngineHttpClientBodyTest10",
2999  DetectEngineHttpClientBodyTest10);
3000  UtRegisterTest("DetectEngineHttpClientBodyTest11",
3001  DetectEngineHttpClientBodyTest11);
3002  UtRegisterTest("DetectEngineHttpClientBodyTest12",
3003  DetectEngineHttpClientBodyTest12);
3004  UtRegisterTest("DetectEngineHttpClientBodyTest13",
3005  DetectEngineHttpClientBodyTest13);
3006  UtRegisterTest("DetectEngineHttpClientBodyTest14",
3007  DetectEngineHttpClientBodyTest14);
3008  UtRegisterTest("DetectEngineHttpClientBodyTest15",
3009  DetectEngineHttpClientBodyTest15);
3010  UtRegisterTest("DetectEngineHttpClientBodyTest16",
3011  DetectEngineHttpClientBodyTest16);
3012  UtRegisterTest("DetectEngineHttpClientBodyTest17",
3013  DetectEngineHttpClientBodyTest17);
3014  UtRegisterTest("DetectEngineHttpClientBodyTest18",
3015  DetectEngineHttpClientBodyTest18);
3016  UtRegisterTest("DetectEngineHttpClientBodyTest19",
3017  DetectEngineHttpClientBodyTest19);
3018  UtRegisterTest("DetectEngineHttpClientBodyTest20",
3019  DetectEngineHttpClientBodyTest20);
3020  UtRegisterTest("DetectEngineHttpClientBodyTest21",
3021  DetectEngineHttpClientBodyTest21);
3022  UtRegisterTest("DetectEngineHttpClientBodyTest22",
3023  DetectEngineHttpClientBodyTest22);
3024  UtRegisterTest("DetectEngineHttpClientBodyTest23",
3025  DetectEngineHttpClientBodyTest23);
3026  UtRegisterTest("DetectEngineHttpClientBodyTest24",
3027  DetectEngineHttpClientBodyTest24);
3028  UtRegisterTest("DetectEngineHttpClientBodyTest25",
3029  DetectEngineHttpClientBodyTest25);
3030  UtRegisterTest("DetectEngineHttpClientBodyTest26",
3031  DetectEngineHttpClientBodyTest26);
3032  UtRegisterTest("DetectEngineHttpClientBodyTest27",
3033  DetectEngineHttpClientBodyTest27);
3034  UtRegisterTest("DetectEngineHttpClientBodyTest28",
3035  DetectEngineHttpClientBodyTest28);
3036  UtRegisterTest("DetectEngineHttpClientBodyTest29",
3037  DetectEngineHttpClientBodyTest29);
3038 
3039  UtRegisterTest("DetectEngineHttpClientBodyTest30",
3040  DetectEngineHttpClientBodyTest30);
3041  UtRegisterTest("DetectEngineHttpClientBodyTest31",
3042  DetectEngineHttpClientBodyTest31);
3043 }
3044 
3045 #endif
3046 
3047 /**
3048  * @}
3049  */
TestSteps
Definition: detect-http-client-body.c:107
DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_RELATIVE_NEXT
Definition: detect-content.h:64
UTHParseSignature
int UTHParseSignature(const char *str, bool expect)
parser a sig and see if the expected result is correct
Definition: util-unittest-helper.c:930
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:79
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1003
flow-util.h
stream-tcp.h
DetectHttpClientBodyRegisterTests
void DetectHttpClientBodyRegisterTests(void)
Definition: detect-http-client-body.c:2941
HtpBody_::sb
StreamingBuffer * sb
Definition: app-layer-htp.h:188
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:37
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:379
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:463
Flow_
Flow data structure.
Definition: flow.h:357
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2442
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:314
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:227
DE_QUIET
#define DE_QUIET
Definition: detect.h:287
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:337
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1809
DetectIsdataatData_
Definition: detect-isdataat.h:35
DetectContentData_
Definition: detect-content.h:86
DetectPcreData_::flags
uint16_t flags
Definition: detect-pcre.h:47
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2434
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:459
StreamingBufferSegmentCompareRawData
int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t *rawdata, uint32_t rawdata_len)
Definition: util-streaming-buffer.c:1554
Flow_::protoctx
void * protoctx
Definition: flow.h:447
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:97
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:588
detect-engine-prefilter.h
util-unittest.h
HTPConfigure
void HTPConfigure(void)
Definition: app-layer-htp.c:2930
HtpBody_::first
HtpBodyChunk * first
Definition: app-layer-htp.h:185
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
SignatureInitData_::smlists_tail
struct SigMatch_ ** smlists_tail
Definition: detect.h:536
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:356
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:40
app-layer-htp.h
TestSteps::expect
int expect
Definition: detect-http-client-body.c:111
util-debug.h
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:3253
DetectEngineThreadCtx_
Definition: detect.h:1025
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
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:317
DETECT_CONTENT_IS_SINGLE
#define DETECT_CONTENT_IS_SINGLE(c)
Definition: detect-content.h:66
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:491
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:78
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2129
app-layer-parser.h
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:316
Packet_
Definition: decode.h:428
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:97
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:611
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:664
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:228
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:1143
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1951
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:293
detect-engine-content-inspection.h
Packet_::flow
struct Flow_ * flow
Definition: decode.h:465
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3153
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:668
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:1323
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3367
SigMatch_::type
uint16_t type
Definition: detect.h:314
HtpBodyChunk_
Definition: app-layer-htp.h:176
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
DetectContentData_::content
uint8_t * content
Definition: detect-content.h:87
ConfRestoreContextBackup
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:676
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:791
HtpTxUserData_
Definition: app-layer-htp.h:207
util-validate.h
HtpConfigRestoreBackup
void HtpConfigRestoreBackup(void)
Definition: app-layer-htp.c:3260
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:485
Flow_::alstate
void * alstate
Definition: flow.h:482
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
Flow_::flags
uint32_t flags
Definition: flow.h:427
detect-parse.h
Signature_
Signature container.
Definition: detect.h:540
SigMatch_
a single match condition for a signature
Definition: detect.h:313
DETECT_ISDATAAT
@ DETECT_ISDATAAT
Definition: detect-engine-register.h:82
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:229
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2403
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:88
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:786
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:66
DETECT_PCRE_RELATIVE
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:29
TcpSession_
Definition: stream-tcp-private.h:272
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:456
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1136
HtpBodyChunk_::sbseg
StreamingBufferSegment sbseg
Definition: app-layer-htp.h:179
TestSteps::input_size
size_t input_size
Definition: detect-http-client-body.c:109
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:129
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1000
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:468