suricata
detect-lua.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2024 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) {
183  StatsIncr(det_ctx->tv, det_ctx->lua_blocked_function_errors);
185  } else if (context->instruction_count_error) {
186  StatsIncr(det_ctx->tv, det_ctx->lua_instruction_limit_errors);
188  } else if (context->memory_limit_error) {
189  StatsIncr(det_ctx->tv, 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  StatsIncr(det_ctx->tv, 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  double script_ret = lua_tonumber(tlua->luastate, 1);
217  SCLogDebug("script_ret %f", script_ret);
218  lua_pop(tlua->luastate, 1);
219 
220  if (script_ret == 1.0)
221  match = 1;
222 
223  /* script returns a table */
224  } else if (lua_type(tlua->luastate, 1) == LUA_TTABLE) {
225  lua_pushnil(tlua->luastate);
226  const char *k, *v;
227  while (lua_next(tlua->luastate, -2)) {
228  v = lua_tostring(tlua->luastate, -1);
229  lua_pop(tlua->luastate, 1);
230  k = lua_tostring(tlua->luastate, -1);
231 
232  if (!k || !v)
233  continue;
234 
235  SCLogDebug("k='%s', v='%s'", k, v);
236 
237  if (strcmp(k, "retval") == 0) {
238  int val;
239  if (StringParseInt32(&val, 10, 0, (const char *)v) < 0) {
240  SCLogError("Invalid value "
241  "for \"retval\" from LUA return table: '%s'",
242  v);
243  match = 0;
244  }
245  else if (val == 1) {
246  match = 1;
247  }
248  } else {
249  /* set flow var? */
250  }
251  }
252 
253  /* pop the table */
254  lua_pop(tlua->luastate, 1);
255  }
256  }
257 
258  if (lua->negated) {
259  if (match == 1)
260  match = 0;
261  else
262  match = 1;
263  }
264 
265  while (lua_gettop(tlua->luastate) > 0) {
266  lua_pop(tlua->luastate, 1);
267  }
268 
269  SCReturnInt(match);
270 }
271 
273  const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset,
274  Flow *f)
275 {
276  SCEnter();
277 
278  if (buffer == NULL || buffer_len == 0)
279  SCReturnInt(0);
280 
281  DetectLuaData *lua = (DetectLuaData *)smd->ctx;
282  if (lua == NULL)
283  SCReturnInt(0);
284 
285  DetectLuaThreadData *tlua =
287  if (tlua == NULL)
288  SCReturnInt(0);
289 
290  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
291 
292  /* prepare data to pass to script */
293  lua_getglobal(tlua->luastate, "match");
294  lua_newtable(tlua->luastate); /* stack at -1 */
295 
296  lua_pushliteral(tlua->luastate, "offset"); /* stack at -2 */
297  lua_pushnumber(tlua->luastate, (int)(offset + 1));
298  lua_settable(tlua->luastate, -3);
299 
300  lua_pushstring(tlua->luastate, lua->buffername); /* stack at -2 */
301  LuaPushStringBuffer(tlua->luastate, (const uint8_t *)buffer, (size_t)buffer_len);
302  lua_settable(tlua->luastate, -3);
303 
304  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
305 }
306 
307 /**
308  * \brief match the specified lua script
309  *
310  * \param t thread local vars
311  * \param det_ctx pattern matcher thread local data
312  * \param p packet
313  * \param s signature being inspected
314  * \param m sigmatch that we will cast into DetectLuaData
315  *
316  * \retval 0 no match
317  * \retval 1 match
318  */
319 static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
320  Packet *p, const Signature *s, const SigMatchCtx *ctx)
321 {
322  SCEnter();
323  DetectLuaData *lua = (DetectLuaData *)ctx;
324  if (lua == NULL)
325  SCReturnInt(0);
326 
328  if (tlua == NULL)
329  SCReturnInt(0);
330 
331  /* setup extension data for use in lua c functions */
332  uint8_t flags = 0;
333  if (p->flowflags & FLOW_PKT_TOSERVER)
334  flags = STREAM_TOSERVER;
335  else if (p->flowflags & FLOW_PKT_TOCLIENT)
336  flags = STREAM_TOCLIENT;
337 
338  LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
339 
340  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
341 
342  if ((tlua->flags & FLAG_DATATYPE_PAYLOAD) && p->payload_len == 0)
343  SCReturnInt(0);
344  if ((tlua->flags & FLAG_DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
345  SCReturnInt(0);
346 
347  lua_getglobal(tlua->luastate, "match");
348  lua_newtable(tlua->luastate); /* stack at -1 */
349 
350  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
351 }
352 
353 static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
354  Flow *f, uint8_t flags, void *state,
355  const Signature *s, const SigMatchCtx *ctx)
356 {
357  SCEnter();
358  DetectLuaData *lua = (DetectLuaData *)ctx;
359  if (lua == NULL)
360  SCReturnInt(0);
361 
363  if (tlua == NULL)
364  SCReturnInt(0);
365 
366  /* setup extension data for use in lua c functions */
367  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
368 
369  lua_getglobal(tlua->luastate, "match");
370  lua_newtable(tlua->luastate); /* stack at -1 */
371 
372  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
373 }
374 
375 /**
376  * \brief match the specified lua script in a list with a tx
377  *
378  * \param t thread local vars
379  * \param det_ctx pattern matcher thread local data
380  * \param s signature being inspected
381  * \param m sigmatch that we will cast into DetectLuaData
382  *
383  * \retval 0 no match
384  * \retval 1 match
385  */
386 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
387  Flow *f, uint8_t flags,
388  void *state, void *txv, const Signature *s,
389  const SigMatchCtx *ctx)
390 {
391  return DetectLuaAppMatchCommon(det_ctx, f, flags, state, s, ctx);
392 }
393 
394 #ifdef UNITTESTS
395 /* if this ptr is set the lua setup functions will use this buffer as the
396  * lua script instead of calling luaL_loadfile on the filename supplied. */
397 static const char *ut_script = NULL;
398 #endif
399 
400 static void *DetectLuaThreadInit(void *data)
401 {
402  int status;
403  DetectLuaData *lua = (DetectLuaData *)data;
404  BUG_ON(lua == NULL);
405 
407  if (unlikely(t == NULL)) {
408  SCLogError("couldn't alloc ctx memory");
409  return NULL;
410  }
411 
412  t->flags = lua->flags;
413 
415  if (t->luastate == NULL) {
416  SCLogError("luastate pool depleted");
417  goto error;
418  }
419 
420  if (lua->allow_restricted_functions) {
421  luaL_openlibs(t->luastate);
423  } else {
425  }
426 
427  LuaStateSetDetectLuaData(t->luastate, lua);
428 
429  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
430 #ifdef UNITTESTS
431  if (ut_script != NULL) {
432  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
433  if (status) {
434  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
435  goto error;
436  }
437  } else {
438 #endif
439  status = luaL_loadfile(t->luastate, lua->filename);
440  if (status) {
441  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
442  goto error;
443  }
444 #ifdef UNITTESTS
445  }
446 #endif
447 
448  /* prime the script (or something) */
449  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
450  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
451  goto error;
452  }
453 
454  /* thread_init call */
455  lua_getglobal(t->luastate, "thread_init");
456  if (lua_isfunction(t->luastate, -1)) {
457  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
458  SCLogError("couldn't run script 'thread_init' function: %s",
459  lua_tostring(t->luastate, -1));
460  goto error;
461  }
462  } else {
463  lua_pop(t->luastate, 1);
464  }
465 
466  return (void *)t;
467 
468 error:
469  if (t->luastate != NULL)
471  SCFree(t);
472  return NULL;
473 }
474 
475 static void DetectLuaThreadFree(void *ctx)
476 {
477  if (ctx != NULL) {
479  if (t->luastate != NULL)
481  SCFree(t);
482  }
483 }
484 
485 /**
486  * \brief Parse the lua keyword
487  *
488  * \param de_ctx Pointer to the detection engine context
489  * \param str Pointer to the user provided option
490  *
491  * \retval lua pointer to DetectLuaData on success
492  * \retval NULL on failure
493  */
494 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
495 {
496  DetectLuaData *lua = NULL;
497 
498  /* We have a correct lua option */
499  lua = SCCalloc(1, sizeof(DetectLuaData));
500  if (unlikely(lua == NULL))
501  goto error;
502 
503  if (strlen(str) && str[0] == '!') {
504  lua->negated = 1;
505  str++;
506  }
507 
508  /* get full filename */
510  if (lua->filename == NULL) {
511  goto error;
512  }
513 
514  return lua;
515 
516 error:
517  if (lua != NULL)
518  DetectLuaFree(de_ctx, lua);
519  return NULL;
520 }
521 
522 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
523 {
524  int status;
525 
527  if (luastate == NULL)
528  return -1;
529  if (ld->allow_restricted_functions) {
530  luaL_openlibs(luastate);
531  SCLuaRequirefBuiltIns(luastate);
532  } else {
533  SCLuaSbLoadLibs(luastate);
534  }
535  LuaStateSetDetectLuaData(luastate, ld);
536 
537  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
538 #ifdef UNITTESTS
539  if (ut_script != NULL) {
540  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
541  if (status) {
542  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
543  goto error;
544  }
545  } else {
546 #endif
547  status = luaL_loadfile(luastate, ld->filename);
548  if (status) {
549  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
550  goto error;
551  }
552 #ifdef UNITTESTS
553  }
554 #endif
555 
556  /* prime the script (or something) */
557  if (lua_pcall(luastate, 0, 0, 0) != 0) {
558  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
559  goto error;
560  }
561 
562  lua_getglobal(luastate, "init");
563  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
564  SCLogError("no init function in script");
565  goto error;
566  }
567 
568  /* Pass the signature as the first argument, setting up bytevars depends on
569  * access to the signature. */
570  lua_pushlightuserdata(luastate, (void *)s);
571 
572  if (lua_pcall(luastate, 1, 1, 0) != 0) {
573  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
574  goto error;
575  }
576 
577  /* process returns from script */
578  if (lua_gettop(luastate) == 0) {
579  SCLogError("init function in script should return table, nothing returned");
580  goto error;
581  }
582  if (lua_type(luastate, 1) != LUA_TTABLE) {
583  SCLogError("init function in script should return table, returned is not table");
584  goto error;
585  }
586 
587  lua_pushnil(luastate);
588  const char *k;
589  while (lua_next(luastate, -2)) {
590  k = lua_tostring(luastate, -2);
591  if (k == NULL)
592  continue;
593 
594  /* handle flowvar and bytes separately as they have a table as value */
595  if (strcmp(k, "flowvar") == 0) {
596  if (lua_istable(luastate, -1)) {
597  lua_pushnil(luastate);
598  while (lua_next(luastate, -2) != 0) {
599  /* value at -1, key is at -2 which we ignore */
600  const char *value = lua_tostring(luastate, -1);
601  SCLogDebug("value %s", value);
602  /* removes 'value'; keeps 'key' for next iteration */
603  lua_pop(luastate, 1);
604 
605  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
606  SCLogError("too many flowvars registered");
607  goto error;
608  }
609 
610  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
611  ld->flowvar[ld->flowvars++] = idx;
612  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
613  }
614  }
615  lua_pop(luastate, 1);
616  continue;
617  } else if (strcmp(k, "flowint") == 0) {
618  if (lua_istable(luastate, -1)) {
619  lua_pushnil(luastate);
620  while (lua_next(luastate, -2) != 0) {
621  /* value at -1, key is at -2 which we ignore */
622  const char *value = lua_tostring(luastate, -1);
623  SCLogDebug("value %s", value);
624  /* removes 'value'; keeps 'key' for next iteration */
625  lua_pop(luastate, 1);
626 
627  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
628  SCLogError("too many flowints registered");
629  goto error;
630  }
631 
632  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
633  ld->flowint[ld->flowints++] = idx;
634  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
635  }
636  }
637  lua_pop(luastate, 1);
638  continue;
639  }
640 
641  bool required = lua_toboolean(luastate, -1);
642  lua_pop(luastate, 1);
643  if (!required) {
644  continue;
645  }
646 
647  if (strcmp(k, "ja3") == 0) {
648  ld->flags |= FLAG_LIST_JA3;
649  } else if (strcmp(k, "ja3s") == 0) {
650  ld->flags |= FLAG_LIST_JA3S;
651  } else if (strcmp(k, "packet") == 0) {
653  } else if (strcmp(k, "payload") == 0) {
655  } else if (strcmp(k, "buffer") == 0) {
657 
658  ld->buffername = SCStrdup("buffer");
659  if (ld->buffername == NULL) {
660  SCLogError("alloc error");
661  goto error;
662  }
663  } else if (strcmp(k, "stream") == 0) {
665 
666  ld->buffername = SCStrdup("stream");
667  if (ld->buffername == NULL) {
668  SCLogError("alloc error");
669  goto error;
670  }
671  /* old options no longer supported */
672  } else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
673  strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
674  strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
675  SCLogError("data type %s no longer supported, use rule hooks", k);
676  goto error;
677 
678  } else {
679  SCLogError("unsupported data type %s", k);
680  goto error;
681  }
682  }
683 
684  /* pop the table */
685  lua_pop(luastate, 1);
686  SCLuaSbStateClose(luastate);
687  return 0;
688 error:
689  SCLuaSbStateClose(luastate);
690  return -1;
691 }
692 
693 /**
694  * \brief this function is used to parse lua options
695  * \brief into the current signature
696  *
697  * \param de_ctx pointer to the Detection Engine Context
698  * \param s pointer to the Current Signature
699  * \param str pointer to the user provided "lua" option
700  *
701  * \retval 0 on Success
702  * \retval -1 on Failure
703  */
704 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
705 {
706  /* First check if Lua rules are enabled, by default Lua in rules
707  * is disabled. */
708  int enabled = 0;
709  if (SCConfGetBool("security.lua.allow-rules", &enabled) == 1 && !enabled) {
710  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
711  return -1;
712  }
713 
714  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
715  if (lua == NULL)
716  return -1;
717 
718  /* Load lua sandbox configurations */
719  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
720  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
721  (void)SCConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
722  (void)SCConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
723  lua->alloc_limit = lua_alloc_limit;
724  lua->instruction_limit = lua_instruction_limit;
725 
726  int allow_restricted_functions = 0;
727  (void)SCConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
728  lua->allow_restricted_functions = allow_restricted_functions;
729 
730  if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
731  goto error;
732  }
733 
735  DetectLuaThreadInit, (void *)lua,
736  DetectLuaThreadFree, 0);
737  if (lua->thread_ctx_id == -1)
738  goto error;
739 
740  int list = DetectBufferGetActiveList(de_ctx, s);
741  SCLogDebug("buffer list %d -> %d", list, s->init_data->list);
742  if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
743  /* what needs to happen here is: we register to the rule hook, so e.g.
744  * http1.request_complete. This means we need a list.
745  *
746  * This includes each pkt, payload, stream, etc. */
747 
749  list = s->init_data->hook.sm_list;
750  SCLogDebug("setting list %d", list);
751  }
752  }
753 
754  if (list == -1) {
755  SCLogError("lua failed to set up");
756  goto error;
757  }
758  if (list == 0) {
759  if (lua->flags & FLAG_LIST_JA3) {
760  list = g_lua_ja3_list_id;
761  } else if (lua->flags & FLAG_LIST_JA3S) {
762  list = g_lua_ja3s_list_id;
763  }
764  }
765 
766  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
767  goto error;
768  }
769 
770  return 0;
771 
772 error:
773  if (lua != NULL)
774  DetectLuaFree(de_ctx, lua);
775  return -1;
776 }
777 
778 /**
779  * \brief this function will free memory associated with DetectLuaData
780  *
781  * \param ptr pointer to DetectLuaData
782  */
783 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
784 {
785  if (ptr != NULL) {
786  DetectLuaData *lua = (DetectLuaData *)ptr;
787 
788  if (lua->buffername)
789  SCFree(lua->buffername);
790  if (lua->filename)
791  SCFree(lua->filename);
792 
793  for (uint16_t i = 0; i < lua->flowints; i++) {
795  }
796  for (uint16_t i = 0; i < lua->flowvars; i++) {
798  }
799  for (uint16_t i = 0; i < lua->bytevars; i++) {
800  SCFree(lua->bytevar[i].name);
801  }
802 
804 
805  SCFree(lua);
806  }
807 }
808 
809 #ifdef UNITTESTS
810 #include "detect-engine-alert.h"
811 
812 /** \test http buffer */
813 static int LuaMatchTest01(void)
814 {
815  SCConfSetFinal("security.lua.allow-rules", "true");
816 
817  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
818  "function init (args)\n"
819  " flowvarlib.register(\"cnt\")\n"
820  " return {}\n"
821  "end\n"
822  "function thread_init (args)\n"
823  " cnt = flowvarlib.get(\"cnt\")\n"
824  "end\n"
825  "\n"
826  "function match(args)\n"
827  " a = cnt:value()\n"
828  " if a then\n"
829  " a = tostring(tonumber(a)+1)\n"
830  " print (a)\n"
831  " cnt:set(a, #a)\n"
832  " else\n"
833  " a = tostring(1)\n"
834  " print (a)\n"
835  " cnt:set(a, #a)\n"
836  " end\n"
837  " \n"
838  " print (\"pre check: \" .. (a))\n"
839  " if tonumber(a) == 2 then\n"
840  " print \"match\"\n"
841  " return 1\n"
842  " end\n"
843  " return 0\n"
844  "end\n"
845  "return 0\n";
846  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
847  "sid:1;)";
848  uint8_t httpbuf1[] =
849  "POST / HTTP/1.1\r\n"
850  "Host: www.emergingthreats.net\r\n\r\n";
851  uint8_t httpbuf2[] =
852  "POST / HTTP/1.1\r\n"
853  "Host: www.openinfosecfoundation.org\r\n\r\n";
854  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
855  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
856  TcpSession ssn;
857  Flow f;
858  ThreadVars th_v;
859  DetectEngineThreadCtx *det_ctx;
860 
862 
863  ut_script = script;
864 
865  memset(&th_v, 0, sizeof(th_v));
866  memset(&f, 0, sizeof(f));
867  memset(&ssn, 0, sizeof(ssn));
868 
869  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
870  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
871 
872  FLOW_INITIALIZE(&f);
873  f.protoctx = (void *)&ssn;
874  f.proto = IPPROTO_TCP;
875  f.flags |= FLOW_IPV4;
877 
878  p1->flow = &f;
882  p2->flow = &f;
886 
887  StreamTcpInitConfig(true);
888 
891  de_ctx->flags |= DE_QUIET;
892 
894  FAIL_IF_NULL(s);
895 
897  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
898 
899  int r = AppLayerParserParse(
900  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
901  FAIL_IF(r != 0);
902  HtpState *http_state = f.alstate;
903  FAIL_IF_NULL(http_state);
904 
905  /* do detect for p1 */
906  SCLogDebug("inspecting p1");
907  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
908 
909  FAIL_IF(PacketAlertCheck(p1, 1));
910 
911  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
912  FAIL_IF(r != 0);
913 
914  /* do detect for p2 */
915  SCLogDebug("inspecting p2");
916  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
917 
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 
926  FAIL_IF(fv->data.fv_str.value_len != 1);
927 
928  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
929 
932 
933  StreamTcpFreeConfig(true);
934  FLOW_DESTROY(&f);
935  UTHFreePackets(&p1, 1);
936  UTHFreePackets(&p2, 1);
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  memset(&f, 0, sizeof(f));
990  memset(&ssn, 0, sizeof(ssn));
991 
992  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
993  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
994 
995  FLOW_INITIALIZE(&f);
996  f.protoctx = (void *)&ssn;
997  f.proto = IPPROTO_TCP;
998  f.flags |= FLOW_IPV4;
1000 
1001  p1->flow = &f;
1005  p2->flow = &f;
1009 
1010  StreamTcpInitConfig(true);
1011 
1014  de_ctx->flags |= DE_QUIET;
1015 
1017  FAIL_IF_NULL(s);
1018 
1020  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1021 
1022  int r = AppLayerParserParse(
1023  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1024  FAIL_IF(r != 0);
1025 
1026  HtpState *http_state = f.alstate;
1027  FAIL_IF_NULL(http_state);
1028 
1029  /* do detect for p1 */
1030  SCLogDebug("inspecting p1");
1031  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1032 
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 
1041  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1042 
1043  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1044  FAIL_IF(id == 0);
1045 
1046  FlowVar *fv = FlowVarGet(&f, id);
1047  FAIL_IF_NULL(fv);
1048 
1049  FAIL_IF(fv->data.fv_str.value_len != 1);
1050 
1051  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1052 
1055 
1056  StreamTcpFreeConfig(true);
1057  FLOW_DESTROY(&f);
1058  UTHFreePackets(&p1, 1);
1059  UTHFreePackets(&p2, 1);
1060  PASS;
1061 }
1062 
1063 /** \test payload buffer */
1064 static int LuaMatchTest02(void)
1065 {
1066  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1067  "function init (args)\n"
1068  " flowvarlib.register(\"cnt\")\n"
1069  " local needs = {}\n"
1070  " needs[\"payload\"] = tostring(true)\n"
1071  " return needs\n"
1072  "end\n"
1073  "function thread_init (args)\n"
1074  " cnt = flowvarlib.get(\"cnt\")\n"
1075  "end\n"
1076  "\n"
1077  "function match(args)\n"
1078  " a = cnt:value()\n"
1079  " if a then\n"
1080  " a = tostring(tonumber(a)+1)\n"
1081  " print (a)\n"
1082  " cnt:set(a, #a)\n"
1083  " else\n"
1084  " a = tostring(1)\n"
1085  " print (a)\n"
1086  " cnt:set(a, #a)\n"
1087  " end\n"
1088  " \n"
1089  " print (\"pre check: \" .. (a))\n"
1090  " if tonumber(a) == 2 then\n"
1091  " print \"match\"\n"
1092  " return 1\n"
1093  " end\n"
1094  " return 0\n"
1095  "end\n"
1096  "return 0\n";
1097  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1098  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1099  "Host: www.emergingthreats.net\r\n\r\n";
1100  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1101  "Host: www.openinfosecfoundation.org\r\n\r\n";
1102  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1103  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1104  TcpSession ssn;
1105  Flow f;
1106  ThreadVars th_v;
1107  DetectEngineThreadCtx *det_ctx;
1108 
1109  ut_script = script;
1110 
1111  memset(&th_v, 0, sizeof(th_v));
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 
1161  FAIL_IF(fv->data.fv_str.value_len != 1);
1162 
1163  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1164 
1166 
1167  StreamTcpFreeConfig(true);
1168  FLOW_DESTROY(&f);
1169  UTHFreePackets(&p1, 1);
1170  UTHFreePackets(&p2, 1);
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  memset(&f, 0, sizeof(f));
1224  memset(&ssn, 0, sizeof(ssn));
1225 
1226  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1227  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1228 
1229  FLOW_INITIALIZE(&f);
1230  f.protoctx = (void *)&ssn;
1231  f.proto = IPPROTO_TCP;
1232  f.flags |= FLOW_IPV4;
1233  f.alproto = ALPROTO_HTTP1;
1234 
1235  p1->flow = &f;
1239  p2->flow = &f;
1243 
1244  StreamTcpInitConfig(true);
1245 
1248  de_ctx->flags |= DE_QUIET;
1249 
1251  FAIL_IF_NULL(s);
1252 
1254  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1255 
1256  /* do detect for p1 */
1257  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1258  FAIL_IF(PacketAlertCheck(p1, 1));
1259 
1260  /* do detect for p2 */
1261  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1262 
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 
1271  FAIL_IF(fv->data.fv_str.value_len != 1);
1272 
1273  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1274 
1276 
1277  StreamTcpFreeConfig(true);
1278  FLOW_DESTROY(&f);
1279  UTHFreePackets(&p1, 1);
1280  UTHFreePackets(&p2, 1);
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  memset(&f, 0, sizeof(f));
1335  memset(&ssn, 0, sizeof(ssn));
1336 
1337  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1338  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1339 
1340  FLOW_INITIALIZE(&f);
1341  f.protoctx = (void *)&ssn;
1342  f.proto = IPPROTO_TCP;
1343  f.flags |= FLOW_IPV4;
1344  f.alproto = ALPROTO_HTTP1;
1345 
1346  p1->flow = &f;
1350  p2->flow = &f;
1354 
1355  StreamTcpInitConfig(true);
1356 
1359  de_ctx->flags |= DE_QUIET;
1360 
1362  FAIL_IF_NULL(s);
1363 
1365  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1366 
1367  /* do detect for p1 */
1368  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1369  FAIL_IF(PacketAlertCheck(p1, 1));
1370 
1371  /* do detect for p2 */
1372  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1373 
1374  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1375 
1376  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1377  FAIL_IF(id == 0);
1378 
1379  FlowVar *fv = FlowVarGet(&f, id);
1380  FAIL_IF_NULL(fv);
1381 
1382  FAIL_IF(fv->data.fv_str.value_len != 1);
1383 
1384  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1385 
1387 
1388  StreamTcpFreeConfig(true);
1389  FLOW_DESTROY(&f);
1390  UTHFreePackets(&p1, 1);
1391  UTHFreePackets(&p2, 1);
1392  PASS;
1393 }
1394 
1395 /** \test packet buffer */
1396 static int LuaMatchTest03a(void)
1397 {
1398  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1399  "function init (args)\n"
1400  " flowvarlib.register(\"cnt\")\n"
1401  " local needs = {}\n"
1402  " needs[\"packet\"] = tostring(true)\n"
1403  " return needs\n"
1404  "end\n"
1405  "\n"
1406  "function thread_init (args)\n"
1407  " cnt = flowvarlib.get(\"cnt\")\n"
1408  "end\n"
1409  "\n"
1410  "function match(args)\n"
1411  " a = cnt:value()\n"
1412  " if a then\n"
1413  " a = tostring(tonumber(a)+1)\n"
1414  " print (a)\n"
1415  " cnt:set(a, #a)\n"
1416  " else\n"
1417  " a = tostring(1)\n"
1418  " print (a)\n"
1419  " cnt:set(a, #a)\n"
1420  " end\n"
1421  " \n"
1422  " print (\"pre check: \" .. (a))\n"
1423  " if tonumber(a) == 2 then\n"
1424  " print \"match\"\n"
1425  " return 1\n"
1426  " end\n"
1427  " return 0\n"
1428  "end\n"
1429  "return 0\n";
1430  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1431  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1432  "Host: www.emergingthreats.net\r\n\r\n";
1433  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1434  "Host: www.openinfosecfoundation.org\r\n\r\n";
1435  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1436  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1437  TcpSession ssn;
1438  Flow f;
1439  ThreadVars th_v;
1440  DetectEngineThreadCtx *det_ctx;
1441 
1442  ut_script = script;
1443 
1444  memset(&th_v, 0, sizeof(th_v));
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 
1489  FlowVar *fv = FlowVarGet(&f, id);
1490  FAIL_IF_NULL(fv);
1491 
1492  FAIL_IF(fv->data.fv_str.value_len != 1);
1493 
1494  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1495 
1497 
1498  StreamTcpFreeConfig(true);
1499  FLOW_DESTROY(&f);
1500  UTHFreePackets(&p1, 1);
1501  UTHFreePackets(&p2, 1);
1502  PASS;
1503 }
1504 
1505 /** \test http buffer, flowints */
1506 static int LuaMatchTest04(void)
1507 {
1508  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1509  "function init (args)\n"
1510  " flowintlib.register(\"cnt\")\n"
1511  " return {}\n"
1512  "end\n"
1513  "\n"
1514  "function thread_init (args)\n"
1515  " cnt = flowintlib.get(\"cnt\")\n"
1516  "end\n"
1517  "\n"
1518  "function match(args)\n"
1519  " print \"inspecting\""
1520  " a = cnt:value()\n"
1521  " if a then\n"
1522  " cnt:set(a + 1)\n"
1523  " else\n"
1524  " cnt:set(1)\n"
1525  " end\n"
1526  " \n"
1527  " a = cnt:value()\n"
1528  " if a == 2 then\n"
1529  " print \"match\"\n"
1530  " return 1\n"
1531  " end\n"
1532  " return 0\n"
1533  "end\n"
1534  "return 0\n";
1535  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1536  "sid:1;)";
1537  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1538  "Host: www.emergingthreats.net\r\n\r\n";
1539  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1540  "Host: www.openinfosecfoundation.org\r\n\r\n";
1541  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1542  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1543  TcpSession ssn;
1544  Flow f;
1545  ThreadVars th_v;
1546  DetectEngineThreadCtx *det_ctx;
1547 
1549 
1550  ut_script = script;
1551 
1552  memset(&th_v, 0, sizeof(th_v));
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  SCLogInfo("p1");
1595  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1596 
1597  FAIL_IF(PacketAlertCheck(p1, 1));
1598 
1599  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1600  FAIL_IF(r != 0);
1601  /* do detect for p2 */
1602  SCLogInfo("p2");
1603  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1604 
1605  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1606 
1607  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1608  FAIL_IF(id == 0);
1609 
1610  FlowVar *fv = FlowVarGet(&f, id);
1611  FAIL_IF_NULL(fv);
1612 
1613  FAIL_IF(fv->data.fv_int.value != 2);
1614 
1617 
1618  StreamTcpFreeConfig(true);
1619  FLOW_DESTROY(&f);
1620  UTHFreePackets(&p1, 1);
1621  UTHFreePackets(&p2, 1);
1622  PASS;
1623 }
1624 
1625 /** \test http buffer, flowints */
1626 static int LuaMatchTest04a(void)
1627 {
1628  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1629  "function init (args)\n"
1630  " flowintlib.register(\"cnt\")\n"
1631  " return {}\n"
1632  "end\n"
1633  "\n"
1634  "function thread_init (args)\n"
1635  " cnt = flowintlib.get(\"cnt\")\n"
1636  "end\n"
1637  "\n"
1638  "function match(args)\n"
1639  " print \"inspecting\""
1640  " a = cnt:value()\n"
1641  " if a then\n"
1642  " cnt:set(a + 1)\n"
1643  " else\n"
1644  " cnt:set(1)\n"
1645  " end\n"
1646  " \n"
1647  " a = cnt:value()\n"
1648  " if a == 2 then\n"
1649  " print \"match\"\n"
1650  " return 1\n"
1651  " end\n"
1652  " return 0\n"
1653  "end\n"
1654  "return 0\n";
1655  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1656  "sid:1;)";
1657  uint8_t httpbuf1[] =
1658  "POST / HTTP/1.1\r\n"
1659  "Host: www.emergingthreats.net\r\n\r\n";
1660  uint8_t httpbuf2[] =
1661  "POST / HTTP/1.1\r\n"
1662  "Host: www.openinfosecfoundation.org\r\n\r\n";
1663  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1664  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1665  TcpSession ssn;
1666  Flow f;
1667  ThreadVars th_v;
1668  DetectEngineThreadCtx *det_ctx;
1669 
1671 
1672  ut_script = script;
1673 
1674  memset(&th_v, 0, sizeof(th_v));
1675  memset(&f, 0, sizeof(f));
1676  memset(&ssn, 0, sizeof(ssn));
1677 
1678  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1679  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1680 
1681  FLOW_INITIALIZE(&f);
1682  f.protoctx = (void *)&ssn;
1683  f.proto = IPPROTO_TCP;
1684  f.flags |= FLOW_IPV4;
1685  f.alproto = ALPROTO_HTTP1;
1686 
1687  p1->flow = &f;
1691 
1692  p2->flow = &f;
1696 
1697  StreamTcpInitConfig(true);
1698 
1701  de_ctx->flags |= DE_QUIET;
1702 
1704  FAIL_IF_NULL(s);
1705 
1707  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1708 
1709  int r = AppLayerParserParse(
1710  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1711  FAIL_IF(r != 0);
1712  HtpState *http_state = f.alstate;
1713  FAIL_IF_NULL(http_state);
1714 
1715  /* do detect for p1 */
1716  SCLogInfo("p1");
1717  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1718 
1719  FAIL_IF(PacketAlertCheck(p1, 1));
1720 
1721  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1722  FAIL_IF(r != 0);
1723  /* do detect for p2 */
1724  SCLogInfo("p2");
1725  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1726 
1727  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1728 
1729  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1730  FAIL_IF(id == 0);
1731 
1732  FlowVar *fv = FlowVarGet(&f, id);
1733  FAIL_IF_NULL(fv);
1734 
1735  FAIL_IF(fv->data.fv_int.value != 2);
1736 
1739 
1740  StreamTcpFreeConfig(true);
1741  FLOW_DESTROY(&f);
1742  UTHFreePackets(&p1, 1);
1743  UTHFreePackets(&p2, 1);
1744  PASS;
1745 }
1746 
1747 /** \test http buffer, flowints */
1748 static int LuaMatchTest05(void)
1749 {
1750  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1751  "function init (args)\n"
1752  " flowintlib.register(\"cnt\")\n"
1753  " return {}\n"
1754  "end\n"
1755  "\n"
1756  "function thread_init (args)\n"
1757  " cnt = flowintlib.get(\"cnt\")\n"
1758  "end\n"
1759  "\n"
1760  "function match(args)\n"
1761  " print \"inspecting\""
1762  " a = cnt:incr()\n"
1763  " if a == 2 then\n"
1764  " print \"match\"\n"
1765  " return 1\n"
1766  " end\n"
1767  " return 0\n"
1768  "end\n"
1769  "return 0\n";
1770  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1771  "sid:1;)";
1772  uint8_t httpbuf1[] =
1773  "POST / HTTP/1.1\r\n"
1774  "Host: www.emergingthreats.net\r\n\r\n";
1775  uint8_t httpbuf2[] =
1776  "POST / HTTP/1.1\r\n"
1777  "Host: www.openinfosecfoundation.org\r\n\r\n";
1778  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1779  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1780  TcpSession ssn;
1781  Flow f;
1782  ThreadVars th_v;
1783  DetectEngineThreadCtx *det_ctx;
1784 
1786 
1787  ut_script = script;
1788 
1789  memset(&th_v, 0, sizeof(th_v));
1790  memset(&f, 0, sizeof(f));
1791  memset(&ssn, 0, sizeof(ssn));
1792 
1793  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1794  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1795 
1796  FLOW_INITIALIZE(&f);
1797  f.protoctx = (void *)&ssn;
1798  f.proto = IPPROTO_TCP;
1799  f.flags |= FLOW_IPV4;
1800  f.alproto = ALPROTO_HTTP1;
1801 
1802  p1->flow = &f;
1806 
1807  p2->flow = &f;
1811 
1812  StreamTcpInitConfig(true);
1813 
1816  de_ctx->flags |= DE_QUIET;
1817 
1819  FAIL_IF_NULL(s);
1820 
1822  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1823 
1824  int r = AppLayerParserParse(
1825  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1826  FAIL_IF(r != 0);
1827  HtpState *http_state = f.alstate;
1828  FAIL_IF_NULL(http_state);
1829 
1830  /* do detect for p1 */
1831  SCLogInfo("p1");
1832  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1833 
1834  FAIL_IF(PacketAlertCheck(p1, 1));
1835 
1836  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1837  FAIL_IF(r != 0);
1838  /* do detect for p2 */
1839  SCLogInfo("p2");
1840  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1841 
1842  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1843 
1844  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1845  FAIL_IF(id == 0);
1846 
1847  FlowVar *fv = FlowVarGet(&f, id);
1848  FAIL_IF_NULL(fv);
1849 
1850  FAIL_IF(fv->data.fv_int.value != 2);
1851 
1854 
1855  StreamTcpFreeConfig(true);
1856  FLOW_DESTROY(&f);
1857  UTHFreePackets(&p1, 1);
1858  UTHFreePackets(&p2, 1);
1859  PASS;
1860 }
1861 
1862 /** \test http buffer, flowints */
1863 static int LuaMatchTest05a(void)
1864 {
1865  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1866  "function init (args)\n"
1867  " flowintlib.register(\"cnt\")\n"
1868  " return {}\n"
1869  "end\n"
1870  "\n"
1871  "function thread_init (args)\n"
1872  " cnt = flowintlib.get(\"cnt\")\n"
1873  "end\n"
1874  "\n"
1875  "function match(args)\n"
1876  " print \"inspecting\""
1877  " a = cnt:incr()\n"
1878  " if a == 2 then\n"
1879  " print \"match\"\n"
1880  " return 1\n"
1881  " end\n"
1882  " return 0\n"
1883  "end\n"
1884  "return 0\n";
1885  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1886  "sid:1;)";
1887  uint8_t httpbuf1[] =
1888  "POST / HTTP/1.1\r\n"
1889  "Host: www.emergingthreats.net\r\n\r\n";
1890  uint8_t httpbuf2[] =
1891  "POST / HTTP/1.1\r\n"
1892  "Host: www.openinfosecfoundation.org\r\n\r\n";
1893  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1894  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1895  TcpSession ssn;
1896  Flow f;
1897  ThreadVars th_v;
1898  DetectEngineThreadCtx *det_ctx;
1899 
1901 
1902  ut_script = script;
1903 
1904  memset(&th_v, 0, sizeof(th_v));
1905  memset(&f, 0, sizeof(f));
1906  memset(&ssn, 0, sizeof(ssn));
1907 
1908  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1909  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1910 
1911  FLOW_INITIALIZE(&f);
1912  f.protoctx = (void *)&ssn;
1913  f.proto = IPPROTO_TCP;
1914  f.flags |= FLOW_IPV4;
1915  f.alproto = ALPROTO_HTTP1;
1916 
1917  p1->flow = &f;
1921 
1922  p2->flow = &f;
1926 
1927  StreamTcpInitConfig(true);
1928 
1931  de_ctx->flags |= DE_QUIET;
1932 
1934  FAIL_IF_NULL(s);
1935 
1937  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1938 
1939  int r = AppLayerParserParse(
1940  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1941  FAIL_IF(r != 0);
1942  HtpState *http_state = f.alstate;
1943  FAIL_IF_NULL(http_state);
1944 
1945  /* do detect for p1 */
1946  SCLogInfo("p1");
1947  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1948 
1949  FAIL_IF(PacketAlertCheck(p1, 1));
1950 
1951  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1952  FAIL_IF(r != 0);
1953  /* do detect for p2 */
1954  SCLogInfo("p2");
1955  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1956 
1957  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1958 
1959  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1960  FAIL_IF(id == 0);
1961 
1962  FlowVar *fv = FlowVarGet(&f, id);
1963  FAIL_IF_NULL(fv);
1964 
1965  FAIL_IF(fv->data.fv_int.value != 2);
1966 
1969 
1970  StreamTcpFreeConfig(true);
1971  FLOW_DESTROY(&f);
1972  UTHFreePackets(&p1, 1);
1973  UTHFreePackets(&p2, 1);
1974  PASS;
1975 }
1976 
1977 /** \test http buffer, flowints */
1978 static int LuaMatchTest06(void)
1979 {
1980  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1981  "function init (args)\n"
1982  " flowintlib.register(\"cnt\")\n"
1983  " return {}\n"
1984  "end\n"
1985  "\n"
1986  "function thread_init (args)\n"
1987  " cnt = flowintlib.get(\"cnt\")\n"
1988  "end\n"
1989  "\n"
1990  "function match(args)\n"
1991  " print \"inspecting\""
1992  " a = cnt:value()\n"
1993  " if a == nil then\n"
1994  " print \"new var set to 2\""
1995  " cnt:set(2)\n"
1996  " end\n"
1997  " a = cnt:decr()\n"
1998  " if a == 0 then\n"
1999  " print \"match\"\n"
2000  " return 1\n"
2001  " end\n"
2002  " return 0\n"
2003  "end\n"
2004  "return 0\n";
2005  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2006  "sid:1;)";
2007  uint8_t httpbuf1[] =
2008  "POST / HTTP/1.1\r\n"
2009  "Host: www.emergingthreats.net\r\n\r\n";
2010  uint8_t httpbuf2[] =
2011  "POST / HTTP/1.1\r\n"
2012  "Host: www.openinfosecfoundation.org\r\n\r\n";
2013  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2014  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2015  TcpSession ssn;
2016  Flow f;
2017  ThreadVars th_v;
2018  DetectEngineThreadCtx *det_ctx;
2019 
2021 
2022  ut_script = script;
2023 
2024  memset(&th_v, 0, sizeof(th_v));
2025  memset(&f, 0, sizeof(f));
2026  memset(&ssn, 0, sizeof(ssn));
2027 
2028  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2029  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2030 
2031  FLOW_INITIALIZE(&f);
2032  f.protoctx = (void *)&ssn;
2033  f.proto = IPPROTO_TCP;
2034  f.flags |= FLOW_IPV4;
2035  f.alproto = ALPROTO_HTTP1;
2036 
2037  p1->flow = &f;
2041 
2042  p2->flow = &f;
2046 
2047  StreamTcpInitConfig(true);
2048 
2051  de_ctx->flags |= DE_QUIET;
2052 
2054  FAIL_IF_NULL(s);
2055 
2057  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2058 
2059  int r = AppLayerParserParse(
2060  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2061  FAIL_IF(r != 0);
2062  HtpState *http_state = f.alstate;
2063  FAIL_IF_NULL(http_state);
2064 
2065  /* do detect for p1 */
2066  SCLogInfo("p1");
2067  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2068 
2069  FAIL_IF(PacketAlertCheck(p1, 1));
2070 
2071  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2072  FAIL_IF(r != 0);
2073  /* do detect for p2 */
2074  SCLogInfo("p2");
2075  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2076 
2077  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2078 
2079  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2080  FAIL_IF(id == 0);
2081 
2082  FlowVar *fv = FlowVarGet(&f, id);
2083  FAIL_IF_NULL(fv);
2084 
2085  FAIL_IF(fv->data.fv_int.value != 0);
2086 
2089 
2090  StreamTcpFreeConfig(true);
2091  FLOW_DESTROY(&f);
2092  UTHFreePackets(&p1, 1);
2093  UTHFreePackets(&p2, 1);
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));
2145  memset(&f, 0, sizeof(f));
2146  memset(&ssn, 0, sizeof(ssn));
2147 
2148  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2149  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2150 
2151  FLOW_INITIALIZE(&f);
2152  f.protoctx = (void *)&ssn;
2153  f.proto = IPPROTO_TCP;
2154  f.flags |= FLOW_IPV4;
2155  f.alproto = ALPROTO_HTTP1;
2156 
2157  p1->flow = &f;
2161 
2162  p2->flow = &f;
2166 
2167  StreamTcpInitConfig(true);
2168 
2171  de_ctx->flags |= DE_QUIET;
2172 
2174  FAIL_IF_NULL(s);
2175 
2177  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2178 
2179  int r = AppLayerParserParse(
2180  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2181  FAIL_IF(r != 0);
2182  HtpState *http_state = f.alstate;
2183  FAIL_IF_NULL(http_state);
2184 
2185  /* do detect for p1 */
2186  SCLogInfo("p1");
2187  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2188 
2189  FAIL_IF(PacketAlertCheck(p1, 1));
2190 
2191  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2192  FAIL_IF(r != 0);
2193  /* do detect for p2 */
2194  SCLogInfo("p2");
2195  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2196 
2197  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2198 
2199  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2200  FAIL_IF(id == 0);
2201 
2202  FlowVar *fv = FlowVarGet(&f, id);
2203  FAIL_IF_NULL(fv);
2204 
2205  FAIL_IF(fv->data.fv_int.value != 0);
2206 
2209 
2210  StreamTcpFreeConfig(true);
2211  FLOW_DESTROY(&f);
2212  UTHFreePackets(&p1, 1);
2213  UTHFreePackets(&p2, 1);
2214  PASS;
2215 }
2216 
2217 void DetectLuaRegisterTests(void)
2218 {
2219  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2220  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2221  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2222  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2223  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2224  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2225  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2226  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2227  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2228  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2229  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2230  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2231 }
2232 #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:1462
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
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
SigTableElmt_::desc
const char * desc
Definition: detect.h:1461
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1264
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
util-lua-common.h
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1446
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:1459
stream-tcp.h
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3733
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:275
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:378
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:356
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:932
DetectEngineThreadCtx_::lua_blocked_function_errors
uint16_t lua_blocked_function_errors
Definition: detect.h:1379
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:2643
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1424
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:233
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:2420
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:53
util-lua-builtins.h
StringParseInt32
int StringParseInt32(int32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:622
VarNameStoreRegister
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
Definition: util-var-name.c:155
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3437
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:532
DetectEngineThreadCtx_::lua_instruction_limit_errors
uint16_t lua_instruction_limit_errors
Definition: detect.h:1382
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:272
Flow_::protoctx
void * protoctx
Definition: flow.h:441
SigMatchData_
Data needed for Match()
Definition: detect.h:365
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1441
FLAG_DATATYPE_PACKET
#define FLAG_DATATYPE_PACKET
Definition: detect-lua.c:112
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:100
Packet_::payload_len
uint16_t payload_len
Definition: decode.h: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
DetectEngineThreadCtx_::lua_rule_errors
uint16_t lua_rule_errors
Definition: detect.h:1376
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:488
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.
Definition: util-var-name.c:315
decode.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1244
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:23
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:277
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:3369
VarNameStoreUnregister
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
Definition: util-var-name.c:201
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:255
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:272
SignatureInitData_::hook
SignatureHook hook
Definition: detect.h:590
SIGNATURE_HOOK_TYPE_NOT_SET
@ SIGNATURE_HOOK_TYPE_NOT_SET
Definition: detect.h:547
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
DetectEngineThreadCtx_::lua_memory_limit_errors
uint16_t lua_memory_limit_errors
Definition: detect.h:1385
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:1421
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
FlowVar_::data
union FlowVar_::@124 data
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:234
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:225
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:2204
SCConfSetFinal
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:318
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:1215
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:859
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:3663
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:1291
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
detect-engine-buffer.h
SCLuaSbResetInstructionCounter
void SCLuaSbResetInstructionCounter(lua_State *L)
Definition: util-lua-sandbox.c:388
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:1956
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:1252
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:267
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:479
Flow_::flags
uint32_t flags
Definition: flow.h:421
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:235
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2604
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:272
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:934
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:3715
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:281
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine-buffer.c:109
flow-var.h
DetectLuaData::filename
char * filename
Definition: detect-lua.h:47
FlowVar_
Definition: flow-var.h:55
app-layer-ssl.h
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1260
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1448
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