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/rule-lua-scripting.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_DATATYPE_STREAM BIT_U32(2)
115 #define FLAG_LIST_JA3 BIT_U32(3)
116 #define FLAG_LIST_JA3S BIT_U32(4)
117 #define FLAG_DATATYPE_BUFFER BIT_U32(22)
118 #define FLAG_ERROR_LOGGED BIT_U32(23)
119 #define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
120 #define FLAG_INSTRUCTION_LIMIT_LOGGED BIT_U32(25)
121 #define FLAG_MEMORY_LIMIT_LOGGED BIT_U32(26)
122 
123 #define DEFAULT_LUA_ALLOC_LIMIT 500000
124 #define DEFAULT_LUA_INSTRUCTION_LIMIT 500000
125 
126 /** \brief dump stack from lua state to screen */
127 void LuaDumpStack(lua_State *state, const char *prefix)
128 {
129  int size = lua_gettop(state);
130  printf("%s: size %d\n", prefix, size);
131 
132  for (int i = 1; i <= size; i++) {
133  int type = lua_type(state, i);
134  printf("- %s: Stack size=%d, level=%d, type=%d, ", prefix, size, i, type);
135 
136  switch (type) {
137  case LUA_TFUNCTION:
138  printf("function %s", lua_tostring(state, i));
139  break;
140  case LUA_TBOOLEAN:
141  printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
142  break;
143  case LUA_TNUMBER:
144  printf("number %g", lua_tonumber(state, i));
145  break;
146  case LUA_TSTRING:
147  printf("string `%s'", lua_tostring(state, i));
148  break;
149  case LUA_TTABLE:
150  printf("table `%s'", lua_tostring(state, i));
151  break;
152  default:
153  printf("other %s", lua_typename(state, type));
154  break;
155 
156  }
157  printf("\n");
158  }
159 }
160 
161 static void LuaStateSetDetectLuaData(lua_State *state, DetectLuaData *data)
162 {
163  lua_pushlightuserdata(state, (void *)&luaext_key_ld);
164  lua_pushlightuserdata(state, (void *)data);
165  lua_settable(state, LUA_REGISTRYINDEX);
166 }
167 
168 /**
169  * \brief Common function to run the Lua match function and process
170  * the return value.
171  */
172 static int DetectLuaRunMatch(
173  DetectEngineThreadCtx *det_ctx, const DetectLuaData *lua, DetectLuaThreadData *tlua)
174 {
175  /* Reset instruction count. */
177 
178  if (lua_pcall(tlua->luastate, 1, 1, 0) != 0) {
179  const char *reason = lua_tostring(tlua->luastate, -1);
180  SCLuaSbState *context = SCLuaSbGetContext(tlua->luastate);
181  uint32_t flag = 0;
182  if (context->blocked_function_error) {
185  } else if (context->instruction_count_error) {
188  } else if (context->memory_limit_error) {
189  StatsCounterIncr(&det_ctx->tv->stats, det_ctx->lua_memory_limit_errors);
190  reason = "memory limit exceeded";
192  } else {
193  flag = FLAG_ERROR_LOGGED;
194  }
195 
196  /* Log once per thread per error type, the message from Lua
197  * will include the filename. */
198  if (!(tlua->flags & flag)) {
199  SCLogWarning("Lua script failed to run successfully: %s", reason);
200  tlua->flags |= flag;
201  }
202 
203  StatsCounterIncr(&det_ctx->tv->stats, det_ctx->lua_rule_errors);
204  while (lua_gettop(tlua->luastate) > 0) {
205  lua_pop(tlua->luastate, 1);
206  }
207  SCReturnInt(0);
208  }
209 
210  int match = 0;
211 
212  /* process returns from script */
213  if (lua_gettop(tlua->luastate) > 0) {
214  /* script returns a number (return 1 or return 0) */
215  if (lua_type(tlua->luastate, 1) == LUA_TNUMBER) {
216  lua_Integer script_ret = lua_tointeger(tlua->luastate, 1);
217  SCLogDebug("script_ret %lld", script_ret);
218  lua_pop(tlua->luastate, 1);
219  if (script_ret == 1)
220  match = 1;
221  } else {
222  SCLogDebug("Unsupported datatype returned from Lua script");
223  }
224  }
225 
226  if (lua->negated) {
227  if (match == 1)
228  match = 0;
229  else
230  match = 1;
231  }
232 
233  while (lua_gettop(tlua->luastate) > 0) {
234  lua_pop(tlua->luastate, 1);
235  }
236 
237  SCReturnInt(match);
238 }
239 
241  const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset,
242  Flow *f)
243 {
244  SCEnter();
245 
246  if (buffer == NULL || buffer_len == 0)
247  SCReturnInt(0);
248 
249  DetectLuaData *lua = (DetectLuaData *)smd->ctx;
250  if (lua == NULL)
251  SCReturnInt(0);
252 
253  DetectLuaThreadData *tlua =
255  if (tlua == NULL)
256  SCReturnInt(0);
257 
258  /* disable bytes limit temporarily to allow the setup of buffer and other data the script will
259  * use. */
260  const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
261 
262  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
263 
264  /* prepare data to pass to script */
265  lua_getglobal(tlua->luastate, "match");
266  lua_newtable(tlua->luastate); /* stack at -1 */
267 
268  lua_pushliteral(tlua->luastate, "offset"); /* stack at -2 */
269  lua_pushnumber(tlua->luastate, (int)(offset + 1));
270  lua_settable(tlua->luastate, -3);
271 
272  lua_pushstring(tlua->luastate, lua->buffername); /* stack at -2 */
273  LuaPushStringBuffer(tlua->luastate, (const uint8_t *)buffer, (size_t)buffer_len);
274  lua_settable(tlua->luastate, -3);
275 
276  /* restore configured bytes limit and account for the allocations done for the setup above. */
277  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
279  int r = DetectLuaRunMatch(det_ctx, lua, tlua);
280  /* restore configured limit */
281  SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
282  SCReturnInt(r);
283 }
284 
285 /**
286  * \brief match the specified lua script
287  *
288  * \param t thread local vars
289  * \param det_ctx pattern matcher thread local data
290  * \param p packet
291  * \param s signature being inspected
292  * \param m sigmatch that we will cast into DetectLuaData
293  *
294  * \retval 0 no match
295  * \retval 1 match
296  */
297 static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
298  Packet *p, const Signature *s, const SigMatchCtx *ctx)
299 {
300  SCEnter();
301  DetectLuaData *lua = (DetectLuaData *)ctx;
302  if (lua == NULL)
303  SCReturnInt(0);
304 
306  if (tlua == NULL)
307  SCReturnInt(0);
308 
309  /* setup extension data for use in lua c functions */
310  uint8_t flags = 0;
311  if (p->flowflags & FLOW_PKT_TOSERVER)
312  flags = STREAM_TOSERVER;
313  else if (p->flowflags & FLOW_PKT_TOCLIENT)
314  flags = STREAM_TOCLIENT;
315 
316  /* disable bytes limit temporarily to allow the setup of buffer and other data the script will
317  * use. */
318  const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
319 
320  LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
321 
322  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
323 
324  if ((tlua->flags & FLAG_DATATYPE_PAYLOAD) && p->payload_len == 0)
325  SCReturnInt(0);
326  if ((tlua->flags & FLAG_DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
327  SCReturnInt(0);
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)
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 (lua->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 DetectLuaThreadFree(void *ctx)
474 {
475  if (ctx != NULL) {
477  if (t->luastate != NULL)
479  SCFree(t);
480  }
481 }
482 
483 /**
484  * \brief Parse the lua keyword
485  *
486  * \param de_ctx Pointer to the detection engine context
487  * \param str Pointer to the user provided option
488  *
489  * \retval lua pointer to DetectLuaData on success
490  * \retval NULL on failure
491  */
492 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
493 {
494  DetectLuaData *lua = NULL;
495 
496  /* We have a correct lua option */
497  lua = SCCalloc(1, sizeof(DetectLuaData));
498  if (unlikely(lua == NULL))
499  goto error;
500 
501  if (strlen(str) && str[0] == '!') {
502  lua->negated = 1;
503  str++;
504  }
505 
506  /* get full filename */
508  if (lua->filename == NULL) {
509  goto error;
510  }
511 
512  return lua;
513 
514 error:
515  DetectLuaFree(de_ctx, lua);
516  return NULL;
517 }
518 
519 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
520 {
521  int status;
522 
524  if (luastate == NULL)
525  return -1;
526  if (ld->allow_restricted_functions) {
527  luaL_openlibs(luastate);
528  SCLuaRequirefBuiltIns(luastate);
529  } else {
530  SCLuaSbLoadLibs(luastate);
531  }
532  LuaStateSetDetectLuaData(luastate, ld);
533 
534  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
535 #ifdef UNITTESTS
536  if (ut_script != NULL) {
537  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
538  if (status) {
539  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
540  goto error;
541  }
542  } else {
543 #endif
544  status = luaL_loadfile(luastate, ld->filename);
545  if (status) {
546  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
547  goto error;
548  }
549 #ifdef UNITTESTS
550  }
551 #endif
552 
553  /* prime the script (or something) */
554  if (lua_pcall(luastate, 0, 0, 0) != 0) {
555  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
556  goto error;
557  }
558 
559  lua_getglobal(luastate, "init");
560  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
561  SCLogError("no init function in script");
562  goto error;
563  }
564 
565  /* Pass the signature as the first argument, setting up bytevars depends on
566  * access to the signature. */
567  lua_pushlightuserdata(luastate, (void *)s);
568 
569  if (lua_pcall(luastate, 1, 1, 0) != 0) {
570  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
571  goto error;
572  }
573 
574  /* process returns from script */
575  if (lua_gettop(luastate) == 0) {
576  SCLogError("init function in script should return table, nothing returned");
577  goto error;
578  }
579  if (lua_type(luastate, 1) != LUA_TTABLE) {
580  SCLogError("init function in script should return table, returned is not table");
581  goto error;
582  }
583 
584  lua_pushnil(luastate);
585  const char *k;
586  while (lua_next(luastate, -2)) {
587  k = lua_tostring(luastate, -2);
588  if (k == NULL)
589  continue;
590 
591  /* handle flowvar and bytes separately as they have a table as value */
592  if (strcmp(k, "flowvar") == 0) {
593  if (lua_istable(luastate, -1)) {
594  lua_pushnil(luastate);
595  while (lua_next(luastate, -2) != 0) {
596  /* value at -1, key is at -2 which we ignore */
597  const char *value = lua_tostring(luastate, -1);
598  SCLogDebug("value %s", value);
599  /* removes 'value'; keeps 'key' for next iteration */
600  lua_pop(luastate, 1);
601 
602  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
603  SCLogError("too many flowvars registered");
604  goto error;
605  }
606 
607  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
608  if (unlikely(idx == 0))
609  goto error;
610  ld->flowvar[ld->flowvars++] = idx;
611  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
612  }
613  }
614  lua_pop(luastate, 1);
615  continue;
616  } else if (strcmp(k, "flowint") == 0) {
617  if (lua_istable(luastate, -1)) {
618  lua_pushnil(luastate);
619  while (lua_next(luastate, -2) != 0) {
620  /* value at -1, key is at -2 which we ignore */
621  const char *value = lua_tostring(luastate, -1);
622  SCLogDebug("value %s", value);
623  /* removes 'value'; keeps 'key' for next iteration */
624  lua_pop(luastate, 1);
625 
626  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
627  SCLogError("too many flowints registered");
628  goto error;
629  }
630 
631  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
632  if (unlikely(idx == 0))
633  goto error;
634  ld->flowint[ld->flowints++] = idx;
635  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
636  }
637  }
638  lua_pop(luastate, 1);
639  continue;
640  }
641 
642  bool required = lua_toboolean(luastate, -1);
643  lua_pop(luastate, 1);
644  if (!required) {
645  continue;
646  }
647 
648  if (strcmp(k, "ja3") == 0) {
649  ld->flags |= FLAG_LIST_JA3;
650  } else if (strcmp(k, "ja3s") == 0) {
651  ld->flags |= FLAG_LIST_JA3S;
652  } else if (strcmp(k, "packet") == 0) {
654  } else if (strcmp(k, "payload") == 0) {
656  } else if (strcmp(k, "buffer") == 0) {
658 
659  ld->buffername = SCStrdup("buffer");
660  if (ld->buffername == NULL) {
661  SCLogError("alloc error");
662  goto error;
663  }
664  } else if (strcmp(k, "stream") == 0) {
666 
667  ld->buffername = SCStrdup("stream");
668  if (ld->buffername == NULL) {
669  SCLogError("alloc error");
670  goto error;
671  }
672  /* old options no longer supported */
673  } else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
674  strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
675  strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
676  SCLogError("data type %s no longer supported, use rule hooks", k);
677  goto error;
678 
679  } else {
680  SCLogError("unsupported data type %s", k);
681  goto error;
682  }
683  }
684 
685  /* pop the table */
686  lua_pop(luastate, 1);
687  SCLuaSbStateClose(luastate);
688  return 0;
689 error:
690  SCLuaSbStateClose(luastate);
691  return -1;
692 }
693 
694 /**
695  * \brief this function is used to parse lua options
696  * \brief into the current signature
697  *
698  * \param de_ctx pointer to the Detection Engine Context
699  * \param s pointer to the Current Signature
700  * \param str pointer to the user provided "lua" option
701  *
702  * \retval 0 on Success
703  * \retval -1 on Failure
704  */
705 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
706 {
707  /* First check if Lua rules are enabled, by default Lua in rules
708  * is disabled. */
709  int enabled = 0;
710  if (SCConfGetBool("security.lua.allow-rules", &enabled) == 1 && !enabled) {
711  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
712  return -1;
713  }
714 
715  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
716  if (lua == NULL)
717  return -1;
718 
719  /* Load lua sandbox configurations */
720  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
721  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
722  (void)SCConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
723  (void)SCConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
724  lua->alloc_limit = lua_alloc_limit;
725  lua->instruction_limit = lua_instruction_limit;
726 
727  int allow_restricted_functions = 0;
728  (void)SCConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
729  lua->allow_restricted_functions = allow_restricted_functions;
730 
731  if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
732  goto error;
733  }
734 
736  DetectLuaThreadInit, (void *)lua,
737  DetectLuaThreadFree, 0);
738  if (lua->thread_ctx_id == -1)
739  goto error;
740 
741  int list = DetectBufferGetActiveList(de_ctx, s);
742  SCLogDebug("buffer list %d -> %d", list, s->init_data->list);
743  if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
744  /* what needs to happen here is: we register to the rule hook, so e.g.
745  * http1.request_complete. This means we need a list.
746  *
747  * This includes each pkt, payload, stream, etc. */
748 
750  list = s->init_data->hook.sm_list;
751  SCLogDebug("setting list %d", list);
752  }
753  }
754 
755  if (list == -1) {
756  SCLogError("lua failed to set up");
757  goto error;
758  }
759  if (list == 0) {
760  if (lua->flags & FLAG_LIST_JA3) {
761  list = g_lua_ja3_list_id;
762  } else if (lua->flags & FLAG_LIST_JA3S) {
763  list = g_lua_ja3s_list_id;
764  }
765  }
766 
767  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
768  goto error;
769  }
770 
771  return 0;
772 
773 error:
774  if (lua != NULL)
775  DetectLuaFree(de_ctx, lua);
776  return -1;
777 }
778 
779 /**
780  * \brief this function will free memory associated with DetectLuaData
781  *
782  * \param ptr pointer to DetectLuaData
783  */
784 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
785 {
786  if (ptr != NULL) {
787  DetectLuaData *lua = (DetectLuaData *)ptr;
788 
789  if (lua->buffername)
790  SCFree(lua->buffername);
791  if (lua->filename)
792  SCFree(lua->filename);
793 
794  for (uint16_t i = 0; i < lua->flowints; i++) {
796  }
797  for (uint16_t i = 0; i < lua->flowvars; i++) {
799  }
800  for (uint16_t i = 0; i < lua->bytevars; i++) {
801  SCFree(lua->bytevar[i].name);
802  }
803 
805 
806  SCFree(lua);
807  }
808 }
809 
810 #ifdef UNITTESTS
811 #include "detect-engine-alert.h"
812 
813 /** \test http buffer */
814 static int LuaMatchTest01(void)
815 {
816  SCConfSetFinal("security.lua.allow-rules", "true");
817 
818  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
819  "function init (args)\n"
820  " flowvarlib.register(\"cnt\")\n"
821  " return {}\n"
822  "end\n"
823  "function thread_init (args)\n"
824  " cnt = flowvarlib.get(\"cnt\")\n"
825  "end\n"
826  "\n"
827  "function match(args)\n"
828  " a = cnt:value()\n"
829  " if a then\n"
830  " a = tostring(tonumber(a)+1)\n"
831  " print (a)\n"
832  " cnt:set(a, #a)\n"
833  " else\n"
834  " a = tostring(1)\n"
835  " print (a)\n"
836  " cnt:set(a, #a)\n"
837  " end\n"
838  " \n"
839  " print (\"pre check: \" .. (a))\n"
840  " if tonumber(a) == 2 then\n"
841  " print \"match\"\n"
842  " return 1\n"
843  " end\n"
844  " return 0\n"
845  "end\n"
846  "return 0\n";
847  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
848  "sid:1;)";
849  uint8_t httpbuf1[] =
850  "POST / HTTP/1.1\r\n"
851  "Host: www.emergingthreats.net\r\n\r\n";
852  uint8_t httpbuf2[] =
853  "POST / HTTP/1.1\r\n"
854  "Host: www.openinfosecfoundation.org\r\n\r\n";
855  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
856  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
857  TcpSession ssn;
858  Flow f;
859  ThreadVars th_v;
860  DetectEngineThreadCtx *det_ctx;
861 
863 
864  ut_script = script;
865 
866  memset(&th_v, 0, sizeof(th_v));
867  StatsThreadInit(&th_v.stats);
868  memset(&f, 0, sizeof(f));
869  memset(&ssn, 0, sizeof(ssn));
870 
871  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
872  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
873 
874  FLOW_INITIALIZE(&f);
875  f.protoctx = (void *)&ssn;
876  f.proto = IPPROTO_TCP;
877  f.flags |= FLOW_IPV4;
879 
880  p1->flow = &f;
884  p2->flow = &f;
888 
889  StreamTcpInitConfig(true);
890 
893  de_ctx->flags |= DE_QUIET;
894 
896  FAIL_IF_NULL(s);
897 
899  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
900 
901  int r = AppLayerParserParse(
902  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
903  FAIL_IF(r != 0);
904  HtpState *http_state = f.alstate;
905  FAIL_IF_NULL(http_state);
906 
907  /* do detect for p1 */
908  SCLogDebug("inspecting p1");
909  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
910  FAIL_IF(PacketAlertCheck(p1, 1));
911 
912  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
913  FAIL_IF(r != 0);
914 
915  /* do detect for p2 */
916  SCLogDebug("inspecting p2");
917  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
919 
920  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
921  FAIL_IF(id == 0);
922 
923  FlowVar *fv = FlowVarGet(&f, id);
924  FAIL_IF_NULL(fv);
925  FAIL_IF(fv->data.fv_str.value_len != 1);
926  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
927 
928  UTHFreePackets(&p1, 1);
929  UTHFreePackets(&p2, 1);
930  FLOW_DESTROY(&f);
931 
933  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
935  StreamTcpFreeConfig(true);
936  StatsThreadCleanup(&th_v.stats);
937  PASS;
938 }
939 
940 static int LuaMatchTest01a(void)
941 {
942  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
943  "function init (args)\n"
944  " flowvarlib.register(\"cnt\")\n"
945  " return {}\n"
946  "end\n"
947  "function thread_init (args)\n"
948  " cnt = flowvarlib.get(\"cnt\")\n"
949  "end\n"
950  "\n"
951  "function match(args)\n"
952  " a = cnt:value(0)\n"
953  " if a then\n"
954  " a = tostring(tonumber(a)+1)\n"
955  " print (a)\n"
956  " cnt:set(a, #a)\n"
957  " else\n"
958  " a = tostring(1)\n"
959  " print (a)\n"
960  " cnt:set(a, #a)\n"
961  " end\n"
962  " \n"
963  " print (\"pre check: \" .. (a))\n"
964  " if tonumber(a) == 2 then\n"
965  " print \"match\"\n"
966  " return 1\n"
967  " end\n"
968  " return 0\n"
969  "end\n"
970  "return 0\n";
971  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
972  "sid:1;)";
973  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
974  "Host: www.emergingthreats.net\r\n\r\n";
975  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
976  "Host: www.openinfosecfoundation.org\r\n\r\n";
977  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
978  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
979  TcpSession ssn;
980  Flow f;
981  ThreadVars th_v;
982  DetectEngineThreadCtx *det_ctx;
983 
985 
986  ut_script = script;
987 
988  memset(&th_v, 0, sizeof(th_v));
989  StatsThreadInit(&th_v.stats);
990  memset(&f, 0, sizeof(f));
991  memset(&ssn, 0, sizeof(ssn));
992 
993  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
994  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
995 
996  FLOW_INITIALIZE(&f);
997  f.protoctx = (void *)&ssn;
998  f.proto = IPPROTO_TCP;
999  f.flags |= FLOW_IPV4;
1000  f.alproto = ALPROTO_HTTP1;
1001 
1002  p1->flow = &f;
1006  p2->flow = &f;
1010 
1011  StreamTcpInitConfig(true);
1012 
1015  de_ctx->flags |= DE_QUIET;
1016 
1018  FAIL_IF_NULL(s);
1019 
1021  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1022 
1023  int r = AppLayerParserParse(
1024  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1025  FAIL_IF(r != 0);
1026 
1027  HtpState *http_state = f.alstate;
1028  FAIL_IF_NULL(http_state);
1029 
1030  /* do detect for p1 */
1031  SCLogDebug("inspecting p1");
1032  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1033  FAIL_IF(PacketAlertCheck(p1, 1));
1034 
1035  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1036  FAIL_IF(r != 0);
1037  /* do detect for p2 */
1038  SCLogDebug("inspecting p2");
1039  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1040  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1041 
1042  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1043  FAIL_IF(id == 0);
1044 
1045  FlowVar *fv = FlowVarGet(&f, id);
1046  FAIL_IF_NULL(fv);
1047  FAIL_IF(fv->data.fv_str.value_len != 1);
1048  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1049 
1050  UTHFreePackets(&p1, 1);
1051  UTHFreePackets(&p2, 1);
1052  FLOW_DESTROY(&f);
1053 
1055  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1057  StreamTcpFreeConfig(true);
1058  StatsThreadCleanup(&th_v.stats);
1059  PASS;
1060 }
1061 
1062 /** \test payload buffer */
1063 static int LuaMatchTest02(void)
1064 {
1065  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1066  "function init (args)\n"
1067  " flowvarlib.register(\"cnt\")\n"
1068  " local needs = {}\n"
1069  " needs[\"payload\"] = tostring(true)\n"
1070  " return needs\n"
1071  "end\n"
1072  "function thread_init (args)\n"
1073  " cnt = flowvarlib.get(\"cnt\")\n"
1074  "end\n"
1075  "\n"
1076  "function match(args)\n"
1077  " a = cnt:value()\n"
1078  " if a then\n"
1079  " a = tostring(tonumber(a)+1)\n"
1080  " print (a)\n"
1081  " cnt:set(a, #a)\n"
1082  " else\n"
1083  " a = tostring(1)\n"
1084  " print (a)\n"
1085  " cnt:set(a, #a)\n"
1086  " end\n"
1087  " \n"
1088  " print (\"pre check: \" .. (a))\n"
1089  " if tonumber(a) == 2 then\n"
1090  " print \"match\"\n"
1091  " return 1\n"
1092  " end\n"
1093  " return 0\n"
1094  "end\n"
1095  "return 0\n";
1096  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1097  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1098  "Host: www.emergingthreats.net\r\n\r\n";
1099  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1100  "Host: www.openinfosecfoundation.org\r\n\r\n";
1101  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1102  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1103  TcpSession ssn;
1104  Flow f;
1105  ThreadVars th_v;
1106  DetectEngineThreadCtx *det_ctx;
1107 
1108  ut_script = script;
1109 
1110  memset(&th_v, 0, sizeof(th_v));
1111  StatsThreadInit(&th_v.stats);
1112  memset(&f, 0, sizeof(f));
1113  memset(&ssn, 0, sizeof(ssn));
1114 
1115  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1116  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1117 
1118  FLOW_INITIALIZE(&f);
1119  f.protoctx = (void *)&ssn;
1120  f.proto = IPPROTO_TCP;
1121  f.flags |= FLOW_IPV4;
1122  f.alproto = ALPROTO_HTTP1;
1123 
1124  p1->flow = &f;
1128  p2->flow = &f;
1132 
1133  StreamTcpInitConfig(true);
1134 
1137  de_ctx->flags |= DE_QUIET;
1138 
1140  FAIL_IF_NULL(s);
1141 
1143  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1144 
1145  /* do detect for p1 */
1146  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1147 
1148  FAIL_IF(PacketAlertCheck(p1, 1));
1149 
1150  /* do detect for p2 */
1151  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1152 
1153  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1154 
1155  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1156  FAIL_IF(id == 0);
1157 
1158  FlowVar *fv = FlowVarGet(&f, id);
1159  FAIL_IF_NULL(fv);
1160  FAIL_IF(fv->data.fv_str.value_len != 1);
1161  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1162 
1163  UTHFreePackets(&p1, 1);
1164  UTHFreePackets(&p2, 1);
1165  FLOW_DESTROY(&f);
1166 
1167  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1169  StreamTcpFreeConfig(true);
1170  StatsThreadCleanup(&th_v.stats);
1171  PASS;
1172 }
1173 
1174 /** \test payload buffer */
1175 static int LuaMatchTest02a(void)
1176 {
1177  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1178  "function init (args)\n"
1179  " flowvarlib.register(\"cnt\")"
1180  " local needs = {}\n"
1181  " needs[\"payload\"] = tostring(true)\n"
1182  " return needs\n"
1183  "end\n"
1184  "function thread_init (args)\n"
1185  " cnt = flowvarlib.get(\"cnt\")"
1186  "end\n"
1187  "\n"
1188  "function match(args)\n"
1189  " a = cnt:value()\n"
1190  " if a then\n"
1191  " a = tostring(tonumber(a)+1)\n"
1192  " print (a)\n"
1193  " cnt:set(a, #a)\n"
1194  " else\n"
1195  " a = tostring(1)\n"
1196  " print (a)\n"
1197  " cnt:set(a, #a)\n"
1198  " end\n"
1199  " \n"
1200  " print (\"pre check: \" .. (a))\n"
1201  " if tonumber(a) == 2 then\n"
1202  " print \"match\"\n"
1203  " return 1\n"
1204  " end\n"
1205  " return 0\n"
1206  "end\n"
1207  "return 0\n";
1208  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1209  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1210  "Host: www.emergingthreats.net\r\n\r\n";
1211  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1212  "Host: www.openinfosecfoundation.org\r\n\r\n";
1213  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1214  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1215  TcpSession ssn;
1216  Flow f;
1217  ThreadVars th_v;
1218  DetectEngineThreadCtx *det_ctx;
1219 
1220  ut_script = script;
1221 
1222  memset(&th_v, 0, sizeof(th_v));
1223  StatsThreadInit(&th_v.stats);
1224  memset(&f, 0, sizeof(f));
1225  memset(&ssn, 0, sizeof(ssn));
1226 
1227  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1228  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1229 
1230  FLOW_INITIALIZE(&f);
1231  f.protoctx = (void *)&ssn;
1232  f.proto = IPPROTO_TCP;
1233  f.flags |= FLOW_IPV4;
1234  f.alproto = ALPROTO_HTTP1;
1235 
1236  p1->flow = &f;
1240  p2->flow = &f;
1244 
1245  StreamTcpInitConfig(true);
1246 
1249  de_ctx->flags |= DE_QUIET;
1250 
1252  FAIL_IF_NULL(s);
1253 
1255  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1256 
1257  /* do detect for p1 */
1258  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1259  FAIL_IF(PacketAlertCheck(p1, 1));
1260 
1261  /* do detect for p2 */
1262  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1263  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1264 
1265  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1266  FAIL_IF(id == 0);
1267 
1268  FlowVar *fv = FlowVarGet(&f, id);
1269  FAIL_IF_NULL(fv);
1270  FAIL_IF(fv->data.fv_str.value_len != 1);
1271  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1272 
1273  UTHFreePackets(&p1, 1);
1274  UTHFreePackets(&p2, 1);
1275  FLOW_DESTROY(&f);
1276 
1277  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1279  StreamTcpFreeConfig(true);
1280  StatsThreadCleanup(&th_v.stats);
1281  PASS;
1282 }
1283 
1284 /** \test packet buffer */
1285 static int LuaMatchTest03(void)
1286 {
1287  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1288  "function init (args)\n"
1289  " flowvarlib.register(\"cnt\")\n"
1290  " local needs = {}\n"
1291  " needs[\"packet\"] = tostring(true)\n"
1292  " return needs\n"
1293  "end\n"
1294  "\n"
1295  "function thread_init (args)\n"
1296  " cnt = flowvarlib.get(\"cnt\")\n"
1297  "end\n"
1298  "\n"
1299  "function match(args)\n"
1300  " a = cnt:value()\n"
1301  " if a then\n"
1302  " a = tostring(tonumber(a)+1)\n"
1303  " print (a)\n"
1304  " cnt:set(a, #a)\n"
1305  " else\n"
1306  " a = tostring(1)\n"
1307  " print (a)\n"
1308  " cnt:set(a, #a)\n"
1309  " end\n"
1310  " \n"
1311  " print (\"pre check: \" .. (a))\n"
1312  " if tonumber(a) == 2 then\n"
1313  " print \"match\"\n"
1314  " return 1\n"
1315  " end\n"
1316  " return 0\n"
1317  "end\n"
1318  "return 0\n";
1319  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1320  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1321  "Host: www.emergingthreats.net\r\n\r\n";
1322  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1323  "Host: www.openinfosecfoundation.org\r\n\r\n";
1324  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1325  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1326  TcpSession ssn;
1327  Flow f;
1328  ThreadVars th_v;
1329  DetectEngineThreadCtx *det_ctx;
1330 
1331  ut_script = script;
1332 
1333  memset(&th_v, 0, sizeof(th_v));
1334  StatsThreadInit(&th_v.stats);
1335  memset(&f, 0, sizeof(f));
1336  memset(&ssn, 0, sizeof(ssn));
1337 
1338  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1339  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1340 
1341  FLOW_INITIALIZE(&f);
1342  f.protoctx = (void *)&ssn;
1343  f.proto = IPPROTO_TCP;
1344  f.flags |= FLOW_IPV4;
1345  f.alproto = ALPROTO_HTTP1;
1346 
1347  p1->flow = &f;
1351  p2->flow = &f;
1355 
1356  StreamTcpInitConfig(true);
1357 
1360  de_ctx->flags |= DE_QUIET;
1361 
1363  FAIL_IF_NULL(s);
1364 
1366  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1367 
1368  /* do detect for p1 */
1369  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1370  FAIL_IF(PacketAlertCheck(p1, 1));
1371 
1372  /* do detect for p2 */
1373  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1374  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1375 
1376  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1377  FAIL_IF(id == 0);
1378  FlowVar *fv = FlowVarGet(&f, id);
1379  FAIL_IF_NULL(fv);
1380  FAIL_IF(fv->data.fv_str.value_len != 1);
1381  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1382 
1383  UTHFreePackets(&p1, 1);
1384  UTHFreePackets(&p2, 1);
1385  FLOW_DESTROY(&f);
1386 
1387  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1389  StreamTcpFreeConfig(true);
1390  StatsThreadCleanup(&th_v.stats);
1391  PASS;
1392 }
1393 
1394 /** \test packet buffer */
1395 static int LuaMatchTest03a(void)
1396 {
1397  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1398  "function init (args)\n"
1399  " flowvarlib.register(\"cnt\")\n"
1400  " local needs = {}\n"
1401  " needs[\"packet\"] = tostring(true)\n"
1402  " return needs\n"
1403  "end\n"
1404  "\n"
1405  "function thread_init (args)\n"
1406  " cnt = flowvarlib.get(\"cnt\")\n"
1407  "end\n"
1408  "\n"
1409  "function match(args)\n"
1410  " a = cnt:value()\n"
1411  " if a then\n"
1412  " a = tostring(tonumber(a)+1)\n"
1413  " print (a)\n"
1414  " cnt:set(a, #a)\n"
1415  " else\n"
1416  " a = tostring(1)\n"
1417  " print (a)\n"
1418  " cnt:set(a, #a)\n"
1419  " end\n"
1420  " \n"
1421  " print (\"pre check: \" .. (a))\n"
1422  " if tonumber(a) == 2 then\n"
1423  " print \"match\"\n"
1424  " return 1\n"
1425  " end\n"
1426  " return 0\n"
1427  "end\n"
1428  "return 0\n";
1429  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1430  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1431  "Host: www.emergingthreats.net\r\n\r\n";
1432  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1433  "Host: www.openinfosecfoundation.org\r\n\r\n";
1434  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1435  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1436  TcpSession ssn;
1437  Flow f;
1438  ThreadVars th_v;
1439  DetectEngineThreadCtx *det_ctx;
1440 
1441  ut_script = script;
1442 
1443  memset(&th_v, 0, sizeof(th_v));
1444  StatsThreadInit(&th_v.stats);
1445  memset(&f, 0, sizeof(f));
1446  memset(&ssn, 0, sizeof(ssn));
1447 
1448  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1449  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1450 
1451  FLOW_INITIALIZE(&f);
1452  f.protoctx = (void *)&ssn;
1453  f.proto = IPPROTO_TCP;
1454  f.flags |= FLOW_IPV4;
1455  f.alproto = ALPROTO_HTTP1;
1456 
1457  p1->flow = &f;
1461  p2->flow = &f;
1465 
1466  StreamTcpInitConfig(true);
1467 
1470  de_ctx->flags |= DE_QUIET;
1471 
1473  FAIL_IF_NULL(s);
1474 
1476  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1477 
1478  /* do detect for p1 */
1479  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1480  FAIL_IF(PacketAlertCheck(p1, 1));
1481 
1482  /* do detect for p2 */
1483  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1484  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1485 
1486  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1487  FAIL_IF(id == 0);
1488  FlowVar *fv = FlowVarGet(&f, id);
1489  FAIL_IF_NULL(fv);
1490  FAIL_IF(fv->data.fv_str.value_len != 1);
1491  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1492 
1493  UTHFreePackets(&p1, 1);
1494  UTHFreePackets(&p2, 1);
1495  FLOW_DESTROY(&f);
1496 
1497  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1499  StreamTcpFreeConfig(true);
1500  StatsThreadCleanup(&th_v.stats);
1501  PASS;
1502 }
1503 
1504 /** \test http buffer, flowints */
1505 static int LuaMatchTest04(void)
1506 {
1507  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1508  "function init (args)\n"
1509  " flowintlib.register(\"cnt\")\n"
1510  " return {}\n"
1511  "end\n"
1512  "\n"
1513  "function thread_init (args)\n"
1514  " cnt = flowintlib.get(\"cnt\")\n"
1515  "end\n"
1516  "\n"
1517  "function match(args)\n"
1518  " print \"inspecting\""
1519  " a = cnt:value()\n"
1520  " if a then\n"
1521  " cnt:set(a + 1)\n"
1522  " else\n"
1523  " cnt:set(1)\n"
1524  " end\n"
1525  " \n"
1526  " a = cnt:value()\n"
1527  " if a == 2 then\n"
1528  " print \"match\"\n"
1529  " return 1\n"
1530  " end\n"
1531  " return 0\n"
1532  "end\n"
1533  "return 0\n";
1534  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1535  "sid:1;)";
1536  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1537  "Host: www.emergingthreats.net\r\n\r\n";
1538  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1539  "Host: www.openinfosecfoundation.org\r\n\r\n";
1540  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1541  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1542  TcpSession ssn;
1543  Flow f;
1544  ThreadVars th_v;
1545  DetectEngineThreadCtx *det_ctx;
1546 
1548 
1549  ut_script = script;
1550 
1551  memset(&th_v, 0, sizeof(th_v));
1552  StatsThreadInit(&th_v.stats);
1553  memset(&f, 0, sizeof(f));
1554  memset(&ssn, 0, sizeof(ssn));
1555 
1556  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1557  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1558 
1559  FLOW_INITIALIZE(&f);
1560  f.protoctx = (void *)&ssn;
1561  f.proto = IPPROTO_TCP;
1562  f.flags |= FLOW_IPV4;
1563  f.alproto = ALPROTO_HTTP1;
1564 
1565  p1->flow = &f;
1569 
1570  p2->flow = &f;
1574 
1575  StreamTcpInitConfig(true);
1576 
1579  de_ctx->flags |= DE_QUIET;
1580 
1582  FAIL_IF_NULL(s);
1583 
1585  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1586 
1587  int r = AppLayerParserParse(
1588  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1589  FAIL_IF(r != 0);
1590  HtpState *http_state = f.alstate;
1591  FAIL_IF_NULL(http_state);
1592 
1593  /* do detect for p1 */
1594  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1595  FAIL_IF(PacketAlertCheck(p1, 1));
1596 
1597  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1598  FAIL_IF(r != 0);
1599 
1600  /* do detect for p2 */
1601  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1602  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1603 
1604  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1605  FAIL_IF(id == 0);
1606  FlowVar *fv = FlowVarGet(&f, id);
1607  FAIL_IF_NULL(fv);
1608  FAIL_IF(fv->data.fv_int.value != 2);
1609 
1610  UTHFreePackets(&p1, 1);
1611  UTHFreePackets(&p2, 1);
1612  FLOW_DESTROY(&f);
1613 
1615  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1617  StreamTcpFreeConfig(true);
1618  StatsThreadCleanup(&th_v.stats);
1619  PASS;
1620 }
1621 
1622 /** \test http buffer, flowints */
1623 static int LuaMatchTest04a(void)
1624 {
1625  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1626  "function init (args)\n"
1627  " flowintlib.register(\"cnt\")\n"
1628  " return {}\n"
1629  "end\n"
1630  "\n"
1631  "function thread_init (args)\n"
1632  " cnt = flowintlib.get(\"cnt\")\n"
1633  "end\n"
1634  "\n"
1635  "function match(args)\n"
1636  " print \"inspecting\""
1637  " a = cnt:value()\n"
1638  " if a then\n"
1639  " cnt:set(a + 1)\n"
1640  " else\n"
1641  " cnt:set(1)\n"
1642  " end\n"
1643  " \n"
1644  " a = cnt:value()\n"
1645  " if a == 2 then\n"
1646  " print \"match\"\n"
1647  " return 1\n"
1648  " end\n"
1649  " return 0\n"
1650  "end\n"
1651  "return 0\n";
1652  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1653  "sid:1;)";
1654  uint8_t httpbuf1[] =
1655  "POST / HTTP/1.1\r\n"
1656  "Host: www.emergingthreats.net\r\n\r\n";
1657  uint8_t httpbuf2[] =
1658  "POST / HTTP/1.1\r\n"
1659  "Host: www.openinfosecfoundation.org\r\n\r\n";
1660  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1661  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1662  TcpSession ssn;
1663  Flow f;
1664  ThreadVars th_v;
1665  DetectEngineThreadCtx *det_ctx;
1666 
1668 
1669  ut_script = script;
1670 
1671  memset(&th_v, 0, sizeof(th_v));
1672  StatsThreadInit(&th_v.stats);
1673  memset(&f, 0, sizeof(f));
1674  memset(&ssn, 0, sizeof(ssn));
1675 
1676  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1677  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1678 
1679  FLOW_INITIALIZE(&f);
1680  f.protoctx = (void *)&ssn;
1681  f.proto = IPPROTO_TCP;
1682  f.flags |= FLOW_IPV4;
1683  f.alproto = ALPROTO_HTTP1;
1684 
1685  p1->flow = &f;
1689 
1690  p2->flow = &f;
1694 
1695  StreamTcpInitConfig(true);
1696 
1699  de_ctx->flags |= DE_QUIET;
1700 
1702  FAIL_IF_NULL(s);
1703 
1705  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1706 
1707  int r = AppLayerParserParse(
1708  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1709  FAIL_IF(r != 0);
1710  HtpState *http_state = f.alstate;
1711  FAIL_IF_NULL(http_state);
1712 
1713  /* do detect for p1 */
1714  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1715  FAIL_IF(PacketAlertCheck(p1, 1));
1716 
1717  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1718  FAIL_IF(r != 0);
1719 
1720  /* do detect for p2 */
1721  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1722  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1723 
1724  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1725  FAIL_IF(id == 0);
1726  FlowVar *fv = FlowVarGet(&f, id);
1727  FAIL_IF_NULL(fv);
1728  FAIL_IF(fv->data.fv_int.value != 2);
1729 
1730  UTHFreePackets(&p1, 1);
1731  UTHFreePackets(&p2, 1);
1732  FLOW_DESTROY(&f);
1733 
1735  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1737  StreamTcpFreeConfig(true);
1738  StatsThreadCleanup(&th_v.stats);
1739  PASS;
1740 }
1741 
1742 /** \test http buffer, flowints */
1743 static int LuaMatchTest05(void)
1744 {
1745  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1746  "function init (args)\n"
1747  " flowintlib.register(\"cnt\")\n"
1748  " return {}\n"
1749  "end\n"
1750  "\n"
1751  "function thread_init (args)\n"
1752  " cnt = flowintlib.get(\"cnt\")\n"
1753  "end\n"
1754  "\n"
1755  "function match(args)\n"
1756  " print \"inspecting\""
1757  " a = cnt:incr()\n"
1758  " if a == 2 then\n"
1759  " print \"match\"\n"
1760  " return 1\n"
1761  " end\n"
1762  " return 0\n"
1763  "end\n"
1764  "return 0\n";
1765  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1766  "sid:1;)";
1767  uint8_t httpbuf1[] =
1768  "POST / HTTP/1.1\r\n"
1769  "Host: www.emergingthreats.net\r\n\r\n";
1770  uint8_t httpbuf2[] =
1771  "POST / HTTP/1.1\r\n"
1772  "Host: www.openinfosecfoundation.org\r\n\r\n";
1773  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1774  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1775  TcpSession ssn;
1776  Flow f;
1777  ThreadVars th_v;
1778  DetectEngineThreadCtx *det_ctx;
1779 
1781 
1782  ut_script = script;
1783 
1784  memset(&th_v, 0, sizeof(th_v));
1785  StatsThreadInit(&th_v.stats);
1786  memset(&f, 0, sizeof(f));
1787  memset(&ssn, 0, sizeof(ssn));
1788 
1789  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1790  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1791 
1792  FLOW_INITIALIZE(&f);
1793  f.protoctx = (void *)&ssn;
1794  f.proto = IPPROTO_TCP;
1795  f.flags |= FLOW_IPV4;
1796  f.alproto = ALPROTO_HTTP1;
1797 
1798  p1->flow = &f;
1802 
1803  p2->flow = &f;
1807 
1808  StreamTcpInitConfig(true);
1809 
1812  de_ctx->flags |= DE_QUIET;
1813 
1815  FAIL_IF_NULL(s);
1816 
1818  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1819 
1820  int r = AppLayerParserParse(
1821  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1822  FAIL_IF(r != 0);
1823  HtpState *http_state = f.alstate;
1824  FAIL_IF_NULL(http_state);
1825 
1826  /* do detect for p1 */
1827  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1828  FAIL_IF(PacketAlertCheck(p1, 1));
1829 
1830  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1831  FAIL_IF(r != 0);
1832 
1833  /* do detect for p2 */
1834  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1835  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1836 
1837  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1838  FAIL_IF(id == 0);
1839  FlowVar *fv = FlowVarGet(&f, id);
1840  FAIL_IF_NULL(fv);
1841  FAIL_IF(fv->data.fv_int.value != 2);
1842 
1843  UTHFreePackets(&p1, 1);
1844  UTHFreePackets(&p2, 1);
1845  FLOW_DESTROY(&f);
1846 
1848  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1850  StreamTcpFreeConfig(true);
1851  StatsThreadCleanup(&th_v.stats);
1852  PASS;
1853 }
1854 
1855 /** \test http buffer, flowints */
1856 static int LuaMatchTest05a(void)
1857 {
1858  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1859  "function init (args)\n"
1860  " flowintlib.register(\"cnt\")\n"
1861  " return {}\n"
1862  "end\n"
1863  "\n"
1864  "function thread_init (args)\n"
1865  " cnt = flowintlib.get(\"cnt\")\n"
1866  "end\n"
1867  "\n"
1868  "function match(args)\n"
1869  " print \"inspecting\""
1870  " a = cnt:incr()\n"
1871  " if a == 2 then\n"
1872  " print \"match\"\n"
1873  " return 1\n"
1874  " end\n"
1875  " return 0\n"
1876  "end\n"
1877  "return 0\n";
1878  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1879  "sid:1;)";
1880  uint8_t httpbuf1[] =
1881  "POST / HTTP/1.1\r\n"
1882  "Host: www.emergingthreats.net\r\n\r\n";
1883  uint8_t httpbuf2[] =
1884  "POST / HTTP/1.1\r\n"
1885  "Host: www.openinfosecfoundation.org\r\n\r\n";
1886  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1887  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1888  TcpSession ssn;
1889  Flow f;
1890  ThreadVars th_v;
1891  DetectEngineThreadCtx *det_ctx;
1892 
1894 
1895  ut_script = script;
1896 
1897  memset(&th_v, 0, sizeof(th_v));
1898  StatsThreadInit(&th_v.stats);
1899  memset(&f, 0, sizeof(f));
1900  memset(&ssn, 0, sizeof(ssn));
1901 
1902  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1903  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1904 
1905  FLOW_INITIALIZE(&f);
1906  f.protoctx = (void *)&ssn;
1907  f.proto = IPPROTO_TCP;
1908  f.flags |= FLOW_IPV4;
1909  f.alproto = ALPROTO_HTTP1;
1910 
1911  p1->flow = &f;
1915 
1916  p2->flow = &f;
1920 
1921  StreamTcpInitConfig(true);
1922 
1925  de_ctx->flags |= DE_QUIET;
1926 
1928  FAIL_IF_NULL(s);
1929 
1931  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1932 
1933  int r = AppLayerParserParse(
1934  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1935  FAIL_IF(r != 0);
1936  HtpState *http_state = f.alstate;
1937  FAIL_IF_NULL(http_state);
1938 
1939  /* do detect for p1 */
1940  SCLogInfo("p1");
1941  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1942  FAIL_IF(PacketAlertCheck(p1, 1));
1943 
1944  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1945  FAIL_IF(r != 0);
1946  /* do detect for p2 */
1947  SCLogInfo("p2");
1948  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1949 
1950  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1951 
1952  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1953  FAIL_IF(id == 0);
1954  FlowVar *fv = FlowVarGet(&f, id);
1955  FAIL_IF_NULL(fv);
1956  FAIL_IF(fv->data.fv_int.value != 2);
1957 
1958  UTHFreePackets(&p1, 1);
1959  UTHFreePackets(&p2, 1);
1960  FLOW_DESTROY(&f);
1961 
1963  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1965  StreamTcpFreeConfig(true);
1966  StatsThreadCleanup(&th_v.stats);
1967  PASS;
1968 }
1969 
1970 /** \test http buffer, flowints */
1971 static int LuaMatchTest06(void)
1972 {
1973  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1974  "function init (args)\n"
1975  " flowintlib.register(\"cnt\")\n"
1976  " return {}\n"
1977  "end\n"
1978  "\n"
1979  "function thread_init (args)\n"
1980  " cnt = flowintlib.get(\"cnt\")\n"
1981  "end\n"
1982  "\n"
1983  "function match(args)\n"
1984  " print \"inspecting\""
1985  " a = cnt:value()\n"
1986  " if a == nil then\n"
1987  " print \"new var set to 2\""
1988  " cnt:set(2)\n"
1989  " end\n"
1990  " a = cnt:decr()\n"
1991  " if a == 0 then\n"
1992  " print \"match\"\n"
1993  " return 1\n"
1994  " end\n"
1995  " return 0\n"
1996  "end\n"
1997  "return 0\n";
1998  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1999  "sid:1;)";
2000  uint8_t httpbuf1[] =
2001  "POST / HTTP/1.1\r\n"
2002  "Host: www.emergingthreats.net\r\n\r\n";
2003  uint8_t httpbuf2[] =
2004  "POST / HTTP/1.1\r\n"
2005  "Host: www.openinfosecfoundation.org\r\n\r\n";
2006  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2007  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2008  TcpSession ssn;
2009  Flow f;
2010  ThreadVars th_v;
2011  DetectEngineThreadCtx *det_ctx;
2012 
2014 
2015  ut_script = script;
2016 
2017  memset(&th_v, 0, sizeof(th_v));
2018  StatsThreadInit(&th_v.stats);
2019  memset(&f, 0, sizeof(f));
2020  memset(&ssn, 0, sizeof(ssn));
2021 
2022  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2023  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2024 
2025  FLOW_INITIALIZE(&f);
2026  f.protoctx = (void *)&ssn;
2027  f.proto = IPPROTO_TCP;
2028  f.flags |= FLOW_IPV4;
2029  f.alproto = ALPROTO_HTTP1;
2030 
2031  p1->flow = &f;
2035 
2036  p2->flow = &f;
2040 
2041  StreamTcpInitConfig(true);
2042 
2045  de_ctx->flags |= DE_QUIET;
2046 
2048  FAIL_IF_NULL(s);
2049 
2051  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2052 
2053  int r = AppLayerParserParse(
2054  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2055  FAIL_IF(r != 0);
2056  HtpState *http_state = f.alstate;
2057  FAIL_IF_NULL(http_state);
2058 
2059  /* do detect for p1 */
2060  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2061  FAIL_IF(PacketAlertCheck(p1, 1));
2062 
2063  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2064  FAIL_IF(r != 0);
2065 
2066  /* do detect for p2 */
2067  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2068  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2069 
2070  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2071  FAIL_IF(id == 0);
2072  FlowVar *fv = FlowVarGet(&f, id);
2073  FAIL_IF_NULL(fv);
2074  FAIL_IF(fv->data.fv_int.value != 0);
2075 
2076  UTHFreePackets(&p1, 1);
2077  UTHFreePackets(&p2, 1);
2078  FLOW_DESTROY(&f);
2079 
2081  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2083  StreamTcpFreeConfig(true);
2084  StatsThreadCleanup(&th_v.stats);
2085  PASS;
2086 }
2087 
2088 /** \test http buffer, flowints */
2089 static int LuaMatchTest06a(void)
2090 {
2091  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2092  "function init (args)\n"
2093  " flowintlib.register(\"cnt\")\n"
2094  " return {}\n"
2095  "end\n"
2096  "\n"
2097  "function thread_init (args)\n"
2098  " cnt = flowintlib.get(\"cnt\")\n"
2099  "end\n"
2100  "\n"
2101  "function match(args)\n"
2102  " print \"inspecting\""
2103  " a = cnt:value()\n"
2104  " if a == nil then\n"
2105  " print \"new var set to 2\""
2106  " cnt:set(2)\n"
2107  " end\n"
2108  " a = cnt:decr()\n"
2109  " if a == 0 then\n"
2110  " print \"match\"\n"
2111  " return 1\n"
2112  " end\n"
2113  " return 0\n"
2114  "end\n"
2115  "return 0\n";
2116  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2117  "sid:1;)";
2118  uint8_t httpbuf1[] =
2119  "POST / HTTP/1.1\r\n"
2120  "Host: www.emergingthreats.net\r\n\r\n";
2121  uint8_t httpbuf2[] =
2122  "POST / HTTP/1.1\r\n"
2123  "Host: www.openinfosecfoundation.org\r\n\r\n";
2124  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2125  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2126  TcpSession ssn;
2127  Flow f;
2128  ThreadVars th_v;
2129  DetectEngineThreadCtx *det_ctx;
2130 
2132 
2133  ut_script = script;
2134 
2135  memset(&th_v, 0, sizeof(th_v));
2136  StatsThreadInit(&th_v.stats);
2137  memset(&f, 0, sizeof(f));
2138  memset(&ssn, 0, sizeof(ssn));
2139 
2140  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2141  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2142 
2143  FLOW_INITIALIZE(&f);
2144  f.protoctx = (void *)&ssn;
2145  f.proto = IPPROTO_TCP;
2146  f.flags |= FLOW_IPV4;
2147  f.alproto = ALPROTO_HTTP1;
2148 
2149  p1->flow = &f;
2153 
2154  p2->flow = &f;
2158 
2159  StreamTcpInitConfig(true);
2160 
2163  de_ctx->flags |= DE_QUIET;
2164 
2166  FAIL_IF_NULL(s);
2167 
2169  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2170 
2171  int r = AppLayerParserParse(
2172  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2173  FAIL_IF(r != 0);
2174  HtpState *http_state = f.alstate;
2175  FAIL_IF_NULL(http_state);
2176 
2177  /* do detect for p1 */
2178  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2179  FAIL_IF(PacketAlertCheck(p1, 1));
2180 
2181  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2182  FAIL_IF(r != 0);
2183 
2184  /* do detect for p2 */
2185  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2186  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2187 
2188  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2189  FAIL_IF(id == 0);
2190  FlowVar *fv = FlowVarGet(&f, id);
2191  FAIL_IF_NULL(fv);
2192  FAIL_IF(fv->data.fv_int.value != 0);
2193 
2194  UTHFreePackets(&p1, 1);
2195  UTHFreePackets(&p2, 1);
2196  FLOW_DESTROY(&f);
2197 
2199  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2201  StreamTcpFreeConfig(true);
2202  StatsThreadCleanup(&th_v.stats);
2203  PASS;
2204 }
2205 
2206 void DetectLuaRegisterTests(void)
2207 {
2208  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2209  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2210  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2211  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2212  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2213  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2214  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2215  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2216  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2217  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2218  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2219  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2220 }
2221 #endif
FLAG_MEMORY_LIMIT_LOGGED
#define FLAG_MEMORY_LIMIT_LOGGED
Definition: detect-lua.c:121
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:1461
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:1460
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1270
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SCLuaSbUpdateBytesLimit
void SCLuaSbUpdateBytesLimit(lua_State *L)
Definition: util-lua-sandbox.c:396
util-lua-common.h
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1445
SignatureHook_::sm_list
int sm_list
Definition: detect.h:573
FLAG_BLOCKED_FUNCTION_LOGGED
#define FLAG_BLOCKED_FUNCTION_LOGGED
Definition: detect-lua.c:119
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1458
FlowVar_::data
union FlowVar_::@117 data
stream-tcp.h
SCLuaSbResetBytesLimit
uint64_t SCLuaSbResetBytesLimit(lua_State *L)
Definition: util-lua-sandbox.c:385
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3729
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:352
Flow_::proto
uint8_t proto
Definition: flow.h:369
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:142
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:41
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:368
Packet_::flags
uint32_t flags
Definition: decode.h:544
SCLuaSbState
Definition: util-lua-sandbox.h:40
Flow_
Flow data structure.
Definition: flow.h:347
DetectLuaData::allow_restricted_functions
int allow_restricted_functions
Definition: detect-lua.h:58
FLAG_INSTRUCTION_LIMIT_LOGGED
#define FLAG_INSTRUCTION_LIMIT_LOGGED
Definition: detect-lua.c:120
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:933
DEFAULT_LUA_INSTRUCTION_LIMIT
#define DEFAULT_LUA_INSTRUCTION_LIMIT
Definition: detect-lua.c:124
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:64
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2634
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1423
DETECT_LUA_MAX_FLOWVARS
#define DETECT_LUA_MAX_FLOWVARS
Definition: detect-lua.h:35
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:324
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:224
util-var-name.h
TLS_STATE_SERVER_HELLO_DONE
@ TLS_STATE_SERVER_HELLO_DONE
Definition: app-layer-ssl.h:89
SCConfGetBool
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition: conf.c:497
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:365
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2418
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:53
util-lua-builtins.h
VarNameStoreRegister
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
Definition: util-var-name.c:155
DetectEngineThreadCtx_::lua_instruction_limit_errors
StatsCounterId lua_instruction_limit_errors
Definition: detect.h:1381
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3447
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:532
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:272
Flow_::protoctx
void * protoctx
Definition: flow.h:432
SigMatchData_
Data needed for Match()
Definition: detect.h:365
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1440
FLAG_DATATYPE_PACKET
#define FLAG_DATATYPE_PACKET
Definition: detect-lua.c:112
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:99
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:606
util-unittest.h
HtpState_
Definition: app-layer-htp.h:181
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:523
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:271
app-layer-htp.h
FLAG_LIST_JA3S
#define FLAG_LIST_JA3S
Definition: detect-lua.c:116
VarNameStoreLookupByName
uint32_t VarNameStoreLookupByName(const char *name, const enum VarTypes type)
find name for id+type at packet time. As the active store won't be modified, we don't need locks.
Definition: util-var-name.c:326
decode.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:19
SCLuaSbRestoreBytesLimit
void SCLuaSbRestoreBytesLimit(lua_State *L, const uint64_t cfg_limit)
Definition: util-lua-sandbox.c:404
DetectEngineThreadCtx_
Definition: detect.h:1245
DetectEngineThreadCtx_::lua_memory_limit_errors
StatsCounterId lua_memory_limit_errors
Definition: detect.h:1384
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:79
SCConfGetInt
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:414
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:24
DETECT_LUA
@ DETECT_LUA
Definition: detect-engine-register.h:92
SignatureInitData_::list
int list
Definition: detect.h:628
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:388
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:3364
VarNameStoreUnregister
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
Definition: util-var-name.c:204
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:165
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:240
SignatureInitData_::hook
SignatureHook hook
Definition: detect.h:590
SIGNATURE_HOOK_TYPE_NOT_SET
@ SIGNATURE_HOOK_TYPE_NOT_SET
Definition: detect.h:547
DetectEngineThreadCtx_::lua_rule_errors
StatsCounterId lua_rule_errors
Definition: detect.h:1375
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
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:501
detect-engine-build.h
type
uint16_t type
Definition: decode-vlan.c:106
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:208
FLAG_DATATYPE_STREAM
#define FLAG_DATATYPE_STREAM
Definition: detect-lua.c:114
SCLuaSbStateClose
void SCLuaSbStateClose(lua_State *L)
Definition: util-lua-sandbox.c:361
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:118
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:747
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1420
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:85
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:225
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:127
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:2194
SCConfSetFinal
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:318
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1249
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:297
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
util-lua-sandbox.h
SCLuaSbLoadLibs
void SCLuaSbLoadLibs(lua_State *L)
Definition: util-lua-sandbox.c:280
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:40
Packet_::flow
struct Flow_ * flow
Definition: decode.h:546
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:1214
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:867
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:3659
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:1277
detect-lua-extensions.h
suricata-common.h
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
DEFAULT_LUA_ALLOC_LIMIT
#define DEFAULT_LUA_ALLOC_LIMIT
Definition: detect-lua.c:123
SignatureHook_::type
enum SignatureHookType type
Definition: detect.h:572
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3601
detect-engine-buffer.h
SCLuaSbResetInstructionCounter
void SCLuaSbResetInstructionCounter(lua_State *L)
Definition: util-lua-sandbox.c:415
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:1946
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:308
DetectEngineThreadCtx_::tv
ThreadVars * tv
Definition: detect.h:1253
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
FLAG_DATATYPE_BUFFER
#define FLAG_DATATYPE_BUFFER
Definition: detect-lua.c:117
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::alstate
void * alstate
Definition: flow.h:470
Flow_::flags
uint32_t flags
Definition: flow.h:412
detect-parse.h
Signature_
Signature container.
Definition: detect.h:668
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:226
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2595
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:106
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:273
SCLuaSbStateNew
lua_State * SCLuaSbStateNew(uint64_t alloclimit, uint64_t instructionlimit)
Allocate a new Lua sandbox.
Definition: util-lua-sandbox.c:320
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:935
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:3711
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:441
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:1345
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:1378
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1266
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1447
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:319
app-layer.h
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:456
FLAG_LIST_JA3
#define FLAG_LIST_JA3
Definition: detect-lua.c:115