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;
310  flags = STREAM_TOSERVER;
311  else if (p->flowflags & FLOW_PKT_TOCLIENT)
312  flags = STREAM_TOCLIENT;
313 
314  /* bail early if we're not going to run inspection, avoid running the
315  * reset/restore logic at all. */
316  if ((tlua->flags & FLAG_DATATYPE_PAYLOAD) && p->payload_len == 0)
317  SCReturnInt(0);
318  if ((tlua->flags & FLAG_DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
319  SCReturnInt(0);
320 
321  /* disable bytes limit temporarily to allow the setup of buffer and other data the script will
322  * use. */
323  const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
324 
325  LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
326 
327  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
328 
329  lua_getglobal(tlua->luastate, "match");
330  lua_newtable(tlua->luastate); /* stack at -1 */
331 
332  /* restore configured bytes limit and account for the allocations done for the setup above. */
333  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
335  int r = DetectLuaRunMatch(det_ctx, lua, tlua);
336  /* restore configured limit */
337  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
338  SCReturnInt(r);
339 }
340 
341 static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
342  Flow *f, uint8_t flags, void *state,
343  const Signature *s, const SigMatchCtx *ctx)
344 {
345  SCEnter();
346  DetectLuaData *lua = (DetectLuaData *)ctx;
347  if (lua == NULL)
348  SCReturnInt(0);
349 
351  if (tlua == NULL)
352  SCReturnInt(0);
353 
354  /* disable bytes limit temporarily to allow the setup of buffer and other data the script will
355  * use. */
356  const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
357 
358  /* setup extension data for use in lua c functions */
359  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
360 
361  lua_getglobal(tlua->luastate, "match");
362  lua_newtable(tlua->luastate); /* stack at -1 */
363 
364  /* restore configured bytes limit and account for the allocations done for the setup above. */
365  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
367  int r = DetectLuaRunMatch(det_ctx, lua, tlua);
368  /* restore configured limit */
369  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
370  SCReturnInt(r);
371 }
372 
373 /**
374  * \brief match the specified lua script in a list with a tx
375  *
376  * \param t thread local vars
377  * \param det_ctx pattern matcher thread local data
378  * \param s signature being inspected
379  * \param m sigmatch that we will cast into DetectLuaData
380  *
381  * \retval 0 no match
382  * \retval 1 match
383  */
384 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
385  Flow *f, uint8_t flags,
386  void *state, void *txv, const Signature *s,
387  const SigMatchCtx *ctx)
388 {
389  return DetectLuaAppMatchCommon(det_ctx, f, flags, state, s, ctx);
390 }
391 
392 #ifdef UNITTESTS
393 /* if this ptr is set the lua setup functions will use this buffer as the
394  * lua script instead of calling luaL_loadfile on the filename supplied. */
395 static const char *ut_script = NULL;
396 #endif
397 
398 static void *DetectLuaThreadInit(void *data, bool allow_restricted_functions)
399 {
400  int status;
401  DetectLuaData *lua = (DetectLuaData *)data;
402  BUG_ON(lua == NULL);
403 
405  if (unlikely(t == NULL)) {
406  SCLogError("couldn't alloc ctx memory");
407  return NULL;
408  }
409 
410  t->flags = lua->flags;
411 
413  if (t->luastate == NULL) {
414  SCLogError("luastate pool depleted");
415  goto error;
416  }
417 
418  if (allow_restricted_functions) {
419  luaL_openlibs(t->luastate);
421  } else {
423  }
424 
425  LuaStateSetDetectLuaData(t->luastate, lua);
426 
427  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
428 #ifdef UNITTESTS
429  if (ut_script != NULL) {
430  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
431  if (status) {
432  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
433  goto error;
434  }
435  } else {
436 #endif
437  status = luaL_loadfile(t->luastate, lua->filename);
438  if (status) {
439  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
440  goto error;
441  }
442 #ifdef UNITTESTS
443  }
444 #endif
445 
446  /* prime the script (or something) */
447  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
448  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
449  goto error;
450  }
451 
452  /* thread_init call */
453  lua_getglobal(t->luastate, "thread_init");
454  if (lua_isfunction(t->luastate, -1)) {
455  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
456  SCLogError("couldn't run script 'thread_init' function: %s",
457  lua_tostring(t->luastate, -1));
458  goto error;
459  }
460  } else {
461  lua_pop(t->luastate, 1);
462  }
463 
464  return (void *)t;
465 
466 error:
467  if (t->luastate != NULL)
469  SCFree(t);
470  return NULL;
471 }
472 
473 static void *DetectLuaThreadRestrictedInit(void *data)
474 {
475  return DetectLuaThreadInit(data, false);
476 }
477 
478 static void *DetectLuaThreadAllowInit(void *data)
479 {
480  return DetectLuaThreadInit(data, true);
481 }
482 
483 static void DetectLuaThreadFree(void *ctx)
484 {
485  if (ctx != NULL) {
487  if (t->luastate != NULL)
489  SCFree(t);
490  }
491 }
492 
493 /**
494  * \brief Parse the lua keyword
495  *
496  * \param de_ctx Pointer to the detection engine context
497  * \param str Pointer to the user provided option
498  *
499  * \retval lua pointer to DetectLuaData on success
500  * \retval NULL on failure
501  */
502 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
503 {
504  DetectLuaData *lua = NULL;
505 
506  /* We have a correct lua option */
507  lua = SCCalloc(1, sizeof(DetectLuaData));
508  if (unlikely(lua == NULL))
509  goto error;
510 
511  if (strlen(str) && str[0] == '!') {
512  lua->negated = 1;
513  str++;
514  }
515 
516  /* get full filename */
518  if (lua->filename == NULL) {
519  goto error;
520  }
521 
522  return lua;
523 
524 error:
525  DetectLuaFree(de_ctx, lua);
526  return NULL;
527 }
528 
529 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s,
530  int allow_restricted_functions)
531 {
532  int status;
533 
535  if (luastate == NULL)
536  return -1;
537  if (allow_restricted_functions) {
538  luaL_openlibs(luastate);
539  SCLuaRequirefBuiltIns(luastate);
540  } else {
541  SCLuaSbLoadLibs(luastate);
542  }
543  LuaStateSetDetectLuaData(luastate, ld);
544 
545  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
546 #ifdef UNITTESTS
547  if (ut_script != NULL) {
548  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
549  if (status) {
550  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
551  goto error;
552  }
553  } else {
554 #endif
555  status = luaL_loadfile(luastate, ld->filename);
556  if (status) {
557  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
558  goto error;
559  }
560 #ifdef UNITTESTS
561  }
562 #endif
563 
564  /* prime the script (or something) */
565  if (lua_pcall(luastate, 0, 0, 0) != 0) {
566  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
567  goto error;
568  }
569 
570  lua_getglobal(luastate, "init");
571  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
572  SCLogError("no init function in script");
573  goto error;
574  }
575 
576  /* Pass the signature as the first argument, setting up bytevars depends on
577  * access to the signature. */
578  lua_pushlightuserdata(luastate, (void *)s);
579 
580  if (lua_pcall(luastate, 1, 1, 0) != 0) {
581  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
582  goto error;
583  }
584 
585  /* process returns from script */
586  if (lua_gettop(luastate) == 0) {
587  SCLogError("init function in script should return table, nothing returned");
588  goto error;
589  }
590  if (lua_type(luastate, 1) != LUA_TTABLE) {
591  SCLogError("init function in script should return table, returned is not table");
592  goto error;
593  }
594 
595  lua_pushnil(luastate);
596  const char *k;
597  while (lua_next(luastate, -2)) {
598  k = lua_tostring(luastate, -2);
599  if (k == NULL)
600  continue;
601 
602  /* handle flowvar and bytes separately as they have a table as value */
603  if (strcmp(k, "flowvar") == 0) {
604  if (lua_istable(luastate, -1)) {
605  lua_pushnil(luastate);
606  while (lua_next(luastate, -2) != 0) {
607  /* value at -1, key is at -2 which we ignore */
608  const char *value = lua_tostring(luastate, -1);
609  SCLogDebug("value %s", value);
610  /* removes 'value'; keeps 'key' for next iteration */
611  lua_pop(luastate, 1);
612 
613  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
614  SCLogError("too many flowvars registered");
615  goto error;
616  }
617 
618  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
619  if (unlikely(idx == 0))
620  goto error;
621  ld->flowvar[ld->flowvars++] = idx;
622  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
623  }
624  }
625  lua_pop(luastate, 1);
626  continue;
627  } else if (strcmp(k, "flowint") == 0) {
628  if (lua_istable(luastate, -1)) {
629  lua_pushnil(luastate);
630  while (lua_next(luastate, -2) != 0) {
631  /* value at -1, key is at -2 which we ignore */
632  const char *value = lua_tostring(luastate, -1);
633  SCLogDebug("value %s", value);
634  /* removes 'value'; keeps 'key' for next iteration */
635  lua_pop(luastate, 1);
636 
637  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
638  SCLogError("too many flowints registered");
639  goto error;
640  }
641 
642  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
643  if (unlikely(idx == 0))
644  goto error;
645  ld->flowint[ld->flowints++] = idx;
646  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
647  }
648  }
649  lua_pop(luastate, 1);
650  continue;
651  }
652 
653  bool required = lua_toboolean(luastate, -1);
654  lua_pop(luastate, 1);
655  if (!required) {
656  continue;
657  }
658 
659  if (strcmp(k, "ja3") == 0) {
660  ld->flags |= FLAG_LIST_JA3;
661  } else if (strcmp(k, "ja3s") == 0) {
662  ld->flags |= FLAG_LIST_JA3S;
663  } else if (strcmp(k, "packet") == 0) {
665  } else if (strcmp(k, "payload") == 0) {
667  } else if (strcmp(k, "buffer") == 0) {
668  ld->buffername = SCStrdup("buffer");
669  if (ld->buffername == NULL) {
670  SCLogError("alloc error");
671  goto error;
672  }
673  } else if (strcmp(k, "stream") == 0) {
674  ld->buffername = SCStrdup("stream");
675  if (ld->buffername == NULL) {
676  SCLogError("alloc error");
677  goto error;
678  }
679  /* old options no longer supported */
680  } else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
681  strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
682  strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
683  SCLogError("data type %s no longer supported, use rule hooks", k);
684  goto error;
685 
686  } else {
687  SCLogError("unsupported data type %s", k);
688  goto error;
689  }
690  }
691 
692  /* pop the table */
693  lua_pop(luastate, 1);
694  SCLuaSbStateClose(luastate);
695  return 0;
696 error:
697  SCLuaSbStateClose(luastate);
698  return -1;
699 }
700 
701 /**
702  * \brief this function is used to parse lua options
703  * \brief into the current signature
704  *
705  * \param de_ctx pointer to the Detection Engine Context
706  * \param s pointer to the Current Signature
707  * \param str pointer to the user provided "lua" option
708  *
709  * \retval 0 on Success
710  * \retval -1 on Failure
711  */
712 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
713 {
714  /* First check if Lua rules are enabled, by default Lua in rules
715  * is disabled. */
716  int enabled = 0;
717  if (SCConfGetBool("security.lua.allow-rules", &enabled) == 1 && !enabled) {
718  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
719  return -1;
720  }
721 
722  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
723  if (lua == NULL)
724  return -1;
725 
726  /* Load lua sandbox configurations */
727  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
728  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
729  (void)SCConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
730  (void)SCConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
731  lua->alloc_limit = lua_alloc_limit;
732  lua->instruction_limit = lua_instruction_limit;
733 
734  int allow_restricted_functions = 0;
735  (void)SCConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
736 
737  if (DetectLuaSetupPrime(de_ctx, lua, s, allow_restricted_functions) == -1) {
738  goto error;
739  }
740 
741  void *cb = DetectLuaThreadRestrictedInit;
742  if (allow_restricted_functions) {
743  cb = DetectLuaThreadAllowInit;
744  }
745 
746  lua->thread_ctx_id =
747  DetectRegisterThreadCtxFuncs(de_ctx, "lua", cb, (void *)lua, DetectLuaThreadFree, 0);
748  if (lua->thread_ctx_id == -1)
749  goto error;
750 
751  int list = DetectBufferGetActiveList(de_ctx, s);
752  SCLogDebug("buffer list %d -> %d", list, s->init_data->list);
753  if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
754  /* what needs to happen here is: we register to the rule hook, so e.g.
755  * http1.request_complete. This means we need a list.
756  *
757  * This includes each pkt, payload, stream, etc. */
758 
760  list = s->init_data->hook.sm_list;
761  SCLogDebug("setting list %d", list);
762  }
763  }
764 
765  if (list == -1) {
766  SCLogError("lua failed to set up");
767  goto error;
768  }
769  if (list == 0) {
770  if (lua->flags & FLAG_LIST_JA3) {
771  list = g_lua_ja3_list_id;
772  } else if (lua->flags & FLAG_LIST_JA3S) {
773  list = g_lua_ja3s_list_id;
774  }
775  }
776 
777  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
778  goto error;
779  }
780 
781  return 0;
782 
783 error:
784  if (lua != NULL)
785  DetectLuaFree(de_ctx, lua);
786  return -1;
787 }
788 
789 /**
790  * \brief this function will free memory associated with DetectLuaData
791  *
792  * \param ptr pointer to DetectLuaData
793  */
794 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
795 {
796  if (ptr != NULL) {
797  DetectLuaData *lua = (DetectLuaData *)ptr;
798 
799  if (lua->buffername)
800  SCFree(lua->buffername);
801  if (lua->filename)
802  SCFree(lua->filename);
803 
804  for (uint16_t i = 0; i < lua->flowints; i++) {
806  }
807  for (uint16_t i = 0; i < lua->flowvars; i++) {
809  }
810  for (uint16_t i = 0; i < lua->bytevars; i++) {
811  SCFree(lua->bytevar[i].name);
812  }
813 
815 
816  SCFree(lua);
817  }
818 }
819 
820 #ifdef UNITTESTS
821 #include "detect-engine-alert.h"
822 
823 /** \test http buffer */
824 static int LuaMatchTest01(void)
825 {
826  SCConfSetFinal("security.lua.allow-rules", "true");
827 
828  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
829  "function init (args)\n"
830  " flowvarlib.register(\"cnt\")\n"
831  " return {}\n"
832  "end\n"
833  "function thread_init (args)\n"
834  " cnt = flowvarlib.get(\"cnt\")\n"
835  "end\n"
836  "\n"
837  "function match(args)\n"
838  " a = cnt:value()\n"
839  " if a then\n"
840  " a = tostring(tonumber(a)+1)\n"
841  " print (a)\n"
842  " cnt:set(a, #a)\n"
843  " else\n"
844  " a = tostring(1)\n"
845  " print (a)\n"
846  " cnt:set(a, #a)\n"
847  " end\n"
848  " \n"
849  " print (\"pre check: \" .. (a))\n"
850  " if tonumber(a) == 2 then\n"
851  " print \"match\"\n"
852  " return 1\n"
853  " end\n"
854  " return 0\n"
855  "end\n"
856  "return 0\n";
857  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
858  "sid:1;)";
859  uint8_t httpbuf1[] =
860  "POST / HTTP/1.1\r\n"
861  "Host: www.emergingthreats.net\r\n\r\n";
862  uint8_t httpbuf2[] =
863  "POST / HTTP/1.1\r\n"
864  "Host: www.openinfosecfoundation.org\r\n\r\n";
865  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
866  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
867  TcpSession ssn;
868  Flow f;
870  DetectEngineThreadCtx *det_ctx;
871 
873 
874  ut_script = script;
875 
876  memset(&th_v, 0, sizeof(th_v));
878  memset(&f, 0, sizeof(f));
879  memset(&ssn, 0, sizeof(ssn));
880 
881  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
882  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
883 
884  FLOW_INITIALIZE(&f);
885  f.protoctx = (void *)&ssn;
886  f.proto = IPPROTO_TCP;
887  f.flags |= FLOW_IPV4;
889 
890  p1->flow = &f;
894  p2->flow = &f;
898 
899  StreamTcpInitConfig(true);
900 
903  de_ctx->flags |= DE_QUIET;
904 
906  FAIL_IF_NULL(s);
907 
909  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
910 
911  int r = AppLayerParserParse(
912  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
913  FAIL_IF(r != 0);
914  HtpState *http_state = f.alstate;
915  FAIL_IF_NULL(http_state);
916 
917  /* do detect for p1 */
918  SCLogDebug("inspecting p1");
919  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
920  FAIL_IF(PacketAlertCheck(p1, 1));
921 
922  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
923  FAIL_IF(r != 0);
924 
925  /* do detect for p2 */
926  SCLogDebug("inspecting p2");
927  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
929 
930  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
931  FAIL_IF(id == 0);
932 
933  FlowVar *fv = FlowVarGet(&f, id);
934  FAIL_IF_NULL(fv);
935  FAIL_IF(fv->data.fv_str.value_len != 1);
936  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
937 
938  UTHFreePackets(&p1, 1);
939  UTHFreePackets(&p2, 1);
940  FLOW_DESTROY(&f);
941 
943  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
945  StreamTcpFreeConfig(true);
947  PASS;
948 }
949 
950 static int LuaMatchTest01a(void)
951 {
952  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
953  "function init (args)\n"
954  " flowvarlib.register(\"cnt\")\n"
955  " return {}\n"
956  "end\n"
957  "function thread_init (args)\n"
958  " cnt = flowvarlib.get(\"cnt\")\n"
959  "end\n"
960  "\n"
961  "function match(args)\n"
962  " a = cnt:value(0)\n"
963  " if a then\n"
964  " a = tostring(tonumber(a)+1)\n"
965  " print (a)\n"
966  " cnt:set(a, #a)\n"
967  " else\n"
968  " a = tostring(1)\n"
969  " print (a)\n"
970  " cnt:set(a, #a)\n"
971  " end\n"
972  " \n"
973  " print (\"pre check: \" .. (a))\n"
974  " if tonumber(a) == 2 then\n"
975  " print \"match\"\n"
976  " return 1\n"
977  " end\n"
978  " return 0\n"
979  "end\n"
980  "return 0\n";
981  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
982  "sid:1;)";
983  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
984  "Host: www.emergingthreats.net\r\n\r\n";
985  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
986  "Host: www.openinfosecfoundation.org\r\n\r\n";
987  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
988  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
989  TcpSession ssn;
990  Flow f;
992  DetectEngineThreadCtx *det_ctx;
993 
995 
996  ut_script = script;
997 
998  memset(&th_v, 0, sizeof(th_v));
1000  memset(&f, 0, sizeof(f));
1001  memset(&ssn, 0, sizeof(ssn));
1002 
1003  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1004  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1005 
1006  FLOW_INITIALIZE(&f);
1007  f.protoctx = (void *)&ssn;
1008  f.proto = IPPROTO_TCP;
1009  f.flags |= FLOW_IPV4;
1010  f.alproto = ALPROTO_HTTP1;
1011 
1012  p1->flow = &f;
1016  p2->flow = &f;
1020 
1021  StreamTcpInitConfig(true);
1022 
1025  de_ctx->flags |= DE_QUIET;
1026 
1028  FAIL_IF_NULL(s);
1029 
1031  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1032 
1033  int r = AppLayerParserParse(
1034  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1035  FAIL_IF(r != 0);
1036 
1037  HtpState *http_state = f.alstate;
1038  FAIL_IF_NULL(http_state);
1039 
1040  /* do detect for p1 */
1041  SCLogDebug("inspecting p1");
1042  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1043  FAIL_IF(PacketAlertCheck(p1, 1));
1044 
1045  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1046  FAIL_IF(r != 0);
1047  /* do detect for p2 */
1048  SCLogDebug("inspecting p2");
1049  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1050  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1051 
1052  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1053  FAIL_IF(id == 0);
1054 
1055  FlowVar *fv = FlowVarGet(&f, id);
1056  FAIL_IF_NULL(fv);
1057  FAIL_IF(fv->data.fv_str.value_len != 1);
1058  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1059 
1060  UTHFreePackets(&p1, 1);
1061  UTHFreePackets(&p2, 1);
1062  FLOW_DESTROY(&f);
1063 
1065  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1067  StreamTcpFreeConfig(true);
1069  PASS;
1070 }
1071 
1072 /** \test payload buffer */
1073 static int LuaMatchTest02(void)
1074 {
1075  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1076  "function init (args)\n"
1077  " flowvarlib.register(\"cnt\")\n"
1078  " local needs = {}\n"
1079  " needs[\"payload\"] = tostring(true)\n"
1080  " return needs\n"
1081  "end\n"
1082  "function thread_init (args)\n"
1083  " cnt = flowvarlib.get(\"cnt\")\n"
1084  "end\n"
1085  "\n"
1086  "function match(args)\n"
1087  " a = cnt:value()\n"
1088  " if a then\n"
1089  " a = tostring(tonumber(a)+1)\n"
1090  " print (a)\n"
1091  " cnt:set(a, #a)\n"
1092  " else\n"
1093  " a = tostring(1)\n"
1094  " print (a)\n"
1095  " cnt:set(a, #a)\n"
1096  " end\n"
1097  " \n"
1098  " print (\"pre check: \" .. (a))\n"
1099  " if tonumber(a) == 2 then\n"
1100  " print \"match\"\n"
1101  " return 1\n"
1102  " end\n"
1103  " return 0\n"
1104  "end\n"
1105  "return 0\n";
1106  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1107  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1108  "Host: www.emergingthreats.net\r\n\r\n";
1109  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1110  "Host: www.openinfosecfoundation.org\r\n\r\n";
1111  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1112  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1113  TcpSession ssn;
1114  Flow f;
1115  ThreadVars th_v;
1116  DetectEngineThreadCtx *det_ctx;
1117 
1118  ut_script = script;
1119 
1120  memset(&th_v, 0, sizeof(th_v));
1122  memset(&f, 0, sizeof(f));
1123  memset(&ssn, 0, sizeof(ssn));
1124 
1125  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1126  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1127 
1128  FLOW_INITIALIZE(&f);
1129  f.protoctx = (void *)&ssn;
1130  f.proto = IPPROTO_TCP;
1131  f.flags |= FLOW_IPV4;
1132  f.alproto = ALPROTO_HTTP1;
1133 
1134  p1->flow = &f;
1138  p2->flow = &f;
1142 
1143  StreamTcpInitConfig(true);
1144 
1147  de_ctx->flags |= DE_QUIET;
1148 
1150  FAIL_IF_NULL(s);
1151 
1153  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1154 
1155  /* do detect for p1 */
1156  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1157 
1158  FAIL_IF(PacketAlertCheck(p1, 1));
1159 
1160  /* do detect for p2 */
1161  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1162 
1163  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1164 
1165  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1166  FAIL_IF(id == 0);
1167 
1168  FlowVar *fv = FlowVarGet(&f, id);
1169  FAIL_IF_NULL(fv);
1170  FAIL_IF(fv->data.fv_str.value_len != 1);
1171  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1172 
1173  UTHFreePackets(&p1, 1);
1174  UTHFreePackets(&p2, 1);
1175  FLOW_DESTROY(&f);
1176 
1177  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1179  StreamTcpFreeConfig(true);
1181  PASS;
1182 }
1183 
1184 /** \test payload buffer */
1185 static int LuaMatchTest02a(void)
1186 {
1187  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1188  "function init (args)\n"
1189  " flowvarlib.register(\"cnt\")"
1190  " local needs = {}\n"
1191  " needs[\"payload\"] = tostring(true)\n"
1192  " return needs\n"
1193  "end\n"
1194  "function thread_init (args)\n"
1195  " cnt = flowvarlib.get(\"cnt\")"
1196  "end\n"
1197  "\n"
1198  "function match(args)\n"
1199  " a = cnt:value()\n"
1200  " if a then\n"
1201  " a = tostring(tonumber(a)+1)\n"
1202  " print (a)\n"
1203  " cnt:set(a, #a)\n"
1204  " else\n"
1205  " a = tostring(1)\n"
1206  " print (a)\n"
1207  " cnt:set(a, #a)\n"
1208  " end\n"
1209  " \n"
1210  " print (\"pre check: \" .. (a))\n"
1211  " if tonumber(a) == 2 then\n"
1212  " print \"match\"\n"
1213  " return 1\n"
1214  " end\n"
1215  " return 0\n"
1216  "end\n"
1217  "return 0\n";
1218  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1219  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1220  "Host: www.emergingthreats.net\r\n\r\n";
1221  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1222  "Host: www.openinfosecfoundation.org\r\n\r\n";
1223  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1224  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1225  TcpSession ssn;
1226  Flow f;
1227  ThreadVars th_v;
1228  DetectEngineThreadCtx *det_ctx;
1229 
1230  ut_script = script;
1231 
1232  memset(&th_v, 0, sizeof(th_v));
1234  memset(&f, 0, sizeof(f));
1235  memset(&ssn, 0, sizeof(ssn));
1236 
1237  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1238  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1239 
1240  FLOW_INITIALIZE(&f);
1241  f.protoctx = (void *)&ssn;
1242  f.proto = IPPROTO_TCP;
1243  f.flags |= FLOW_IPV4;
1244  f.alproto = ALPROTO_HTTP1;
1245 
1246  p1->flow = &f;
1250  p2->flow = &f;
1254 
1255  StreamTcpInitConfig(true);
1256 
1259  de_ctx->flags |= DE_QUIET;
1260 
1262  FAIL_IF_NULL(s);
1263 
1265  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1266 
1267  /* do detect for p1 */
1268  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1269  FAIL_IF(PacketAlertCheck(p1, 1));
1270 
1271  /* do detect for p2 */
1272  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1273  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1274 
1275  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1276  FAIL_IF(id == 0);
1277 
1278  FlowVar *fv = FlowVarGet(&f, id);
1279  FAIL_IF_NULL(fv);
1280  FAIL_IF(fv->data.fv_str.value_len != 1);
1281  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1282 
1283  UTHFreePackets(&p1, 1);
1284  UTHFreePackets(&p2, 1);
1285  FLOW_DESTROY(&f);
1286 
1287  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1289  StreamTcpFreeConfig(true);
1291  PASS;
1292 }
1293 
1294 /** \test packet buffer */
1295 static int LuaMatchTest03(void)
1296 {
1297  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1298  "function init (args)\n"
1299  " flowvarlib.register(\"cnt\")\n"
1300  " local needs = {}\n"
1301  " needs[\"packet\"] = tostring(true)\n"
1302  " return needs\n"
1303  "end\n"
1304  "\n"
1305  "function thread_init (args)\n"
1306  " cnt = flowvarlib.get(\"cnt\")\n"
1307  "end\n"
1308  "\n"
1309  "function match(args)\n"
1310  " a = cnt:value()\n"
1311  " if a then\n"
1312  " a = tostring(tonumber(a)+1)\n"
1313  " print (a)\n"
1314  " cnt:set(a, #a)\n"
1315  " else\n"
1316  " a = tostring(1)\n"
1317  " print (a)\n"
1318  " cnt:set(a, #a)\n"
1319  " end\n"
1320  " \n"
1321  " print (\"pre check: \" .. (a))\n"
1322  " if tonumber(a) == 2 then\n"
1323  " print \"match\"\n"
1324  " return 1\n"
1325  " end\n"
1326  " return 0\n"
1327  "end\n"
1328  "return 0\n";
1329  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1330  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1331  "Host: www.emergingthreats.net\r\n\r\n";
1332  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1333  "Host: www.openinfosecfoundation.org\r\n\r\n";
1334  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1335  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1336  TcpSession ssn;
1337  Flow f;
1338  ThreadVars th_v;
1339  DetectEngineThreadCtx *det_ctx;
1340 
1341  ut_script = script;
1342 
1343  memset(&th_v, 0, sizeof(th_v));
1345  memset(&f, 0, sizeof(f));
1346  memset(&ssn, 0, sizeof(ssn));
1347 
1348  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1349  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1350 
1351  FLOW_INITIALIZE(&f);
1352  f.protoctx = (void *)&ssn;
1353  f.proto = IPPROTO_TCP;
1354  f.flags |= FLOW_IPV4;
1355  f.alproto = ALPROTO_HTTP1;
1356 
1357  p1->flow = &f;
1361  p2->flow = &f;
1365 
1366  StreamTcpInitConfig(true);
1367 
1370  de_ctx->flags |= DE_QUIET;
1371 
1373  FAIL_IF_NULL(s);
1374 
1376  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1377 
1378  /* do detect for p1 */
1379  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1380  FAIL_IF(PacketAlertCheck(p1, 1));
1381 
1382  /* do detect for p2 */
1383  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1384  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1385 
1386  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1387  FAIL_IF(id == 0);
1388  FlowVar *fv = FlowVarGet(&f, id);
1389  FAIL_IF_NULL(fv);
1390  FAIL_IF(fv->data.fv_str.value_len != 1);
1391  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1392 
1393  UTHFreePackets(&p1, 1);
1394  UTHFreePackets(&p2, 1);
1395  FLOW_DESTROY(&f);
1396 
1397  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1399  StreamTcpFreeConfig(true);
1401  PASS;
1402 }
1403 
1404 /** \test packet buffer */
1405 static int LuaMatchTest03a(void)
1406 {
1407  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1408  "function init (args)\n"
1409  " flowvarlib.register(\"cnt\")\n"
1410  " local needs = {}\n"
1411  " needs[\"packet\"] = tostring(true)\n"
1412  " return needs\n"
1413  "end\n"
1414  "\n"
1415  "function thread_init (args)\n"
1416  " cnt = flowvarlib.get(\"cnt\")\n"
1417  "end\n"
1418  "\n"
1419  "function match(args)\n"
1420  " a = cnt:value()\n"
1421  " if a then\n"
1422  " a = tostring(tonumber(a)+1)\n"
1423  " print (a)\n"
1424  " cnt:set(a, #a)\n"
1425  " else\n"
1426  " a = tostring(1)\n"
1427  " print (a)\n"
1428  " cnt:set(a, #a)\n"
1429  " end\n"
1430  " \n"
1431  " print (\"pre check: \" .. (a))\n"
1432  " if tonumber(a) == 2 then\n"
1433  " print \"match\"\n"
1434  " return 1\n"
1435  " end\n"
1436  " return 0\n"
1437  "end\n"
1438  "return 0\n";
1439  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1440  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1441  "Host: www.emergingthreats.net\r\n\r\n";
1442  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1443  "Host: www.openinfosecfoundation.org\r\n\r\n";
1444  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1445  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1446  TcpSession ssn;
1447  Flow f;
1448  ThreadVars th_v;
1449  DetectEngineThreadCtx *det_ctx;
1450 
1451  ut_script = script;
1452 
1453  memset(&th_v, 0, sizeof(th_v));
1455  memset(&f, 0, sizeof(f));
1456  memset(&ssn, 0, sizeof(ssn));
1457 
1458  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1459  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1460 
1461  FLOW_INITIALIZE(&f);
1462  f.protoctx = (void *)&ssn;
1463  f.proto = IPPROTO_TCP;
1464  f.flags |= FLOW_IPV4;
1465  f.alproto = ALPROTO_HTTP1;
1466 
1467  p1->flow = &f;
1471  p2->flow = &f;
1475 
1476  StreamTcpInitConfig(true);
1477 
1480  de_ctx->flags |= DE_QUIET;
1481 
1483  FAIL_IF_NULL(s);
1484 
1486  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1487 
1488  /* do detect for p1 */
1489  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1490  FAIL_IF(PacketAlertCheck(p1, 1));
1491 
1492  /* do detect for p2 */
1493  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1494  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1495 
1496  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1497  FAIL_IF(id == 0);
1498  FlowVar *fv = FlowVarGet(&f, id);
1499  FAIL_IF_NULL(fv);
1500  FAIL_IF(fv->data.fv_str.value_len != 1);
1501  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1502 
1503  UTHFreePackets(&p1, 1);
1504  UTHFreePackets(&p2, 1);
1505  FLOW_DESTROY(&f);
1506 
1507  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1509  StreamTcpFreeConfig(true);
1511  PASS;
1512 }
1513 
1514 /** \test http buffer, flowints */
1515 static int LuaMatchTest04(void)
1516 {
1517  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1518  "function init (args)\n"
1519  " flowintlib.register(\"cnt\")\n"
1520  " return {}\n"
1521  "end\n"
1522  "\n"
1523  "function thread_init (args)\n"
1524  " cnt = flowintlib.get(\"cnt\")\n"
1525  "end\n"
1526  "\n"
1527  "function match(args)\n"
1528  " print \"inspecting\""
1529  " a = cnt:value()\n"
1530  " if a then\n"
1531  " cnt:set(a + 1)\n"
1532  " else\n"
1533  " cnt:set(1)\n"
1534  " end\n"
1535  " \n"
1536  " a = cnt:value()\n"
1537  " if a == 2 then\n"
1538  " print \"match\"\n"
1539  " return 1\n"
1540  " end\n"
1541  " return 0\n"
1542  "end\n"
1543  "return 0\n";
1544  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1545  "sid:1;)";
1546  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1547  "Host: www.emergingthreats.net\r\n\r\n";
1548  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1549  "Host: www.openinfosecfoundation.org\r\n\r\n";
1550  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1551  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1552  TcpSession ssn;
1553  Flow f;
1554  ThreadVars th_v;
1555  DetectEngineThreadCtx *det_ctx;
1556 
1558 
1559  ut_script = script;
1560 
1561  memset(&th_v, 0, sizeof(th_v));
1563  memset(&f, 0, sizeof(f));
1564  memset(&ssn, 0, sizeof(ssn));
1565 
1566  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1567  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1568 
1569  FLOW_INITIALIZE(&f);
1570  f.protoctx = (void *)&ssn;
1571  f.proto = IPPROTO_TCP;
1572  f.flags |= FLOW_IPV4;
1573  f.alproto = ALPROTO_HTTP1;
1574 
1575  p1->flow = &f;
1579 
1580  p2->flow = &f;
1584 
1585  StreamTcpInitConfig(true);
1586 
1589  de_ctx->flags |= DE_QUIET;
1590 
1592  FAIL_IF_NULL(s);
1593 
1595  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1596 
1597  int r = AppLayerParserParse(
1598  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1599  FAIL_IF(r != 0);
1600  HtpState *http_state = f.alstate;
1601  FAIL_IF_NULL(http_state);
1602 
1603  /* do detect for p1 */
1604  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1605  FAIL_IF(PacketAlertCheck(p1, 1));
1606 
1607  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1608  FAIL_IF(r != 0);
1609 
1610  /* do detect for p2 */
1611  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1612  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1613 
1614  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1615  FAIL_IF(id == 0);
1616  FlowVar *fv = FlowVarGet(&f, id);
1617  FAIL_IF_NULL(fv);
1618  FAIL_IF(fv->data.fv_int.value != 2);
1619 
1620  UTHFreePackets(&p1, 1);
1621  UTHFreePackets(&p2, 1);
1622  FLOW_DESTROY(&f);
1623 
1625  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1627  StreamTcpFreeConfig(true);
1629  PASS;
1630 }
1631 
1632 /** \test http buffer, flowints */
1633 static int LuaMatchTest04a(void)
1634 {
1635  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1636  "function init (args)\n"
1637  " flowintlib.register(\"cnt\")\n"
1638  " return {}\n"
1639  "end\n"
1640  "\n"
1641  "function thread_init (args)\n"
1642  " cnt = flowintlib.get(\"cnt\")\n"
1643  "end\n"
1644  "\n"
1645  "function match(args)\n"
1646  " print \"inspecting\""
1647  " a = cnt:value()\n"
1648  " if a then\n"
1649  " cnt:set(a + 1)\n"
1650  " else\n"
1651  " cnt:set(1)\n"
1652  " end\n"
1653  " \n"
1654  " a = cnt:value()\n"
1655  " if a == 2 then\n"
1656  " print \"match\"\n"
1657  " return 1\n"
1658  " end\n"
1659  " return 0\n"
1660  "end\n"
1661  "return 0\n";
1662  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1663  "sid:1;)";
1664  uint8_t httpbuf1[] =
1665  "POST / HTTP/1.1\r\n"
1666  "Host: www.emergingthreats.net\r\n\r\n";
1667  uint8_t httpbuf2[] =
1668  "POST / HTTP/1.1\r\n"
1669  "Host: www.openinfosecfoundation.org\r\n\r\n";
1670  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1671  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1672  TcpSession ssn;
1673  Flow f;
1674  ThreadVars th_v;
1675  DetectEngineThreadCtx *det_ctx;
1676 
1678 
1679  ut_script = script;
1680 
1681  memset(&th_v, 0, sizeof(th_v));
1683  memset(&f, 0, sizeof(f));
1684  memset(&ssn, 0, sizeof(ssn));
1685 
1686  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1687  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1688 
1689  FLOW_INITIALIZE(&f);
1690  f.protoctx = (void *)&ssn;
1691  f.proto = IPPROTO_TCP;
1692  f.flags |= FLOW_IPV4;
1693  f.alproto = ALPROTO_HTTP1;
1694 
1695  p1->flow = &f;
1699 
1700  p2->flow = &f;
1704 
1705  StreamTcpInitConfig(true);
1706 
1709  de_ctx->flags |= DE_QUIET;
1710 
1712  FAIL_IF_NULL(s);
1713 
1715  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1716 
1717  int r = AppLayerParserParse(
1718  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1719  FAIL_IF(r != 0);
1720  HtpState *http_state = f.alstate;
1721  FAIL_IF_NULL(http_state);
1722 
1723  /* do detect for p1 */
1724  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1725  FAIL_IF(PacketAlertCheck(p1, 1));
1726 
1727  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1728  FAIL_IF(r != 0);
1729 
1730  /* do detect for p2 */
1731  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1732  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1733 
1734  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1735  FAIL_IF(id == 0);
1736  FlowVar *fv = FlowVarGet(&f, id);
1737  FAIL_IF_NULL(fv);
1738  FAIL_IF(fv->data.fv_int.value != 2);
1739 
1740  UTHFreePackets(&p1, 1);
1741  UTHFreePackets(&p2, 1);
1742  FLOW_DESTROY(&f);
1743 
1745  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1747  StreamTcpFreeConfig(true);
1749  PASS;
1750 }
1751 
1752 /** \test http buffer, flowints */
1753 static int LuaMatchTest05(void)
1754 {
1755  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1756  "function init (args)\n"
1757  " flowintlib.register(\"cnt\")\n"
1758  " return {}\n"
1759  "end\n"
1760  "\n"
1761  "function thread_init (args)\n"
1762  " cnt = flowintlib.get(\"cnt\")\n"
1763  "end\n"
1764  "\n"
1765  "function match(args)\n"
1766  " print \"inspecting\""
1767  " a = cnt:incr()\n"
1768  " if a == 2 then\n"
1769  " print \"match\"\n"
1770  " return 1\n"
1771  " end\n"
1772  " return 0\n"
1773  "end\n"
1774  "return 0\n";
1775  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1776  "sid:1;)";
1777  uint8_t httpbuf1[] =
1778  "POST / HTTP/1.1\r\n"
1779  "Host: www.emergingthreats.net\r\n\r\n";
1780  uint8_t httpbuf2[] =
1781  "POST / HTTP/1.1\r\n"
1782  "Host: www.openinfosecfoundation.org\r\n\r\n";
1783  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1784  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1785  TcpSession ssn;
1786  Flow f;
1787  ThreadVars th_v;
1788  DetectEngineThreadCtx *det_ctx;
1789 
1791 
1792  ut_script = script;
1793 
1794  memset(&th_v, 0, sizeof(th_v));
1796  memset(&f, 0, sizeof(f));
1797  memset(&ssn, 0, sizeof(ssn));
1798 
1799  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1800  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1801 
1802  FLOW_INITIALIZE(&f);
1803  f.protoctx = (void *)&ssn;
1804  f.proto = IPPROTO_TCP;
1805  f.flags |= FLOW_IPV4;
1806  f.alproto = ALPROTO_HTTP1;
1807 
1808  p1->flow = &f;
1812 
1813  p2->flow = &f;
1817 
1818  StreamTcpInitConfig(true);
1819 
1822  de_ctx->flags |= DE_QUIET;
1823 
1825  FAIL_IF_NULL(s);
1826 
1828  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1829 
1830  int r = AppLayerParserParse(
1831  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1832  FAIL_IF(r != 0);
1833  HtpState *http_state = f.alstate;
1834  FAIL_IF_NULL(http_state);
1835 
1836  /* do detect for p1 */
1837  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1838  FAIL_IF(PacketAlertCheck(p1, 1));
1839 
1840  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1841  FAIL_IF(r != 0);
1842 
1843  /* do detect for p2 */
1844  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1845  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1846 
1847  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1848  FAIL_IF(id == 0);
1849  FlowVar *fv = FlowVarGet(&f, id);
1850  FAIL_IF_NULL(fv);
1851  FAIL_IF(fv->data.fv_int.value != 2);
1852 
1853  UTHFreePackets(&p1, 1);
1854  UTHFreePackets(&p2, 1);
1855  FLOW_DESTROY(&f);
1856 
1858  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1860  StreamTcpFreeConfig(true);
1862  PASS;
1863 }
1864 
1865 /** \test http buffer, flowints */
1866 static int LuaMatchTest05a(void)
1867 {
1868  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1869  "function init (args)\n"
1870  " flowintlib.register(\"cnt\")\n"
1871  " return {}\n"
1872  "end\n"
1873  "\n"
1874  "function thread_init (args)\n"
1875  " cnt = flowintlib.get(\"cnt\")\n"
1876  "end\n"
1877  "\n"
1878  "function match(args)\n"
1879  " print \"inspecting\""
1880  " a = cnt:incr()\n"
1881  " if a == 2 then\n"
1882  " print \"match\"\n"
1883  " return 1\n"
1884  " end\n"
1885  " return 0\n"
1886  "end\n"
1887  "return 0\n";
1888  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1889  "sid:1;)";
1890  uint8_t httpbuf1[] =
1891  "POST / HTTP/1.1\r\n"
1892  "Host: www.emergingthreats.net\r\n\r\n";
1893  uint8_t httpbuf2[] =
1894  "POST / HTTP/1.1\r\n"
1895  "Host: www.openinfosecfoundation.org\r\n\r\n";
1896  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1897  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1898  TcpSession ssn;
1899  Flow f;
1900  ThreadVars th_v;
1901  DetectEngineThreadCtx *det_ctx;
1902 
1904 
1905  ut_script = script;
1906 
1907  memset(&th_v, 0, sizeof(th_v));
1909  memset(&f, 0, sizeof(f));
1910  memset(&ssn, 0, sizeof(ssn));
1911 
1912  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1913  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1914 
1915  FLOW_INITIALIZE(&f);
1916  f.protoctx = (void *)&ssn;
1917  f.proto = IPPROTO_TCP;
1918  f.flags |= FLOW_IPV4;
1919  f.alproto = ALPROTO_HTTP1;
1920 
1921  p1->flow = &f;
1925 
1926  p2->flow = &f;
1930 
1931  StreamTcpInitConfig(true);
1932 
1935  de_ctx->flags |= DE_QUIET;
1936 
1938  FAIL_IF_NULL(s);
1939 
1941  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1942 
1943  int r = AppLayerParserParse(
1944  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1945  FAIL_IF(r != 0);
1946  HtpState *http_state = f.alstate;
1947  FAIL_IF_NULL(http_state);
1948 
1949  /* do detect for p1 */
1950  SCLogInfo("p1");
1951  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1952  FAIL_IF(PacketAlertCheck(p1, 1));
1953 
1954  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1955  FAIL_IF(r != 0);
1956  /* do detect for p2 */
1957  SCLogInfo("p2");
1958  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1959 
1960  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1961 
1962  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1963  FAIL_IF(id == 0);
1964  FlowVar *fv = FlowVarGet(&f, id);
1965  FAIL_IF_NULL(fv);
1966  FAIL_IF(fv->data.fv_int.value != 2);
1967 
1968  UTHFreePackets(&p1, 1);
1969  UTHFreePackets(&p2, 1);
1970  FLOW_DESTROY(&f);
1971 
1973  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1975  StreamTcpFreeConfig(true);
1977  PASS;
1978 }
1979 
1980 /** \test http buffer, flowints */
1981 static int LuaMatchTest06(void)
1982 {
1983  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1984  "function init (args)\n"
1985  " flowintlib.register(\"cnt\")\n"
1986  " return {}\n"
1987  "end\n"
1988  "\n"
1989  "function thread_init (args)\n"
1990  " cnt = flowintlib.get(\"cnt\")\n"
1991  "end\n"
1992  "\n"
1993  "function match(args)\n"
1994  " print \"inspecting\""
1995  " a = cnt:value()\n"
1996  " if a == nil then\n"
1997  " print \"new var set to 2\""
1998  " cnt:set(2)\n"
1999  " end\n"
2000  " a = cnt:decr()\n"
2001  " if a == 0 then\n"
2002  " print \"match\"\n"
2003  " return 1\n"
2004  " end\n"
2005  " return 0\n"
2006  "end\n"
2007  "return 0\n";
2008  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2009  "sid:1;)";
2010  uint8_t httpbuf1[] =
2011  "POST / HTTP/1.1\r\n"
2012  "Host: www.emergingthreats.net\r\n\r\n";
2013  uint8_t httpbuf2[] =
2014  "POST / HTTP/1.1\r\n"
2015  "Host: www.openinfosecfoundation.org\r\n\r\n";
2016  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2017  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2018  TcpSession ssn;
2019  Flow f;
2020  ThreadVars th_v;
2021  DetectEngineThreadCtx *det_ctx;
2022 
2024 
2025  ut_script = script;
2026 
2027  memset(&th_v, 0, sizeof(th_v));
2029  memset(&f, 0, sizeof(f));
2030  memset(&ssn, 0, sizeof(ssn));
2031 
2032  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2033  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2034 
2035  FLOW_INITIALIZE(&f);
2036  f.protoctx = (void *)&ssn;
2037  f.proto = IPPROTO_TCP;
2038  f.flags |= FLOW_IPV4;
2039  f.alproto = ALPROTO_HTTP1;
2040 
2041  p1->flow = &f;
2045 
2046  p2->flow = &f;
2050 
2051  StreamTcpInitConfig(true);
2052 
2055  de_ctx->flags |= DE_QUIET;
2056 
2058  FAIL_IF_NULL(s);
2059 
2061  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2062 
2063  int r = AppLayerParserParse(
2064  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2065  FAIL_IF(r != 0);
2066  HtpState *http_state = f.alstate;
2067  FAIL_IF_NULL(http_state);
2068 
2069  /* do detect for p1 */
2070  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2071  FAIL_IF(PacketAlertCheck(p1, 1));
2072 
2073  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2074  FAIL_IF(r != 0);
2075 
2076  /* do detect for p2 */
2077  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2078  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2079 
2080  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2081  FAIL_IF(id == 0);
2082  FlowVar *fv = FlowVarGet(&f, id);
2083  FAIL_IF_NULL(fv);
2084  FAIL_IF(fv->data.fv_int.value != 0);
2085 
2086  UTHFreePackets(&p1, 1);
2087  UTHFreePackets(&p2, 1);
2088  FLOW_DESTROY(&f);
2089 
2091  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2093  StreamTcpFreeConfig(true);
2095  PASS;
2096 }
2097 
2098 /** \test http buffer, flowints */
2099 static int LuaMatchTest06a(void)
2100 {
2101  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2102  "function init (args)\n"
2103  " flowintlib.register(\"cnt\")\n"
2104  " return {}\n"
2105  "end\n"
2106  "\n"
2107  "function thread_init (args)\n"
2108  " cnt = flowintlib.get(\"cnt\")\n"
2109  "end\n"
2110  "\n"
2111  "function match(args)\n"
2112  " print \"inspecting\""
2113  " a = cnt:value()\n"
2114  " if a == nil then\n"
2115  " print \"new var set to 2\""
2116  " cnt:set(2)\n"
2117  " end\n"
2118  " a = cnt:decr()\n"
2119  " if a == 0 then\n"
2120  " print \"match\"\n"
2121  " return 1\n"
2122  " end\n"
2123  " return 0\n"
2124  "end\n"
2125  "return 0\n";
2126  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2127  "sid:1;)";
2128  uint8_t httpbuf1[] =
2129  "POST / HTTP/1.1\r\n"
2130  "Host: www.emergingthreats.net\r\n\r\n";
2131  uint8_t httpbuf2[] =
2132  "POST / HTTP/1.1\r\n"
2133  "Host: www.openinfosecfoundation.org\r\n\r\n";
2134  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2135  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2136  TcpSession ssn;
2137  Flow f;
2138  ThreadVars th_v;
2139  DetectEngineThreadCtx *det_ctx;
2140 
2142 
2143  ut_script = script;
2144 
2145  memset(&th_v, 0, sizeof(th_v));
2147  memset(&f, 0, sizeof(f));
2148  memset(&ssn, 0, sizeof(ssn));
2149 
2150  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2151  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2152 
2153  FLOW_INITIALIZE(&f);
2154  f.protoctx = (void *)&ssn;
2155  f.proto = IPPROTO_TCP;
2156  f.flags |= FLOW_IPV4;
2157  f.alproto = ALPROTO_HTTP1;
2158 
2159  p1->flow = &f;
2163 
2164  p2->flow = &f;
2168 
2169  StreamTcpInitConfig(true);
2170 
2173  de_ctx->flags |= DE_QUIET;
2174 
2176  FAIL_IF_NULL(s);
2177 
2179  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2180 
2181  int r = AppLayerParserParse(
2182  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2183  FAIL_IF(r != 0);
2184  HtpState *http_state = f.alstate;
2185  FAIL_IF_NULL(http_state);
2186 
2187  /* do detect for p1 */
2188  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2189  FAIL_IF(PacketAlertCheck(p1, 1));
2190 
2191  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2192  FAIL_IF(r != 0);
2193 
2194  /* do detect for p2 */
2195  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2196  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2197 
2198  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2199  FAIL_IF(id == 0);
2200  FlowVar *fv = FlowVarGet(&f, id);
2201  FAIL_IF_NULL(fv);
2202  FAIL_IF(fv->data.fv_int.value != 0);
2203 
2204  UTHFreePackets(&p1, 1);
2205  UTHFreePackets(&p2, 1);
2206  FLOW_DESTROY(&f);
2207 
2209  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2211  StreamTcpFreeConfig(true);
2213  PASS;
2214 }
2215 
2216 void DetectLuaRegisterTests(void)
2217 {
2218  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2219  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2220  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2221  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2222  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2223  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2224  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2225  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2226  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2227  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2228  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2229  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2230 }
2231 #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:1527
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:1526
Flow_::flags
uint64_t flags
Definition: flow.h:404
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1311
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:1511
SignatureHook_::sm_list
int sm_list
Definition: detect.h:581
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:1524
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:3999
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:377
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:371
Packet_::flags
uint32_t flags
Definition: decode.h:562
type
uint8_t type
Definition: decode-sctp.h:0
SCLuaSbState
Definition: util-lua-sandbox.h:40
Flow_
Flow data structure.
Definition: flow.h:355
FLAG_INSTRUCTION_LIMIT_LOGGED
#define FLAG_INSTRUCTION_LIMIT_LOGGED
Definition: detect-lua.c:118
ctx
struct Thresholds ctx
th_v
ThreadVars * th_v
Definition: fuzz_iprep.c:20
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:987
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:2878
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1489
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:356
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:232
util-var-name.h
TLS_STATE_SERVER_HELLO_DONE
@ TLS_STATE_SERVER_HELLO_DONE
Definition: app-layer-ssl.h:91
SCConfGetBool
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition: conf.c:524
DE_QUIET
#define DE_QUIET
Definition: detect.h:333
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:243
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:3064
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:53
util-lua-builtins.h
p
Packet * p
Definition: fuzz_iprep.c:21
VarNameStoreRegister
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
Definition: util-var-name.c:156
DetectEngineThreadCtx_::lua_instruction_limit_errors
StatsCounterId lua_instruction_limit_errors
Definition: detect.h:1447
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3859
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:547
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:274
Flow_::protoctx
void * protoctx
Definition: flow.h:434
SigMatchData_
Data needed for Match()
Definition: detect.h:368
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1506
FLAG_DATATYPE_PACKET
#define FLAG_DATATYPE_PACKET
Definition: detect-lua.c:112
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:100
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:621
util-unittest.h
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, uint8_t progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:276
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:530
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:273
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:327
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:1306
DetectEngineThreadCtx_::lua_memory_limit_errors
StatsCounterId lua_memory_limit_errors
Definition: detect.h:1450
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:81
SCConfGetInt
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:441
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:24
DETECT_LUA
@ DETECT_LUA
Definition: detect-engine-register.h:101
SignatureInitData_::list
int list
Definition: detect.h:641
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:420
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:3626
VarNameStoreUnregister
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
Definition: util-var-name.c:205
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:600
SIGNATURE_HOOK_TYPE_NOT_SET
@ SIGNATURE_HOOK_TYPE_NOT_SET
Definition: detect.h:552
DetectEngineThreadCtx_::lua_rule_errors
StatsCounterId lua_rule_errors
Definition: detect.h:1441
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:516
detect-engine-build.h
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:767
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1486
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:233
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:2300
SCConfSetFinal
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:321
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:329
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:354
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:564
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:1389
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:3929
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:1554
detect-lua-extensions.h
suricata-common.h
FlowVar_::data
union FlowVar_::@121 data
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:580
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3871
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:2121
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:1314
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:480
detect-parse.h
Signature_
Signature container.
Definition: detect.h:688
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:234
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2839
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
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:989
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:3981
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:451
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:1444
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1307
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1513
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:455
FLAG_LIST_JA3
#define FLAG_LIST_JA3
Definition: detect-lua.c:114