suricata
detect-http-client-body.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2016 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \ingroup httplayer
20  *
21  * @{
22  */
23 
24 
25 /** \file
26  *
27  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
28  * \author Victor Julien <victor@inliniac.net>
29  *
30  * \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 
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;
121  FAIL_IF_NULL(alp_tctx);
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 
137 
139  FAIL_IF_NULL(de_ctx);
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;
146  f.alproto = ALPROTO_HTTP;
147 
148  SCLogDebug("sig %s", sig);
149  Signature *s = DetectEngineAppendSig(de_ctx, (char *)sig);
150  FAIL_IF_NULL(s);
151 
152  SigGroupBuild(de_ctx);
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;
166 
167  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
168  b->direction, (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);
184  AppLayerParserThreadCtxFree(alp_tctx);
185  DetectEngineCtxFree(de_ctx);
186 
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 
833  de_ctx = DetectEngineCtxInit();
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:
854  DetectEngineCtxFree(de_ctx);
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 
868  de_ctx = DetectEngineCtxInit();
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:
880  DetectEngineCtxFree(de_ctx);
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 
894  de_ctx = DetectEngineCtxInit();
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:
906  DetectEngineCtxFree(de_ctx);
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 
920  de_ctx = DetectEngineCtxInit();
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:
932  DetectEngineCtxFree(de_ctx);
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 
946  de_ctx = DetectEngineCtxInit();
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:
958  DetectEngineCtxFree(de_ctx);
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_HTTP;
1004 
1006 
1007  de_ctx = DetectEngineCtxInit();
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 
1020  SigGroupBuild(de_ctx);
1021  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1022 
1023  FLOWLOCK_WRLOCK(&f);
1024  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1025  STREAM_TOSERVER, http_buf, http_len);
1026  if (r != 0) {
1027  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1028  result = 0;
1029  FLOWLOCK_UNLOCK(&f);
1030  goto end;
1031  }
1032  FLOWLOCK_UNLOCK(&f);
1033 
1034  http_state = f.alstate;
1035  if (http_state == NULL) {
1036  printf("no http state: \n");
1037  result = 0;
1038  goto end;
1039  }
1040 
1041  /* do detect */
1042  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1043 
1044  if (!(PacketAlertCheck(p, 1))) {
1045  printf("sid 1 didn't match but should have\n");
1046  goto end;
1047  }
1048 
1049  result = 1;
1050 end:
1051  if (alp_tctx != NULL)
1052  AppLayerParserThreadCtxFree(alp_tctx);
1053  if (de_ctx != NULL)
1054  DetectEngineCtxFree(de_ctx);
1055 
1057  FLOW_DESTROY(&f);
1058  UTHFreePackets(&p, 1);
1059  return result;
1060 }
1061 
1062 /**
1063  *\test Test that the http_client_body content matches against a http request
1064  * which holds the content.
1065  */
1066 static int DetectHttpClientBodyTest07(void)
1067 {
1068  TcpSession ssn;
1069  Packet *p1 = NULL;
1070  Packet *p2 = NULL;
1071  ThreadVars th_v;
1072  DetectEngineCtx *de_ctx = NULL;
1073  DetectEngineThreadCtx *det_ctx = NULL;
1074  HtpState *http_state = NULL;
1075  Flow f;
1076  uint8_t http1_buf[] =
1077  "GET /index.html HTTP/1.0\r\n"
1078  "Host: www.openinfosecfoundation.org\r\n"
1079  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1080  "Content-Type: text/html\r\n"
1081  "Content-Length: 54\r\n"
1082  "\r\n"
1083  "This is dummy message body1";
1084  uint8_t http2_buf[] =
1085  "This is dummy message body2";
1086  uint32_t http1_len = sizeof(http1_buf) - 1;
1087  uint32_t http2_len = sizeof(http2_buf) - 1;
1088  int result = 0;
1090 
1091  memset(&th_v, 0, sizeof(th_v));
1092  memset(&f, 0, sizeof(f));
1093  memset(&ssn, 0, sizeof(ssn));
1094 
1095  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1096  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1097 
1098  FLOW_INITIALIZE(&f);
1099  f.protoctx = (void *)&ssn;
1100  f.proto = IPPROTO_TCP;
1101  f.flags |= FLOW_IPV4;
1102 
1103  p1->flow = &f;
1107  p2->flow = &f;
1111  f.alproto = ALPROTO_HTTP;
1112 
1114 
1115  de_ctx = DetectEngineCtxInit();
1116  if (de_ctx == NULL)
1117  goto end;
1118 
1119  de_ctx->flags |= DE_QUIET;
1120 
1121  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1122  "(msg:\"http client body test\"; "
1123  "content:\"message\"; http_client_body; "
1124  "sid:1;)");
1125  if (de_ctx->sig_list == NULL)
1126  goto end;
1127 
1128  SigGroupBuild(de_ctx);
1129  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1130 
1131  FLOWLOCK_WRLOCK(&f);
1132  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1133  STREAM_TOSERVER, http1_buf, http1_len);
1134  if (r != 0) {
1135  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1136  result = 0;
1137  FLOWLOCK_UNLOCK(&f);
1138  goto end;
1139  }
1140  FLOWLOCK_UNLOCK(&f);
1141 
1142  http_state = f.alstate;
1143  if (http_state == NULL) {
1144  printf("no http state: ");
1145  goto end;
1146  }
1147 
1148  /* do detect */
1149  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1150 
1151  if (PacketAlertCheck(p1, 1)) {
1152  printf("sid 1 matched on p1 but shouldn't have: ");
1153  goto end;
1154  }
1155 
1156  FLOWLOCK_WRLOCK(&f);
1157  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1158  STREAM_TOSERVER, http2_buf, http2_len);
1159  if (r != 0) {
1160  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1161  FLOWLOCK_UNLOCK(&f);
1162  goto end;
1163  }
1164  FLOWLOCK_UNLOCK(&f);
1165 
1166  /* do detect */
1167  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1168  if (!(PacketAlertCheck(p2, 1))) {
1169  printf("sid 1 didn't match on p2 but should have: ");
1170  goto end;
1171  }
1172 
1173  result = 1;
1174 end:
1175  if (alp_tctx != NULL)
1176  AppLayerParserThreadCtxFree(alp_tctx);
1177  if (de_ctx != NULL)
1178  DetectEngineCtxFree(de_ctx);
1179 
1181  FLOW_DESTROY(&f);
1182  UTHFreePackets(&p1, 1);
1183  UTHFreePackets(&p2, 1);
1184  return result;
1185 }
1186 
1187 /**
1188  *\test Test that the http_client_body content matches against a http request
1189  * which holds the content.
1190  */
1191 static int DetectHttpClientBodyTest08(void)
1192 {
1193  TcpSession ssn;
1194  Packet *p1 = NULL;
1195  Packet *p2 = NULL;
1196  ThreadVars th_v;
1197  DetectEngineCtx *de_ctx = NULL;
1198  DetectEngineThreadCtx *det_ctx = NULL;
1199  HtpState *http_state = NULL;
1200  Flow f;
1201  uint8_t http1_buf[] =
1202  "GET /index.html HTTP/1.0\r\n"
1203  "Host: www.openinfosecfoundation.org\r\n"
1204  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1205  "Content-Type: text/html\r\n"
1206  "Content-Length: 46\r\n"
1207  "\r\n"
1208  "This is dummy body1";
1209  uint8_t http2_buf[] =
1210  "This is dummy message body2";
1211  uint32_t http1_len = sizeof(http1_buf) - 1;
1212  uint32_t http2_len = sizeof(http2_buf) - 1;
1213  int result = 0;
1215 
1216  memset(&th_v, 0, sizeof(th_v));
1217  memset(&f, 0, sizeof(f));
1218  memset(&ssn, 0, sizeof(ssn));
1219 
1220  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1221  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1222 
1223  FLOW_INITIALIZE(&f);
1224  f.protoctx = (void *)&ssn;
1225  f.proto = IPPROTO_TCP;
1226  f.flags |= FLOW_IPV4;
1227 
1228  p1->flow = &f;
1232  p2->flow = &f;
1236  f.alproto = ALPROTO_HTTP;
1237 
1239 
1240  de_ctx = DetectEngineCtxInit();
1241  if (de_ctx == NULL)
1242  goto end;
1243 
1244  de_ctx->flags |= DE_QUIET;
1245 
1246  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1247  "(msg:\"http client body test\"; "
1248  "content:\"message\"; http_client_body; "
1249  "sid:1;)");
1250  if (de_ctx->sig_list == NULL)
1251  goto end;
1252 
1253  SigGroupBuild(de_ctx);
1254  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1255 
1256  FLOWLOCK_WRLOCK(&f);
1257  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1258  STREAM_TOSERVER, http1_buf, http1_len);
1259  if (r != 0) {
1260  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1261  result = 0;
1262  FLOWLOCK_UNLOCK(&f);
1263  goto end;
1264  }
1265  FLOWLOCK_UNLOCK(&f);
1266 
1267  http_state = f.alstate;
1268  if (http_state == NULL) {
1269  printf("no http state: ");
1270  result = 0;
1271  goto end;
1272  }
1273 
1274  /* do detect */
1275  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1276 
1277  if ((PacketAlertCheck(p1, 1))) {
1278  printf("sid 1 didn't match but should have");
1279  goto end;
1280  }
1281 
1282  FLOWLOCK_WRLOCK(&f);
1283  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1284  STREAM_TOSERVER, http2_buf, http2_len);
1285  if (r != 0) {
1286  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1287  result = 0;
1288  FLOWLOCK_UNLOCK(&f);
1289  goto end;
1290  }
1291  FLOWLOCK_UNLOCK(&f);
1292 
1293  /* do detect */
1294  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1295 
1296  if (!(PacketAlertCheck(p2, 1))) {
1297  printf("sid 1 didn't match but should have");
1298  goto end;
1299  }
1300 
1301  result = 1;
1302 end:
1303  if (alp_tctx != NULL)
1304  AppLayerParserThreadCtxFree(alp_tctx);
1305  if (de_ctx != NULL)
1306  DetectEngineCtxFree(de_ctx);
1307 
1309  FLOW_DESTROY(&f);
1310  UTHFreePackets(&p1, 1);
1311  UTHFreePackets(&p2, 1);
1312  return result;
1313 }
1314 
1315 /**
1316  *\test Test that the http_client_body content matches against a http request
1317  * which holds the content, against a cross boundary present pattern.
1318  */
1319 static int DetectHttpClientBodyTest09(void)
1320 {
1321  TcpSession ssn;
1322  Packet *p1 = NULL;
1323  Packet *p2 = NULL;
1324  ThreadVars th_v;
1325  DetectEngineCtx *de_ctx = NULL;
1326  DetectEngineThreadCtx *det_ctx = NULL;
1327  HtpState *http_state = NULL;
1328  Flow f;
1329  uint8_t http1_buf[] =
1330  "GET /index.html HTTP/1.0\r\n"
1331  "Host: www.openinfosecfoundation.org\r\n"
1332  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1333  "Content-Type: text/html\r\n"
1334  "Content-Length: 46\r\n"
1335  "\r\n"
1336  "This is dummy body1";
1337  uint8_t http2_buf[] =
1338  "This is dummy message body2";
1339  uint32_t http1_len = sizeof(http1_buf) - 1;
1340  uint32_t http2_len = sizeof(http2_buf) - 1;
1341  int result = 0;
1343 
1344  memset(&th_v, 0, sizeof(th_v));
1345  memset(&f, 0, sizeof(f));
1346  memset(&ssn, 0, sizeof(ssn));
1347 
1348  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1349  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1350 
1351  FLOW_INITIALIZE(&f);
1352  f.protoctx = (void *)&ssn;
1353  f.proto = IPPROTO_TCP;
1354  f.flags |= FLOW_IPV4;
1355 
1356  p1->flow = &f;
1360  p2->flow = &f;
1364  f.alproto = ALPROTO_HTTP;
1365 
1367 
1368  de_ctx = DetectEngineCtxInit();
1369  if (de_ctx == NULL)
1370  goto end;
1371 
1372  de_ctx->flags |= DE_QUIET;
1373 
1374  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1375  "(msg:\"http client body test\"; "
1376  "content:\"body1This\"; http_client_body; "
1377  "sid:1;)");
1378  if (de_ctx->sig_list == NULL)
1379  goto end;
1380 
1381  SigGroupBuild(de_ctx);
1382  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1383 
1384  FLOWLOCK_WRLOCK(&f);
1385  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1386  STREAM_TOSERVER, http1_buf, http1_len);
1387  if (r != 0) {
1388  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1389  result = 0;
1390  FLOWLOCK_UNLOCK(&f);
1391  goto end;
1392  }
1393  FLOWLOCK_UNLOCK(&f);
1394 
1395  http_state = f.alstate;
1396  if (http_state == NULL) {
1397  printf("no http state: ");
1398  result = 0;
1399  goto end;
1400  }
1401 
1402  /* do detect */
1403  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1404 
1405  if ((PacketAlertCheck(p1, 1))) {
1406  printf("sid 1 didn't match but should have");
1407  goto end;
1408  }
1409 
1410  FLOWLOCK_WRLOCK(&f);
1411  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1412  STREAM_TOSERVER, http2_buf, http2_len);
1413  if (r != 0) {
1414  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1415  result = 0;
1416  FLOWLOCK_UNLOCK(&f);
1417  goto end;
1418  }
1419  FLOWLOCK_UNLOCK(&f);
1420 
1421  /* do detect */
1422  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1423 
1424  if (!(PacketAlertCheck(p2, 1))) {
1425  printf("sid 1 didn't match but should have");
1426  goto end;
1427  }
1428 
1429  result = 1;
1430 end:
1431  if (alp_tctx != NULL)
1432  AppLayerParserThreadCtxFree(alp_tctx);
1433  if (de_ctx != NULL)
1434  DetectEngineCtxFree(de_ctx);
1435 
1437  FLOW_DESTROY(&f);
1438  UTHFreePackets(&p1, 1);
1439  UTHFreePackets(&p2, 1);
1440  return result;
1441 }
1442 
1443 /**
1444  *\test Test that the http_client_body content matches against a http request
1445  * against a case insensitive pattern.
1446  */
1447 static int DetectHttpClientBodyTest10(void)
1448 {
1449  TcpSession ssn;
1450  Packet *p1 = NULL;
1451  Packet *p2 = NULL;
1452  ThreadVars th_v;
1453  DetectEngineCtx *de_ctx = NULL;
1454  DetectEngineThreadCtx *det_ctx = NULL;
1455  HtpState *http_state = NULL;
1456  Flow f;
1457  uint8_t http1_buf[] =
1458  "GET /index.html HTTP/1.0\r\n"
1459  "Host: www.openinfosecfoundation.org\r\n"
1460  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1461  "Content-Type: text/html\r\n"
1462  "Content-Length: 46\r\n"
1463  "\r\n"
1464  "This is dummy bodY1";
1465  uint8_t http2_buf[] =
1466  "This is dummy message body2";
1467  uint32_t http1_len = sizeof(http1_buf) - 1;
1468  uint32_t http2_len = sizeof(http2_buf) - 1;
1469  int result = 0;
1471 
1472  memset(&th_v, 0, sizeof(th_v));
1473  memset(&f, 0, sizeof(f));
1474  memset(&ssn, 0, sizeof(ssn));
1475 
1476  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1477  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1478 
1479  FLOW_INITIALIZE(&f);
1480  f.protoctx = (void *)&ssn;
1481  f.proto = IPPROTO_TCP;
1482  f.flags |= FLOW_IPV4;
1483 
1484  p1->flow = &f;
1488  p2->flow = &f;
1492  f.alproto = ALPROTO_HTTP;
1493 
1495 
1496  de_ctx = DetectEngineCtxInit();
1497  if (de_ctx == NULL)
1498  goto end;
1499 
1500  de_ctx->flags |= DE_QUIET;
1501 
1502  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1503  "(msg:\"http client body test\"; "
1504  "content:\"body1This\"; http_client_body; nocase;"
1505  "sid:1;)");
1506  if (de_ctx->sig_list == NULL)
1507  goto end;
1508 
1509  SigGroupBuild(de_ctx);
1510  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1511 
1512  FLOWLOCK_WRLOCK(&f);
1513  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1514  STREAM_TOSERVER, http1_buf, http1_len);
1515  if (r != 0) {
1516  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1517  result = 0;
1518  FLOWLOCK_UNLOCK(&f);
1519  goto end;
1520  }
1521  FLOWLOCK_UNLOCK(&f);
1522 
1523  http_state = f.alstate;
1524  if (http_state == NULL) {
1525  printf("no http state: \n");
1526  result = 0;
1527  goto end;
1528  }
1529 
1530  /* do detect */
1531  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1532 
1533  if ((PacketAlertCheck(p1, 1))) {
1534  printf("sid 1 didn't match but should have\n");
1535  goto end;
1536  }
1537 
1538  FLOWLOCK_WRLOCK(&f);
1539  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1540  STREAM_TOSERVER, http2_buf, http2_len);
1541  if (r != 0) {
1542  printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
1543  result = 0;
1544  FLOWLOCK_UNLOCK(&f);
1545  goto end;
1546  }
1547  FLOWLOCK_UNLOCK(&f);
1548 
1549  /* do detect */
1550  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1551 
1552  if (!(PacketAlertCheck(p2, 1))) {
1553  printf("sid 1 didn't match but should have");
1554  goto end;
1555  }
1556 
1557  result = 1;
1558 end:
1559  if (alp_tctx != NULL)
1560  AppLayerParserThreadCtxFree(alp_tctx);
1561  if (de_ctx != NULL)
1562  DetectEngineCtxFree(de_ctx);
1563 
1565  FLOW_DESTROY(&f);
1566  UTHFreePackets(&p1, 1);
1567  UTHFreePackets(&p2, 1);
1568  return result;
1569 }
1570 
1571 /**
1572  *\test Test that the negated http_client_body content matches against a
1573  * http request which doesn't hold the content.
1574  */
1575 static int DetectHttpClientBodyTest11(void)
1576 {
1577  TcpSession ssn;
1578  Packet *p = NULL;
1579  ThreadVars th_v;
1580  DetectEngineCtx *de_ctx = NULL;
1581  DetectEngineThreadCtx *det_ctx = NULL;
1582  HtpState *http_state = NULL;
1583  Flow f;
1584  uint8_t http_buf[] =
1585  "GET /index.html HTTP/1.0\r\n"
1586  "Host: www.openinfosecfoundation.org\r\n"
1587  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1588  "Content-Type: text/html\r\n"
1589  "Content-Length: 26\r\n"
1590  "\r\n"
1591  "This is dummy message body";
1592  uint32_t http_len = sizeof(http_buf) - 1;
1593  int result = 0;
1595 
1596  memset(&th_v, 0, sizeof(th_v));
1597  memset(&f, 0, sizeof(f));
1598  memset(&ssn, 0, sizeof(ssn));
1599 
1600  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1601 
1602  FLOW_INITIALIZE(&f);
1603  f.protoctx = (void *)&ssn;
1604  f.proto = IPPROTO_TCP;
1605  f.flags |= FLOW_IPV4;
1606 
1607  p->flow = &f;
1611  f.alproto = ALPROTO_HTTP;
1612 
1614 
1615  de_ctx = DetectEngineCtxInit();
1616  if (de_ctx == NULL)
1617  goto end;
1618 
1619  de_ctx->flags |= DE_QUIET;
1620 
1621  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1622  "(msg:\"http client body test\"; "
1623  "content:!\"message1\"; http_client_body; "
1624  "sid:1;)");
1625  if (de_ctx->sig_list == NULL)
1626  goto end;
1627 
1628  SigGroupBuild(de_ctx);
1629  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1630 
1631  FLOWLOCK_WRLOCK(&f);
1632  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1633  STREAM_TOSERVER, http_buf, http_len);
1634  if (r != 0) {
1635  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1636  result = 0;
1637  FLOWLOCK_UNLOCK(&f);
1638  goto end;
1639  }
1640  FLOWLOCK_UNLOCK(&f);
1641 
1642  http_state = f.alstate;
1643  if (http_state == NULL) {
1644  printf("no http state: ");
1645  result = 0;
1646  goto end;
1647  }
1648 
1649  /* do detect */
1650  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1651 
1652  if (!(PacketAlertCheck(p, 1))) {
1653  printf("sid 1 didn't match but should have");
1654  goto end;
1655  }
1656 
1657  result = 1;
1658 end:
1659  if (alp_tctx != NULL)
1660  AppLayerParserThreadCtxFree(alp_tctx);
1661  if (de_ctx != NULL)
1662  DetectEngineCtxFree(de_ctx);
1663 
1665  FLOW_DESTROY(&f);
1666  UTHFreePackets(&p, 1);
1667  return result;
1668 }
1669 
1670 /**
1671  *\test Negative test that the negated http_client_body content matches against a
1672  * http request which holds hold the content.
1673  */
1674 static int DetectHttpClientBodyTest12(void)
1675 {
1676  TcpSession ssn;
1677  Packet *p = NULL;
1678  ThreadVars th_v;
1679  DetectEngineCtx *de_ctx = NULL;
1680  DetectEngineThreadCtx *det_ctx = NULL;
1681  HtpState *http_state = NULL;
1682  Flow f;
1683  uint8_t http_buf[] =
1684  "GET /index.html HTTP/1.0\r\n"
1685  "Host: www.openinfosecfoundation.org\r\n"
1686  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1687  "Content-Type: text/html\r\n"
1688  "Content-Length: 26\r\n"
1689  "\r\n"
1690  "This is dummy message body";
1691  uint32_t http_len = sizeof(http_buf) - 1;
1692  int result = 0;
1694 
1695  memset(&th_v, 0, sizeof(th_v));
1696  memset(&f, 0, sizeof(f));
1697  memset(&ssn, 0, sizeof(ssn));
1698 
1699  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1700 
1701  FLOW_INITIALIZE(&f);
1702  f.protoctx = (void *)&ssn;
1703  f.proto = IPPROTO_TCP;
1704  f.flags |= FLOW_IPV4;
1705 
1706  p->flow = &f;
1710  f.alproto = ALPROTO_HTTP;
1711 
1713 
1714  de_ctx = DetectEngineCtxInit();
1715  if (de_ctx == NULL)
1716  goto end;
1717 
1718  de_ctx->flags |= DE_QUIET;
1719 
1720  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1721  "(msg:\"http client body test\"; "
1722  "content:!\"message\"; http_client_body; "
1723  "sid:1;)");
1724  if (de_ctx->sig_list == NULL)
1725  goto end;
1726 
1727  SigGroupBuild(de_ctx);
1728  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1729 
1730  FLOWLOCK_WRLOCK(&f);
1731  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1732  STREAM_TOSERVER, http_buf, http_len);
1733  if (r != 0) {
1734  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1735  result = 0;
1736  FLOWLOCK_UNLOCK(&f);
1737  goto end;
1738  }
1739  FLOWLOCK_UNLOCK(&f);
1740 
1741  http_state = f.alstate;
1742  if (http_state == NULL) {
1743  printf("no http state: ");
1744  result = 0;
1745  goto end;
1746  }
1747 
1748  /* do detect */
1749  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1750 
1751  if ((PacketAlertCheck(p, 1))) {
1752  printf("sid 1 didn't match but should have");
1753  goto end;
1754  }
1755 
1756  result = 1;
1757 end:
1758  if (alp_tctx != NULL)
1759  AppLayerParserThreadCtxFree(alp_tctx);
1760  if (de_ctx != NULL)
1761  DetectEngineCtxFree(de_ctx);
1762 
1764  FLOW_DESTROY(&f);
1765  UTHFreePackets(&p, 1);
1766  return result;
1767 }
1768 
1769 /**
1770  *\test Test that the http_client_body content matches against a http request
1771  * which holds the content.
1772  */
1773 static int DetectHttpClientBodyTest13(void)
1774 {
1775  TcpSession ssn;
1776  Packet *p = NULL;
1777  ThreadVars th_v;
1778  DetectEngineCtx *de_ctx = NULL;
1779  DetectEngineThreadCtx *det_ctx = NULL;
1780  HtpState *http_state = NULL;
1781  Flow f;
1782  uint8_t http_buf[] =
1783  "GET /index.html HTTP/1.0\r\n"
1784  "Host: www.openinfosecfoundation.org\r\n"
1785  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
1786  "Content-Type: text/html\r\n"
1787  "Content-Length: 55\r\n"
1788  "\r\n"
1789  "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend";
1790  uint32_t http_len = sizeof(http_buf) - 1;
1791  int result = 0;
1793 
1794  memset(&th_v, 0, sizeof(th_v));
1795  memset(&f, 0, sizeof(f));
1796  memset(&ssn, 0, sizeof(ssn));
1797 
1798  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1799 
1800  FLOW_INITIALIZE(&f);
1801  f.protoctx = (void *)&ssn;
1802  f.proto = IPPROTO_TCP;
1803  f.flags |= FLOW_IPV4;
1804 
1805  p->flow = &f;
1809  f.alproto = ALPROTO_HTTP;
1810 
1812 
1813  de_ctx = DetectEngineCtxInit();
1814  if (de_ctx == NULL)
1815  goto end;
1816 
1817  de_ctx->flags |= DE_QUIET;
1818 
1819  de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1820  "(msg:\"http client body test\"; "
1821  "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_client_body; "
1822  "sid:1;)");
1823  if (de_ctx->sig_list == NULL)
1824  goto end;
1825 
1826  SigGroupBuild(de_ctx);
1827  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1828 
1829  FLOWLOCK_WRLOCK(&f);
1830  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1831  STREAM_TOSERVER, http_buf, http_len);
1832  if (r != 0) {
1833  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1834  result = 0;
1835  FLOWLOCK_UNLOCK(&f);
1836  goto end;
1837  }
1838  FLOWLOCK_UNLOCK(&f);
1839 
1840  http_state = f.alstate;
1841  if (http_state == NULL) {
1842  printf("no http state: ");
1843  result = 0;
1844  goto end;
1845  }
1846 
1847  /* do detect */
1848  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1849 
1850  if (!(PacketAlertCheck(p, 1))) {
1851  printf("sid 1 didn't match but should have");
1852  goto end;
1853  }
1854 
1855  result = 1;
1856 end:
1857  if (alp_tctx != NULL)
1858  AppLayerParserThreadCtxFree(alp_tctx);
1859  if (de_ctx != NULL)
1860  DetectEngineCtxFree(de_ctx);
1861 
1863  FLOW_DESTROY(&f);
1864  UTHFreePackets(&p, 1);
1865  return result;
1866 }
1867 
1868 /** \test multiple http transactions and body chunks of request handling */
1869 static int DetectHttpClientBodyTest14(void)
1870 {
1871  int result = 0;
1872  Signature *s = NULL;
1873  DetectEngineThreadCtx *det_ctx = NULL;
1874  ThreadVars th_v;
1875  Flow f;
1876  TcpSession ssn;
1877  Packet *p = NULL;
1878  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
1879  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
1880  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
1881  uint8_t httpbuf4[] = "Body one!!";
1882  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1883  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1884  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1885  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1886  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
1887  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
1888  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
1889  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
1890  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
1891  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
1893 
1894  memset(&th_v, 0, sizeof(th_v));
1895  memset(&f, 0, sizeof(f));
1896  memset(&ssn, 0, sizeof(ssn));
1897 
1898  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1899 
1900  FLOW_INITIALIZE(&f);
1901  f.protoctx = (void *)&ssn;
1902  f.proto = IPPROTO_TCP;
1903  f.flags |= FLOW_IPV4;
1904 
1905  p->flow = &f;
1909  f.alproto = ALPROTO_HTTP;
1910 
1912 
1914  if (de_ctx == NULL) {
1915  goto end;
1916  }
1917 
1918  de_ctx->flags |= DE_QUIET;
1919 
1920  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;)");
1921  if (s == NULL) {
1922  printf("sig parse failed: ");
1923  goto end;
1924  }
1925  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;)");
1926  if (s == NULL) {
1927  printf("sig2 parse failed: ");
1928  goto end;
1929  }
1930 
1931  SigGroupBuild(de_ctx);
1932  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1933 
1934  FLOWLOCK_WRLOCK(&f);
1935  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1936  STREAM_TOSERVER, httpbuf1, httplen1);
1937  if (r != 0) {
1938  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1939  FLOWLOCK_UNLOCK(&f);
1940  goto end;
1941  }
1942  FLOWLOCK_UNLOCK(&f);
1943 
1944  /* do detect */
1945  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1946  if (PacketAlertCheck(p, 1)) {
1947  printf("sig 1 alerted: ");
1948  goto end;
1949  }
1950  p->alerts.cnt = 0;
1951 
1952  FLOWLOCK_WRLOCK(&f);
1953  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1954  STREAM_TOSERVER, httpbuf2, httplen2);
1955  if (r != 0) {
1956  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
1957  FLOWLOCK_UNLOCK(&f);
1958  goto end;
1959  }
1960  FLOWLOCK_UNLOCK(&f);
1961 
1962  /* do detect */
1963  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1964  if (PacketAlertCheck(p, 1)) {
1965  printf("sig 1 alerted (2): ");
1966  FLOWLOCK_UNLOCK(&f);
1967  goto end;
1968  }
1969  p->alerts.cnt = 0;
1970 
1971  FLOWLOCK_WRLOCK(&f);
1972  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1973  STREAM_TOSERVER, httpbuf3, httplen3);
1974  if (r != 0) {
1975  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
1976  FLOWLOCK_UNLOCK(&f);
1977  goto end;
1978  }
1979  FLOWLOCK_UNLOCK(&f);
1980 
1981  /* do detect */
1982  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1983  if (PacketAlertCheck(p, 1)) {
1984  printf("signature matched, but shouldn't have: ");
1985  goto end;
1986  }
1987  p->alerts.cnt = 0;
1988 
1989  FLOWLOCK_WRLOCK(&f);
1990  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1991  STREAM_TOSERVER, httpbuf4, httplen4);
1992  if (r != 0) {
1993  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
1994  result = 0;
1995  FLOWLOCK_UNLOCK(&f);
1996  goto end;
1997  }
1998  FLOWLOCK_UNLOCK(&f);
1999 
2000  /* do detect */
2001  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2002  if (!(PacketAlertCheck(p, 1))) {
2003  printf("sig 1 didn't alert: ");
2004  goto end;
2005  }
2006  p->alerts.cnt = 0;
2007 
2008  FLOWLOCK_WRLOCK(&f);
2009  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2010  STREAM_TOSERVER, httpbuf5, httplen5);
2011  if (r != 0) {
2012  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2013  FLOWLOCK_UNLOCK(&f);
2014  goto end;
2015  }
2016  FLOWLOCK_UNLOCK(&f);
2017 
2018  /* do detect */
2019  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2020  if (PacketAlertCheck(p, 1)) {
2021  printf("sig 1 alerted (5): ");
2022  goto end;
2023  }
2024  p->alerts.cnt = 0;
2025 
2026  FLOWLOCK_WRLOCK(&f);
2027  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2028  STREAM_TOSERVER, httpbuf6, httplen6);
2029  if (r != 0) {
2030  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2031  FLOWLOCK_UNLOCK(&f);
2032  goto end;
2033  }
2034  FLOWLOCK_UNLOCK(&f);
2035 
2036  /* do detect */
2037  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2038  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2039  printf("sig 1 alerted (request 2, chunk 6): ");
2040  goto end;
2041  }
2042  p->alerts.cnt = 0;
2043 
2044  SCLogDebug("sending data chunk 7");
2045 
2046  FLOWLOCK_WRLOCK(&f);
2047  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2048  STREAM_TOSERVER, httpbuf7, httplen7);
2049  if (r != 0) {
2050  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2051  FLOWLOCK_UNLOCK(&f);
2052  goto end;
2053  }
2054  FLOWLOCK_UNLOCK(&f);
2055 
2056  /* do detect */
2057  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2058  if (!(PacketAlertCheck(p, 2))) {
2059  printf("signature 2 didn't match, but should have: ");
2060  goto end;
2061  }
2062  p->alerts.cnt = 0;
2063 
2064  HtpState *htp_state = f.alstate;
2065  if (htp_state == NULL) {
2066  printf("no http state: ");
2067  result = 0;
2068  goto end;
2069  }
2070 
2071  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2072  printf("The http app layer doesn't have 2 transactions, but it should: ");
2073  goto end;
2074  }
2075 
2076  result = 1;
2077 end:
2078  if (alp_tctx != NULL)
2079  AppLayerParserThreadCtxFree(alp_tctx);
2080  if (det_ctx != NULL) {
2081  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2082  }
2083  if (de_ctx != NULL) {
2084  DetectEngineCtxFree(de_ctx);
2085  }
2086 
2088  FLOW_DESTROY(&f);
2089  UTHFreePacket(p);
2090  return result;
2091 }
2092 
2093 /** \test multiple http transactions and body chunks of request handling */
2094 static int DetectHttpClientBodyTest15(void)
2095 {
2096  int result = 0;
2097  Signature *s = NULL;
2098  DetectEngineThreadCtx *det_ctx = NULL;
2099  ThreadVars th_v;
2100  Flow f;
2101  TcpSession ssn;
2102  Packet *p = NULL;
2103  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
2104  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2105  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
2106  uint8_t httpbuf4[] = "Body one!!";
2107  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2108  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2109  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2110  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2111  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
2112  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
2113  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2114  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2115  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2116  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
2118 
2119  memset(&th_v, 0, sizeof(th_v));
2120  memset(&f, 0, sizeof(f));
2121  memset(&ssn, 0, sizeof(ssn));
2122 
2123  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2124 
2125  FLOW_INITIALIZE(&f);
2126  f.protoctx = (void *)&ssn;
2127  f.proto = IPPROTO_TCP;
2128  f.flags |= FLOW_IPV4;
2129 
2130  p->flow = &f;
2134  f.alproto = ALPROTO_HTTP;
2135 
2137 
2139  if (de_ctx == NULL) {
2140  goto end;
2141  }
2142 
2143  de_ctx->flags |= DE_QUIET;
2144 
2145  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;)");
2146  if (s == NULL) {
2147  printf("sig parse failed: ");
2148  goto end;
2149  }
2150  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;)");
2151  if (s == NULL) {
2152  printf("sig2 parse failed: ");
2153  goto end;
2154  }
2155 
2156  SigGroupBuild(de_ctx);
2157  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2158 
2159  FLOWLOCK_WRLOCK(&f);
2160  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2161  STREAM_TOSERVER, httpbuf1, httplen1);
2162  if (r != 0) {
2163  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2164  FLOWLOCK_UNLOCK(&f);
2165  goto end;
2166  }
2167  FLOWLOCK_UNLOCK(&f);
2168 
2169  /* do detect */
2170  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2171  if (PacketAlertCheck(p, 1)) {
2172  printf("sig 1 alerted: ");
2173  goto end;
2174  }
2175  p->alerts.cnt = 0;
2176 
2177  FLOWLOCK_WRLOCK(&f);
2178  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2179  STREAM_TOSERVER, httpbuf2, httplen2);
2180  if (r != 0) {
2181  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
2182  FLOWLOCK_UNLOCK(&f);
2183  goto end;
2184  }
2185  FLOWLOCK_UNLOCK(&f);
2186 
2187  /* do detect */
2188  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2189  if (PacketAlertCheck(p, 1)) {
2190  printf("sig 1 alerted (2): ");
2191  goto end;
2192  }
2193  p->alerts.cnt = 0;
2194 
2195  FLOWLOCK_WRLOCK(&f);
2196  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2197  STREAM_TOSERVER, httpbuf3, httplen3);
2198  if (r != 0) {
2199  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
2200  FLOWLOCK_UNLOCK(&f);
2201  goto end;
2202  }
2203  FLOWLOCK_UNLOCK(&f);
2204 
2205  /* do detect */
2206  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2207  if (PacketAlertCheck(p, 1)) {
2208  printf("signature matched, but shouldn't have: ");
2209  goto end;
2210  }
2211  p->alerts.cnt = 0;
2212 
2213  FLOWLOCK_WRLOCK(&f);
2214  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2215  STREAM_TOSERVER, httpbuf4, httplen4);
2216  if (r != 0) {
2217  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
2218  result = 0;
2219  FLOWLOCK_UNLOCK(&f);
2220  goto end;
2221  }
2222  FLOWLOCK_UNLOCK(&f);
2223 
2224  /* do detect */
2225  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2226  if (!(PacketAlertCheck(p, 1))) {
2227  printf("sig 1 didn't alert: ");
2228  goto end;
2229  }
2230  p->alerts.cnt = 0;
2231 
2232  FLOWLOCK_WRLOCK(&f);
2233  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2234  STREAM_TOSERVER, httpbuf5, httplen5);
2235  if (r != 0) {
2236  printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r);
2237  FLOWLOCK_UNLOCK(&f);
2238  goto end;
2239  }
2240  FLOWLOCK_UNLOCK(&f);
2241 
2242  /* do detect */
2243  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2244  if (PacketAlertCheck(p, 1)) {
2245  printf("sig 1 alerted (5): ");
2246  goto end;
2247  }
2248  p->alerts.cnt = 0;
2249 
2250  FLOWLOCK_WRLOCK(&f);
2251  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2252  STREAM_TOSERVER, httpbuf6, httplen6);
2253  if (r != 0) {
2254  printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r);
2255  FLOWLOCK_UNLOCK(&f);
2256  goto end;
2257  }
2258  FLOWLOCK_UNLOCK(&f);
2259 
2260  /* do detect */
2261  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2262  if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) {
2263  printf("sig 1 alerted (request 2, chunk 6): ");
2264  goto end;
2265  }
2266  p->alerts.cnt = 0;
2267 
2268  SCLogDebug("sending data chunk 7");
2269 
2270  FLOWLOCK_WRLOCK(&f);
2271  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2272  STREAM_TOSERVER, httpbuf7, httplen7);
2273  if (r != 0) {
2274  printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r);
2275  FLOWLOCK_UNLOCK(&f);
2276  goto end;
2277  }
2278  FLOWLOCK_UNLOCK(&f);
2279 
2280  /* do detect */
2281  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2282  if (!(PacketAlertCheck(p, 2))) {
2283  printf("signature 2 didn't match, but should have: ");
2284  goto end;
2285  }
2286  p->alerts.cnt = 0;
2287 
2288  HtpState *htp_state = f.alstate;
2289  if (htp_state == NULL) {
2290  printf("no http state: ");
2291  result = 0;
2292  goto end;
2293  }
2294 
2295  /* hardcoded check of the transactions and it's client body chunks */
2296  if (AppLayerParserGetTxCnt(&f, htp_state) != 2) {
2297  printf("The http app layer doesn't have 2 transactions, but it should: ");
2298  goto end;
2299  }
2300 
2301  htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0);
2302  htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1);
2303 
2304  HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2305 
2306  HtpBodyChunk *cur = htud->request_body.first;
2307  if (htud->request_body.first == NULL) {
2308  SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2309  goto end;
2310  }
2311 
2313  (uint8_t *)"Body one!!", 10) != 1)
2314  {
2315  SCLogDebug("Body data in t1 is not correctly set: ");
2316  goto end;
2317  }
2318 
2319  htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2320 
2321  cur = htud->request_body.first;
2322  if (htud->request_body.first == NULL) {
2323  SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): ");
2324  goto end;
2325  }
2326 
2328  (uint8_t *)"Body two!!", 10) != 1)
2329  {
2330  SCLogDebug("Body data in t1 is not correctly set: ");
2331  goto end;
2332  }
2333 
2334  result = 1;
2335 end:
2336  if (alp_tctx != NULL)
2337  AppLayerParserThreadCtxFree(alp_tctx);
2338  if (det_ctx != NULL) {
2339  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2340  }
2341  if (de_ctx != NULL) {
2342  DetectEngineCtxFree(de_ctx);
2343  }
2344 
2346  FLOW_DESTROY(&f);
2347  UTHFreePacket(p);
2348  return result;
2349 }
2350 
2351 static int DetectHttpClientBodyTest22(void)
2352 {
2353  DetectEngineCtx *de_ctx = NULL;
2354  int result = 0;
2355 
2356  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2357  goto end;
2358 
2359  de_ctx->flags |= DE_QUIET;
2360  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2361  "(content:\"one\"; content:\"two\"; http_client_body; "
2362  "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2363  if (de_ctx->sig_list == NULL) {
2364  printf("de_ctx->sig_list == NULL\n");
2365  goto end;
2366  }
2367 
2368  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2369  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2370  goto end;
2371  }
2372 
2373  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2374  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2375  goto end;
2376  }
2377 
2378  DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2379  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2380  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2381  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2382  if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 ||
2383  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2384  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2385  memcmp(hcbd1->content, "two", hcbd1->content_len) != 0 ||
2386  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2387  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2388  goto end;
2389  }
2390 
2391  if (!DETECT_CONTENT_IS_SINGLE(cd1) ||
2392  !DETECT_CONTENT_IS_SINGLE(cd2) ||
2393  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2394  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2395  goto end;
2396  }
2397 
2398  result = 1;
2399 
2400  end:
2401  DetectEngineCtxFree(de_ctx);
2402  return result;
2403 }
2404 
2405 static int DetectHttpClientBodyTest23(void)
2406 {
2407  DetectEngineCtx *de_ctx = NULL;
2408  int result = 0;
2409 
2410  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2411  goto end;
2412 
2413  de_ctx->flags |= DE_QUIET;
2414  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2415  "(content:\"one\"; http_client_body; pcre:/two/; "
2416  "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)");
2417  if (de_ctx->sig_list == NULL) {
2418  printf("de_ctx->sig_list == NULL\n");
2419  goto end;
2420  }
2421 
2422  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2423  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2424  goto end;
2425  }
2426 
2427  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2428  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2429  goto end;
2430  }
2431 
2432  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2433  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2434  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2435  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2436  if (pd1->flags != 0 ||
2437  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2438  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2439  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2440  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2441  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2442  goto end;
2443  }
2444 
2445  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
2446  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2447  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2448  goto end;
2449  }
2450 
2451  result = 1;
2452 
2453  end:
2454  DetectEngineCtxFree(de_ctx);
2455  return result;
2456 }
2457 
2458 static int DetectHttpClientBodyTest24(void)
2459 {
2460  DetectEngineCtx *de_ctx = NULL;
2461  int result = 0;
2462 
2463  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2464  goto end;
2465 
2466  de_ctx->flags |= DE_QUIET;
2467  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2468  "(content:\"one\"; http_client_body; pcre:/two/; "
2469  "content:\"three\"; distance:10; within:15; http_client_body; content:\"four\"; sid:1;)");
2470  if (de_ctx->sig_list == NULL) {
2471  printf("de_ctx->sig_list == NULL\n");
2472  goto end;
2473  }
2474 
2475  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2476  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2477  goto end;
2478  }
2479 
2480  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2481  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2482  goto end;
2483  }
2484 
2485  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2486  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2487  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2488  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2489  if (pd1->flags != 0 ||
2490  cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2491  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2492  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2493  hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
2494  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2495  goto end;
2496  }
2497 
2498  if (!DETECT_CONTENT_IS_SINGLE(cd2) ||
2499  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2500  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2501  goto end;
2502  }
2503 
2504  result = 1;
2505 
2506  end:
2507  DetectEngineCtxFree(de_ctx);
2508  return result;
2509 }
2510 
2511 static int DetectHttpClientBodyTest25(void)
2512 {
2513  DetectEngineCtx *de_ctx = NULL;
2514  int result = 0;
2515 
2516  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2517  goto end;
2518 
2519  de_ctx->flags |= DE_QUIET;
2520  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2521  "(content:\"one\"; http_client_body; pcre:/two/; "
2522  "content:\"three\"; distance:10; http_client_body; "
2523  "content:\"four\"; distance:10; sid:1;)");
2524  if (de_ctx->sig_list == NULL) {
2525  printf("de_ctx->sig_list == NULL\n");
2526  goto end;
2527  }
2528 
2529  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2530  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2531  goto end;
2532  }
2533 
2534  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2535  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2536  goto end;
2537  }
2538 
2539  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2540  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2541  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2542  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2543  if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT ||
2544  cd2->flags != DETECT_CONTENT_DISTANCE ||
2545  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2546  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2547  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2548  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2549  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2550  goto end;
2551  }
2552 
2553  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2554  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2555  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2556  goto end;
2557  }
2558 
2559  result = 1;
2560 
2561  end:
2562  DetectEngineCtxFree(de_ctx);
2563  return result;
2564 }
2565 
2566 static int DetectHttpClientBodyTest26(void)
2567 {
2568  DetectEngineCtx *de_ctx = NULL;
2569  int result = 0;
2570 
2571  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2572  goto end;
2573 
2574  de_ctx->flags |= DE_QUIET;
2575  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2576  "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2577  "content:\"three\"; distance:10; http_client_body; within:10; "
2578  "content:\"four\"; distance:10; sid:1;)");
2579  if (de_ctx->sig_list == NULL) {
2580  printf("de_ctx->sig_list == NULL\n");
2581  goto end;
2582  }
2583 
2584  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2585  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2586  goto end;
2587  }
2588 
2589  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2590  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2591  goto end;
2592  }
2593 
2594  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2595  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2596  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2597  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2598  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2599  cd2->flags != DETECT_CONTENT_DISTANCE ||
2600  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2602  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2603  hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) ||
2604  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2605  printf ("failed: http_client_body incorrect flags");
2606  goto end;
2607  }
2608 
2609  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2610  DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2611  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2612  goto end;
2613  }
2614 
2615  result = 1;
2616 
2617  end:
2618  DetectEngineCtxFree(de_ctx);
2619  return result;
2620 }
2621 
2622 static int DetectHttpClientBodyTest27(void)
2623 {
2624  DetectEngineCtx *de_ctx = NULL;
2625  int result = 0;
2626 
2627  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2628  goto end;
2629 
2630  de_ctx->flags |= DE_QUIET;
2631  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2632  "(content:\"one\"; offset:10; http_client_body; pcre:/two/; "
2633  "content:\"three\"; distance:10; http_client_body; within:10; "
2634  "content:\"four\"; distance:10; sid:1;)");
2635  if (de_ctx->sig_list == NULL) {
2636  printf("de_ctx->sig_list == NULL\n");
2637  goto end;
2638  }
2639 
2640  result = 1;
2641 
2642  end:
2643  DetectEngineCtxFree(de_ctx);
2644  return result;
2645 }
2646 
2647 static int DetectHttpClientBodyTest28(void)
2648 {
2649  DetectEngineCtx *de_ctx = NULL;
2650  int result = 0;
2651 
2652  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2653  goto end;
2654 
2655  de_ctx->flags |= DE_QUIET;
2656  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2657  "(content:\"one\"; http_client_body; pcre:/two/; "
2658  "content:\"three\"; http_client_body; depth:10; "
2659  "content:\"four\"; distance:10; sid:1;)");
2660  if (de_ctx->sig_list == NULL) {
2661  printf("de_ctx->sig_list == NULL\n");
2662  goto end;
2663  }
2664 
2665  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
2666  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
2667  goto end;
2668  }
2669 
2670  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2671  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2672  goto end;
2673  }
2674 
2675  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx;
2676  DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
2677  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2678  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2679  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2680  cd2->flags != DETECT_CONTENT_DISTANCE ||
2681  memcmp(cd2->content, "four", cd2->content_len) != 0 ||
2682  hcbd1->flags != 0 ||
2683  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2684  hcbd2->flags != DETECT_CONTENT_DEPTH ||
2685  memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) {
2686  goto end;
2687  }
2688 
2689  if (DETECT_CONTENT_IS_SINGLE(cd2) ||
2690  !DETECT_CONTENT_IS_SINGLE(hcbd1) ||
2691  DETECT_CONTENT_IS_SINGLE(hcbd2)) {
2692  goto end;
2693  }
2694 
2695  result = 1;
2696 
2697  end:
2698  DetectEngineCtxFree(de_ctx);
2699  return result;
2700 }
2701 
2702 static int DetectHttpClientBodyTest29(void)
2703 {
2704  DetectEngineCtx *de_ctx = NULL;
2705  int result = 0;
2706 
2707  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2708  goto end;
2709 
2710  de_ctx->flags |= DE_QUIET;
2711  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2712  "(content:\"one\"; http_client_body; "
2713  "content:\"two\"; distance:0; http_client_body; sid:1;)");
2714  if (de_ctx->sig_list == NULL) {
2715  printf("de_ctx->sig_list == NULL\n");
2716  goto end;
2717  }
2718 
2719  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2720  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2721  goto end;
2722  }
2723 
2724  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2725  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2726  goto end;
2727  }
2728 
2729  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2730  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2731  if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2732  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2733  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2734  memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2735  goto end;
2736  }
2737 
2738  result = 1;
2739 
2740  end:
2741  DetectEngineCtxFree(de_ctx);
2742  return result;
2743 }
2744 
2745 static int DetectHttpClientBodyTest30(void)
2746 {
2747  DetectEngineCtx *de_ctx = NULL;
2748  int result = 0;
2749 
2750  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2751  goto end;
2752 
2753  de_ctx->flags |= DE_QUIET;
2754  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2755  "(content:\"one\"; http_client_body; "
2756  "content:\"two\"; within:5; http_client_body; sid:1;)");
2757  if (de_ctx->sig_list == NULL) {
2758  printf("de_ctx->sig_list == NULL\n");
2759  goto end;
2760  }
2761 
2762  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2763  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2764  goto end;
2765  }
2766 
2767  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2768  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2769  goto end;
2770  }
2771 
2772  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2773  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2774  if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2775  memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 ||
2776  hcbd2->flags != DETECT_CONTENT_WITHIN ||
2777  memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) {
2778  goto end;
2779  }
2780 
2781  result = 1;
2782 
2783  end:
2784  DetectEngineCtxFree(de_ctx);
2785  return result;
2786 }
2787 
2788 static int DetectHttpClientBodyTest31(void)
2789 {
2790  DetectEngineCtx *de_ctx = NULL;
2791  int result = 0;
2792 
2793  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2794  goto end;
2795 
2796  de_ctx->flags |= DE_QUIET;
2797  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2798  "(content:\"one\"; within:5; http_client_body; sid:1;)");
2799  if (de_ctx->sig_list == NULL) {
2800  printf("de_ctx->sig_list == NULL\n");
2801  goto end;
2802  }
2803 
2804  result = 1;
2805 
2806  end:
2807  DetectEngineCtxFree(de_ctx);
2808  return result;
2809 }
2810 
2811 static int DetectHttpClientBodyTest32(void)
2812 {
2813  DetectEngineCtx *de_ctx = NULL;
2814  int result = 0;
2815 
2816  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2817  goto end;
2818 
2819  de_ctx->flags |= DE_QUIET;
2820  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2821  "(content:\"one\"; http_client_body; within:5; sid:1;)");
2822  if (de_ctx->sig_list == NULL) {
2823  printf("de_ctx->sig_list != NULL\n");
2824  goto end;
2825  }
2826 
2827  result = 1;
2828 
2829  end:
2830  DetectEngineCtxFree(de_ctx);
2831  return result;
2832 }
2833 
2834 static int DetectHttpClientBodyTest33(void)
2835 {
2836  DetectEngineCtx *de_ctx = NULL;
2837  int result = 0;
2838 
2839  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2840  goto end;
2841 
2842  de_ctx->flags |= DE_QUIET;
2843  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2844  "(content:\"one\"; within:5; sid:1;)");
2845  if (de_ctx->sig_list == NULL) {
2846  printf("de_ctx->sig_list == NULL\n");
2847  goto end;
2848  }
2849 
2850  result = 1;
2851 
2852  end:
2853  DetectEngineCtxFree(de_ctx);
2854  return result;
2855 }
2856 
2857 static int DetectHttpClientBodyTest34(void)
2858 {
2859  DetectEngineCtx *de_ctx = NULL;
2860  int result = 0;
2861 
2862  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2863  goto end;
2864 
2865  de_ctx->flags |= DE_QUIET;
2866  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2867  "(pcre:/one/P; "
2868  "content:\"two\"; within:5; http_client_body; sid:1;)");
2869  if (de_ctx->sig_list == NULL) {
2870  printf("de_ctx->sig_list == NULL\n");
2871  goto end;
2872  }
2873 
2874  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2875  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2876  goto end;
2877  }
2878 
2879  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2880  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2881  goto end;
2882  }
2883 
2884  if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2885  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_CONTENT ||
2886  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2887  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_PCRE) {
2888 
2889  goto end;
2890  }
2891 
2892  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2893  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2894  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2895  hcbd2->flags != DETECT_CONTENT_WITHIN ||
2896  memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2897  goto end;
2898  }
2899 
2900  result = 1;
2901 
2902  end:
2903  DetectEngineCtxFree(de_ctx);
2904  return result;
2905 }
2906 
2907 static int DetectHttpClientBodyTest35(void)
2908 {
2909  DetectEngineCtx *de_ctx = NULL;
2910  int result = 0;
2911 
2912  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2913  goto end;
2914 
2915  de_ctx->flags |= DE_QUIET;
2916  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2917  "(content:\"two\"; http_client_body; "
2918  "pcre:/one/PR; sid:1;)");
2919  if (de_ctx->sig_list == NULL) {
2920  printf("de_ctx->sig_list == NULL\n");
2921  goto end;
2922  }
2923 
2924  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2925  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2926  goto end;
2927  }
2928 
2929  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2930  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2931  goto end;
2932  }
2933 
2934  if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2935  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_PCRE ||
2936  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2937  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_CONTENT) {
2938 
2939  goto end;
2940  }
2941 
2942  DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2943  DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2944  if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
2945  hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
2946  memcmp(hcbd1->content, "two", hcbd1->content_len) != 0) {
2947  goto end;
2948  }
2949 
2950  result = 1;
2951 
2952  end:
2953  DetectEngineCtxFree(de_ctx);
2954  return result;
2955 }
2956 
2957 static int DetectHttpClientBodyTest36(void)
2958 {
2959  DetectEngineCtx *de_ctx = NULL;
2960  int result = 0;
2961 
2962  if ( (de_ctx = DetectEngineCtxInit()) == NULL)
2963  goto end;
2964 
2965  de_ctx->flags |= DE_QUIET;
2966  de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
2967  "(pcre:/one/P; "
2968  "content:\"two\"; distance:5; http_client_body; sid:1;)");
2969  if (de_ctx->sig_list == NULL) {
2970  printf("de_ctx->sig_list == NULL\n");
2971  goto end;
2972  }
2973 
2974  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2975  printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
2976  goto end;
2977  }
2978 
2979  if (de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL) {
2980  printf("de_ctx->sig_list->sm_lists[g_http_client_body_buffer_id] == NULL\n");
2981  goto end;
2982  }
2983 
2984  if (de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id] == NULL ||
2985  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->type != DETECT_CONTENT ||
2986  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev == NULL ||
2987  de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->type != DETECT_PCRE) {
2988 
2989  goto end;
2990  }
2991 
2992  DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->prev->ctx;
2993  DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_client_body_buffer_id]->ctx;
2994  if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
2995  hcbd2->flags != DETECT_CONTENT_DISTANCE ||
2996  memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) {
2997  goto end;
2998  }
2999 
3000  result = 1;
3001 
3002  end:
3003  DetectEngineCtxFree(de_ctx);
3004  return result;
3005 }
3006 
3007 static int DetectHttpClientBodyIsdataatParseTest(void)
3008 {
3010  FAIL_IF_NULL(de_ctx);
3011  de_ctx->flags |= DE_QUIET;
3012 
3013  Signature *s = DetectEngineAppendSig(de_ctx,
3014  "alert tcp any any -> any any ("
3015  "content:\"one\"; http_client_body; "
3016  "isdataat:!4,relative; sid:1;)");
3017  FAIL_IF_NULL(s);
3018 
3019  SigMatch *sm = s->init_data->smlists_tail[g_http_client_body_buffer_id];
3020  FAIL_IF_NULL(sm);
3022 
3023  DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
3026  FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
3027 
3028  DetectEngineCtxFree(de_ctx);
3029  PASS;
3030 }
3031 
3033 {
3034  UtRegisterTest("DetectHttpClientBodyParserTest01", DetectHttpClientBodyParserTest01);
3035  UtRegisterTest("DetectHttpClientBodyParserTest02", DetectHttpClientBodyParserTest02);
3036  UtRegisterTest("DetectHttpClientBodyTest01", DetectHttpClientBodyTest01);
3037  UtRegisterTest("DetectHttpClientBodyTest02", DetectHttpClientBodyTest02);
3038  UtRegisterTest("DetectHttpClientBodyTest03", DetectHttpClientBodyTest03);
3039  UtRegisterTest("DetectHttpClientBodyTest04", DetectHttpClientBodyTest04);
3040  UtRegisterTest("DetectHttpClientBodyTest05", DetectHttpClientBodyTest05);
3041  UtRegisterTest("DetectHttpClientBodyTest06", DetectHttpClientBodyTest06);
3042  UtRegisterTest("DetectHttpClientBodyTest07", DetectHttpClientBodyTest07);
3043  UtRegisterTest("DetectHttpClientBodyTest08", DetectHttpClientBodyTest08);
3044  UtRegisterTest("DetectHttpClientBodyTest09", DetectHttpClientBodyTest09);
3045  UtRegisterTest("DetectHttpClientBodyTest10", DetectHttpClientBodyTest10);
3046  UtRegisterTest("DetectHttpClientBodyTest11", DetectHttpClientBodyTest11);
3047  UtRegisterTest("DetectHttpClientBodyTest12", DetectHttpClientBodyTest12);
3048  UtRegisterTest("DetectHttpClientBodyTest13", DetectHttpClientBodyTest13);
3049  UtRegisterTest("DetectHttpClientBodyTest14", DetectHttpClientBodyTest14);
3050  UtRegisterTest("DetectHttpClientBodyTest15", DetectHttpClientBodyTest15);
3051 
3052  UtRegisterTest("DetectHttpClientBodyTest22", DetectHttpClientBodyTest22);
3053  UtRegisterTest("DetectHttpClientBodyTest23", DetectHttpClientBodyTest23);
3054  UtRegisterTest("DetectHttpClientBodyTest24", DetectHttpClientBodyTest24);
3055  UtRegisterTest("DetectHttpClientBodyTest25", DetectHttpClientBodyTest25);
3056  UtRegisterTest("DetectHttpClientBodyTest26", DetectHttpClientBodyTest26);
3057  UtRegisterTest("DetectHttpClientBodyTest27", DetectHttpClientBodyTest27);
3058  UtRegisterTest("DetectHttpClientBodyTest28", DetectHttpClientBodyTest28);
3059  UtRegisterTest("DetectHttpClientBodyTest29", DetectHttpClientBodyTest29);
3060  UtRegisterTest("DetectHttpClientBodyTest30", DetectHttpClientBodyTest30);
3061  UtRegisterTest("DetectHttpClientBodyTest31", DetectHttpClientBodyTest31);
3062  UtRegisterTest("DetectHttpClientBodyTest32", DetectHttpClientBodyTest32);
3063  UtRegisterTest("DetectHttpClientBodyTest33", DetectHttpClientBodyTest33);
3064  UtRegisterTest("DetectHttpClientBodyTest34", DetectHttpClientBodyTest34);
3065  UtRegisterTest("DetectHttpClientBodyTest35", DetectHttpClientBodyTest35);
3066  UtRegisterTest("DetectHttpClientBodyTest36", DetectHttpClientBodyTest36);
3067 
3068  UtRegisterTest("DetectHttpClientBodyIsdataatParseTest",
3069  DetectHttpClientBodyIsdataatParseTest);
3070 
3071  UtRegisterTest("DetectEngineHttpClientBodyTest01",
3072  DetectEngineHttpClientBodyTest01);
3073  UtRegisterTest("DetectEngineHttpClientBodyTest02",
3074  DetectEngineHttpClientBodyTest02);
3075  UtRegisterTest("DetectEngineHttpClientBodyTest03",
3076  DetectEngineHttpClientBodyTest03);
3077  UtRegisterTest("DetectEngineHttpClientBodyTest04",
3078  DetectEngineHttpClientBodyTest04);
3079  UtRegisterTest("DetectEngineHttpClientBodyTest05",
3080  DetectEngineHttpClientBodyTest05);
3081  UtRegisterTest("DetectEngineHttpClientBodyTest06",
3082  DetectEngineHttpClientBodyTest06);
3083  UtRegisterTest("DetectEngineHttpClientBodyTest07",
3084  DetectEngineHttpClientBodyTest07);
3085  UtRegisterTest("DetectEngineHttpClientBodyTest08",
3086  DetectEngineHttpClientBodyTest08);
3087  UtRegisterTest("DetectEngineHttpClientBodyTest09",
3088  DetectEngineHttpClientBodyTest09);
3089  UtRegisterTest("DetectEngineHttpClientBodyTest10",
3090  DetectEngineHttpClientBodyTest10);
3091  UtRegisterTest("DetectEngineHttpClientBodyTest11",
3092  DetectEngineHttpClientBodyTest11);
3093  UtRegisterTest("DetectEngineHttpClientBodyTest12",
3094  DetectEngineHttpClientBodyTest12);
3095  UtRegisterTest("DetectEngineHttpClientBodyTest13",
3096  DetectEngineHttpClientBodyTest13);
3097  UtRegisterTest("DetectEngineHttpClientBodyTest14",
3098  DetectEngineHttpClientBodyTest14);
3099  UtRegisterTest("DetectEngineHttpClientBodyTest15",
3100  DetectEngineHttpClientBodyTest15);
3101  UtRegisterTest("DetectEngineHttpClientBodyTest16",
3102  DetectEngineHttpClientBodyTest16);
3103  UtRegisterTest("DetectEngineHttpClientBodyTest17",
3104  DetectEngineHttpClientBodyTest17);
3105  UtRegisterTest("DetectEngineHttpClientBodyTest18",
3106  DetectEngineHttpClientBodyTest18);
3107  UtRegisterTest("DetectEngineHttpClientBodyTest19",
3108  DetectEngineHttpClientBodyTest19);
3109  UtRegisterTest("DetectEngineHttpClientBodyTest20",
3110  DetectEngineHttpClientBodyTest20);
3111  UtRegisterTest("DetectEngineHttpClientBodyTest21",
3112  DetectEngineHttpClientBodyTest21);
3113  UtRegisterTest("DetectEngineHttpClientBodyTest22",
3114  DetectEngineHttpClientBodyTest22);
3115  UtRegisterTest("DetectEngineHttpClientBodyTest23",
3116  DetectEngineHttpClientBodyTest23);
3117  UtRegisterTest("DetectEngineHttpClientBodyTest24",
3118  DetectEngineHttpClientBodyTest24);
3119  UtRegisterTest("DetectEngineHttpClientBodyTest25",
3120  DetectEngineHttpClientBodyTest25);
3121  UtRegisterTest("DetectEngineHttpClientBodyTest26",
3122  DetectEngineHttpClientBodyTest26);
3123  UtRegisterTest("DetectEngineHttpClientBodyTest27",
3124  DetectEngineHttpClientBodyTest27);
3125  UtRegisterTest("DetectEngineHttpClientBodyTest28",
3126  DetectEngineHttpClientBodyTest28);
3127  UtRegisterTest("DetectEngineHttpClientBodyTest29",
3128  DetectEngineHttpClientBodyTest29);
3129 
3130  UtRegisterTest("DetectEngineHttpClientBodyTest30",
3131  DetectEngineHttpClientBodyTest30);
3132  UtRegisterTest("DetectEngineHttpClientBodyTest31",
3133  DetectEngineHttpClientBodyTest31);
3134 }
3135 
3136 #endif
3137 
3138 /**
3139  * @}
3140  */
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SignatureInitData * init_data
Definition: detect.h:586
#define SCLogDebug(...)
Definition: util-debug.h:335
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:27
struct Flow_ * flow
Definition: decode.h:445
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint8_t proto
Definition: flow.h:344
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:243
#define unlikely(expr)
Definition: util-optimize.h:35
#define PASS
Pass the test.
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
int UTHParseSignature(const char *str, bool expect)
parser a sig and see if the expected result is correct
Signature * sig_list
Definition: detect.h:762
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:203
#define ISDATAAT_RELATIVE
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define DETECT_CONTENT_DISTANCE
#define TOTAL_REQUESTS
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
#define ISDATAAT_RAWBYTES
Signature container.
Definition: detect.h:517
StreamingBufferSegment sbseg
#define DETECT_CONTENT_DEPTH
#define TRUE
HtpBody request_body
void * protoctx
Definition: flow.h:400
uint16_t flags
Definition: detect-pcre.h:42
#define DETECT_CONTENT_IS_SINGLE(c)
struct SigMatch_ * next
Definition: detect.h:317
main detection engine ctx
Definition: detect.h:756
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:438
void HTPConfigure(void)
#define DE_QUIET
Definition: detect.h:287
void ConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition: conf.c:699
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
void HtpConfigCreateBackup(void)
const uint8_t * input
uint8_t flags
Definition: detect.h:757
Data structures and function prototypes for keeping state for the detection engine.
#define ISDATAAT_NEGATED
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
StreamingBuffer * sb
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void ConfInit(void)
Initialize the configuration system.
Definition: conf.c:113
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1670
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
uint8_t flowflags
Definition: decode.h:439
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.
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:711
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
struct SigMatch_ ** smlists_tail
Definition: detect.h:513
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
uint8_t type
Definition: detect.h:314
SigMatchCtx * ctx
Definition: detect.h:316
void HtpConfigRestoreBackup(void)
#define SCMalloc(a)
Definition: util-mem.h:222
#define SCFree(a)
Definition: util-mem.h:322
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t *rawdata, uint32_t rawdata_len)
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
PacketAlerts alerts
Definition: decode.h:555
#define DETECT_CONTENT_WITHIN
#define PKT_HAS_FLOW
Definition: decode.h:1090
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
HtpBodyChunk * first
uint16_t cnt
Definition: decode.h:293
#define DETECT_CONTENT_RELATIVE_NEXT
Per thread variable structure.
Definition: threadvars.h:57
#define FLOW_PKT_TOCLIENT
Definition: flow.h:202
AppProto alproto
application level protocol
Definition: flow.h:409
uint32_t flags
Definition: decode.h:443
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void DetectHttpClientBodyRegisterTests(void)
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
#define DETECT_CONTENT_OFFSET
Flow data structure.
Definition: flow.h:325
#define FLOW_IPV4
Definition: flow.h:94
uint32_t flags
Definition: flow.h:379
#define PKT_STREAM_EST
Definition: decode.h:1088
a single match condition for a signature
Definition: detect.h:313
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
DetectEngineCtx * DetectEngineCtxInit(void)