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-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/rule-lua-scripting.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_DATATYPE_STREAM BIT_U32(2)
114 #define FLAG_LIST_JA3 BIT_U32(3)
115 #define FLAG_LIST_JA3S BIT_U32(4)
116 #define FLAG_DATATYPE_BUFFER BIT_U32(22)
117 #define FLAG_ERROR_LOGGED BIT_U32(23)
118 #define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
119 #define FLAG_INSTRUCTION_LIMIT_LOGGED BIT_U32(25)
120 #define FLAG_MEMORY_LIMIT_LOGGED BIT_U32(26)
121 
122 #define DEFAULT_LUA_ALLOC_LIMIT 500000
123 #define DEFAULT_LUA_INSTRUCTION_LIMIT 500000
124 
125 /** \brief dump stack from lua state to screen */
126 void LuaDumpStack(lua_State *state, const char *prefix)
127 {
128  int size = lua_gettop(state);
129  printf("%s: size %d\n", prefix, size);
130 
131  for (int i = 1; i <= size; i++) {
132  int type = lua_type(state, i);
133  printf("- %s: Stack size=%d, level=%d, type=%d, ", prefix, size, i, type);
134 
135  switch (type) {
136  case LUA_TFUNCTION:
137  printf("function %s", lua_tostring(state, i));
138  break;
139  case LUA_TBOOLEAN:
140  printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
141  break;
142  case LUA_TNUMBER:
143  printf("number %g", lua_tonumber(state, i));
144  break;
145  case LUA_TSTRING:
146  printf("string `%s'", lua_tostring(state, i));
147  break;
148  case LUA_TTABLE:
149  printf("table `%s'", lua_tostring(state, i));
150  break;
151  default:
152  printf("other %s", lua_typename(state, type));
153  break;
154 
155  }
156  printf("\n");
157  }
158 }
159 
160 static void LuaStateSetDetectLuaData(lua_State *state, DetectLuaData *data)
161 {
162  lua_pushlightuserdata(state, (void *)&luaext_key_ld);
163  lua_pushlightuserdata(state, (void *)data);
164  lua_settable(state, LUA_REGISTRYINDEX);
165 }
166 
167 /**
168  * \brief Common function to run the Lua match function and process
169  * the return value.
170  */
171 static int DetectLuaRunMatch(
172  DetectEngineThreadCtx *det_ctx, const DetectLuaData *lua, DetectLuaThreadData *tlua)
173 {
174  /* Reset instruction count. */
176 
177  if (lua_pcall(tlua->luastate, 1, 1, 0) != 0) {
178  const char *reason = lua_tostring(tlua->luastate, -1);
179  SCLuaSbState *context = SCLuaSbGetContext(tlua->luastate);
180  uint32_t flag = 0;
181  if (context->blocked_function_error) {
182  StatsIncr(det_ctx->tv, det_ctx->lua_blocked_function_errors);
184  } else if (context->instruction_count_error) {
185  StatsIncr(det_ctx->tv, det_ctx->lua_instruction_limit_errors);
187  } else if (context->memory_limit_error) {
188  StatsIncr(det_ctx->tv, det_ctx->lua_memory_limit_errors);
189  reason = "memory limit exceeded";
191  } else {
192  flag = FLAG_ERROR_LOGGED;
193  }
194 
195  /* Log once per thread per error type, the message from Lua
196  * will include the filename. */
197  if (!(tlua->flags & flag)) {
198  SCLogWarning("Lua script failed to run successfully: %s", reason);
199  tlua->flags |= flag;
200  }
201 
202  StatsIncr(det_ctx->tv, det_ctx->lua_rule_errors);
203  while (lua_gettop(tlua->luastate) > 0) {
204  lua_pop(tlua->luastate, 1);
205  }
206  SCReturnInt(0);
207  }
208 
209  int match = 0;
210 
211  /* process returns from script */
212  if (lua_gettop(tlua->luastate) > 0) {
213  /* script returns a number (return 1 or return 0) */
214  if (lua_type(tlua->luastate, 1) == LUA_TNUMBER) {
215  double script_ret = lua_tonumber(tlua->luastate, 1);
216  SCLogDebug("script_ret %f", script_ret);
217  lua_pop(tlua->luastate, 1);
218 
219  if (script_ret == 1.0)
220  match = 1;
221 
222  /* script returns a table */
223  } else if (lua_type(tlua->luastate, 1) == LUA_TTABLE) {
224  lua_pushnil(tlua->luastate);
225  const char *k, *v;
226  while (lua_next(tlua->luastate, -2)) {
227  v = lua_tostring(tlua->luastate, -1);
228  lua_pop(tlua->luastate, 1);
229  k = lua_tostring(tlua->luastate, -1);
230 
231  if (!k || !v)
232  continue;
233 
234  SCLogDebug("k='%s', v='%s'", k, v);
235 
236  if (strcmp(k, "retval") == 0) {
237  int val;
238  if (StringParseInt32(&val, 10, 0, (const char *)v) < 0) {
239  SCLogError("Invalid value "
240  "for \"retval\" from LUA return table: '%s'",
241  v);
242  match = 0;
243  }
244  else if (val == 1) {
245  match = 1;
246  }
247  } else {
248  /* set flow var? */
249  }
250  }
251 
252  /* pop the table */
253  lua_pop(tlua->luastate, 1);
254  }
255  }
256 
257  if (lua->negated) {
258  if (match == 1)
259  match = 0;
260  else
261  match = 1;
262  }
263 
264  while (lua_gettop(tlua->luastate) > 0) {
265  lua_pop(tlua->luastate, 1);
266  }
267 
268  SCReturnInt(match);
269 }
270 
272  const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset,
273  Flow *f)
274 {
275  SCEnter();
276 
277  if (buffer == NULL || buffer_len == 0)
278  SCReturnInt(0);
279 
280  DetectLuaData *lua = (DetectLuaData *)smd->ctx;
281  if (lua == NULL)
282  SCReturnInt(0);
283 
284  DetectLuaThreadData *tlua =
286  if (tlua == NULL)
287  SCReturnInt(0);
288 
289  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
290 
291  /* prepare data to pass to script */
292  lua_getglobal(tlua->luastate, "match");
293  lua_newtable(tlua->luastate); /* stack at -1 */
294 
295  lua_pushliteral(tlua->luastate, "offset"); /* stack at -2 */
296  lua_pushnumber(tlua->luastate, (int)(offset + 1));
297  lua_settable(tlua->luastate, -3);
298 
299  lua_pushstring(tlua->luastate, lua->buffername); /* stack at -2 */
300  LuaPushStringBuffer(tlua->luastate, (const uint8_t *)buffer, (size_t)buffer_len);
301  lua_settable(tlua->luastate, -3);
302 
303  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
304 }
305 
306 /**
307  * \brief match the specified lua script
308  *
309  * \param t thread local vars
310  * \param det_ctx pattern matcher thread local data
311  * \param p packet
312  * \param s signature being inspected
313  * \param m sigmatch that we will cast into DetectLuaData
314  *
315  * \retval 0 no match
316  * \retval 1 match
317  */
318 static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
319  Packet *p, const Signature *s, const SigMatchCtx *ctx)
320 {
321  SCEnter();
322  DetectLuaData *lua = (DetectLuaData *)ctx;
323  if (lua == NULL)
324  SCReturnInt(0);
325 
327  if (tlua == NULL)
328  SCReturnInt(0);
329 
330  /* setup extension data for use in lua c functions */
331  uint8_t flags = 0;
332  if (p->flowflags & FLOW_PKT_TOSERVER)
333  flags = STREAM_TOSERVER;
334  else if (p->flowflags & FLOW_PKT_TOCLIENT)
335  flags = STREAM_TOCLIENT;
336 
337  LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
338 
339  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
340 
341  if ((tlua->flags & FLAG_DATATYPE_PAYLOAD) && p->payload_len == 0)
342  SCReturnInt(0);
343  if ((tlua->flags & FLAG_DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
344  SCReturnInt(0);
345 
346  lua_getglobal(tlua->luastate, "match");
347  lua_newtable(tlua->luastate); /* stack at -1 */
348 
349  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
350 }
351 
352 static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
353  Flow *f, uint8_t flags, void *state,
354  const Signature *s, const SigMatchCtx *ctx)
355 {
356  SCEnter();
357  DetectLuaData *lua = (DetectLuaData *)ctx;
358  if (lua == NULL)
359  SCReturnInt(0);
360 
362  if (tlua == NULL)
363  SCReturnInt(0);
364 
365  /* setup extension data for use in lua c functions */
366  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
367 
368  lua_getglobal(tlua->luastate, "match");
369  lua_newtable(tlua->luastate); /* stack at -1 */
370 
371  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
372 }
373 
374 /**
375  * \brief match the specified lua script in a list with a tx
376  *
377  * \param t thread local vars
378  * \param det_ctx pattern matcher thread local data
379  * \param s signature being inspected
380  * \param m sigmatch that we will cast into DetectLuaData
381  *
382  * \retval 0 no match
383  * \retval 1 match
384  */
385 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
386  Flow *f, uint8_t flags,
387  void *state, void *txv, const Signature *s,
388  const SigMatchCtx *ctx)
389 {
390  return DetectLuaAppMatchCommon(det_ctx, f, flags, state, s, ctx);
391 }
392 
393 #ifdef UNITTESTS
394 /* if this ptr is set the lua setup functions will use this buffer as the
395  * lua script instead of calling luaL_loadfile on the filename supplied. */
396 static const char *ut_script = NULL;
397 #endif
398 
399 static void *DetectLuaThreadInit(void *data)
400 {
401  int status;
402  DetectLuaData *lua = (DetectLuaData *)data;
403  BUG_ON(lua == NULL);
404 
406  if (unlikely(t == NULL)) {
407  SCLogError("couldn't alloc ctx memory");
408  return NULL;
409  }
410 
411  t->flags = lua->flags;
412 
414  if (t->luastate == NULL) {
415  SCLogError("luastate pool depleted");
416  goto error;
417  }
418 
419  if (lua->allow_restricted_functions) {
420  luaL_openlibs(t->luastate);
422  } else {
424  }
425 
427  LuaStateSetDetectLuaData(t->luastate, lua);
428 
429  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
430 #ifdef UNITTESTS
431  if (ut_script != NULL) {
432  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
433  if (status) {
434  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
435  goto error;
436  }
437  } else {
438 #endif
439  status = luaL_loadfile(t->luastate, lua->filename);
440  if (status) {
441  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
442  goto error;
443  }
444 #ifdef UNITTESTS
445  }
446 #endif
447 
448  /* prime the script (or something) */
449  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
450  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
451  goto error;
452  }
453 
454  /* thread_init call */
455  lua_getglobal(t->luastate, "thread_init");
456  if (lua_isfunction(t->luastate, -1)) {
457  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
458  SCLogError("couldn't run script 'thread_init' function: %s",
459  lua_tostring(t->luastate, -1));
460  goto error;
461  }
462  } else {
463  lua_pop(t->luastate, 1);
464  }
465 
466  return (void *)t;
467 
468 error:
469  if (t->luastate != NULL)
471  SCFree(t);
472  return NULL;
473 }
474 
475 static void DetectLuaThreadFree(void *ctx)
476 {
477  if (ctx != NULL) {
479  if (t->luastate != NULL)
481  SCFree(t);
482  }
483 }
484 
485 /**
486  * \brief Parse the lua keyword
487  *
488  * \param de_ctx Pointer to the detection engine context
489  * \param str Pointer to the user provided option
490  *
491  * \retval lua pointer to DetectLuaData on success
492  * \retval NULL on failure
493  */
494 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
495 {
496  DetectLuaData *lua = NULL;
497 
498  /* We have a correct lua option */
499  lua = SCCalloc(1, sizeof(DetectLuaData));
500  if (unlikely(lua == NULL))
501  goto error;
502 
503  if (strlen(str) && str[0] == '!') {
504  lua->negated = 1;
505  str++;
506  }
507 
508  /* get full filename */
510  if (lua->filename == NULL) {
511  goto error;
512  }
513 
514  return lua;
515 
516 error:
517  if (lua != NULL)
518  DetectLuaFree(de_ctx, lua);
519  return NULL;
520 }
521 
522 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
523 {
524  int status;
525 
527  if (luastate == NULL)
528  return -1;
529  if (ld->allow_restricted_functions) {
530  luaL_openlibs(luastate);
531  SCLuaRequirefBuiltIns(luastate);
532  } else {
533  SCLuaSbLoadLibs(luastate);
534  }
535  LuaStateSetDetectLuaData(luastate, ld);
536 
537  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
538 #ifdef UNITTESTS
539  if (ut_script != NULL) {
540  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
541  if (status) {
542  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
543  goto error;
544  }
545  } else {
546 #endif
547  status = luaL_loadfile(luastate, ld->filename);
548  if (status) {
549  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
550  goto error;
551  }
552 #ifdef UNITTESTS
553  }
554 #endif
555 
556  /* prime the script (or something) */
557  if (lua_pcall(luastate, 0, 0, 0) != 0) {
558  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
559  goto error;
560  }
561 
562  lua_getglobal(luastate, "init");
563  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
564  SCLogError("no init function in script");
565  goto error;
566  }
567 
568  if (lua_pcall(luastate, 0, 1, 0) != 0) {
569  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
570  goto error;
571  }
572 
573  /* process returns from script */
574  if (lua_gettop(luastate) == 0) {
575  SCLogError("init function in script should return table, nothing returned");
576  goto error;
577  }
578  if (lua_type(luastate, 1) != LUA_TTABLE) {
579  SCLogError("init function in script should return table, returned is not table");
580  goto error;
581  }
582 
583  lua_pushnil(luastate);
584  const char *k;
585  while (lua_next(luastate, -2)) {
586  k = lua_tostring(luastate, -2);
587  if (k == NULL)
588  continue;
589 
590  /* handle flowvar and bytes separately as they have a table as value */
591  if (strcmp(k, "flowvar") == 0) {
592  if (lua_istable(luastate, -1)) {
593  lua_pushnil(luastate);
594  while (lua_next(luastate, -2) != 0) {
595  /* value at -1, key is at -2 which we ignore */
596  const char *value = lua_tostring(luastate, -1);
597  SCLogDebug("value %s", value);
598  /* removes 'value'; keeps 'key' for next iteration */
599  lua_pop(luastate, 1);
600 
601  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
602  SCLogError("too many flowvars registered");
603  goto error;
604  }
605 
606  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
607  ld->flowvar[ld->flowvars++] = idx;
608  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
609  }
610  }
611  lua_pop(luastate, 1);
612  continue;
613  } else if (strcmp(k, "flowint") == 0) {
614  if (lua_istable(luastate, -1)) {
615  lua_pushnil(luastate);
616  while (lua_next(luastate, -2) != 0) {
617  /* value at -1, key is at -2 which we ignore */
618  const char *value = lua_tostring(luastate, -1);
619  SCLogDebug("value %s", value);
620  /* removes 'value'; keeps 'key' for next iteration */
621  lua_pop(luastate, 1);
622 
623  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
624  SCLogError("too many flowints registered");
625  goto error;
626  }
627 
628  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
629  ld->flowint[ld->flowints++] = idx;
630  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
631  }
632  }
633  lua_pop(luastate, 1);
634  continue;
635  } else if (strcmp(k, "bytevar") == 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->bytevars == DETECT_LUA_MAX_BYTEVARS) {
646  SCLogError("too many bytevars registered");
647  goto error;
648  }
649 
651  if (!DetectByteRetrieveSMVar(value, s, &idx)) {
652  SCLogError("Unknown byte_extract or byte_math var "
653  "requested by lua script - %s",
654  value);
655  goto error;
656  }
657  ld->bytevar[ld->bytevars++] = idx;
658  SCLogDebug("script uses bytevar %u with script id %u", idx, ld->bytevars - 1);
659  }
660  }
661  lua_pop(luastate, 1);
662  continue;
663  }
664 
665  bool required = lua_toboolean(luastate, -1);
666  lua_pop(luastate, 1);
667  if (!required) {
668  continue;
669  }
670 
671  if (strcmp(k, "ja3") == 0) {
672  ld->flags |= FLAG_LIST_JA3;
673  } else if (strcmp(k, "ja3s") == 0) {
674  ld->flags |= FLAG_LIST_JA3S;
675  } else if (strcmp(k, "packet") == 0) {
677  } else if (strcmp(k, "payload") == 0) {
679  } else if (strcmp(k, "buffer") == 0) {
681 
682  ld->buffername = SCStrdup("buffer");
683  if (ld->buffername == NULL) {
684  SCLogError("alloc error");
685  goto error;
686  }
687  } else if (strcmp(k, "stream") == 0) {
689 
690  ld->buffername = SCStrdup("stream");
691  if (ld->buffername == NULL) {
692  SCLogError("alloc error");
693  goto error;
694  }
695  /* old options no longer supported */
696  } else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
697  strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
698  strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
699  SCLogError("data type %s no longer supported, use rule hooks", k);
700  goto error;
701 
702  } else {
703  SCLogError("unsupported data type %s", k);
704  goto error;
705  }
706  }
707 
708  /* pop the table */
709  lua_pop(luastate, 1);
710  SCLuaSbStateClose(luastate);
711  return 0;
712 error:
713  SCLuaSbStateClose(luastate);
714  return -1;
715 }
716 
717 /**
718  * \brief this function is used to parse lua options
719  * \brief into the current signature
720  *
721  * \param de_ctx pointer to the Detection Engine Context
722  * \param s pointer to the Current Signature
723  * \param str pointer to the user provided "lua" option
724  *
725  * \retval 0 on Success
726  * \retval -1 on Failure
727  */
728 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
729 {
730  /* First check if Lua rules are enabled, by default Lua in rules
731  * is disabled. */
732  int enabled = 0;
733  if (SCConfGetBool("security.lua.allow-rules", &enabled) == 1 && !enabled) {
734  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
735  return -1;
736  }
737 
738  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
739  if (lua == NULL)
740  return -1;
741 
742  /* Load lua sandbox configurations */
743  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
744  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
745  (void)SCConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
746  (void)SCConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
747  lua->alloc_limit = lua_alloc_limit;
748  lua->instruction_limit = lua_instruction_limit;
749 
750  int allow_restricted_functions = 0;
751  (void)SCConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
752  lua->allow_restricted_functions = allow_restricted_functions;
753 
754  if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
755  goto error;
756  }
757 
759  DetectLuaThreadInit, (void *)lua,
760  DetectLuaThreadFree, 0);
761  if (lua->thread_ctx_id == -1)
762  goto error;
763 
764  int list = DetectBufferGetActiveList(de_ctx, s);
765  SCLogDebug("buffer list %d -> %d", list, s->init_data->list);
766  if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
767  /* what needs to happen here is: we register to the rule hook, so e.g.
768  * http1.request_complete. This means we need a list.
769  *
770  * This includes each pkt, payload, stream, etc. */
771 
773  list = s->init_data->hook.sm_list;
774  SCLogDebug("setting list %d", list);
775  }
776  }
777 
778  if (list == -1) {
779  SCLogError("lua failed to set up");
780  goto error;
781  }
782  if (list == 0) {
783  if (lua->flags & FLAG_LIST_JA3) {
784  list = g_lua_ja3_list_id;
785  } else if (lua->flags & FLAG_LIST_JA3S) {
786  list = g_lua_ja3s_list_id;
787  }
788  }
789 
790  if (SigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
791  goto error;
792  }
793 
794  return 0;
795 
796 error:
797  if (lua != NULL)
798  DetectLuaFree(de_ctx, lua);
799  return -1;
800 }
801 
802 /**
803  * \brief this function will free memory associated with DetectLuaData
804  *
805  * \param ptr pointer to DetectLuaData
806  */
807 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
808 {
809  if (ptr != NULL) {
810  DetectLuaData *lua = (DetectLuaData *)ptr;
811 
812  if (lua->buffername)
813  SCFree(lua->buffername);
814  if (lua->filename)
815  SCFree(lua->filename);
816 
817  for (uint16_t i = 0; i < lua->flowints; i++) {
819  }
820  for (uint16_t i = 0; i < lua->flowvars; i++) {
822  }
823 
825 
826  SCFree(lua);
827  }
828 }
829 
830 #ifdef UNITTESTS
831 #include "detect-engine-alert.h"
832 
833 /** \test http buffer */
834 static int LuaMatchTest01(void)
835 {
836  SCConfSetFinal("security.lua.allow-rules", "true");
837 
838  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
839  "function init (args)\n"
840  " flowvarlib.register(\"cnt\")\n"
841  " return {}\n"
842  "end\n"
843  "function thread_init (args)\n"
844  " cnt = flowvarlib.get(\"cnt\")\n"
845  "end\n"
846  "\n"
847  "function match(args)\n"
848  " a = cnt:value()\n"
849  " if a then\n"
850  " a = tostring(tonumber(a)+1)\n"
851  " print (a)\n"
852  " cnt:set(a, #a)\n"
853  " else\n"
854  " a = tostring(1)\n"
855  " print (a)\n"
856  " cnt:set(a, #a)\n"
857  " end\n"
858  " \n"
859  " print (\"pre check: \" .. (a))\n"
860  " if tonumber(a) == 2 then\n"
861  " print \"match\"\n"
862  " return 1\n"
863  " end\n"
864  " return 0\n"
865  "end\n"
866  "return 0\n";
867  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
868  "sid:1;)";
869  uint8_t httpbuf1[] =
870  "POST / HTTP/1.1\r\n"
871  "Host: www.emergingthreats.net\r\n\r\n";
872  uint8_t httpbuf2[] =
873  "POST / HTTP/1.1\r\n"
874  "Host: www.openinfosecfoundation.org\r\n\r\n";
875  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
876  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
877  TcpSession ssn;
878  Flow f;
879  ThreadVars th_v;
880  DetectEngineThreadCtx *det_ctx;
881 
883 
884  ut_script = script;
885 
886  memset(&th_v, 0, sizeof(th_v));
887  memset(&f, 0, sizeof(f));
888  memset(&ssn, 0, sizeof(ssn));
889 
890  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
891  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
892 
893  FLOW_INITIALIZE(&f);
894  f.protoctx = (void *)&ssn;
895  f.proto = IPPROTO_TCP;
896  f.flags |= FLOW_IPV4;
898 
899  p1->flow = &f;
903  p2->flow = &f;
907 
908  StreamTcpInitConfig(true);
909 
912  de_ctx->flags |= DE_QUIET;
913 
915  FAIL_IF_NULL(s);
916 
918  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
919 
920  int r = AppLayerParserParse(
921  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
922  FAIL_IF(r != 0);
923  HtpState *http_state = f.alstate;
924  FAIL_IF_NULL(http_state);
925 
926  /* do detect for p1 */
927  SCLogDebug("inspecting p1");
928  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
929 
930  FAIL_IF(PacketAlertCheck(p1, 1));
931 
932  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
933  FAIL_IF(r != 0);
934 
935  /* do detect for p2 */
936  SCLogDebug("inspecting p2");
937  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
938 
940 
941  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
942  FAIL_IF(id == 0);
943 
944  FlowVar *fv = FlowVarGet(&f, id);
945  FAIL_IF_NULL(fv);
946 
947  FAIL_IF(fv->data.fv_str.value_len != 1);
948 
949  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
950 
953 
954  StreamTcpFreeConfig(true);
955  FLOW_DESTROY(&f);
956  UTHFreePackets(&p1, 1);
957  UTHFreePackets(&p2, 1);
958  PASS;
959 }
960 
961 static int LuaMatchTest01a(void)
962 {
963  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
964  "function init (args)\n"
965  " flowvarlib.register(\"cnt\")\n"
966  " return {}\n"
967  "end\n"
968  "function thread_init (args)\n"
969  " cnt = flowvarlib.get(\"cnt\")\n"
970  "end\n"
971  "\n"
972  "function match(args)\n"
973  " a = cnt:value(0)\n"
974  " if a then\n"
975  " a = tostring(tonumber(a)+1)\n"
976  " print (a)\n"
977  " cnt:set(a, #a)\n"
978  " else\n"
979  " a = tostring(1)\n"
980  " print (a)\n"
981  " cnt:set(a, #a)\n"
982  " end\n"
983  " \n"
984  " print (\"pre check: \" .. (a))\n"
985  " if tonumber(a) == 2 then\n"
986  " print \"match\"\n"
987  " return 1\n"
988  " end\n"
989  " return 0\n"
990  "end\n"
991  "return 0\n";
992  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
993  "sid:1;)";
994  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
995  "Host: www.emergingthreats.net\r\n\r\n";
996  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
997  "Host: www.openinfosecfoundation.org\r\n\r\n";
998  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
999  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1000  TcpSession ssn;
1001  Flow f;
1002  ThreadVars th_v;
1003  DetectEngineThreadCtx *det_ctx;
1004 
1006 
1007  ut_script = script;
1008 
1009  memset(&th_v, 0, sizeof(th_v));
1010  memset(&f, 0, sizeof(f));
1011  memset(&ssn, 0, sizeof(ssn));
1012 
1013  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1014  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1015 
1016  FLOW_INITIALIZE(&f);
1017  f.protoctx = (void *)&ssn;
1018  f.proto = IPPROTO_TCP;
1019  f.flags |= FLOW_IPV4;
1020  f.alproto = ALPROTO_HTTP1;
1021 
1022  p1->flow = &f;
1026  p2->flow = &f;
1030 
1031  StreamTcpInitConfig(true);
1032 
1035  de_ctx->flags |= DE_QUIET;
1036 
1038  FAIL_IF_NULL(s);
1039 
1041  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1042 
1043  int r = AppLayerParserParse(
1044  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1045  FAIL_IF(r != 0);
1046 
1047  HtpState *http_state = f.alstate;
1048  FAIL_IF_NULL(http_state);
1049 
1050  /* do detect for p1 */
1051  SCLogDebug("inspecting p1");
1052  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1053 
1054  FAIL_IF(PacketAlertCheck(p1, 1));
1055 
1056  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1057  FAIL_IF(r != 0);
1058  /* do detect for p2 */
1059  SCLogDebug("inspecting p2");
1060  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1061 
1062  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1063 
1064  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1065  FAIL_IF(id == 0);
1066 
1067  FlowVar *fv = FlowVarGet(&f, id);
1068  FAIL_IF_NULL(fv);
1069 
1070  FAIL_IF(fv->data.fv_str.value_len != 1);
1071 
1072  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1073 
1076 
1077  StreamTcpFreeConfig(true);
1078  FLOW_DESTROY(&f);
1079  UTHFreePackets(&p1, 1);
1080  UTHFreePackets(&p2, 1);
1081  PASS;
1082 }
1083 
1084 /** \test payload buffer */
1085 static int LuaMatchTest02(void)
1086 {
1087  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1088  "function init (args)\n"
1089  " flowvarlib.register(\"cnt\")\n"
1090  " local needs = {}\n"
1091  " needs[\"payload\"] = tostring(true)\n"
1092  " return needs\n"
1093  "end\n"
1094  "function thread_init (args)\n"
1095  " cnt = flowvarlib.get(\"cnt\")\n"
1096  "end\n"
1097  "\n"
1098  "function match(args)\n"
1099  " a = cnt:value()\n"
1100  " if a then\n"
1101  " a = tostring(tonumber(a)+1)\n"
1102  " print (a)\n"
1103  " cnt:set(a, #a)\n"
1104  " else\n"
1105  " a = tostring(1)\n"
1106  " print (a)\n"
1107  " cnt:set(a, #a)\n"
1108  " end\n"
1109  " \n"
1110  " print (\"pre check: \" .. (a))\n"
1111  " if tonumber(a) == 2 then\n"
1112  " print \"match\"\n"
1113  " return 1\n"
1114  " end\n"
1115  " return 0\n"
1116  "end\n"
1117  "return 0\n";
1118  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1119  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1120  "Host: www.emergingthreats.net\r\n\r\n";
1121  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1122  "Host: www.openinfosecfoundation.org\r\n\r\n";
1123  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1124  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1125  TcpSession ssn;
1126  Flow f;
1127  ThreadVars th_v;
1128  DetectEngineThreadCtx *det_ctx;
1129 
1130  ut_script = script;
1131 
1132  memset(&th_v, 0, sizeof(th_v));
1133  memset(&f, 0, sizeof(f));
1134  memset(&ssn, 0, sizeof(ssn));
1135 
1136  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1137  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1138 
1139  FLOW_INITIALIZE(&f);
1140  f.protoctx = (void *)&ssn;
1141  f.proto = IPPROTO_TCP;
1142  f.flags |= FLOW_IPV4;
1143  f.alproto = ALPROTO_HTTP1;
1144 
1145  p1->flow = &f;
1149  p2->flow = &f;
1153 
1154  StreamTcpInitConfig(true);
1155 
1158  de_ctx->flags |= DE_QUIET;
1159 
1161  FAIL_IF_NULL(s);
1162 
1164  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1165 
1166  /* do detect for p1 */
1167  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1168 
1169  FAIL_IF(PacketAlertCheck(p1, 1));
1170 
1171  /* do detect for p2 */
1172  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1173 
1174  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1175 
1176  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1177  FAIL_IF(id == 0);
1178 
1179  FlowVar *fv = FlowVarGet(&f, id);
1180  FAIL_IF_NULL(fv);
1181 
1182  FAIL_IF(fv->data.fv_str.value_len != 1);
1183 
1184  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1185 
1187 
1188  StreamTcpFreeConfig(true);
1189  FLOW_DESTROY(&f);
1190  UTHFreePackets(&p1, 1);
1191  UTHFreePackets(&p2, 1);
1192  PASS;
1193 }
1194 
1195 /** \test payload buffer */
1196 static int LuaMatchTest02a(void)
1197 {
1198  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1199  "function init (args)\n"
1200  " flowvarlib.register(\"cnt\")"
1201  " local needs = {}\n"
1202  " needs[\"payload\"] = tostring(true)\n"
1203  " return needs\n"
1204  "end\n"
1205  "function thread_init (args)\n"
1206  " cnt = flowvarlib.get(\"cnt\")"
1207  "end\n"
1208  "\n"
1209  "function match(args)\n"
1210  " a = cnt:value()\n"
1211  " if a then\n"
1212  " a = tostring(tonumber(a)+1)\n"
1213  " print (a)\n"
1214  " cnt:set(a, #a)\n"
1215  " else\n"
1216  " a = tostring(1)\n"
1217  " print (a)\n"
1218  " cnt:set(a, #a)\n"
1219  " end\n"
1220  " \n"
1221  " print (\"pre check: \" .. (a))\n"
1222  " if tonumber(a) == 2 then\n"
1223  " print \"match\"\n"
1224  " return 1\n"
1225  " end\n"
1226  " return 0\n"
1227  "end\n"
1228  "return 0\n";
1229  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1230  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1231  "Host: www.emergingthreats.net\r\n\r\n";
1232  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1233  "Host: www.openinfosecfoundation.org\r\n\r\n";
1234  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1235  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1236  TcpSession ssn;
1237  Flow f;
1238  ThreadVars th_v;
1239  DetectEngineThreadCtx *det_ctx;
1240 
1241  ut_script = script;
1242 
1243  memset(&th_v, 0, sizeof(th_v));
1244  memset(&f, 0, sizeof(f));
1245  memset(&ssn, 0, sizeof(ssn));
1246 
1247  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1248  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1249 
1250  FLOW_INITIALIZE(&f);
1251  f.protoctx = (void *)&ssn;
1252  f.proto = IPPROTO_TCP;
1253  f.flags |= FLOW_IPV4;
1254  f.alproto = ALPROTO_HTTP1;
1255 
1256  p1->flow = &f;
1260  p2->flow = &f;
1264 
1265  StreamTcpInitConfig(true);
1266 
1269  de_ctx->flags |= DE_QUIET;
1270 
1272  FAIL_IF_NULL(s);
1273 
1275  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1276 
1277  /* do detect for p1 */
1278  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1279  FAIL_IF(PacketAlertCheck(p1, 1));
1280 
1281  /* do detect for p2 */
1282  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1283 
1284  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1285 
1286  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1287  FAIL_IF(id == 0);
1288 
1289  FlowVar *fv = FlowVarGet(&f, id);
1290  FAIL_IF_NULL(fv);
1291 
1292  FAIL_IF(fv->data.fv_str.value_len != 1);
1293 
1294  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1295 
1297 
1298  StreamTcpFreeConfig(true);
1299  FLOW_DESTROY(&f);
1300  UTHFreePackets(&p1, 1);
1301  UTHFreePackets(&p2, 1);
1302  PASS;
1303 }
1304 
1305 /** \test packet buffer */
1306 static int LuaMatchTest03(void)
1307 {
1308  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1309  "function init (args)\n"
1310  " flowvarlib.register(\"cnt\")\n"
1311  " local needs = {}\n"
1312  " needs[\"packet\"] = tostring(true)\n"
1313  " return needs\n"
1314  "end\n"
1315  "\n"
1316  "function thread_init (args)\n"
1317  " cnt = flowvarlib.get(\"cnt\")\n"
1318  "end\n"
1319  "\n"
1320  "function match(args)\n"
1321  " a = cnt:value()\n"
1322  " if a then\n"
1323  " a = tostring(tonumber(a)+1)\n"
1324  " print (a)\n"
1325  " cnt:set(a, #a)\n"
1326  " else\n"
1327  " a = tostring(1)\n"
1328  " print (a)\n"
1329  " cnt:set(a, #a)\n"
1330  " end\n"
1331  " \n"
1332  " print (\"pre check: \" .. (a))\n"
1333  " if tonumber(a) == 2 then\n"
1334  " print \"match\"\n"
1335  " return 1\n"
1336  " end\n"
1337  " return 0\n"
1338  "end\n"
1339  "return 0\n";
1340  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1341  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1342  "Host: www.emergingthreats.net\r\n\r\n";
1343  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1344  "Host: www.openinfosecfoundation.org\r\n\r\n";
1345  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1346  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1347  TcpSession ssn;
1348  Flow f;
1349  ThreadVars th_v;
1350  DetectEngineThreadCtx *det_ctx;
1351 
1352  ut_script = script;
1353 
1354  memset(&th_v, 0, sizeof(th_v));
1355  memset(&f, 0, sizeof(f));
1356  memset(&ssn, 0, sizeof(ssn));
1357 
1358  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1359  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1360 
1361  FLOW_INITIALIZE(&f);
1362  f.protoctx = (void *)&ssn;
1363  f.proto = IPPROTO_TCP;
1364  f.flags |= FLOW_IPV4;
1365  f.alproto = ALPROTO_HTTP1;
1366 
1367  p1->flow = &f;
1371  p2->flow = &f;
1375 
1376  StreamTcpInitConfig(true);
1377 
1380  de_ctx->flags |= DE_QUIET;
1381 
1383  FAIL_IF_NULL(s);
1384 
1386  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1387 
1388  /* do detect for p1 */
1389  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1390  FAIL_IF(PacketAlertCheck(p1, 1));
1391 
1392  /* do detect for p2 */
1393  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1394 
1395  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1396 
1397  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1398  FAIL_IF(id == 0);
1399 
1400  FlowVar *fv = FlowVarGet(&f, id);
1401  FAIL_IF_NULL(fv);
1402 
1403  FAIL_IF(fv->data.fv_str.value_len != 1);
1404 
1405  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1406 
1408 
1409  StreamTcpFreeConfig(true);
1410  FLOW_DESTROY(&f);
1411  UTHFreePackets(&p1, 1);
1412  UTHFreePackets(&p2, 1);
1413  PASS;
1414 }
1415 
1416 /** \test packet buffer */
1417 static int LuaMatchTest03a(void)
1418 {
1419  const char script[] = "local flowvarlib = require(\"suricata.flowvar\")\n"
1420  "function init (args)\n"
1421  " flowvarlib.register(\"cnt\")\n"
1422  " local needs = {}\n"
1423  " needs[\"packet\"] = tostring(true)\n"
1424  " return needs\n"
1425  "end\n"
1426  "\n"
1427  "function thread_init (args)\n"
1428  " cnt = flowvarlib.get(\"cnt\")\n"
1429  "end\n"
1430  "\n"
1431  "function match(args)\n"
1432  " a = cnt:value()\n"
1433  " if a then\n"
1434  " a = tostring(tonumber(a)+1)\n"
1435  " print (a)\n"
1436  " cnt:set(a, #a)\n"
1437  " else\n"
1438  " a = tostring(1)\n"
1439  " print (a)\n"
1440  " cnt:set(a, #a)\n"
1441  " end\n"
1442  " \n"
1443  " print (\"pre check: \" .. (a))\n"
1444  " if tonumber(a) == 2 then\n"
1445  " print \"match\"\n"
1446  " return 1\n"
1447  " end\n"
1448  " return 0\n"
1449  "end\n"
1450  "return 0\n";
1451  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1452  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1453  "Host: www.emergingthreats.net\r\n\r\n";
1454  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1455  "Host: www.openinfosecfoundation.org\r\n\r\n";
1456  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1457  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1458  TcpSession ssn;
1459  Flow f;
1460  ThreadVars th_v;
1461  DetectEngineThreadCtx *det_ctx;
1462 
1463  ut_script = script;
1464 
1465  memset(&th_v, 0, sizeof(th_v));
1466  memset(&f, 0, sizeof(f));
1467  memset(&ssn, 0, sizeof(ssn));
1468 
1469  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1470  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1471 
1472  FLOW_INITIALIZE(&f);
1473  f.protoctx = (void *)&ssn;
1474  f.proto = IPPROTO_TCP;
1475  f.flags |= FLOW_IPV4;
1476  f.alproto = ALPROTO_HTTP1;
1477 
1478  p1->flow = &f;
1482  p2->flow = &f;
1486 
1487  StreamTcpInitConfig(true);
1488 
1491  de_ctx->flags |= DE_QUIET;
1492 
1494  FAIL_IF_NULL(s);
1495 
1497  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1498 
1499  /* do detect for p1 */
1500  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1501  FAIL_IF(PacketAlertCheck(p1, 1));
1502 
1503  /* do detect for p2 */
1504  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1505  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1506 
1507  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1508  FAIL_IF(id == 0);
1509 
1510  FlowVar *fv = FlowVarGet(&f, id);
1511  FAIL_IF_NULL(fv);
1512 
1513  FAIL_IF(fv->data.fv_str.value_len != 1);
1514 
1515  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1516 
1518 
1519  StreamTcpFreeConfig(true);
1520  FLOW_DESTROY(&f);
1521  UTHFreePackets(&p1, 1);
1522  UTHFreePackets(&p2, 1);
1523  PASS;
1524 }
1525 
1526 /** \test http buffer, flowints */
1527 static int LuaMatchTest04(void)
1528 {
1529  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1530  "function init (args)\n"
1531  " flowintlib.register(\"cnt\")\n"
1532  " return {}\n"
1533  "end\n"
1534  "\n"
1535  "function thread_init (args)\n"
1536  " cnt = flowintlib.get(\"cnt\")\n"
1537  "end\n"
1538  "\n"
1539  "function match(args)\n"
1540  " print \"inspecting\""
1541  " a = cnt:value()\n"
1542  " if a then\n"
1543  " cnt:set(a + 1)\n"
1544  " else\n"
1545  " cnt:set(1)\n"
1546  " end\n"
1547  " \n"
1548  " a = cnt:value()\n"
1549  " if a == 2 then\n"
1550  " print \"match\"\n"
1551  " return 1\n"
1552  " end\n"
1553  " return 0\n"
1554  "end\n"
1555  "return 0\n";
1556  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1557  "sid:1;)";
1558  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1559  "Host: www.emergingthreats.net\r\n\r\n";
1560  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1561  "Host: www.openinfosecfoundation.org\r\n\r\n";
1562  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1563  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1564  TcpSession ssn;
1565  Flow f;
1566  ThreadVars th_v;
1567  DetectEngineThreadCtx *det_ctx;
1568 
1570 
1571  ut_script = script;
1572 
1573  memset(&th_v, 0, sizeof(th_v));
1574  memset(&f, 0, sizeof(f));
1575  memset(&ssn, 0, sizeof(ssn));
1576 
1577  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1578  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1579 
1580  FLOW_INITIALIZE(&f);
1581  f.protoctx = (void *)&ssn;
1582  f.proto = IPPROTO_TCP;
1583  f.flags |= FLOW_IPV4;
1584  f.alproto = ALPROTO_HTTP1;
1585 
1586  p1->flow = &f;
1590 
1591  p2->flow = &f;
1595 
1596  StreamTcpInitConfig(true);
1597 
1600  de_ctx->flags |= DE_QUIET;
1601 
1603  FAIL_IF_NULL(s);
1604 
1606  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1607 
1608  int r = AppLayerParserParse(
1609  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1610  FAIL_IF(r != 0);
1611  HtpState *http_state = f.alstate;
1612  FAIL_IF_NULL(http_state);
1613 
1614  /* do detect for p1 */
1615  SCLogInfo("p1");
1616  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1617 
1618  FAIL_IF(PacketAlertCheck(p1, 1));
1619 
1620  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1621  FAIL_IF(r != 0);
1622  /* do detect for p2 */
1623  SCLogInfo("p2");
1624  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1625 
1626  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1627 
1628  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1629  FAIL_IF(id == 0);
1630 
1631  FlowVar *fv = FlowVarGet(&f, id);
1632  FAIL_IF_NULL(fv);
1633 
1634  FAIL_IF(fv->data.fv_int.value != 2);
1635 
1638 
1639  StreamTcpFreeConfig(true);
1640  FLOW_DESTROY(&f);
1641  UTHFreePackets(&p1, 1);
1642  UTHFreePackets(&p2, 1);
1643  PASS;
1644 }
1645 
1646 /** \test http buffer, flowints */
1647 static int LuaMatchTest04a(void)
1648 {
1649  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1650  "function init (args)\n"
1651  " flowintlib.register(\"cnt\")\n"
1652  " return {}\n"
1653  "end\n"
1654  "\n"
1655  "function thread_init (args)\n"
1656  " cnt = flowintlib.get(\"cnt\")\n"
1657  "end\n"
1658  "\n"
1659  "function match(args)\n"
1660  " print \"inspecting\""
1661  " a = cnt:value()\n"
1662  " if a then\n"
1663  " cnt:set(a + 1)\n"
1664  " else\n"
1665  " cnt:set(1)\n"
1666  " end\n"
1667  " \n"
1668  " a = cnt:value()\n"
1669  " if a == 2 then\n"
1670  " print \"match\"\n"
1671  " return 1\n"
1672  " end\n"
1673  " return 0\n"
1674  "end\n"
1675  "return 0\n";
1676  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1677  "sid:1;)";
1678  uint8_t httpbuf1[] =
1679  "POST / HTTP/1.1\r\n"
1680  "Host: www.emergingthreats.net\r\n\r\n";
1681  uint8_t httpbuf2[] =
1682  "POST / HTTP/1.1\r\n"
1683  "Host: www.openinfosecfoundation.org\r\n\r\n";
1684  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1685  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1686  TcpSession ssn;
1687  Flow f;
1688  ThreadVars th_v;
1689  DetectEngineThreadCtx *det_ctx;
1690 
1692 
1693  ut_script = script;
1694 
1695  memset(&th_v, 0, sizeof(th_v));
1696  memset(&f, 0, sizeof(f));
1697  memset(&ssn, 0, sizeof(ssn));
1698 
1699  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1700  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1701 
1702  FLOW_INITIALIZE(&f);
1703  f.protoctx = (void *)&ssn;
1704  f.proto = IPPROTO_TCP;
1705  f.flags |= FLOW_IPV4;
1706  f.alproto = ALPROTO_HTTP1;
1707 
1708  p1->flow = &f;
1712 
1713  p2->flow = &f;
1717 
1718  StreamTcpInitConfig(true);
1719 
1722  de_ctx->flags |= DE_QUIET;
1723 
1725  FAIL_IF_NULL(s);
1726 
1728  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1729 
1730  int r = AppLayerParserParse(
1731  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1732  FAIL_IF(r != 0);
1733  HtpState *http_state = f.alstate;
1734  FAIL_IF_NULL(http_state);
1735 
1736  /* do detect for p1 */
1737  SCLogInfo("p1");
1738  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1739 
1740  FAIL_IF(PacketAlertCheck(p1, 1));
1741 
1742  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1743  FAIL_IF(r != 0);
1744  /* do detect for p2 */
1745  SCLogInfo("p2");
1746  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1747 
1748  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1749 
1750  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1751  FAIL_IF(id == 0);
1752 
1753  FlowVar *fv = FlowVarGet(&f, id);
1754  FAIL_IF_NULL(fv);
1755 
1756  FAIL_IF(fv->data.fv_int.value != 2);
1757 
1760 
1761  StreamTcpFreeConfig(true);
1762  FLOW_DESTROY(&f);
1763  UTHFreePackets(&p1, 1);
1764  UTHFreePackets(&p2, 1);
1765  PASS;
1766 }
1767 
1768 /** \test http buffer, flowints */
1769 static int LuaMatchTest05(void)
1770 {
1771  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1772  "function init (args)\n"
1773  " flowintlib.register(\"cnt\")\n"
1774  " return {}\n"
1775  "end\n"
1776  "\n"
1777  "function thread_init (args)\n"
1778  " cnt = flowintlib.get(\"cnt\")\n"
1779  "end\n"
1780  "\n"
1781  "function match(args)\n"
1782  " print \"inspecting\""
1783  " a = cnt:incr()\n"
1784  " if a == 2 then\n"
1785  " print \"match\"\n"
1786  " return 1\n"
1787  " end\n"
1788  " return 0\n"
1789  "end\n"
1790  "return 0\n";
1791  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1792  "sid:1;)";
1793  uint8_t httpbuf1[] =
1794  "POST / HTTP/1.1\r\n"
1795  "Host: www.emergingthreats.net\r\n\r\n";
1796  uint8_t httpbuf2[] =
1797  "POST / HTTP/1.1\r\n"
1798  "Host: www.openinfosecfoundation.org\r\n\r\n";
1799  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1800  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1801  TcpSession ssn;
1802  Flow f;
1803  ThreadVars th_v;
1804  DetectEngineThreadCtx *det_ctx;
1805 
1807 
1808  ut_script = script;
1809 
1810  memset(&th_v, 0, sizeof(th_v));
1811  memset(&f, 0, sizeof(f));
1812  memset(&ssn, 0, sizeof(ssn));
1813 
1814  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1815  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1816 
1817  FLOW_INITIALIZE(&f);
1818  f.protoctx = (void *)&ssn;
1819  f.proto = IPPROTO_TCP;
1820  f.flags |= FLOW_IPV4;
1821  f.alproto = ALPROTO_HTTP1;
1822 
1823  p1->flow = &f;
1827 
1828  p2->flow = &f;
1832 
1833  StreamTcpInitConfig(true);
1834 
1837  de_ctx->flags |= DE_QUIET;
1838 
1840  FAIL_IF_NULL(s);
1841 
1843  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1844 
1845  int r = AppLayerParserParse(
1846  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1847  FAIL_IF(r != 0);
1848  HtpState *http_state = f.alstate;
1849  FAIL_IF_NULL(http_state);
1850 
1851  /* do detect for p1 */
1852  SCLogInfo("p1");
1853  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1854 
1855  FAIL_IF(PacketAlertCheck(p1, 1));
1856 
1857  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1858  FAIL_IF(r != 0);
1859  /* do detect for p2 */
1860  SCLogInfo("p2");
1861  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1862 
1863  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1864 
1865  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1866  FAIL_IF(id == 0);
1867 
1868  FlowVar *fv = FlowVarGet(&f, id);
1869  FAIL_IF_NULL(fv);
1870 
1871  FAIL_IF(fv->data.fv_int.value != 2);
1872 
1875 
1876  StreamTcpFreeConfig(true);
1877  FLOW_DESTROY(&f);
1878  UTHFreePackets(&p1, 1);
1879  UTHFreePackets(&p2, 1);
1880  PASS;
1881 }
1882 
1883 /** \test http buffer, flowints */
1884 static int LuaMatchTest05a(void)
1885 {
1886  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
1887  "function init (args)\n"
1888  " flowintlib.register(\"cnt\")\n"
1889  " return {}\n"
1890  "end\n"
1891  "\n"
1892  "function thread_init (args)\n"
1893  " cnt = flowintlib.get(\"cnt\")\n"
1894  "end\n"
1895  "\n"
1896  "function match(args)\n"
1897  " print \"inspecting\""
1898  " a = cnt:incr()\n"
1899  " if a == 2 then\n"
1900  " print \"match\"\n"
1901  " return 1\n"
1902  " end\n"
1903  " return 0\n"
1904  "end\n"
1905  "return 0\n";
1906  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
1907  "sid:1;)";
1908  uint8_t httpbuf1[] =
1909  "POST / HTTP/1.1\r\n"
1910  "Host: www.emergingthreats.net\r\n\r\n";
1911  uint8_t httpbuf2[] =
1912  "POST / HTTP/1.1\r\n"
1913  "Host: www.openinfosecfoundation.org\r\n\r\n";
1914  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1915  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1916  TcpSession ssn;
1917  Flow f;
1918  ThreadVars th_v;
1919  DetectEngineThreadCtx *det_ctx;
1920 
1922 
1923  ut_script = script;
1924 
1925  memset(&th_v, 0, sizeof(th_v));
1926  memset(&f, 0, sizeof(f));
1927  memset(&ssn, 0, sizeof(ssn));
1928 
1929  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1930  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1931 
1932  FLOW_INITIALIZE(&f);
1933  f.protoctx = (void *)&ssn;
1934  f.proto = IPPROTO_TCP;
1935  f.flags |= FLOW_IPV4;
1936  f.alproto = ALPROTO_HTTP1;
1937 
1938  p1->flow = &f;
1942 
1943  p2->flow = &f;
1947 
1948  StreamTcpInitConfig(true);
1949 
1952  de_ctx->flags |= DE_QUIET;
1953 
1955  FAIL_IF_NULL(s);
1956 
1958  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1959 
1960  int r = AppLayerParserParse(
1961  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1962  FAIL_IF(r != 0);
1963  HtpState *http_state = f.alstate;
1964  FAIL_IF_NULL(http_state);
1965 
1966  /* do detect for p1 */
1967  SCLogInfo("p1");
1968  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1969 
1970  FAIL_IF(PacketAlertCheck(p1, 1));
1971 
1972  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1973  FAIL_IF(r != 0);
1974  /* do detect for p2 */
1975  SCLogInfo("p2");
1976  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1977 
1978  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1979 
1980  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1981  FAIL_IF(id == 0);
1982 
1983  FlowVar *fv = FlowVarGet(&f, id);
1984  FAIL_IF_NULL(fv);
1985 
1986  FAIL_IF(fv->data.fv_int.value != 2);
1987 
1990 
1991  StreamTcpFreeConfig(true);
1992  FLOW_DESTROY(&f);
1993  UTHFreePackets(&p1, 1);
1994  UTHFreePackets(&p2, 1);
1995  PASS;
1996 }
1997 
1998 /** \test http buffer, flowints */
1999 static int LuaMatchTest06(void)
2000 {
2001  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2002  "function init (args)\n"
2003  " flowintlib.register(\"cnt\")\n"
2004  " return {}\n"
2005  "end\n"
2006  "\n"
2007  "function thread_init (args)\n"
2008  " cnt = flowintlib.get(\"cnt\")\n"
2009  "end\n"
2010  "\n"
2011  "function match(args)\n"
2012  " print \"inspecting\""
2013  " a = cnt:value()\n"
2014  " if a == nil then\n"
2015  " print \"new var set to 2\""
2016  " cnt:set(2)\n"
2017  " end\n"
2018  " a = cnt:decr()\n"
2019  " if a == 0 then\n"
2020  " print \"match\"\n"
2021  " return 1\n"
2022  " end\n"
2023  " return 0\n"
2024  "end\n"
2025  "return 0\n";
2026  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2027  "sid:1;)";
2028  uint8_t httpbuf1[] =
2029  "POST / HTTP/1.1\r\n"
2030  "Host: www.emergingthreats.net\r\n\r\n";
2031  uint8_t httpbuf2[] =
2032  "POST / HTTP/1.1\r\n"
2033  "Host: www.openinfosecfoundation.org\r\n\r\n";
2034  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2035  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2036  TcpSession ssn;
2037  Flow f;
2038  ThreadVars th_v;
2039  DetectEngineThreadCtx *det_ctx;
2040 
2042 
2043  ut_script = script;
2044 
2045  memset(&th_v, 0, sizeof(th_v));
2046  memset(&f, 0, sizeof(f));
2047  memset(&ssn, 0, sizeof(ssn));
2048 
2049  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2050  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2051 
2052  FLOW_INITIALIZE(&f);
2053  f.protoctx = (void *)&ssn;
2054  f.proto = IPPROTO_TCP;
2055  f.flags |= FLOW_IPV4;
2056  f.alproto = ALPROTO_HTTP1;
2057 
2058  p1->flow = &f;
2062 
2063  p2->flow = &f;
2067 
2068  StreamTcpInitConfig(true);
2069 
2072  de_ctx->flags |= DE_QUIET;
2073 
2075  FAIL_IF_NULL(s);
2076 
2078  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2079 
2080  int r = AppLayerParserParse(
2081  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2082  FAIL_IF(r != 0);
2083  HtpState *http_state = f.alstate;
2084  FAIL_IF_NULL(http_state);
2085 
2086  /* do detect for p1 */
2087  SCLogInfo("p1");
2088  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2089 
2090  FAIL_IF(PacketAlertCheck(p1, 1));
2091 
2092  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2093  FAIL_IF(r != 0);
2094  /* do detect for p2 */
2095  SCLogInfo("p2");
2096  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2097 
2098  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2099 
2100  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2101  FAIL_IF(id == 0);
2102 
2103  FlowVar *fv = FlowVarGet(&f, id);
2104  FAIL_IF_NULL(fv);
2105 
2106  FAIL_IF(fv->data.fv_int.value != 0);
2107 
2110 
2111  StreamTcpFreeConfig(true);
2112  FLOW_DESTROY(&f);
2113  UTHFreePackets(&p1, 1);
2114  UTHFreePackets(&p2, 1);
2115  PASS;
2116 }
2117 
2118 /** \test http buffer, flowints */
2119 static int LuaMatchTest06a(void)
2120 {
2121  const char script[] = "local flowintlib = require(\"suricata.flowint\")\n"
2122  "function init (args)\n"
2123  " flowintlib.register(\"cnt\")\n"
2124  " return {}\n"
2125  "end\n"
2126  "\n"
2127  "function thread_init (args)\n"
2128  " cnt = flowintlib.get(\"cnt\")\n"
2129  "end\n"
2130  "\n"
2131  "function match(args)\n"
2132  " print \"inspecting\""
2133  " a = cnt:value()\n"
2134  " if a == nil then\n"
2135  " print \"new var set to 2\""
2136  " cnt:set(2)\n"
2137  " end\n"
2138  " a = cnt:decr()\n"
2139  " if a == 0 then\n"
2140  " print \"match\"\n"
2141  " return 1\n"
2142  " end\n"
2143  " return 0\n"
2144  "end\n"
2145  "return 0\n";
2146  char sig[] = "alert http1:request_complete any any -> any any (flow:to_server; lua:unittest; "
2147  "sid:1;)";
2148  uint8_t httpbuf1[] =
2149  "POST / HTTP/1.1\r\n"
2150  "Host: www.emergingthreats.net\r\n\r\n";
2151  uint8_t httpbuf2[] =
2152  "POST / HTTP/1.1\r\n"
2153  "Host: www.openinfosecfoundation.org\r\n\r\n";
2154  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2155  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2156  TcpSession ssn;
2157  Flow f;
2158  ThreadVars th_v;
2159  DetectEngineThreadCtx *det_ctx;
2160 
2162 
2163  ut_script = script;
2164 
2165  memset(&th_v, 0, sizeof(th_v));
2166  memset(&f, 0, sizeof(f));
2167  memset(&ssn, 0, sizeof(ssn));
2168 
2169  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2170  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2171 
2172  FLOW_INITIALIZE(&f);
2173  f.protoctx = (void *)&ssn;
2174  f.proto = IPPROTO_TCP;
2175  f.flags |= FLOW_IPV4;
2176  f.alproto = ALPROTO_HTTP1;
2177 
2178  p1->flow = &f;
2182 
2183  p2->flow = &f;
2187 
2188  StreamTcpInitConfig(true);
2189 
2192  de_ctx->flags |= DE_QUIET;
2193 
2195  FAIL_IF_NULL(s);
2196 
2198  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2199 
2200  int r = AppLayerParserParse(
2201  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2202  FAIL_IF(r != 0);
2203  HtpState *http_state = f.alstate;
2204  FAIL_IF_NULL(http_state);
2205 
2206  /* do detect for p1 */
2207  SCLogInfo("p1");
2208  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2209 
2210  FAIL_IF(PacketAlertCheck(p1, 1));
2211 
2212  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2213  FAIL_IF(r != 0);
2214  /* do detect for p2 */
2215  SCLogInfo("p2");
2216  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2217 
2218  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2219 
2220  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2221  FAIL_IF(id == 0);
2222 
2223  FlowVar *fv = FlowVarGet(&f, id);
2224  FAIL_IF_NULL(fv);
2225 
2226  FAIL_IF(fv->data.fv_int.value != 0);
2227 
2230 
2231  StreamTcpFreeConfig(true);
2232  FLOW_DESTROY(&f);
2233  UTHFreePackets(&p1, 1);
2234  UTHFreePackets(&p2, 1);
2235  PASS;
2236 }
2237 
2238 void DetectLuaRegisterTests(void)
2239 {
2240  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2241  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2242  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2243  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2244  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2245  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2246  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2247  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2248  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2249  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2250  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2251  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2252 }
2253 #endif
FLAG_MEMORY_LIMIT_LOGGED
#define FLAG_MEMORY_LIMIT_LOGGED
Definition: detect-lua.c:120
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:1431
SCLuaSbState::memory_limit_error
bool memory_limit_error
Definition: util-lua-sandbox.h:56
detect-engine.h
LuaStateSetThreadVars
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv)
Definition: util-lua.c:110
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
SigTableElmt_::desc
const char * desc
Definition: detect.h:1430
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:155
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1250
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1418
SignatureHook_::sm_list
int sm_list
Definition: detect.h:575
FLAG_BLOCKED_FUNCTION_LOGGED
#define FLAG_BLOCKED_FUNCTION_LOGGED
Definition: detect-lua.c:118
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1428
stream-tcp.h
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3753
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:269
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:368
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:119
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:931
DetectEngineThreadCtx_::lua_blocked_function_errors
uint16_t lua_blocked_function_errors
Definition: detect.h:1354
DEFAULT_LUA_INSTRUCTION_LIMIT
#define DEFAULT_LUA_INSTRUCTION_LIMIT
Definition: detect-lua.c:123
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:58
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2674
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1399
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:329
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:2347
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:3439
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:523
DetectEngineThreadCtx_::lua_instruction_limit_errors
uint16_t lua_instruction_limit_errors
Definition: detect.h:1357
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:271
Flow_::protoctx
void * protoctx
Definition: flow.h:441
SigMatchData_
Data needed for Match()
Definition: detect.h:365
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1413
FLAG_DATATYPE_PACKET
#define FLAG_DATATYPE_PACKET
Definition: detect-lua.c:111
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:1351
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:270
app-layer-htp.h
FLAG_LIST_JA3S
#define FLAG_LIST_JA3S
Definition: detect-lua.c:115
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:1223
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:630
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
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:3400
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:112
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
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:271
SignatureInitData_::hook
SignatureHook hook
Definition: detect.h:592
SIGNATURE_HOOK_TYPE_NOT_SET
@ SIGNATURE_HOOK_TYPE_NOT_SET
Definition: detect.h:559
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:1360
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:113
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:117
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:749
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1396
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:73
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:90
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
LuaDumpStack
void LuaDumpStack(lua_State *state, const char *prefix)
dump stack from lua state to screen
Definition: detect-lua.c:126
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:2129
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:351
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:1093
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:3683
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:122
SignatureHook_::type
enum SignatureHookType type
Definition: detect.h:574
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:2060
DetectLuaData::flowvars
uint16_t flowvars
Definition: detect-lua.h:47
luaext_key_ld
const char luaext_key_ld[]
Definition: detect-lua-extensions.c:47
str
#define str(s)
Definition: suricata-common.h:308
DetectEngineThreadCtx_::tv
ThreadVars * tv
Definition: detect.h:1231
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
FLAG_DATATYPE_BUFFER
#define FLAG_DATATYPE_BUFFER
Definition: detect-lua.c:116
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:670
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:2635
LuaRegisterExtensions
int LuaRegisterExtensions(lua_State *lua_state)
Register Suricata Lua functions.
Definition: detect-lua-extensions.c:117
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:245
SCLuaSbStateNew
lua_State * SCLuaSbStateNew(uint64_t alloclimit, uint64_t instructionlimit)
Allocate a new Lua sandbox.
Definition: util-lua-sandbox.c:319
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:464
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:933
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:3735
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:275
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:1247
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1420
FlowVar_::data
union FlowVar_::@113 data
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:114