suricata
detect-lua.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2025 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  */
24 
25 #include "suricata-common.h"
26 #include "conf.h"
27 
28 #include "decode.h"
29 
30 #include "detect.h"
31 #include "detect-parse.h"
32 
33 #include "detect-engine.h"
34 #include "detect-engine-buffer.h"
35 #include "detect-engine-mpm.h"
36 #include "detect-engine-build.h"
37 
38 #include "detect-byte.h"
39 
40 #include "flow.h"
41 #include "flow-var.h"
42 #include "flow-util.h"
43 
44 #include "util-byte.h"
45 
46 #include "util-unittest.h"
47 #include "util-unittest-helper.h"
48 
49 #include "app-layer.h"
50 #include "app-layer-parser.h"
51 #include "app-layer-htp.h"
52 #include "app-layer-ssl.h"
53 
54 #include "stream-tcp.h"
55 
56 #include "detect-lua.h"
57 #include "detect-lua-extensions.h"
58 
59 #include "util-var-name.h"
60 
61 #include "util-lua.h"
62 #include "util-lua-builtins.h"
63 #include "util-lua-common.h"
64 #include "util-lua-sandbox.h"
65 
66 static int DetectLuaMatch (DetectEngineThreadCtx *,
67  Packet *, const Signature *, const SigMatchCtx *);
68 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
69  Flow *f, uint8_t flags,
70  void *state, void *txv, const Signature *s,
71  const SigMatchCtx *ctx);
72 static int DetectLuaSetup (DetectEngineCtx *, Signature *, const char *);
73 #ifdef UNITTESTS
74 static void DetectLuaRegisterTests(void);
75 #endif
76 static void DetectLuaFree(DetectEngineCtx *, void *);
77 static int g_lua_ja3_list_id = 0;
78 static int g_lua_ja3s_list_id = 0;
79 
80 /**
81  * \brief Registration function for keyword: lua
82  */
84 {
86  sigmatch_table[DETECT_LUA].desc = "match via a lua script";
87  sigmatch_table[DETECT_LUA].url = "/rules/lua-detection.html";
88  sigmatch_table[DETECT_LUA].Match = DetectLuaMatch;
89  sigmatch_table[DETECT_LUA].AppLayerTxMatch = DetectLuaAppTxMatch;
90  sigmatch_table[DETECT_LUA].Setup = DetectLuaSetup;
91  sigmatch_table[DETECT_LUA].Free = DetectLuaFree;
92 #ifdef UNITTESTS
93  sigmatch_table[DETECT_LUA].RegisterTests = DetectLuaRegisterTests;
94 #endif
95 
96  g_lua_ja3_list_id = DetectBufferTypeRegister("ja3.lua");
101 
102  g_lua_ja3s_list_id = DetectBufferTypeRegister("ja3s.lua");
107 
108  SCLogDebug("registering lua rule option");
109 }
110 
111 /* Flags for DetectLuaThreadData. */
112 #define FLAG_DATATYPE_PACKET BIT_U32(0)
113 #define FLAG_DATATYPE_PAYLOAD BIT_U32(1)
114 #define FLAG_LIST_JA3 BIT_U32(3)
115 #define FLAG_LIST_JA3S BIT_U32(4)
116 #define FLAG_ERROR_LOGGED BIT_U32(23)
117 #define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
118 #define FLAG_INSTRUCTION_LIMIT_LOGGED BIT_U32(25)
119 #define FLAG_MEMORY_LIMIT_LOGGED BIT_U32(26)
120 
121 #define DEFAULT_LUA_ALLOC_LIMIT 500000
122 #define DEFAULT_LUA_INSTRUCTION_LIMIT 500000
123 
124 /** \brief dump stack from lua state to screen */
125 void LuaDumpStack(lua_State *state, const char *prefix)
126 {
127  int size = lua_gettop(state);
128  printf("%s: size %d\n", prefix, size);
129 
130  for (int i = 1; i <= size; i++) {
131  int type = lua_type(state, i);
132  printf("- %s: Stack size=%d, level=%d, type=%d, ", prefix, size, i, type);
133 
134  switch (type) {
135  case LUA_TFUNCTION:
136  printf("function %s", lua_tostring(state, i));
137  break;
138  case LUA_TBOOLEAN:
139  printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
140  break;
141  case LUA_TNUMBER:
142  printf("number %g", lua_tonumber(state, i));
143  break;
144  case LUA_TSTRING:
145  printf("string `%s'", lua_tostring(state, i));
146  break;
147  case LUA_TTABLE:
148  printf("table `%s'", lua_tostring(state, i));
149  break;
150  default:
151  printf("other %s", lua_typename(state, type));
152  break;
153 
154  }
155  printf("\n");
156  }
157 }
158 
159 static void LuaStateSetDetectLuaData(lua_State *state, DetectLuaData *data)
160 {
161  lua_pushlightuserdata(state, (void *)&luaext_key_ld);
162  lua_pushlightuserdata(state, (void *)data);
163  lua_settable(state, LUA_REGISTRYINDEX);
164 }
165 
166 /**
167  * \brief Common function to run the Lua match function and process
168  * the return value.
169  */
170 static int DetectLuaRunMatch(
171  DetectEngineThreadCtx *det_ctx, const DetectLuaData *lua, DetectLuaThreadData *tlua)
172 {
173  /* Reset instruction count. */
175 
176  if (lua_pcall(tlua->luastate, 1, 1, 0) != 0) {
177  const char *reason = lua_tostring(tlua->luastate, -1);
178  SCLuaSbState *context = SCLuaSbGetContext(tlua->luastate);
179  uint32_t flag = 0;
180  if (context->blocked_function_error) {
183  } else if (context->instruction_count_error) {
186  } else if (context->memory_limit_error) {
187  StatsCounterIncr(&det_ctx->tv->stats, det_ctx->lua_memory_limit_errors);
188  reason = "memory limit exceeded";
190  } else {
191  flag = FLAG_ERROR_LOGGED;
192  }
193 
194  /* Log once per thread per error type, the message from Lua
195  * will include the filename. */
196  if (!(tlua->flags & flag)) {
197  SCLogWarning("Lua script failed to run successfully: %s", reason);
198  tlua->flags |= flag;
199  }
200 
201  StatsCounterIncr(&det_ctx->tv->stats, det_ctx->lua_rule_errors);
202  while (lua_gettop(tlua->luastate) > 0) {
203  lua_pop(tlua->luastate, 1);
204  }
205  SCReturnInt(0);
206  }
207 
208  int match = 0;
209 
210  /* process returns from script */
211  if (lua_gettop(tlua->luastate) > 0) {
212  /* script returns a number (return 1 or return 0) */
213  if (lua_type(tlua->luastate, 1) == LUA_TNUMBER) {
214  lua_Integer script_ret = lua_tointeger(tlua->luastate, 1);
215  SCLogDebug("script_ret %lld", script_ret);
216  lua_pop(tlua->luastate, 1);
217  if (script_ret == 1)
218  match = 1;
219  } else {
220  SCLogDebug("Unsupported datatype returned from Lua script");
221  }
222  }
223 
224  if (lua->negated) {
225  if (match == 1)
226  match = 0;
227  else
228  match = 1;
229  }
230 
231  while (lua_gettop(tlua->luastate) > 0) {
232  lua_pop(tlua->luastate, 1);
233  }
234 
235  SCReturnInt(match);
236 }
237 
239  const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset,
240  Flow *f)
241 {
242  SCEnter();
243 
244  if (buffer == NULL || buffer_len == 0)
245  SCReturnInt(0);
246 
247  DetectLuaData *lua = (DetectLuaData *)smd->ctx;
248  if (lua == NULL)
249  SCReturnInt(0);
250 
251  DetectLuaThreadData *tlua =
253  if (tlua == NULL)
254  SCReturnInt(0);
255 
256  /* disable bytes limit temporarily to allow the setup of buffer and other data the script will
257  * use. */
258  const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
259 
260  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
261 
262  /* prepare data to pass to script */
263  lua_getglobal(tlua->luastate, "match");
264  lua_newtable(tlua->luastate); /* stack at -1 */
265 
266  lua_pushliteral(tlua->luastate, "offset"); /* stack at -2 */
267  lua_pushnumber(tlua->luastate, (int)(offset + 1));
268  lua_settable(tlua->luastate, -3);
269 
270  lua_pushstring(tlua->luastate, lua->buffername); /* stack at -2 */
271  LuaPushStringBuffer(tlua->luastate, (const uint8_t *)buffer, (size_t)buffer_len);
272  lua_settable(tlua->luastate, -3);
273 
274  /* restore configured bytes limit and account for the allocations done for the setup above. */
275  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
277  int r = DetectLuaRunMatch(det_ctx, lua, tlua);
278  /* restore configured limit */
279  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
280  SCReturnInt(r);
281 }
282 
283 /**
284  * \brief match the specified lua script
285  *
286  * \param t thread local vars
287  * \param det_ctx pattern matcher thread local data
288  * \param p packet
289  * \param s signature being inspected
290  * \param m sigmatch that we will cast into DetectLuaData
291  *
292  * \retval 0 no match
293  * \retval 1 match
294  */
295 static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
296  Packet *p, const Signature *s, const SigMatchCtx *ctx)
297 {
298  SCEnter();
299  DetectLuaData *lua = (DetectLuaData *)ctx;
300  if (lua == NULL)
301  SCReturnInt(0);
302 
304  if (tlua == NULL)
305  SCReturnInt(0);
306 
307  /* setup extension data for use in lua c functions */
308  uint8_t flags = 0;
309  if (p->flowflags & FLOW_PKT_TOSERVER)
310  flags = STREAM_TOSERVER;
311  else if (p->flowflags & FLOW_PKT_TOCLIENT)
312  flags = STREAM_TOCLIENT;
313 
314  /* disable bytes limit temporarily to allow the setup of buffer and other data the script will
315  * use. */
316  const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
317 
318  LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
319 
320  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
321 
322  if ((tlua->flags & FLAG_DATATYPE_PAYLOAD) && p->payload_len == 0)
323  SCReturnInt(0);
324  if ((tlua->flags & FLAG_DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
325  SCReturnInt(0);
326 
327  lua_getglobal(tlua->luastate, "match");
328  lua_newtable(tlua->luastate); /* stack at -1 */
329 
330  /* restore configured bytes limit and account for the allocations done for the setup above. */
331  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
333  int r = DetectLuaRunMatch(det_ctx, lua, tlua);
334  /* restore configured limit */
335  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
336  SCReturnInt(r);
337 }
338 
339 static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
340  Flow *f, uint8_t flags, void *state,
341  const Signature *s, const SigMatchCtx *ctx)
342 {
343  SCEnter();
344  DetectLuaData *lua = (DetectLuaData *)ctx;
345  if (lua == NULL)
346  SCReturnInt(0);
347 
349  if (tlua == NULL)
350  SCReturnInt(0);
351 
352  /* disable bytes limit temporarily to allow the setup of buffer and other data the script will
353  * use. */
354  const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
355 
356  /* setup extension data for use in lua c functions */
357  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
358 
359  lua_getglobal(tlua->luastate, "match");
360  lua_newtable(tlua->luastate); /* stack at -1 */
361 
362  /* restore configured bytes limit and account for the allocations done for the setup above. */
363  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
365  int r = DetectLuaRunMatch(det_ctx, lua, tlua);
366  /* restore configured limit */
367  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
368  SCReturnInt(r);
369 }
370 
371 /**
372  * \brief match the specified lua script in a list with a tx
373  *
374  * \param t thread local vars
375  * \param det_ctx pattern matcher thread local data
376  * \param s signature being inspected
377  * \param m sigmatch that we will cast into DetectLuaData
378  *
379  * \retval 0 no match
380  * \retval 1 match
381  */
382 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
383  Flow *f, uint8_t flags,
384  void *state, void *txv, const Signature *s,
385  const SigMatchCtx *ctx)
386 {
387  return DetectLuaAppMatchCommon(det_ctx, f, flags, state, s, ctx);
388 }
389 
390 #ifdef UNITTESTS
391 /* if this ptr is set the lua setup functions will use this buffer as the
392  * lua script instead of calling luaL_loadfile on the filename supplied. */
393 static const char *ut_script = NULL;
394 #endif
395 
396 static void *DetectLuaThreadInit(void *data, bool allow_restricted_functions)
397 {
398  int status;
399  DetectLuaData *lua = (DetectLuaData *)data;
400  BUG_ON(lua == NULL);
401 
403  if (unlikely(t == NULL)) {
404  SCLogError("couldn't alloc ctx memory");
405  return NULL;
406  }
407 
408  t->flags = lua->flags;
409 
411  if (t->luastate == NULL) {
412  SCLogError("luastate pool depleted");
413  goto error;
414  }
415 
416  if (allow_restricted_functions) {
417  luaL_openlibs(t->luastate);
419  } else {
421  }
422 
423  LuaStateSetDetectLuaData(t->luastate, lua);
424 
425  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
426 #ifdef UNITTESTS
427  if (ut_script != NULL) {
428  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
429  if (status) {
430  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
431  goto error;
432  }
433  } else {
434 #endif
435  status = luaL_loadfile(t->luastate, lua->filename);
436  if (status) {
437  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
438  goto error;
439  }
440 #ifdef UNITTESTS
441  }
442 #endif
443 
444  /* prime the script (or something) */
445  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
446  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
447  goto error;
448  }
449 
450  /* thread_init call */
451  lua_getglobal(t->luastate, "thread_init");
452  if (lua_isfunction(t->luastate, -1)) {
453  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
454  SCLogError("couldn't run script 'thread_init' function: %s",
455  lua_tostring(t->luastate, -1));
456  goto error;
457  }
458  } else {
459  lua_pop(t->luastate, 1);
460  }
461 
462  return (void *)t;
463 
464 error:
465  if (t->luastate != NULL)
467  SCFree(t);
468  return NULL;
469 }
470 
471 static void *DetectLuaThreadRestrictedInit(void *data)
472 {
473  return DetectLuaThreadInit(data, false);
474 }
475 
476 static void *DetectLuaThreadAllowInit(void *data)
477 {
478  return DetectLuaThreadInit(data, true);
479 }
480 
481 static void DetectLuaThreadFree(void *ctx)
482 {
483  if (ctx != NULL) {
485  if (t->luastate != NULL)
487  SCFree(t);
488  }
489 }
490 
491 /**
492  * \brief Parse the lua keyword
493  *
494  * \param de_ctx Pointer to the detection engine context
495  * \param str Pointer to the user provided option
496  *
497  * \retval lua pointer to DetectLuaData on success
498  * \retval NULL on failure
499  */
500 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
501 {
502  DetectLuaData *lua = NULL;
503 
504  /* We have a correct lua option */
505  lua = SCCalloc(1, sizeof(DetectLuaData));
506  if (unlikely(lua == NULL))
507  goto error;
508 
509  if (strlen(str) && str[0] == '!') {
510  lua->negated = 1;
511  str++;
512  }
513 
514  /* get full filename */
516  if (lua->filename == NULL) {
517  goto error;
518  }
519 
520  return lua;
521 
522 error:
523  DetectLuaFree(de_ctx, lua);
524  return NULL;
525 }
526 
527 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s,
528  int allow_restricted_functions)
529 {
530  int status;
531 
533  if (luastate == NULL)
534  return -1;
535  if (allow_restricted_functions) {
536  luaL_openlibs(luastate);
537  SCLuaRequirefBuiltIns(luastate);
538  } else {
539  SCLuaSbLoadLibs(luastate);
540  }
541  LuaStateSetDetectLuaData(luastate, ld);
542 
543  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
544 #ifdef UNITTESTS
545  if (ut_script != NULL) {
546  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
547  if (status) {
548  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
549  goto error;
550  }
551  } else {
552 #endif
553  status = luaL_loadfile(luastate, ld->filename);
554  if (status) {
555  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
556  goto error;
557  }
558 #ifdef UNITTESTS
559  }
560 #endif
561 
562  /* prime the script (or something) */
563  if (lua_pcall(luastate, 0, 0, 0) != 0) {
564  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
565  goto error;
566  }
567 
568  lua_getglobal(luastate, "init");
569  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
570  SCLogError("no init function in script");
571  goto error;
572  }
573 
574  /* Pass the signature as the first argument, setting up bytevars depends on
575  * access to the signature. */
576  lua_pushlightuserdata(luastate, (void *)s);
577 
578  if (lua_pcall(luastate, 1, 1, 0) != 0) {
579  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
580  goto error;
581  }
582 
583  /* process returns from script */
584  if (lua_gettop(luastate) == 0) {
585  SCLogError("init function in script should return table, nothing returned");
586  goto error;
587  }
588  if (lua_type(luastate, 1) != LUA_TTABLE) {
589  SCLogError("init function in script should return table, returned is not table");
590  goto error;
591  }
592 
593  lua_pushnil(luastate);
594  const char *k;
595  while (lua_next(luastate, -2)) {
596  k = lua_tostring(luastate, -2);
597  if (k == NULL)
598  continue;
599 
600  /* handle flowvar and bytes separately as they have a table as value */
601  if (strcmp(k, "flowvar") == 0) {
602  if (lua_istable(luastate, -1)) {
603  lua_pushnil(luastate);
604  while (lua_next(luastate, -2) != 0) {
605  /* value at -1, key is at -2 which we ignore */
606  const char *value = lua_tostring(luastate, -1);
607  SCLogDebug("value %s", value);
608  /* removes 'value'; keeps 'key' for next iteration */
609  lua_pop(luastate, 1);
610 
611  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
612  SCLogError("too many flowvars registered");
613  goto error;
614  }
615 
616  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
617  if (unlikely(idx == 0))
618  goto error;
619  ld->flowvar[ld->flowvars++] = idx;
620  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
621  }
622  }
623  lua_pop(luastate, 1);
624  continue;
625  } else if (strcmp(k, "flowint") == 0) {
626  if (lua_istable(luastate, -1)) {
627  lua_pushnil(luastate);
628  while (lua_next(luastate, -2) != 0) {
629  /* value at -1, key is at -2 which we ignore */
630  const char *value = lua_tostring(luastate, -1);
631  SCLogDebug("value %s", value);
632  /* removes 'value'; keeps 'key' for next iteration */
633  lua_pop(luastate, 1);
634 
635  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
636  SCLogError("too many flowints registered");
637  goto error;
638  }
639 
640  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
641  if (unlikely(idx == 0))
642  goto error;
643  ld->flowint[ld->flowints++] = idx;
644  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
645  }
646  }
647  lua_pop(luastate, 1);
648  continue;
649  }
650 
651  bool required = lua_toboolean(luastate, -1);
652  lua_pop(luastate, 1);
653  if (!required) {
654  continue;
655  }
656 
657  if (strcmp(k, "ja3") == 0) {
658  ld->flags |= FLAG_LIST_JA3;
659  } else if (strcmp(k, "ja3s") == 0) {
660  ld->flags |= FLAG_LIST_JA3S;
661  } else if (strcmp(k, "packet") == 0) {
663  } else if (strcmp(k, "payload") == 0) {
665  } else if (strcmp(k, "buffer") == 0) {
666  ld->buffername = SCStrdup("buffer");
667  if (ld->buffername == NULL) {
668  SCLogError("alloc error");
669  goto error;
670  }
671  } else if (strcmp(k, "stream") == 0) {
672  ld->buffername = SCStrdup("stream");
673  if (ld->buffername == NULL) {
674  SCLogError("alloc error");
675  goto error;
676  }
677  /* old options no longer supported */
678  } else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
679  strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
680  strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
681  SCLogError("data type %s no longer supported, use rule hooks", k);
682  goto error;
683 
684  } else {
685  SCLogError("unsupported data type %s", k);
686  goto error;
687  }
688  }
689 
690  /* pop the table */
691  lua_pop(luastate, 1);
692  SCLuaSbStateClose(luastate);
693  return 0;
694 error:
695  SCLuaSbStateClose(luastate);
696  return -1;
697 }
698 
699 /**
700  * \brief this function is used to parse lua options
701  * \brief into the current signature
702  *
703  * \param de_ctx pointer to the Detection Engine Context
704  * \param s pointer to the Current Signature
705  * \param str pointer to the user provided "lua" option
706  *
707  * \retval 0 on Success
708  * \retval -1 on Failure
709  */
710 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
711 {
712  /* First check if Lua rules are enabled, by default Lua in rules
713  * is disabled. */
714  int enabled = 0;
715  if (SCConfGetBool("security.lua.allow-rules", &enabled) == 1 && !enabled) {
716  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
717  return -1;
718  }
719 
720  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
721  if (lua == NULL)
722  return -1;
723 
724  /* Load lua sandbox configurations */
725  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
726  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
727  (void)SCConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
728  (void)SCConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
729  lua->alloc_limit = lua_alloc_limit;
730  lua->instruction_limit = lua_instruction_limit;
731 
732  int allow_restricted_functions = 0;
733  (void)SCConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
734 
735  if (DetectLuaSetupPrime(de_ctx, lua, s, allow_restricted_functions) == -1) {
736  goto error;
737  }
738 
739  void *cb = DetectLuaThreadRestrictedInit;
740  if (allow_restricted_functions) {
741  cb = DetectLuaThreadAllowInit;
742  }
743 
744  lua->thread_ctx_id =
745  DetectRegisterThreadCtxFuncs(de_ctx, "lua", cb, (void *)lua, DetectLuaThreadFree, 0);
746  if (lua->thread_ctx_id == -1)
747  goto error;
748 
749  int list = DetectBufferGetActiveList(de_ctx, s);
750  SCLogDebug("buffer list %d -> %d", list, s->init_data->list);
751  if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
752  /* what needs to happen here is: we register to the rule hook, so e.g.
753  * http1.request_complete. This means we need a list.
754  *
755  * This includes each pkt, payload, stream, etc. */
756 
758  list = s->init_data->hook.sm_list;
759  SCLogDebug("setting list %d", list);
760  }
761  }
762 
763  if (list == -1) {
764  SCLogError("lua failed to set up");
765  goto error;
766  }
767  if (list == 0) {
768  if (lua->flags & FLAG_LIST_JA3) {
769  list = g_lua_ja3_list_id;
770  } else if (lua->flags & FLAG_LIST_JA3S) {
771  list = g_lua_ja3s_list_id;
772  }
773  }
774 
775  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
776  goto error;
777  }
778 
779  return 0;
780 
781 error:
782  if (lua != NULL)
783  DetectLuaFree(de_ctx, lua);
784  return -1;
785 }
786 
787 /**
788  * \brief this function will free memory associated with DetectLuaData
789  *
790  * \param ptr pointer to DetectLuaData
791  */
792 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
793 {
794  if (ptr != NULL) {
795  DetectLuaData *lua = (DetectLuaData *)ptr;
796 
797  if (lua->buffername)
798  SCFree(lua->buffername);
799  if (lua->filename)
800  SCFree(lua->filename);
801 
802  for (uint16_t i = 0; i < lua->flowints; i++) {
804  }
805  for (uint16_t i = 0; i < lua->flowvars; i++) {
807  }
808  for (uint16_t i = 0; i < lua->bytevars; i++) {
809  SCFree(lua->bytevar[i].name);
810  }
811 
813 
814  SCFree(lua);
815  }
816 }
817 
818 #ifdef UNITTESTS
819 #include "detect-engine-alert.h"
820 
821 /** \test http buffer */
822 static int LuaMatchTest01(void)
823 {
824  SCConfSetFinal("security.lua.allow-rules", "true");
825 
826  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
827  "function init (args)\n"
828  " flowvarlib.register(\"cnt\")\n"
829  " return {}\n"
830  "end\n"
831  "function thread_init (args)\n"
832  " cnt = flowvarlib.get(\"cnt\")\n"
833  "end\n"
834  "\n"
835  "function match(args)\n"
836  " a = cnt:value()\n"
837  " if a then\n"
838  " a = tostring(tonumber(a)+1)\n"
839  " print (a)\n"
840  " cnt:set(a, #a)\n"
841  " else\n"
842  " a = tostring(1)\n"
843  " print (a)\n"
844  " cnt:set(a, #a)\n"
845  " end\n"
846  " \n"
847  " print (\"pre check: \" .. (a))\n"
848  " if tonumber(a) == 2 then\n"
849  " print \"match\"\n"
850  " return 1\n"
851  " end\n"
852  " return 0\n"
853  "end\n"
854  "return 0\n";
855  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
856  "sid:1;)";
857  uint8_t httpbuf1[] =
858  "POST / HTTP/1.1\r\n"
859  "Host: www.emergingthreats.net\r\n\r\n";
860  uint8_t httpbuf2[] =
861  "POST / HTTP/1.1\r\n"
862  "Host: www.openinfosecfoundation.org\r\n\r\n";
863  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
864  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
865  TcpSession ssn;
866  Flow f;
867  ThreadVars th_v;
868  DetectEngineThreadCtx *det_ctx;
869 
871 
872  ut_script = script;
873 
874  memset(&th_v, 0, sizeof(th_v));
875  StatsThreadInit(&th_v.stats);
876  memset(&f, 0, sizeof(f));
877  memset(&ssn, 0, sizeof(ssn));
878 
879  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
880  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
881 
882  FLOW_INITIALIZE(&f);
883  f.protoctx = (void *)&ssn;
884  f.proto = IPPROTO_TCP;
885  f.flags |= FLOW_IPV4;
887 
888  p1->flow = &f;
892  p2->flow = &f;
896 
897  StreamTcpInitConfig(true);
898 
901  de_ctx->flags |= DE_QUIET;
902 
904  FAIL_IF_NULL(s);
905 
907  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
908 
909  int r = AppLayerParserParse(
910  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
911  FAIL_IF(r != 0);
912  HtpState *http_state = f.alstate;
913  FAIL_IF_NULL(http_state);
914 
915  /* do detect for p1 */
916  SCLogDebug("inspecting p1");
917  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
918  FAIL_IF(PacketAlertCheck(p1, 1));
919 
920  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
921  FAIL_IF(r != 0);
922 
923  /* do detect for p2 */
924  SCLogDebug("inspecting p2");
925  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
927 
928  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
929  FAIL_IF(id == 0);
930 
931  FlowVar *fv = FlowVarGet(&f, id);
932  FAIL_IF_NULL(fv);
933  FAIL_IF(fv->data.fv_str.value_len != 1);
934  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
935 
936  UTHFreePackets(&p1, 1);
937  UTHFreePackets(&p2, 1);
938  FLOW_DESTROY(&f);
939 
941  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
943  StreamTcpFreeConfig(true);
944  StatsThreadCleanup(&th_v.stats);
945  PASS;
946 }
947 
948 static int LuaMatchTest01a(void)
949 {
950  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
951  "function init (args)\n"
952  " flowvarlib.register(\"cnt\")\n"
953  " return {}\n"
954  "end\n"
955  "function thread_init (args)\n"
956  " cnt = flowvarlib.get(\"cnt\")\n"
957  "end\n"
958  "\n"
959  "function match(args)\n"
960  " a = cnt:value(0)\n"
961  " if a then\n"
962  " a = tostring(tonumber(a)+1)\n"
963  " print (a)\n"
964  " cnt:set(a, #a)\n"
965  " else\n"
966  " a = tostring(1)\n"
967  " print (a)\n"
968  " cnt:set(a, #a)\n"
969  " end\n"
970  " \n"
971  " print (\"pre check: \" .. (a))\n"
972  " if tonumber(a) == 2 then\n"
973  " print \"match\"\n"
974  " return 1\n"
975  " end\n"
976  " return 0\n"
977  "end\n"
978  "return 0\n";
979  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
980  "sid:1;)";
981  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
982  "Host: www.emergingthreats.net\r\n\r\n";
983  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
984  "Host: www.openinfosecfoundation.org\r\n\r\n";
985  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
986  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
987  TcpSession ssn;
988  Flow f;
989  ThreadVars th_v;
990  DetectEngineThreadCtx *det_ctx;
991 
993 
994  ut_script = script;
995 
996  memset(&th_v, 0, sizeof(th_v));
997  StatsThreadInit(&th_v.stats);
998  memset(&f, 0, sizeof(f));
999  memset(&ssn, 0, sizeof(ssn));
1000 
1001  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1002  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1003 
1004  FLOW_INITIALIZE(&f);
1005  f.protoctx = (void *)&ssn;
1006  f.proto = IPPROTO_TCP;
1007  f.flags |= FLOW_IPV4;
1008  f.alproto = ALPROTO_HTTP1;
1009 
1010  p1->flow = &f;
1014  p2->flow = &f;
1018 
1019  StreamTcpInitConfig(true);
1020 
1023  de_ctx->flags |= DE_QUIET;
1024 
1026  FAIL_IF_NULL(s);
1027 
1029  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1030 
1031  int r = AppLayerParserParse(
1032  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1033  FAIL_IF(r != 0);
1034 
1035  HtpState *http_state = f.alstate;
1036  FAIL_IF_NULL(http_state);
1037 
1038  /* do detect for p1 */
1039  SCLogDebug("inspecting p1");
1040  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1041  FAIL_IF(PacketAlertCheck(p1, 1));
1042 
1043  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1044  FAIL_IF(r != 0);
1045  /* do detect for p2 */
1046  SCLogDebug("inspecting p2");
1047  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1048  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1049 
1050  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1051  FAIL_IF(id == 0);
1052 
1053  FlowVar *fv = FlowVarGet(&f, id);
1054  FAIL_IF_NULL(fv);
1055  FAIL_IF(fv->data.fv_str.value_len != 1);
1056  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1057 
1058  UTHFreePackets(&p1, 1);
1059  UTHFreePackets(&p2, 1);
1060  FLOW_DESTROY(&f);
1061 
1063  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1065  StreamTcpFreeConfig(true);
1066  StatsThreadCleanup(&th_v.stats);
1067  PASS;
1068 }
1069 
1070 /** \test payload buffer */
1071 static int LuaMatchTest02(void)
1072 {
1073  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1074  "function init (args)\n"
1075  " flowvarlib.register(\"cnt\")\n"
1076  " local needs = {}\n"
1077  " needs[\"payload\"] = tostring(true)\n"
1078  " return needs\n"
1079  "end\n"
1080  "function thread_init (args)\n"
1081  " cnt = flowvarlib.get(\"cnt\")\n"
1082  "end\n"
1083  "\n"
1084  "function match(args)\n"
1085  " a = cnt:value()\n"
1086  " if a then\n"
1087  " a = tostring(tonumber(a)+1)\n"
1088  " print (a)\n"
1089  " cnt:set(a, #a)\n"
1090  " else\n"
1091  " a = tostring(1)\n"
1092  " print (a)\n"
1093  " cnt:set(a, #a)\n"
1094  " end\n"
1095  " \n"
1096  " print (\"pre check: \" .. (a))\n"
1097  " if tonumber(a) == 2 then\n"
1098  " print \"match\"\n"
1099  " return 1\n"
1100  " end\n"
1101  " return 0\n"
1102  "end\n"
1103  "return 0\n";
1104  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1105  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1106  "Host: www.emergingthreats.net\r\n\r\n";
1107  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1108  "Host: www.openinfosecfoundation.org\r\n\r\n";
1109  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1110  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1111  TcpSession ssn;
1112  Flow f;
1113  ThreadVars th_v;
1114  DetectEngineThreadCtx *det_ctx;
1115 
1116  ut_script = script;
1117 
1118  memset(&th_v, 0, sizeof(th_v));
1119  StatsThreadInit(&th_v.stats);
1120  memset(&f, 0, sizeof(f));
1121  memset(&ssn, 0, sizeof(ssn));
1122 
1123  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1124  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1125 
1126  FLOW_INITIALIZE(&f);
1127  f.protoctx = (void *)&ssn;
1128  f.proto = IPPROTO_TCP;
1129  f.flags |= FLOW_IPV4;
1130  f.alproto = ALPROTO_HTTP1;
1131 
1132  p1->flow = &f;
1136  p2->flow = &f;
1140 
1141  StreamTcpInitConfig(true);
1142 
1145  de_ctx->flags |= DE_QUIET;
1146 
1148  FAIL_IF_NULL(s);
1149 
1151  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1152 
1153  /* do detect for p1 */
1154  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1155 
1156  FAIL_IF(PacketAlertCheck(p1, 1));
1157 
1158  /* do detect for p2 */
1159  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1160 
1161  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1162 
1163  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1164  FAIL_IF(id == 0);
1165 
1166  FlowVar *fv = FlowVarGet(&f, id);
1167  FAIL_IF_NULL(fv);
1168  FAIL_IF(fv->data.fv_str.value_len != 1);
1169  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1170 
1171  UTHFreePackets(&p1, 1);
1172  UTHFreePackets(&p2, 1);
1173  FLOW_DESTROY(&f);
1174 
1175  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1177  StreamTcpFreeConfig(true);
1178  StatsThreadCleanup(&th_v.stats);
1179  PASS;
1180 }
1181 
1182 /** \test payload buffer */
1183 static int LuaMatchTest02a(void)
1184 {
1185  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1186  "function init (args)\n"
1187  " flowvarlib.register(\"cnt\")"
1188  " local needs = {}\n"
1189  " needs[\"payload\"] = tostring(true)\n"
1190  " return needs\n"
1191  "end\n"
1192  "function thread_init (args)\n"
1193  " cnt = flowvarlib.get(\"cnt\")"
1194  "end\n"
1195  "\n"
1196  "function match(args)\n"
1197  " a = cnt:value()\n"
1198  " if a then\n"
1199  " a = tostring(tonumber(a)+1)\n"
1200  " print (a)\n"
1201  " cnt:set(a, #a)\n"
1202  " else\n"
1203  " a = tostring(1)\n"
1204  " print (a)\n"
1205  " cnt:set(a, #a)\n"
1206  " end\n"
1207  " \n"
1208  " print (\"pre check: \" .. (a))\n"
1209  " if tonumber(a) == 2 then\n"
1210  " print \"match\"\n"
1211  " return 1\n"
1212  " end\n"
1213  " return 0\n"
1214  "end\n"
1215  "return 0\n";
1216  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1217  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1218  "Host: www.emergingthreats.net\r\n\r\n";
1219  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1220  "Host: www.openinfosecfoundation.org\r\n\r\n";
1221  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1222  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1223  TcpSession ssn;
1224  Flow f;
1225  ThreadVars th_v;
1226  DetectEngineThreadCtx *det_ctx;
1227 
1228  ut_script = script;
1229 
1230  memset(&th_v, 0, sizeof(th_v));
1231  StatsThreadInit(&th_v.stats);
1232  memset(&f, 0, sizeof(f));
1233  memset(&ssn, 0, sizeof(ssn));
1234 
1235  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1236  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1237 
1238  FLOW_INITIALIZE(&f);
1239  f.protoctx = (void *)&ssn;
1240  f.proto = IPPROTO_TCP;
1241  f.flags |= FLOW_IPV4;
1242  f.alproto = ALPROTO_HTTP1;
1243 
1244  p1->flow = &f;
1248  p2->flow = &f;
1252 
1253  StreamTcpInitConfig(true);
1254 
1257  de_ctx->flags |= DE_QUIET;
1258 
1260  FAIL_IF_NULL(s);
1261 
1263  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1264 
1265  /* do detect for p1 */
1266  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1267  FAIL_IF(PacketAlertCheck(p1, 1));
1268 
1269  /* do detect for p2 */
1270  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1271  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1272 
1273  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1274  FAIL_IF(id == 0);
1275 
1276  FlowVar *fv = FlowVarGet(&f, id);
1277  FAIL_IF_NULL(fv);
1278  FAIL_IF(fv->data.fv_str.value_len != 1);
1279  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1280 
1281  UTHFreePackets(&p1, 1);
1282  UTHFreePackets(&p2, 1);
1283  FLOW_DESTROY(&f);
1284 
1285  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1287  StreamTcpFreeConfig(true);
1288  StatsThreadCleanup(&th_v.stats);
1289  PASS;
1290 }
1291 
1292 /** \test packet buffer */
1293 static int LuaMatchTest03(void)
1294 {
1295  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1296  "function init (args)\n"
1297  " flowvarlib.register(\"cnt\")\n"
1298  " local needs = {}\n"
1299  " needs[\"packet\"] = tostring(true)\n"
1300  " return needs\n"
1301  "end\n"
1302  "\n"
1303  "function thread_init (args)\n"
1304  " cnt = flowvarlib.get(\"cnt\")\n"
1305  "end\n"
1306  "\n"
1307  "function match(args)\n"
1308  " a = cnt:value()\n"
1309  " if a then\n"
1310  " a = tostring(tonumber(a)+1)\n"
1311  " print (a)\n"
1312  " cnt:set(a, #a)\n"
1313  " else\n"
1314  " a = tostring(1)\n"
1315  " print (a)\n"
1316  " cnt:set(a, #a)\n"
1317  " end\n"
1318  " \n"
1319  " print (\"pre check: \" .. (a))\n"
1320  " if tonumber(a) == 2 then\n"
1321  " print \"match\"\n"
1322  " return 1\n"
1323  " end\n"
1324  " return 0\n"
1325  "end\n"
1326  "return 0\n";
1327  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1328  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1329  "Host: www.emergingthreats.net\r\n\r\n";
1330  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1331  "Host: www.openinfosecfoundation.org\r\n\r\n";
1332  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1333  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1334  TcpSession ssn;
1335  Flow f;
1336  ThreadVars th_v;
1337  DetectEngineThreadCtx *det_ctx;
1338 
1339  ut_script = script;
1340 
1341  memset(&th_v, 0, sizeof(th_v));
1342  StatsThreadInit(&th_v.stats);
1343  memset(&f, 0, sizeof(f));
1344  memset(&ssn, 0, sizeof(ssn));
1345 
1346  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1347  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1348 
1349  FLOW_INITIALIZE(&f);
1350  f.protoctx = (void *)&ssn;
1351  f.proto = IPPROTO_TCP;
1352  f.flags |= FLOW_IPV4;
1353  f.alproto = ALPROTO_HTTP1;
1354 
1355  p1->flow = &f;
1359  p2->flow = &f;
1363 
1364  StreamTcpInitConfig(true);
1365 
1368  de_ctx->flags |= DE_QUIET;
1369 
1371  FAIL_IF_NULL(s);
1372 
1374  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1375 
1376  /* do detect for p1 */
1377  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1378  FAIL_IF(PacketAlertCheck(p1, 1));
1379 
1380  /* do detect for p2 */
1381  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1382  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1383 
1384  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1385  FAIL_IF(id == 0);
1386  FlowVar *fv = FlowVarGet(&f, id);
1387  FAIL_IF_NULL(fv);
1388  FAIL_IF(fv->data.fv_str.value_len != 1);
1389  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1390 
1391  UTHFreePackets(&p1, 1);
1392  UTHFreePackets(&p2, 1);
1393  FLOW_DESTROY(&f);
1394 
1395  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1397  StreamTcpFreeConfig(true);
1398  StatsThreadCleanup(&th_v.stats);
1399  PASS;
1400 }
1401 
1402 /** \test packet buffer */
1403 static int LuaMatchTest03a(void)
1404 {
1405  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1406  "function init (args)\n"
1407  " flowvarlib.register(\"cnt\")\n"
1408  " local needs = {}\n"
1409  " needs[\"packet\"] = tostring(true)\n"
1410  " return needs\n"
1411  "end\n"
1412  "\n"
1413  "function thread_init (args)\n"
1414  " cnt = flowvarlib.get(\"cnt\")\n"
1415  "end\n"
1416  "\n"
1417  "function match(args)\n"
1418  " a = cnt:value()\n"
1419  " if a then\n"
1420  " a = tostring(tonumber(a)+1)\n"
1421  " print (a)\n"
1422  " cnt:set(a, #a)\n"
1423  " else\n"
1424  " a = tostring(1)\n"
1425  " print (a)\n"
1426  " cnt:set(a, #a)\n"
1427  " end\n"
1428  " \n"
1429  " print (\"pre check: \" .. (a))\n"
1430  " if tonumber(a) == 2 then\n"
1431  " print \"match\"\n"
1432  " return 1\n"
1433  " end\n"
1434  " return 0\n"
1435  "end\n"
1436  "return 0\n";
1437  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1438  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1439  "Host: www.emergingthreats.net\r\n\r\n";
1440  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1441  "Host: www.openinfosecfoundation.org\r\n\r\n";
1442  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1443  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1444  TcpSession ssn;
1445  Flow f;
1446  ThreadVars th_v;
1447  DetectEngineThreadCtx *det_ctx;
1448 
1449  ut_script = script;
1450 
1451  memset(&th_v, 0, sizeof(th_v));
1452  StatsThreadInit(&th_v.stats);
1453  memset(&f, 0, sizeof(f));
1454  memset(&ssn, 0, sizeof(ssn));
1455 
1456  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1457  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1458 
1459  FLOW_INITIALIZE(&f);
1460  f.protoctx = (void *)&ssn;
1461  f.proto = IPPROTO_TCP;
1462  f.flags |= FLOW_IPV4;
1463  f.alproto = ALPROTO_HTTP1;
1464 
1465  p1->flow = &f;
1469  p2->flow = &f;
1473 
1474  StreamTcpInitConfig(true);
1475 
1478  de_ctx->flags |= DE_QUIET;
1479 
1481  FAIL_IF_NULL(s);
1482 
1484  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1485 
1486  /* do detect for p1 */
1487  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1488  FAIL_IF(PacketAlertCheck(p1, 1));
1489 
1490  /* do detect for p2 */
1491  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1492  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1493 
1494  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1495  FAIL_IF(id == 0);
1496  FlowVar *fv = FlowVarGet(&f, id);
1497  FAIL_IF_NULL(fv);
1498  FAIL_IF(fv->data.fv_str.value_len != 1);
1499  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1500 
1501  UTHFreePackets(&p1, 1);
1502  UTHFreePackets(&p2, 1);
1503  FLOW_DESTROY(&f);
1504 
1505  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1507  StreamTcpFreeConfig(true);
1508  StatsThreadCleanup(&th_v.stats);
1509  PASS;
1510 }
1511 
1512 /** \test http buffer, flowints */
1513 static int LuaMatchTest04(void)
1514 {
1515  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1516  "function init (args)\n"
1517  " flowintlib.register(\"cnt\")\n"
1518  " return {}\n"
1519  "end\n"
1520  "\n"
1521  "function thread_init (args)\n"
1522  " cnt = flowintlib.get(\"cnt\")\n"
1523  "end\n"
1524  "\n"
1525  "function match(args)\n"
1526  " print \"inspecting\""
1527  " a = cnt:value()\n"
1528  " if a then\n"
1529  " cnt:set(a + 1)\n"
1530  " else\n"
1531  " cnt:set(1)\n"
1532  " end\n"
1533  " \n"
1534  " a = cnt:value()\n"
1535  " if a == 2 then\n"
1536  " print \"match\"\n"
1537  " return 1\n"
1538  " end\n"
1539  " return 0\n"
1540  "end\n"
1541  "return 0\n";
1542  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1543  "sid:1;)";
1544  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1545  "Host: www.emergingthreats.net\r\n\r\n";
1546  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1547  "Host: www.openinfosecfoundation.org\r\n\r\n";
1548  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1549  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1550  TcpSession ssn;
1551  Flow f;
1552  ThreadVars th_v;
1553  DetectEngineThreadCtx *det_ctx;
1554 
1556 
1557  ut_script = script;
1558 
1559  memset(&th_v, 0, sizeof(th_v));
1560  StatsThreadInit(&th_v.stats);
1561  memset(&f, 0, sizeof(f));
1562  memset(&ssn, 0, sizeof(ssn));
1563 
1564  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1565  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1566 
1567  FLOW_INITIALIZE(&f);
1568  f.protoctx = (void *)&ssn;
1569  f.proto = IPPROTO_TCP;
1570  f.flags |= FLOW_IPV4;
1571  f.alproto = ALPROTO_HTTP1;
1572 
1573  p1->flow = &f;
1577 
1578  p2->flow = &f;
1582 
1583  StreamTcpInitConfig(true);
1584 
1587  de_ctx->flags |= DE_QUIET;
1588 
1590  FAIL_IF_NULL(s);
1591 
1593  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1594 
1595  int r = AppLayerParserParse(
1596  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1597  FAIL_IF(r != 0);
1598  HtpState *http_state = f.alstate;
1599  FAIL_IF_NULL(http_state);
1600 
1601  /* do detect for p1 */
1602  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1603  FAIL_IF(PacketAlertCheck(p1, 1));
1604 
1605  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1606  FAIL_IF(r != 0);
1607 
1608  /* do detect for p2 */
1609  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1610  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1611 
1612  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1613  FAIL_IF(id == 0);
1614  FlowVar *fv = FlowVarGet(&f, id);
1615  FAIL_IF_NULL(fv);
1616  FAIL_IF(fv->data.fv_int.value != 2);
1617 
1618  UTHFreePackets(&p1, 1);
1619  UTHFreePackets(&p2, 1);
1620  FLOW_DESTROY(&f);
1621 
1623  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1625  StreamTcpFreeConfig(true);
1626  StatsThreadCleanup(&th_v.stats);
1627  PASS;
1628 }
1629 
1630 /** \test http buffer, flowints */
1631 static int LuaMatchTest04a(void)
1632 {
1633  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1634  "function init (args)\n"
1635  " flowintlib.register(\"cnt\")\n"
1636  " return {}\n"
1637  "end\n"
1638  "\n"
1639  "function thread_init (args)\n"
1640  " cnt = flowintlib.get(\"cnt\")\n"
1641  "end\n"
1642  "\n"
1643  "function match(args)\n"
1644  " print \"inspecting\""
1645  " a = cnt:value()\n"
1646  " if a then\n"
1647  " cnt:set(a + 1)\n"
1648  " else\n"
1649  " cnt:set(1)\n"
1650  " end\n"
1651  " \n"
1652  " a = cnt:value()\n"
1653  " if a == 2 then\n"
1654  " print \"match\"\n"
1655  " return 1\n"
1656  " end\n"
1657  " return 0\n"
1658  "end\n"
1659  "return 0\n";
1660  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1661  "sid:1;)";
1662  uint8_t httpbuf1[] =
1663  "POST / HTTP/1.1\r\n"
1664  "Host: www.emergingthreats.net\r\n\r\n";
1665  uint8_t httpbuf2[] =
1666  "POST / HTTP/1.1\r\n"
1667  "Host: www.openinfosecfoundation.org\r\n\r\n";
1668  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1669  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1670  TcpSession ssn;
1671  Flow f;
1672  ThreadVars th_v;
1673  DetectEngineThreadCtx *det_ctx;
1674 
1676 
1677  ut_script = script;
1678 
1679  memset(&th_v, 0, sizeof(th_v));
1680  StatsThreadInit(&th_v.stats);
1681  memset(&f, 0, sizeof(f));
1682  memset(&ssn, 0, sizeof(ssn));
1683 
1684  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1685  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1686 
1687  FLOW_INITIALIZE(&f);
1688  f.protoctx = (void *)&ssn;
1689  f.proto = IPPROTO_TCP;
1690  f.flags |= FLOW_IPV4;
1691  f.alproto = ALPROTO_HTTP1;
1692 
1693  p1->flow = &f;
1697 
1698  p2->flow = &f;
1702 
1703  StreamTcpInitConfig(true);
1704 
1707  de_ctx->flags |= DE_QUIET;
1708 
1710  FAIL_IF_NULL(s);
1711 
1713  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1714 
1715  int r = AppLayerParserParse(
1716  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1717  FAIL_IF(r != 0);
1718  HtpState *http_state = f.alstate;
1719  FAIL_IF_NULL(http_state);
1720 
1721  /* do detect for p1 */
1722  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1723  FAIL_IF(PacketAlertCheck(p1, 1));
1724 
1725  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1726  FAIL_IF(r != 0);
1727 
1728  /* do detect for p2 */
1729  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1730  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1731 
1732  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1733  FAIL_IF(id == 0);
1734  FlowVar *fv = FlowVarGet(&f, id);
1735  FAIL_IF_NULL(fv);
1736  FAIL_IF(fv->data.fv_int.value != 2);
1737 
1738  UTHFreePackets(&p1, 1);
1739  UTHFreePackets(&p2, 1);
1740  FLOW_DESTROY(&f);
1741 
1743  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1745  StreamTcpFreeConfig(true);
1746  StatsThreadCleanup(&th_v.stats);
1747  PASS;
1748 }
1749 
1750 /** \test http buffer, flowints */
1751 static int LuaMatchTest05(void)
1752 {
1753  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1754  "function init (args)\n"
1755  " flowintlib.register(\"cnt\")\n"
1756  " return {}\n"
1757  "end\n"
1758  "\n"
1759  "function thread_init (args)\n"
1760  " cnt = flowintlib.get(\"cnt\")\n"
1761  "end\n"
1762  "\n"
1763  "function match(args)\n"
1764  " print \"inspecting\""
1765  " a = cnt:incr()\n"
1766  " if a == 2 then\n"
1767  " print \"match\"\n"
1768  " return 1\n"
1769  " end\n"
1770  " return 0\n"
1771  "end\n"
1772  "return 0\n";
1773  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1774  "sid:1;)";
1775  uint8_t httpbuf1[] =
1776  "POST / HTTP/1.1\r\n"
1777  "Host: www.emergingthreats.net\r\n\r\n";
1778  uint8_t httpbuf2[] =
1779  "POST / HTTP/1.1\r\n"
1780  "Host: www.openinfosecfoundation.org\r\n\r\n";
1781  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1782  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1783  TcpSession ssn;
1784  Flow f;
1785  ThreadVars th_v;
1786  DetectEngineThreadCtx *det_ctx;
1787 
1789 
1790  ut_script = script;
1791 
1792  memset(&th_v, 0, sizeof(th_v));
1793  StatsThreadInit(&th_v.stats);
1794  memset(&f, 0, sizeof(f));
1795  memset(&ssn, 0, sizeof(ssn));
1796 
1797  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1798  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1799 
1800  FLOW_INITIALIZE(&f);
1801  f.protoctx = (void *)&ssn;
1802  f.proto = IPPROTO_TCP;
1803  f.flags |= FLOW_IPV4;
1804  f.alproto = ALPROTO_HTTP1;
1805 
1806  p1->flow = &f;
1810 
1811  p2->flow = &f;
1815 
1816  StreamTcpInitConfig(true);
1817 
1820  de_ctx->flags |= DE_QUIET;
1821 
1823  FAIL_IF_NULL(s);
1824 
1826  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1827 
1828  int r = AppLayerParserParse(
1829  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1830  FAIL_IF(r != 0);
1831  HtpState *http_state = f.alstate;
1832  FAIL_IF_NULL(http_state);
1833 
1834  /* do detect for p1 */
1835  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1836  FAIL_IF(PacketAlertCheck(p1, 1));
1837 
1838  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1839  FAIL_IF(r != 0);
1840 
1841  /* do detect for p2 */
1842  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1843  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1844 
1845  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1846  FAIL_IF(id == 0);
1847  FlowVar *fv = FlowVarGet(&f, id);
1848  FAIL_IF_NULL(fv);
1849  FAIL_IF(fv->data.fv_int.value != 2);
1850 
1851  UTHFreePackets(&p1, 1);
1852  UTHFreePackets(&p2, 1);
1853  FLOW_DESTROY(&f);
1854 
1856  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1858  StreamTcpFreeConfig(true);
1859  StatsThreadCleanup(&th_v.stats);
1860  PASS;
1861 }
1862 
1863 /** \test http buffer, flowints */
1864 static int LuaMatchTest05a(void)
1865 {
1866  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1867  "function init (args)\n"
1868  " flowintlib.register(\"cnt\")\n"
1869  " return {}\n"
1870  "end\n"
1871  "\n"
1872  "function thread_init (args)\n"
1873  " cnt = flowintlib.get(\"cnt\")\n"
1874  "end\n"
1875  "\n"
1876  "function match(args)\n"
1877  " print \"inspecting\""
1878  " a = cnt:incr()\n"
1879  " if a == 2 then\n"
1880  " print \"match\"\n"
1881  " return 1\n"
1882  " end\n"
1883  " return 0\n"
1884  "end\n"
1885  "return 0\n";
1886  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1887  "sid:1;)";
1888  uint8_t httpbuf1[] =
1889  "POST / HTTP/1.1\r\n"
1890  "Host: www.emergingthreats.net\r\n\r\n";
1891  uint8_t httpbuf2[] =
1892  "POST / HTTP/1.1\r\n"
1893  "Host: www.openinfosecfoundation.org\r\n\r\n";
1894  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1895  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1896  TcpSession ssn;
1897  Flow f;
1898  ThreadVars th_v;
1899  DetectEngineThreadCtx *det_ctx;
1900 
1902 
1903  ut_script = script;
1904 
1905  memset(&th_v, 0, sizeof(th_v));
1906  StatsThreadInit(&th_v.stats);
1907  memset(&f, 0, sizeof(f));
1908  memset(&ssn, 0, sizeof(ssn));
1909 
1910  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1911  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1912 
1913  FLOW_INITIALIZE(&f);
1914  f.protoctx = (void *)&ssn;
1915  f.proto = IPPROTO_TCP;
1916  f.flags |= FLOW_IPV4;
1917  f.alproto = ALPROTO_HTTP1;
1918 
1919  p1->flow = &f;
1923 
1924  p2->flow = &f;
1928 
1929  StreamTcpInitConfig(true);
1930 
1933  de_ctx->flags |= DE_QUIET;
1934 
1936  FAIL_IF_NULL(s);
1937 
1939  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1940 
1941  int r = AppLayerParserParse(
1942  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1943  FAIL_IF(r != 0);
1944  HtpState *http_state = f.alstate;
1945  FAIL_IF_NULL(http_state);
1946 
1947  /* do detect for p1 */
1948  SCLogInfo("p1");
1949  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1950  FAIL_IF(PacketAlertCheck(p1, 1));
1951 
1952  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1953  FAIL_IF(r != 0);
1954  /* do detect for p2 */
1955  SCLogInfo("p2");
1956  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1957 
1958  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1959 
1960  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1961  FAIL_IF(id == 0);
1962  FlowVar *fv = FlowVarGet(&f, id);
1963  FAIL_IF_NULL(fv);
1964  FAIL_IF(fv->data.fv_int.value != 2);
1965 
1966  UTHFreePackets(&p1, 1);
1967  UTHFreePackets(&p2, 1);
1968  FLOW_DESTROY(&f);
1969 
1971  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1973  StreamTcpFreeConfig(true);
1974  StatsThreadCleanup(&th_v.stats);
1975  PASS;
1976 }
1977 
1978 /** \test http buffer, flowints */
1979 static int LuaMatchTest06(void)
1980 {
1981  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1982  "function init (args)\n"
1983  " flowintlib.register(\"cnt\")\n"
1984  " return {}\n"
1985  "end\n"
1986  "\n"
1987  "function thread_init (args)\n"
1988  " cnt = flowintlib.get(\"cnt\")\n"
1989  "end\n"
1990  "\n"
1991  "function match(args)\n"
1992  " print \"inspecting\""
1993  " a = cnt:value()\n"
1994  " if a == nil then\n"
1995  " print \"new var set to 2\""
1996  " cnt:set(2)\n"
1997  " end\n"
1998  " a = cnt:decr()\n"
1999  " if a == 0 then\n"
2000  " print \"match\"\n"
2001  " return 1\n"
2002  " end\n"
2003  " return 0\n"
2004  "end\n"
2005  "return 0\n";
2006  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2007  "sid:1;)";
2008  uint8_t httpbuf1[] =
2009  "POST / HTTP/1.1\r\n"
2010  "Host: www.emergingthreats.net\r\n\r\n";
2011  uint8_t httpbuf2[] =
2012  "POST / HTTP/1.1\r\n"
2013  "Host: www.openinfosecfoundation.org\r\n\r\n";
2014  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2015  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2016  TcpSession ssn;
2017  Flow f;
2018  ThreadVars th_v;
2019  DetectEngineThreadCtx *det_ctx;
2020 
2022 
2023  ut_script = script;
2024 
2025  memset(&th_v, 0, sizeof(th_v));
2026  StatsThreadInit(&th_v.stats);
2027  memset(&f, 0, sizeof(f));
2028  memset(&ssn, 0, sizeof(ssn));
2029 
2030  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2031  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2032 
2033  FLOW_INITIALIZE(&f);
2034  f.protoctx = (void *)&ssn;
2035  f.proto = IPPROTO_TCP;
2036  f.flags |= FLOW_IPV4;
2037  f.alproto = ALPROTO_HTTP1;
2038 
2039  p1->flow = &f;
2043 
2044  p2->flow = &f;
2048 
2049  StreamTcpInitConfig(true);
2050 
2053  de_ctx->flags |= DE_QUIET;
2054 
2056  FAIL_IF_NULL(s);
2057 
2059  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2060 
2061  int r = AppLayerParserParse(
2062  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2063  FAIL_IF(r != 0);
2064  HtpState *http_state = f.alstate;
2065  FAIL_IF_NULL(http_state);
2066 
2067  /* do detect for p1 */
2068  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2069  FAIL_IF(PacketAlertCheck(p1, 1));
2070 
2071  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2072  FAIL_IF(r != 0);
2073 
2074  /* do detect for p2 */
2075  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2076  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2077 
2078  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2079  FAIL_IF(id == 0);
2080  FlowVar *fv = FlowVarGet(&f, id);
2081  FAIL_IF_NULL(fv);
2082  FAIL_IF(fv->data.fv_int.value != 0);
2083 
2084  UTHFreePackets(&p1, 1);
2085  UTHFreePackets(&p2, 1);
2086  FLOW_DESTROY(&f);
2087 
2089  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2091  StreamTcpFreeConfig(true);
2092  StatsThreadCleanup(&th_v.stats);
2093  PASS;
2094 }
2095 
2096 /** \test http buffer, flowints */
2097 static int LuaMatchTest06a(void)
2098 {
2099  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2100  "function init (args)\n"
2101  " flowintlib.register(\"cnt\")\n"
2102  " return {}\n"
2103  "end\n"
2104  "\n"
2105  "function thread_init (args)\n"
2106  " cnt = flowintlib.get(\"cnt\")\n"
2107  "end\n"
2108  "\n"
2109  "function match(args)\n"
2110  " print \"inspecting\""
2111  " a = cnt:value()\n"
2112  " if a == nil then\n"
2113  " print \"new var set to 2\""
2114  " cnt:set(2)\n"
2115  " end\n"
2116  " a = cnt:decr()\n"
2117  " if a == 0 then\n"
2118  " print \"match\"\n"
2119  " return 1\n"
2120  " end\n"
2121  " return 0\n"
2122  "end\n"
2123  "return 0\n";
2124  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2125  "sid:1;)";
2126  uint8_t httpbuf1[] =
2127  "POST / HTTP/1.1\r\n"
2128  "Host: www.emergingthreats.net\r\n\r\n";
2129  uint8_t httpbuf2[] =
2130  "POST / HTTP/1.1\r\n"
2131  "Host: www.openinfosecfoundation.org\r\n\r\n";
2132  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2133  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2134  TcpSession ssn;
2135  Flow f;
2136  ThreadVars th_v;
2137  DetectEngineThreadCtx *det_ctx;
2138 
2140 
2141  ut_script = script;
2142 
2143  memset(&th_v, 0, sizeof(th_v));
2144  StatsThreadInit(&th_v.stats);
2145  memset(&f, 0, sizeof(f));
2146  memset(&ssn, 0, sizeof(ssn));
2147 
2148  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2149  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2150 
2151  FLOW_INITIALIZE(&f);
2152  f.protoctx = (void *)&ssn;
2153  f.proto = IPPROTO_TCP;
2154  f.flags |= FLOW_IPV4;
2155  f.alproto = ALPROTO_HTTP1;
2156 
2157  p1->flow = &f;
2161 
2162  p2->flow = &f;
2166 
2167  StreamTcpInitConfig(true);
2168 
2171  de_ctx->flags |= DE_QUIET;
2172 
2174  FAIL_IF_NULL(s);
2175 
2177  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2178 
2179  int r = AppLayerParserParse(
2180  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2181  FAIL_IF(r != 0);
2182  HtpState *http_state = f.alstate;
2183  FAIL_IF_NULL(http_state);
2184 
2185  /* do detect for p1 */
2186  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2187  FAIL_IF(PacketAlertCheck(p1, 1));
2188 
2189  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2190  FAIL_IF(r != 0);
2191 
2192  /* do detect for p2 */
2193  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2194  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2195 
2196  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2197  FAIL_IF(id == 0);
2198  FlowVar *fv = FlowVarGet(&f, id);
2199  FAIL_IF_NULL(fv);
2200  FAIL_IF(fv->data.fv_int.value != 0);
2201 
2202  UTHFreePackets(&p1, 1);
2203  UTHFreePackets(&p2, 1);
2204  FLOW_DESTROY(&f);
2205 
2207  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2209  StreamTcpFreeConfig(true);
2210  StatsThreadCleanup(&th_v.stats);
2211  PASS;
2212 }
2213 
2214 void DetectLuaRegisterTests(void)
2215 {
2216  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2217  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2218  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2219  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2220  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2221  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2222  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2223  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2224  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2225  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2226  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2227  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2228 }
2229 #endif
FLAG_MEMORY_LIMIT_LOGGED
#define FLAG_MEMORY_LIMIT_LOGGED
Definition: detect-lua.c:119
util-byte.h
DetectLuaData::bytevars
uint16_t bytevars
Definition: detect-lua.h:54
DetectLuaData
Definition: detect-lua.h:44
SigTableElmt_::url
const char * url
Definition: detect.h:1512
SCLuaSbState::memory_limit_error
bool memory_limit_error
Definition: util-lua-sandbox.h:56
detect-engine.h
LuaStateSetThreadVars
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv)
Definition: util-lua.c:110
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:1511
Flow_::flags
uint64_t flags
Definition: flow.h:403
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1304
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SCLuaSbUpdateBytesLimit
void SCLuaSbUpdateBytesLimit(lua_State *L)
Definition: util-lua-sandbox.c:403
util-lua-common.h
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1496
SignatureHook_::sm_list
int sm_list
Definition: detect.h:577
FLAG_BLOCKED_FUNCTION_LOGGED
#define FLAG_BLOCKED_FUNCTION_LOGGED
Definition: detect-lua.c:117
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1509
stream-tcp.h
SCLuaSbResetBytesLimit
uint64_t SCLuaSbResetBytesLimit(lua_State *L)
Definition: util-lua-sandbox.c:392
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3834
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
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:39
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
DetectLuaDataBytevarEntry_::name
char * name
Definition: detect-lua.h:40
DetectLuaData::flags
uint32_t flags
Definition: detect-lua.h:48
SCLuaSbGetContext
SCLuaSbState * SCLuaSbGetContext(lua_State *L)
Definition: util-lua-sandbox.c:359
Flow_::proto
uint8_t proto
Definition: flow.h:376
util-lua.h
ALPROTO_QUIC
@ ALPROTO_QUIC
Definition: app-layer-protos.h:57
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:144
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:41
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:368
Packet_::flags
uint32_t flags
Definition: decode.h:560
SCLuaSbState
Definition: util-lua-sandbox.h:40
Flow_
Flow data structure.
Definition: flow.h:354
FLAG_INSTRUCTION_LIMIT_LOGGED
#define FLAG_INSTRUCTION_LIMIT_LOGGED
Definition: detect-lua.c:118
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:973
DEFAULT_LUA_INSTRUCTION_LIMIT
#define DEFAULT_LUA_INSTRUCTION_LIMIT
Definition: detect-lua.c:122
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:64
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2715
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1474
DETECT_LUA_MAX_FLOWVARS
#define DETECT_LUA_MAX_FLOWVARS
Definition: detect-lua.h:35
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:324
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:231
util-var-name.h
TLS_STATE_SERVER_HELLO_DONE
@ TLS_STATE_SERVER_HELLO_DONE
Definition: app-layer-ssl.h:90
SCConfGetBool
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition: conf.c:498
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
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:365
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2971
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:53
util-lua-builtins.h
VarNameStoreRegister
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
Definition: util-var-name.c:155
DetectEngineThreadCtx_::lua_instruction_limit_errors
StatsCounterId lua_instruction_limit_errors
Definition: detect.h:1432
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3580
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:545
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:271
Flow_::protoctx
void * protoctx
Definition: flow.h:433
SigMatchData_
Data needed for Match()
Definition: detect.h:365
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1491
FLAG_DATATYPE_PACKET
#define FLAG_DATATYPE_PACKET
Definition: detect-lua.c:112
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:99
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:619
util-unittest.h
HtpState_
Definition: app-layer-htp.h:183
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DetectLuaThreadData::flags
uint32_t flags
Definition: detect-lua.h:32
DetectLuaThreadData::luastate
lua_State * luastate
Definition: detect-lua.h:31
lua_State
struct lua_State lua_State
Definition: suricata-common.h:531
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:65
DetectLuaData::buffername
char * buffername
Definition: detect-lua.h:49
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:498
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
DetectLuaData::negated
int negated
Definition: detect-lua.h:46
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:270
app-layer-htp.h
FLAG_LIST_JA3S
#define FLAG_LIST_JA3S
Definition: detect-lua.c:115
VarNameStoreLookupByName
uint32_t VarNameStoreLookupByName(const char *name, const enum VarTypes type)
find name for id+type at packet time. As the active store won't be modified, we don't need locks.
Definition: util-var-name.c:326
decode.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
SCLuaSbRestoreBytesLimit
void SCLuaSbRestoreBytesLimit(lua_State *L, const uint64_t cfg_limit)
Definition: util-lua-sandbox.c:411
DetectEngineThreadCtx_
Definition: detect.h:1291
DetectEngineThreadCtx_::lua_memory_limit_errors
StatsCounterId lua_memory_limit_errors
Definition: detect.h:1435
DetectLuaData::thread_ctx_id
int thread_ctx_id
Definition: detect-lua.h:45
DetectLuaData::instruction_limit
uint64_t instruction_limit
Definition: detect-lua.h:57
TLS_STATE_CLIENT_HELLO_DONE
@ TLS_STATE_CLIENT_HELLO_DONE
Definition: app-layer-ssl.h:80
SCConfGetInt
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:415
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:24
DETECT_LUA
@ DETECT_LUA
Definition: detect-engine-register.h:94
SignatureInitData_::list
int list
Definition: detect.h:632
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect-engine-mpm.h
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:387
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
DetectLuaRegister
void DetectLuaRegister(void)
Registration function for keyword: lua.
Definition: detect-lua.c:83
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3459
VarNameStoreUnregister
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
Definition: util-var-name.c:204
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:164
DETECT_LUA_MAX_FLOWINTS
#define DETECT_LUA_MAX_FLOWINTS
Definition: detect-lua.h:36
FLAG_DATATYPE_PAYLOAD
#define FLAG_DATATYPE_PAYLOAD
Definition: detect-lua.c:113
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
app-layer-parser.h
DetectLuaMatchBuffer
int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset, Flow *f)
Definition: detect-lua.c:238
SignatureInitData_::hook
SignatureHook hook
Definition: detect.h:594
SIGNATURE_HOOK_TYPE_NOT_SET
@ SIGNATURE_HOOK_TYPE_NOT_SET
Definition: detect.h:548
DetectEngineThreadCtx_::lua_rule_errors
StatsCounterId lua_rule_errors
Definition: detect.h:1426
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:325
DetectLuaData::bytevar
DetectLuaDataBytevarEntry bytevar[DETECT_LUA_MAX_BYTEVARS]
Definition: detect-lua.h:55
DetectLuaData::alloc_limit
uint64_t alloc_limit
Definition: detect-lua.h:56
DetectLuaData::flowints
uint16_t flowints
Definition: detect-lua.h:51
Packet_
Definition: decode.h:514
detect-engine-build.h
type
uint16_t type
Definition: decode-vlan.c:106
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:209
SCLuaSbStateClose
void SCLuaSbStateClose(lua_State *L)
Definition: util-lua-sandbox.c:368
DetectLuaData::flowint
uint32_t flowint[DETECT_LUA_MAX_FLOWINTS]
Definition: detect-lua.h:50
detect-engine-alert.h
conf.h
FLAG_ERROR_LOGGED
#define FLAG_ERROR_LOGGED
Definition: detect-lua.c:116
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:754
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1471
detect-byte.h
SCLuaRequirefBuiltIns
void SCLuaRequirefBuiltIns(lua_State *L)
Register Suricata built-in modules for loading in a non-sandboxed environment.
Definition: util-lua-builtins.c:87
SCLuaSbState::blocked_function_error
bool blocked_function_error
Definition: util-lua-sandbox.h:54
DetectLuaThreadData
Definition: detect-lua.h:30
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:232
LuaExtensionsMatchSetup
void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p, const Signature *s, uint8_t flags)
Definition: detect-lua-extensions.c:47
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:232
LuaDumpStack
void LuaDumpStack(lua_State *state, const char *prefix)
dump stack from lua state to screen
Definition: detect-lua.c:125
FlowVarTypeInt_::value
uint32_t value
Definition: flow-var.h:46
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2274
SCConfSetFinal
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:319
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1333
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:297
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
util-lua-sandbox.h
SCLuaSbLoadLibs
void SCLuaSbLoadLibs(lua_State *L)
Definition: util-lua-sandbox.c:287
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:40
Packet_::flow
struct Flow_ * flow
Definition: decode.h:562
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:1275
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:866
flags
uint8_t flags
Definition: decode-gre.h:0
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:3764
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:1315
detect-lua-extensions.h
suricata-common.h
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
DEFAULT_LUA_ALLOC_LIMIT
#define DEFAULT_LUA_ALLOC_LIMIT
Definition: detect-lua.c:121
SignatureHook_::type
enum SignatureHookType type
Definition: detect.h:576
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3706
detect-engine-buffer.h
SCLuaSbResetInstructionCounter
void SCLuaSbResetInstructionCounter(lua_State *L)
Definition: util-lua-sandbox.c:422
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
DetectEngineInspectGenericList
uint8_t DetectEngineInspectGenericList(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:2007
FlowVar_::data
union FlowVar_::@116 data
DetectLuaData::flowvars
uint16_t flowvars
Definition: detect-lua.h:52
luaext_key_ld
const char luaext_key_ld[]
Definition: detect-lua-extensions.c:45
str
#define str(s)
Definition: suricata-common.h:316
DetectEngineThreadCtx_::tv
ThreadVars * tv
Definition: detect.h:1299
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::alstate
void * alstate
Definition: flow.h:479
detect-parse.h
Signature_
Signature container.
Definition: detect.h:675
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:39
VAR_TYPE_FLOW_INT
@ VAR_TYPE_FLOW_INT
Definition: util-var.h:37
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:233
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2676
SCLuaSbState::instruction_count_error
bool instruction_count_error
Definition: util-lua-sandbox.h:55
DetectLoadCompleteSigPath
char * DetectLoadCompleteSigPath(const DetectEngineCtx *de_ctx, const char *sig_file)
Create the path if default-rule-path was specified.
Definition: detect-engine-loader.c:108
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:273
SCLuaSbStateNew
lua_State * SCLuaSbStateNew(uint64_t alloclimit, uint64_t instructionlimit)
Allocate a new Lua sandbox.
Definition: util-lua-sandbox.c:327
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:975
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:84
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:60
DetectUnregisterThreadCtxFuncs
int DetectUnregisterThreadCtxFuncs(DetectEngineCtx *de_ctx, void *data, const char *name)
Remove Thread keyword context registration.
Definition: detect-engine.c:3816
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine-buffer.c:109
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1429
flow-var.h
DetectLuaData::filename
char * filename
Definition: detect-lua.h:47
FlowVar_
Definition: flow-var.h:55
app-layer-ssl.h
DetectEngineThreadCtx_::lua_blocked_function_errors
StatsCounterId lua_blocked_function_errors
Definition: detect.h:1429
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1300
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1498
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:319
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:456
FLAG_LIST_JA3
#define FLAG_LIST_JA3
Definition: detect-lua.c:114