suricata
detect-pcre.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Implements the pcre keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "pcre.h"
28 #include "debug.h"
29 #include "decode.h"
30 #include "detect.h"
31 
32 #include "pkt-var.h"
33 #include "flow-var.h"
34 #include "flow-util.h"
35 
36 #include "detect-pcre.h"
37 #include "detect-flowvar.h"
38 
39 #include "detect-parse.h"
40 #include "detect-engine.h"
41 #include "detect-engine-sigorder.h"
42 #include "detect-engine-mpm.h"
43 #include "detect-engine-state.h"
44 
45 #include "util-var-name.h"
46 #include "util-unittest-helper.h"
47 #include "util-debug.h"
48 #include "util-unittest.h"
49 #include "util-print.h"
50 #include "util-pool.h"
51 
52 #include "conf.h"
53 #include "app-layer.h"
54 #include "app-layer-htp.h"
55 #include "stream.h"
56 #include "stream-tcp.h"
57 #include "stream-tcp-private.h"
58 #include "stream-tcp-reassemble.h"
59 #include "app-layer-protos.h"
60 #include "app-layer-parser.h"
61 #include "util-pages.h"
62 
63 /* pcre named substring capture supports only 32byte names, A-z0-9 plus _
64  * and needs to start with non-numeric. */
65 #define PARSE_CAPTURE_REGEX "\\(\\?P\\<([A-z]+)\\_([A-z0-9_]+)\\>"
66 #define PARSE_REGEX "(?<!\\\\)/(.*(?<!(?<!\\\\)\\\\))/([^\"]*)"
67 
68 #define SC_MATCH_LIMIT_DEFAULT 3500
69 #define SC_MATCH_LIMIT_RECURSION_DEFAULT 1500
70 
71 static int pcre_match_limit = 0;
72 static int pcre_match_limit_recursion = 0;
73 
74 static DetectParseRegex parse_regex;
75 static DetectParseRegex parse_capture_regex;
76 
77 #ifdef PCRE_HAVE_JIT
78 static int pcre_use_jit = 1;
79 #endif
80 
81 #ifdef PCRE_HAVE_JIT_EXEC
82 #define PCRE_JIT_MIN_STACK 32*1024
83 #define PCRE_JIT_MAX_STACK 512*1024
84 
85 #endif
86 
87 /* \brief Helper function for using pcre_exec with/without JIT
88  */
89 static inline int DetectPcreExec(DetectEngineThreadCtx *det_ctx, DetectPcreData *pd, DetectParseRegex *regex,
90  const char *str, const size_t strlen, int start_offset, int options, int *ovector, int ovector_size)
91 {
92 #ifdef PCRE_HAVE_JIT_EXEC
93  if (pd->thread_ctx_jit_stack_id != -1) {
94  pcre_jit_stack *jit_stack = (pcre_jit_stack *)
95  DetectThreadCtxGetKeywordThreadCtx(det_ctx, pd->thread_ctx_jit_stack_id);
96  if (jit_stack) {
97  SCLogDebug("Using jit_stack %p", jit_stack);
98  return pcre_jit_exec(regex->regex, regex->study, str, strlen,
99  start_offset, options, ovector, ovector_size,
100  jit_stack);
101  }
102  }
103 #endif
104  /* Fallback if registration during setup failed */
105  return pcre_exec(regex->regex, regex->study, str, strlen,
106  start_offset, options, ovector, ovector_size);
107 }
108 
109 static int DetectPcreSetup (DetectEngineCtx *, Signature *, const char *);
110 static void DetectPcreFree(DetectEngineCtx *, void *);
111 #ifdef UNITTESTS
112 static void DetectPcreRegisterTests(void);
113 #endif
114 
116 {
117  sigmatch_table[DETECT_PCRE].name = "pcre";
118  sigmatch_table[DETECT_PCRE].desc = "match on regular expression";
119  sigmatch_table[DETECT_PCRE].url = "/rules/payload-keywords.html#pcre-perl-compatible-regular-expressions";
121  sigmatch_table[DETECT_PCRE].Setup = DetectPcreSetup;
122  sigmatch_table[DETECT_PCRE].Free = DetectPcreFree;
123 #ifdef UNITTESTS
124  sigmatch_table[DETECT_PCRE].RegisterTests = DetectPcreRegisterTests;
125 #endif
127 
128  intmax_t val = 0;
129 
130  if (!ConfGetInt("pcre.match-limit", &val)) {
131  pcre_match_limit = SC_MATCH_LIMIT_DEFAULT;
132  SCLogDebug("Using PCRE match-limit setting of: %i", pcre_match_limit);
133  }
134  else {
135  pcre_match_limit = val;
136  if (pcre_match_limit != SC_MATCH_LIMIT_DEFAULT) {
137  SCLogInfo("Using PCRE match-limit setting of: %i", pcre_match_limit);
138  } else {
139  SCLogDebug("Using PCRE match-limit setting of: %i", pcre_match_limit);
140  }
141  }
142 
143  val = 0;
144 
145  if (!ConfGetInt("pcre.match-limit-recursion", &val)) {
146  pcre_match_limit_recursion = SC_MATCH_LIMIT_RECURSION_DEFAULT;
147  SCLogDebug("Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
148  }
149  else {
150  pcre_match_limit_recursion = val;
151  if (pcre_match_limit_recursion != SC_MATCH_LIMIT_RECURSION_DEFAULT) {
152  SCLogInfo("Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
153  } else {
154  SCLogDebug("Using PCRE match-limit-recursion setting of: %i", pcre_match_limit_recursion);
155  }
156  }
157 
158  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
159 
160  /* setup the capture regex, as it needs PCRE_UNGREEDY we do it manually */
161  /* pkt_http_ua should be pkt, http_ua, for this reason the UNGREEDY */
162  if (!DetectSetupParseRegexesOpts(PARSE_CAPTURE_REGEX, &parse_capture_regex, PCRE_UNGREEDY)) {
163  FatalError(SC_ERR_PCRE_COMPILE, "pcre compile and study failed");
164  }
165 
166 #ifdef PCRE_HAVE_JIT
167  if (PageSupportsRWX() == 0) {
168  SCLogConfig("PCRE won't use JIT as OS doesn't allow RWX pages");
169  pcre_use_jit = 0;
170  }
171 #endif
172 
173  return;
174 }
175 
176 /**
177  * \brief Match a regex on a single payload.
178  *
179  * \param det_ctx Thread detection ctx.
180  * \param s Signature.
181  * \param sm Sig match to match against.
182  * \param p Packet to set PktVars if any.
183  * \param f Flow to set FlowVars if any.
184  * \param payload Payload to inspect.
185  * \param payload_len Length of the payload.
186  *
187  * \retval 1 Match.
188  * \retval 0 No match.
189  */
191  const SigMatchData *smd, Packet *p, Flow *f,
192  const uint8_t *payload, uint32_t payload_len)
193 {
194  SCEnter();
195  int ret = 0;
196  int ov[MAX_SUBSTRINGS];
197  const uint8_t *ptr = NULL;
198  uint16_t len = 0;
199  uint16_t capture_len = 0;
200 
201  DetectPcreData *pe = (DetectPcreData *)smd->ctx;
202 
203  if (pe->flags & DETECT_PCRE_RELATIVE) {
204  ptr = payload + det_ctx->buffer_offset;
205  len = payload_len - det_ctx->buffer_offset;
206  } else {
207  ptr = payload;
208  len = payload_len;
209  }
210 
211  int start_offset = 0;
212  if (det_ctx->pcre_match_start_offset != 0) {
213  start_offset = (payload + det_ctx->pcre_match_start_offset - ptr);
214  }
215 
216  /* run the actual pcre detection */
217  ret = DetectPcreExec(det_ctx, pe, &pe->parse_regex, (char *) ptr, len, start_offset, 0, ov, MAX_SUBSTRINGS);
218  SCLogDebug("ret %d (negating %s)", ret, (pe->flags & DETECT_PCRE_NEGATE) ? "set" : "not set");
219 
220  if (ret == PCRE_ERROR_NOMATCH) {
221  if (pe->flags & DETECT_PCRE_NEGATE) {
222  /* regex didn't match with negate option means we
223  * consider it a match */
224  ret = 1;
225  } else {
226  ret = 0;
227  }
228  } else if (ret >= 0) {
229  if (pe->flags & DETECT_PCRE_NEGATE) {
230  /* regex matched but we're negated, so not
231  * considering it a match */
232  ret = 0;
233  } else {
234  /* regex matched and we're not negated,
235  * considering it a match */
236 
237  SCLogDebug("ret %d pe->idx %u", ret, pe->idx);
238 
239  /* see if we need to do substring capturing. */
240  if (ret > 1 && pe->idx != 0) {
241  uint8_t x;
242  for (x = 0; x < pe->idx; x++) {
243  SCLogDebug("capturing %u", x);
244  const char *str_ptr = NULL;
245  ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, x+1, &str_ptr);
246  if (unlikely(ret == 0)) {
247  pcre_free_substring(str_ptr);
248  continue;
249  }
250 
251  SCLogDebug("data %p/%u, type %u id %u p %p",
252  str_ptr, ret, pe->captypes[x], pe->capids[x], p);
253 
254  if (pe->captypes[x] == VAR_TYPE_PKT_VAR_KV) {
255  /* get the value, as first capture is the key */
256  const char *str_ptr2 = NULL;
257  int ret2 = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, x+2, &str_ptr2);
258  if (unlikely(ret2 == 0)) {
259  pcre_free_substring(str_ptr);
260  pcre_free_substring(str_ptr2);
261  break;
262  }
263  /* key length is limited to 256 chars */
264  uint16_t key_len = (ret < 0xff) ? (uint16_t)ret : 0xff;
265  capture_len = (ret2 < 0xffff) ? (uint16_t)ret2 : 0xffff;
266 
267  (void)DetectVarStoreMatchKeyValue(det_ctx,
268  (uint8_t *)str_ptr, key_len,
269  (uint8_t *)str_ptr2, capture_len,
271 
272  } else if (pe->captypes[x] == VAR_TYPE_PKT_VAR) {
273  /* store max 64k. Errors are ignored */
274  capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
275  (void)DetectVarStoreMatch(det_ctx, pe->capids[x],
276  (uint8_t *)str_ptr, capture_len,
278 
279  } else if (pe->captypes[x] == VAR_TYPE_FLOW_VAR && f != NULL) {
280  /* store max 64k. Errors are ignored */
281  capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
282  (void)DetectVarStoreMatch(det_ctx, pe->capids[x],
283  (uint8_t *)str_ptr, capture_len,
285  }
286  }
287  }
288 
289  /* update offset for pcre RELATIVE */
290  det_ctx->buffer_offset = (ptr + ov[1]) - payload;
291  det_ctx->pcre_match_start_offset = (ptr + ov[0] + 1) - payload;
292 
293  ret = 1;
294  }
295 
296  } else {
297  SCLogDebug("pcre had matching error");
298  ret = 0;
299  }
300  SCReturnInt(ret);
301 }
302 
303 static int DetectPcreSetList(int list, int set)
304 {
305  if (list != DETECT_SM_LIST_NOTSET) {
306  SCLogError(SC_ERR_INVALID_SIGNATURE, "only one pcre option to specify a buffer type is allowed");
307  return -1;
308  }
309  return set;
310 }
311 
312 static int DetectPcreHasUpperCase(const char *re)
313 {
314  size_t len = strlen(re);
315  bool is_meta = false;
316  bool is_meta_hex = false;
317  int meta_hex_cnt = 0;
318 
319  for (size_t i = 0; i < len; i++) {
320  if (is_meta_hex) {
321  meta_hex_cnt++;
322 
323  if (meta_hex_cnt == 2) {
324  is_meta_hex = false;
325  meta_hex_cnt = 0;
326  }
327  } else if (is_meta) {
328  if (re[i] == 'x') {
329  is_meta_hex = true;
330  } else {
331  is_meta = false;
332  }
333  }
334  else if (re[i] == '\\') {
335  is_meta = true;
336  }
337  else if (isupper((unsigned char)re[i])) {
338  return 1;
339  }
340  }
341 
342  return 0;
343 }
344 
345 static DetectPcreData *DetectPcreParse (DetectEngineCtx *de_ctx,
346  const char *regexstr, int *sm_list, char *capture_names,
347  size_t capture_names_size, bool negate, AppProto *alproto)
348 {
349  int ec;
350  const char *eb;
351  int eo;
352  int opts = 0;
353  DetectPcreData *pd = NULL;
354  char *op = NULL;
355  int ret = 0, res = 0;
356  int ov[MAX_SUBSTRINGS];
357  int check_host_header = 0;
358  char op_str[64] = "";
359 
360  int cut_capture = 0;
361  char *fcap = strstr(regexstr, "flow:");
362  char *pcap = strstr(regexstr, "pkt:");
363  /* take the size of the whole input as buffer size for the regex we will
364  * extract below. Add 1 to please Coverity's alloc_strlen test. */
365  size_t slen = strlen(regexstr) + 1;
366  if (fcap || pcap) {
367  SCLogDebug("regexstr %s", regexstr);
368 
369  if (fcap && !pcap)
370  cut_capture = fcap - regexstr;
371  else if (pcap && !fcap)
372  cut_capture = pcap - regexstr;
373  else
374  cut_capture = MIN((pcap - regexstr), (fcap - regexstr));
375 
376  SCLogDebug("cut_capture %d", cut_capture);
377 
378  if (cut_capture > 1) {
379  int offset = cut_capture - 1;
380  while (offset) {
381  SCLogDebug("regexstr[offset] %c", regexstr[offset]);
382  if (regexstr[offset] == ',' || regexstr[offset] == ' ') {
383  offset--;
384  }
385  else
386  break;
387  }
388 
389  if (cut_capture == (offset + 1)) {
390  SCLogDebug("missing separators, assume it's part of the regex");
391  } else {
392  slen = offset + 1;
393  strlcpy(capture_names, regexstr+cut_capture, capture_names_size);
394  if (capture_names[strlen(capture_names)-1] == '"')
395  capture_names[strlen(capture_names)-1] = '\0';
396  }
397  }
398  }
399 
400  char re[slen];
401  ret = pcre_exec(parse_regex.regex, parse_regex.study, regexstr,
402  slen, 0, 0, ov, MAX_SUBSTRINGS);
403  if (ret <= 0) {
404  SCLogError(SC_ERR_PCRE_MATCH, "pcre parse error: %s", regexstr);
405  goto error;
406  }
407 
408  res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS,
409  1, re, slen);
410  if (res < 0) {
411  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
412  return NULL;
413  }
414 
415  if (ret > 2) {
416  res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS,
417  2, op_str, sizeof(op_str));
418  if (res < 0) {
419  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
420  return NULL;
421  }
422  op = op_str;
423  }
424  //printf("ret %" PRId32 " re \'%s\', op \'%s\'\n", ret, re, op);
425 
426  pd = SCCalloc(1, sizeof(DetectPcreData));
427  if (unlikely(pd == NULL))
428  goto error;
429 
430  if (negate)
431  pd->flags |= DETECT_PCRE_NEGATE;
432 
433  if (op != NULL) {
434  while (*op) {
435  SCLogDebug("regex option %c", *op);
436 
437  switch (*op) {
438  case 'A':
439  opts |= PCRE_ANCHORED;
440  break;
441  case 'E':
442  opts |= PCRE_DOLLAR_ENDONLY;
443  break;
444  case 'G':
445  opts |= PCRE_UNGREEDY;
446  break;
447 
448  case 'i':
449  opts |= PCRE_CASELESS;
451  break;
452  case 'm':
453  opts |= PCRE_MULTILINE;
454  break;
455  case 's':
456  opts |= PCRE_DOTALL;
457  break;
458  case 'x':
459  opts |= PCRE_EXTENDED;
460  break;
461 
462  case 'O':
464  break;
465 
466  case 'B': /* snort's option */
467  if (*sm_list != DETECT_SM_LIST_NOTSET) {
468  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'B' inconsistent with chosen buffer");
469  goto error;
470  }
472  break;
473  case 'R': /* snort's option */
475  break;
476 
477  /* buffer selection */
478 
479  case 'U': { /* snort's option */
480  if (pd->flags & DETECT_PCRE_RAWBYTES) {
481  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'U' inconsistent with 'B'");
482  goto error;
483  }
484  int list = DetectBufferTypeGetByName("http_uri");
485  *sm_list = DetectPcreSetList(*sm_list, list);
486  *alproto = ALPROTO_HTTP;
487  break;
488  }
489  case 'V': {
490  if (pd->flags & DETECT_PCRE_RAWBYTES) {
491  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'V' inconsistent with 'B'");
492  goto error;
493  }
494  int list = DetectBufferTypeGetByName("http_user_agent");
495  *sm_list = DetectPcreSetList(*sm_list, list);
496  *alproto = ALPROTO_HTTP;
497  break;
498  }
499  case 'W': {
500  if (pd->flags & DETECT_PCRE_RAWBYTES) {
501  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'W' inconsistent with 'B'");
502  goto error;
503  }
504  int list = DetectBufferTypeGetByName("http_host");
505  *sm_list = DetectPcreSetList(*sm_list, list);
506  *alproto = ALPROTO_HTTP;
507  check_host_header = 1;
508  break;
509  }
510  case 'Z': {
511  if (pd->flags & DETECT_PCRE_RAWBYTES) {
512  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'Z' inconsistent with 'B'");
513  goto error;
514  }
515  int list = DetectBufferTypeGetByName("http_raw_host");
516  *sm_list = DetectPcreSetList(*sm_list, list);
517  *alproto = ALPROTO_HTTP;
518  break;
519  }
520  case 'H': { /* snort's option */
521  if (pd->flags & DETECT_PCRE_RAWBYTES) {
522  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'H' inconsistent with 'B'");
523  goto error;
524  }
525  int list = DetectBufferTypeGetByName("http_header");
526  *sm_list = DetectPcreSetList(*sm_list, list);
527  *alproto = ALPROTO_HTTP;
528  break;
529  } case 'I': { /* snort's option */
530  if (pd->flags & DETECT_PCRE_RAWBYTES) {
531  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'I' inconsistent with 'B'");
532  goto error;
533  }
534  int list = DetectBufferTypeGetByName("http_raw_uri");
535  *sm_list = DetectPcreSetList(*sm_list, list);
536  *alproto = ALPROTO_HTTP;
537  break;
538  }
539  case 'D': { /* snort's option */
540  int list = DetectBufferTypeGetByName("http_raw_header");
541  *sm_list = DetectPcreSetList(*sm_list, list);
542  *alproto = ALPROTO_HTTP;
543  break;
544  }
545  case 'M': { /* snort's option */
546  if (pd->flags & DETECT_PCRE_RAWBYTES) {
547  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'M' inconsistent with 'B'");
548  goto error;
549  }
550  int list = DetectBufferTypeGetByName("http_method");
551  *sm_list = DetectPcreSetList(*sm_list, list);
552  *alproto = ALPROTO_HTTP;
553  break;
554  }
555  case 'C': { /* snort's option */
556  if (pd->flags & DETECT_PCRE_RAWBYTES) {
557  SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'C' inconsistent with 'B'");
558  goto error;
559  }
560  int list = DetectBufferTypeGetByName("http_cookie");
561  *sm_list = DetectPcreSetList(*sm_list, list);
562  *alproto = ALPROTO_HTTP;
563  break;
564  }
565  case 'P': {
566  /* snort's option (http request body inspection) */
567  int list = DetectBufferTypeGetByName("http_client_body");
568  *sm_list = DetectPcreSetList(*sm_list, list);
569  *alproto = ALPROTO_HTTP;
570  break;
571  }
572  case 'Q': {
573  int list = DetectBufferTypeGetByName("file_data");
574  /* suricata extension (http response body inspection) */
575  *sm_list = DetectPcreSetList(*sm_list, list);
576  *alproto = ALPROTO_HTTP;
577  break;
578  }
579  case 'Y': {
580  /* snort's option */
581  int list = DetectBufferTypeGetByName("http_stat_msg");
582  *sm_list = DetectPcreSetList(*sm_list, list);
583  *alproto = ALPROTO_HTTP;
584  break;
585  }
586  case 'S': {
587  /* snort's option */
588  int list = DetectBufferTypeGetByName("http_stat_code");
589  *sm_list = DetectPcreSetList(*sm_list, list);
590  *alproto = ALPROTO_HTTP;
591  break;
592  }
593  default:
594  SCLogError(SC_ERR_UNKNOWN_REGEX_MOD, "unknown regex modifier '%c'", *op);
595  goto error;
596  }
597  op++;
598  }
599  }
600  if (*sm_list == -1)
601  goto error;
602 
603  SCLogDebug("DetectPcreParse: \"%s\"", re);
604 
605  /* host header */
606  if (check_host_header) {
607  if (pd->flags & DETECT_PCRE_CASELESS) {
608  SCLogWarning(SC_ERR_INVALID_SIGNATURE, "http host pcre(\"W\") "
609  "specified along with \"i(caseless)\" modifier. "
610  "Since the hostname buffer we match against "
611  "is actually lowercase, having a "
612  "nocase is redundant.");
613  }
614  else if (DetectPcreHasUpperCase(re)) {
615  SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre host(\"W\") "
616  "specified has an uppercase char. "
617  "Since the hostname buffer we match against "
618  "is actually lowercase, please specify an "
619  "all lowercase based pcre.");
620  goto error;
621  }
622  }
623 
624  /* Try to compile as if all (...) groups had been meant as (?:...),
625  * which is the common case in most rules.
626  * If we fail because a capture group is later referenced (e.g., \1),
627  * PCRE will let us know.
628  */
629  if (capture_names == NULL || strlen(capture_names) == 0)
630  opts |= PCRE_NO_AUTO_CAPTURE;
631 
632  pd->parse_regex.regex = pcre_compile2(re, opts, &ec, &eb, &eo, NULL);
633  if (pd->parse_regex.regex == NULL && ec == 15) { // reference to non-existent subpattern
634  opts &= ~PCRE_NO_AUTO_CAPTURE;
635  pd->parse_regex.regex = pcre_compile(re, opts, &eb, &eo, NULL);
636  }
637 
638  if (pd->parse_regex.regex == NULL) {
639  SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed "
640  "at offset %" PRId32 ": %s", regexstr, eo, eb);
641  goto error;
642  }
643 
644  int options = 0;
645 #ifdef PCRE_HAVE_JIT
646  if (pcre_use_jit)
647  options |= PCRE_STUDY_JIT_COMPILE;
648 #endif
649  pd->parse_regex.study = pcre_study(pd->parse_regex.regex, options, &eb);
650  if(eb != NULL) {
651  SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed : %s", eb);
652  goto error;
653  }
654 
655 #ifdef PCRE_HAVE_JIT
656  int jit = 0;
657  ret = pcre_fullinfo(pd->parse_regex.regex, pd->parse_regex.study, PCRE_INFO_JIT, &jit);
658  if (ret != 0 || jit != 1) {
659  /* warning, so we won't print the sig after this. Adding
660  * file and line to the message so the admin can figure
661  * out what sig this is about */
662  SCLogDebug("PCRE JIT compiler does not support: %s. "
663  "Falling back to regular PCRE handling (%s:%d)",
664  regexstr, de_ctx->rule_file, de_ctx->rule_line);
665  }
666 
667 #endif /*PCRE_HAVE_JIT*/
668 
669  if (pd->parse_regex.study == NULL)
670  pd->parse_regex.study = (pcre_extra *) SCCalloc(1,sizeof(pcre_extra));
671 
672  if (pd->parse_regex.study) {
673  if(pd->flags & DETECT_PCRE_MATCH_LIMIT) {
674  if(pcre_match_limit >= -1) {
675  pd->parse_regex.study->match_limit = pcre_match_limit;
676  pd->parse_regex.study->flags |= PCRE_EXTRA_MATCH_LIMIT;
677  }
678 #ifndef NO_PCRE_MATCH_RLIMIT
679  if(pcre_match_limit_recursion >= -1) {
680  pd->parse_regex.study->match_limit_recursion = pcre_match_limit_recursion;
681  pd->parse_regex.study->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
682  }
683 #endif /* NO_PCRE_MATCH_RLIMIT */
684  } else {
685  pd->parse_regex.study->match_limit = SC_MATCH_LIMIT_DEFAULT;
686  pd->parse_regex.study->flags |= PCRE_EXTRA_MATCH_LIMIT;
687 #ifndef NO_PCRE_MATCH_RLIMIT
688  pd->parse_regex.study->match_limit_recursion = SC_MATCH_LIMIT_RECURSION_DEFAULT;
689  pd->parse_regex.study->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
690 #endif /* NO_PCRE_MATCH_RLIMIT */
691  }
692  } else {
693  goto error;
694  }
695  return pd;
696 
697 error:
698  DetectPcreFree(de_ctx, pd);
699  return NULL;
700 }
701 
702 /** \internal
703  * \brief check if we need to extract capture settings and set them up if needed
704  */
705 static int DetectPcreParseCapture(const char *regexstr, DetectEngineCtx *de_ctx, DetectPcreData *pd,
706  char *capture_names)
707 {
708  int ret = 0, res = 0;
709  int ov[MAX_SUBSTRINGS];
710  memset(&ov, 0, sizeof(ov));
711  char type_str[16] = "";
712  const char *orig_right_edge = regexstr + strlen(regexstr);
713  char *name_array[DETECT_PCRE_CAPTURE_MAX] = { NULL };
714  int name_idx = 0;
715  int capture_cnt = 0;
716  int key = 0;
717 
718  SCLogDebug("regexstr %s, pd %p", regexstr, pd);
719 
720  ret = pcre_fullinfo(pd->parse_regex.regex, pd->parse_regex.study, PCRE_INFO_CAPTURECOUNT, &capture_cnt);
721  SCLogDebug("ret %d capture_cnt %d", ret, capture_cnt);
722  if (ret == 0 && capture_cnt && strlen(capture_names) > 0)
723  {
724  char *ptr = NULL;
725  while ((name_array[name_idx] = strtok_r(name_idx == 0 ? capture_names : NULL, " ,", &ptr))){
726  if (name_idx > capture_cnt) {
727  SCLogError(SC_ERR_VAR_LIMIT, "more pkt/flow "
728  "var capture names than capturing substrings");
729  return -1;
730  }
731  SCLogDebug("name '%s'", name_array[name_idx]);
732 
733  if (strcmp(name_array[name_idx], "pkt:key") == 0) {
734  key = 1;
735  SCLogDebug("key-value/key");
736 
737  pd->captypes[pd->idx] = VAR_TYPE_PKT_VAR_KV;
738  SCLogDebug("id %u type %u", pd->capids[pd->idx], pd->captypes[pd->idx]);
739  pd->idx++;
740 
741  } else if (key == 1 && strcmp(name_array[name_idx], "pkt:value") == 0) {
742  SCLogDebug("key-value/value");
743  key = 0;
744 
745  /* kv error conditions */
746  } else if (key == 0 && strcmp(name_array[name_idx], "pkt:value") == 0) {
747  return -1;
748  } else if (key == 1) {
749  return -1;
750 
751  } else if (strncmp(name_array[name_idx], "flow:", 5) == 0) {
752  pd->capids[pd->idx] = VarNameStoreSetupAdd(name_array[name_idx]+5, VAR_TYPE_FLOW_VAR);
753  pd->captypes[pd->idx] = VAR_TYPE_FLOW_VAR;
754  pd->idx++;
755 
756  } else if (strncmp(name_array[name_idx], "pkt:", 4) == 0) {
757  pd->capids[pd->idx] = VarNameStoreSetupAdd(name_array[name_idx]+4, VAR_TYPE_PKT_VAR);
758  pd->captypes[pd->idx] = VAR_TYPE_PKT_VAR;
759  SCLogDebug("id %u type %u", pd->capids[pd->idx], pd->captypes[pd->idx]);
760  pd->idx++;
761 
762  } else {
763  SCLogError(SC_ERR_VAR_LIMIT, " pkt/flow "
764  "var capture names must start with 'pkt:' or 'flow:'");
765  return -1;
766  }
767 
768  name_idx++;
769  if (name_idx >= DETECT_PCRE_CAPTURE_MAX)
770  break;
771  }
772  }
773 
774  /* take the size of the whole input as buffer size for the string we will
775  * extract below. Add 1 to please Coverity's alloc_strlen test. */
776  size_t cap_buffer_len = strlen(regexstr) + 1;
777  char capture_str[cap_buffer_len];
778  memset(capture_str, 0x00, cap_buffer_len);
779 
780  if (de_ctx == NULL)
781  goto error;
782 
783  while (1) {
784  SCLogDebug("\'%s\'", regexstr);
785 
786  ret = pcre_exec(parse_capture_regex.regex, parse_capture_regex.study, regexstr,
787  strlen(regexstr), 0, 0, ov, MAX_SUBSTRINGS);
788  if (ret < 3) {
789  return 0;
790  }
791 
792  res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS, 1, type_str, sizeof(type_str));
793  if (res < 0) {
794  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
795  goto error;
796  }
797  res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS, 2, capture_str, cap_buffer_len);
798  if (res < 0) {
799  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
800  goto error;
801  }
802  if (strlen(capture_str) == 0 || strlen(type_str) == 0) {
803  goto error;
804  }
805 
806  SCLogDebug("type \'%s\'", type_str);
807  SCLogDebug("capture \'%s\'", capture_str);
808 
809  if (pd->idx >= DETECT_PCRE_CAPTURE_MAX) {
810  SCLogError(SC_ERR_VAR_LIMIT, "rule can have maximally %d pkt/flow "
811  "var captures", DETECT_PCRE_CAPTURE_MAX);
812  return -1;
813  }
814 
815  if (strcmp(type_str, "pkt") == 0) {
816  pd->capids[pd->idx] = VarNameStoreSetupAdd((char *)capture_str, VAR_TYPE_PKT_VAR);
817  pd->captypes[pd->idx] = VAR_TYPE_PKT_VAR;
818  SCLogDebug("id %u type %u", pd->capids[pd->idx], pd->captypes[pd->idx]);
819  pd->idx++;
820  } else if (strcmp(type_str, "flow") == 0) {
821  pd->capids[pd->idx] = VarNameStoreSetupAdd((char *)capture_str, VAR_TYPE_FLOW_VAR);
822  pd->captypes[pd->idx] = VAR_TYPE_FLOW_VAR;
823  pd->idx++;
824  }
825 
826  //SCLogNotice("pd->capname %s", pd->capname);
827  regexstr += ov[1];
828 
829  if (regexstr >= orig_right_edge)
830  break;
831  }
832  return 0;
833 
834 error:
835  return -1;
836 }
837 
838 #ifdef PCRE_HAVE_JIT_EXEC
839 static void *DetectPcreThreadInit(void *data /*@unused@*/)
840 {
841  pcre_jit_stack *jit_stack = pcre_jit_stack_alloc(PCRE_JIT_MIN_STACK, PCRE_JIT_MAX_STACK);
842 
843  if (jit_stack == NULL) {
844  SCLogWarning(SC_WARN_PCRE_JITSTACK, "Unable to allocate PCRE JIT stack; will continue without JIT stack");
845  }
846  SCLogDebug("Using jit_stack %p", jit_stack);
847 
848  return (void *)jit_stack;
849 }
850 
851 static void DetectPcreThreadFree(void *ctx)
852 {
853  SCLogDebug("freeing jit_stack %p", ctx);
854  if (ctx != NULL)
855  pcre_jit_stack_free((pcre_jit_stack *)ctx);
856 }
857 
858 #endif
859 static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, const char *regexstr)
860 {
861  SCEnter();
862  DetectPcreData *pd = NULL;
863  SigMatch *sm = NULL;
864  int parsed_sm_list = DETECT_SM_LIST_NOTSET;
865  char capture_names[1024] = "";
866  AppProto alproto = ALPROTO_UNKNOWN;
867 
868  pd = DetectPcreParse(de_ctx, regexstr, &parsed_sm_list,
869  capture_names, sizeof(capture_names), s->init_data->negated,
870  &alproto);
871  if (pd == NULL)
872  goto error;
873  if (DetectPcreParseCapture(regexstr, de_ctx, pd, capture_names) < 0)
874  goto error;
875 
876 #ifdef PCRE_HAVE_JIT_EXEC
877  /* Deliberately silent on failures. Not having a context id means
878  * JIT will be bypassed */
879  pd->thread_ctx_jit_stack_id = DetectRegisterThreadCtxFuncs(de_ctx, "pcre",
880  DetectPcreThreadInit, (void *)pd,
881  DetectPcreThreadFree, 1);
882 #endif
883 
884  int sm_list = -1;
885  if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
886  if (parsed_sm_list != DETECT_SM_LIST_NOTSET && parsed_sm_list != s->init_data->list) {
888  "Expression seen with a sticky buffer still set; either (1) reset sticky "
889  "buffer with pkt_data or (2) use a sticky buffer providing \"%s\".",
890  DetectBufferTypeGetDescriptionById(de_ctx, parsed_sm_list));
891  goto error;
892  }
893  if (DetectBufferGetActiveList(de_ctx, s) == -1)
894  goto error;
895 
896  s->flags |= SIG_FLAG_APPLAYER;
897  sm_list = s->init_data->list;
898  } else {
899  switch (parsed_sm_list) {
901  sm_list = DETECT_SM_LIST_PMATCH;
902  break;
903  default: {
904  if (alproto != ALPROTO_UNKNOWN) {
905  /* see if the proto doesn't conflict
906  * with what we already have. */
907  if (s->alproto != ALPROTO_UNKNOWN &&
908  alproto != s->alproto) {
909  goto error;
910  }
911  if (DetectSignatureSetAppProto(s, alproto) < 0)
912  goto error;
913  }
914  sm_list = parsed_sm_list;
915  break;
916  }
917  }
918  }
919  if (sm_list == -1)
920  goto error;
921 
922  sm = SigMatchAlloc();
923  if (sm == NULL)
924  goto error;
925  sm->type = DETECT_PCRE;
926  sm->ctx = (void *)pd;
927  SigMatchAppendSMToList(s, sm, sm_list);
928 
929  for (uint8_t x = 0; x < pd->idx; x++) {
930  if (DetectFlowvarPostMatchSetup(de_ctx, s, pd->capids[x]) < 0)
931  goto error_nofree;
932  }
933 
934  if (!(pd->flags & DETECT_PCRE_RELATIVE))
935  goto okay;
936 
937  /* errors below shouldn't free pd */
938 
939  SigMatch *prev_pm = DetectGetLastSMByListPtr(s, sm->prev,
941  if (s->init_data->list == DETECT_SM_LIST_NOTSET && prev_pm == NULL) {
942  SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre with /R (relative) needs "
943  "preceding match in the same buffer");
944  goto error_nofree;
945  /* null is allowed when we use a sticky buffer */
946  } else if (prev_pm == NULL) {
947  goto okay;
948  }
949  if (prev_pm->type == DETECT_CONTENT) {
950  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
952  } else if (prev_pm->type == DETECT_PCRE) {
953  DetectPcreData *tmp = (DetectPcreData *)prev_pm->ctx;
955  }
956 
957  okay:
958  SCReturnInt(0);
959  error:
960  DetectPcreFree(de_ctx, pd);
961  error_nofree:
962  SCReturnInt(-1);
963 }
964 
965 static void DetectPcreFree(DetectEngineCtx *de_ctx, void *ptr)
966 {
967  if (ptr == NULL)
968  return;
969 
970  DetectPcreData *pd = (DetectPcreData *)ptr;
972  SCFree(pd);
973 
974  return;
975 }
976 
977 #ifdef UNITTESTS /* UNITTESTS */
978 static int g_file_data_buffer_id = 0;
979 static int g_http_header_buffer_id = 0;
980 static int g_dce_stub_data_buffer_id = 0;
981 
982 /**
983  * \test DetectPcreParseTest01 make sure we don't allow invalid opts 7.
984  */
985 static int DetectPcreParseTest01 (void)
986 {
987  int result = 1;
988  DetectPcreData *pd = NULL;
989  const char *teststring = "/blah/7";
990  int list = DETECT_SM_LIST_NOTSET;
993  AppProto alproto = ALPROTO_UNKNOWN;
994 
995  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
996  FAIL_IF_NOT_NULL(pd);
997 
999  return result;
1000 }
1001 
1002 /**
1003  * \test DetectPcreParseTest02 make sure we don't allow invalid opts Ui$.
1004  */
1005 static int DetectPcreParseTest02 (void)
1006 {
1007  int result = 1;
1008  DetectPcreData *pd = NULL;
1009  const char *teststring = "/blah/Ui$";
1010  int list = DETECT_SM_LIST_NOTSET;
1013  AppProto alproto = ALPROTO_UNKNOWN;
1014 
1015  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1016  FAIL_IF_NOT_NULL(pd);
1017  FAIL_IF_NOT(alproto == ALPROTO_HTTP);
1018 
1020  return result;
1021 }
1022 
1023 /**
1024  * \test DetectPcreParseTest03 make sure we don't allow invalid opts UZi.
1025  */
1026 static int DetectPcreParseTest03 (void)
1027 {
1028  int result = 1;
1029  DetectPcreData *pd = NULL;
1030  const char *teststring = "/blah/UNi";
1031  int list = DETECT_SM_LIST_NOTSET;
1034  AppProto alproto = ALPROTO_UNKNOWN;
1035 
1036  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1037  FAIL_IF_NOT_NULL(pd);
1038 
1040  return result;
1041 }
1042 
1043 /**
1044  * \test DetectPcreParseTest04 make sure we allow escaped "
1045  */
1046 static int DetectPcreParseTest04 (void)
1047 {
1048  int result = 1;
1049  DetectPcreData *pd = NULL;
1050  const char *teststring = "/b\\\"lah/i";
1051  int list = DETECT_SM_LIST_NOTSET;
1054  AppProto alproto = ALPROTO_UNKNOWN;
1055 
1056  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1057  FAIL_IF_NULL(pd);
1058  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1059 
1060  DetectPcreFree(NULL, pd);
1062  return result;
1063 }
1064 
1065 /**
1066  * \test DetectPcreParseTest05 make sure we parse pcre with no opts
1067  */
1068 static int DetectPcreParseTest05 (void)
1069 {
1070  int result = 1;
1071  DetectPcreData *pd = NULL;
1072  const char *teststring = "/b(l|a)h/";
1073  int list = DETECT_SM_LIST_NOTSET;
1076  AppProto alproto = ALPROTO_UNKNOWN;
1077 
1078  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1079  FAIL_IF_NULL(pd);
1080  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1081 
1082  DetectPcreFree(NULL, pd);
1084  return result;
1085 }
1086 
1087 /**
1088  * \test DetectPcreParseTest06 make sure we parse pcre with smi opts
1089  */
1090 static int DetectPcreParseTest06 (void)
1091 {
1092  int result = 1;
1093  DetectPcreData *pd = NULL;
1094  const char *teststring = "/b(l|a)h/smi";
1095  int list = DETECT_SM_LIST_NOTSET;
1098  AppProto alproto = ALPROTO_UNKNOWN;
1099 
1100  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1101  FAIL_IF_NULL(pd);
1102  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1103 
1104  DetectPcreFree(NULL, pd);
1106  return result;
1107 }
1108 
1109 /**
1110  * \test DetectPcreParseTest07 make sure we parse pcre with /Ui opts
1111  */
1112 static int DetectPcreParseTest07 (void)
1113 {
1114  int result = 1;
1115  DetectPcreData *pd = NULL;
1116  const char *teststring = "/blah/Ui";
1117  int list = DETECT_SM_LIST_NOTSET;
1120  AppProto alproto = ALPROTO_UNKNOWN;
1121 
1122  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1123  FAIL_IF_NULL(pd);
1124  FAIL_IF_NOT(alproto == ALPROTO_HTTP);
1125 
1126  DetectPcreFree(NULL, pd);
1128  return result;
1129 }
1130 
1131 /**
1132  * \test DetectPcreParseTest08 make sure we parse pcre with O opts
1133  */
1134 static int DetectPcreParseTest08 (void)
1135 {
1136  int result = 1;
1137  DetectPcreData *pd = NULL;
1138  const char *teststring = "/b(l|a)h/O";
1139  int list = DETECT_SM_LIST_NOTSET;
1142  AppProto alproto = ALPROTO_UNKNOWN;
1143 
1144  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1145  FAIL_IF_NULL(pd);
1146  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1147 
1148  DetectPcreFree(NULL, pd);
1150  return result;
1151 }
1152 
1153 /**
1154  * \test DetectPcreParseTest09 make sure we parse pcre with a content
1155  * that has slashes
1156  */
1157 static int DetectPcreParseTest09 (void)
1158 {
1159  DetectPcreData *pd = NULL;
1160  const char *teststring = "/lala\\\\/";
1161  int list = DETECT_SM_LIST_NOTSET;
1164  AppProto alproto = ALPROTO_UNKNOWN;
1165 
1166  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1167  FAIL_IF_NULL(pd);
1168 
1169  DetectPcreFree(NULL, pd);
1171  PASS;
1172 }
1173 
1174 /**
1175  * \test Test pcre option for dce sig(yeah I'm bored of writing test titles).
1176  */
1177 static int DetectPcreParseTest10(void)
1178 {
1179  Signature *s = SigAlloc();
1182 
1184 
1185  FAIL_IF_NOT(DetectPcreSetup(de_ctx, s, "/bamboo/") == 0);
1186  FAIL_IF_NOT(s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
1187 
1188  SigFree(de_ctx, s);
1189 
1190  s = SigAlloc();
1191  FAIL_IF_NULL(s);
1192 
1193  /* failure since we have no preceding content/pcre/bytejump */
1194  FAIL_IF_NOT(DetectPcreSetup(de_ctx, s, "/bamboo/") == 0);
1195  FAIL_IF_NOT(s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
1196 
1197  SigFree(de_ctx, s);
1199 
1200  PASS;
1201 }
1202 
1203 /**
1204  * \test Test pcre option for dce sig.
1205  */
1206 static int DetectPcreParseTest11(void)
1207 {
1208  DetectEngineCtx *de_ctx = NULL;
1209  Signature *s = NULL;
1210  DetectPcreData *data = NULL;
1211 
1214 
1215  de_ctx->flags |= DE_QUIET;
1216  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1217  "(msg:\"Testing bytejump_body\"; "
1218  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1219  "dce_stub_data; "
1220  "pcre:/bamboo/R; sid:1;)");
1221  FAIL_IF(de_ctx == NULL);
1222  s = de_ctx->sig_list;
1223  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1224  FAIL_IF_NOT(s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_PCRE);
1225  data = (DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1227  !(data->flags & DETECT_PCRE_RELATIVE));
1228 
1229  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1230  "(msg:\"Testing bytejump_body\"; "
1231  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1232  "dce_stub_data; "
1233  "pcre:/bamboo/R; sid:1;)");
1234  FAIL_IF_NULL(s->next);
1235  s = s->next;
1236  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1237  FAIL_IF_NOT(s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_PCRE);
1238  data = (DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1240  !(data->flags & DETECT_PCRE_RELATIVE));
1241 
1242  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1243  "(msg:\"Testing bytejump_body\"; "
1244  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1245  "dce_stub_data; "
1246  "pcre:/bamboo/RB; sid:1;)");
1247  FAIL_IF(s->next == NULL);
1248  s = s->next;
1249  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1250  FAIL_IF_NOT(s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_PCRE);
1251  data = (DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1252  FAIL_IF(!(data->flags & DETECT_PCRE_RAWBYTES) ||
1253  !(data->flags & DETECT_PCRE_RELATIVE));
1254 
1255  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1256  "(msg:\"Testing bytejump_body\"; "
1257  "content:\"one\"; pcre:/bamboo/; sid:1;)");
1258  FAIL_IF(s->next == NULL);
1259  s = s->next;
1260  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] != NULL);
1261 
1265 
1266  PASS;
1267 }
1268 
1269 /**
1270  * \test Test pcre option with file data. pcre is relative to file_data,
1271  * so relative flag should be unset.
1272  */
1273 static int DetectPcreParseTest12(void)
1274 {
1275  DetectEngineCtx *de_ctx = NULL;
1276  Signature *s = NULL;
1277  DetectPcreData *data = NULL;
1278 
1281 
1282  de_ctx->flags |= DE_QUIET;
1283  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1284  "(file_data; pcre:/abc/R; sid:1;)");
1285  FAIL_IF (de_ctx->sig_list == NULL);
1286 
1287  s = de_ctx->sig_list;
1288  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1289 
1290  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_PCRE);
1291 
1292  data = (DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1294  !(data->flags & DETECT_PCRE_RELATIVE));
1295 
1299 
1300  PASS;
1301 }
1302 
1303 /**
1304  * \test Test pcre option with file data.
1305  */
1306 static int DetectPcreParseTest13(void)
1307 {
1308  DetectEngineCtx *de_ctx = NULL;
1309  Signature *s = NULL;
1310  DetectPcreData *data = NULL;
1311 
1314 
1315  de_ctx->flags |= DE_QUIET;
1316  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1317  "(file_data; content:\"abc\"; pcre:/def/R; sid:1;)");
1318  FAIL_IF(de_ctx->sig_list == NULL);
1319 
1320  s = de_ctx->sig_list;
1321  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1322 
1323  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_PCRE);
1324 
1325  data = (DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1327  !(data->flags & DETECT_PCRE_RELATIVE));
1328 
1332 
1333  PASS;
1334 }
1335 
1336 /**
1337  * \test Test pcre option with file data.
1338  */
1339 static int DetectPcreParseTest14(void)
1340 {
1341  DetectEngineCtx *de_ctx = NULL;
1342  Signature *s = NULL;
1343  DetectPcreData *data = NULL;
1344 
1346  FAIL_IF(de_ctx == NULL);
1347 
1348  de_ctx->flags |= DE_QUIET;
1349  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1350  "(file_data; pcre:/def/; sid:1;)");
1351  FAIL_IF(de_ctx->sig_list == NULL);
1352 
1353  s = de_ctx->sig_list;
1354  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1355 
1356  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_PCRE);
1357 
1358  data = (DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1360  data->flags & DETECT_PCRE_RELATIVE);
1361 
1365 
1366  PASS;
1367 }
1368 
1369 /** \test Check a signature with pcre relative method */
1370 static int DetectPcreParseTest15(void)
1371 {
1372  DetectEngineCtx *de_ctx = NULL;
1373 
1374  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1375 
1376  de_ctx->flags |= DE_QUIET;
1378  "alert tcp any any -> any any "
1379  "(msg:\"Testing pcre relative http_method\"; "
1380  "content:\"GET\"; "
1381  "http_method; pcre:\"/abc/RM\"; sid:1;)");
1383 
1384  if (de_ctx != NULL)
1386  if (de_ctx != NULL)
1388  PASS;
1389 }
1390 
1391 
1392 /** \test Check a signature with pcre relative cookie */
1393 static int DetectPcreParseTest16(void)
1394 {
1395  DetectEngineCtx *de_ctx = NULL;
1396 
1397  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1398 
1399  de_ctx->flags |= DE_QUIET;
1401  "alert tcp any any -> any any "
1402  "(msg:\"Testing pcre relative http_cookie\"; "
1403  "content:\"test\"; "
1404  "http_cookie; pcre:\"/abc/RC\"; sid:1;)");
1406 
1407  if (de_ctx != NULL)
1409  if (de_ctx != NULL)
1411  PASS;
1412 }
1413 
1414 /** \test Check a signature with pcre relative raw header */
1415 static int DetectPcreParseTest17(void)
1416 {
1417  DetectEngineCtx *de_ctx = NULL;
1418 
1419  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1420 
1421  de_ctx->flags |= DE_QUIET;
1423  "alert tcp any any -> any any "
1424  "(msg:\"Testing pcre relative http_raw_header\"; "
1425  "flow:to_server; content:\"test\"; "
1426  "http_raw_header; pcre:\"/abc/RD\"; sid:1;)");
1428 
1429  if (de_ctx != NULL)
1431  if (de_ctx != NULL)
1433  PASS;
1434 }
1435 
1436 /** \test Check a signature with pcre relative header */
1437 static int DetectPcreParseTest18(void)
1438 {
1439  DetectEngineCtx *de_ctx = NULL;
1440 
1441  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1442 
1443  de_ctx->flags |= DE_QUIET;
1445  "alert tcp any any -> any any "
1446  "(msg:\"Testing pcre relative http_header\"; "
1447  "content:\"test\"; "
1448  "http_header; pcre:\"/abc/RH\"; sid:1;)");
1450 
1451  if (de_ctx != NULL)
1453  if (de_ctx != NULL)
1455  PASS;
1456 }
1457 
1458 /** \test Check a signature with pcre relative client-body */
1459 static int DetectPcreParseTest19(void)
1460 {
1461  DetectEngineCtx *de_ctx = NULL;
1462 
1463  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1464 
1465  de_ctx->flags |= DE_QUIET;
1467  "alert tcp any any -> any any "
1468  "(msg:\"Testing pcre relative http_client_body\"; "
1469  "content:\"test\"; "
1470  "http_client_body; pcre:\"/abc/RP\"; sid:1;)");
1472 
1473  if (de_ctx != NULL)
1475  if (de_ctx != NULL)
1477  PASS;
1478 }
1479 
1480 /** \test Check a signature with pcre relative raw uri */
1481 static int DetectPcreParseTest20(void)
1482 {
1483  DetectEngineCtx *de_ctx = NULL;
1484 
1485  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1486 
1487  de_ctx->flags |= DE_QUIET;
1489  "alert tcp any any -> any any "
1490  "(msg:\"Testing http_raw_uri\"; "
1491  "content:\"test\"; "
1492  "http_raw_uri; pcre:\"/abc/RI\"; sid:1;)");
1494 
1495  if (de_ctx != NULL)
1497  if (de_ctx != NULL)
1499  PASS;
1500 }
1501 
1502 /** \test Check a signature with pcre relative uricontent */
1503 static int DetectPcreParseTest21(void)
1504 {
1505  DetectEngineCtx *de_ctx = NULL;
1506 
1507  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1508 
1509  de_ctx->flags |= DE_QUIET;
1511  "alert tcp any any -> any any "
1512  "(msg:\"Testing pcre relative uricontent\"; "
1513  "uricontent:\"test\"; "
1514  "pcre:\"/abc/RU\"; sid:1;)");
1516 
1517  if (de_ctx != NULL)
1519  if (de_ctx != NULL)
1521  PASS;
1522 }
1523 
1524 /** \test Check a signature with pcre relative http_uri */
1525 static int DetectPcreParseTest22(void)
1526 {
1527  DetectEngineCtx *de_ctx = NULL;
1528 
1529  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1530 
1531  de_ctx->flags |= DE_QUIET;
1533  "alert tcp any any -> any any "
1534  "(msg:\"Testing pcre relative http_uri\"; "
1535  "content:\"test\"; "
1536  "http_uri; pcre:\"/abc/RU\"; sid:1;)");
1538 
1539  if (de_ctx != NULL)
1541  if (de_ctx != NULL)
1543  PASS;
1544 }
1545 
1546 /** \test Check a signature with inconsistent pcre relative */
1547 static int DetectPcreParseTest23(void)
1548 {
1549  DetectEngineCtx *de_ctx = NULL;
1550 
1551  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1552 
1553  de_ctx->flags |= DE_QUIET;
1555  "alert tcp any any -> any any "
1556  "(msg:\"Testing inconsistent pcre relative\"; "
1557  "content:\"GET\"; "
1558  "http_cookie; pcre:\"/abc/RM\"; sid:1;)");
1560 
1561  if (de_ctx != NULL)
1563  if (de_ctx != NULL)
1565  PASS;
1566 }
1567 
1568 /** \test Check a signature with inconsistent pcre modifiers */
1569 static int DetectPcreParseTest24(void)
1570 {
1571  DetectEngineCtx *de_ctx = NULL;
1572 
1573  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1574 
1575  de_ctx->flags |= DE_QUIET;
1577  "alert tcp any any -> any any "
1578  "(msg:\"Testing inconsistent pcre modifiers\"; "
1579  "pcre:\"/abc/UI\"; sid:1;)");
1581 
1582  if (de_ctx != NULL)
1584  if (de_ctx != NULL)
1586  PASS;
1587 }
1588 
1589 /** \test Check a signature with inconsistent pcre modifiers */
1590 static int DetectPcreParseTest25(void)
1591 {
1592  DetectEngineCtx *de_ctx = NULL;
1593 
1594  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1595 
1596  de_ctx->flags |= DE_QUIET;
1598  "alert tcp any any -> any any "
1599  "(msg:\"Testing inconsistent pcre modifiers\"; "
1600  "pcre:\"/abc/DH\"; sid:1;)");
1602 
1603  if (de_ctx != NULL)
1605  if (de_ctx != NULL)
1607  PASS;
1608 }
1609 
1610 /** \test Check a signature with inconsistent pcre modifiers */
1611 static int DetectPcreParseTest26(void)
1612 {
1613  DetectEngineCtx *de_ctx = NULL;
1614 
1615  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1616 
1617  de_ctx->flags |= DE_QUIET;
1619  "alert http any any -> any any "
1620  "(msg:\"Testing inconsistent pcre modifiers\"; "
1621  "pcre:\"/abc/F\"; sid:1;)");
1623 
1624  if (de_ctx != NULL)
1626  if (de_ctx != NULL)
1628  PASS;
1629 }
1630 
1631 /** \test Bug 1098 */
1632 static int DetectPcreParseTest27(void)
1633 {
1634  DetectEngineCtx *de_ctx = NULL;
1635 
1636  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1637 
1638  de_ctx->flags |= DE_QUIET;
1639  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any 80 "
1640  "(content:\"baduricontent\"; http_raw_uri; "
1641  "pcre:\"/^[a-z]{5}\\.html/R\"; sid:2; rev:2;)");
1642  FAIL_IF_NOT(de_ctx->sig_list == NULL);
1643 
1644  if (de_ctx != NULL)
1646  if (de_ctx != NULL)
1648  PASS;
1649 }
1650 
1651 /** \test Bug 1957 */
1652 static int DetectPcreParseTest28(void)
1653 {
1654  DetectEngineCtx *de_ctx = NULL;
1655 
1656  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1657 
1658  de_ctx->flags |= DE_QUIET;
1659  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any 80 "
1660  "(content:\"|2E|suricata\"; http_host; pcre:\"/\\x2Esuricata$/W\"; "
1661  "sid:2; rev:2;)");
1663 
1665  PASS;
1666 }
1667 
1668 static int DetectPcreTestSig01(void)
1669 {
1670  uint8_t *buf = (uint8_t *)
1671  "GET /one/ HTTP/1.1\r\n"
1672  "Host: one.example.org\r\n"
1673  "\r\n\r\n"
1674  "GET /two/ HTTP/1.1\r\n"
1675  "Host: two.example.org\r\n"
1676  "\r\n\r\n";
1677  uint16_t buflen = strlen((char *)buf);
1678  Packet *p = NULL;
1679  ThreadVars th_v;
1680  DetectEngineThreadCtx *det_ctx = NULL;
1682 
1683  memset(&th_v, 0, sizeof(th_v));
1684 
1686 
1687  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1688  FAIL_IF_NULL(p);
1689  p->tcph->th_seq = htonl(1000);
1690  Flow *f = UTHBuildFlow(AF_INET, "192.168.1.5", "192.168.1.1", 41424, 80);
1691  FAIL_IF_NULL(f);
1692  f->proto = IPPROTO_TCP;
1693  UTHAddSessionToFlow(f, 1000, 1000);
1694  UTHAddStreamToFlow(f, 0, buf, buflen);
1695 
1696  p->flow = f;
1700  f->alproto = ALPROTO_HTTP;
1702  FAIL_IF(de_ctx == NULL);
1703 
1704  de_ctx->flags |= DE_QUIET;
1705 
1706  de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/^gEt/i\"; pcre:\"/\\/two\\//U\"; pcre:\"/GET \\/two\\//\"; pcre:\"/\\s+HTTP/R\"; sid:1;)");
1707  FAIL_IF(de_ctx->sig_list == NULL);
1708 
1710  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1711 
1712  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP,
1713  STREAM_TOSERVER | STREAM_START, buf, buflen);
1714  FAIL_IF(r != 0);
1715 
1716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1717  FAIL_IF_NOT(PacketAlertCheck(p, 1) == 1);
1718 
1720  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1722 
1724  UTHFreeFlow(f);
1725 
1727  UTHFreePackets(&p, 1);
1728  PASS;
1729 }
1730 
1731 static int DetectPcreTestSig02(void)
1732 {
1733  uint8_t *buf = (uint8_t *)
1734  "GET /one/ HTTP/1.1\r\n"
1735  "Host: one.example.org\r\n"
1736  "\r\n\r\n"
1737  "GET /two/ HTTP/1.1\r\n"
1738  "Host: two.example.org\r\n"
1739  "\r\n\r\n";
1740  uint16_t buflen = strlen((char *)buf);
1741  Packet *p = NULL;
1742  Flow f;
1743  ThreadVars th_v;
1744  DetectEngineThreadCtx *det_ctx;
1745 
1746  memset(&th_v, 0, sizeof(th_v));
1747  memset(&f, 0, sizeof(f));
1748 
1749  FLOW_INITIALIZE(&f);
1750 
1751  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1752  p->flow = &f;
1754 
1755  pcre_match_limit = 100;
1756  pcre_match_limit_recursion = 100;
1757 
1759  FAIL_IF(de_ctx == NULL);
1760 
1761  de_ctx->flags |= DE_QUIET;
1762 
1763  de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/two/O\"; sid:2;)");
1764  FAIL_IF(de_ctx->sig_list == NULL);
1765 
1767  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1768 
1769  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1770  FAIL_IF_NOT(PacketAlertCheck(p, 2) == 1);
1771 
1774 
1775  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1777  FLOW_DESTROY(&f);
1778 
1779  UTHFreePackets(&p, 1);
1780  PASS;
1781 }
1782 
1783 /**
1784  * \test DetectPcreTestSig03Real negation test ! outside of "" this sig should not match
1785  */
1786 static int DetectPcreTestSig03(void)
1787 {
1788  uint8_t *buf = (uint8_t *)
1789  "GET /one/ HTTP/1.1\r\n"
1790  "Host: one.example.org\r\n"
1791  "\r\n\r\n"
1792  "GET /two/ HTTP/1.1\r\n"
1793  "Host: two.example.org\r\n"
1794  "\r\n\r\n";
1795  uint16_t buflen = strlen((char *)buf);
1796  Packet *p = NULL;
1797  ThreadVars th_v;
1798  DetectEngineThreadCtx *det_ctx;
1799 
1800  memset(&th_v, 0, sizeof(th_v));
1801 
1802  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1803 
1805  FAIL_IF(de_ctx == NULL);
1806 
1807  de_ctx->flags |= DE_QUIET;
1808 
1809  de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"GET\"; pcre:!\"/two/\"; sid:1;)");
1810  FAIL_IF(de_ctx->sig_list == NULL);
1811 
1813  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1814 
1815  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1816  FAIL_IF(PacketAlertCheck(p, 1));
1819 
1820  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1822 
1823  UTHFreePackets(&p, 1);
1824  PASS;
1825 }
1826 
1827 /**
1828  * \test Check the signature with pcre modifier P (match with L7 to http body data)
1829  */
1830 static int DetectPcreModifPTest04(void)
1831 {
1832  uint8_t httpbuf1[] =
1833  "GET / HTTP/1.1\r\n"
1834  "Host: www.emergingthreats.net\r\n"
1835  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
1836  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
1837  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
1838  "Accept-Encoding: gzip,deflate\r\n"
1839  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
1840  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1841  "Server: Apache\r\n"
1842  "X-Powered-By: PHP/5.2.5\r\n"
1843  "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n"
1844  "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n"
1845  "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1846  "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
1847  "Pragma: no-cache\r\n"
1848  "Keep-Alive: timeout=15, max=100\r\n"
1849  "Connection: Keep-Alive\r\n"
1850  "Transfer-Encoding: chunked\r\n"
1851  "Content-Type: text/html; charset=utf-8\r\n"
1852  "\r\n"
1853  "15"
1854  "\r\n"
1855  "<!DOCTYPE html PUBLIC\r\n"
1856  "0\r\n\r\n";
1857 
1858  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1859  TcpSession ssn;
1860  Packet *p = NULL;
1861  Flow f;
1862  Signature *s = NULL;
1863  ThreadVars th_v;
1864  DetectEngineThreadCtx *det_ctx;
1866 
1867  memset(&th_v, 0, sizeof(th_v));
1868  memset(&f, 0, sizeof(f));
1869  memset(&ssn, 0, sizeof(ssn));
1870 
1871  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1872 
1873  FLOW_INITIALIZE(&f);
1874  f.protoctx = (void *)&ssn;
1875  f.proto = IPPROTO_TCP;
1876  f.flags |= FLOW_IPV4;
1877 
1878  p->flow = &f;
1882  f.alproto = ALPROTO_HTTP;
1883 
1885 
1887  FAIL_IF(de_ctx == NULL);
1888 
1889  de_ctx->flags |= DE_QUIET;
1890 
1891  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
1892  "\"Pcre modifier P\"; pcre:\"/DOCTYPE/P\"; "
1893  "sid:1;)");
1894  FAIL_IF(s == NULL);
1895 
1896  s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\""
1897  "Pcre modifier P (no match)\"; pcre:\"/blah/P\"; sid:2;)");
1898  FAIL_IF(s->next == NULL);
1899 
1901  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1902 
1903  FLOWLOCK_WRLOCK(&f);
1904  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1905  STREAM_TOSERVER, httpbuf1, httplen1);
1906  FAIL_IF(r != 0);
1907  FLOWLOCK_UNLOCK(&f);
1908 
1909  HtpState *http_state = f.alstate;
1910  FAIL_IF(http_state == NULL);
1911 
1912  /* do detect */
1913  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1914 
1915  FAIL_IF(!(PacketAlertCheck(p, 1)));
1916  FAIL_IF(PacketAlertCheck(p, 2));
1917 
1918  if (alp_tctx != NULL)
1920  if (de_ctx != NULL) SigGroupCleanup(de_ctx);
1921  if (de_ctx != NULL) SigCleanSignatures(de_ctx);
1922  if (de_ctx != NULL) DetectEngineCtxFree(de_ctx);
1923 
1925  FLOW_DESTROY(&f);
1926  UTHFreePackets(&p, 1);
1927  PASS;
1928 }
1929 
1930 /**
1931  * \test Check the signature with pcre modifier P (match with L7 to http body data)
1932  * over fragmented chunks (DOCTYPE fragmented)
1933  */
1934 static int DetectPcreModifPTest05(void)
1935 {
1936  uint8_t httpbuf1[] =
1937  "GET / HTTP/1.1\r\n"
1938  "Host: www.emergingthreats.net\r\n"
1939  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
1940  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
1941  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
1942  "Accept-Encoding: gzip,deflate\r\n"
1943  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
1944  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1945  "Server: Apache\r\n"
1946  "X-Powered-By: PHP/5.2.5\r\n"
1947  "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n"
1948  "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n"
1949  "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1950  "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
1951  "Pragma: no-cache\r\n"
1952  "Keep-Alive: timeout=15, max=100\r\n"
1953  "Connection: Keep-Alive\r\n"
1954  "Transfer-Encoding: chunked\r\n"
1955  "Content-Type: text/html; charset=utf-8\r\n"
1956  "\r\n"
1957  "15"
1958  "\r\n"
1959  "<!DOC";
1960 
1961  uint8_t httpbuf2[] = "<!DOCTYPE html PUBLIC\r\n0\r\n\r\n";
1962 
1963  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1964  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1965  TcpSession ssn;
1966  Packet *p1 = NULL;
1967  Packet *p2 = NULL;
1968  Flow f;
1969  Signature *s = NULL;
1970  ThreadVars th_v;
1971  DetectEngineThreadCtx *det_ctx;
1973 
1974  memset(&th_v, 0, sizeof(th_v));
1975  memset(&f, 0, sizeof(f));
1976  memset(&ssn, 0, sizeof(ssn));
1977 
1978  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1979  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1980 
1981  FLOW_INITIALIZE(&f);
1982  f.protoctx = (void *)&ssn;
1983  f.proto = IPPROTO_TCP;
1984  f.flags |= FLOW_IPV4;
1985 
1986  p1->flow = &f;
1990  p2->flow = &f;
1994  f.alproto = ALPROTO_HTTP;
1995 
1997 
1999  FAIL_IF(de_ctx == NULL);
2000 
2001  de_ctx->flags |= DE_QUIET;
2002 
2003  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2004  "\"Pcre modifier P\"; pcre:\"/DOC/P\"; "
2005  "sid:1;)");
2006  FAIL_IF(s == NULL);
2007 
2008  s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\""
2009  "Pcre modifier P (no match)\"; pcre:\"/DOCTYPE/P\"; sid:2;)");
2010  FAIL_IF(s->next == NULL);
2011 
2013  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2014 
2015  FLOWLOCK_WRLOCK(&f);
2016  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2017  STREAM_TOSERVER, httpbuf1, httplen1);
2018  FAIL_IF(r != 0);
2019  FLOWLOCK_UNLOCK(&f);
2020 
2021  /* do detect for p1 */
2022  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2023 
2024  HtpState *http_state = f.alstate;
2025  FAIL_IF(http_state == NULL);
2026 
2027  FAIL_IF(PacketAlertCheck(p1, 1));
2028 
2029  FAIL_IF(PacketAlertCheck(p1, 2));
2030 
2031  FLOWLOCK_WRLOCK(&f);
2032  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2033  STREAM_TOSERVER, httpbuf2, httplen2);
2034  FAIL_IF(r != 0);
2035  FLOWLOCK_UNLOCK(&f);
2036 
2037  /* do detect for p2 */
2038  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2039 
2040  FAIL_IF(!(PacketAlertCheck(p2, 1)));
2041 
2042  FAIL_IF(!(PacketAlertCheck(p2, 2)));
2043 
2044  if (alp_tctx != NULL)
2046  if (de_ctx != NULL) SigGroupCleanup(de_ctx);
2047  if (de_ctx != NULL) SigCleanSignatures(de_ctx);
2048  if (de_ctx != NULL) DetectEngineCtxFree(de_ctx);
2049 
2051  FLOW_DESTROY(&f);
2052  UTHFreePackets(&p1, 1);
2053  UTHFreePackets(&p2, 1);
2054  PASS;
2055 }
2056 
2057 static int DetectPcreTestSig06(void)
2058 {
2059  uint8_t *buf = (uint8_t *)
2060  "lalala lalala\\ lala\n";
2061  uint16_t buflen = strlen((char *)buf);
2062  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
2063  int result = 0;
2064 
2065  char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/ lalala\\\\/\"; sid:1;)";
2066  if (UTHPacketMatchSig(p, sig) == 0) {
2067  result = 0;
2068  goto end;
2069  }
2070  result = 1;
2071 end:
2072  if (p != NULL)
2073  UTHFreePacket(p);
2074  return result;
2075 }
2076 
2077 /** \test anchored pcre */
2078 static int DetectPcreTestSig07(void)
2079 {
2080  uint8_t *buf = (uint8_t *)
2081  "lalala\n";
2082  uint16_t buflen = strlen((char *)buf);
2083  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
2084 
2085  char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)";
2086  FAIL_IF(UTHPacketMatchSig(p, sig) == 0);
2087 
2088  if (p != NULL)
2089  UTHFreePacket(p);
2090  PASS;
2091 }
2092 
2093 /** \test anchored pcre */
2094 static int DetectPcreTestSig08(void)
2095 {
2096  /* test it also without ending in a newline "\n" */
2097  uint8_t *buf = (uint8_t *)
2098  "lalala";
2099  uint16_t buflen = strlen((char *)buf);
2100  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
2101 
2102  char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)";
2103  FAIL_IF(UTHPacketMatchSig(p, sig) == 0);
2104 
2105  if (p != NULL)
2106  UTHFreePacket(p);
2107  PASS;
2108 }
2109 
2110 /** \test Check the signature working to alert when cookie modifier is
2111  * passed to pcre
2112  */
2113 static int DetectPcreTestSig09(void)
2114 {
2115  Flow f;
2116  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2117  "Cookie: dummy\r\n\r\n";
2118  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2119  TcpSession ssn;
2120  Packet *p = NULL;
2121  Signature *s = NULL;
2122  ThreadVars th_v;
2123  DetectEngineThreadCtx *det_ctx = NULL;
2124  HtpState *http_state = NULL;
2126 
2127  memset(&th_v, 0, sizeof(th_v));
2128  memset(&p, 0, sizeof(p));
2129  memset(&f, 0, sizeof(f));
2130  memset(&ssn, 0, sizeof(ssn));
2131 
2132  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2133 
2134  FLOW_INITIALIZE(&f);
2135  f.protoctx = (void *)&ssn;
2136  f.proto = IPPROTO_TCP;
2137  f.flags |= FLOW_IPV4;
2138 
2139  p->flow = &f;
2143  f.alproto = ALPROTO_HTTP;
2144 
2146 
2148  FAIL_IF(de_ctx == NULL);
2149 
2150  de_ctx->flags |= DE_QUIET;
2151 
2152  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2153  "\"HTTP cookie\"; pcre:\"/dummy/C\"; "
2154  " sid:1;)");
2155  FAIL_IF(s == NULL);
2156 
2158  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2159 
2160  FLOWLOCK_WRLOCK(&f);
2161  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2162  STREAM_TOSERVER, httpbuf1, httplen1);
2163  FAIL_IF(r != 0);
2164  FLOWLOCK_UNLOCK(&f);
2165 
2166  http_state = f.alstate;
2167  FAIL_IF(http_state == NULL);
2168 
2169  /* do detect */
2170  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2171 
2172  FAIL_IF(!PacketAlertCheck(p, 1));
2173 
2174  if (alp_tctx != NULL)
2176  if (det_ctx != NULL) {
2177  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2178  }
2179  if (de_ctx != NULL) {
2182  }
2183 
2185  UTHFreePackets(&p, 1);
2186  PASS;
2187 }
2188 
2189 /** \test Check the signature working to alert when cookie modifier is
2190  * passed to a negated pcre
2191  */
2192 static int DetectPcreTestSig10(void)
2193 {
2194  Flow f;
2195  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2196  "Cookie: dummoOOooooO\r\n\r\n";
2197  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2198  TcpSession ssn;
2199  Packet *p = NULL;
2200  Signature *s = NULL;
2201  ThreadVars th_v;
2202  DetectEngineThreadCtx *det_ctx = NULL;
2203  HtpState *http_state = NULL;
2205 
2206  memset(&th_v, 0, sizeof(th_v));
2207  memset(&p, 0, sizeof(p));
2208  memset(&f, 0, sizeof(f));
2209  memset(&ssn, 0, sizeof(ssn));
2210 
2211  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2212 
2213  FLOW_INITIALIZE(&f);
2214  f.protoctx = (void *)&ssn;
2215  f.proto = IPPROTO_TCP;
2216  f.flags |= FLOW_IPV4;
2217 
2218  p->flow = &f;
2222  f.alproto = ALPROTO_HTTP;
2223 
2225 
2227  FAIL_IF(de_ctx == NULL);
2228 
2229  de_ctx->flags |= DE_QUIET;
2230 
2231  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2232  "\"HTTP cookie\"; pcre:!\"/dummy/C\"; "
2233  " sid:1;)");
2234  FAIL_IF(s == NULL);
2235 
2237  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2238 
2239  FLOWLOCK_WRLOCK(&f);
2240  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2241  STREAM_TOSERVER, httpbuf1, httplen1);
2242  FAIL_IF(r != 0);
2243  FLOWLOCK_UNLOCK(&f);
2244 
2245  http_state = f.alstate;
2246  FAIL_IF(http_state == NULL);
2247 
2248  /* do detect */
2249  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2250 
2251  FAIL_IF(!PacketAlertCheck(p, 1));
2252 
2253  if (alp_tctx != NULL)
2255  if (det_ctx != NULL) {
2256  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2257  }
2258  if (de_ctx != NULL) {
2261  }
2262 
2264  UTHFreePackets(&p, 1);
2265  PASS;
2266 }
2267 
2268 /** \test Check the signature working to alert when method modifier is
2269  * passed to pcre
2270  */
2271 static int DetectPcreTestSig11(void)
2272 {
2273  Flow f;
2274  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2275  "Cookie: dummy\r\n\r\n";
2276  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2277  TcpSession ssn;
2278  Packet *p = NULL;
2279  Signature *s = NULL;
2280  ThreadVars th_v;
2281  DetectEngineThreadCtx *det_ctx = NULL;
2282  HtpState *http_state = NULL;
2284 
2285  memset(&th_v, 0, sizeof(th_v));
2286  memset(&p, 0, sizeof(p));
2287  memset(&f, 0, sizeof(f));
2288  memset(&ssn, 0, sizeof(ssn));
2289 
2290  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2291 
2292  FLOW_INITIALIZE(&f);
2293  f.protoctx = (void *)&ssn;
2294  f.proto = IPPROTO_TCP;
2295  f.flags |= FLOW_IPV4;
2296 
2297  p->flow = &f;
2301  f.alproto = ALPROTO_HTTP;
2302 
2304 
2306  FAIL_IF(de_ctx == NULL);
2307 
2308  de_ctx->flags |= DE_QUIET;
2309 
2310  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2311  "\"HTTP method\"; pcre:\"/POST/M\"; "
2312  " sid:1;)");
2313  FAIL_IF(s == NULL);
2314 
2316  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2317 
2318  FLOWLOCK_WRLOCK(&f);
2319  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2320  STREAM_TOSERVER, httpbuf1, httplen1);
2321  FAIL_IF(r != 0);
2322  FLOWLOCK_UNLOCK(&f);
2323 
2324  http_state = f.alstate;
2325  FAIL_IF(http_state == NULL);
2326 
2327  /* do detect */
2328  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2329 
2330  FAIL_IF(!PacketAlertCheck(p, 1));
2331 
2332  if (alp_tctx != NULL)
2334  if (det_ctx != NULL) {
2335  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2336  }
2337  if (de_ctx != NULL) {
2340  }
2341 
2343  UTHFreePackets(&p, 1);
2344  PASS;
2345 }
2346 
2347 /** \test Check the signature working to alert when method modifier is
2348  * passed to a negated pcre
2349  */
2350 static int DetectPcreTestSig12(void)
2351 {
2352  Flow f;
2353  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2354  "Cookie: dummoOOooooO\r\n\r\n";
2355  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2356  TcpSession ssn;
2357  Packet *p = NULL;
2358  Signature *s = NULL;
2359  ThreadVars th_v;
2360  DetectEngineThreadCtx *det_ctx = NULL;
2361  HtpState *http_state = NULL;
2363 
2364  memset(&th_v, 0, sizeof(th_v));
2365  memset(&p, 0, sizeof(p));
2366  memset(&f, 0, sizeof(f));
2367  memset(&ssn, 0, sizeof(ssn));
2368 
2369  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2370 
2371  FLOW_INITIALIZE(&f);
2372  f.protoctx = (void *)&ssn;
2373  f.proto = IPPROTO_TCP;
2374  f.flags |= FLOW_IPV4;
2375 
2376  p->flow = &f;
2380  f.alproto = ALPROTO_HTTP;
2381 
2383 
2385  FAIL_IF(de_ctx == NULL);
2386 
2387  de_ctx->flags |= DE_QUIET;
2388 
2389  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2390  "\"HTTP method\"; pcre:!\"/POST/M\"; "
2391  " sid:1;)");
2392  FAIL_IF(s == NULL);
2393 
2395  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2396 
2397  FLOWLOCK_WRLOCK(&f);
2398  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2399  STREAM_TOSERVER, httpbuf1, httplen1);
2400  FAIL_IF(r != 0);
2401  FLOWLOCK_UNLOCK(&f);
2402 
2403  http_state = f.alstate;
2404  FAIL_IF(http_state == NULL);
2405 
2406  /* do detect */
2407  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2408 
2409  FAIL_IF(!PacketAlertCheck(p, 1));
2410 
2411  if (alp_tctx != NULL)
2413  if (det_ctx != NULL) {
2414  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2415  }
2416  if (de_ctx != NULL) {
2419  }
2420 
2422  UTHFreePackets(&p, 1);
2423  PASS;
2424 }
2425 
2426 /** \test Check the signature working to alert when header modifier is
2427  * passed to pcre
2428  */
2429 static int DetectPcreTestSig13(void)
2430 {
2431  Flow f;
2432  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2433  "Cookie: dummy\r\n\r\n";
2434  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2435  TcpSession ssn;
2436  Packet *p = NULL;
2437  Signature *s = NULL;
2438  ThreadVars th_v;
2439  DetectEngineThreadCtx *det_ctx = NULL;
2440  HtpState *http_state = NULL;
2442 
2443  memset(&th_v, 0, sizeof(th_v));
2444  memset(&p, 0, sizeof(p));
2445  memset(&f, 0, sizeof(f));
2446  memset(&ssn, 0, sizeof(ssn));
2447 
2448  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2449 
2450  FLOW_INITIALIZE(&f);
2451  f.protoctx = (void *)&ssn;
2452  f.proto = IPPROTO_TCP;
2453  f.flags |= FLOW_IPV4;
2454 
2455  p->flow = &f;
2459  f.alproto = ALPROTO_HTTP;
2460 
2462 
2464  FAIL_IF(de_ctx == NULL);
2465 
2466  de_ctx->flags |= DE_QUIET;
2467 
2468  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2469  "\"HTTP header\"; pcre:\"/User[-_]Agent[:]?\\sMozilla/H\"; "
2470  " sid:1;)");
2471  FAIL_IF(s == NULL);
2472 
2474  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2475 
2476  FLOWLOCK_WRLOCK(&f);
2477  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2478  STREAM_TOSERVER, httpbuf1, httplen1);
2479  FAIL_IF(r != 0);
2480  FLOWLOCK_UNLOCK(&f);
2481 
2482  http_state = f.alstate;
2483  FAIL_IF(http_state == NULL);
2484 
2485  /* do detect */
2486  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2487 
2488  FAIL_IF(!PacketAlertCheck(p, 1));
2489 
2490  if (alp_tctx != NULL)
2492  if (det_ctx != NULL) {
2493  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2494  }
2495  if (de_ctx != NULL) {
2498  }
2499 
2501  UTHFreePackets(&p, 1);
2502  PASS;
2503 }
2504 
2505 /** \test Check the signature working to alert when header modifier is
2506  * passed to a negated pcre
2507  */
2508 static int DetectPcreTestSig14(void)
2509 {
2510  Flow f;
2511  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: IEXPLORER/1.0\r\n"
2512  "Cookie: dummoOOooooO\r\n\r\n";
2513  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2514  TcpSession ssn;
2515  Packet *p = NULL;
2516  Signature *s = NULL;
2517  ThreadVars th_v;
2518  DetectEngineThreadCtx *det_ctx = NULL;
2519  HtpState *http_state = NULL;
2521 
2522  memset(&th_v, 0, sizeof(th_v));
2523  memset(&p, 0, sizeof(p));
2524  memset(&f, 0, sizeof(f));
2525  memset(&ssn, 0, sizeof(ssn));
2526 
2527  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2528 
2529  FLOW_INITIALIZE(&f);
2530  f.protoctx = (void *)&ssn;
2531  f.proto = IPPROTO_TCP;
2532  f.flags |= FLOW_IPV4;
2533 
2534  p->flow = &f;
2538  f.alproto = ALPROTO_HTTP;
2539 
2541 
2543  FAIL_IF(de_ctx == NULL);
2544 
2545  de_ctx->flags |= DE_QUIET;
2546 
2547  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2548  "\"HTTP header\"; pcre:!\"/User-Agent[:]?\\s+Mozilla/H\"; "
2549  " sid:1;)");
2550  FAIL_IF(s == NULL);
2551 
2553  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2554 
2555  FLOWLOCK_WRLOCK(&f);
2556  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2557  STREAM_TOSERVER, httpbuf1, httplen1);
2558  FAIL_IF(r != 0);
2559  FLOWLOCK_UNLOCK(&f);
2560 
2561  http_state = f.alstate;
2562  FAIL_IF(http_state == NULL);
2563 
2564  /* do detect */
2565  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2566 
2567  FAIL_IF(!PacketAlertCheck(p, 1));
2568 
2569  if (alp_tctx != NULL)
2571  if (det_ctx != NULL) {
2572  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2573  }
2574  if (de_ctx != NULL) {
2577  }
2578 
2580  UTHFreePackets(&p, 1);
2581  PASS;
2582 }
2583 
2584 /** \test Check the signature working to alert when cookie and relative modifiers are
2585  * passed to pcre
2586  */
2587 static int DetectPcreTestSig15(void)
2588 {
2589  Flow f;
2590  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2591  "Cookie: dummy 1234\r\n\r\n";
2592  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2593  TcpSession ssn;
2594  Packet *p = NULL;
2595  Signature *s = NULL;
2596  ThreadVars th_v;
2597  DetectEngineThreadCtx *det_ctx = NULL;
2598  HtpState *http_state = NULL;
2600 
2601  memset(&th_v, 0, sizeof(th_v));
2602  memset(&p, 0, sizeof(p));
2603  memset(&f, 0, sizeof(f));
2604  memset(&ssn, 0, sizeof(ssn));
2605 
2606  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2607 
2608  FLOW_INITIALIZE(&f);
2609  f.protoctx = (void *)&ssn;
2610  f.proto = IPPROTO_TCP;
2611  f.flags |= FLOW_IPV4;
2612 
2613  p->flow = &f;
2617  f.alproto = ALPROTO_HTTP;
2618 
2620 
2622  FAIL_IF(de_ctx == NULL);
2623 
2624  de_ctx->flags |= DE_QUIET;
2625 
2626  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2627  "\"pcre relative HTTP cookie\"; content:\"dummy\";"
2628  " http_cookie; pcre:\"/1234/RC\"; "
2629  " sid:1;)");
2630  FAIL_IF(s == NULL);
2631 
2633  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2634 
2635  FLOWLOCK_WRLOCK(&f);
2636  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2637  STREAM_TOSERVER, httpbuf1, httplen1);
2638  FAIL_IF(r != 0);
2639  FLOWLOCK_UNLOCK(&f);
2640 
2641  http_state = f.alstate;
2642  FAIL_IF(http_state == NULL);
2643 
2644  /* do detect */
2645  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2646 
2647  FAIL_IF(!PacketAlertCheck(p, 1));
2648 
2649  if (alp_tctx != NULL)
2651  if (det_ctx != NULL) {
2652  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2653  }
2654  if (de_ctx != NULL) {
2657  }
2658 
2660  UTHFreePackets(&p, 1);
2661  PASS;
2662 }
2663 
2664 /** \test Check the signature working to alert when method and relative modifiers are
2665  * passed to pcre
2666  */
2667 static int DetectPcreTestSig16(void)
2668 {
2669  Flow f;
2670  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2671  "Cookie: dummy 1234\r\n\r\n";
2672  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2673  TcpSession ssn;
2674  Packet *p = NULL;
2675  Signature *s = NULL;
2676  ThreadVars th_v;
2677  DetectEngineThreadCtx *det_ctx = NULL;
2678  HtpState *http_state = NULL;
2680 
2681  memset(&th_v, 0, sizeof(th_v));
2682  memset(&p, 0, sizeof(p));
2683  memset(&f, 0, sizeof(f));
2684  memset(&ssn, 0, sizeof(ssn));
2685 
2686  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2687 
2688  FLOW_INITIALIZE(&f);
2689  f.protoctx = (void *)&ssn;
2690  f.proto = IPPROTO_TCP;
2691  f.flags |= FLOW_IPV4;
2692 
2693  p->flow = &f;
2697  f.alproto = ALPROTO_HTTP;
2698 
2700 
2702  FAIL_IF(de_ctx == NULL);
2703 
2704  de_ctx->flags |= DE_QUIET;
2705 
2706  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2707  "\"pcre relative HTTP method\"; content:\"PO\";"
2708  " http_method; pcre:\"/ST/RM\"; "
2709  " sid:1;)");
2710  FAIL_IF(s == NULL);
2711 
2713  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2714 
2715  FLOWLOCK_WRLOCK(&f);
2716  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2717  STREAM_TOSERVER, httpbuf1, httplen1);
2718  FAIL_IF(r != 0);
2719  FLOWLOCK_UNLOCK(&f);
2720 
2721  http_state = f.alstate;
2722  FAIL_IF(http_state == NULL);
2723 
2724  /* do detect */
2725  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2726 
2727  FAIL_IF(!PacketAlertCheck(p, 1));
2728 
2729  if (alp_tctx != NULL)
2731  if (det_ctx != NULL) {
2732  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2733  }
2734  if (de_ctx != NULL) {
2737  }
2738 
2740  UTHFreePackets(&p, 1);
2741  PASS;
2742 }
2743 
2744 /** \test Test tracking of body chunks per transactions (on requests)
2745  */
2746 static int DetectPcreTxBodyChunksTest01(void)
2747 {
2748  Flow f;
2749  TcpSession ssn;
2750  Packet *p = NULL;
2751  uint8_t httpbuf1[] = "GET / HTTP/1.1\r\n";
2752  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2753  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
2754  uint8_t httpbuf4[] = "Body one!!";
2755  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2756  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2757  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2758  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2759  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
2760  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
2761  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2762  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2763  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2764  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
2766 
2767  memset(&f, 0, sizeof(f));
2768  memset(&ssn, 0, sizeof(ssn));
2769 
2770  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2771 
2772  FLOW_INITIALIZE(&f);
2773  f.protoctx = (void *)&ssn;
2774  f.proto = IPPROTO_TCP;
2775  f.flags |= FLOW_IPV4;
2776 
2777  p->flow = &f;
2781  f.alproto = ALPROTO_HTTP;
2782 
2784 
2786 
2787  FLOWLOCK_WRLOCK(&f);
2788  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2789  STREAM_TOSERVER | STREAM_START, httpbuf1,
2790  httplen1);
2791  FAIL_IF(r != 0);
2792 
2793  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2794  STREAM_TOSERVER, httpbuf2, httplen2);
2795  FAIL_IF(r != 0);
2796 
2797  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2798  STREAM_TOSERVER, httpbuf3, httplen3);
2799  FAIL_IF(r != 0);
2800 
2801  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2802  STREAM_TOSERVER, httpbuf4, httplen4);
2803  FAIL_IF(r != 0);
2804 
2805  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2806  STREAM_TOSERVER, httpbuf5, httplen5);
2807  FAIL_IF(r != 0);
2808 
2809  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2810  STREAM_TOSERVER, httpbuf6, httplen6);
2811  FAIL_IF(r != 0);
2812 
2813  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2814  STREAM_TOSERVER, httpbuf7, httplen7);
2815  FAIL_IF(r != 0);
2816 
2817  /* Now we should have 2 transactions, each with it's own list
2818  * of request body chunks (let's test it) */
2819 
2820  HtpState *htp_state = f.alstate;
2821  FAIL_IF(htp_state == NULL);
2822 
2823  /* hardcoded check of the transactions and it's client body chunks */
2824  FAIL_IF(AppLayerParserGetTxCnt(&f, htp_state) != 2);
2825 
2826  htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0);
2827  htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1);
2828 
2829  HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2830  FAIL_IF(htud == NULL);
2831 
2832  HtpBodyChunk *cur = htud->request_body.first;
2833  FAIL_IF(htud->request_body.first == NULL);
2834 
2835  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body one!!", 10) != 1);
2836 
2837  htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2838 
2839  cur = htud->request_body.first;
2840  FAIL_IF(htud->request_body.first == NULL);
2841 
2842  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body two!!", 10) != 1);
2843 
2844  if (alp_tctx != NULL)
2846  FLOWLOCK_UNLOCK(&f);
2848  FLOW_DESTROY(&f);
2849  UTHFreePacket(p);
2850  PASS;
2851 }
2852 
2853 /** \test test pcre P modifier with multiple pipelined http transactions */
2854 static int DetectPcreTxBodyChunksTest02(void)
2855 {
2856  Signature *s = NULL;
2857  DetectEngineThreadCtx *det_ctx = NULL;
2858  ThreadVars th_v;
2859  Flow f;
2860  TcpSession ssn;
2861  Packet *p = NULL;
2862  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
2863  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2864  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
2865  uint8_t httpbuf4[] = "Body one!!";
2866  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2867  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2868  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2869  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2870  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
2871  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
2872  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2873  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2874  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2875  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
2877 
2878  memset(&th_v, 0, sizeof(th_v));
2879  memset(&f, 0, sizeof(f));
2880  memset(&ssn, 0, sizeof(ssn));
2881 
2882  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2883 
2884  FLOW_INITIALIZE(&f);
2885  f.protoctx = (void *)&ssn;
2886  f.proto = IPPROTO_TCP;
2887  f.flags |= FLOW_IPV4;
2888 
2889  p->flow = &f;
2893  f.alproto = ALPROTO_HTTP;
2894 
2896 
2898  FAIL_IF(de_ctx == NULL);
2899 
2900  de_ctx->flags |= DE_QUIET;
2901 
2902  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)");
2903  FAIL_IF(s == NULL);
2904  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)");
2905  FAIL_IF(s == NULL);
2906 
2908  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2909 
2910  FLOWLOCK_WRLOCK(&f);
2911  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2912  STREAM_TOSERVER, httpbuf1, httplen1);
2913  FAIL_IF(r != 0);
2914  FLOWLOCK_UNLOCK(&f);
2915 
2916  /* do detect */
2917  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2918  FAIL_IF(PacketAlertCheck(p, 1));
2919  p->alerts.cnt = 0;
2920 
2921  FLOWLOCK_WRLOCK(&f);
2922  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2923  STREAM_TOSERVER, httpbuf2, httplen2);
2924  FAIL_IF(r != 0);
2925  FLOWLOCK_UNLOCK(&f);
2926 
2927  /* do detect */
2928  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2929  FAIL_IF(PacketAlertCheck(p, 1));
2930  p->alerts.cnt = 0;
2931 
2932  FLOWLOCK_WRLOCK(&f);
2933  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2934  STREAM_TOSERVER, httpbuf3, httplen3);
2935  FAIL_IF(r != 0);
2936  FLOWLOCK_UNLOCK(&f);
2937 
2938  /* do detect */
2939  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2940  FAIL_IF(PacketAlertCheck(p, 1));
2941  p->alerts.cnt = 0;
2942 
2943  FLOWLOCK_WRLOCK(&f);
2944  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2945  STREAM_TOSERVER, httpbuf4, httplen4);
2946  FAIL_IF(r != 0);
2947  FLOWLOCK_UNLOCK(&f);
2948 
2949  /* do detect */
2950  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2951  FAIL_IF(!(PacketAlertCheck(p, 1)));
2952  p->alerts.cnt = 0;
2953 
2954  FLOWLOCK_WRLOCK(&f);
2955  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2956  STREAM_TOSERVER, httpbuf5, httplen5);
2957  FAIL_IF(r != 0);
2958  FLOWLOCK_UNLOCK(&f);
2959 
2960  /* do detect */
2961  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2962  FAIL_IF(PacketAlertCheck(p, 1));
2963  p->alerts.cnt = 0;
2964 
2965  FLOWLOCK_WRLOCK(&f);
2966  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2967  STREAM_TOSERVER, httpbuf6, httplen6);
2968  FAIL_IF(r != 0);
2969  FLOWLOCK_UNLOCK(&f);
2970 
2971  /* do detect */
2972  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2973  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
2974  p->alerts.cnt = 0;
2975 
2976  SCLogDebug("sending data chunk 7");
2977 
2978  FLOWLOCK_WRLOCK(&f);
2979  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2980  STREAM_TOSERVER, httpbuf7, httplen7);
2981  FAIL_IF(r != 0);
2982  FLOWLOCK_UNLOCK(&f);
2983 
2984  /* do detect */
2985  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2986  FAIL_IF(!(PacketAlertCheck(p, 2)));
2987  p->alerts.cnt = 0;
2988 
2989  HtpState *htp_state = f.alstate;
2990  FAIL_IF(htp_state == NULL);
2991 
2992  /* hardcoded check of the transactions and it's client body chunks */
2993  FAIL_IF(AppLayerParserGetTxCnt(&f, htp_state) != 2);
2994 
2995  htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0);
2996  htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1);
2997 
2998  HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2999 
3000  HtpBodyChunk *cur = htud->request_body.first;
3001  FAIL_IF(htud->request_body.first == NULL);
3002 
3003  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body one!!", 10) != 1);
3004 
3005  htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
3006 
3007  cur = htud->request_body.first;
3008  FAIL_IF(htud->request_body.first == NULL);
3009 
3010  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body two!!", 10) != 1);
3011 
3012  if (alp_tctx != NULL)
3014  if (det_ctx != NULL) {
3015  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
3016  }
3017  if (de_ctx != NULL) {
3020  }
3021 
3023  FLOW_DESTROY(&f);
3024  UTHFreePacket(p);
3025  PASS;
3026 }
3027 
3028 /** \test multiple http transactions and body chunks of request handling */
3029 static int DetectPcreTxBodyChunksTest03(void)
3030 {
3031  Signature *s = NULL;
3032  DetectEngineThreadCtx *det_ctx = NULL;
3033  ThreadVars th_v;
3034  Flow f;
3035  TcpSession ssn;
3036  Packet *p = NULL;
3037  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
3038  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
3039  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
3040  uint8_t httpbuf4[] = "Body one!!";
3041  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3042  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
3043  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
3044  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
3045  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
3046  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
3047  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
3048  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
3049  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
3050  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
3052 
3053  memset(&th_v, 0, sizeof(th_v));
3054  memset(&f, 0, sizeof(f));
3055  memset(&ssn, 0, sizeof(ssn));
3056 
3057  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3058 
3059  FLOW_INITIALIZE(&f);
3060  f.protoctx = (void *)&ssn;
3061  f.proto = IPPROTO_TCP;
3062  f.flags |= FLOW_IPV4;
3063 
3064  p->flow = &f;
3068  f.alproto = ALPROTO_HTTP;
3069 
3071 
3073  FAIL_IF(de_ctx == NULL);
3074 
3075  de_ctx->flags |= DE_QUIET;
3076 
3077  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)");
3078  FAIL_IF(s == NULL);
3079  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)");
3080  FAIL_IF(s == NULL);
3081 
3083  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3084 
3085  FLOWLOCK_WRLOCK(&f);
3086  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3087  STREAM_TOSERVER, httpbuf1, httplen1);
3088  FAIL_IF(r != 0);
3089  FLOWLOCK_UNLOCK(&f);
3090 
3091  /* do detect */
3092  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3093  FAIL_IF(PacketAlertCheck(p, 1));
3094  p->alerts.cnt = 0;
3095 
3096  FLOWLOCK_WRLOCK(&f);
3097  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3098  STREAM_TOSERVER, httpbuf2, httplen2);
3099  FAIL_IF(r != 0);
3100  FLOWLOCK_UNLOCK(&f);
3101 
3102  /* do detect */
3103  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3104  FAIL_IF(PacketAlertCheck(p, 1));
3105  p->alerts.cnt = 0;
3106 
3107  FLOWLOCK_WRLOCK(&f);
3108  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3109  STREAM_TOSERVER, httpbuf3, httplen3);
3110  FAIL_IF(r != 0);
3111  FLOWLOCK_UNLOCK(&f);
3112 
3113  /* do detect */
3114  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3115  FAIL_IF(PacketAlertCheck(p, 1));
3116  p->alerts.cnt = 0;
3117 
3118  FLOWLOCK_WRLOCK(&f);
3119  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3120  STREAM_TOSERVER, httpbuf4, httplen4);
3121  FAIL_IF(r != 0);
3122  FLOWLOCK_UNLOCK(&f);
3123 
3124  /* do detect */
3125  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3126  FAIL_IF(!(PacketAlertCheck(p, 1)));
3127  p->alerts.cnt = 0;
3128 
3129  FLOWLOCK_WRLOCK(&f);
3130  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3131  STREAM_TOSERVER, httpbuf5, httplen5);
3132  FAIL_IF(r != 0);
3133  FLOWLOCK_UNLOCK(&f);
3134 
3135  /* do detect */
3136  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3137  FAIL_IF(PacketAlertCheck(p, 1));
3138  p->alerts.cnt = 0;
3139 
3140  FLOWLOCK_WRLOCK(&f);
3141  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3142  STREAM_TOSERVER, httpbuf6, httplen6);
3143  FAIL_IF(r != 0);
3144  FLOWLOCK_UNLOCK(&f);
3145 
3146  /* do detect */
3147  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3148  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
3149  p->alerts.cnt = 0;
3150 
3151  SCLogDebug("sending data chunk 7");
3152 
3153  FLOWLOCK_WRLOCK(&f);
3154  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3155  STREAM_TOSERVER, httpbuf7, httplen7);
3156  FAIL_IF(r != 0);
3157  FLOWLOCK_UNLOCK(&f);
3158 
3159  /* do detect */
3160  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3161  FAIL_IF(!(PacketAlertCheck(p, 2)));
3162  p->alerts.cnt = 0;
3163 
3164  HtpState *htp_state = f.alstate;
3165  FAIL_IF(htp_state == NULL);
3166 
3167  FAIL_IF(AppLayerParserGetTxCnt(&f, htp_state) != 2);
3168 
3169  if (alp_tctx != NULL)
3171  if (det_ctx != NULL) {
3172  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
3173  }
3174  if (de_ctx != NULL) {
3177  }
3178 
3180  FLOW_DESTROY(&f);
3181  UTHFreePacket(p);
3182  PASS;
3183 }
3184 
3185 /**
3186  * \test flowvar capture on http buffer
3187  */
3188 static int DetectPcreFlowvarCapture01(void)
3189 {
3190  uint8_t uabuf1[] =
3191  "Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13";
3192  uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */
3193  uint8_t httpbuf1[] =
3194  "GET / HTTP/1.1\r\n"
3195  "Host: www.emergingthreats.net\r\n"
3196  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
3197  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3198  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3199  "Accept-Encoding: gzip,deflate\r\n"
3200  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3201  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3202  "Server: Apache\r\n"
3203  "\r\n"
3204  "<!DOCTYPE html PUBLIC\r\n\r\n";
3205  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3206  TcpSession ssn;
3207  Packet *p1 = NULL;
3208  Flow f;
3209  Signature *s = NULL;
3210  ThreadVars th_v;
3211  DetectEngineThreadCtx *det_ctx;
3213 
3214  memset(&th_v, 0, sizeof(th_v));
3215  memset(&f, 0, sizeof(f));
3216  memset(&ssn, 0, sizeof(ssn));
3217 
3218  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3219 
3220  FLOW_INITIALIZE(&f);
3221  f.protoctx = (void *)&ssn;
3222  f.proto = IPPROTO_TCP;
3223  f.flags |= FLOW_IPV4;
3224  f.alproto = ALPROTO_HTTP;
3225 
3226  p1->flow = &f;
3230 
3232 
3234  FAIL_IF(de_ctx == NULL);
3235  de_ctx->flags |= DE_QUIET;
3236 
3237  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; sid:1;)");
3238  FAIL_IF(s == NULL);
3239 
3240  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3241  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3242  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3243  DetectPcreData *pd = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3244 
3246  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3247 
3248  FLOWLOCK_WRLOCK(&f);
3249  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3250  STREAM_TOSERVER, httpbuf1, httplen1);
3251  FAIL_IF(r != 0);
3252  FLOWLOCK_UNLOCK(&f);
3253 
3254  HtpState *http_state = f.alstate;
3255  FAIL_IF(http_state == NULL);
3256 
3257  /* do detect for p1 */
3258  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3259 
3260  FAIL_IF(!(PacketAlertCheck(p1, 1)));
3261 
3262  FlowVar *fv = FlowVarGet(&f, pd->capids[0]);
3263  FAIL_IF(fv == NULL);
3264 
3265  FAIL_IF(fv->data.fv_str.value_len != ualen1);
3266 
3267  if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) {
3268  PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len);
3269  PrintRawDataFp(stdout, uabuf1, ualen1);
3270 
3271  printf("buffer mismatch: ");
3272  FAIL;
3273  }
3274 
3275  if (alp_tctx != NULL)
3277  if (de_ctx != NULL)
3279 
3281  FLOW_DESTROY(&f);
3282  UTHFreePackets(&p1, 1);
3283  PASS;
3284 }
3285 
3286 /**
3287  * \test flowvar capture on http buffer, capture overwrite
3288  */
3289 static int DetectPcreFlowvarCapture02(void)
3290 {
3291  uint8_t uabuf1[] =
3292  "Apache";
3293  uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */
3294  uint8_t httpbuf1[] =
3295  "GET / HTTP/1.1\r\n"
3296  "Host: www.emergingthreats.net\r\n"
3297  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
3298  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3299  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3300  "Accept-Encoding: gzip,deflate\r\n"
3301  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3302  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3303  "Server: Apache\r\n"
3304  "\r\n"
3305  "<!DOCTYPE html PUBLIC\r\n\r\n";
3306  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3307  TcpSession ssn;
3308  Packet *p1 = NULL;
3309  Flow f;
3310  Signature *s = NULL;
3311  ThreadVars th_v;
3312  DetectEngineThreadCtx *det_ctx;
3314 
3315  memset(&th_v, 0, sizeof(th_v));
3316  memset(&f, 0, sizeof(f));
3317  memset(&ssn, 0, sizeof(ssn));
3318 
3319  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3320 
3321  FLOW_INITIALIZE(&f);
3322  f.protoctx = (void *)&ssn;
3323  f.proto = IPPROTO_TCP;
3324  f.flags |= FLOW_IPV4;
3325  f.alproto = ALPROTO_HTTP;
3326 
3327  p1->flow = &f;
3331 
3333 
3335  FAIL_IF(de_ctx == NULL);
3336  de_ctx->flags |= DE_QUIET;
3337 
3338  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; priority:1; sid:1;)");
3339  FAIL_IF(s == NULL);
3340 
3341  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3342  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3343  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3344  DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3345 
3346  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; priority:3; sid:2;)");
3347  FAIL_IF(s == NULL);
3348 
3349  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3350  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3351  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3352  DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3353 
3354  FAIL_IF(pd1->capids[0] != pd2->capids[0]);
3355 
3360  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3361 
3362  FLOWLOCK_WRLOCK(&f);
3363  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3364  STREAM_TOSERVER, httpbuf1, httplen1);
3365  FAIL_IF(r != 0);
3366  FLOWLOCK_UNLOCK(&f);
3367 
3368  HtpState *http_state = f.alstate;
3369  FAIL_IF(http_state == NULL);
3370 
3371  /* do detect for p1 */
3372  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3373 
3374  FAIL_IF(!(PacketAlertCheck(p1, 1)));
3375 
3376  FlowVar *fv = FlowVarGet(&f, pd1->capids[0]);
3377  FAIL_IF(fv == NULL);
3378 
3379  if (fv->data.fv_str.value_len != ualen1) {
3380  PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len);
3381  PrintRawDataFp(stdout, uabuf1, ualen1);
3382  printf("%u != %u: ", fv->data.fv_str.value_len, ualen1);
3383  FAIL;
3384  }
3385 
3386  if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) {
3387  PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len);
3388  PrintRawDataFp(stdout, uabuf1, ualen1);
3389 
3390  printf("buffer mismatch: ");
3391  FAIL;
3392  }
3393 
3394  if (alp_tctx != NULL)
3396  if (de_ctx != NULL)
3398 
3400  FLOW_DESTROY(&f);
3401  UTHFreePackets(&p1, 1);
3402  PASS;
3403 }
3404 
3405 /**
3406  * \test flowvar capture on http buffer, capture overwrite + no matching sigs, so flowvars should not be set.
3407  */
3408 static int DetectPcreFlowvarCapture03(void)
3409 {
3410  uint8_t httpbuf1[] =
3411  "GET / HTTP/1.1\r\n"
3412  "Host: www.emergingthreats.net\r\n"
3413  "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n"
3414  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3415  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3416  "Accept-Encoding: gzip,deflate\r\n"
3417  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3418  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3419  "Server: Apache\r\n"
3420  "\r\n"
3421  "<!DOCTYPE html PUBLIC\r\n\r\n";
3422  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3423  TcpSession ssn;
3424  Packet *p1 = NULL;
3425  Flow f;
3426  Signature *s = NULL;
3427  ThreadVars th_v;
3428  DetectEngineThreadCtx *det_ctx;
3430 
3431  memset(&th_v, 0, sizeof(th_v));
3432  memset(&f, 0, sizeof(f));
3433  memset(&ssn, 0, sizeof(ssn));
3434 
3435  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3436 
3437  FLOW_INITIALIZE(&f);
3438  f.protoctx = (void *)&ssn;
3439  f.proto = IPPROTO_TCP;
3440  f.flags |= FLOW_IPV4;
3441  f.alproto = ALPROTO_HTTP;
3442 
3443  p1->flow = &f;
3447 
3449 
3451  FAIL_IF(de_ctx == NULL);
3452  de_ctx->flags |= DE_QUIET;
3453 
3454  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:1; sid:1;)");
3455  FAIL_IF(s == NULL);
3456 
3457  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3458  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3459  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3460  DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3461 
3462  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:3; sid:2;)");
3463  FAIL_IF(s == NULL);
3464 
3465  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3466  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3467  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3468  DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3469 
3470  FAIL_IF(pd1->capids[0] != pd2->capids[0]);
3471 
3473  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3474 
3475  FLOWLOCK_WRLOCK(&f);
3476  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3477  STREAM_TOSERVER, httpbuf1, httplen1);
3478  FAIL_IF(r != 0);
3479  FLOWLOCK_UNLOCK(&f);
3480 
3481  HtpState *http_state = f.alstate;
3482  FAIL_IF(http_state == NULL);
3483 
3484  /* do detect for p1 */
3485  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3486 
3487  FAIL_IF(PacketAlertCheck(p1, 1));
3488 
3489  FlowVar *fv = FlowVarGet(&f, pd1->capids[0]);
3490  FAIL_IF(fv != NULL);
3491 
3492  if (alp_tctx != NULL)
3494  if (de_ctx != NULL)
3496 
3498  FLOW_DESTROY(&f);
3499  UTHFreePackets(&p1, 1);
3500  PASS;
3501 }
3502 
3503 /**
3504  * \brief Test parsing of pcre's with the W modifier set.
3505  */
3506 static int DetectPcreParseHttpHost(void)
3507 {
3508  AppProto alproto = ALPROTO_UNKNOWN;
3509  int list = DETECT_SM_LIST_NOTSET;
3511 
3512  FAIL_IF(de_ctx == NULL);
3513 
3514  DetectPcreData *pd = DetectPcreParse(de_ctx, "/domain\\.com/W", &list, NULL, 0, false, &alproto);
3515  FAIL_IF(pd == NULL);
3516  DetectPcreFree(NULL, pd);
3517 
3518  list = DETECT_SM_LIST_NOTSET;
3519  pd = DetectPcreParse(de_ctx, "/dOmain\\.com/W", &list, NULL, 0, false, &alproto);
3520  FAIL_IF(pd != NULL);
3521 
3522  /* Uppercase meta characters are valid. */
3523  list = DETECT_SM_LIST_NOTSET;
3524  pd = DetectPcreParse(de_ctx, "/domain\\D+\\.com/W", &list, NULL, 0, false, &alproto);
3525  FAIL_IF(pd == NULL);
3526  DetectPcreFree(NULL, pd);
3527 
3528  /* This should not parse as the first \ escapes the second \, then
3529  * we have a D. */
3530  list = DETECT_SM_LIST_NOTSET;
3531  pd = DetectPcreParse(de_ctx, "/\\\\Ddomain\\.com/W", &list, NULL, 0, false, &alproto);
3532  FAIL_IF(pd != NULL);
3533 
3535  PASS;
3536 }
3537 
3538 /**
3539  * \brief Test parsing of capture extension
3540  */
3541 static int DetectPcreParseCaptureTest(void)
3542 {
3544  FAIL_IF(de_ctx == NULL);
3545 
3546  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
3547  "(content:\"Server: \"; http_header; pcre:\"/(.*)\\r\\n/HR, flow:somecapture\"; content:\"xyz\"; http_header; sid:1;)");
3548  FAIL_IF(s == NULL);
3549  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
3550  "(content:\"Server: \"; http_header; pcre:\"/(flow:.*)\\r\\n/HR\"; content:\"xyz\"; http_header; sid:2;)");
3551  FAIL_IF(s == NULL);
3552  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
3553  "(content:\"Server: \"; http_header; pcre:\"/([a-z]+)([0-9]+)\\r\\n/HR, flow:somecapture, pkt:anothercap\"; content:\"xyz\"; http_header; sid:3;)");
3554  FAIL_IF(s == NULL);
3555 
3557 
3558  uint32_t capid = VarNameStoreLookupByName("somecapture", VAR_TYPE_FLOW_VAR);
3559  FAIL_IF (capid != 1);
3560  capid = VarNameStoreLookupByName("anothercap", VAR_TYPE_PKT_VAR);
3561  FAIL_IF (capid != 2);
3562 
3564  PASS;
3565 }
3566 
3567 /**
3568  * \brief this function registers unit tests for DetectPcre
3569  */
3570 static void DetectPcreRegisterTests(void)
3571 {
3572  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
3573  g_http_header_buffer_id = DetectBufferTypeGetByName("http_header");
3574  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
3575 
3576  UtRegisterTest("DetectPcreParseTest01", DetectPcreParseTest01);
3577  UtRegisterTest("DetectPcreParseTest02", DetectPcreParseTest02);
3578  UtRegisterTest("DetectPcreParseTest03", DetectPcreParseTest03);
3579  UtRegisterTest("DetectPcreParseTest04", DetectPcreParseTest04);
3580  UtRegisterTest("DetectPcreParseTest05", DetectPcreParseTest05);
3581  UtRegisterTest("DetectPcreParseTest06", DetectPcreParseTest06);
3582  UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07);
3583  UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08);
3584  UtRegisterTest("DetectPcreParseTest09", DetectPcreParseTest09);
3585  UtRegisterTest("DetectPcreParseTest10", DetectPcreParseTest10);
3586  UtRegisterTest("DetectPcreParseTest11", DetectPcreParseTest11);
3587  UtRegisterTest("DetectPcreParseTest12", DetectPcreParseTest12);
3588  UtRegisterTest("DetectPcreParseTest13", DetectPcreParseTest13);
3589  UtRegisterTest("DetectPcreParseTest14", DetectPcreParseTest14);
3590  UtRegisterTest("DetectPcreParseTest15", DetectPcreParseTest15);
3591  UtRegisterTest("DetectPcreParseTest16", DetectPcreParseTest16);
3592  UtRegisterTest("DetectPcreParseTest17", DetectPcreParseTest17);
3593  UtRegisterTest("DetectPcreParseTest18", DetectPcreParseTest18);
3594  UtRegisterTest("DetectPcreParseTest19", DetectPcreParseTest19);
3595  UtRegisterTest("DetectPcreParseTest20", DetectPcreParseTest20);
3596  UtRegisterTest("DetectPcreParseTest21", DetectPcreParseTest21);
3597  UtRegisterTest("DetectPcreParseTest22", DetectPcreParseTest22);
3598  UtRegisterTest("DetectPcreParseTest23", DetectPcreParseTest23);
3599  UtRegisterTest("DetectPcreParseTest24", DetectPcreParseTest24);
3600  UtRegisterTest("DetectPcreParseTest25", DetectPcreParseTest25);
3601  UtRegisterTest("DetectPcreParseTest26", DetectPcreParseTest26);
3602  UtRegisterTest("DetectPcreParseTest27", DetectPcreParseTest27);
3603  UtRegisterTest("DetectPcreParseTest28", DetectPcreParseTest28);
3604 
3605  UtRegisterTest("DetectPcreTestSig01 -- pcre test", DetectPcreTestSig01);
3606  UtRegisterTest("DetectPcreTestSig02 -- pcre test", DetectPcreTestSig02);
3607  UtRegisterTest("DetectPcreTestSig03 -- negated pcre test",
3608  DetectPcreTestSig03);
3609 
3610  UtRegisterTest("DetectPcreModifPTest04 -- Modifier P",
3611  DetectPcreModifPTest04);
3612  UtRegisterTest("DetectPcreModifPTest05 -- Modifier P fragmented",
3613  DetectPcreModifPTest05);
3614  UtRegisterTest("DetectPcreTestSig06", DetectPcreTestSig06);
3615  UtRegisterTest("DetectPcreTestSig07 -- anchored pcre",
3616  DetectPcreTestSig07);
3617  UtRegisterTest("DetectPcreTestSig08 -- anchored pcre",
3618  DetectPcreTestSig08);
3619  UtRegisterTest("DetectPcreTestSig09 -- Cookie modifier",
3620  DetectPcreTestSig09);
3621  UtRegisterTest("DetectPcreTestSig10 -- negated Cookie modifier",
3622  DetectPcreTestSig10);
3623  UtRegisterTest("DetectPcreTestSig11 -- Method modifier",
3624  DetectPcreTestSig11);
3625  UtRegisterTest("DetectPcreTestSig12 -- negated Method modifier",
3626  DetectPcreTestSig12);
3627  UtRegisterTest("DetectPcreTestSig13 -- Header modifier",
3628  DetectPcreTestSig13);
3629  UtRegisterTest("DetectPcreTestSig14 -- negated Header modifier",
3630  DetectPcreTestSig14);
3631  UtRegisterTest("DetectPcreTestSig15 -- relative Cookie modifier",
3632  DetectPcreTestSig15);
3633  UtRegisterTest("DetectPcreTestSig16 -- relative Method modifier",
3634  DetectPcreTestSig16);
3635 
3636  UtRegisterTest("DetectPcreTxBodyChunksTest01",
3637  DetectPcreTxBodyChunksTest01);
3638  UtRegisterTest("DetectPcreTxBodyChunksTest02 -- modifier P, body chunks per tx",
3639  DetectPcreTxBodyChunksTest02);
3640  UtRegisterTest("DetectPcreTxBodyChunksTest03 -- modifier P, body chunks per tx",
3641  DetectPcreTxBodyChunksTest03);
3642 
3643  UtRegisterTest("DetectPcreFlowvarCapture01 -- capture for http_header",
3644  DetectPcreFlowvarCapture01);
3645  UtRegisterTest("DetectPcreFlowvarCapture02 -- capture for http_header",
3646  DetectPcreFlowvarCapture02);
3647  UtRegisterTest("DetectPcreFlowvarCapture03 -- capture for http_header",
3648  DetectPcreFlowvarCapture03);
3649 
3650  UtRegisterTest("DetectPcreParseHttpHost", DetectPcreParseHttpHost);
3651  UtRegisterTest("DetectPcreParseCaptureTest", DetectPcreParseCaptureTest);
3652 
3653 }
3654 #endif /* UNITTESTS */
DETECT_PCRE_CASELESS
#define DETECT_PCRE_CASELESS
Definition: detect-pcre.h:31
ConfGetInt
int ConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:436
SigTableElmt_::url
const char * url
Definition: detect.h:1214
DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_RELATIVE_NEXT
Definition: detect-content.h:64
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1480
SigMatch_::prev
struct SigMatch_ * prev
Definition: detect.h:325
DetectPcreData_::idx
uint8_t idx
Definition: detect-pcre.h:49
len
uint8_t len
Definition: app-layer-dnp3.h:2
DetectEngineThreadCtx_::buffer_offset
uint32_t buffer_offset
Definition: detect.h:1041
SC_ERR_PCRE_COMPILE
@ SC_ERR_PCRE_COMPILE
Definition: util-error.h:35
DetectFlowvarPostMatchSetup
int DetectFlowvarPostMatchSetup(DetectEngineCtx *de_ctx, Signature *s, uint32_t idx)
Setup a post-match for flowvar storage We're piggyback riding the DetectFlowvarData struct.
Definition: detect-flowvar.c:256
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:90
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1213
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1109
UTHAddStreamToFlow
int UTHAddStreamToFlow(Flow *f, int direction, uint8_t *data, uint32_t data_len)
Definition: util-unittest-helper.c:533
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1201
flow-util.h
DetectPcrePayloadMatch
int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *payload, uint32_t payload_len)
Match a regex on a single payload.
Definition: detect-pcre.c:190
SigTableElmt_::name
const char * name
Definition: detect.h:1211
stream-tcp.h
HtpBody_::sb
StreamingBuffer * sb
Definition: app-layer-htp.h:189
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1381
DetectEngineCtx_::rule_file
char * rule_file
Definition: detect.h:871
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3123
MAX_SUBSTRINGS
#define MAX_SUBSTRINGS
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
DetectVarStoreMatch
int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx, uint8_t *buffer, uint16_t len, int type)
Store flowvar in det_ctx so we can exec it post-match.
Definition: detect-flowvar.c:220
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:59
Signature_::alproto
AppProto alproto
Definition: detect.h:532
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
SIGMATCH_QUOTES_OPTIONAL
#define SIGMATCH_QUOTES_OPTIONAL
Definition: detect.h:1392
Flow_::proto
uint8_t proto
Definition: flow.h:365
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:73
PacketAlerts_::cnt
uint16_t cnt
Definition: decode.h:299
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:138
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:39
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:332
Packet_::flags
uint32_t flags
Definition: decode.h:449
SC_WARN_PCRE_JITSTACK
@ SC_WARN_PCRE_JITSTACK
Definition: util-error.h:359
Flow_
Flow data structure.
Definition: flow.h:347
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2051
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-pcre.c:66
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1205
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:767
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:57
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2093
HtpTxUserData_::request_body
HtpBody request_body
Definition: app-layer-htp.h:216
SCSigSignatureOrderingModuleCleanup
void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx)
De-registers all the signature ordering functions registered.
Definition: detect-engine-sigorder.c:808
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:278
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:219
util-var-name.h
MIN
#define MIN(x, y)
Definition: suricata-common.h:377
DetectPcreData_::parse_regex
DetectParseRegex parse_regex
Definition: detect-pcre.h:41
DE_QUIET
#define DE_QUIET
Definition: detect.h:294
UTHPacketMatchSig
int UTHPacketMatchSig(Packet *p, const char *sig)
Definition: util-unittest-helper.c:882
DetectGetLastSMByListPtr
SigMatch * DetectGetLastSMByListPtr(const Signature *s, SigMatch *sm_list,...)
Returns the sm with the largest index (added last) from the list passed to us as a pointer.
Definition: detect-parse.c:508
stream-tcp-reassemble.h
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:337
SC_ERR_VAR_LIMIT
@ SC_ERR_VAR_LIMIT
Definition: util-error.h:328
FlowVar_::data
union FlowVar_::@115 data
DetectContentData_
Definition: detect-content.h:86
DetectPcreData_::flags
uint16_t flags
Definition: detect-pcre.h:48
SC_ERR_PCRE_GET_SUBSTRING
@ SC_ERR_PCRE_GET_SUBSTRING
Definition: util-error.h:34
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:39
DETECT_PCRE_CAPTURE_MAX
#define DETECT_PCRE_CAPTURE_MAX
Definition: detect-pcre.h:37
DETECT_VAR_TYPE_PKT_POSTMATCH
#define DETECT_VAR_TYPE_PKT_POSTMATCH
Definition: detect.h:654
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:445
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine.c:1005
StreamingBufferSegmentCompareRawData
int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t *rawdata, uint32_t rawdata_len)
Definition: util-streaming-buffer.c:833
Flow_::protoctx
void * protoctx
Definition: flow.h:441
SigMatchData_
Data needed for Match()
Definition: detect.h:329
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1196
detect-pcre.h
PARSE_CAPTURE_REGEX
#define PARSE_CAPTURE_REGEX
Definition: detect-pcre.c:65
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:95
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:564
util-unittest.h
HtpBody_::first
HtpBodyChunk * first
Definition: app-layer-htp.h:186
HtpState_
Definition: app-layer-htp.h:243
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:264
STREAM_START
#define STREAM_START
Definition: stream.h:29
SIG_FLAG_APPLAYER
#define SIG_FLAG_APPLAYER
Definition: detect.h:218
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:880
VAR_TYPE_PKT_VAR_KV
@ VAR_TYPE_PKT_VAR_KV
Definition: util-var.h:33
detect-flowvar.h
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
DetectPcreData_::capids
uint32_t capids[DETECT_PCRE_CAPTURE_MAX]
Definition: detect-pcre.h:51
Signature_::next
struct Signature_ * next
Definition: detect.h:600
SC_MATCH_LIMIT_RECURSION_DEFAULT
#define SC_MATCH_LIMIT_RECURSION_DEFAULT
Definition: detect-pcre.c:69
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:521
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
app-layer-htp.h
VarNameStoreLookupByName
uint32_t VarNameStoreLookupByName(const char *name, const enum VarTypes type)
Definition: util-var-name.c:309
decode.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
SC_ERR_PCRE_MATCH
@ SC_ERR_PCRE_MATCH
Definition: util-error.h:32
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
DETECT_PCRE_RAWBYTES
#define DETECT_PCRE_RAWBYTES
Definition: detect-pcre.h:30
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectParseRegex_::study
pcre_extra * study
Definition: detect-parse.h:44
DetectEngineThreadCtx_
Definition: detect.h:1010
SCSigOrderSignatures
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
Definition: detect-engine-sigorder.c:728
UTHAddSessionToFlow
int UTHAddSessionToFlow(Flow *f, uint32_t ts_isn, uint32_t tc_isn)
Definition: util-unittest-helper.c:549
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
AppLayerHtpEnableRequestBodyCallback
void AppLayerHtpEnableRequestBodyCallback(void)
Sets a flag that informs the HTP app layer that some module in the engine needs the http request body...
Definition: app-layer-htp.c:473
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:19
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2488
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:261
SignatureInitData_::list
int list
Definition: detect.h:505
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
SCSigRegisterSignatureOrderingFuncs
void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
Lets you register the Signature ordering functions. The order in which the functions are registered,...
Definition: detect-engine-sigorder.c:788
PrintRawDataFp
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:141
app-layer-parser.h
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:323
SigMatchSignatures
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1688
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:1949
Signature_::flags
uint32_t flags
Definition: detect.h:529
stream.h
SC_MATCH_LIMIT_DEFAULT
#define SC_MATCH_LIMIT_DEFAULT
Definition: detect-pcre.c:68
Packet_
Definition: decode.h:414
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:668
stream-tcp-private.h
conf.h
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:97
SIGMATCH_HANDLE_NEGATION
#define SIGMATCH_HANDLE_NEGATION
Definition: detect.h:1400
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:597
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
SignatureInitData_::negated
bool negated
Definition: detect.h:485
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1179
PageSupportsRWX
#define PageSupportsRWX()
Definition: util-pages.h:37
SC_ERR_PCRE_STUDY
@ SC_ERR_PCRE_STUDY
Definition: util-error.h:36
util-pages.h
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:217
DETECT_PCRE
@ DETECT_PCRE
Definition: detect-engine-register.h:61
DETECT_VAR_TYPE_FLOW_POSTMATCH
#define DETECT_VAR_TYPE_FLOW_POSTMATCH
Definition: detect.h:653
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1032
DetectPcreData_::captypes
uint8_t captypes[DETECT_PCRE_CAPTURE_MAX]
Definition: detect-pcre.h:50
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1884
SigMatch_::type
uint8_t type
Definition: detect.h:321
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:526
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:252
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:115
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2356
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:38
Packet_::flow
struct Flow_ * flow
Definition: decode.h:451
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2797
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
DetectRegisterThreadCtxFuncs
int DetectRegisterThreadCtxFuncs(DetectEngineCtx *de_ctx, const char *name, void *(*InitFunc)(void *), void *data, void(*FreeFunc)(void *), int mode)
Register Thread keyword context Funcs.
Definition: detect-engine.c:3046
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1178
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3005
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:531
HtpBodyChunk_
Definition: app-layer-htp.h:177
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
DetectParseRegex_
Definition: detect-parse.h:42
VarNameStoreSetupAdd
uint32_t VarNameStoreSetupAdd(const char *name, const enum VarTypes type)
add to staging or return existing id if already in there
Definition: util-var-name.c:323
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:773
HtpTxUserData_
Definition: app-layer-htp.h:208
detect-engine-sigorder.h
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
DetectEngineThreadCtx_::pcre_match_start_offset
uint32_t pcre_match_start_offset
Definition: detect.h:1043
str
#define str(s)
Definition: suricata-common.h:273
DetectParseRegex_::regex
pcre * regex
Definition: detect-parse.h:43
SCLogWarning
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:244
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:485
Flow_::alstate
void * alstate
Definition: flow.h:476
Flow_::flags
uint32_t flags
Definition: flow.h:421
detect-parse.h
Signature_
Signature container.
Definition: detect.h:528
SigMatch_
a single match condition for a signature
Definition: detect.h:320
payload_len
uint16_t payload_len
Definition: stream-tcp-private.h:1
FAIL
#define FAIL
Fail a test.
Definition: util-unittest.h:60
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:37
SC_ERR_UNKNOWN_REGEX_MOD
@ SC_ERR_UNKNOWN_REGEX_MOD
Definition: util-error.h:161
ALPROTO_HTTP
@ ALPROTO_HTTP
Definition: app-layer-protos.h:30
StreamTcpInitConfig
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:221
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2048
DETECT_PCRE_RELATIVE_NEXT
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:34
app-layer-protos.h
DetectVarStoreMatchKeyValue
int DetectVarStoreMatchKeyValue(DetectEngineThreadCtx *det_ctx, uint8_t *key, uint16_t key_len, uint8_t *buffer, uint16_t len, int type)
Store flowvar in det_ctx so we can exec it post-match.
Definition: detect-flowvar.c:200
DetectBufferTypeGetDescriptionById
const char * DetectBufferTypeGetDescriptionById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:917
DetectPcreData_
Definition: detect-pcre.h:39
DetectParseFreeRegex
void DetectParseFreeRegex(DetectParseRegex *r)
Definition: detect-parse.c:2426
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:768
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:78
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:87
DETECT_PCRE_RELATIVE
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:29
SigAlloc
Signature * SigAlloc(void)
Definition: detect-parse.c:1257
UTHRemoveSessionFromFlow
int UTHRemoveSessionFromFlow(Flow *f)
Definition: util-unittest-helper.c:569
DetectEngineCtx_::rule_line
int rule_line
Definition: detect.h:872
TcpSession_
Definition: stream-tcp-private.h:261
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
util-pool.h
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
DETECT_PCRE_NEGATE
#define DETECT_PCRE_NEGATE
Definition: detect-pcre.h:35
DetectSetupParseRegexesOpts
bool DetectSetupParseRegexesOpts(const char *parse_str, DetectParseRegex *detect_parse, int opts)
Definition: detect-parse.c:2464
flow-var.h
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1023
HtpBodyChunk_::sbseg
StreamingBufferSegment sbseg
Definition: app-layer-htp.h:180
FlowVar_
Definition: flow-var.h:48
DetectPcreRegister
void DetectPcreRegister(void)
Definition: detect-pcre.c:115
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:130
VAR_TYPE_PKT_VAR
@ VAR_TYPE_PKT_VAR
Definition: util-var.h:32
debug.h
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1107
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1203
app-layer.h
DETECT_PCRE_MATCH_LIMIT
#define DETECT_PCRE_MATCH_LIMIT
Definition: detect-pcre.h:33
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:468