suricata
detect-pcre.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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_HTTP1;
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 - 1)) {
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 && !AppProtoEquals(s->alproto, alproto)) {
908  goto error;
909  }
910  if (DetectSignatureSetAppProto(s, alproto) < 0)
911  goto error;
912  }
913  sm_list = parsed_sm_list;
914  break;
915  }
916  }
917  }
918  if (sm_list == -1)
919  goto error;
920 
921  sm = SigMatchAlloc();
922  if (sm == NULL)
923  goto error;
924  sm->type = DETECT_PCRE;
925  sm->ctx = (void *)pd;
926  SigMatchAppendSMToList(s, sm, sm_list);
927 
928  for (uint8_t x = 0; x < pd->idx; x++) {
929  if (DetectFlowvarPostMatchSetup(de_ctx, s, pd->capids[x]) < 0)
930  goto error_nofree;
931  }
932 
933  if (!(pd->flags & DETECT_PCRE_RELATIVE))
934  goto okay;
935 
936  /* errors below shouldn't free pd */
937 
938  SigMatch *prev_pm = DetectGetLastSMByListPtr(s, sm->prev,
940  if (s->init_data->list == DETECT_SM_LIST_NOTSET && prev_pm == NULL) {
941  SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre with /R (relative) needs "
942  "preceding match in the same buffer");
943  goto error_nofree;
944  /* null is allowed when we use a sticky buffer */
945  } else if (prev_pm == NULL) {
946  goto okay;
947  }
948  if (prev_pm->type == DETECT_CONTENT) {
949  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
951  } else if (prev_pm->type == DETECT_PCRE) {
952  DetectPcreData *tmp = (DetectPcreData *)prev_pm->ctx;
954  }
955 
956  okay:
957  SCReturnInt(0);
958  error:
959  DetectPcreFree(de_ctx, pd);
960  error_nofree:
961  SCReturnInt(-1);
962 }
963 
964 static void DetectPcreFree(DetectEngineCtx *de_ctx, void *ptr)
965 {
966  if (ptr == NULL)
967  return;
968 
969  DetectPcreData *pd = (DetectPcreData *)ptr;
971  SCFree(pd);
972 
973  return;
974 }
975 
976 #ifdef UNITTESTS /* UNITTESTS */
977 static int g_file_data_buffer_id = 0;
978 static int g_http_header_buffer_id = 0;
979 static int g_dce_stub_data_buffer_id = 0;
980 
981 /**
982  * \test DetectPcreParseTest01 make sure we don't allow invalid opts 7.
983  */
984 static int DetectPcreParseTest01 (void)
985 {
986  int result = 1;
987  DetectPcreData *pd = NULL;
988  const char *teststring = "/blah/7";
989  int list = DETECT_SM_LIST_NOTSET;
992  AppProto alproto = ALPROTO_UNKNOWN;
993 
994  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
995  FAIL_IF_NOT_NULL(pd);
996 
998  return result;
999 }
1000 
1001 /**
1002  * \test DetectPcreParseTest02 make sure we don't allow invalid opts Ui$.
1003  */
1004 static int DetectPcreParseTest02 (void)
1005 {
1006  int result = 1;
1007  DetectPcreData *pd = NULL;
1008  const char *teststring = "/blah/Ui$";
1009  int list = DETECT_SM_LIST_NOTSET;
1012  AppProto alproto = ALPROTO_UNKNOWN;
1013 
1014  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1015  FAIL_IF_NOT_NULL(pd);
1016  FAIL_IF_NOT(alproto == ALPROTO_HTTP1);
1017 
1019  return result;
1020 }
1021 
1022 /**
1023  * \test DetectPcreParseTest03 make sure we don't allow invalid opts UZi.
1024  */
1025 static int DetectPcreParseTest03 (void)
1026 {
1027  int result = 1;
1028  DetectPcreData *pd = NULL;
1029  const char *teststring = "/blah/UNi";
1030  int list = DETECT_SM_LIST_NOTSET;
1033  AppProto alproto = ALPROTO_UNKNOWN;
1034 
1035  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1036  FAIL_IF_NOT_NULL(pd);
1037 
1039  return result;
1040 }
1041 
1042 /**
1043  * \test DetectPcreParseTest04 make sure we allow escaped "
1044  */
1045 static int DetectPcreParseTest04 (void)
1046 {
1047  int result = 1;
1048  DetectPcreData *pd = NULL;
1049  const char *teststring = "/b\\\"lah/i";
1050  int list = DETECT_SM_LIST_NOTSET;
1053  AppProto alproto = ALPROTO_UNKNOWN;
1054 
1055  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1056  FAIL_IF_NULL(pd);
1057  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1058 
1059  DetectPcreFree(NULL, pd);
1061  return result;
1062 }
1063 
1064 /**
1065  * \test DetectPcreParseTest05 make sure we parse pcre with no opts
1066  */
1067 static int DetectPcreParseTest05 (void)
1068 {
1069  int result = 1;
1070  DetectPcreData *pd = NULL;
1071  const char *teststring = "/b(l|a)h/";
1072  int list = DETECT_SM_LIST_NOTSET;
1075  AppProto alproto = ALPROTO_UNKNOWN;
1076 
1077  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1078  FAIL_IF_NULL(pd);
1079  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1080 
1081  DetectPcreFree(NULL, pd);
1083  return result;
1084 }
1085 
1086 /**
1087  * \test DetectPcreParseTest06 make sure we parse pcre with smi opts
1088  */
1089 static int DetectPcreParseTest06 (void)
1090 {
1091  int result = 1;
1092  DetectPcreData *pd = NULL;
1093  const char *teststring = "/b(l|a)h/smi";
1094  int list = DETECT_SM_LIST_NOTSET;
1097  AppProto alproto = ALPROTO_UNKNOWN;
1098 
1099  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1100  FAIL_IF_NULL(pd);
1101  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1102 
1103  DetectPcreFree(NULL, pd);
1105  return result;
1106 }
1107 
1108 /**
1109  * \test DetectPcreParseTest07 make sure we parse pcre with /Ui opts
1110  */
1111 static int DetectPcreParseTest07 (void)
1112 {
1113  int result = 1;
1114  DetectPcreData *pd = NULL;
1115  const char *teststring = "/blah/Ui";
1116  int list = DETECT_SM_LIST_NOTSET;
1119  AppProto alproto = ALPROTO_UNKNOWN;
1120 
1121  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1122  FAIL_IF_NULL(pd);
1123  FAIL_IF_NOT(alproto == ALPROTO_HTTP1);
1124 
1125  DetectPcreFree(NULL, pd);
1127  return result;
1128 }
1129 
1130 /**
1131  * \test DetectPcreParseTest08 make sure we parse pcre with O opts
1132  */
1133 static int DetectPcreParseTest08 (void)
1134 {
1135  int result = 1;
1136  DetectPcreData *pd = NULL;
1137  const char *teststring = "/b(l|a)h/O";
1138  int list = DETECT_SM_LIST_NOTSET;
1141  AppProto alproto = ALPROTO_UNKNOWN;
1142 
1143  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1144  FAIL_IF_NULL(pd);
1145  FAIL_IF_NOT(alproto == ALPROTO_UNKNOWN);
1146 
1147  DetectPcreFree(NULL, pd);
1149  return result;
1150 }
1151 
1152 /**
1153  * \test DetectPcreParseTest09 make sure we parse pcre with a content
1154  * that has slashes
1155  */
1156 static int DetectPcreParseTest09 (void)
1157 {
1158  DetectPcreData *pd = NULL;
1159  const char *teststring = "/lala\\\\/";
1160  int list = DETECT_SM_LIST_NOTSET;
1163  AppProto alproto = ALPROTO_UNKNOWN;
1164 
1165  pd = DetectPcreParse(de_ctx, teststring, &list, NULL, 0, false, &alproto);
1166  FAIL_IF_NULL(pd);
1167 
1168  DetectPcreFree(NULL, pd);
1170  PASS;
1171 }
1172 
1173 /**
1174  * \test Test pcre option for dce sig(yeah I'm bored of writing test titles).
1175  */
1176 static int DetectPcreParseTest10(void)
1177 {
1178  Signature *s = SigAlloc();
1181 
1183 
1184  FAIL_IF_NOT(DetectPcreSetup(de_ctx, s, "/bamboo/") == 0);
1185  FAIL_IF_NOT(s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
1186 
1187  SigFree(de_ctx, s);
1188 
1189  s = SigAlloc();
1190  FAIL_IF_NULL(s);
1191 
1192  /* failure since we have no preceding content/pcre/bytejump */
1193  FAIL_IF_NOT(DetectPcreSetup(de_ctx, s, "/bamboo/") == 0);
1194  FAIL_IF_NOT(s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
1195 
1196  SigFree(de_ctx, s);
1198 
1199  PASS;
1200 }
1201 
1202 /**
1203  * \test Test pcre option for dce sig.
1204  */
1205 static int DetectPcreParseTest11(void)
1206 {
1207  DetectEngineCtx *de_ctx = NULL;
1208  Signature *s = NULL;
1209  DetectPcreData *data = NULL;
1210 
1213 
1214  de_ctx->flags |= DE_QUIET;
1215  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1216  "(msg:\"Testing bytejump_body\"; "
1217  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1218  "dce_stub_data; "
1219  "pcre:/bamboo/R; sid:1;)");
1220  FAIL_IF(de_ctx == NULL);
1221  s = de_ctx->sig_list;
1222  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1223  FAIL_IF_NOT(s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_PCRE);
1224  data = (DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1226  !(data->flags & DETECT_PCRE_RELATIVE));
1227 
1228  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1229  "(msg:\"Testing bytejump_body\"; "
1230  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1231  "dce_stub_data; "
1232  "pcre:/bamboo/R; sid:1;)");
1233  FAIL_IF_NULL(s->next);
1234  s = s->next;
1235  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1236  FAIL_IF_NOT(s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_PCRE);
1237  data = (DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1239  !(data->flags & DETECT_PCRE_RELATIVE));
1240 
1241  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1242  "(msg:\"Testing bytejump_body\"; "
1243  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1244  "dce_stub_data; "
1245  "pcre:/bamboo/RB; sid:1;)");
1246  FAIL_IF(s->next == NULL);
1247  s = s->next;
1248  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL);
1249  FAIL_IF_NOT(s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_PCRE);
1250  data = (DetectPcreData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1251  FAIL_IF(!(data->flags & DETECT_PCRE_RAWBYTES) ||
1252  !(data->flags & DETECT_PCRE_RELATIVE));
1253 
1254  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1255  "(msg:\"Testing bytejump_body\"; "
1256  "content:\"one\"; pcre:/bamboo/; sid:1;)");
1257  FAIL_IF(s->next == NULL);
1258  s = s->next;
1259  FAIL_IF(s->sm_lists_tail[g_dce_stub_data_buffer_id] != NULL);
1260 
1264 
1265  PASS;
1266 }
1267 
1268 /**
1269  * \test Test pcre option with file data. pcre is relative to file_data,
1270  * so relative flag should be unset.
1271  */
1272 static int DetectPcreParseTest12(void)
1273 {
1274  DetectEngineCtx *de_ctx = NULL;
1275  Signature *s = NULL;
1276  DetectPcreData *data = NULL;
1277 
1280 
1281  de_ctx->flags |= DE_QUIET;
1282  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1283  "(file_data; pcre:/abc/R; sid:1;)");
1284  FAIL_IF (de_ctx->sig_list == NULL);
1285 
1286  s = de_ctx->sig_list;
1287  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1288 
1289  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_PCRE);
1290 
1291  data = (DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1293  !(data->flags & DETECT_PCRE_RELATIVE));
1294 
1298 
1299  PASS;
1300 }
1301 
1302 /**
1303  * \test Test pcre option with file data.
1304  */
1305 static int DetectPcreParseTest13(void)
1306 {
1307  DetectEngineCtx *de_ctx = NULL;
1308  Signature *s = NULL;
1309  DetectPcreData *data = NULL;
1310 
1313 
1314  de_ctx->flags |= DE_QUIET;
1315  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1316  "(file_data; content:\"abc\"; pcre:/def/R; sid:1;)");
1317  FAIL_IF(de_ctx->sig_list == NULL);
1318 
1319  s = de_ctx->sig_list;
1320  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1321 
1322  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_PCRE);
1323 
1324  data = (DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1326  !(data->flags & DETECT_PCRE_RELATIVE));
1327 
1331 
1332  PASS;
1333 }
1334 
1335 /**
1336  * \test Test pcre option with file data.
1337  */
1338 static int DetectPcreParseTest14(void)
1339 {
1340  DetectEngineCtx *de_ctx = NULL;
1341  Signature *s = NULL;
1342  DetectPcreData *data = NULL;
1343 
1345  FAIL_IF(de_ctx == NULL);
1346 
1347  de_ctx->flags |= DE_QUIET;
1348  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1349  "(file_data; pcre:/def/; sid:1;)");
1350  FAIL_IF(de_ctx->sig_list == NULL);
1351 
1352  s = de_ctx->sig_list;
1353  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id] == NULL);
1354 
1355  FAIL_IF(s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_PCRE);
1356 
1357  data = (DetectPcreData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1359  data->flags & DETECT_PCRE_RELATIVE);
1360 
1364 
1365  PASS;
1366 }
1367 
1368 /** \test Check a signature with pcre relative method */
1369 static int DetectPcreParseTest15(void)
1370 {
1371  DetectEngineCtx *de_ctx = NULL;
1372 
1373  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1374 
1375  de_ctx->flags |= DE_QUIET;
1377  "alert tcp any any -> any any "
1378  "(msg:\"Testing pcre relative http_method\"; "
1379  "content:\"GET\"; "
1380  "http_method; pcre:\"/abc/RM\"; sid:1;)");
1382 
1383  if (de_ctx != NULL)
1385  if (de_ctx != NULL)
1387  PASS;
1388 }
1389 
1390 
1391 /** \test Check a signature with pcre relative cookie */
1392 static int DetectPcreParseTest16(void)
1393 {
1394  DetectEngineCtx *de_ctx = NULL;
1395 
1396  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1397 
1398  de_ctx->flags |= DE_QUIET;
1400  "alert tcp any any -> any any "
1401  "(msg:\"Testing pcre relative http_cookie\"; "
1402  "content:\"test\"; "
1403  "http_cookie; pcre:\"/abc/RC\"; sid:1;)");
1405 
1406  if (de_ctx != NULL)
1408  if (de_ctx != NULL)
1410  PASS;
1411 }
1412 
1413 /** \test Check a signature with pcre relative raw header */
1414 static int DetectPcreParseTest17(void)
1415 {
1416  DetectEngineCtx *de_ctx = NULL;
1417 
1418  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1419 
1420  de_ctx->flags |= DE_QUIET;
1422  "alert tcp any any -> any any "
1423  "(msg:\"Testing pcre relative http_raw_header\"; "
1424  "flow:to_server; content:\"test\"; "
1425  "http_raw_header; pcre:\"/abc/RD\"; sid:1;)");
1427 
1428  if (de_ctx != NULL)
1430  if (de_ctx != NULL)
1432  PASS;
1433 }
1434 
1435 /** \test Check a signature with pcre relative header */
1436 static int DetectPcreParseTest18(void)
1437 {
1438  DetectEngineCtx *de_ctx = NULL;
1439 
1440  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1441 
1442  de_ctx->flags |= DE_QUIET;
1444  "alert tcp any any -> any any "
1445  "(msg:\"Testing pcre relative http_header\"; "
1446  "content:\"test\"; "
1447  "http_header; pcre:\"/abc/RH\"; sid:1;)");
1449 
1450  if (de_ctx != NULL)
1452  if (de_ctx != NULL)
1454  PASS;
1455 }
1456 
1457 /** \test Check a signature with pcre relative client-body */
1458 static int DetectPcreParseTest19(void)
1459 {
1460  DetectEngineCtx *de_ctx = NULL;
1461 
1462  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1463 
1464  de_ctx->flags |= DE_QUIET;
1466  "alert tcp any any -> any any "
1467  "(msg:\"Testing pcre relative http_client_body\"; "
1468  "content:\"test\"; "
1469  "http_client_body; pcre:\"/abc/RP\"; sid:1;)");
1471 
1472  if (de_ctx != NULL)
1474  if (de_ctx != NULL)
1476  PASS;
1477 }
1478 
1479 /** \test Check a signature with pcre relative raw uri */
1480 static int DetectPcreParseTest20(void)
1481 {
1482  DetectEngineCtx *de_ctx = NULL;
1483 
1484  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1485 
1486  de_ctx->flags |= DE_QUIET;
1488  "alert tcp any any -> any any "
1489  "(msg:\"Testing http_raw_uri\"; "
1490  "content:\"test\"; "
1491  "http_raw_uri; pcre:\"/abc/RI\"; sid:1;)");
1493 
1494  if (de_ctx != NULL)
1496  if (de_ctx != NULL)
1498  PASS;
1499 }
1500 
1501 /** \test Check a signature with pcre relative uricontent */
1502 static int DetectPcreParseTest21(void)
1503 {
1504  DetectEngineCtx *de_ctx = NULL;
1505 
1506  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1507 
1508  de_ctx->flags |= DE_QUIET;
1510  "alert tcp any any -> any any "
1511  "(msg:\"Testing pcre relative uricontent\"; "
1512  "uricontent:\"test\"; "
1513  "pcre:\"/abc/RU\"; sid:1;)");
1515 
1516  if (de_ctx != NULL)
1518  if (de_ctx != NULL)
1520  PASS;
1521 }
1522 
1523 /** \test Check a signature with pcre relative http_uri */
1524 static int DetectPcreParseTest22(void)
1525 {
1526  DetectEngineCtx *de_ctx = NULL;
1527 
1528  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1529 
1530  de_ctx->flags |= DE_QUIET;
1532  "alert tcp any any -> any any "
1533  "(msg:\"Testing pcre relative http_uri\"; "
1534  "content:\"test\"; "
1535  "http_uri; pcre:\"/abc/RU\"; sid:1;)");
1537 
1538  if (de_ctx != NULL)
1540  if (de_ctx != NULL)
1542  PASS;
1543 }
1544 
1545 /** \test Check a signature with inconsistent pcre relative */
1546 static int DetectPcreParseTest23(void)
1547 {
1548  DetectEngineCtx *de_ctx = NULL;
1549 
1550  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1551 
1552  de_ctx->flags |= DE_QUIET;
1554  "alert tcp any any -> any any "
1555  "(msg:\"Testing inconsistent pcre relative\"; "
1556  "content:\"GET\"; "
1557  "http_cookie; pcre:\"/abc/RM\"; sid:1;)");
1559 
1560  if (de_ctx != NULL)
1562  if (de_ctx != NULL)
1564  PASS;
1565 }
1566 
1567 /** \test Check a signature with inconsistent pcre modifiers */
1568 static int DetectPcreParseTest24(void)
1569 {
1570  DetectEngineCtx *de_ctx = NULL;
1571 
1572  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1573 
1574  de_ctx->flags |= DE_QUIET;
1576  "alert tcp any any -> any any "
1577  "(msg:\"Testing inconsistent pcre modifiers\"; "
1578  "pcre:\"/abc/UI\"; sid:1;)");
1580 
1581  if (de_ctx != NULL)
1583  if (de_ctx != NULL)
1585  PASS;
1586 }
1587 
1588 /** \test Check a signature with inconsistent pcre modifiers */
1589 static int DetectPcreParseTest25(void)
1590 {
1591  DetectEngineCtx *de_ctx = NULL;
1592 
1593  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1594 
1595  de_ctx->flags |= DE_QUIET;
1597  "alert tcp any any -> any any "
1598  "(msg:\"Testing inconsistent pcre modifiers\"; "
1599  "pcre:\"/abc/DH\"; sid:1;)");
1601 
1602  if (de_ctx != NULL)
1604  if (de_ctx != NULL)
1606  PASS;
1607 }
1608 
1609 /** \test Check a signature with inconsistent pcre modifiers */
1610 static int DetectPcreParseTest26(void)
1611 {
1612  DetectEngineCtx *de_ctx = NULL;
1613 
1614  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1615 
1616  de_ctx->flags |= DE_QUIET;
1618  "alert http any any -> any any "
1619  "(msg:\"Testing inconsistent pcre modifiers\"; "
1620  "pcre:\"/abc/F\"; sid:1;)");
1622 
1623  if (de_ctx != NULL)
1625  if (de_ctx != NULL)
1627  PASS;
1628 }
1629 
1630 /** \test Bug 1098 */
1631 static int DetectPcreParseTest27(void)
1632 {
1633  DetectEngineCtx *de_ctx = NULL;
1634 
1635  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1636 
1637  de_ctx->flags |= DE_QUIET;
1638  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any 80 "
1639  "(content:\"baduricontent\"; http_raw_uri; "
1640  "pcre:\"/^[a-z]{5}\\.html/R\"; sid:2; rev:2;)");
1641  FAIL_IF_NOT(de_ctx->sig_list == NULL);
1642 
1643  if (de_ctx != NULL)
1645  if (de_ctx != NULL)
1647  PASS;
1648 }
1649 
1650 /** \test Bug 1957 */
1651 static int DetectPcreParseTest28(void)
1652 {
1653  DetectEngineCtx *de_ctx = NULL;
1654 
1655  FAIL_IF( (de_ctx = DetectEngineCtxInit()) == NULL);
1656 
1657  de_ctx->flags |= DE_QUIET;
1658  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any 80 "
1659  "(content:\"|2E|suricata\"; http_host; pcre:\"/\\x2Esuricata$/W\"; "
1660  "sid:2; rev:2;)");
1662 
1664  PASS;
1665 }
1666 
1667 static int DetectPcreTestSig01(void)
1668 {
1669  uint8_t *buf = (uint8_t *)
1670  "GET /one/ HTTP/1.1\r\n"
1671  "Host: one.example.org\r\n"
1672  "\r\n\r\n"
1673  "GET /two/ HTTP/1.1\r\n"
1674  "Host: two.example.org\r\n"
1675  "\r\n\r\n";
1676  uint16_t buflen = strlen((char *)buf);
1677  Packet *p = NULL;
1678  ThreadVars th_v;
1679  DetectEngineThreadCtx *det_ctx = NULL;
1681 
1682  memset(&th_v, 0, sizeof(th_v));
1683 
1684  StreamTcpInitConfig(true);
1685 
1686  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1687  FAIL_IF_NULL(p);
1688  p->tcph->th_seq = htonl(1000);
1689  Flow *f = UTHBuildFlow(AF_INET, "192.168.1.5", "192.168.1.1", 41424, 80);
1690  FAIL_IF_NULL(f);
1691  f->proto = IPPROTO_TCP;
1692  UTHAddSessionToFlow(f, 1000, 1000);
1693  UTHAddStreamToFlow(f, 0, buf, buflen);
1694 
1695  p->flow = f;
1699  f->alproto = ALPROTO_HTTP1;
1701  FAIL_IF(de_ctx == NULL);
1702 
1703  de_ctx->flags |= DE_QUIET;
1704 
1705  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;)");
1706  FAIL_IF(de_ctx->sig_list == NULL);
1707 
1709  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1710 
1711  int r = AppLayerParserParse(
1712  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, buf, buflen);
1713  FAIL_IF(r != 0);
1714 
1715  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1716  FAIL_IF_NOT(PacketAlertCheck(p, 1) == 1);
1717 
1719  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1721 
1723  UTHFreeFlow(f);
1724 
1725  StreamTcpFreeConfig(true);
1726  UTHFreePackets(&p, 1);
1727  PASS;
1728 }
1729 
1730 static int DetectPcreTestSig02(void)
1731 {
1732  uint8_t *buf = (uint8_t *)
1733  "GET /one/ HTTP/1.1\r\n"
1734  "Host: one.example.org\r\n"
1735  "\r\n\r\n"
1736  "GET /two/ HTTP/1.1\r\n"
1737  "Host: two.example.org\r\n"
1738  "\r\n\r\n";
1739  uint16_t buflen = strlen((char *)buf);
1740  Packet *p = NULL;
1741  Flow f;
1742  ThreadVars th_v;
1743  DetectEngineThreadCtx *det_ctx;
1744 
1745  memset(&th_v, 0, sizeof(th_v));
1746  memset(&f, 0, sizeof(f));
1747 
1748  FLOW_INITIALIZE(&f);
1749 
1750  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1751  p->flow = &f;
1753 
1754  pcre_match_limit = 100;
1755  pcre_match_limit_recursion = 100;
1756 
1758  FAIL_IF(de_ctx == NULL);
1759 
1760  de_ctx->flags |= DE_QUIET;
1761 
1762  de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/two/O\"; sid:2;)");
1763  FAIL_IF(de_ctx->sig_list == NULL);
1764 
1766  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1767 
1768  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1769  FAIL_IF_NOT(PacketAlertCheck(p, 2) == 1);
1770 
1773 
1774  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1776  FLOW_DESTROY(&f);
1777 
1778  UTHFreePackets(&p, 1);
1779  PASS;
1780 }
1781 
1782 /**
1783  * \test DetectPcreTestSig03Real negation test ! outside of "" this sig should not match
1784  */
1785 static int DetectPcreTestSig03(void)
1786 {
1787  uint8_t *buf = (uint8_t *)
1788  "GET /one/ HTTP/1.1\r\n"
1789  "Host: one.example.org\r\n"
1790  "\r\n\r\n"
1791  "GET /two/ HTTP/1.1\r\n"
1792  "Host: two.example.org\r\n"
1793  "\r\n\r\n";
1794  uint16_t buflen = strlen((char *)buf);
1795  Packet *p = NULL;
1796  ThreadVars th_v;
1797  DetectEngineThreadCtx *det_ctx;
1798 
1799  memset(&th_v, 0, sizeof(th_v));
1800 
1801  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1802 
1804  FAIL_IF(de_ctx == NULL);
1805 
1806  de_ctx->flags |= DE_QUIET;
1807 
1808  de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"GET\"; pcre:!\"/two/\"; sid:1;)");
1809  FAIL_IF(de_ctx->sig_list == NULL);
1810 
1812  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1813 
1814  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1815  FAIL_IF(PacketAlertCheck(p, 1));
1818 
1819  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1821 
1822  UTHFreePackets(&p, 1);
1823  PASS;
1824 }
1825 
1826 /**
1827  * \test Check the signature with pcre modifier P (match with L7 to http body data)
1828  */
1829 static int DetectPcreModifPTest04(void)
1830 {
1831  uint8_t httpbuf1[] =
1832  "GET / HTTP/1.1\r\n"
1833  "Host: www.emergingthreats.net\r\n"
1834  "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"
1835  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
1836  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
1837  "Accept-Encoding: gzip,deflate\r\n"
1838  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
1839  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1840  "Server: Apache\r\n"
1841  "X-Powered-By: PHP/5.2.5\r\n"
1842  "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n"
1843  "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n"
1844  "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1845  "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
1846  "Pragma: no-cache\r\n"
1847  "Keep-Alive: timeout=15, max=100\r\n"
1848  "Connection: Keep-Alive\r\n"
1849  "Transfer-Encoding: chunked\r\n"
1850  "Content-Type: text/html; charset=utf-8\r\n"
1851  "\r\n"
1852  "15"
1853  "\r\n"
1854  "<!DOCTYPE html PUBLIC\r\n"
1855  "0\r\n\r\n";
1856 
1857  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1858  TcpSession ssn;
1859  Packet *p = NULL;
1860  Flow f;
1861  Signature *s = NULL;
1862  ThreadVars th_v;
1863  DetectEngineThreadCtx *det_ctx;
1865 
1866  memset(&th_v, 0, sizeof(th_v));
1867  memset(&f, 0, sizeof(f));
1868  memset(&ssn, 0, sizeof(ssn));
1869 
1870  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1871 
1872  FLOW_INITIALIZE(&f);
1873  f.protoctx = (void *)&ssn;
1874  f.proto = IPPROTO_TCP;
1875  f.flags |= FLOW_IPV4;
1876 
1877  p->flow = &f;
1881  f.alproto = ALPROTO_HTTP1;
1882 
1883  StreamTcpInitConfig(true);
1884 
1886  FAIL_IF(de_ctx == NULL);
1887 
1888  de_ctx->flags |= DE_QUIET;
1889 
1890  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
1891  "\"Pcre modifier P\"; pcre:\"/DOCTYPE/P\"; "
1892  "sid:1;)");
1893  FAIL_IF(s == NULL);
1894 
1895  s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\""
1896  "Pcre modifier P (no match)\"; pcre:\"/blah/P\"; sid:2;)");
1897  FAIL_IF(s->next == NULL);
1898 
1900  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1901 
1902  FLOWLOCK_WRLOCK(&f);
1903  int r = AppLayerParserParse(
1904  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1905  FAIL_IF(r != 0);
1906  FLOWLOCK_UNLOCK(&f);
1907 
1908  HtpState *http_state = f.alstate;
1909  FAIL_IF(http_state == NULL);
1910 
1911  /* do detect */
1912  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1913 
1914  FAIL_IF(!(PacketAlertCheck(p, 1)));
1915  FAIL_IF(PacketAlertCheck(p, 2));
1916 
1917  if (alp_tctx != NULL)
1919  if (de_ctx != NULL) SigGroupCleanup(de_ctx);
1920  if (de_ctx != NULL) SigCleanSignatures(de_ctx);
1921  if (de_ctx != NULL) DetectEngineCtxFree(de_ctx);
1922 
1923  StreamTcpFreeConfig(true);
1924  FLOW_DESTROY(&f);
1925  UTHFreePackets(&p, 1);
1926  PASS;
1927 }
1928 
1929 /**
1930  * \test Check the signature with pcre modifier P (match with L7 to http body data)
1931  * over fragmented chunks (DOCTYPE fragmented)
1932  */
1933 static int DetectPcreModifPTest05(void)
1934 {
1935  uint8_t httpbuf1[] =
1936  "GET / HTTP/1.1\r\n"
1937  "Host: www.emergingthreats.net\r\n"
1938  "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"
1939  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
1940  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
1941  "Accept-Encoding: gzip,deflate\r\n"
1942  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
1943  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1944  "Server: Apache\r\n"
1945  "X-Powered-By: PHP/5.2.5\r\n"
1946  "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n"
1947  "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n"
1948  "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
1949  "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n"
1950  "Pragma: no-cache\r\n"
1951  "Keep-Alive: timeout=15, max=100\r\n"
1952  "Connection: Keep-Alive\r\n"
1953  "Transfer-Encoding: chunked\r\n"
1954  "Content-Type: text/html; charset=utf-8\r\n"
1955  "\r\n"
1956  "15"
1957  "\r\n"
1958  "<!DOC";
1959 
1960  uint8_t httpbuf2[] = "<!DOCTYPE html PUBLIC\r\n0\r\n\r\n";
1961 
1962  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1963  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1964  TcpSession ssn;
1965  Packet *p1 = NULL;
1966  Packet *p2 = NULL;
1967  Flow f;
1968  Signature *s = NULL;
1969  ThreadVars th_v;
1970  DetectEngineThreadCtx *det_ctx;
1972 
1973  memset(&th_v, 0, sizeof(th_v));
1974  memset(&f, 0, sizeof(f));
1975  memset(&ssn, 0, sizeof(ssn));
1976 
1977  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1978  p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1979 
1980  FLOW_INITIALIZE(&f);
1981  f.protoctx = (void *)&ssn;
1982  f.proto = IPPROTO_TCP;
1983  f.flags |= FLOW_IPV4;
1984 
1985  p1->flow = &f;
1989  p2->flow = &f;
1993  f.alproto = ALPROTO_HTTP1;
1994 
1995  StreamTcpInitConfig(true);
1996 
1998  FAIL_IF(de_ctx == NULL);
1999 
2000  de_ctx->flags |= DE_QUIET;
2001 
2002  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2003  "\"Pcre modifier P\"; pcre:\"/DOC/P\"; "
2004  "sid:1;)");
2005  FAIL_IF(s == NULL);
2006 
2007  s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\""
2008  "Pcre modifier P (no match)\"; pcre:\"/DOCTYPE/P\"; sid:2;)");
2009  FAIL_IF(s->next == NULL);
2010 
2012  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2013 
2014  FLOWLOCK_WRLOCK(&f);
2015  int r = AppLayerParserParse(
2016  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2017  FAIL_IF(r != 0);
2018  FLOWLOCK_UNLOCK(&f);
2019 
2020  /* do detect for p1 */
2021  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2022 
2023  HtpState *http_state = f.alstate;
2024  FAIL_IF(http_state == NULL);
2025 
2026  FAIL_IF(PacketAlertCheck(p1, 1));
2027 
2028  FAIL_IF(PacketAlertCheck(p1, 2));
2029 
2030  FLOWLOCK_WRLOCK(&f);
2031  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2032  FAIL_IF(r != 0);
2033  FLOWLOCK_UNLOCK(&f);
2034 
2035  /* do detect for p2 */
2036  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2037 
2038  FAIL_IF(!(PacketAlertCheck(p2, 1)));
2039 
2040  FAIL_IF(!(PacketAlertCheck(p2, 2)));
2041 
2042  if (alp_tctx != NULL)
2044  if (de_ctx != NULL) SigGroupCleanup(de_ctx);
2045  if (de_ctx != NULL) SigCleanSignatures(de_ctx);
2046  if (de_ctx != NULL) DetectEngineCtxFree(de_ctx);
2047 
2048  StreamTcpFreeConfig(true);
2049  FLOW_DESTROY(&f);
2050  UTHFreePackets(&p1, 1);
2051  UTHFreePackets(&p2, 1);
2052  PASS;
2053 }
2054 
2055 static int DetectPcreTestSig06(void)
2056 {
2057  uint8_t *buf = (uint8_t *)
2058  "lalala lalala\\ lala\n";
2059  uint16_t buflen = strlen((char *)buf);
2060  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
2061  int result = 0;
2062 
2063  char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/ lalala\\\\/\"; sid:1;)";
2064  if (UTHPacketMatchSig(p, sig) == 0) {
2065  result = 0;
2066  goto end;
2067  }
2068  result = 1;
2069 end:
2070  if (p != NULL)
2071  UTHFreePacket(p);
2072  return result;
2073 }
2074 
2075 /** \test anchored pcre */
2076 static int DetectPcreTestSig07(void)
2077 {
2078  uint8_t *buf = (uint8_t *)
2079  "lalala\n";
2080  uint16_t buflen = strlen((char *)buf);
2081  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
2082 
2083  char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)";
2084  FAIL_IF(UTHPacketMatchSig(p, sig) == 0);
2085 
2086  if (p != NULL)
2087  UTHFreePacket(p);
2088  PASS;
2089 }
2090 
2091 /** \test anchored pcre */
2092 static int DetectPcreTestSig08(void)
2093 {
2094  /* test it also without ending in a newline "\n" */
2095  uint8_t *buf = (uint8_t *)
2096  "lalala";
2097  uint16_t buflen = strlen((char *)buf);
2098  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
2099 
2100  char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)";
2101  FAIL_IF(UTHPacketMatchSig(p, sig) == 0);
2102 
2103  if (p != NULL)
2104  UTHFreePacket(p);
2105  PASS;
2106 }
2107 
2108 /** \test Check the signature working to alert when cookie modifier is
2109  * passed to pcre
2110  */
2111 static int DetectPcreTestSig09(void)
2112 {
2113  Flow f;
2114  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2115  "Cookie: dummy\r\n\r\n";
2116  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2117  TcpSession ssn;
2118  Packet *p = NULL;
2119  Signature *s = NULL;
2120  ThreadVars th_v;
2121  DetectEngineThreadCtx *det_ctx = NULL;
2122  HtpState *http_state = NULL;
2124 
2125  memset(&th_v, 0, sizeof(th_v));
2126  memset(&p, 0, sizeof(p));
2127  memset(&f, 0, sizeof(f));
2128  memset(&ssn, 0, sizeof(ssn));
2129 
2130  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2131 
2132  FLOW_INITIALIZE(&f);
2133  f.protoctx = (void *)&ssn;
2134  f.proto = IPPROTO_TCP;
2135  f.flags |= FLOW_IPV4;
2136 
2137  p->flow = &f;
2141  f.alproto = ALPROTO_HTTP1;
2142 
2143  StreamTcpInitConfig(true);
2144 
2146  FAIL_IF(de_ctx == NULL);
2147 
2148  de_ctx->flags |= DE_QUIET;
2149 
2150  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2151  "\"HTTP cookie\"; pcre:\"/dummy/C\"; "
2152  " sid:1;)");
2153  FAIL_IF(s == NULL);
2154 
2156  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2157 
2158  FLOWLOCK_WRLOCK(&f);
2159  int r = AppLayerParserParse(
2160  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2161  FAIL_IF(r != 0);
2162  FLOWLOCK_UNLOCK(&f);
2163 
2164  http_state = f.alstate;
2165  FAIL_IF(http_state == NULL);
2166 
2167  /* do detect */
2168  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2169 
2170  FAIL_IF(!PacketAlertCheck(p, 1));
2171 
2172  if (alp_tctx != NULL)
2174  if (det_ctx != NULL) {
2175  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2176  }
2177  if (de_ctx != NULL) {
2180  }
2181 
2182  StreamTcpFreeConfig(true);
2183  UTHFreePackets(&p, 1);
2184  PASS;
2185 }
2186 
2187 /** \test Check the signature working to alert when cookie modifier is
2188  * passed to a negated pcre
2189  */
2190 static int DetectPcreTestSig10(void)
2191 {
2192  Flow f;
2193  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2194  "Cookie: dummoOOooooO\r\n\r\n";
2195  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2196  TcpSession ssn;
2197  Packet *p = NULL;
2198  Signature *s = NULL;
2199  ThreadVars th_v;
2200  DetectEngineThreadCtx *det_ctx = NULL;
2201  HtpState *http_state = NULL;
2203 
2204  memset(&th_v, 0, sizeof(th_v));
2205  memset(&p, 0, sizeof(p));
2206  memset(&f, 0, sizeof(f));
2207  memset(&ssn, 0, sizeof(ssn));
2208 
2209  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2210 
2211  FLOW_INITIALIZE(&f);
2212  f.protoctx = (void *)&ssn;
2213  f.proto = IPPROTO_TCP;
2214  f.flags |= FLOW_IPV4;
2215 
2216  p->flow = &f;
2220  f.alproto = ALPROTO_HTTP1;
2221 
2222  StreamTcpInitConfig(true);
2223 
2225  FAIL_IF(de_ctx == NULL);
2226 
2227  de_ctx->flags |= DE_QUIET;
2228 
2229  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2230  "\"HTTP cookie\"; pcre:!\"/dummy/C\"; "
2231  " sid:1;)");
2232  FAIL_IF(s == NULL);
2233 
2235  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2236 
2237  FLOWLOCK_WRLOCK(&f);
2238  int r = AppLayerParserParse(
2239  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2240  FAIL_IF(r != 0);
2241  FLOWLOCK_UNLOCK(&f);
2242 
2243  http_state = f.alstate;
2244  FAIL_IF(http_state == NULL);
2245 
2246  /* do detect */
2247  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2248 
2249  FAIL_IF(!PacketAlertCheck(p, 1));
2250 
2251  if (alp_tctx != NULL)
2253  if (det_ctx != NULL) {
2254  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2255  }
2256  if (de_ctx != NULL) {
2259  }
2260 
2261  StreamTcpFreeConfig(true);
2262  UTHFreePackets(&p, 1);
2263  PASS;
2264 }
2265 
2266 /** \test Check the signature working to alert when method modifier is
2267  * passed to pcre
2268  */
2269 static int DetectPcreTestSig11(void)
2270 {
2271  Flow f;
2272  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2273  "Cookie: dummy\r\n\r\n";
2274  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2275  TcpSession ssn;
2276  Packet *p = NULL;
2277  Signature *s = NULL;
2278  ThreadVars th_v;
2279  DetectEngineThreadCtx *det_ctx = NULL;
2280  HtpState *http_state = NULL;
2282 
2283  memset(&th_v, 0, sizeof(th_v));
2284  memset(&p, 0, sizeof(p));
2285  memset(&f, 0, sizeof(f));
2286  memset(&ssn, 0, sizeof(ssn));
2287 
2288  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2289 
2290  FLOW_INITIALIZE(&f);
2291  f.protoctx = (void *)&ssn;
2292  f.proto = IPPROTO_TCP;
2293  f.flags |= FLOW_IPV4;
2294 
2295  p->flow = &f;
2299  f.alproto = ALPROTO_HTTP1;
2300 
2301  StreamTcpInitConfig(true);
2302 
2304  FAIL_IF(de_ctx == NULL);
2305 
2306  de_ctx->flags |= DE_QUIET;
2307 
2308  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2309  "\"HTTP method\"; pcre:\"/POST/M\"; "
2310  " sid:1;)");
2311  FAIL_IF(s == NULL);
2312 
2314  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2315 
2316  FLOWLOCK_WRLOCK(&f);
2317  int r = AppLayerParserParse(
2318  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2319  FAIL_IF(r != 0);
2320  FLOWLOCK_UNLOCK(&f);
2321 
2322  http_state = f.alstate;
2323  FAIL_IF(http_state == NULL);
2324 
2325  /* do detect */
2326  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2327 
2328  FAIL_IF(!PacketAlertCheck(p, 1));
2329 
2330  if (alp_tctx != NULL)
2332  if (det_ctx != NULL) {
2333  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2334  }
2335  if (de_ctx != NULL) {
2338  }
2339 
2340  StreamTcpFreeConfig(true);
2341  UTHFreePackets(&p, 1);
2342  PASS;
2343 }
2344 
2345 /** \test Check the signature working to alert when method modifier is
2346  * passed to a negated pcre
2347  */
2348 static int DetectPcreTestSig12(void)
2349 {
2350  Flow f;
2351  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2352  "Cookie: dummoOOooooO\r\n\r\n";
2353  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2354  TcpSession ssn;
2355  Packet *p = NULL;
2356  Signature *s = NULL;
2357  ThreadVars th_v;
2358  DetectEngineThreadCtx *det_ctx = NULL;
2359  HtpState *http_state = NULL;
2361 
2362  memset(&th_v, 0, sizeof(th_v));
2363  memset(&p, 0, sizeof(p));
2364  memset(&f, 0, sizeof(f));
2365  memset(&ssn, 0, sizeof(ssn));
2366 
2367  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2368 
2369  FLOW_INITIALIZE(&f);
2370  f.protoctx = (void *)&ssn;
2371  f.proto = IPPROTO_TCP;
2372  f.flags |= FLOW_IPV4;
2373 
2374  p->flow = &f;
2378  f.alproto = ALPROTO_HTTP1;
2379 
2380  StreamTcpInitConfig(true);
2381 
2383  FAIL_IF(de_ctx == NULL);
2384 
2385  de_ctx->flags |= DE_QUIET;
2386 
2387  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2388  "\"HTTP method\"; pcre:!\"/POST/M\"; "
2389  " sid:1;)");
2390  FAIL_IF(s == NULL);
2391 
2393  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2394 
2395  FLOWLOCK_WRLOCK(&f);
2396  int r = AppLayerParserParse(
2397  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2398  FAIL_IF(r != 0);
2399  FLOWLOCK_UNLOCK(&f);
2400 
2401  http_state = f.alstate;
2402  FAIL_IF(http_state == NULL);
2403 
2404  /* do detect */
2405  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2406 
2407  FAIL_IF(!PacketAlertCheck(p, 1));
2408 
2409  if (alp_tctx != NULL)
2411  if (det_ctx != NULL) {
2412  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2413  }
2414  if (de_ctx != NULL) {
2417  }
2418 
2419  StreamTcpFreeConfig(true);
2420  UTHFreePackets(&p, 1);
2421  PASS;
2422 }
2423 
2424 /** \test Check the signature working to alert when header modifier is
2425  * passed to pcre
2426  */
2427 static int DetectPcreTestSig13(void)
2428 {
2429  Flow f;
2430  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2431  "Cookie: dummy\r\n\r\n";
2432  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2433  TcpSession ssn;
2434  Packet *p = NULL;
2435  Signature *s = NULL;
2436  ThreadVars th_v;
2437  DetectEngineThreadCtx *det_ctx = NULL;
2438  HtpState *http_state = NULL;
2440 
2441  memset(&th_v, 0, sizeof(th_v));
2442  memset(&p, 0, sizeof(p));
2443  memset(&f, 0, sizeof(f));
2444  memset(&ssn, 0, sizeof(ssn));
2445 
2446  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2447 
2448  FLOW_INITIALIZE(&f);
2449  f.protoctx = (void *)&ssn;
2450  f.proto = IPPROTO_TCP;
2451  f.flags |= FLOW_IPV4;
2452 
2453  p->flow = &f;
2457  f.alproto = ALPROTO_HTTP1;
2458 
2459  StreamTcpInitConfig(true);
2460 
2462  FAIL_IF(de_ctx == NULL);
2463 
2464  de_ctx->flags |= DE_QUIET;
2465 
2466  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2467  "\"HTTP header\"; pcre:\"/User[-_]Agent[:]?\\sMozilla/H\"; "
2468  " sid:1;)");
2469  FAIL_IF(s == NULL);
2470 
2472  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2473 
2474  FLOWLOCK_WRLOCK(&f);
2475  int r = AppLayerParserParse(
2476  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2477  FAIL_IF(r != 0);
2478  FLOWLOCK_UNLOCK(&f);
2479 
2480  http_state = f.alstate;
2481  FAIL_IF(http_state == NULL);
2482 
2483  /* do detect */
2484  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2485 
2486  FAIL_IF(!PacketAlertCheck(p, 1));
2487 
2488  if (alp_tctx != NULL)
2490  if (det_ctx != NULL) {
2491  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2492  }
2493  if (de_ctx != NULL) {
2496  }
2497 
2498  StreamTcpFreeConfig(true);
2499  UTHFreePackets(&p, 1);
2500  PASS;
2501 }
2502 
2503 /** \test Check the signature working to alert when header modifier is
2504  * passed to a negated pcre
2505  */
2506 static int DetectPcreTestSig14(void)
2507 {
2508  Flow f;
2509  uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: IEXPLORER/1.0\r\n"
2510  "Cookie: dummoOOooooO\r\n\r\n";
2511  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2512  TcpSession ssn;
2513  Packet *p = NULL;
2514  Signature *s = NULL;
2515  ThreadVars th_v;
2516  DetectEngineThreadCtx *det_ctx = NULL;
2517  HtpState *http_state = NULL;
2519 
2520  memset(&th_v, 0, sizeof(th_v));
2521  memset(&p, 0, sizeof(p));
2522  memset(&f, 0, sizeof(f));
2523  memset(&ssn, 0, sizeof(ssn));
2524 
2525  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2526 
2527  FLOW_INITIALIZE(&f);
2528  f.protoctx = (void *)&ssn;
2529  f.proto = IPPROTO_TCP;
2530  f.flags |= FLOW_IPV4;
2531 
2532  p->flow = &f;
2536  f.alproto = ALPROTO_HTTP1;
2537 
2538  StreamTcpInitConfig(true);
2539 
2541  FAIL_IF(de_ctx == NULL);
2542 
2543  de_ctx->flags |= DE_QUIET;
2544 
2545  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2546  "\"HTTP header\"; pcre:!\"/User-Agent[:]?\\s+Mozilla/H\"; "
2547  " sid:1;)");
2548  FAIL_IF(s == NULL);
2549 
2551  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2552 
2553  FLOWLOCK_WRLOCK(&f);
2554  int r = AppLayerParserParse(
2555  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2556  FAIL_IF(r != 0);
2557  FLOWLOCK_UNLOCK(&f);
2558 
2559  http_state = f.alstate;
2560  FAIL_IF(http_state == NULL);
2561 
2562  /* do detect */
2563  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2564 
2565  FAIL_IF(!PacketAlertCheck(p, 1));
2566 
2567  if (alp_tctx != NULL)
2569  if (det_ctx != NULL) {
2570  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2571  }
2572  if (de_ctx != NULL) {
2575  }
2576 
2577  StreamTcpFreeConfig(true);
2578  UTHFreePackets(&p, 1);
2579  PASS;
2580 }
2581 
2582 /** \test Check the signature working to alert when cookie and relative modifiers are
2583  * passed to pcre
2584  */
2585 static int DetectPcreTestSig15(void)
2586 {
2587  Flow f;
2588  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2589  "Cookie: dummy 1234\r\n\r\n";
2590  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2591  TcpSession ssn;
2592  Packet *p = NULL;
2593  Signature *s = NULL;
2594  ThreadVars th_v;
2595  DetectEngineThreadCtx *det_ctx = NULL;
2596  HtpState *http_state = NULL;
2598 
2599  memset(&th_v, 0, sizeof(th_v));
2600  memset(&p, 0, sizeof(p));
2601  memset(&f, 0, sizeof(f));
2602  memset(&ssn, 0, sizeof(ssn));
2603 
2604  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2605 
2606  FLOW_INITIALIZE(&f);
2607  f.protoctx = (void *)&ssn;
2608  f.proto = IPPROTO_TCP;
2609  f.flags |= FLOW_IPV4;
2610 
2611  p->flow = &f;
2615  f.alproto = ALPROTO_HTTP1;
2616 
2617  StreamTcpInitConfig(true);
2618 
2620  FAIL_IF(de_ctx == NULL);
2621 
2622  de_ctx->flags |= DE_QUIET;
2623 
2624  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2625  "\"pcre relative HTTP cookie\"; content:\"dummy\";"
2626  " http_cookie; pcre:\"/1234/RC\"; "
2627  " sid:1;)");
2628  FAIL_IF(s == NULL);
2629 
2631  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2632 
2633  FLOWLOCK_WRLOCK(&f);
2634  int r = AppLayerParserParse(
2635  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2636  FAIL_IF(r != 0);
2637  FLOWLOCK_UNLOCK(&f);
2638 
2639  http_state = f.alstate;
2640  FAIL_IF(http_state == NULL);
2641 
2642  /* do detect */
2643  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2644 
2645  FAIL_IF(!PacketAlertCheck(p, 1));
2646 
2647  if (alp_tctx != NULL)
2649  if (det_ctx != NULL) {
2650  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2651  }
2652  if (de_ctx != NULL) {
2655  }
2656 
2657  StreamTcpFreeConfig(true);
2658  UTHFreePackets(&p, 1);
2659  PASS;
2660 }
2661 
2662 /** \test Check the signature working to alert when method and relative modifiers are
2663  * passed to pcre
2664  */
2665 static int DetectPcreTestSig16(void)
2666 {
2667  Flow f;
2668  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"
2669  "Cookie: dummy 1234\r\n\r\n";
2670  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2671  TcpSession ssn;
2672  Packet *p = NULL;
2673  Signature *s = NULL;
2674  ThreadVars th_v;
2675  DetectEngineThreadCtx *det_ctx = NULL;
2676  HtpState *http_state = NULL;
2678 
2679  memset(&th_v, 0, sizeof(th_v));
2680  memset(&p, 0, sizeof(p));
2681  memset(&f, 0, sizeof(f));
2682  memset(&ssn, 0, sizeof(ssn));
2683 
2684  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2685 
2686  FLOW_INITIALIZE(&f);
2687  f.protoctx = (void *)&ssn;
2688  f.proto = IPPROTO_TCP;
2689  f.flags |= FLOW_IPV4;
2690 
2691  p->flow = &f;
2695  f.alproto = ALPROTO_HTTP1;
2696 
2697  StreamTcpInitConfig(true);
2698 
2700  FAIL_IF(de_ctx == NULL);
2701 
2702  de_ctx->flags |= DE_QUIET;
2703 
2704  s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:"
2705  "\"pcre relative HTTP method\"; content:\"PO\";"
2706  " http_method; pcre:\"/ST/RM\"; "
2707  " sid:1;)");
2708  FAIL_IF(s == NULL);
2709 
2711  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2712 
2713  FLOWLOCK_WRLOCK(&f);
2714  int r = AppLayerParserParse(
2715  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2716  FAIL_IF(r != 0);
2717  FLOWLOCK_UNLOCK(&f);
2718 
2719  http_state = f.alstate;
2720  FAIL_IF(http_state == NULL);
2721 
2722  /* do detect */
2723  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2724 
2725  FAIL_IF(!PacketAlertCheck(p, 1));
2726 
2727  if (alp_tctx != NULL)
2729  if (det_ctx != NULL) {
2730  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2731  }
2732  if (de_ctx != NULL) {
2735  }
2736 
2737  StreamTcpFreeConfig(true);
2738  UTHFreePackets(&p, 1);
2739  PASS;
2740 }
2741 
2742 /** \test Test tracking of body chunks per transactions (on requests)
2743  */
2744 static int DetectPcreTxBodyChunksTest01(void)
2745 {
2746  Flow f;
2747  TcpSession ssn;
2748  Packet *p = NULL;
2749  uint8_t httpbuf1[] = "GET / HTTP/1.1\r\n";
2750  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2751  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
2752  uint8_t httpbuf4[] = "Body one!!";
2753  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2754  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2755  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2756  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2757  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
2758  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
2759  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2760  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2761  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2762  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
2764 
2765  memset(&f, 0, sizeof(f));
2766  memset(&ssn, 0, sizeof(ssn));
2767 
2768  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2769 
2770  FLOW_INITIALIZE(&f);
2771  f.protoctx = (void *)&ssn;
2772  f.proto = IPPROTO_TCP;
2773  f.flags |= FLOW_IPV4;
2774 
2775  p->flow = &f;
2779  f.alproto = ALPROTO_HTTP1;
2780 
2781  StreamTcpInitConfig(true);
2782 
2784 
2785  FLOWLOCK_WRLOCK(&f);
2786  int r = AppLayerParserParse(
2787  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
2788  FAIL_IF(r != 0);
2789 
2790  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2791  FAIL_IF(r != 0);
2792 
2793  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
2794  FAIL_IF(r != 0);
2795 
2796  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
2797  FAIL_IF(r != 0);
2798 
2799  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
2800  FAIL_IF(r != 0);
2801 
2802  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
2803  FAIL_IF(r != 0);
2804 
2805  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
2806  FAIL_IF(r != 0);
2807 
2808  /* Now we should have 2 transactions, each with it's own list
2809  * of request body chunks (let's test it) */
2810 
2811  HtpState *htp_state = f.alstate;
2812  FAIL_IF(htp_state == NULL);
2813 
2814  /* hardcoded check of the transactions and it's client body chunks */
2815  FAIL_IF(AppLayerParserGetTxCnt(&f, htp_state) != 2);
2816 
2817  htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 0);
2818  htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 1);
2819 
2820  HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2821  FAIL_IF(htud == NULL);
2822 
2823  HtpBodyChunk *cur = htud->request_body.first;
2824  FAIL_IF(htud->request_body.first == NULL);
2825 
2826  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body one!!", 10) != 1);
2827 
2828  htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2829 
2830  cur = htud->request_body.first;
2831  FAIL_IF(htud->request_body.first == NULL);
2832 
2833  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body two!!", 10) != 1);
2834 
2835  if (alp_tctx != NULL)
2837  FLOWLOCK_UNLOCK(&f);
2838  StreamTcpFreeConfig(true);
2839  FLOW_DESTROY(&f);
2840  UTHFreePacket(p);
2841  PASS;
2842 }
2843 
2844 /** \test test pcre P modifier with multiple pipelined http transactions */
2845 static int DetectPcreTxBodyChunksTest02(void)
2846 {
2847  Signature *s = NULL;
2848  DetectEngineThreadCtx *det_ctx = NULL;
2849  ThreadVars th_v;
2850  Flow f;
2851  TcpSession ssn;
2852  Packet *p = NULL;
2853  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
2854  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
2855  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
2856  uint8_t httpbuf4[] = "Body one!!";
2857  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2858  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2859  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
2860  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
2861  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
2862  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
2863  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
2864  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
2865  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
2866  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
2868 
2869  memset(&th_v, 0, sizeof(th_v));
2870  memset(&f, 0, sizeof(f));
2871  memset(&ssn, 0, sizeof(ssn));
2872 
2873  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2874 
2875  FLOW_INITIALIZE(&f);
2876  f.protoctx = (void *)&ssn;
2877  f.proto = IPPROTO_TCP;
2878  f.flags |= FLOW_IPV4;
2879 
2880  p->flow = &f;
2884  f.alproto = ALPROTO_HTTP1;
2885 
2886  StreamTcpInitConfig(true);
2887 
2889  FAIL_IF(de_ctx == NULL);
2890 
2891  de_ctx->flags |= DE_QUIET;
2892 
2893  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;)");
2894  FAIL_IF(s == NULL);
2895  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;)");
2896  FAIL_IF(s == NULL);
2897 
2899  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2900 
2901  FLOWLOCK_WRLOCK(&f);
2902  int r = AppLayerParserParse(
2903  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2904  FAIL_IF(r != 0);
2905  FLOWLOCK_UNLOCK(&f);
2906 
2907  /* do detect */
2908  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2909  FAIL_IF(PacketAlertCheck(p, 1));
2910  p->alerts.cnt = 0;
2911 
2912  FLOWLOCK_WRLOCK(&f);
2913  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2914  FAIL_IF(r != 0);
2915  FLOWLOCK_UNLOCK(&f);
2916 
2917  /* do detect */
2918  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2919  FAIL_IF(PacketAlertCheck(p, 1));
2920  p->alerts.cnt = 0;
2921 
2922  FLOWLOCK_WRLOCK(&f);
2923  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
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_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
2934  FAIL_IF(r != 0);
2935  FLOWLOCK_UNLOCK(&f);
2936 
2937  /* do detect */
2938  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2939  FAIL_IF(!(PacketAlertCheck(p, 1)));
2940  p->alerts.cnt = 0;
2941 
2942  FLOWLOCK_WRLOCK(&f);
2943  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
2944  FAIL_IF(r != 0);
2945  FLOWLOCK_UNLOCK(&f);
2946 
2947  /* do detect */
2948  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2949  FAIL_IF(PacketAlertCheck(p, 1));
2950  p->alerts.cnt = 0;
2951 
2952  FLOWLOCK_WRLOCK(&f);
2953  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
2954  FAIL_IF(r != 0);
2955  FLOWLOCK_UNLOCK(&f);
2956 
2957  /* do detect */
2958  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2959  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
2960  p->alerts.cnt = 0;
2961 
2962  SCLogDebug("sending data chunk 7");
2963 
2964  FLOWLOCK_WRLOCK(&f);
2965  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
2966  FAIL_IF(r != 0);
2967  FLOWLOCK_UNLOCK(&f);
2968 
2969  /* do detect */
2970  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2971  FAIL_IF(!(PacketAlertCheck(p, 2)));
2972  p->alerts.cnt = 0;
2973 
2974  HtpState *htp_state = f.alstate;
2975  FAIL_IF(htp_state == NULL);
2976 
2977  /* hardcoded check of the transactions and it's client body chunks */
2978  FAIL_IF(AppLayerParserGetTxCnt(&f, htp_state) != 2);
2979 
2980  htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 0);
2981  htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, 1);
2982 
2983  HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
2984 
2985  HtpBodyChunk *cur = htud->request_body.first;
2986  FAIL_IF(htud->request_body.first == NULL);
2987 
2988  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body one!!", 10) != 1);
2989 
2990  htud = (HtpTxUserData *) htp_tx_get_user_data(t2);
2991 
2992  cur = htud->request_body.first;
2993  FAIL_IF(htud->request_body.first == NULL);
2994 
2995  FAIL_IF(StreamingBufferSegmentCompareRawData(htud->request_body.sb, &cur->sbseg, (uint8_t *)"Body two!!", 10) != 1);
2996 
2997  if (alp_tctx != NULL)
2999  if (det_ctx != NULL) {
3000  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
3001  }
3002  if (de_ctx != NULL) {
3005  }
3006 
3007  StreamTcpFreeConfig(true);
3008  FLOW_DESTROY(&f);
3009  UTHFreePacket(p);
3010  PASS;
3011 }
3012 
3013 /** \test multiple http transactions and body chunks of request handling */
3014 static int DetectPcreTxBodyChunksTest03(void)
3015 {
3016  Signature *s = NULL;
3017  DetectEngineThreadCtx *det_ctx = NULL;
3018  ThreadVars th_v;
3019  Flow f;
3020  TcpSession ssn;
3021  Packet *p = NULL;
3022  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
3023  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
3024  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
3025  uint8_t httpbuf4[] = "Body one!!";
3026  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3027  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
3028  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
3029  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
3030  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
3031  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
3032  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!";
3033  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
3034  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
3035  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
3037 
3038  memset(&th_v, 0, sizeof(th_v));
3039  memset(&f, 0, sizeof(f));
3040  memset(&ssn, 0, sizeof(ssn));
3041 
3042  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3043 
3044  FLOW_INITIALIZE(&f);
3045  f.protoctx = (void *)&ssn;
3046  f.proto = IPPROTO_TCP;
3047  f.flags |= FLOW_IPV4;
3048 
3049  p->flow = &f;
3053  f.alproto = ALPROTO_HTTP1;
3054 
3055  StreamTcpInitConfig(true);
3056 
3058  FAIL_IF(de_ctx == NULL);
3059 
3060  de_ctx->flags |= DE_QUIET;
3061 
3062  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;)");
3063  FAIL_IF(s == NULL);
3064  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;)");
3065  FAIL_IF(s == NULL);
3066 
3068  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3069 
3070  FLOWLOCK_WRLOCK(&f);
3071  int r = AppLayerParserParse(
3072  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
3073  FAIL_IF(r != 0);
3074  FLOWLOCK_UNLOCK(&f);
3075 
3076  /* do detect */
3077  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3078  FAIL_IF(PacketAlertCheck(p, 1));
3079  p->alerts.cnt = 0;
3080 
3081  FLOWLOCK_WRLOCK(&f);
3082  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
3083  FAIL_IF(r != 0);
3084  FLOWLOCK_UNLOCK(&f);
3085 
3086  /* do detect */
3087  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3088  FAIL_IF(PacketAlertCheck(p, 1));
3089  p->alerts.cnt = 0;
3090 
3091  FLOWLOCK_WRLOCK(&f);
3092  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
3093  FAIL_IF(r != 0);
3094  FLOWLOCK_UNLOCK(&f);
3095 
3096  /* do detect */
3097  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3098  FAIL_IF(PacketAlertCheck(p, 1));
3099  p->alerts.cnt = 0;
3100 
3101  FLOWLOCK_WRLOCK(&f);
3102  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
3103  FAIL_IF(r != 0);
3104  FLOWLOCK_UNLOCK(&f);
3105 
3106  /* do detect */
3107  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3108  FAIL_IF(!(PacketAlertCheck(p, 1)));
3109  p->alerts.cnt = 0;
3110 
3111  FLOWLOCK_WRLOCK(&f);
3112  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
3113  FAIL_IF(r != 0);
3114  FLOWLOCK_UNLOCK(&f);
3115 
3116  /* do detect */
3117  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3118  FAIL_IF(PacketAlertCheck(p, 1));
3119  p->alerts.cnt = 0;
3120 
3121  FLOWLOCK_WRLOCK(&f);
3122  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
3123  FAIL_IF(r != 0);
3124  FLOWLOCK_UNLOCK(&f);
3125 
3126  /* do detect */
3127  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3128  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
3129  p->alerts.cnt = 0;
3130 
3131  SCLogDebug("sending data chunk 7");
3132 
3133  FLOWLOCK_WRLOCK(&f);
3134  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
3135  FAIL_IF(r != 0);
3136  FLOWLOCK_UNLOCK(&f);
3137 
3138  /* do detect */
3139  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3140  FAIL_IF(!(PacketAlertCheck(p, 2)));
3141  p->alerts.cnt = 0;
3142 
3143  HtpState *htp_state = f.alstate;
3144  FAIL_IF(htp_state == NULL);
3145 
3146  FAIL_IF(AppLayerParserGetTxCnt(&f, htp_state) != 2);
3147 
3148  if (alp_tctx != NULL)
3150  if (det_ctx != NULL) {
3151  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
3152  }
3153  if (de_ctx != NULL) {
3156  }
3157 
3158  StreamTcpFreeConfig(true);
3159  FLOW_DESTROY(&f);
3160  UTHFreePacket(p);
3161  PASS;
3162 }
3163 
3164 /**
3165  * \test flowvar capture on http buffer
3166  */
3167 static int DetectPcreFlowvarCapture01(void)
3168 {
3169  uint8_t uabuf1[] =
3170  "Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13";
3171  uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */
3172  uint8_t httpbuf1[] =
3173  "GET / HTTP/1.1\r\n"
3174  "Host: www.emergingthreats.net\r\n"
3175  "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"
3176  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3177  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3178  "Accept-Encoding: gzip,deflate\r\n"
3179  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3180  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3181  "Server: Apache\r\n"
3182  "\r\n"
3183  "<!DOCTYPE html PUBLIC\r\n\r\n";
3184  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3185  TcpSession ssn;
3186  Packet *p1 = NULL;
3187  Flow f;
3188  Signature *s = NULL;
3189  ThreadVars th_v;
3190  DetectEngineThreadCtx *det_ctx;
3192 
3193  memset(&th_v, 0, sizeof(th_v));
3194  memset(&f, 0, sizeof(f));
3195  memset(&ssn, 0, sizeof(ssn));
3196 
3197  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3198 
3199  FLOW_INITIALIZE(&f);
3200  f.protoctx = (void *)&ssn;
3201  f.proto = IPPROTO_TCP;
3202  f.flags |= FLOW_IPV4;
3203  f.alproto = ALPROTO_HTTP1;
3204 
3205  p1->flow = &f;
3209 
3210  StreamTcpInitConfig(true);
3211 
3213  FAIL_IF(de_ctx == NULL);
3214  de_ctx->flags |= DE_QUIET;
3215 
3216  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P<flow_ua>.*)\\r\\n/HR\"; sid:1;)");
3217  FAIL_IF(s == NULL);
3218 
3219  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3220  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3221  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3222  DetectPcreData *pd = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3223 
3225  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3226 
3227  FLOWLOCK_WRLOCK(&f);
3228  int r = AppLayerParserParse(
3229  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
3230  FAIL_IF(r != 0);
3231  FLOWLOCK_UNLOCK(&f);
3232 
3233  HtpState *http_state = f.alstate;
3234  FAIL_IF(http_state == NULL);
3235 
3236  /* do detect for p1 */
3237  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3238 
3239  FAIL_IF(!(PacketAlertCheck(p1, 1)));
3240 
3241  FlowVar *fv = FlowVarGet(&f, pd->capids[0]);
3242  FAIL_IF(fv == NULL);
3243 
3244  FAIL_IF(fv->data.fv_str.value_len != ualen1);
3245 
3246  if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) {
3247  PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len);
3248  PrintRawDataFp(stdout, uabuf1, ualen1);
3249 
3250  printf("buffer mismatch: ");
3251  FAIL;
3252  }
3253 
3254  if (alp_tctx != NULL)
3256  if (de_ctx != NULL)
3258 
3259  StreamTcpFreeConfig(true);
3260  FLOW_DESTROY(&f);
3261  UTHFreePackets(&p1, 1);
3262  PASS;
3263 }
3264 
3265 /**
3266  * \test flowvar capture on http buffer, capture overwrite
3267  */
3268 static int DetectPcreFlowvarCapture02(void)
3269 {
3270  uint8_t uabuf1[] =
3271  "Apache";
3272  uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */
3273  uint8_t httpbuf1[] =
3274  "GET / HTTP/1.1\r\n"
3275  "Host: www.emergingthreats.net\r\n"
3276  "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"
3277  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3278  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3279  "Accept-Encoding: gzip,deflate\r\n"
3280  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3281  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3282  "Server: Apache\r\n"
3283  "\r\n"
3284  "<!DOCTYPE html PUBLIC\r\n\r\n";
3285  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3286  TcpSession ssn;
3287  Packet *p1 = NULL;
3288  Flow f;
3289  Signature *s = NULL;
3290  ThreadVars th_v;
3291  DetectEngineThreadCtx *det_ctx;
3293 
3294  memset(&th_v, 0, sizeof(th_v));
3295  memset(&f, 0, sizeof(f));
3296  memset(&ssn, 0, sizeof(ssn));
3297 
3298  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3299 
3300  FLOW_INITIALIZE(&f);
3301  f.protoctx = (void *)&ssn;
3302  f.proto = IPPROTO_TCP;
3303  f.flags |= FLOW_IPV4;
3304  f.alproto = ALPROTO_HTTP1;
3305 
3306  p1->flow = &f;
3310 
3311  StreamTcpInitConfig(true);
3312 
3314  FAIL_IF(de_ctx == NULL);
3315  de_ctx->flags |= DE_QUIET;
3316 
3317  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;)");
3318  FAIL_IF(s == NULL);
3319 
3320  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3321  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3322  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3323  DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3324 
3325  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;)");
3326  FAIL_IF(s == NULL);
3327 
3328  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3329  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3330  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3331  DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3332 
3333  FAIL_IF(pd1->capids[0] != pd2->capids[0]);
3334 
3339  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3340 
3341  FLOWLOCK_WRLOCK(&f);
3342  int r = AppLayerParserParse(
3343  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
3344  FAIL_IF(r != 0);
3345  FLOWLOCK_UNLOCK(&f);
3346 
3347  HtpState *http_state = f.alstate;
3348  FAIL_IF(http_state == NULL);
3349 
3350  /* do detect for p1 */
3351  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3352 
3353  FAIL_IF(!(PacketAlertCheck(p1, 1)));
3354 
3355  FlowVar *fv = FlowVarGet(&f, pd1->capids[0]);
3356  FAIL_IF(fv == NULL);
3357 
3358  if (fv->data.fv_str.value_len != ualen1) {
3359  PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len);
3360  PrintRawDataFp(stdout, uabuf1, ualen1);
3361  printf("%u != %u: ", fv->data.fv_str.value_len, ualen1);
3362  FAIL;
3363  }
3364 
3365  if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) {
3366  PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len);
3367  PrintRawDataFp(stdout, uabuf1, ualen1);
3368 
3369  printf("buffer mismatch: ");
3370  FAIL;
3371  }
3372 
3373  if (alp_tctx != NULL)
3375  if (de_ctx != NULL)
3377 
3378  StreamTcpFreeConfig(true);
3379  FLOW_DESTROY(&f);
3380  UTHFreePackets(&p1, 1);
3381  PASS;
3382 }
3383 
3384 /**
3385  * \test flowvar capture on http buffer, capture overwrite + no matching sigs, so flowvars should not be set.
3386  */
3387 static int DetectPcreFlowvarCapture03(void)
3388 {
3389  uint8_t httpbuf1[] =
3390  "GET / HTTP/1.1\r\n"
3391  "Host: www.emergingthreats.net\r\n"
3392  "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"
3393  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n"
3394  "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n"
3395  "Accept-Encoding: gzip,deflate\r\n"
3396  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
3397  "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n"
3398  "Server: Apache\r\n"
3399  "\r\n"
3400  "<!DOCTYPE html PUBLIC\r\n\r\n";
3401  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
3402  TcpSession ssn;
3403  Packet *p1 = NULL;
3404  Flow f;
3405  Signature *s = NULL;
3406  ThreadVars th_v;
3407  DetectEngineThreadCtx *det_ctx;
3409 
3410  memset(&th_v, 0, sizeof(th_v));
3411  memset(&f, 0, sizeof(f));
3412  memset(&ssn, 0, sizeof(ssn));
3413 
3414  p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3415 
3416  FLOW_INITIALIZE(&f);
3417  f.protoctx = (void *)&ssn;
3418  f.proto = IPPROTO_TCP;
3419  f.flags |= FLOW_IPV4;
3420  f.alproto = ALPROTO_HTTP1;
3421 
3422  p1->flow = &f;
3426 
3427  StreamTcpInitConfig(true);
3428 
3430  FAIL_IF(de_ctx == NULL);
3431  de_ctx->flags |= DE_QUIET;
3432 
3433  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;)");
3434  FAIL_IF(s == NULL);
3435 
3436  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3437  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3438  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3439  DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3440 
3441  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;)");
3442  FAIL_IF(s == NULL);
3443 
3444  FAIL_IF(s->sm_lists[g_http_header_buffer_id] == NULL ||
3445  s->sm_lists[g_http_header_buffer_id]->next == NULL ||
3446  s->sm_lists[g_http_header_buffer_id]->next->type != DETECT_PCRE);
3447  DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[g_http_header_buffer_id]->next->ctx;
3448 
3449  FAIL_IF(pd1->capids[0] != pd2->capids[0]);
3450 
3452  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3453 
3454  FLOWLOCK_WRLOCK(&f);
3455  int r = AppLayerParserParse(
3456  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
3457  FAIL_IF(r != 0);
3458  FLOWLOCK_UNLOCK(&f);
3459 
3460  HtpState *http_state = f.alstate;
3461  FAIL_IF(http_state == NULL);
3462 
3463  /* do detect for p1 */
3464  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3465 
3466  FAIL_IF(PacketAlertCheck(p1, 1));
3467 
3468  FlowVar *fv = FlowVarGet(&f, pd1->capids[0]);
3469  FAIL_IF(fv != NULL);
3470 
3471  if (alp_tctx != NULL)
3473  if (de_ctx != NULL)
3475 
3476  StreamTcpFreeConfig(true);
3477  FLOW_DESTROY(&f);
3478  UTHFreePackets(&p1, 1);
3479  PASS;
3480 }
3481 
3482 /**
3483  * \brief Test parsing of pcre's with the W modifier set.
3484  */
3485 static int DetectPcreParseHttpHost(void)
3486 {
3487  AppProto alproto = ALPROTO_UNKNOWN;
3488  int list = DETECT_SM_LIST_NOTSET;
3490 
3491  FAIL_IF(de_ctx == NULL);
3492 
3493  DetectPcreData *pd = DetectPcreParse(de_ctx, "/domain\\.com/W", &list, NULL, 0, false, &alproto);
3494  FAIL_IF(pd == NULL);
3495  DetectPcreFree(NULL, pd);
3496 
3497  list = DETECT_SM_LIST_NOTSET;
3498  pd = DetectPcreParse(de_ctx, "/dOmain\\.com/W", &list, NULL, 0, false, &alproto);
3499  FAIL_IF(pd != NULL);
3500 
3501  /* Uppercase meta characters are valid. */
3502  list = DETECT_SM_LIST_NOTSET;
3503  pd = DetectPcreParse(de_ctx, "/domain\\D+\\.com/W", &list, NULL, 0, false, &alproto);
3504  FAIL_IF(pd == NULL);
3505  DetectPcreFree(NULL, pd);
3506 
3507  /* This should not parse as the first \ escapes the second \, then
3508  * we have a D. */
3509  list = DETECT_SM_LIST_NOTSET;
3510  pd = DetectPcreParse(de_ctx, "/\\\\Ddomain\\.com/W", &list, NULL, 0, false, &alproto);
3511  FAIL_IF(pd != NULL);
3512 
3514  PASS;
3515 }
3516 
3517 /**
3518  * \brief Test parsing of capture extension
3519  */
3520 static int DetectPcreParseCaptureTest(void)
3521 {
3523  FAIL_IF(de_ctx == NULL);
3524 
3525  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
3526  "(content:\"Server: \"; http_header; pcre:\"/(.*)\\r\\n/HR, flow:somecapture\"; content:\"xyz\"; http_header; sid:1;)");
3527  FAIL_IF(s == NULL);
3528  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
3529  "(content:\"Server: \"; http_header; pcre:\"/(flow:.*)\\r\\n/HR\"; content:\"xyz\"; http_header; sid:2;)");
3530  FAIL_IF(s == NULL);
3531  s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
3532  "(content:\"Server: \"; http_header; pcre:\"/([a-z]+)([0-9]+)\\r\\n/HR, flow:somecapture, pkt:anothercap\"; content:\"xyz\"; http_header; sid:3;)");
3533  FAIL_IF(s == NULL);
3535  "alert http any any -> any any "
3536  "(content:\"Server: \"; http_header; pcre:\"/([a-z]+)\\r\\n/HR, flow:somecapture, "
3537  "pkt:anothercap\"; content:\"xyz\"; http_header; sid:3;)");
3538  FAIL_IF_NOT_NULL(s);
3539 
3541 
3542  uint32_t capid = VarNameStoreLookupByName("somecapture", VAR_TYPE_FLOW_VAR);
3543  FAIL_IF (capid != 1);
3544  capid = VarNameStoreLookupByName("anothercap", VAR_TYPE_PKT_VAR);
3545  FAIL_IF (capid != 2);
3546 
3548  PASS;
3549 }
3550 
3551 /**
3552  * \brief this function registers unit tests for DetectPcre
3553  */
3554 static void DetectPcreRegisterTests(void)
3555 {
3556  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
3557  g_http_header_buffer_id = DetectBufferTypeGetByName("http_header");
3558  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
3559 
3560  UtRegisterTest("DetectPcreParseTest01", DetectPcreParseTest01);
3561  UtRegisterTest("DetectPcreParseTest02", DetectPcreParseTest02);
3562  UtRegisterTest("DetectPcreParseTest03", DetectPcreParseTest03);
3563  UtRegisterTest("DetectPcreParseTest04", DetectPcreParseTest04);
3564  UtRegisterTest("DetectPcreParseTest05", DetectPcreParseTest05);
3565  UtRegisterTest("DetectPcreParseTest06", DetectPcreParseTest06);
3566  UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07);
3567  UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08);
3568  UtRegisterTest("DetectPcreParseTest09", DetectPcreParseTest09);
3569  UtRegisterTest("DetectPcreParseTest10", DetectPcreParseTest10);
3570  UtRegisterTest("DetectPcreParseTest11", DetectPcreParseTest11);
3571  UtRegisterTest("DetectPcreParseTest12", DetectPcreParseTest12);
3572  UtRegisterTest("DetectPcreParseTest13", DetectPcreParseTest13);
3573  UtRegisterTest("DetectPcreParseTest14", DetectPcreParseTest14);
3574  UtRegisterTest("DetectPcreParseTest15", DetectPcreParseTest15);
3575  UtRegisterTest("DetectPcreParseTest16", DetectPcreParseTest16);
3576  UtRegisterTest("DetectPcreParseTest17", DetectPcreParseTest17);
3577  UtRegisterTest("DetectPcreParseTest18", DetectPcreParseTest18);
3578  UtRegisterTest("DetectPcreParseTest19", DetectPcreParseTest19);
3579  UtRegisterTest("DetectPcreParseTest20", DetectPcreParseTest20);
3580  UtRegisterTest("DetectPcreParseTest21", DetectPcreParseTest21);
3581  UtRegisterTest("DetectPcreParseTest22", DetectPcreParseTest22);
3582  UtRegisterTest("DetectPcreParseTest23", DetectPcreParseTest23);
3583  UtRegisterTest("DetectPcreParseTest24", DetectPcreParseTest24);
3584  UtRegisterTest("DetectPcreParseTest25", DetectPcreParseTest25);
3585  UtRegisterTest("DetectPcreParseTest26", DetectPcreParseTest26);
3586  UtRegisterTest("DetectPcreParseTest27", DetectPcreParseTest27);
3587  UtRegisterTest("DetectPcreParseTest28", DetectPcreParseTest28);
3588 
3589  UtRegisterTest("DetectPcreTestSig01 -- pcre test", DetectPcreTestSig01);
3590  UtRegisterTest("DetectPcreTestSig02 -- pcre test", DetectPcreTestSig02);
3591  UtRegisterTest("DetectPcreTestSig03 -- negated pcre test",
3592  DetectPcreTestSig03);
3593 
3594  UtRegisterTest("DetectPcreModifPTest04 -- Modifier P",
3595  DetectPcreModifPTest04);
3596  UtRegisterTest("DetectPcreModifPTest05 -- Modifier P fragmented",
3597  DetectPcreModifPTest05);
3598  UtRegisterTest("DetectPcreTestSig06", DetectPcreTestSig06);
3599  UtRegisterTest("DetectPcreTestSig07 -- anchored pcre",
3600  DetectPcreTestSig07);
3601  UtRegisterTest("DetectPcreTestSig08 -- anchored pcre",
3602  DetectPcreTestSig08);
3603  UtRegisterTest("DetectPcreTestSig09 -- Cookie modifier",
3604  DetectPcreTestSig09);
3605  UtRegisterTest("DetectPcreTestSig10 -- negated Cookie modifier",
3606  DetectPcreTestSig10);
3607  UtRegisterTest("DetectPcreTestSig11 -- Method modifier",
3608  DetectPcreTestSig11);
3609  UtRegisterTest("DetectPcreTestSig12 -- negated Method modifier",
3610  DetectPcreTestSig12);
3611  UtRegisterTest("DetectPcreTestSig13 -- Header modifier",
3612  DetectPcreTestSig13);
3613  UtRegisterTest("DetectPcreTestSig14 -- negated Header modifier",
3614  DetectPcreTestSig14);
3615  UtRegisterTest("DetectPcreTestSig15 -- relative Cookie modifier",
3616  DetectPcreTestSig15);
3617  UtRegisterTest("DetectPcreTestSig16 -- relative Method modifier",
3618  DetectPcreTestSig16);
3619 
3620  UtRegisterTest("DetectPcreTxBodyChunksTest01",
3621  DetectPcreTxBodyChunksTest01);
3622  UtRegisterTest("DetectPcreTxBodyChunksTest02 -- modifier P, body chunks per tx",
3623  DetectPcreTxBodyChunksTest02);
3624  UtRegisterTest("DetectPcreTxBodyChunksTest03 -- modifier P, body chunks per tx",
3625  DetectPcreTxBodyChunksTest03);
3626 
3627  UtRegisterTest("DetectPcreFlowvarCapture01 -- capture for http_header",
3628  DetectPcreFlowvarCapture01);
3629  UtRegisterTest("DetectPcreFlowvarCapture02 -- capture for http_header",
3630  DetectPcreFlowvarCapture02);
3631  UtRegisterTest("DetectPcreFlowvarCapture03 -- capture for http_header",
3632  DetectPcreFlowvarCapture03);
3633 
3634  UtRegisterTest("DetectPcreParseHttpHost", DetectPcreParseHttpHost);
3635  UtRegisterTest("DetectPcreParseCaptureTest", DetectPcreParseCaptureTest);
3636 
3637 }
3638 #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:1204
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:1489
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:1031
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:1203
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1152
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:1191
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:1201
stream-tcp.h
HtpBody_::sb
StreamingBuffer * sb
Definition: app-layer-htp.h:191
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1388
DetectEngineCtx_::rule_file
char * rule_file
Definition: detect.h:863
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3097
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:60
Signature_::alproto
AppProto alproto
Definition: detect.h:521
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
SIGMATCH_QUOTES_OPTIONAL
#define SIGMATCH_QUOTES_OPTIONAL
Definition: detect.h:1385
Flow_::proto
uint8_t proto
Definition: flow.h:375
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:77
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:353
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2076
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-pcre.c:66
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1195
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:758
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:2067
HtpTxUserData_::request_body
HtpBody request_body
Definition: app-layer-htp.h:218
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:277
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:225
util-var-name.h
MIN
#define MIN(x, y)
Definition: suricata-common.h:372
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
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1653
SC_ERR_VAR_LIMIT
@ SC_ERR_VAR_LIMIT
Definition: util-error.h:328
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:41
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:645
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:445
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine.c:957
StreamingBufferSegmentCompareRawData
int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t *rawdata, uint32_t rawdata_len)
Definition: util-streaming-buffer.c:851
Flow_::protoctx
void * protoctx
Definition: flow.h:451
SigMatchData_
Data needed for Match()
Definition: detect.h:329
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
detect-pcre.h
PARSE_CAPTURE_REGEX
#define PARSE_CAPTURE_REGEX
Definition: detect-pcre.c:65
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:98
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:566
util-unittest.h
HtpBody_::first
HtpBodyChunk * first
Definition: app-layer-htp.h:188
HtpState_
Definition: app-layer-htp.h:245
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:270
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:832
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:590
SC_MATCH_LIMIT_RECURSION_DEFAULT
#define SC_MATCH_LIMIT_RECURSION_DEFAULT
Definition: detect-pcre.c:69
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
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:1003
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:472
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:20
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2513
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:267
SignatureInitData_::list
int list
Definition: detect.h:494
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
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:323
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2001
Signature_::flags
uint32_t flags
Definition: detect.h:518
stream.h
SC_MATCH_LIMIT_DEFAULT
#define SC_MATCH_LIMIT_DEFAULT
Definition: detect-pcre.c:68
Packet_
Definition: decode.h:414
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:1393
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:587
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
SignatureInitData_::negated
bool negated
Definition: detect.h:474
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1169
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:62
DETECT_VAR_TYPE_FLOW_POSTMATCH
#define DETECT_VAR_TYPE_FLOW_POSTMATCH
Definition: detect.h:644
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1090
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:1934
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:251
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:115
FlowVar_::data
union FlowVar_::@107 data
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:2381
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:2771
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:670
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:3020
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:1211
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:2979
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:531
HtpBodyChunk_
Definition: app-layer-htp.h:179
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
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:764
HtpTxUserData_
Definition: app-layer-htp.h:210
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:1033
str
#define str(s)
Definition: suricata-common.h:268
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:486
Flow_::flags
uint32_t flags
Definition: flow.h:431
detect-parse.h
Signature_
Signature container.
Definition: detect.h:517
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_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:227
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2022
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:869
DetectPcreData_
Definition: detect-pcre.h:39
DetectParseFreeRegex
void DetectParseFreeRegex(DetectParseRegex *r)
Definition: detect-parse.c:2451
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:759
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:85
DETECT_PCRE_RELATIVE
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:29
SigAlloc
Signature * SigAlloc(void)
Definition: detect-parse.c:1264
UTHRemoveSessionFromFlow
int UTHRemoveSessionFromFlow(Flow *f)
Definition: util-unittest-helper.c:569
DetectEngineCtx_::rule_line
int rule_line
Definition: detect.h:864
TcpSession_
Definition: stream-tcp-private.h:260
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:460
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:2489
flow-var.h
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1083
HtpBodyChunk_::sbseg
StreamingBufferSegment sbseg
Definition: app-layer-htp.h:182
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:1149
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1193
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