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 
428  LuaStateSetDetectLuaData(t->luastate, lua);
429 
430  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
431 #ifdef UNITTESTS
432  if (ut_script != NULL) {
433  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
434  if (status) {
435  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
436  goto error;
437  }
438  } else {
439 #endif
440  status = luaL_loadfile(t->luastate, lua->filename);
441  if (status) {
442  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
443  goto error;
444  }
445 #ifdef UNITTESTS
446  }
447 #endif
448 
449  /* prime the script (or something) */
450  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
451  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
452  goto error;
453  }
454 
455  /* thread_init call */
456  lua_getglobal(t->luastate, "thread_init");
457  if (lua_isfunction(t->luastate, -1)) {
458  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
459  SCLogError("couldn't run script 'thread_init' function: %s",
460  lua_tostring(t->luastate, -1));
461  goto error;
462  }
463  } else {
464  lua_pop(t->luastate, 1);
465  }
466 
467  return (void *)t;
468 
469 error:
470  if (t->luastate != NULL)
472  SCFree(t);
473  return NULL;
474 }
475 
476 static void DetectLuaThreadFree(void *ctx)
477 {
478  if (ctx != NULL) {
480  if (t->luastate != NULL)
482  SCFree(t);
483  }
484 }
485 
486 /**
487  * \brief Parse the lua keyword
488  *
489  * \param de_ctx Pointer to the detection engine context
490  * \param str Pointer to the user provided option
491  *
492  * \retval lua pointer to DetectLuaData on success
493  * \retval NULL on failure
494  */
495 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
496 {
497  DetectLuaData *lua = NULL;
498 
499  /* We have a correct lua option */
500  lua = SCCalloc(1, sizeof(DetectLuaData));
501  if (unlikely(lua == NULL))
502  goto error;
503 
504  if (strlen(str) && str[0] == '!') {
505  lua->negated = 1;
506  str++;
507  }
508 
509  /* get full filename */
511  if (lua->filename == NULL) {
512  goto error;
513  }
514 
515  return lua;
516 
517 error:
518  if (lua != NULL)
519  DetectLuaFree(de_ctx, lua);
520  return NULL;
521 }
522 
523 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
524 {
525  int status;
526 
528  if (luastate == NULL)
529  return -1;
530  if (ld->allow_restricted_functions) {
531  luaL_openlibs(luastate);
532  SCLuaRequirefBuiltIns(luastate);
533  } else {
534  SCLuaSbLoadLibs(luastate);
535  }
536  LuaStateSetDetectLuaData(luastate, ld);
537 
538  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
539 #ifdef UNITTESTS
540  if (ut_script != NULL) {
541  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
542  if (status) {
543  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
544  goto error;
545  }
546  } else {
547 #endif
548  status = luaL_loadfile(luastate, ld->filename);
549  if (status) {
550  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
551  goto error;
552  }
553 #ifdef UNITTESTS
554  }
555 #endif
556 
557  /* prime the script (or something) */
558  if (lua_pcall(luastate, 0, 0, 0) != 0) {
559  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
560  goto error;
561  }
562 
563  lua_getglobal(luastate, "init");
564  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
565  SCLogError("no init function in script");
566  goto error;
567  }
568 
569  if (lua_pcall(luastate, 0, 1, 0) != 0) {
570  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
571  goto error;
572  }
573 
574  /* process returns from script */
575  if (lua_gettop(luastate) == 0) {
576  SCLogError("init function in script should return table, nothing returned");
577  goto error;
578  }
579  if (lua_type(luastate, 1) != LUA_TTABLE) {
580  SCLogError("init function in script should return table, returned is not table");
581  goto error;
582  }
583 
584  lua_pushnil(luastate);
585  const char *k;
586  while (lua_next(luastate, -2)) {
587  k = lua_tostring(luastate, -2);
588  if (k == NULL)
589  continue;
590 
591  /* handle flowvar and bytes separately as they have a table as value */
592  if (strcmp(k, "flowvar") == 0) {
593  if (lua_istable(luastate, -1)) {
594  lua_pushnil(luastate);
595  while (lua_next(luastate, -2) != 0) {
596  /* value at -1, key is at -2 which we ignore */
597  const char *value = lua_tostring(luastate, -1);
598  SCLogDebug("value %s", value);
599  /* removes 'value'; keeps 'key' for next iteration */
600  lua_pop(luastate, 1);
601 
602  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
603  SCLogError("too many flowvars registered");
604  goto error;
605  }
606 
607  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
608  ld->flowvar[ld->flowvars++] = idx;
609  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
610  }
611  }
612  lua_pop(luastate, 1);
613  continue;
614  } else if (strcmp(k, "flowint") == 0) {
615  if (lua_istable(luastate, -1)) {
616  lua_pushnil(luastate);
617  while (lua_next(luastate, -2) != 0) {
618  /* value at -1, key is at -2 which we ignore */
619  const char *value = lua_tostring(luastate, -1);
620  SCLogDebug("value %s", value);
621  /* removes 'value'; keeps 'key' for next iteration */
622  lua_pop(luastate, 1);
623 
624  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
625  SCLogError("too many flowints registered");
626  goto error;
627  }
628 
629  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
630  ld->flowint[ld->flowints++] = idx;
631  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
632  }
633  }
634  lua_pop(luastate, 1);
635  continue;
636  } else if (strcmp(k, "bytevar") == 0) {
637  if (lua_istable(luastate, -1)) {
638  lua_pushnil(luastate);
639  while (lua_next(luastate, -2) != 0) {
640  /* value at -1, key is at -2 which we ignore */
641  const char *value = lua_tostring(luastate, -1);
642  SCLogDebug("value %s", value);
643  /* removes 'value'; keeps 'key' for next iteration */
644  lua_pop(luastate, 1);
645 
646  if (ld->bytevars == DETECT_LUA_MAX_BYTEVARS) {
647  SCLogError("too many bytevars registered");
648  goto error;
649  }
650 
652  if (!DetectByteRetrieveSMVar(value, s, &idx)) {
653  SCLogError("Unknown byte_extract or byte_math var "
654  "requested by lua script - %s",
655  value);
656  goto error;
657  }
658  ld->bytevar[ld->bytevars++] = idx;
659  SCLogDebug("script uses bytevar %u with script id %u", idx, ld->bytevars - 1);
660  }
661  }
662  lua_pop(luastate, 1);
663  continue;
664  }
665 
666  bool required = lua_toboolean(luastate, -1);
667  lua_pop(luastate, 1);
668  if (!required) {
669  continue;
670  }
671 
672  if (strcmp(k, "ja3") == 0) {
673  ld->flags |= FLAG_LIST_JA3;
674  } else if (strcmp(k, "ja3s") == 0) {
675  ld->flags |= FLAG_LIST_JA3S;
676  } else if (strcmp(k, "packet") == 0) {
678  } else if (strcmp(k, "payload") == 0) {
680  } else if (strcmp(k, "buffer") == 0) {
682 
683  ld->buffername = SCStrdup("buffer");
684  if (ld->buffername == NULL) {
685  SCLogError("alloc error");
686  goto error;
687  }
688  } else if (strcmp(k, "stream") == 0) {
690 
691  ld->buffername = SCStrdup("stream");
692  if (ld->buffername == NULL) {
693  SCLogError("alloc error");
694  goto error;
695  }
696  /* old options no longer supported */
697  } else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
698  strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
699  strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
700  SCLogError("data type %s no longer supported, use rule hooks", k);
701  goto error;
702 
703  } else {
704  SCLogError("unsupported data type %s", k);
705  goto error;
706  }
707  }
708 
709  /* pop the table */
710  lua_pop(luastate, 1);
711  SCLuaSbStateClose(luastate);
712  return 0;
713 error:
714  SCLuaSbStateClose(luastate);
715  return -1;
716 }
717 
718 /**
719  * \brief this function is used to parse lua options
720  * \brief into the current signature
721  *
722  * \param de_ctx pointer to the Detection Engine Context
723  * \param s pointer to the Current Signature
724  * \param str pointer to the user provided "lua" option
725  *
726  * \retval 0 on Success
727  * \retval -1 on Failure
728  */
729 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
730 {
731  /* First check if Lua rules are enabled, by default Lua in rules
732  * is disabled. */
733  int enabled = 0;
734  if (SCConfGetBool("security.lua.allow-rules", &enabled) == 1 && !enabled) {
735  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
736  return -1;
737  }
738 
739  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
740  if (lua == NULL)
741  return -1;
742 
743  /* Load lua sandbox configurations */
744  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
745  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
746  (void)SCConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
747  (void)SCConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
748  lua->alloc_limit = lua_alloc_limit;
749  lua->instruction_limit = lua_instruction_limit;
750 
751  int allow_restricted_functions = 0;
752  (void)SCConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
753  lua->allow_restricted_functions = allow_restricted_functions;
754 
755  if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
756  goto error;
757  }
758 
760  DetectLuaThreadInit, (void *)lua,
761  DetectLuaThreadFree, 0);
762  if (lua->thread_ctx_id == -1)
763  goto error;
764 
765  int list = DetectBufferGetActiveList(de_ctx, s);
766  SCLogDebug("buffer list %d -> %d", list, s->init_data->list);
767  if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
768  /* what needs to happen here is: we register to the rule hook, so e.g.
769  * http1.request_complete. This means we need a list.
770  *
771  * This includes each pkt, payload, stream, etc. */
772 
774  list = s->init_data->hook.sm_list;
775  SCLogDebug("setting list %d", list);
776  }
777  }
778 
779  if (list == -1) {
780  SCLogError("lua failed to set up");
781  goto error;
782  }
783  if (list == 0) {
784  if (lua->flags & FLAG_LIST_JA3) {
785  list = g_lua_ja3_list_id;
786  } else if (lua->flags & FLAG_LIST_JA3S) {
787  list = g_lua_ja3s_list_id;
788  }
789  }
790 
791  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
792  goto error;
793  }
794 
795  return 0;
796 
797 error:
798  if (lua != NULL)
799  DetectLuaFree(de_ctx, lua);
800  return -1;
801 }
802 
803 /**
804  * \brief this function will free memory associated with DetectLuaData
805  *
806  * \param ptr pointer to DetectLuaData
807  */
808 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
809 {
810  if (ptr != NULL) {
811  DetectLuaData *lua = (DetectLuaData *)ptr;
812 
813  if (lua->buffername)
814  SCFree(lua->buffername);
815  if (lua->filename)
816  SCFree(lua->filename);
817 
818  for (uint16_t i = 0; i < lua->flowints; i++) {
820  }
821  for (uint16_t i = 0; i < lua->flowvars; i++) {
823  }
824 
826 
827  SCFree(lua);
828  }
829 }
830 
831 #ifdef UNITTESTS
832 #include "detect-engine-alert.h"
833 
834 /** \test http buffer */
835 static int LuaMatchTest01(void)
836 {
837  SCConfSetFinal("security.lua.allow-rules", "true");
838 
839  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
840  "function init (args)\n"
841  " flowvarlib.register(\"cnt\")\n"
842  " return {}\n"
843  "end\n"
844  "function thread_init (args)\n"
845  " cnt = flowvarlib.get(\"cnt\")\n"
846  "end\n"
847  "\n"
848  "function match(args)\n"
849  " a = cnt:value()\n"
850  " if a then\n"
851  " a = tostring(tonumber(a)+1)\n"
852  " print (a)\n"
853  " cnt:set(a, #a)\n"
854  " else\n"
855  " a = tostring(1)\n"
856  " print (a)\n"
857  " cnt:set(a, #a)\n"
858  " end\n"
859  " \n"
860  " print (\"pre check: \" .. (a))\n"
861  " if tonumber(a) == 2 then\n"
862  " print \"match\"\n"
863  " return 1\n"
864  " end\n"
865  " return 0\n"
866  "end\n"
867  "return 0\n";
868  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
869  "sid:1;)";
870  uint8_t httpbuf1[] =
871  "POST / HTTP/1.1\r\n"
872  "Host: www.emergingthreats.net\r\n\r\n";
873  uint8_t httpbuf2[] =
874  "POST / HTTP/1.1\r\n"
875  "Host: www.openinfosecfoundation.org\r\n\r\n";
876  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
877  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
878  TcpSession ssn;
879  Flow f;
880  ThreadVars th_v;
881  DetectEngineThreadCtx *det_ctx;
882 
884 
885  ut_script = script;
886 
887  memset(&th_v, 0, sizeof(th_v));
888  memset(&f, 0, sizeof(f));
889  memset(&ssn, 0, sizeof(ssn));
890 
891  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
892  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
893 
894  FLOW_INITIALIZE(&f);
895  f.protoctx = (void *)&ssn;
896  f.proto = IPPROTO_TCP;
897  f.flags |= FLOW_IPV4;
899 
900  p1->flow = &f;
904  p2->flow = &f;
908 
909  StreamTcpInitConfig(true);
910 
913  de_ctx->flags |= DE_QUIET;
914 
916  FAIL_IF_NULL(s);
917 
919  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
920 
921  int r = AppLayerParserParse(
922  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
923  FAIL_IF(r != 0);
924  HtpState *http_state = f.alstate;
925  FAIL_IF_NULL(http_state);
926 
927  /* do detect for p1 */
928  SCLogDebug("inspecting p1");
929  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
930 
931  FAIL_IF(PacketAlertCheck(p1, 1));
932 
933  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
934  FAIL_IF(r != 0);
935 
936  /* do detect for p2 */
937  SCLogDebug("inspecting p2");
938  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
939 
941 
942  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
943  FAIL_IF(id == 0);
944 
945  FlowVar *fv = FlowVarGet(&f, id);
946  FAIL_IF_NULL(fv);
947 
948  FAIL_IF(fv->data.fv_str.value_len != 1);
949 
950  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
951 
954 
955  StreamTcpFreeConfig(true);
956  FLOW_DESTROY(&f);
957  UTHFreePackets(&p1, 1);
958  UTHFreePackets(&p2, 1);
959  PASS;
960 }
961 
962 static int LuaMatchTest01a(void)
963 {
964  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
965  "function init (args)\n"
966  " flowvarlib.register(\"cnt\")\n"
967  " return {}\n"
968  "end\n"
969  "function thread_init (args)\n"
970  " cnt = flowvarlib.get(\"cnt\")\n"
971  "end\n"
972  "\n"
973  "function match(args)\n"
974  " a = cnt:value(0)\n"
975  " if a then\n"
976  " a = tostring(tonumber(a)+1)\n"
977  " print (a)\n"
978  " cnt:set(a, #a)\n"
979  " else\n"
980  " a = tostring(1)\n"
981  " print (a)\n"
982  " cnt:set(a, #a)\n"
983  " end\n"
984  " \n"
985  " print (\"pre check: \" .. (a))\n"
986  " if tonumber(a) == 2 then\n"
987  " print \"match\"\n"
988  " return 1\n"
989  " end\n"
990  " return 0\n"
991  "end\n"
992  "return 0\n";
993  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
994  "sid:1;)";
995  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
996  "Host: www.emergingthreats.net\r\n\r\n";
997  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
998  "Host: www.openinfosecfoundation.org\r\n\r\n";
999  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1000  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1001  TcpSession ssn;
1002  Flow f;
1003  ThreadVars th_v;
1004  DetectEngineThreadCtx *det_ctx;
1005 
1007 
1008  ut_script = script;
1009 
1010  memset(&th_v, 0, sizeof(th_v));
1011  memset(&f, 0, sizeof(f));
1012  memset(&ssn, 0, sizeof(ssn));
1013 
1014  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1015  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1016 
1017  FLOW_INITIALIZE(&f);
1018  f.protoctx = (void *)&ssn;
1019  f.proto = IPPROTO_TCP;
1020  f.flags |= FLOW_IPV4;
1021  f.alproto = ALPROTO_HTTP1;
1022 
1023  p1->flow = &f;
1027  p2->flow = &f;
1031 
1032  StreamTcpInitConfig(true);
1033 
1036  de_ctx->flags |= DE_QUIET;
1037 
1039  FAIL_IF_NULL(s);
1040 
1042  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1043 
1044  int r = AppLayerParserParse(
1045  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1046  FAIL_IF(r != 0);
1047 
1048  HtpState *http_state = f.alstate;
1049  FAIL_IF_NULL(http_state);
1050 
1051  /* do detect for p1 */
1052  SCLogDebug("inspecting p1");
1053  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1054 
1055  FAIL_IF(PacketAlertCheck(p1, 1));
1056 
1057  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1058  FAIL_IF(r != 0);
1059  /* do detect for p2 */
1060  SCLogDebug("inspecting p2");
1061  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1062 
1063  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1064 
1065  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1066  FAIL_IF(id == 0);
1067 
1068  FlowVar *fv = FlowVarGet(&f, id);
1069  FAIL_IF_NULL(fv);
1070 
1071  FAIL_IF(fv->data.fv_str.value_len != 1);
1072 
1073  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1074 
1077 
1078  StreamTcpFreeConfig(true);
1079  FLOW_DESTROY(&f);
1080  UTHFreePackets(&p1, 1);
1081  UTHFreePackets(&p2, 1);
1082  PASS;
1083 }
1084 
1085 /** \test payload buffer */
1086 static int LuaMatchTest02(void)
1087 {
1088  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1089  "function init (args)\n"
1090  " flowvarlib.register(\"cnt\")\n"
1091  " local needs = {}\n"
1092  " needs[\"payload\"] = tostring(true)\n"
1093  " return needs\n"
1094  "end\n"
1095  "function thread_init (args)\n"
1096  " cnt = flowvarlib.get(\"cnt\")\n"
1097  "end\n"
1098  "\n"
1099  "function match(args)\n"
1100  " a = cnt:value()\n"
1101  " if a then\n"
1102  " a = tostring(tonumber(a)+1)\n"
1103  " print (a)\n"
1104  " cnt:set(a, #a)\n"
1105  " else\n"
1106  " a = tostring(1)\n"
1107  " print (a)\n"
1108  " cnt:set(a, #a)\n"
1109  " end\n"
1110  " \n"
1111  " print (\"pre check: \" .. (a))\n"
1112  " if tonumber(a) == 2 then\n"
1113  " print \"match\"\n"
1114  " return 1\n"
1115  " end\n"
1116  " return 0\n"
1117  "end\n"
1118  "return 0\n";
1119  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1120  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1121  "Host: www.emergingthreats.net\r\n\r\n";
1122  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1123  "Host: www.openinfosecfoundation.org\r\n\r\n";
1124  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1125  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1126  TcpSession ssn;
1127  Flow f;
1128  ThreadVars th_v;
1129  DetectEngineThreadCtx *det_ctx;
1130 
1131  ut_script = script;
1132 
1133  memset(&th_v, 0, sizeof(th_v));
1134  memset(&f, 0, sizeof(f));
1135  memset(&ssn, 0, sizeof(ssn));
1136 
1137  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1138  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1139 
1140  FLOW_INITIALIZE(&f);
1141  f.protoctx = (void *)&ssn;
1142  f.proto = IPPROTO_TCP;
1143  f.flags |= FLOW_IPV4;
1144  f.alproto = ALPROTO_HTTP1;
1145 
1146  p1->flow = &f;
1150  p2->flow = &f;
1154 
1155  StreamTcpInitConfig(true);
1156 
1159  de_ctx->flags |= DE_QUIET;
1160 
1162  FAIL_IF_NULL(s);
1163 
1165  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1166 
1167  /* do detect for p1 */
1168  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1169 
1170  FAIL_IF(PacketAlertCheck(p1, 1));
1171 
1172  /* do detect for p2 */
1173  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1174 
1175  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1176 
1177  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1178  FAIL_IF(id == 0);
1179 
1180  FlowVar *fv = FlowVarGet(&f, id);
1181  FAIL_IF_NULL(fv);
1182 
1183  FAIL_IF(fv->data.fv_str.value_len != 1);
1184 
1185  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1186 
1188 
1189  StreamTcpFreeConfig(true);
1190  FLOW_DESTROY(&f);
1191  UTHFreePackets(&p1, 1);
1192  UTHFreePackets(&p2, 1);
1193  PASS;
1194 }
1195 
1196 /** \test payload buffer */
1197 static int LuaMatchTest02a(void)
1198 {
1199  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1200  "function init (args)\n"
1201  " flowvarlib.register(\"cnt\")"
1202  " local needs = {}\n"
1203  " needs[\"payload\"] = tostring(true)\n"
1204  " return needs\n"
1205  "end\n"
1206  "function thread_init (args)\n"
1207  " cnt = flowvarlib.get(\"cnt\")"
1208  "end\n"
1209  "\n"
1210  "function match(args)\n"
1211  " a = cnt:value()\n"
1212  " if a then\n"
1213  " a = tostring(tonumber(a)+1)\n"
1214  " print (a)\n"
1215  " cnt:set(a, #a)\n"
1216  " else\n"
1217  " a = tostring(1)\n"
1218  " print (a)\n"
1219  " cnt:set(a, #a)\n"
1220  " end\n"
1221  " \n"
1222  " print (\"pre check: \" .. (a))\n"
1223  " if tonumber(a) == 2 then\n"
1224  " print \"match\"\n"
1225  " return 1\n"
1226  " end\n"
1227  " return 0\n"
1228  "end\n"
1229  "return 0\n";
1230  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1231  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1232  "Host: www.emergingthreats.net\r\n\r\n";
1233  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1234  "Host: www.openinfosecfoundation.org\r\n\r\n";
1235  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1236  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1237  TcpSession ssn;
1238  Flow f;
1239  ThreadVars th_v;
1240  DetectEngineThreadCtx *det_ctx;
1241 
1242  ut_script = script;
1243 
1244  memset(&th_v, 0, sizeof(th_v));
1245  memset(&f, 0, sizeof(f));
1246  memset(&ssn, 0, sizeof(ssn));
1247 
1248  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1249  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1250 
1251  FLOW_INITIALIZE(&f);
1252  f.protoctx = (void *)&ssn;
1253  f.proto = IPPROTO_TCP;
1254  f.flags |= FLOW_IPV4;
1255  f.alproto = ALPROTO_HTTP1;
1256 
1257  p1->flow = &f;
1261  p2->flow = &f;
1265 
1266  StreamTcpInitConfig(true);
1267 
1270  de_ctx->flags |= DE_QUIET;
1271 
1273  FAIL_IF_NULL(s);
1274 
1276  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1277 
1278  /* do detect for p1 */
1279  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1280  FAIL_IF(PacketAlertCheck(p1, 1));
1281 
1282  /* do detect for p2 */
1283  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1284 
1285  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1286 
1287  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1288  FAIL_IF(id == 0);
1289 
1290  FlowVar *fv = FlowVarGet(&f, id);
1291  FAIL_IF_NULL(fv);
1292 
1293  FAIL_IF(fv->data.fv_str.value_len != 1);
1294 
1295  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1296 
1298 
1299  StreamTcpFreeConfig(true);
1300  FLOW_DESTROY(&f);
1301  UTHFreePackets(&p1, 1);
1302  UTHFreePackets(&p2, 1);
1303  PASS;
1304 }
1305 
1306 /** \test packet buffer */
1307 static int LuaMatchTest03(void)
1308 {
1309  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1310  "function init (args)\n"
1311  " flowvarlib.register(\"cnt\")\n"
1312  " local needs = {}\n"
1313  " needs[\"packet\"] = tostring(true)\n"
1314  " return needs\n"
1315  "end\n"
1316  "\n"
1317  "function thread_init (args)\n"
1318  " cnt = flowvarlib.get(\"cnt\")\n"
1319  "end\n"
1320  "\n"
1321  "function match(args)\n"
1322  " a = cnt:value()\n"
1323  " if a then\n"
1324  " a = tostring(tonumber(a)+1)\n"
1325  " print (a)\n"
1326  " cnt:set(a, #a)\n"
1327  " else\n"
1328  " a = tostring(1)\n"
1329  " print (a)\n"
1330  " cnt:set(a, #a)\n"
1331  " end\n"
1332  " \n"
1333  " print (\"pre check: \" .. (a))\n"
1334  " if tonumber(a) == 2 then\n"
1335  " print \"match\"\n"
1336  " return 1\n"
1337  " end\n"
1338  " return 0\n"
1339  "end\n"
1340  "return 0\n";
1341  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1342  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1343  "Host: www.emergingthreats.net\r\n\r\n";
1344  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1345  "Host: www.openinfosecfoundation.org\r\n\r\n";
1346  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1347  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1348  TcpSession ssn;
1349  Flow f;
1350  ThreadVars th_v;
1351  DetectEngineThreadCtx *det_ctx;
1352 
1353  ut_script = script;
1354 
1355  memset(&th_v, 0, sizeof(th_v));
1356  memset(&f, 0, sizeof(f));
1357  memset(&ssn, 0, sizeof(ssn));
1358 
1359  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1360  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1361 
1362  FLOW_INITIALIZE(&f);
1363  f.protoctx = (void *)&ssn;
1364  f.proto = IPPROTO_TCP;
1365  f.flags |= FLOW_IPV4;
1366  f.alproto = ALPROTO_HTTP1;
1367 
1368  p1->flow = &f;
1372  p2->flow = &f;
1376 
1377  StreamTcpInitConfig(true);
1378 
1381  de_ctx->flags |= DE_QUIET;
1382 
1384  FAIL_IF_NULL(s);
1385 
1387  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1388 
1389  /* do detect for p1 */
1390  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1391  FAIL_IF(PacketAlertCheck(p1, 1));
1392 
1393  /* do detect for p2 */
1394  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1395 
1396  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1397 
1398  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1399  FAIL_IF(id == 0);
1400 
1401  FlowVar *fv = FlowVarGet(&f, id);
1402  FAIL_IF_NULL(fv);
1403 
1404  FAIL_IF(fv->data.fv_str.value_len != 1);
1405 
1406  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1407 
1409 
1410  StreamTcpFreeConfig(true);
1411  FLOW_DESTROY(&f);
1412  UTHFreePackets(&p1, 1);
1413  UTHFreePackets(&p2, 1);
1414  PASS;
1415 }
1416 
1417 /** \test packet buffer */
1418 static int LuaMatchTest03a(void)
1419 {
1420  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1421  "function init (args)\n"
1422  " flowvarlib.register(\"cnt\")\n"
1423  " local needs = {}\n"
1424  " needs[\"packet\"] = tostring(true)\n"
1425  " return needs\n"
1426  "end\n"
1427  "\n"
1428  "function thread_init (args)\n"
1429  " cnt = flowvarlib.get(\"cnt\")\n"
1430  "end\n"
1431  "\n"
1432  "function match(args)\n"
1433  " a = cnt:value()\n"
1434  " if a then\n"
1435  " a = tostring(tonumber(a)+1)\n"
1436  " print (a)\n"
1437  " cnt:set(a, #a)\n"
1438  " else\n"
1439  " a = tostring(1)\n"
1440  " print (a)\n"
1441  " cnt:set(a, #a)\n"
1442  " end\n"
1443  " \n"
1444  " print (\"pre check: \" .. (a))\n"
1445  " if tonumber(a) == 2 then\n"
1446  " print \"match\"\n"
1447  " return 1\n"
1448  " end\n"
1449  " return 0\n"
1450  "end\n"
1451  "return 0\n";
1452  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1453  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1454  "Host: www.emergingthreats.net\r\n\r\n";
1455  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1456  "Host: www.openinfosecfoundation.org\r\n\r\n";
1457  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1458  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1459  TcpSession ssn;
1460  Flow f;
1461  ThreadVars th_v;
1462  DetectEngineThreadCtx *det_ctx;
1463 
1464  ut_script = script;
1465 
1466  memset(&th_v, 0, sizeof(th_v));
1467  memset(&f, 0, sizeof(f));
1468  memset(&ssn, 0, sizeof(ssn));
1469 
1470  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1471  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1472 
1473  FLOW_INITIALIZE(&f);
1474  f.protoctx = (void *)&ssn;
1475  f.proto = IPPROTO_TCP;
1476  f.flags |= FLOW_IPV4;
1477  f.alproto = ALPROTO_HTTP1;
1478 
1479  p1->flow = &f;
1483  p2->flow = &f;
1487 
1488  StreamTcpInitConfig(true);
1489 
1492  de_ctx->flags |= DE_QUIET;
1493 
1495  FAIL_IF_NULL(s);
1496 
1498  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1499 
1500  /* do detect for p1 */
1501  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1502  FAIL_IF(PacketAlertCheck(p1, 1));
1503 
1504  /* do detect for p2 */
1505  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1506  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1507 
1508  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1509  FAIL_IF(id == 0);
1510 
1511  FlowVar *fv = FlowVarGet(&f, id);
1512  FAIL_IF_NULL(fv);
1513 
1514  FAIL_IF(fv->data.fv_str.value_len != 1);
1515 
1516  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1517 
1519 
1520  StreamTcpFreeConfig(true);
1521  FLOW_DESTROY(&f);
1522  UTHFreePackets(&p1, 1);
1523  UTHFreePackets(&p2, 1);
1524  PASS;
1525 }
1526 
1527 /** \test http buffer, flowints */
1528 static int LuaMatchTest04(void)
1529 {
1530  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1531  "function init (args)\n"
1532  " flowintlib.register(\"cnt\")\n"
1533  " return {}\n"
1534  "end\n"
1535  "\n"
1536  "function thread_init (args)\n"
1537  " cnt = flowintlib.get(\"cnt\")\n"
1538  "end\n"
1539  "\n"
1540  "function match(args)\n"
1541  " print \"inspecting\""
1542  " a = cnt:value()\n"
1543  " if a then\n"
1544  " cnt:set(a + 1)\n"
1545  " else\n"
1546  " cnt:set(1)\n"
1547  " end\n"
1548  " \n"
1549  " a = cnt:value()\n"
1550  " if a == 2 then\n"
1551  " print \"match\"\n"
1552  " return 1\n"
1553  " end\n"
1554  " return 0\n"
1555  "end\n"
1556  "return 0\n";
1557  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1558  "sid:1;)";
1559  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1560  "Host: www.emergingthreats.net\r\n\r\n";
1561  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1562  "Host: www.openinfosecfoundation.org\r\n\r\n";
1563  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1564  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1565  TcpSession ssn;
1566  Flow f;
1567  ThreadVars th_v;
1568  DetectEngineThreadCtx *det_ctx;
1569 
1571 
1572  ut_script = script;
1573 
1574  memset(&th_v, 0, sizeof(th_v));
1575  memset(&f, 0, sizeof(f));
1576  memset(&ssn, 0, sizeof(ssn));
1577 
1578  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1579  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1580 
1581  FLOW_INITIALIZE(&f);
1582  f.protoctx = (void *)&ssn;
1583  f.proto = IPPROTO_TCP;
1584  f.flags |= FLOW_IPV4;
1585  f.alproto = ALPROTO_HTTP1;
1586 
1587  p1->flow = &f;
1591 
1592  p2->flow = &f;
1596 
1597  StreamTcpInitConfig(true);
1598 
1601  de_ctx->flags |= DE_QUIET;
1602 
1604  FAIL_IF_NULL(s);
1605 
1607  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1608 
1609  int r = AppLayerParserParse(
1610  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1611  FAIL_IF(r != 0);
1612  HtpState *http_state = f.alstate;
1613  FAIL_IF_NULL(http_state);
1614 
1615  /* do detect for p1 */
1616  SCLogInfo("p1");
1617  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1618 
1619  FAIL_IF(PacketAlertCheck(p1, 1));
1620 
1621  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1622  FAIL_IF(r != 0);
1623  /* do detect for p2 */
1624  SCLogInfo("p2");
1625  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1626 
1627  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1628 
1629  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1630  FAIL_IF(id == 0);
1631 
1632  FlowVar *fv = FlowVarGet(&f, id);
1633  FAIL_IF_NULL(fv);
1634 
1635  FAIL_IF(fv->data.fv_int.value != 2);
1636 
1639 
1640  StreamTcpFreeConfig(true);
1641  FLOW_DESTROY(&f);
1642  UTHFreePackets(&p1, 1);
1643  UTHFreePackets(&p2, 1);
1644  PASS;
1645 }
1646 
1647 /** \test http buffer, flowints */
1648 static int LuaMatchTest04a(void)
1649 {
1650  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1651  "function init (args)\n"
1652  " flowintlib.register(\"cnt\")\n"
1653  " return {}\n"
1654  "end\n"
1655  "\n"
1656  "function thread_init (args)\n"
1657  " cnt = flowintlib.get(\"cnt\")\n"
1658  "end\n"
1659  "\n"
1660  "function match(args)\n"
1661  " print \"inspecting\""
1662  " a = cnt:value()\n"
1663  " if a then\n"
1664  " cnt:set(a + 1)\n"
1665  " else\n"
1666  " cnt:set(1)\n"
1667  " end\n"
1668  " \n"
1669  " a = cnt:value()\n"
1670  " if a == 2 then\n"
1671  " print \"match\"\n"
1672  " return 1\n"
1673  " end\n"
1674  " return 0\n"
1675  "end\n"
1676  "return 0\n";
1677  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1678  "sid:1;)";
1679  uint8_t httpbuf1[] =
1680  "POST / HTTP/1.1\r\n"
1681  "Host: www.emergingthreats.net\r\n\r\n";
1682  uint8_t httpbuf2[] =
1683  "POST / HTTP/1.1\r\n"
1684  "Host: www.openinfosecfoundation.org\r\n\r\n";
1685  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1686  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1687  TcpSession ssn;
1688  Flow f;
1689  ThreadVars th_v;
1690  DetectEngineThreadCtx *det_ctx;
1691 
1693 
1694  ut_script = script;
1695 
1696  memset(&th_v, 0, sizeof(th_v));
1697  memset(&f, 0, sizeof(f));
1698  memset(&ssn, 0, sizeof(ssn));
1699 
1700  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1701  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1702 
1703  FLOW_INITIALIZE(&f);
1704  f.protoctx = (void *)&ssn;
1705  f.proto = IPPROTO_TCP;
1706  f.flags |= FLOW_IPV4;
1707  f.alproto = ALPROTO_HTTP1;
1708 
1709  p1->flow = &f;
1713 
1714  p2->flow = &f;
1718 
1719  StreamTcpInitConfig(true);
1720 
1723  de_ctx->flags |= DE_QUIET;
1724 
1726  FAIL_IF_NULL(s);
1727 
1729  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1730 
1731  int r = AppLayerParserParse(
1732  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1733  FAIL_IF(r != 0);
1734  HtpState *http_state = f.alstate;
1735  FAIL_IF_NULL(http_state);
1736 
1737  /* do detect for p1 */
1738  SCLogInfo("p1");
1739  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1740 
1741  FAIL_IF(PacketAlertCheck(p1, 1));
1742 
1743  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1744  FAIL_IF(r != 0);
1745  /* do detect for p2 */
1746  SCLogInfo("p2");
1747  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1748 
1749  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1750 
1751  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1752  FAIL_IF(id == 0);
1753 
1754  FlowVar *fv = FlowVarGet(&f, id);
1755  FAIL_IF_NULL(fv);
1756 
1757  FAIL_IF(fv->data.fv_int.value != 2);
1758 
1761 
1762  StreamTcpFreeConfig(true);
1763  FLOW_DESTROY(&f);
1764  UTHFreePackets(&p1, 1);
1765  UTHFreePackets(&p2, 1);
1766  PASS;
1767 }
1768 
1769 /** \test http buffer, flowints */
1770 static int LuaMatchTest05(void)
1771 {
1772  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1773  "function init (args)\n"
1774  " flowintlib.register(\"cnt\")\n"
1775  " return {}\n"
1776  "end\n"
1777  "\n"
1778  "function thread_init (args)\n"
1779  " cnt = flowintlib.get(\"cnt\")\n"
1780  "end\n"
1781  "\n"
1782  "function match(args)\n"
1783  " print \"inspecting\""
1784  " a = cnt:incr()\n"
1785  " if a == 2 then\n"
1786  " print \"match\"\n"
1787  " return 1\n"
1788  " end\n"
1789  " return 0\n"
1790  "end\n"
1791  "return 0\n";
1792  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1793  "sid:1;)";
1794  uint8_t httpbuf1[] =
1795  "POST / HTTP/1.1\r\n"
1796  "Host: www.emergingthreats.net\r\n\r\n";
1797  uint8_t httpbuf2[] =
1798  "POST / HTTP/1.1\r\n"
1799  "Host: www.openinfosecfoundation.org\r\n\r\n";
1800  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1801  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1802  TcpSession ssn;
1803  Flow f;
1804  ThreadVars th_v;
1805  DetectEngineThreadCtx *det_ctx;
1806 
1808 
1809  ut_script = script;
1810 
1811  memset(&th_v, 0, sizeof(th_v));
1812  memset(&f, 0, sizeof(f));
1813  memset(&ssn, 0, sizeof(ssn));
1814 
1815  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1816  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1817 
1818  FLOW_INITIALIZE(&f);
1819  f.protoctx = (void *)&ssn;
1820  f.proto = IPPROTO_TCP;
1821  f.flags |= FLOW_IPV4;
1822  f.alproto = ALPROTO_HTTP1;
1823 
1824  p1->flow = &f;
1828 
1829  p2->flow = &f;
1833 
1834  StreamTcpInitConfig(true);
1835 
1838  de_ctx->flags |= DE_QUIET;
1839 
1841  FAIL_IF_NULL(s);
1842 
1844  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1845 
1846  int r = AppLayerParserParse(
1847  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1848  FAIL_IF(r != 0);
1849  HtpState *http_state = f.alstate;
1850  FAIL_IF_NULL(http_state);
1851 
1852  /* do detect for p1 */
1853  SCLogInfo("p1");
1854  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1855 
1856  FAIL_IF(PacketAlertCheck(p1, 1));
1857 
1858  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1859  FAIL_IF(r != 0);
1860  /* do detect for p2 */
1861  SCLogInfo("p2");
1862  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1863 
1864  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1865 
1866  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1867  FAIL_IF(id == 0);
1868 
1869  FlowVar *fv = FlowVarGet(&f, id);
1870  FAIL_IF_NULL(fv);
1871 
1872  FAIL_IF(fv->data.fv_int.value != 2);
1873 
1876 
1877  StreamTcpFreeConfig(true);
1878  FLOW_DESTROY(&f);
1879  UTHFreePackets(&p1, 1);
1880  UTHFreePackets(&p2, 1);
1881  PASS;
1882 }
1883 
1884 /** \test http buffer, flowints */
1885 static int LuaMatchTest05a(void)
1886 {
1887  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1888  "function init (args)\n"
1889  " flowintlib.register(\"cnt\")\n"
1890  " return {}\n"
1891  "end\n"
1892  "\n"
1893  "function thread_init (args)\n"
1894  " cnt = flowintlib.get(\"cnt\")\n"
1895  "end\n"
1896  "\n"
1897  "function match(args)\n"
1898  " print \"inspecting\""
1899  " a = cnt:incr()\n"
1900  " if a == 2 then\n"
1901  " print \"match\"\n"
1902  " return 1\n"
1903  " end\n"
1904  " return 0\n"
1905  "end\n"
1906  "return 0\n";
1907  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1908  "sid:1;)";
1909  uint8_t httpbuf1[] =
1910  "POST / HTTP/1.1\r\n"
1911  "Host: www.emergingthreats.net\r\n\r\n";
1912  uint8_t httpbuf2[] =
1913  "POST / HTTP/1.1\r\n"
1914  "Host: www.openinfosecfoundation.org\r\n\r\n";
1915  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1916  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1917  TcpSession ssn;
1918  Flow f;
1919  ThreadVars th_v;
1920  DetectEngineThreadCtx *det_ctx;
1921 
1923 
1924  ut_script = script;
1925 
1926  memset(&th_v, 0, sizeof(th_v));
1927  memset(&f, 0, sizeof(f));
1928  memset(&ssn, 0, sizeof(ssn));
1929 
1930  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1931  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1932 
1933  FLOW_INITIALIZE(&f);
1934  f.protoctx = (void *)&ssn;
1935  f.proto = IPPROTO_TCP;
1936  f.flags |= FLOW_IPV4;
1937  f.alproto = ALPROTO_HTTP1;
1938 
1939  p1->flow = &f;
1943 
1944  p2->flow = &f;
1948 
1949  StreamTcpInitConfig(true);
1950 
1953  de_ctx->flags |= DE_QUIET;
1954 
1956  FAIL_IF_NULL(s);
1957 
1959  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1960 
1961  int r = AppLayerParserParse(
1962  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1963  FAIL_IF(r != 0);
1964  HtpState *http_state = f.alstate;
1965  FAIL_IF_NULL(http_state);
1966 
1967  /* do detect for p1 */
1968  SCLogInfo("p1");
1969  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1970 
1971  FAIL_IF(PacketAlertCheck(p1, 1));
1972 
1973  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1974  FAIL_IF(r != 0);
1975  /* do detect for p2 */
1976  SCLogInfo("p2");
1977  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1978 
1979  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1980 
1981  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1982  FAIL_IF(id == 0);
1983 
1984  FlowVar *fv = FlowVarGet(&f, id);
1985  FAIL_IF_NULL(fv);
1986 
1987  FAIL_IF(fv->data.fv_int.value != 2);
1988 
1991 
1992  StreamTcpFreeConfig(true);
1993  FLOW_DESTROY(&f);
1994  UTHFreePackets(&p1, 1);
1995  UTHFreePackets(&p2, 1);
1996  PASS;
1997 }
1998 
1999 /** \test http buffer, flowints */
2000 static int LuaMatchTest06(void)
2001 {
2002  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2003  "function init (args)\n"
2004  " flowintlib.register(\"cnt\")\n"
2005  " return {}\n"
2006  "end\n"
2007  "\n"
2008  "function thread_init (args)\n"
2009  " cnt = flowintlib.get(\"cnt\")\n"
2010  "end\n"
2011  "\n"
2012  "function match(args)\n"
2013  " print \"inspecting\""
2014  " a = cnt:value()\n"
2015  " if a == nil then\n"
2016  " print \"new var set to 2\""
2017  " cnt:set(2)\n"
2018  " end\n"
2019  " a = cnt:decr()\n"
2020  " if a == 0 then\n"
2021  " print \"match\"\n"
2022  " return 1\n"
2023  " end\n"
2024  " return 0\n"
2025  "end\n"
2026  "return 0\n";
2027  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2028  "sid:1;)";
2029  uint8_t httpbuf1[] =
2030  "POST / HTTP/1.1\r\n"
2031  "Host: www.emergingthreats.net\r\n\r\n";
2032  uint8_t httpbuf2[] =
2033  "POST / HTTP/1.1\r\n"
2034  "Host: www.openinfosecfoundation.org\r\n\r\n";
2035  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2036  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2037  TcpSession ssn;
2038  Flow f;
2039  ThreadVars th_v;
2040  DetectEngineThreadCtx *det_ctx;
2041 
2043 
2044  ut_script = script;
2045 
2046  memset(&th_v, 0, sizeof(th_v));
2047  memset(&f, 0, sizeof(f));
2048  memset(&ssn, 0, sizeof(ssn));
2049 
2050  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2051  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2052 
2053  FLOW_INITIALIZE(&f);
2054  f.protoctx = (void *)&ssn;
2055  f.proto = IPPROTO_TCP;
2056  f.flags |= FLOW_IPV4;
2057  f.alproto = ALPROTO_HTTP1;
2058 
2059  p1->flow = &f;
2063 
2064  p2->flow = &f;
2068 
2069  StreamTcpInitConfig(true);
2070 
2073  de_ctx->flags |= DE_QUIET;
2074 
2076  FAIL_IF_NULL(s);
2077 
2079  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2080 
2081  int r = AppLayerParserParse(
2082  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2083  FAIL_IF(r != 0);
2084  HtpState *http_state = f.alstate;
2085  FAIL_IF_NULL(http_state);
2086 
2087  /* do detect for p1 */
2088  SCLogInfo("p1");
2089  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2090 
2091  FAIL_IF(PacketAlertCheck(p1, 1));
2092 
2093  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2094  FAIL_IF(r != 0);
2095  /* do detect for p2 */
2096  SCLogInfo("p2");
2097  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2098 
2099  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2100 
2101  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2102  FAIL_IF(id == 0);
2103 
2104  FlowVar *fv = FlowVarGet(&f, id);
2105  FAIL_IF_NULL(fv);
2106 
2107  FAIL_IF(fv->data.fv_int.value != 0);
2108 
2111 
2112  StreamTcpFreeConfig(true);
2113  FLOW_DESTROY(&f);
2114  UTHFreePackets(&p1, 1);
2115  UTHFreePackets(&p2, 1);
2116  PASS;
2117 }
2118 
2119 /** \test http buffer, flowints */
2120 static int LuaMatchTest06a(void)
2121 {
2122  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2123  "function init (args)\n"
2124  " flowintlib.register(\"cnt\")\n"
2125  " return {}\n"
2126  "end\n"
2127  "\n"
2128  "function thread_init (args)\n"
2129  " cnt = flowintlib.get(\"cnt\")\n"
2130  "end\n"
2131  "\n"
2132  "function match(args)\n"
2133  " print \"inspecting\""
2134  " a = cnt:value()\n"
2135  " if a == nil then\n"
2136  " print \"new var set to 2\""
2137  " cnt:set(2)\n"
2138  " end\n"
2139  " a = cnt:decr()\n"
2140  " if a == 0 then\n"
2141  " print \"match\"\n"
2142  " return 1\n"
2143  " end\n"
2144  " return 0\n"
2145  "end\n"
2146  "return 0\n";
2147  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2148  "sid:1;)";
2149  uint8_t httpbuf1[] =
2150  "POST / HTTP/1.1\r\n"
2151  "Host: www.emergingthreats.net\r\n\r\n";
2152  uint8_t httpbuf2[] =
2153  "POST / HTTP/1.1\r\n"
2154  "Host: www.openinfosecfoundation.org\r\n\r\n";
2155  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2156  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2157  TcpSession ssn;
2158  Flow f;
2159  ThreadVars th_v;
2160  DetectEngineThreadCtx *det_ctx;
2161 
2163 
2164  ut_script = script;
2165 
2166  memset(&th_v, 0, sizeof(th_v));
2167  memset(&f, 0, sizeof(f));
2168  memset(&ssn, 0, sizeof(ssn));
2169 
2170  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2171  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2172 
2173  FLOW_INITIALIZE(&f);
2174  f.protoctx = (void *)&ssn;
2175  f.proto = IPPROTO_TCP;
2176  f.flags |= FLOW_IPV4;
2177  f.alproto = ALPROTO_HTTP1;
2178 
2179  p1->flow = &f;
2183 
2184  p2->flow = &f;
2188 
2189  StreamTcpInitConfig(true);
2190 
2193  de_ctx->flags |= DE_QUIET;
2194 
2196  FAIL_IF_NULL(s);
2197 
2199  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2200 
2201  int r = AppLayerParserParse(
2202  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2203  FAIL_IF(r != 0);
2204  HtpState *http_state = f.alstate;
2205  FAIL_IF_NULL(http_state);
2206 
2207  /* do detect for p1 */
2208  SCLogInfo("p1");
2209  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2210 
2211  FAIL_IF(PacketAlertCheck(p1, 1));
2212 
2213  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2214  FAIL_IF(r != 0);
2215  /* do detect for p2 */
2216  SCLogInfo("p2");
2217  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2218 
2219  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2220 
2221  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2222  FAIL_IF(id == 0);
2223 
2224  FlowVar *fv = FlowVarGet(&f, id);
2225  FAIL_IF_NULL(fv);
2226 
2227  FAIL_IF(fv->data.fv_int.value != 0);
2228 
2231 
2232  StreamTcpFreeConfig(true);
2233  FLOW_DESTROY(&f);
2234  UTHFreePackets(&p1, 1);
2235  UTHFreePackets(&p2, 1);
2236  PASS;
2237 }
2238 
2239 void DetectLuaRegisterTests(void)
2240 {
2241  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2242  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2243  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2244  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2245  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2246  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2247  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2248  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2249  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2250  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2251  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2252  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2253 }
2254 #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:49
DetectLuaData
Definition: detect-lua.h:39
SigTableElmt_::url
const char * url
Definition: detect.h:1422
SCLuaSbState::memory_limit_error
bool memory_limit_error
Definition: util-lua-sandbox.h:56
FlowVar_::data
union FlowVar_::@114 data
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:1421
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1253
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
util-lua-common.h
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1409
SignatureHook_::sm_list
int sm_list
Definition: detect.h:562
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:1419
stream-tcp.h
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3704
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:270
DetectLuaData::flags
uint32_t flags
Definition: detect-lua.h:43
SCLuaSbGetContext
SCLuaSbState * SCLuaSbGetContext(lua_State *L)
Definition: util-lua-sandbox.c:351
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:141
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:40
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:369
Packet_::flags
uint32_t flags
Definition: decode.h:535
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:53
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:919
DetectEngineThreadCtx_::lua_blocked_function_errors
uint16_t lua_blocked_function_errors
Definition: detect.h:1342
DEFAULT_LUA_INSTRUCTION_LIMIT
#define DEFAULT_LUA_INSTRUCTION_LIMIT
Definition: detect-lua.c:124
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:58
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2624
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1387
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:322
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:2349
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:48
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:3338
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:523
DetectEngineThreadCtx_::lua_instruction_limit_errors
uint16_t lua_instruction_limit_errors
Definition: detect.h:1345
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:366
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1404
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:597
DetectByteIndexType
uint8_t DetectByteIndexType
Definition: detect-byte.h:28
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:1339
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:59
DetectLuaData::buffername
char * buffername
Definition: detect-lua.h:44
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:41
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:1211
DetectLuaData::thread_ctx_id
int thread_ctx_id
Definition: detect-lua.h:40
DetectLuaData::instruction_limit
uint64_t instruction_limit
Definition: detect-lua.h:52
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:22
DETECT_LUA
@ DETECT_LUA
Definition: detect-engine-register.h:92
SignatureInitData_::list
int list
Definition: detect.h:617
SCEnter
#define SCEnter(...)
Definition: util-debug.h:272
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:3350
VarNameStoreUnregister
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
Definition: util-var-name.c:201
DETECT_LUA_MAX_BYTEVARS
#define DETECT_LUA_MAX_BYTEVARS
Definition: detect-lua.h:37
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:250
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:579
SIGNATURE_HOOK_TYPE_NOT_SET
@ SIGNATURE_HOOK_TYPE_NOT_SET
Definition: detect.h:546
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
DetectLuaData::bytevar
uint32_t bytevar[DETECT_LUA_MAX_BYTEVARS]
Definition: detect-lua.h:50
DetectEngineThreadCtx_::lua_memory_limit_errors
uint16_t lua_memory_limit_errors
Definition: detect.h:1348
DetectLuaData::alloc_limit
uint64_t alloc_limit
Definition: detect-lua.h:51
DetectLuaData::flowints
uint16_t flowints
Definition: detect-lua.h:46
Packet_
Definition: decode.h:492
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:360
DetectLuaData::flowint
uint32_t flowint[DETECT_LUA_MAX_FLOWINTS]
Definition: detect-lua.h:45
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:736
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1384
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:79
SCLuaSbState::blocked_function_error
bool blocked_function_error
Definition: util-lua-sandbox.h:54
DetectLuaThreadData
Definition: detect-lua.h:30
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h: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:89
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:45
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2130
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:295
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:352
util-lua-sandbox.h
SCLuaSbLoadLibs
void SCLuaSbLoadLibs(lua_State *L)
Definition: util-lua-sandbox.c:279
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:39
Packet_::flow
struct Flow_ * flow
Definition: decode.h:537
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DetectByteRetrieveSMVar
bool DetectByteRetrieveSMVar(const char *arg, const Signature *s, DetectByteIndexType *index)
Used to retrieve args from BM.
Definition: detect-byte.c:40
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:1192
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:3634
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:1290
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:561
detect-engine-buffer.h
SCLuaSbResetInstructionCounter
void SCLuaSbResetInstructionCounter(lua_State *L)
Definition: util-lua-sandbox.c:387
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:1933
DetectLuaData::flowvars
uint16_t flowvars
Definition: detect-lua.h:47
luaext_key_ld
const char luaext_key_ld[]
Definition: detect-lua-extensions.c:46
str
#define str(s)
Definition: suricata-common.h:308
DetectEngineThreadCtx_::tv
ThreadVars * tv
Definition: detect.h:1219
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:262
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:657
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:38
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:2585
LuaRegisterExtensions
int LuaRegisterExtensions(lua_State *lua_state)
Register Suricata Lua functions.
Definition: detect-lua-extensions.c:116
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:249
SCLuaSbStateNew
lua_State * SCLuaSbStateNew(uint64_t alloclimit, uint64_t instructionlimit)
Allocate a new Lua sandbox.
Definition: util-lua-sandbox.c:319
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:921
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:78
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:58
DetectUnregisterThreadCtxFuncs
int DetectUnregisterThreadCtxFuncs(DetectEngineCtx *de_ctx, void *data, const char *name)
Remove Thread keyword context registration.
Definition: detect-engine.c:3686
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:276
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:42
FlowVar_
Definition: flow-var.h:49
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:1249
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1411
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