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