suricata
detect-urilen.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 Gurvinder Singh <gurvindersighdahiya@gmail.com>
22  *
23  * Implements the urilen keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "app-layer.h"
28 #include "app-layer-protos.h"
29 #include "app-layer-htp.h"
30 #include "util-unittest.h"
31 #include "util-unittest-helper.h"
32 
33 #include "detect.h"
34 #include "detect-parse.h"
35 #include "detect-engine.h"
36 #include "detect-engine-state.h"
37 #include "detect-content.h"
38 
39 #include "detect-urilen.h"
40 #include "util-debug.h"
41 #include "util-byte.h"
42 #include "flow-util.h"
43 #include "stream-tcp.h"
44 
45 /**
46  * \brief Regex for parsing our urilen
47  */
48 #define PARSE_REGEX "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,5})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,5}))?\\s*(?:,\\s*(norm|raw))?\\s*$"
49 
50 static DetectParseRegex parse_regex;
51 
52 /*prototypes*/
53 static int DetectUrilenSetup (DetectEngineCtx *, Signature *, const char *);
54 static void DetectUrilenFree (DetectEngineCtx *, void *);
55 #ifdef UNITTESTS
56 static void DetectUrilenRegisterTests (void);
57 #endif
58 static int g_http_uri_buffer_id = 0;
59 static int g_http_raw_uri_buffer_id = 0;
60 
61 /**
62  * \brief Registration function for urilen: keyword
63  */
64 
66 {
68  sigmatch_table[DETECT_AL_URILEN].desc = "match on the length of the HTTP uri";
69  sigmatch_table[DETECT_AL_URILEN].url = "/rules/http-keywords.html#urilen";
71  sigmatch_table[DETECT_AL_URILEN].Setup = DetectUrilenSetup;
72  sigmatch_table[DETECT_AL_URILEN].Free = DetectUrilenFree;
73 #ifdef UNITTESTS
74  sigmatch_table[DETECT_AL_URILEN].RegisterTests = DetectUrilenRegisterTests;
75 #endif
76  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
77 
78  g_http_uri_buffer_id = DetectBufferTypeRegister("http_uri");
79  g_http_raw_uri_buffer_id = DetectBufferTypeRegister("http_raw_uri");
80 }
81 
82 /**
83  * \brief This function is used to parse urilen options passed via urilen: keyword
84  *
85  * \param urilenstr Pointer to the user provided urilen options
86  *
87  * \retval urilend pointer to DetectUrilenData on success
88  * \retval NULL on failure
89  */
90 
91 static DetectUrilenData *DetectUrilenParse (const char *urilenstr)
92 {
93  DetectUrilenData *urilend = NULL;
94  char *arg1 = NULL;
95  char *arg2 = NULL;
96  char *arg3 = NULL;
97  char *arg4 = NULL;
98  char *arg5 = NULL;
99  int ret = 0, res = 0;
100  size_t pcre2_len;
101 
102  ret = DetectParsePcreExec(&parse_regex, urilenstr, 0, 0);
103  if (ret < 3 || ret > 6) {
104  SCLogError(SC_ERR_PCRE_PARSE, "urilen option pcre parse error: \"%s\"", urilenstr);
105  goto error;
106  }
107  const char *str_ptr;
108 
109  SCLogDebug("ret %d", ret);
110 
111  res = SC_Pcre2SubstringGet(parse_regex.match, 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
112  if (res < 0) {
113  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
114  goto error;
115  }
116  arg1 = (char *) str_ptr;
117  SCLogDebug("Arg1 \"%s\"", arg1);
118 
119  res = pcre2_substring_get_bynumber(parse_regex.match, 2, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
120  if (res < 0) {
121  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
122  goto error;
123  }
124  arg2 = (char *) str_ptr;
125  SCLogDebug("Arg2 \"%s\"", arg2);
126 
127  if (ret > 3) {
128  res = SC_Pcre2SubstringGet(parse_regex.match, 3, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
129  if (res < 0) {
130  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
131  goto error;
132  }
133  arg3 = (char *) str_ptr;
134  SCLogDebug("Arg3 \"%s\"", arg3);
135 
136  if (ret > 4) {
137  res = SC_Pcre2SubstringGet(parse_regex.match, 4, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
138  if (res < 0) {
139  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
140  goto error;
141  }
142  arg4 = (char *) str_ptr;
143  SCLogDebug("Arg4 \"%s\"", arg4);
144  }
145  if (ret > 5) {
146  res = pcre2_substring_get_bynumber(
147  parse_regex.match, 5, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
148  if (res < 0) {
149  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
150  goto error;
151  }
152  arg5 = (char *) str_ptr;
153  SCLogDebug("Arg5 \"%s\"", arg5);
154  }
155  }
156 
157  urilend = SCMalloc(sizeof (DetectUrilenData));
158  if (unlikely(urilend == NULL))
159  goto error;
160  memset(urilend, 0, sizeof(DetectUrilenData));
161 
162  if (arg1 != NULL && arg1[0] == '<')
163  urilend->mode = DETECT_URILEN_LT;
164  else if (arg1 != NULL && arg1[0] == '>')
165  urilend->mode = DETECT_URILEN_GT;
166  else
167  urilend->mode = DETECT_URILEN_EQ;
168 
169  if (arg3 != NULL && strcmp("<>", arg3) == 0) {
170  if (arg1 != NULL && strlen(arg1) != 0) {
171  SCLogError(SC_ERR_INVALID_ARGUMENT,"Range specified but mode also set");
172  goto error;
173  }
174  urilend->mode = DETECT_URILEN_RA;
175  }
176 
177  /** set the first urilen value */
178  if (StringParseUint16(&urilend->urilen1,10,strlen(arg2),arg2) <= 0){
179  SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg2);
180  goto error;
181  }
182 
183  /** set the second urilen value if specified */
184  if (arg4 != NULL && strlen(arg4) > 0) {
185  if (urilend->mode != DETECT_URILEN_RA) {
186  SCLogError(SC_ERR_INVALID_ARGUMENT,"Multiple urilen values specified"
187  " but mode is not range");
188  goto error;
189  }
190 
191  if(StringParseUint16(&urilend->urilen2,10,strlen(arg4),arg4) <= 0)
192  {
193  SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg4);
194  goto error;
195  }
196 
197  if (urilend->urilen2 <= urilend->urilen1){
198  SCLogError(SC_ERR_INVALID_ARGUMENT,"urilen2:%"PRIu16" <= urilen:"
199  "%"PRIu16"",urilend->urilen2,urilend->urilen1);
200  goto error;
201  }
202  }
203 
204  if (arg5 != NULL) {
205  if (strcasecmp("raw", arg5) == 0) {
206  urilend->raw_buffer = 1;
207  }
208  }
209 
210  if (arg1 != NULL)
211  pcre2_substring_free((PCRE2_UCHAR *)arg1);
212  pcre2_substring_free((PCRE2_UCHAR *)arg2);
213  if (arg3 != NULL)
214  pcre2_substring_free((PCRE2_UCHAR *)arg3);
215  if (arg4 != NULL)
216  pcre2_substring_free((PCRE2_UCHAR *)arg4);
217  if (arg5 != NULL)
218  pcre2_substring_free((PCRE2_UCHAR *)arg5);
219  return urilend;
220 
221 error:
222  if (urilend)
223  SCFree(urilend);
224  if (arg1 != NULL)
225  pcre2_substring_free((PCRE2_UCHAR *)arg1);
226  if (arg2 != NULL)
227  pcre2_substring_free((PCRE2_UCHAR *)arg2);
228  if (arg3 != NULL)
229  pcre2_substring_free((PCRE2_UCHAR *)arg3);
230  if (arg4 != NULL)
231  pcre2_substring_free((PCRE2_UCHAR *)arg4);
232  if (arg5 != NULL)
233  pcre2_substring_free((PCRE2_UCHAR *)arg5);
234  return NULL;
235 }
236 
237 /**
238  * \brief this function is used to parse urilen data into the current signature
239  *
240  * \param de_ctx pointer to the Detection Engine Context
241  * \param s pointer to the Current Signature
242  * \param urilenstr pointer to the user provided urilen options
243  *
244  * \retval 0 on Success
245  * \retval -1 on Failure
246  */
247 static int DetectUrilenSetup (DetectEngineCtx *de_ctx, Signature *s, const char *urilenstr)
248 {
249  SCEnter();
250  DetectUrilenData *urilend = NULL;
251  SigMatch *sm = NULL;
252 
254  return -1;
255 
256  urilend = DetectUrilenParse(urilenstr);
257  if (urilend == NULL)
258  goto error;
259  sm = SigMatchAlloc();
260  if (sm == NULL)
261  goto error;
262  sm->type = DETECT_AL_URILEN;
263  sm->ctx = (void *)urilend;
264 
265  if (urilend->raw_buffer)
266  SigMatchAppendSMToList(s, sm, g_http_raw_uri_buffer_id);
267  else
268  SigMatchAppendSMToList(s, sm, g_http_uri_buffer_id);
269 
270  SCReturnInt(0);
271 
272 error:
273  DetectUrilenFree(de_ctx, urilend);
274  SCReturnInt(-1);
275 }
276 
277 /**
278  * \brief this function will free memory associated with DetectUrilenData
279  *
280  * \param ptr pointer to DetectUrilenData
281  */
282 static void DetectUrilenFree(DetectEngineCtx *de_ctx, void *ptr)
283 {
284  if (ptr == NULL)
285  return;
286 
287  DetectUrilenData *urilend = (DetectUrilenData *)ptr;
288  SCFree(urilend);
289 }
290 
291 /** \brief set prefilter dsize pair
292  * \param s signature to get dsize value from
293  */
295 {
296  uint16_t high = 65535;
297  bool found = false;
298 
299  SigMatch *sm = s->init_data->smlists[list];
300  for ( ; sm != NULL; sm = sm->next) {
301  if (sm->type != DETECT_AL_URILEN)
302  continue;
303 
305 
306  switch (dd->mode) {
307  case DETECT_URILEN_LT:
308  high = dd->urilen1 + 1;
309  break;
310  case DETECT_URILEN_EQ:
311  high = dd->urilen1;
312  break;
313  case DETECT_URILEN_RA:
314  high = dd->urilen2 + 1;
315  break;
316  case DETECT_URILEN_GT:
317  high = 65535;
318  break;
319  }
320  found = true;
321  }
322 
323  // skip 65535 to avoid mismatch on uri > 64k
324  if (!found || high == 65535)
325  return;
326 
327  SCLogDebug("high %u", high);
328 
329  sm = s->init_data->smlists[list];
330  for ( ; sm != NULL; sm = sm->next) {
331  if (sm->type != DETECT_CONTENT) {
332  continue;
333  }
335  if (cd == NULL) {
336  continue;
337  }
338 
339  if (cd->depth == 0 || cd->depth > high) {
340  cd->depth = (uint16_t)high;
341  SCLogDebug("updated %u, content %u to have depth %u "
342  "because of urilen.", s->id, cd->id, cd->depth);
343  }
344  }
345 }
346 
347 bool DetectUrilenValidateContent(const Signature *s, int list, const char **sigerror)
348 {
349  const SigMatch *sm = s->init_data->smlists[list];
350  for ( ; sm != NULL; sm = sm->next) {
351  if (sm->type != DETECT_CONTENT) {
352  continue;
353  }
355  if (cd == NULL) {
356  continue;
357  }
358 
359  if (cd->depth && cd->depth < cd->content_len) {
360  *sigerror = "depth or urilen smaller than content len";
361  SCLogError(SC_ERR_INVALID_SIGNATURE, "depth or urilen %u smaller "
362  "than content len %u", cd->depth, cd->content_len);
363  return false;
364  }
365  }
366  return true;
367 }
368 
369 #ifdef UNITTESTS
370 
371 #include "stream.h"
372 #include "stream-tcp-private.h"
373 #include "stream-tcp-reassemble.h"
374 #include "detect-engine.h"
375 #include "detect-engine-mpm.h"
376 #include "app-layer-parser.h"
377 
378 /** \test Test the Urilen keyword setup */
379 static int DetectUrilenParseTest01(void)
380 {
381  int ret = 0;
382  DetectUrilenData *urilend = NULL;
383 
384  urilend = DetectUrilenParse("10");
385  if (urilend != NULL) {
386  if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_EQ &&
387  !urilend->raw_buffer)
388  ret = 1;
389 
390  DetectUrilenFree(NULL, urilend);
391  }
392  return ret;
393 }
394 
395 /** \test Test the Urilen keyword setup */
396 static int DetectUrilenParseTest02(void)
397 {
398  int ret = 0;
399  DetectUrilenData *urilend = NULL;
400 
401  urilend = DetectUrilenParse(" < 10 ");
402  if (urilend != NULL) {
403  if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT &&
404  !urilend->raw_buffer)
405  ret = 1;
406 
407  DetectUrilenFree(NULL, urilend);
408  }
409  return ret;
410 }
411 
412 /** \test Test the Urilen keyword setup */
413 static int DetectUrilenParseTest03(void)
414 {
415  int ret = 0;
416  DetectUrilenData *urilend = NULL;
417 
418  urilend = DetectUrilenParse(" > 10 ");
419  if (urilend != NULL) {
420  if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT &&
421  !urilend->raw_buffer)
422  ret = 1;
423 
424  DetectUrilenFree(NULL, urilend);
425  }
426  return ret;
427 }
428 
429 /** \test Test the Urilen keyword setup */
430 static int DetectUrilenParseTest04(void)
431 {
432  int ret = 0;
433  DetectUrilenData *urilend = NULL;
434 
435  urilend = DetectUrilenParse(" 5 <> 10 ");
436  if (urilend != NULL) {
437  if (urilend->urilen1 == 5 && urilend->urilen2 == 10 &&
438  urilend->mode == DETECT_URILEN_RA &&
439  !urilend->raw_buffer)
440  ret = 1;
441 
442  DetectUrilenFree(NULL, urilend);
443  }
444  return ret;
445 }
446 
447 /** \test Test the Urilen keyword setup */
448 static int DetectUrilenParseTest05(void)
449 {
450  int ret = 0;
451  DetectUrilenData *urilend = NULL;
452 
453  urilend = DetectUrilenParse("5<>10,norm");
454  if (urilend != NULL) {
455  if (urilend->urilen1 == 5 && urilend->urilen2 == 10 &&
456  urilend->mode == DETECT_URILEN_RA &&
457  !urilend->raw_buffer)
458  ret = 1;
459 
460  DetectUrilenFree(NULL, urilend);
461  }
462  return ret;
463 }
464 
465 /** \test Test the Urilen keyword setup */
466 static int DetectUrilenParseTest06(void)
467 {
468  int ret = 0;
469  DetectUrilenData *urilend = NULL;
470 
471  urilend = DetectUrilenParse("5<>10,raw");
472  if (urilend != NULL) {
473  if (urilend->urilen1 == 5 && urilend->urilen2 == 10 &&
474  urilend->mode == DETECT_URILEN_RA &&
475  urilend->raw_buffer)
476  ret = 1;
477 
478  DetectUrilenFree(NULL, urilend);
479  }
480  return ret;
481 }
482 
483 /** \test Test the Urilen keyword setup */
484 static int DetectUrilenParseTest07(void)
485 {
486  int ret = 0;
487  DetectUrilenData *urilend = NULL;
488 
489  urilend = DetectUrilenParse(">10, norm ");
490  if (urilend != NULL) {
491  if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT &&
492  !urilend->raw_buffer)
493  ret = 1;
494 
495  DetectUrilenFree(NULL, urilend);
496  }
497  return ret;
498 }
499 
500 /** \test Test the Urilen keyword setup */
501 static int DetectUrilenParseTest08(void)
502 {
503  int ret = 0;
504  DetectUrilenData *urilend = NULL;
505 
506  urilend = DetectUrilenParse("<10, norm ");
507  if (urilend != NULL) {
508  if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT &&
509  !urilend->raw_buffer)
510  ret = 1;
511 
512  DetectUrilenFree(NULL, urilend);
513  }
514  return ret;
515 }
516 
517 /** \test Test the Urilen keyword setup */
518 static int DetectUrilenParseTest09(void)
519 {
520  int ret = 0;
521  DetectUrilenData *urilend = NULL;
522 
523  urilend = DetectUrilenParse(">10, raw ");
524  if (urilend != NULL) {
525  if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT &&
526  urilend->raw_buffer)
527  ret = 1;
528 
529  DetectUrilenFree(NULL, urilend);
530  }
531  return ret;
532 }
533 
534 /** \test Test the Urilen keyword setup */
535 static int DetectUrilenParseTest10(void)
536 {
537  int ret = 0;
538  DetectUrilenData *urilend = NULL;
539 
540  urilend = DetectUrilenParse("<10, raw ");
541  if (urilend != NULL) {
542  if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT &&
543  urilend->raw_buffer)
544  ret = 1;
545 
546  DetectUrilenFree(NULL, urilend);
547  }
548  return ret;
549 }
550 
551 /**
552  * \brief this function is used to initialize the detection engine context and
553  * setup the signature with passed values.
554  *
555  */
556 
557 static int DetectUrilenInitTest(DetectEngineCtx **de_ctx, Signature **sig,
558  DetectUrilenData **urilend, const char *str)
559 {
560  char fullstr[1024];
561  int result = 0;
562 
563  *de_ctx = NULL;
564  *sig = NULL;
565 
566  if (snprintf(fullstr, 1024, "alert ip any any -> any any (msg:\"Urilen "
567  "test\"; urilen:%s; sid:1;)", str) >= 1024) {
568  goto end;
569  }
570 
572  if (*de_ctx == NULL) {
573  goto end;
574  }
575 
576  (*de_ctx)->flags |= DE_QUIET;
577 
578  (*de_ctx)->sig_list = SigInit(*de_ctx, fullstr);
579  if ((*de_ctx)->sig_list == NULL) {
580  goto end;
581  }
582 
583  *sig = (*de_ctx)->sig_list;
584 
585  *urilend = DetectUrilenParse(str);
586 
587  result = 1;
588 
589 end:
590  return result;
591 }
592 
593 /**
594  * \test DetectUrilenSetpTest01 is a test for setting up an valid urilen values
595  * with valid "<>" operator and include spaces arround the given values.
596  * In the test the values are setup with initializing the detection engine
597  * context and setting up the signature itself.
598  */
599 
600 static int DetectUrilenSetpTest01(void)
601 {
602 
603  DetectUrilenData *urilend = NULL;
604  uint8_t res = 0;
605  Signature *sig = NULL;
606  DetectEngineCtx *de_ctx = NULL;
607 
608  res = DetectUrilenInitTest(&de_ctx, &sig, &urilend, "1 <> 2 ");
609  if (res == 0) {
610  goto end;
611  }
612 
613  if(urilend == NULL)
614  goto cleanup;
615 
616  if (urilend != NULL) {
617  if (urilend->urilen1 == 1 && urilend->urilen2 == 2 &&
618  urilend->mode == DETECT_URILEN_RA)
619  res = 1;
620  }
621 
622 cleanup:
623  if (urilend) SCFree(urilend);
627 end:
628  return res;
629 }
630 
631 /** \test Check a signature with gievn urilen */
632 static int DetectUrilenSigTest01(void)
633 {
634  int result = 0;
635  Flow f;
636  uint8_t httpbuf1[] = "POST /suricata HTTP/1.0\r\n"
637  "Host: foo.bar.tld\r\n"
638  "\r\n";
639  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
640  TcpSession ssn;
641  Packet *p = NULL;
642  Signature *s = NULL;
643  ThreadVars th_v;
644  DetectEngineThreadCtx *det_ctx;
646 
647  memset(&th_v, 0, sizeof(th_v));
648  memset(&f, 0, sizeof(f));
649  memset(&ssn, 0, sizeof(ssn));
650 
651  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
652 
653  FLOW_INITIALIZE(&f);
654  f.protoctx = (void *)&ssn;
655  f.proto = IPPROTO_TCP;
656  f.flags |= FLOW_IPV4;
657 
658  p->flow = &f;
663 
664  StreamTcpInitConfig(true);
665 
667  if (de_ctx == NULL) {
668  goto end;
669  }
670 
671  de_ctx->flags |= DE_QUIET;
672 
673  s = de_ctx->sig_list = SigInit(de_ctx,
674  "alert tcp any any -> any any "
675  "(msg:\"Testing urilen\"; "
676  "urilen: <5; sid:1;)");
677  if (s == NULL) {
678  goto end;
679  }
680 
681  s = s->next = SigInit(de_ctx,
682  "alert tcp any any -> any any "
683  "(msg:\"Testing http_method\"; "
684  "urilen: >5; sid:2;)");
685  if (s == NULL) {
686  goto end;
687  }
688 
690  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
691 
692  FLOWLOCK_WRLOCK(&f);
693  int r = AppLayerParserParse(
694  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
695  if (r != 0) {
696  SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
697  FLOWLOCK_UNLOCK(&f);
698  goto end;
699  }
700  FLOWLOCK_UNLOCK(&f);
701 
702  HtpState *htp_state = f.alstate;
703  if (htp_state == NULL) {
704  SCLogDebug("no http state: ");
705  goto end;
706  }
707 
708  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
709 
710  if ((PacketAlertCheck(p, 1))) {
711  printf("sid 1 alerted, but should not have: \n");
712  goto end;
713  }
714  if (!PacketAlertCheck(p, 2)) {
715  printf("sid 2 did not alerted, but should have: \n");
716  goto end;
717  }
718 
719  result = 1;
720 
721 end:
722  if (alp_tctx != NULL)
724  if (de_ctx != NULL) SigGroupCleanup(de_ctx);
725  if (de_ctx != NULL) SigCleanSignatures(de_ctx);
726  if (de_ctx != NULL) DetectEngineCtxFree(de_ctx);
727 
728  StreamTcpFreeConfig(true);
729  FLOW_DESTROY(&f);
730  UTHFreePackets(&p, 1);
731  return result;
732 }
733 
734 /**
735  * \brief this function registers unit tests for DetectUrilen
736  */
737 void DetectUrilenRegisterTests(void)
738 {
739  UtRegisterTest("DetectUrilenParseTest01", DetectUrilenParseTest01);
740  UtRegisterTest("DetectUrilenParseTest02", DetectUrilenParseTest02);
741  UtRegisterTest("DetectUrilenParseTest03", DetectUrilenParseTest03);
742  UtRegisterTest("DetectUrilenParseTest04", DetectUrilenParseTest04);
743  UtRegisterTest("DetectUrilenParseTest05", DetectUrilenParseTest05);
744  UtRegisterTest("DetectUrilenParseTest06", DetectUrilenParseTest06);
745  UtRegisterTest("DetectUrilenParseTest07", DetectUrilenParseTest07);
746  UtRegisterTest("DetectUrilenParseTest08", DetectUrilenParseTest08);
747  UtRegisterTest("DetectUrilenParseTest09", DetectUrilenParseTest09);
748  UtRegisterTest("DetectUrilenParseTest10", DetectUrilenParseTest10);
749  UtRegisterTest("DetectUrilenSetpTest01", DetectUrilenSetpTest01);
750  UtRegisterTest("DetectUrilenSigTest01", DetectUrilenSigTest01);
751 }
752 #endif /* UNITTESTS */
util-byte.h
DetectParseRegex::match
pcre2_match_data * match
Definition: detect-parse.h:45
SigTableElmt_::url
const char * url
Definition: detect.h:1270
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1490
detect-content.h
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1269
DetectUrilenData_::urilen2
uint16_t urilen2
Definition: detect-urilen.h:34
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2474
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1175
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1257
flow-util.h
DetectParseRegex
Definition: detect-parse.h:42
SigTableElmt_::name
const char * name
Definition: detect.h:1267
stream-tcp.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:60
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Flow_::proto
uint8_t proto
Definition: flow.h:375
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:137
Packet_::flags
uint32_t flags
Definition: decode.h:462
Flow_
Flow data structure.
Definition: flow.h:353
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2115
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:811
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:336
DetectUrilenData_::raw_buffer
uint8_t raw_buffer
Definition: detect-urilen.h:36
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2433
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:320
DetectUrilenData_::urilen1
uint16_t urilen1
Definition: detect-urilen.h:33
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:225
DE_QUIET
#define DE_QUIET
Definition: detect.h:295
stream-tcp-reassemble.h
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:337
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1790
DetectContentData_
Definition: detect-content.h:86
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:42
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:458
Flow_::protoctx
void * protoctx
Definition: flow.h:451
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1252
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:98
DetectUrilenApplyToContent
void DetectUrilenApplyToContent(Signature *s, int list)
set prefilter dsize pair
Definition: detect-urilen.c:294
util-unittest.h
HtpState_
Definition: app-layer-htp.h:247
util-unittest-helper.h
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:270
SC_ERR_PCRE_PARSE
@ SC_ERR_PCRE_PARSE
Definition: util-error.h:37
DETECT_URILEN_GT
#define DETECT_URILEN_GT
Definition: detect-urilen.h:28
Signature_::next
struct Signature_ * next
Definition: detect.h:622
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:357
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
app-layer-htp.h
util-debug.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1060
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DETECT_URILEN_EQ
#define DETECT_URILEN_EQ
Definition: detect-urilen.h:30
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:20
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2597
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:267
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:325
SC_Pcre2SubstringGet
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
Definition: detect-parse.c:2585
SC_ERR_INVALID_ARGUMENT
@ SC_ERR_INVALID_ARGUMENT
Definition: util-error.h:43
DetectContentData_::id
PatIntId id
Definition: detect-content.h:98
app-layer-parser.h
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:324
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2016
DetectContentData_::depth
uint16_t depth
Definition: detect-content.h:99
stream.h
Packet_
Definition: decode.h:427
stream-tcp-private.h
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:619
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1235
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:542
PARSE_REGEX
#define PARSE_REGEX
Regex for parsing our urilen.
Definition: detect-urilen.c:48
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1948
DETECT_URILEN_RA
#define DETECT_URILEN_RA
Definition: detect-urilen.h:29
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:299
DETECT_URILEN_LT
#define DETECT_URILEN_LT
Definition: detect-urilen.h:27
Packet_::flow
struct Flow_ * flow
Definition: decode.h:464
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3142
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:1023
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:662
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:1237
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:322
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
DetectUrilenRegister
void DetectUrilenRegister(void)
Registration function for urilen: keyword.
Definition: detect-urilen.c:65
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:817
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:272
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::alstate
void * alstate
Definition: flow.h:486
Signature_::id
uint32_t id
Definition: detect.h:582
Flow_::flags
uint32_t flags
Definition: flow.h:431
detect-parse.h
Signature_
Signature container.
Definition: detect.h:548
SigMatch_
a single match condition for a signature
Definition: detect.h:321
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:227
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2394
app-layer-protos.h
DetectUrilenData_::mode
uint8_t mode
Definition: detect-urilen.h:35
detect-urilen.h
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h:88
DetectUrilenData_
Definition: detect-urilen.h:32
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:812
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:86
TcpSession_
Definition: stream-tcp-private.h:260
DetectUrilenValidateContent
bool DetectUrilenValidateContent(const Signature *s, int list, const char **sigerror)
Definition: detect-urilen.c:347
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:460
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
DETECT_AL_URILEN
@ DETECT_AL_URILEN
Definition: detect-engine-register.h:126
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:130
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1172
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1259
app-layer.h
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:468