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