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