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-mpm.h"
35 #include "detect-engine-build.h"
36 
37 #include "detect-byte.h"
38 
39 #include "flow.h"
40 #include "flow-var.h"
41 #include "flow-util.h"
42 
43 #include "util-byte.h"
44 
45 #include "util-unittest.h"
46 #include "util-unittest-helper.h"
47 
48 #include "app-layer.h"
49 #include "app-layer-parser.h"
50 #include "app-layer-htp.h"
51 
52 #include "stream-tcp.h"
53 
54 #include "detect-lua.h"
55 #include "detect-lua-extensions.h"
56 
57 #include "util-var-name.h"
58 
59 #include "util-lua.h"
60 #include "util-lua-builtins.h"
61 #include "util-lua-sandbox.h"
62 
63 static int DetectLuaMatch (DetectEngineThreadCtx *,
64  Packet *, const Signature *, const SigMatchCtx *);
65 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
66  Flow *f, uint8_t flags,
67  void *state, void *txv, const Signature *s,
68  const SigMatchCtx *ctx);
69 static int DetectLuaSetup (DetectEngineCtx *, Signature *, const char *);
70 #ifdef UNITTESTS
71 static void DetectLuaRegisterTests(void);
72 #endif
73 static void DetectLuaFree(DetectEngineCtx *, void *);
74 static int g_smtp_generic_list_id = 0;
75 
76 /**
77  * \brief Registration function for keyword: lua
78  */
80 {
82  sigmatch_table[DETECT_LUA].desc = "match via a lua script";
83  sigmatch_table[DETECT_LUA].url = "/rules/rule-lua-scripting.html";
84  sigmatch_table[DETECT_LUA].Match = DetectLuaMatch;
85  sigmatch_table[DETECT_LUA].AppLayerTxMatch = DetectLuaAppTxMatch;
86  sigmatch_table[DETECT_LUA].Setup = DetectLuaSetup;
87  sigmatch_table[DETECT_LUA].Free = DetectLuaFree;
88 #ifdef UNITTESTS
89  sigmatch_table[DETECT_LUA].RegisterTests = DetectLuaRegisterTests;
90 #endif
91  g_smtp_generic_list_id = DetectBufferTypeRegister("smtp_generic");
92 
97 
98  SCLogDebug("registering lua rule option");
99 }
100 
101 /* Flags for DetectLuaThreadData. */
102 #define FLAG_DATATYPE_PACKET BIT_U32(0)
103 #define FLAG_DATATYPE_PAYLOAD BIT_U32(1)
104 #define FLAG_DATATYPE_STREAM BIT_U32(2)
105 #define FLAG_DATATYPE_HTTP_URI BIT_U32(3)
106 #define FLAG_DATATYPE_HTTP_URI_RAW BIT_U32(4)
107 #define FLAG_DATATYPE_HTTP_REQUEST_HEADERS BIT_U32(5)
108 #define FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW BIT_U32(6)
109 #define FLAG_DATATYPE_HTTP_REQUEST_COOKIE BIT_U32(7)
110 #define FLAG_DATATYPE_HTTP_REQUEST_UA BIT_U32(8)
111 #define FLAG_DATATYPE_HTTP_REQUEST_LINE BIT_U32(9)
112 #define FLAG_DATATYPE_HTTP_REQUEST_BODY BIT_U32(10)
113 #define FLAG_DATATYPE_HTTP_RESPONSE_COOKIE BIT_U32(11)
114 #define FLAG_DATATYPE_HTTP_RESPONSE_BODY BIT_U32(12)
115 #define FLAG_DATATYPE_HTTP_RESPONSE_HEADERS BIT_U32(13)
116 #define FLAG_DATATYPE_HTTP_RESPONSE_HEADERS_RAW BIT_U32(14)
117 #define FLAG_DATATYPE_DNS_REQUEST BIT_U32(16)
118 #define FLAG_DATATYPE_DNS_RESPONSE BIT_U32(17)
119 #define FLAG_DATATYPE_SSH BIT_U32(19)
120 #define FLAG_DATATYPE_SMTP BIT_U32(20)
121 #define FLAG_DATATYPE_DNP3 BIT_U32(21)
122 #define FLAG_DATATYPE_BUFFER BIT_U32(22)
123 #define FLAG_ERROR_LOGGED BIT_U32(23)
124 #define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
125 #define FLAG_INSTRUCTION_LIMIT_LOGGED BIT_U32(25)
126 #define FLAG_MEMORY_LIMIT_LOGGED BIT_U32(26)
127 
128 #define DEFAULT_LUA_ALLOC_LIMIT 500000
129 #define DEFAULT_LUA_INSTRUCTION_LIMIT 500000
130 
131 /** \brief dump stack from lua state to screen */
132 void LuaDumpStack(lua_State *state, const char *prefix)
133 {
134  int size = lua_gettop(state);
135  printf("%s: size %d\n", prefix, size);
136 
137  for (int i = 1; i <= size; i++) {
138  int type = lua_type(state, i);
139  printf("- %s: Stack size=%d, level=%d, type=%d, ", prefix, size, i, type);
140 
141  switch (type) {
142  case LUA_TFUNCTION:
143  printf("function %s", lua_tostring(state, i));
144  break;
145  case LUA_TBOOLEAN:
146  printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
147  break;
148  case LUA_TNUMBER:
149  printf("number %g", lua_tonumber(state, i));
150  break;
151  case LUA_TSTRING:
152  printf("string `%s'", lua_tostring(state, i));
153  break;
154  case LUA_TTABLE:
155  printf("table `%s'", lua_tostring(state, i));
156  break;
157  default:
158  printf("other %s", lua_typename(state, type));
159  break;
160 
161  }
162  printf("\n");
163  }
164 }
165 
166 /**
167  * \brief Common function to run the Lua match function and process
168  * the return value.
169  */
170 static int DetectLuaRunMatch(
171  DetectEngineThreadCtx *det_ctx, const DetectLuaData *lua, DetectLuaThreadData *tlua)
172 {
173  /* Reset instruction count. */
175 
176  if (lua_pcall(tlua->luastate, 1, 1, 0) != 0) {
177  const char *reason = lua_tostring(tlua->luastate, -1);
178  SCLuaSbState *context = SCLuaSbGetContext(tlua->luastate);
179  uint32_t flag = 0;
180  if (context->blocked_function_error) {
181  StatsIncr(det_ctx->tv, det_ctx->lua_blocked_function_errors);
183  } else if (context->instruction_count_error) {
184  StatsIncr(det_ctx->tv, det_ctx->lua_instruction_limit_errors);
186  } else if (context->memory_limit_error) {
187  StatsIncr(det_ctx->tv, det_ctx->lua_memory_limit_errors);
188  reason = "memory limit exceeded";
190  } else {
191  flag = FLAG_ERROR_LOGGED;
192  }
193 
194  /* Log once per thread per error type, the message from Lua
195  * will include the filename. */
196  if (!(tlua->flags & flag)) {
197  SCLogWarning("Lua script failed to run successfully: %s", reason);
198  tlua->flags |= flag;
199  }
200 
201  StatsIncr(det_ctx->tv, det_ctx->lua_rule_errors);
202  while (lua_gettop(tlua->luastate) > 0) {
203  lua_pop(tlua->luastate, 1);
204  }
205  SCReturnInt(0);
206  }
207 
208  int match = 0;
209 
210  /* process returns from script */
211  if (lua_gettop(tlua->luastate) > 0) {
212  /* script returns a number (return 1 or return 0) */
213  if (lua_type(tlua->luastate, 1) == LUA_TNUMBER) {
214  double script_ret = lua_tonumber(tlua->luastate, 1);
215  SCLogDebug("script_ret %f", script_ret);
216  lua_pop(tlua->luastate, 1);
217 
218  if (script_ret == 1.0)
219  match = 1;
220 
221  /* script returns a table */
222  } else if (lua_type(tlua->luastate, 1) == LUA_TTABLE) {
223  lua_pushnil(tlua->luastate);
224  const char *k, *v;
225  while (lua_next(tlua->luastate, -2)) {
226  v = lua_tostring(tlua->luastate, -1);
227  lua_pop(tlua->luastate, 1);
228  k = lua_tostring(tlua->luastate, -1);
229 
230  if (!k || !v)
231  continue;
232 
233  SCLogDebug("k='%s', v='%s'", k, v);
234 
235  if (strcmp(k, "retval") == 0) {
236  int val;
237  if (StringParseInt32(&val, 10, 0, (const char *)v) < 0) {
238  SCLogError("Invalid value "
239  "for \"retval\" from LUA return table: '%s'",
240  v);
241  match = 0;
242  }
243  else if (val == 1) {
244  match = 1;
245  }
246  } else {
247  /* set flow var? */
248  }
249  }
250 
251  /* pop the table */
252  lua_pop(tlua->luastate, 1);
253  }
254  }
255 
256  if (lua->negated) {
257  if (match == 1)
258  match = 0;
259  else
260  match = 1;
261  }
262 
263  while (lua_gettop(tlua->luastate) > 0) {
264  lua_pop(tlua->luastate, 1);
265  }
266 
267  SCReturnInt(match);
268 }
269 
271  const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset,
272  Flow *f)
273 {
274  SCEnter();
275 
276  if (buffer == NULL || buffer_len == 0)
277  SCReturnInt(0);
278 
279  DetectLuaData *lua = (DetectLuaData *)smd->ctx;
280  if (lua == NULL)
281  SCReturnInt(0);
282 
283  DetectLuaThreadData *tlua =
285  if (tlua == NULL)
286  SCReturnInt(0);
287 
288  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
289 
290  /* prepare data to pass to script */
291  lua_getglobal(tlua->luastate, "match");
292  lua_newtable(tlua->luastate); /* stack at -1 */
293 
294  lua_pushliteral(tlua->luastate, "offset"); /* stack at -2 */
295  lua_pushnumber(tlua->luastate, (int)(offset + 1));
296  lua_settable(tlua->luastate, -3);
297 
298  lua_pushstring(tlua->luastate, lua->buffername); /* stack at -2 */
299  LuaPushStringBuffer(tlua->luastate, (const uint8_t *)buffer, (size_t)buffer_len);
300  lua_settable(tlua->luastate, -3);
301 
302  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
303 }
304 
305 /**
306  * \brief match the specified lua script
307  *
308  * \param t thread local vars
309  * \param det_ctx pattern matcher thread local data
310  * \param p packet
311  * \param s signature being inspected
312  * \param m sigmatch that we will cast into DetectLuaData
313  *
314  * \retval 0 no match
315  * \retval 1 match
316  */
317 static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
318  Packet *p, const Signature *s, const SigMatchCtx *ctx)
319 {
320  SCEnter();
321  DetectLuaData *lua = (DetectLuaData *)ctx;
322  if (lua == NULL)
323  SCReturnInt(0);
324 
326  if (tlua == NULL)
327  SCReturnInt(0);
328 
329  /* setup extension data for use in lua c functions */
330  uint8_t flags = 0;
331  if (p->flowflags & FLOW_PKT_TOSERVER)
332  flags = STREAM_TOSERVER;
333  else if (p->flowflags & FLOW_PKT_TOCLIENT)
334  flags = STREAM_TOCLIENT;
335 
336  LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
337 
338  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
339 
340  if ((tlua->flags & FLAG_DATATYPE_PAYLOAD) && p->payload_len == 0)
341  SCReturnInt(0);
342  if ((tlua->flags & FLAG_DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
343  SCReturnInt(0);
344  if (tlua->alproto != ALPROTO_UNKNOWN) {
345  if (p->flow == NULL)
346  SCReturnInt(0);
347 
348  AppProto alproto = p->flow->alproto;
349  if (tlua->alproto != alproto)
350  SCReturnInt(0);
351  }
352 
353  lua_getglobal(tlua->luastate, "match");
354  lua_newtable(tlua->luastate); /* stack at -1 */
355 
356  if (tlua->alproto == ALPROTO_HTTP1) {
357  HtpState *htp_state = p->flow->alstate;
358  if (htp_state != NULL && htp_state->connp != NULL) {
359  htp_tx_t *tx = NULL;
361  STREAM_TOSERVER);
362  uint64_t total_txs= AppLayerParserGetTxCnt(p->flow, htp_state);
363  for ( ; idx < total_txs; idx++) {
364  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, idx);
365  if (tx == NULL)
366  continue;
367 
368  if ((tlua->flags & FLAG_DATATYPE_HTTP_REQUEST_LINE) &&
369  htp_tx_request_line(tx) != NULL && bstr_len(htp_tx_request_line(tx)) > 0) {
370  lua_pushliteral(tlua->luastate, "http.request_line"); /* stack at -2 */
372  (const uint8_t *)bstr_ptr(htp_tx_request_line(tx)),
373  bstr_len(htp_tx_request_line(tx)));
374  lua_settable(tlua->luastate, -3);
375  }
376  }
377  }
378  }
379 
380  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
381 }
382 
383 static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
384  Flow *f, uint8_t flags, void *state,
385  const Signature *s, const SigMatchCtx *ctx)
386 {
387  SCEnter();
388  DetectLuaData *lua = (DetectLuaData *)ctx;
389  if (lua == NULL)
390  SCReturnInt(0);
391 
393  if (tlua == NULL)
394  SCReturnInt(0);
395 
396  /* setup extension data for use in lua c functions */
397  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
398 
399  if (tlua->alproto != ALPROTO_UNKNOWN) {
400  int alproto = f->alproto;
401  if (tlua->alproto != alproto)
402  SCReturnInt(0);
403  }
404 
405  lua_getglobal(tlua->luastate, "match");
406  lua_newtable(tlua->luastate); /* stack at -1 */
407 
408  if (tlua->alproto == ALPROTO_HTTP1) {
409  HtpState *htp_state = state;
410  if (htp_state != NULL && htp_state->connp != NULL) {
411  htp_tx_t *tx = NULL;
412  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, det_ctx->tx_id);
413  if (tx != NULL) {
414  if ((tlua->flags & FLAG_DATATYPE_HTTP_REQUEST_LINE) &&
415  htp_tx_request_line(tx) != NULL && bstr_len(htp_tx_request_line(tx)) > 0) {
416  lua_pushliteral(tlua->luastate, "http.request_line"); /* stack at -2 */
418  (const uint8_t *)bstr_ptr(htp_tx_request_line(tx)),
419  bstr_len(htp_tx_request_line(tx)));
420  lua_settable(tlua->luastate, -3);
421  }
422  }
423  }
424  }
425 
426  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
427 }
428 
429 /**
430  * \brief match the specified lua script in a list with a tx
431  *
432  * \param t thread local vars
433  * \param det_ctx pattern matcher thread local data
434  * \param s signature being inspected
435  * \param m sigmatch that we will cast into DetectLuaData
436  *
437  * \retval 0 no match
438  * \retval 1 match
439  */
440 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
441  Flow *f, uint8_t flags,
442  void *state, void *txv, const Signature *s,
443  const SigMatchCtx *ctx)
444 {
445  return DetectLuaAppMatchCommon(det_ctx, f, flags, state, s, ctx);
446 }
447 
448 #ifdef UNITTESTS
449 /* if this ptr is set the lua setup functions will use this buffer as the
450  * lua script instead of calling luaL_loadfile on the filename supplied. */
451 static const char *ut_script = NULL;
452 #endif
453 
454 static void *DetectLuaThreadInit(void *data)
455 {
456  int status;
457  DetectLuaData *lua = (DetectLuaData *)data;
458  BUG_ON(lua == NULL);
459 
461  if (unlikely(t == NULL)) {
462  SCLogError("couldn't alloc ctx memory");
463  return NULL;
464  }
465 
466  t->alproto = lua->alproto;
467  t->flags = lua->flags;
468 
470  if (t->luastate == NULL) {
471  SCLogError("luastate pool depleted");
472  goto error;
473  }
474 
475  if (lua->allow_restricted_functions) {
476  luaL_openlibs(t->luastate);
478  } else {
480  }
481 
483 
484  lua_pushinteger(t->luastate, (lua_Integer)(lua->sid));
485  lua_setglobal(t->luastate, "SCRuleSid");
486  lua_pushinteger(t->luastate, (lua_Integer)(lua->rev));
487  lua_setglobal(t->luastate, "SCRuleRev");
488  lua_pushinteger(t->luastate, (lua_Integer)(lua->gid));
489  lua_setglobal(t->luastate, "SCRuleGid");
490 
491  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
492 #ifdef UNITTESTS
493  if (ut_script != NULL) {
494  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
495  if (status) {
496  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
497  goto error;
498  }
499  } else {
500 #endif
501  status = luaL_loadfile(t->luastate, lua->filename);
502  if (status) {
503  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
504  goto error;
505  }
506 #ifdef UNITTESTS
507  }
508 #endif
509 
510  /* prime the script (or something) */
511  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
512  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
513  goto error;
514  }
515 
516  /* thread_init call */
517  lua_getglobal(t->luastate, "thread_init");
518  if (lua_isfunction(t->luastate, -1)) {
519  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
520  SCLogError("couldn't run script 'thread_init' function: %s",
521  lua_tostring(t->luastate, -1));
522  goto error;
523  }
524  } else {
525  lua_pop(t->luastate, 1);
526  }
527 
528  return (void *)t;
529 
530 error:
531  if (t->luastate != NULL)
533  SCFree(t);
534  return NULL;
535 }
536 
537 static void DetectLuaThreadFree(void *ctx)
538 {
539  if (ctx != NULL) {
541  if (t->luastate != NULL)
543  SCFree(t);
544  }
545 }
546 
547 /**
548  * \brief Parse the lua keyword
549  *
550  * \param de_ctx Pointer to the detection engine context
551  * \param str Pointer to the user provided option
552  *
553  * \retval lua pointer to DetectLuaData on success
554  * \retval NULL on failure
555  */
556 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
557 {
558  DetectLuaData *lua = NULL;
559 
560  /* We have a correct lua option */
561  lua = SCCalloc(1, sizeof(DetectLuaData));
562  if (unlikely(lua == NULL))
563  goto error;
564 
565  if (strlen(str) && str[0] == '!') {
566  lua->negated = 1;
567  str++;
568  }
569 
570  /* get full filename */
572  if (lua->filename == NULL) {
573  goto error;
574  }
575 
576  return lua;
577 
578 error:
579  if (lua != NULL)
580  DetectLuaFree(de_ctx, lua);
581  return NULL;
582 }
583 
584 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
585 {
586  int status;
587 
589  if (luastate == NULL)
590  return -1;
591  if (ld->allow_restricted_functions) {
592  luaL_openlibs(luastate);
593  SCLuaRequirefBuiltIns(luastate);
594  } else {
595  SCLuaSbLoadLibs(luastate);
596  }
597 
598  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
599 #ifdef UNITTESTS
600  if (ut_script != NULL) {
601  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
602  if (status) {
603  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
604  goto error;
605  }
606  } else {
607 #endif
608  status = luaL_loadfile(luastate, ld->filename);
609  if (status) {
610  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
611  goto error;
612  }
613 #ifdef UNITTESTS
614  }
615 #endif
616 
617  /* prime the script (or something) */
618  if (lua_pcall(luastate, 0, 0, 0) != 0) {
619  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
620  goto error;
621  }
622 
623  lua_getglobal(luastate, "init");
624  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
625  SCLogError("no init function in script");
626  goto error;
627  }
628 
629  if (lua_pcall(luastate, 0, 1, 0) != 0) {
630  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
631  goto error;
632  }
633 
634  /* process returns from script */
635  if (lua_gettop(luastate) == 0) {
636  SCLogError("init function in script should return table, nothing returned");
637  goto error;
638  }
639  if (lua_type(luastate, 1) != LUA_TTABLE) {
640  SCLogError("init function in script should return table, returned is not table");
641  goto error;
642  }
643 
644  lua_pushnil(luastate);
645  const char *k;
646  while (lua_next(luastate, -2)) {
647  k = lua_tostring(luastate, -2);
648  if (k == NULL)
649  continue;
650 
651  /* handle flowvar and bytes separately as they have a table as value */
652  if (strcmp(k, "flowvar") == 0) {
653  if (lua_istable(luastate, -1)) {
654  lua_pushnil(luastate);
655  while (lua_next(luastate, -2) != 0) {
656  /* value at -1, key is at -2 which we ignore */
657  const char *value = lua_tostring(luastate, -1);
658  SCLogDebug("value %s", value);
659  /* removes 'value'; keeps 'key' for next iteration */
660  lua_pop(luastate, 1);
661 
662  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
663  SCLogError("too many flowvars registered");
664  goto error;
665  }
666 
667  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
668  ld->flowvar[ld->flowvars++] = idx;
669  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
670  }
671  }
672  lua_pop(luastate, 1);
673  continue;
674  } else if (strcmp(k, "flowint") == 0) {
675  if (lua_istable(luastate, -1)) {
676  lua_pushnil(luastate);
677  while (lua_next(luastate, -2) != 0) {
678  /* value at -1, key is at -2 which we ignore */
679  const char *value = lua_tostring(luastate, -1);
680  SCLogDebug("value %s", value);
681  /* removes 'value'; keeps 'key' for next iteration */
682  lua_pop(luastate, 1);
683 
684  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
685  SCLogError("too many flowints registered");
686  goto error;
687  }
688 
689  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
690  ld->flowint[ld->flowints++] = idx;
691  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
692  }
693  }
694  lua_pop(luastate, 1);
695  continue;
696  } else if (strcmp(k, "bytevar") == 0) {
697  if (lua_istable(luastate, -1)) {
698  lua_pushnil(luastate);
699  while (lua_next(luastate, -2) != 0) {
700  /* value at -1, key is at -2 which we ignore */
701  const char *value = lua_tostring(luastate, -1);
702  SCLogDebug("value %s", value);
703  /* removes 'value'; keeps 'key' for next iteration */
704  lua_pop(luastate, 1);
705 
706  if (ld->bytevars == DETECT_LUA_MAX_BYTEVARS) {
707  SCLogError("too many bytevars registered");
708  goto error;
709  }
710 
712  if (!DetectByteRetrieveSMVar(value, s, &idx)) {
713  SCLogError("Unknown byte_extract or byte_math var "
714  "requested by lua script - %s",
715  value);
716  goto error;
717  }
718  ld->bytevar[ld->bytevars++] = idx;
719  SCLogDebug("script uses bytevar %u with script id %u", idx, ld->bytevars - 1);
720  }
721  }
722  lua_pop(luastate, 1);
723  continue;
724  }
725 
726  bool required = lua_toboolean(luastate, -1);
727  lua_pop(luastate, 1);
728  if (!required) {
729  continue;
730  }
731 
732  if (strcmp(k, "packet") == 0) {
734  } else if (strcmp(k, "payload") == 0) {
736  } else if (strcmp(k, "buffer") == 0) {
738 
739  ld->buffername = SCStrdup("buffer");
740  if (ld->buffername == NULL) {
741  SCLogError("alloc error");
742  goto error;
743  }
744  } else if (strcmp(k, "stream") == 0) {
746 
747  ld->buffername = SCStrdup("stream");
748  if (ld->buffername == NULL) {
749  SCLogError("alloc error");
750  goto error;
751  }
752 
753  } else if (strncmp(k, "http", 4) == 0) {
754  if (ld->alproto != ALPROTO_UNKNOWN && ld->alproto != ALPROTO_HTTP1) {
755  SCLogError(
756  "can just inspect script against one app layer proto like HTTP at a time");
757  goto error;
758  }
759  if (ld->flags != 0) {
760  SCLogError("when inspecting HTTP buffers only a single buffer can be inspected");
761  goto error;
762  }
763 
764  /* http types */
765  ld->alproto = ALPROTO_HTTP1;
766 
767  if (strcmp(k, "http.uri") == 0)
769 
770  else if (strcmp(k, "http.uri.raw") == 0)
772 
773  else if (strcmp(k, "http.request_line") == 0)
775 
776  else if (strcmp(k, "http.request_headers") == 0)
778 
779  else if (strcmp(k, "http.request_headers.raw") == 0)
781 
782  else if (strcmp(k, "http.request_cookie") == 0)
784 
785  else if (strcmp(k, "http.request_user_agent") == 0)
787 
788  else if (strcmp(k, "http.request_body") == 0)
790 
791  else if (strcmp(k, "http.response_body") == 0)
793 
794  else if (strcmp(k, "http.response_cookie") == 0)
796 
797  else if (strcmp(k, "http.response_headers") == 0)
799 
800  else if (strcmp(k, "http.response_headers.raw") == 0)
802 
803  else {
804  SCLogError("unsupported http data type %s", k);
805  goto error;
806  }
807 
808  ld->buffername = SCStrdup(k);
809  if (ld->buffername == NULL) {
810  SCLogError("alloc error");
811  goto error;
812  }
813  } else if (strncmp(k, "dns", 3) == 0) {
814 
815  ld->alproto = ALPROTO_DNS;
816 
817  if (strcmp(k, "dns.request") == 0)
819  else if (strcmp(k, "dns.response") == 0)
821 
822  else {
823  SCLogError("unsupported dns data type %s", k);
824  goto error;
825  }
826  ld->buffername = SCStrdup(k);
827  if (ld->buffername == NULL) {
828  SCLogError("alloc error");
829  goto error;
830  }
831  } else if (strncmp(k, "tls", 3) == 0) {
832 
833  ld->alproto = ALPROTO_TLS;
834 
835  } else if (strncmp(k, "ssh", 3) == 0) {
836 
837  ld->alproto = ALPROTO_SSH;
838 
839  ld->flags |= FLAG_DATATYPE_SSH;
840 
841  } else if (strncmp(k, "smtp", 4) == 0) {
842 
843  ld->alproto = ALPROTO_SMTP;
844 
845  ld->flags |= FLAG_DATATYPE_SMTP;
846 
847  } else if (strncmp(k, "dnp3", 4) == 0) {
848 
849  ld->alproto = ALPROTO_DNP3;
850 
851  ld->flags |= FLAG_DATATYPE_DNP3;
852 
853  } else {
854  SCLogError("unsupported data type %s", k);
855  goto error;
856  }
857  }
858 
859  /* pop the table */
860  lua_pop(luastate, 1);
861  SCLuaSbStateClose(luastate);
862  return 0;
863 error:
864  SCLuaSbStateClose(luastate);
865  return -1;
866 }
867 
868 /**
869  * \brief this function is used to parse lua options
870  * \brief into the current signature
871  *
872  * \param de_ctx pointer to the Detection Engine Context
873  * \param s pointer to the Current Signature
874  * \param str pointer to the user provided "lua" option
875  *
876  * \retval 0 on Success
877  * \retval -1 on Failure
878  */
879 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
880 {
881  /* First check if Lua rules are enabled, by default Lua in rules
882  * is disabled. */
883  int enabled = 0;
884  (void)ConfGetBool("security.lua.allow-rules", &enabled);
885  if (!enabled) {
886  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
887  return -1;
888  }
889 
890  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
891  if (lua == NULL)
892  return -1;
893 
894  /* Load lua sandbox configurations */
895  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
896  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
897  (void)ConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
898  (void)ConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
899  lua->alloc_limit = lua_alloc_limit;
900  lua->instruction_limit = lua_instruction_limit;
901 
902  int allow_restricted_functions = 0;
903  (void)ConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
904  lua->allow_restricted_functions = allow_restricted_functions;
905 
906  if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
907  goto error;
908  }
909 
911  DetectLuaThreadInit, (void *)lua,
912  DetectLuaThreadFree, 0);
913  if (lua->thread_ctx_id == -1)
914  goto error;
915 
916  if (lua->alproto != ALPROTO_UNKNOWN) {
917  if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, lua->alproto)) {
918  goto error;
919  }
920  s->alproto = lua->alproto;
921  }
922 
923  /* Okay so far so good, lets get this into a SigMatch
924  * and put it in the Signature. */
925 
926  int list = -1;
927  if (lua->alproto == ALPROTO_UNKNOWN) {
928  if (lua->flags & FLAG_DATATYPE_STREAM)
929  list = DETECT_SM_LIST_PMATCH;
930  else {
931  if (lua->flags & FLAG_DATATYPE_BUFFER) {
932  if (DetectBufferGetActiveList(de_ctx, s) != -1) {
933  list = s->init_data->list;
934  } else {
935  SCLogError("Lua and sticky buffer failure");
936  goto error;
937  }
938  } else
939  list = DETECT_SM_LIST_MATCH;
940  }
941 
942  } else if (lua->alproto == ALPROTO_HTTP1) {
944  list = DetectBufferTypeGetByName("file_data");
945  } else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_BODY) {
946  list = DetectBufferTypeGetByName("http_client_body");
947  } else if (lua->flags & FLAG_DATATYPE_HTTP_URI) {
948  list = DetectBufferTypeGetByName("http_uri");
949  } else if (lua->flags & FLAG_DATATYPE_HTTP_URI_RAW) {
950  list = DetectBufferTypeGetByName("http_raw_uri");
951  } else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_COOKIE ||
953  list = DetectBufferTypeGetByName("http_cookie");
954  } else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_UA) {
955  list = DetectBufferTypeGetByName("http_user_agent");
956  } else if (lua->flags &
958  list = DetectBufferTypeGetByName("http_header");
959  } else if (lua->flags & (FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW |
961  list = DetectBufferTypeGetByName("http_raw_header");
962  } else {
963  list = DetectBufferTypeGetByName("http_request_line");
964  }
965  } else if (lua->alproto == ALPROTO_DNS) {
966  if (lua->flags & FLAG_DATATYPE_DNS_REQUEST) {
967  list = DetectBufferTypeGetByName("dns_request");
968  } else if (lua->flags & FLAG_DATATYPE_DNS_RESPONSE) {
969  list = DetectBufferTypeGetByName("dns_response");
970  }
971  } else if (lua->alproto == ALPROTO_TLS) {
972  list = DetectBufferTypeGetByName("tls_generic");
973  } else if (lua->alproto == ALPROTO_SSH) {
974  list = DetectBufferTypeGetByName("ssh_banner");
975  } else if (lua->alproto == ALPROTO_SMTP) {
976  list = g_smtp_generic_list_id;
977  } else if (lua->alproto == ALPROTO_DNP3) {
978  list = DetectBufferTypeGetByName("dnp3");
979  } else {
980  SCLogError("lua can't be used with protocol %s", AppLayerGetProtoName(lua->alproto));
981  goto error;
982  }
983 
984  if (list == -1) {
985  SCLogError("lua can't be used with protocol %s", AppLayerGetProtoName(lua->alproto));
986  goto error;
987  }
988 
989  if (SigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
990  goto error;
991  }
992 
993  return 0;
994 
995 error:
996  if (lua != NULL)
997  DetectLuaFree(de_ctx, lua);
998  return -1;
999 }
1000 
1001 /** \brief post-sig parse function to set the sid,rev,gid into the
1002  * ctx, as this isn't available yet during parsing.
1003  */
1005 {
1006  int i;
1007  SigMatch *sm;
1008 
1009  for (i = 0; i < DETECT_SM_LIST_MAX; i++) {
1010  for (sm = s->init_data->smlists[i]; sm != NULL; sm = sm->next) {
1011  if (sm->type != DETECT_LUA)
1012  continue;
1013 
1014  DetectLuaData *ld = (DetectLuaData *)sm->ctx;
1015  ld->sid = s->id;
1016  ld->rev = s->rev;
1017  ld->gid = s->gid;
1018  }
1019  }
1020 }
1021 
1022 /**
1023  * \brief this function will free memory associated with DetectLuaData
1024  *
1025  * \param ptr pointer to DetectLuaData
1026  */
1027 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
1028 {
1029  if (ptr != NULL) {
1030  DetectLuaData *lua = (DetectLuaData *)ptr;
1031 
1032  if (lua->buffername)
1033  SCFree(lua->buffername);
1034  if (lua->filename)
1035  SCFree(lua->filename);
1036 
1037  for (uint16_t i = 0; i < lua->flowints; i++) {
1039  }
1040  for (uint16_t i = 0; i < lua->flowvars; i++) {
1042  }
1043 
1045 
1046  SCFree(lua);
1047  }
1048 }
1049 
1050 #ifdef UNITTESTS
1051 #include "detect-engine-alert.h"
1052 
1053 /** \test http buffer */
1054 static int LuaMatchTest01(void)
1055 {
1056  ConfSetFinal("security.lua.allow-rules", "true");
1057 
1058  const char script[] =
1059  "function init (args)\n"
1060  " local needs = {}\n"
1061  " needs[\"http.request_headers\"] = tostring(true)\n"
1062  " needs[\"flowvar\"] = {\"cnt\"}\n"
1063  " return needs\n"
1064  "end\n"
1065  "\n"
1066  "function match(args)\n"
1067  " a = ScFlowvarGet(0)\n"
1068  " if a then\n"
1069  " a = tostring(tonumber(a)+1)\n"
1070  " print (a)\n"
1071  " ScFlowvarSet(0, a, #a)\n"
1072  " else\n"
1073  " a = tostring(1)\n"
1074  " print (a)\n"
1075  " ScFlowvarSet(0, a, #a)\n"
1076  " end\n"
1077  " \n"
1078  " print (\"pre check: \" .. (a))\n"
1079  " if tonumber(a) == 2 then\n"
1080  " print \"match\"\n"
1081  " return 1\n"
1082  " end\n"
1083  " return 0\n"
1084  "end\n"
1085  "return 0\n";
1086  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1087  uint8_t httpbuf1[] =
1088  "POST / HTTP/1.1\r\n"
1089  "Host: www.emergingthreats.net\r\n\r\n";
1090  uint8_t httpbuf2[] =
1091  "POST / HTTP/1.1\r\n"
1092  "Host: www.openinfosecfoundation.org\r\n\r\n";
1093  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1094  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1095  TcpSession ssn;
1096  Flow f;
1097  ThreadVars th_v;
1098  DetectEngineThreadCtx *det_ctx;
1099 
1101 
1102  ut_script = script;
1103 
1104  memset(&th_v, 0, sizeof(th_v));
1105  memset(&f, 0, sizeof(f));
1106  memset(&ssn, 0, sizeof(ssn));
1107 
1108  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1109  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1110 
1111  FLOW_INITIALIZE(&f);
1112  f.protoctx = (void *)&ssn;
1113  f.proto = IPPROTO_TCP;
1114  f.flags |= FLOW_IPV4;
1115  f.alproto = ALPROTO_HTTP1;
1116 
1117  p1->flow = &f;
1121  p2->flow = &f;
1125 
1126  StreamTcpInitConfig(true);
1127 
1130  de_ctx->flags |= DE_QUIET;
1131 
1133  FAIL_IF_NULL(s);
1134 
1136  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1137 
1138  int r = AppLayerParserParse(
1139  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1140  FAIL_IF(r != 0);
1141  HtpState *http_state = f.alstate;
1142  FAIL_IF_NULL(http_state);
1143 
1144  /* do detect for p1 */
1145  SCLogDebug("inspecting p1");
1146  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1147 
1148  FAIL_IF(PacketAlertCheck(p1, 1));
1149 
1150  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1151  FAIL_IF(r != 0);
1152 
1153  /* do detect for p2 */
1154  SCLogDebug("inspecting p2");
1155  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1156 
1157  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1158 
1159  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1160  FAIL_IF(id == 0);
1161 
1162  FlowVar *fv = FlowVarGet(&f, id);
1163  FAIL_IF_NULL(fv);
1164 
1165  FAIL_IF(fv->data.fv_str.value_len != 1);
1166 
1167  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1168 
1171 
1172  StreamTcpFreeConfig(true);
1173  FLOW_DESTROY(&f);
1174  UTHFreePackets(&p1, 1);
1175  UTHFreePackets(&p2, 1);
1176  PASS;
1177 }
1178 
1179 static int LuaMatchTest01a(void)
1180 {
1181  const char script[] = "function init (args)\n"
1182  " local needs = {}\n"
1183  " needs[\"http.request_headers\"] = tostring(true)\n"
1184  " needs[\"flowvar\"] = {\"cnt\"}\n"
1185  " return needs\n"
1186  "end\n"
1187  "\n"
1188  "function match(args)\n"
1189  " a = SCFlowvarGet(0)\n"
1190  " if a then\n"
1191  " a = tostring(tonumber(a)+1)\n"
1192  " print (a)\n"
1193  " SCFlowvarSet(0, a, #a)\n"
1194  " else\n"
1195  " a = tostring(1)\n"
1196  " print (a)\n"
1197  " SCFlowvarSet(0, a, #a)\n"
1198  " end\n"
1199  " \n"
1200  " print (\"pre check: \" .. (a))\n"
1201  " if tonumber(a) == 2 then\n"
1202  " print \"match\"\n"
1203  " return 1\n"
1204  " end\n"
1205  " return 0\n"
1206  "end\n"
1207  "return 0\n";
1208  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1209  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1210  "Host: www.emergingthreats.net\r\n\r\n";
1211  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1212  "Host: www.openinfosecfoundation.org\r\n\r\n";
1213  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1214  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1215  TcpSession ssn;
1216  Flow f;
1217  ThreadVars th_v;
1218  DetectEngineThreadCtx *det_ctx;
1219 
1221 
1222  ut_script = script;
1223 
1224  memset(&th_v, 0, sizeof(th_v));
1225  memset(&f, 0, sizeof(f));
1226  memset(&ssn, 0, sizeof(ssn));
1227 
1228  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1229  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1230 
1231  FLOW_INITIALIZE(&f);
1232  f.protoctx = (void *)&ssn;
1233  f.proto = IPPROTO_TCP;
1234  f.flags |= FLOW_IPV4;
1235  f.alproto = ALPROTO_HTTP1;
1236 
1237  p1->flow = &f;
1241  p2->flow = &f;
1245 
1246  StreamTcpInitConfig(true);
1247 
1250  de_ctx->flags |= DE_QUIET;
1251 
1253  FAIL_IF_NULL(s);
1254 
1256  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1257 
1258  int r = AppLayerParserParse(
1259  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1260  FAIL_IF(r != 0);
1261 
1262  HtpState *http_state = f.alstate;
1263  FAIL_IF_NULL(http_state);
1264 
1265  /* do detect for p1 */
1266  SCLogDebug("inspecting p1");
1267  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1268 
1269  FAIL_IF(PacketAlertCheck(p1, 1));
1270 
1271  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1272  FAIL_IF(r != 0);
1273  /* do detect for p2 */
1274  SCLogDebug("inspecting p2");
1275  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1276 
1277  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1278 
1279  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1280  FAIL_IF(id == 0);
1281 
1282  FlowVar *fv = FlowVarGet(&f, id);
1283  FAIL_IF_NULL(fv);
1284 
1285  FAIL_IF(fv->data.fv_str.value_len != 1);
1286 
1287  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1288 
1291 
1292  StreamTcpFreeConfig(true);
1293  FLOW_DESTROY(&f);
1294  UTHFreePackets(&p1, 1);
1295  UTHFreePackets(&p2, 1);
1296  PASS;
1297 }
1298 
1299 /** \test payload buffer */
1300 static int LuaMatchTest02(void)
1301 {
1302  const char script[] = "function init (args)\n"
1303  " local needs = {}\n"
1304  " needs[\"payload\"] = tostring(true)\n"
1305  " needs[\"flowvar\"] = {\"cnt\"}\n"
1306  " return needs\n"
1307  "end\n"
1308  "\n"
1309  "function match(args)\n"
1310  " a = ScFlowvarGet(0)\n"
1311  " if a then\n"
1312  " a = tostring(tonumber(a)+1)\n"
1313  " print (a)\n"
1314  " ScFlowvarSet(0, a, #a)\n"
1315  " else\n"
1316  " a = tostring(1)\n"
1317  " print (a)\n"
1318  " ScFlowvarSet(0, a, #a)\n"
1319  " end\n"
1320  " \n"
1321  " print (\"pre check: \" .. (a))\n"
1322  " if tonumber(a) == 2 then\n"
1323  " print \"match\"\n"
1324  " return 1\n"
1325  " end\n"
1326  " return 0\n"
1327  "end\n"
1328  "return 0\n";
1329  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1330  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1331  "Host: www.emergingthreats.net\r\n\r\n";
1332  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1333  "Host: www.openinfosecfoundation.org\r\n\r\n";
1334  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1335  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1336  TcpSession ssn;
1337  Flow f;
1338  ThreadVars th_v;
1339  DetectEngineThreadCtx *det_ctx;
1340 
1341  ut_script = script;
1342 
1343  memset(&th_v, 0, sizeof(th_v));
1344  memset(&f, 0, sizeof(f));
1345  memset(&ssn, 0, sizeof(ssn));
1346 
1347  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1348  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1349 
1350  FLOW_INITIALIZE(&f);
1351  f.protoctx = (void *)&ssn;
1352  f.proto = IPPROTO_TCP;
1353  f.flags |= FLOW_IPV4;
1354  f.alproto = ALPROTO_HTTP1;
1355 
1356  p1->flow = &f;
1360  p2->flow = &f;
1364 
1365  StreamTcpInitConfig(true);
1366 
1369  de_ctx->flags |= DE_QUIET;
1370 
1372  FAIL_IF_NULL(s);
1373 
1375  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1376 
1377  /* do detect for p1 */
1378  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1379 
1380  FAIL_IF(PacketAlertCheck(p1, 1));
1381 
1382  /* do detect for p2 */
1383  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1384 
1385  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1386 
1387  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1388  FAIL_IF(id == 0);
1389 
1390  FlowVar *fv = FlowVarGet(&f, id);
1391  FAIL_IF_NULL(fv);
1392 
1393  FAIL_IF(fv->data.fv_str.value_len != 1);
1394 
1395  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1396 
1398 
1399  StreamTcpFreeConfig(true);
1400  FLOW_DESTROY(&f);
1401  UTHFreePackets(&p1, 1);
1402  UTHFreePackets(&p2, 1);
1403  PASS;
1404 }
1405 
1406 /** \test payload buffer */
1407 static int LuaMatchTest02a(void)
1408 {
1409  const char script[] = "function init (args)\n"
1410  " local needs = {}\n"
1411  " needs[\"payload\"] = tostring(true)\n"
1412  " needs[\"flowvar\"] = {\"cnt\"}\n"
1413  " return needs\n"
1414  "end\n"
1415  "\n"
1416  "function match(args)\n"
1417  " a = SCFlowvarGet(0)\n"
1418  " if a then\n"
1419  " a = tostring(tonumber(a)+1)\n"
1420  " print (a)\n"
1421  " SCFlowvarSet(0, a, #a)\n"
1422  " else\n"
1423  " a = tostring(1)\n"
1424  " print (a)\n"
1425  " SCFlowvarSet(0, a, #a)\n"
1426  " end\n"
1427  " \n"
1428  " print (\"pre check: \" .. (a))\n"
1429  " if tonumber(a) == 2 then\n"
1430  " print \"match\"\n"
1431  " return 1\n"
1432  " end\n"
1433  " return 0\n"
1434  "end\n"
1435  "return 0\n";
1436  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1437  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1438  "Host: www.emergingthreats.net\r\n\r\n";
1439  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1440  "Host: www.openinfosecfoundation.org\r\n\r\n";
1441  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1442  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1443  TcpSession ssn;
1444  Flow f;
1445  ThreadVars th_v;
1446  DetectEngineThreadCtx *det_ctx;
1447 
1448  ut_script = script;
1449 
1450  memset(&th_v, 0, sizeof(th_v));
1451  memset(&f, 0, sizeof(f));
1452  memset(&ssn, 0, sizeof(ssn));
1453 
1454  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1455  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1456 
1457  FLOW_INITIALIZE(&f);
1458  f.protoctx = (void *)&ssn;
1459  f.proto = IPPROTO_TCP;
1460  f.flags |= FLOW_IPV4;
1461  f.alproto = ALPROTO_HTTP1;
1462 
1463  p1->flow = &f;
1467  p2->flow = &f;
1471 
1472  StreamTcpInitConfig(true);
1473 
1476  de_ctx->flags |= DE_QUIET;
1477 
1479  FAIL_IF_NULL(s);
1480 
1482  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1483 
1484  /* do detect for p1 */
1485  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1486  FAIL_IF(PacketAlertCheck(p1, 1));
1487 
1488  /* do detect for p2 */
1489  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1490 
1491  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1492 
1493  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1494  FAIL_IF(id == 0);
1495 
1496  FlowVar *fv = FlowVarGet(&f, id);
1497  FAIL_IF_NULL(fv);
1498 
1499  FAIL_IF(fv->data.fv_str.value_len != 1);
1500 
1501  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1502 
1504 
1505  StreamTcpFreeConfig(true);
1506  FLOW_DESTROY(&f);
1507  UTHFreePackets(&p1, 1);
1508  UTHFreePackets(&p2, 1);
1509  PASS;
1510 }
1511 
1512 /** \test packet buffer */
1513 static int LuaMatchTest03(void)
1514 {
1515  const char script[] = "function init (args)\n"
1516  " local needs = {}\n"
1517  " needs[\"packet\"] = tostring(true)\n"
1518  " needs[\"flowvar\"] = {\"cnt\"}\n"
1519  " return needs\n"
1520  "end\n"
1521  "\n"
1522  "function match(args)\n"
1523  " a = ScFlowvarGet(0)\n"
1524  " if a then\n"
1525  " a = tostring(tonumber(a)+1)\n"
1526  " print (a)\n"
1527  " ScFlowvarSet(0, a, #a)\n"
1528  " else\n"
1529  " a = tostring(1)\n"
1530  " print (a)\n"
1531  " ScFlowvarSet(0, a, #a)\n"
1532  " end\n"
1533  " \n"
1534  " print (\"pre check: \" .. (a))\n"
1535  " if tonumber(a) == 2 then\n"
1536  " print \"match\"\n"
1537  " return 1\n"
1538  " end\n"
1539  " return 0\n"
1540  "end\n"
1541  "return 0\n";
1542  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1543  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1544  "Host: www.emergingthreats.net\r\n\r\n";
1545  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1546  "Host: www.openinfosecfoundation.org\r\n\r\n";
1547  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1548  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1549  TcpSession ssn;
1550  Flow f;
1551  ThreadVars th_v;
1552  DetectEngineThreadCtx *det_ctx;
1553 
1554  ut_script = script;
1555 
1556  memset(&th_v, 0, sizeof(th_v));
1557  memset(&f, 0, sizeof(f));
1558  memset(&ssn, 0, sizeof(ssn));
1559 
1560  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1561  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1562 
1563  FLOW_INITIALIZE(&f);
1564  f.protoctx = (void *)&ssn;
1565  f.proto = IPPROTO_TCP;
1566  f.flags |= FLOW_IPV4;
1567  f.alproto = ALPROTO_HTTP1;
1568 
1569  p1->flow = &f;
1573  p2->flow = &f;
1577 
1578  StreamTcpInitConfig(true);
1579 
1582  de_ctx->flags |= DE_QUIET;
1583 
1585  FAIL_IF_NULL(s);
1586 
1588  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1589 
1590  /* do detect for p1 */
1591  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1592  FAIL_IF(PacketAlertCheck(p1, 1));
1593 
1594  /* do detect for p2 */
1595  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1596 
1597  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1598 
1599  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1600  FAIL_IF(id == 0);
1601 
1602  FlowVar *fv = FlowVarGet(&f, id);
1603  FAIL_IF_NULL(fv);
1604 
1605  FAIL_IF(fv->data.fv_str.value_len != 1);
1606 
1607  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1608 
1610 
1611  StreamTcpFreeConfig(true);
1612  FLOW_DESTROY(&f);
1613  UTHFreePackets(&p1, 1);
1614  UTHFreePackets(&p2, 1);
1615  PASS;
1616 }
1617 
1618 /** \test packet buffer */
1619 static int LuaMatchTest03a(void)
1620 {
1621  const char script[] = "function init (args)\n"
1622  " local needs = {}\n"
1623  " needs[\"packet\"] = tostring(true)\n"
1624  " needs[\"flowvar\"] = {\"cnt\"}\n"
1625  " return needs\n"
1626  "end\n"
1627  "\n"
1628  "function match(args)\n"
1629  " a = SCFlowvarGet(0)\n"
1630  " if a then\n"
1631  " a = tostring(tonumber(a)+1)\n"
1632  " print (a)\n"
1633  " SCFlowvarSet(0, a, #a)\n"
1634  " else\n"
1635  " a = tostring(1)\n"
1636  " print (a)\n"
1637  " SCFlowvarSet(0, a, #a)\n"
1638  " end\n"
1639  " \n"
1640  " print (\"pre check: \" .. (a))\n"
1641  " if tonumber(a) == 2 then\n"
1642  " print \"match\"\n"
1643  " return 1\n"
1644  " end\n"
1645  " return 0\n"
1646  "end\n"
1647  "return 0\n";
1648  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1649  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1650  "Host: www.emergingthreats.net\r\n\r\n";
1651  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1652  "Host: www.openinfosecfoundation.org\r\n\r\n";
1653  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1654  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1655  TcpSession ssn;
1656  Flow f;
1657  ThreadVars th_v;
1658  DetectEngineThreadCtx *det_ctx;
1659 
1660  ut_script = script;
1661 
1662  memset(&th_v, 0, sizeof(th_v));
1663  memset(&f, 0, sizeof(f));
1664  memset(&ssn, 0, sizeof(ssn));
1665 
1666  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1667  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1668 
1669  FLOW_INITIALIZE(&f);
1670  f.protoctx = (void *)&ssn;
1671  f.proto = IPPROTO_TCP;
1672  f.flags |= FLOW_IPV4;
1673  f.alproto = ALPROTO_HTTP1;
1674 
1675  p1->flow = &f;
1679  p2->flow = &f;
1683 
1684  StreamTcpInitConfig(true);
1685 
1688  de_ctx->flags |= DE_QUIET;
1689 
1691  FAIL_IF_NULL(s);
1692 
1694  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1695 
1696  /* do detect for p1 */
1697  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1698  FAIL_IF(PacketAlertCheck(p1, 1));
1699 
1700  /* do detect for p2 */
1701  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1702  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1703 
1704  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1705  FAIL_IF(id == 0);
1706 
1707  FlowVar *fv = FlowVarGet(&f, id);
1708  FAIL_IF_NULL(fv);
1709 
1710  FAIL_IF(fv->data.fv_str.value_len != 1);
1711 
1712  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1713 
1715 
1716  StreamTcpFreeConfig(true);
1717  FLOW_DESTROY(&f);
1718  UTHFreePackets(&p1, 1);
1719  UTHFreePackets(&p2, 1);
1720  PASS;
1721 }
1722 
1723 /** \test http buffer, flowints */
1724 static int LuaMatchTest04(void)
1725 {
1726  const char script[] = "function init (args)\n"
1727  " local needs = {}\n"
1728  " needs[\"http.request_headers\"] = tostring(true)\n"
1729  " needs[\"flowint\"] = {\"cnt\"}\n"
1730  " return needs\n"
1731  "end\n"
1732  "\n"
1733  "function match(args)\n"
1734  " print \"inspecting\""
1735  " a = ScFlowintGet(0)\n"
1736  " if a then\n"
1737  " ScFlowintSet(0, a + 1)\n"
1738  " else\n"
1739  " ScFlowintSet(0, 1)\n"
1740  " end\n"
1741  " \n"
1742  " a = ScFlowintGet(0)\n"
1743  " if a == 2 then\n"
1744  " print \"match\"\n"
1745  " return 1\n"
1746  " end\n"
1747  " return 0\n"
1748  "end\n"
1749  "return 0\n";
1750  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1751  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1752  "Host: www.emergingthreats.net\r\n\r\n";
1753  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1754  "Host: www.openinfosecfoundation.org\r\n\r\n";
1755  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1756  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1757  TcpSession ssn;
1758  Flow f;
1759  ThreadVars th_v;
1760  DetectEngineThreadCtx *det_ctx;
1761 
1763 
1764  ut_script = script;
1765 
1766  memset(&th_v, 0, sizeof(th_v));
1767  memset(&f, 0, sizeof(f));
1768  memset(&ssn, 0, sizeof(ssn));
1769 
1770  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1771  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1772 
1773  FLOW_INITIALIZE(&f);
1774  f.protoctx = (void *)&ssn;
1775  f.proto = IPPROTO_TCP;
1776  f.flags |= FLOW_IPV4;
1777  f.alproto = ALPROTO_HTTP1;
1778 
1779  p1->flow = &f;
1783 
1784  p2->flow = &f;
1788 
1789  StreamTcpInitConfig(true);
1790 
1793  de_ctx->flags |= DE_QUIET;
1794 
1796  FAIL_IF_NULL(s);
1797 
1799  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1800 
1801  int r = AppLayerParserParse(
1802  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1803  FAIL_IF(r != 0);
1804  HtpState *http_state = f.alstate;
1805  FAIL_IF_NULL(http_state);
1806 
1807  /* do detect for p1 */
1808  SCLogInfo("p1");
1809  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1810 
1811  FAIL_IF(PacketAlertCheck(p1, 1));
1812 
1813  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1814  FAIL_IF(r != 0);
1815  /* do detect for p2 */
1816  SCLogInfo("p2");
1817  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1818 
1819  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1820 
1821  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1822  FAIL_IF(id == 0);
1823 
1824  FlowVar *fv = FlowVarGet(&f, id);
1825  FAIL_IF_NULL(fv);
1826 
1827  FAIL_IF(fv->data.fv_int.value != 2);
1828 
1831 
1832  StreamTcpFreeConfig(true);
1833  FLOW_DESTROY(&f);
1834  UTHFreePackets(&p1, 1);
1835  UTHFreePackets(&p2, 1);
1836  PASS;
1837 }
1838 
1839 /** \test http buffer, flowints */
1840 static int LuaMatchTest04a(void)
1841 {
1842  const char script[] = "function init (args)\n"
1843  " local needs = {}\n"
1844  " needs[\"http.request_headers\"] = tostring(true)\n"
1845  " needs[\"flowint\"] = {\"cnt\"}\n"
1846  " return needs\n"
1847  "end\n"
1848  "\n"
1849  "function match(args)\n"
1850  " print \"inspecting\""
1851  " a = SCFlowintGet(0)\n"
1852  " if a then\n"
1853  " SCFlowintSet(0, a + 1)\n"
1854  " else\n"
1855  " SCFlowintSet(0, 1)\n"
1856  " end\n"
1857  " \n"
1858  " a = SCFlowintGet(0)\n"
1859  " if a == 2 then\n"
1860  " print \"match\"\n"
1861  " return 1\n"
1862  " end\n"
1863  " return 0\n"
1864  "end\n"
1865  "return 0\n";
1866  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1867  uint8_t httpbuf1[] =
1868  "POST / HTTP/1.1\r\n"
1869  "Host: www.emergingthreats.net\r\n\r\n";
1870  uint8_t httpbuf2[] =
1871  "POST / HTTP/1.1\r\n"
1872  "Host: www.openinfosecfoundation.org\r\n\r\n";
1873  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1874  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1875  TcpSession ssn;
1876  Flow f;
1877  ThreadVars th_v;
1878  DetectEngineThreadCtx *det_ctx;
1879 
1881 
1882  ut_script = script;
1883 
1884  memset(&th_v, 0, sizeof(th_v));
1885  memset(&f, 0, sizeof(f));
1886  memset(&ssn, 0, sizeof(ssn));
1887 
1888  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1889  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1890 
1891  FLOW_INITIALIZE(&f);
1892  f.protoctx = (void *)&ssn;
1893  f.proto = IPPROTO_TCP;
1894  f.flags |= FLOW_IPV4;
1895  f.alproto = ALPROTO_HTTP1;
1896 
1897  p1->flow = &f;
1901 
1902  p2->flow = &f;
1906 
1907  StreamTcpInitConfig(true);
1908 
1911  de_ctx->flags |= DE_QUIET;
1912 
1914  FAIL_IF_NULL(s);
1915 
1917  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1918 
1919  int r = AppLayerParserParse(
1920  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1921  FAIL_IF(r != 0);
1922  HtpState *http_state = f.alstate;
1923  FAIL_IF_NULL(http_state);
1924 
1925  /* do detect for p1 */
1926  SCLogInfo("p1");
1927  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1928 
1929  FAIL_IF(PacketAlertCheck(p1, 1));
1930 
1931  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1932  FAIL_IF(r != 0);
1933  /* do detect for p2 */
1934  SCLogInfo("p2");
1935  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1936 
1937  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1938 
1939  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1940  FAIL_IF(id == 0);
1941 
1942  FlowVar *fv = FlowVarGet(&f, id);
1943  FAIL_IF_NULL(fv);
1944 
1945  FAIL_IF(fv->data.fv_int.value != 2);
1946 
1949 
1950  StreamTcpFreeConfig(true);
1951  FLOW_DESTROY(&f);
1952  UTHFreePackets(&p1, 1);
1953  UTHFreePackets(&p2, 1);
1954  PASS;
1955 }
1956 
1957 /** \test http buffer, flowints */
1958 static int LuaMatchTest05(void)
1959 {
1960  const char script[] = "function init (args)\n"
1961  " local needs = {}\n"
1962  " needs[\"http.request_headers\"] = tostring(true)\n"
1963  " needs[\"flowint\"] = {\"cnt\"}\n"
1964  " return needs\n"
1965  "end\n"
1966  "\n"
1967  "function match(args)\n"
1968  " print \"inspecting\""
1969  " a = ScFlowintIncr(0)\n"
1970  " if a == 2 then\n"
1971  " print \"match\"\n"
1972  " return 1\n"
1973  " end\n"
1974  " return 0\n"
1975  "end\n"
1976  "return 0\n";
1977  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1978  uint8_t httpbuf1[] =
1979  "POST / HTTP/1.1\r\n"
1980  "Host: www.emergingthreats.net\r\n\r\n";
1981  uint8_t httpbuf2[] =
1982  "POST / HTTP/1.1\r\n"
1983  "Host: www.openinfosecfoundation.org\r\n\r\n";
1984  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1985  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1986  TcpSession ssn;
1987  Flow f;
1988  ThreadVars th_v;
1989  DetectEngineThreadCtx *det_ctx;
1990 
1992 
1993  ut_script = script;
1994 
1995  memset(&th_v, 0, sizeof(th_v));
1996  memset(&f, 0, sizeof(f));
1997  memset(&ssn, 0, sizeof(ssn));
1998 
1999  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2000  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2001 
2002  FLOW_INITIALIZE(&f);
2003  f.protoctx = (void *)&ssn;
2004  f.proto = IPPROTO_TCP;
2005  f.flags |= FLOW_IPV4;
2006  f.alproto = ALPROTO_HTTP1;
2007 
2008  p1->flow = &f;
2012 
2013  p2->flow = &f;
2017 
2018  StreamTcpInitConfig(true);
2019 
2022  de_ctx->flags |= DE_QUIET;
2023 
2025  FAIL_IF_NULL(s);
2026 
2028  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2029 
2030  int r = AppLayerParserParse(
2031  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2032  FAIL_IF(r != 0);
2033  HtpState *http_state = f.alstate;
2034  FAIL_IF_NULL(http_state);
2035 
2036  /* do detect for p1 */
2037  SCLogInfo("p1");
2038  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2039 
2040  FAIL_IF(PacketAlertCheck(p1, 1));
2041 
2042  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2043  FAIL_IF(r != 0);
2044  /* do detect for p2 */
2045  SCLogInfo("p2");
2046  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2047 
2048  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2049 
2050  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2051  FAIL_IF(id == 0);
2052 
2053  FlowVar *fv = FlowVarGet(&f, id);
2054  FAIL_IF_NULL(fv);
2055 
2056  FAIL_IF(fv->data.fv_int.value != 2);
2057 
2060 
2061  StreamTcpFreeConfig(true);
2062  FLOW_DESTROY(&f);
2063  UTHFreePackets(&p1, 1);
2064  UTHFreePackets(&p2, 1);
2065  PASS;
2066 }
2067 
2068 /** \test http buffer, flowints */
2069 static int LuaMatchTest05a(void)
2070 {
2071  const char script[] = "function init (args)\n"
2072  " local needs = {}\n"
2073  " needs[\"http.request_headers\"] = tostring(true)\n"
2074  " needs[\"flowint\"] = {\"cnt\"}\n"
2075  " return needs\n"
2076  "end\n"
2077  "\n"
2078  "function match(args)\n"
2079  " print \"inspecting\""
2080  " a = SCFlowintIncr(0)\n"
2081  " if a == 2 then\n"
2082  " print \"match\"\n"
2083  " return 1\n"
2084  " end\n"
2085  " return 0\n"
2086  "end\n"
2087  "return 0\n";
2088  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
2089  uint8_t httpbuf1[] =
2090  "POST / HTTP/1.1\r\n"
2091  "Host: www.emergingthreats.net\r\n\r\n";
2092  uint8_t httpbuf2[] =
2093  "POST / HTTP/1.1\r\n"
2094  "Host: www.openinfosecfoundation.org\r\n\r\n";
2095  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2096  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2097  TcpSession ssn;
2098  Flow f;
2099  ThreadVars th_v;
2100  DetectEngineThreadCtx *det_ctx;
2101 
2103 
2104  ut_script = script;
2105 
2106  memset(&th_v, 0, sizeof(th_v));
2107  memset(&f, 0, sizeof(f));
2108  memset(&ssn, 0, sizeof(ssn));
2109 
2110  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2111  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2112 
2113  FLOW_INITIALIZE(&f);
2114  f.protoctx = (void *)&ssn;
2115  f.proto = IPPROTO_TCP;
2116  f.flags |= FLOW_IPV4;
2117  f.alproto = ALPROTO_HTTP1;
2118 
2119  p1->flow = &f;
2123 
2124  p2->flow = &f;
2128 
2129  StreamTcpInitConfig(true);
2130 
2133  de_ctx->flags |= DE_QUIET;
2134 
2136  FAIL_IF_NULL(s);
2137 
2139  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2140 
2141  int r = AppLayerParserParse(
2142  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2143  FAIL_IF(r != 0);
2144  HtpState *http_state = f.alstate;
2145  FAIL_IF_NULL(http_state);
2146 
2147  /* do detect for p1 */
2148  SCLogInfo("p1");
2149  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2150 
2151  FAIL_IF(PacketAlertCheck(p1, 1));
2152 
2153  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2154  FAIL_IF(r != 0);
2155  /* do detect for p2 */
2156  SCLogInfo("p2");
2157  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2158 
2159  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2160 
2161  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2162  FAIL_IF(id == 0);
2163 
2164  FlowVar *fv = FlowVarGet(&f, id);
2165  FAIL_IF_NULL(fv);
2166 
2167  FAIL_IF(fv->data.fv_int.value != 2);
2168 
2171 
2172  StreamTcpFreeConfig(true);
2173  FLOW_DESTROY(&f);
2174  UTHFreePackets(&p1, 1);
2175  UTHFreePackets(&p2, 1);
2176  PASS;
2177 }
2178 
2179 /** \test http buffer, flowints */
2180 static int LuaMatchTest06(void)
2181 {
2182  const char script[] = "function init (args)\n"
2183  " local needs = {}\n"
2184  " needs[\"http.request_headers\"] = tostring(true)\n"
2185  " needs[\"flowint\"] = {\"cnt\"}\n"
2186  " return needs\n"
2187  "end\n"
2188  "\n"
2189  "function match(args)\n"
2190  " print \"inspecting\""
2191  " a = ScFlowintGet(0)\n"
2192  " if a == nil then\n"
2193  " print \"new var set to 2\""
2194  " ScFlowintSet(0, 2)\n"
2195  " end\n"
2196  " a = ScFlowintDecr(0)\n"
2197  " if a == 0 then\n"
2198  " print \"match\"\n"
2199  " return 1\n"
2200  " end\n"
2201  " return 0\n"
2202  "end\n"
2203  "return 0\n";
2204  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
2205  uint8_t httpbuf1[] =
2206  "POST / HTTP/1.1\r\n"
2207  "Host: www.emergingthreats.net\r\n\r\n";
2208  uint8_t httpbuf2[] =
2209  "POST / HTTP/1.1\r\n"
2210  "Host: www.openinfosecfoundation.org\r\n\r\n";
2211  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2212  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2213  TcpSession ssn;
2214  Flow f;
2215  ThreadVars th_v;
2216  DetectEngineThreadCtx *det_ctx;
2217 
2219 
2220  ut_script = script;
2221 
2222  memset(&th_v, 0, sizeof(th_v));
2223  memset(&f, 0, sizeof(f));
2224  memset(&ssn, 0, sizeof(ssn));
2225 
2226  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2227  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2228 
2229  FLOW_INITIALIZE(&f);
2230  f.protoctx = (void *)&ssn;
2231  f.proto = IPPROTO_TCP;
2232  f.flags |= FLOW_IPV4;
2233  f.alproto = ALPROTO_HTTP1;
2234 
2235  p1->flow = &f;
2239 
2240  p2->flow = &f;
2244 
2245  StreamTcpInitConfig(true);
2246 
2249  de_ctx->flags |= DE_QUIET;
2250 
2252  FAIL_IF_NULL(s);
2253 
2255  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2256 
2257  int r = AppLayerParserParse(
2258  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2259  FAIL_IF(r != 0);
2260  HtpState *http_state = f.alstate;
2261  FAIL_IF_NULL(http_state);
2262 
2263  /* do detect for p1 */
2264  SCLogInfo("p1");
2265  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2266 
2267  FAIL_IF(PacketAlertCheck(p1, 1));
2268 
2269  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2270  FAIL_IF(r != 0);
2271  /* do detect for p2 */
2272  SCLogInfo("p2");
2273  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2274 
2275  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2276 
2277  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2278  FAIL_IF(id == 0);
2279 
2280  FlowVar *fv = FlowVarGet(&f, id);
2281  FAIL_IF_NULL(fv);
2282 
2283  FAIL_IF(fv->data.fv_int.value != 0);
2284 
2287 
2288  StreamTcpFreeConfig(true);
2289  FLOW_DESTROY(&f);
2290  UTHFreePackets(&p1, 1);
2291  UTHFreePackets(&p2, 1);
2292  PASS;
2293 }
2294 
2295 /** \test http buffer, flowints */
2296 static int LuaMatchTest06a(void)
2297 {
2298  const char script[] = "function init (args)\n"
2299  " local needs = {}\n"
2300  " needs[\"http.request_headers\"] = tostring(true)\n"
2301  " needs[\"flowint\"] = {\"cnt\"}\n"
2302  " return needs\n"
2303  "end\n"
2304  "\n"
2305  "function match(args)\n"
2306  " print \"inspecting\""
2307  " a = SCFlowintGet(0)\n"
2308  " if a == nil then\n"
2309  " print \"new var set to 2\""
2310  " SCFlowintSet(0, 2)\n"
2311  " end\n"
2312  " a = SCFlowintDecr(0)\n"
2313  " if a == 0 then\n"
2314  " print \"match\"\n"
2315  " return 1\n"
2316  " end\n"
2317  " return 0\n"
2318  "end\n"
2319  "return 0\n";
2320  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
2321  uint8_t httpbuf1[] =
2322  "POST / HTTP/1.1\r\n"
2323  "Host: www.emergingthreats.net\r\n\r\n";
2324  uint8_t httpbuf2[] =
2325  "POST / HTTP/1.1\r\n"
2326  "Host: www.openinfosecfoundation.org\r\n\r\n";
2327  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2328  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2329  TcpSession ssn;
2330  Flow f;
2331  ThreadVars th_v;
2332  DetectEngineThreadCtx *det_ctx;
2333 
2335 
2336  ut_script = script;
2337 
2338  memset(&th_v, 0, sizeof(th_v));
2339  memset(&f, 0, sizeof(f));
2340  memset(&ssn, 0, sizeof(ssn));
2341 
2342  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2343  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2344 
2345  FLOW_INITIALIZE(&f);
2346  f.protoctx = (void *)&ssn;
2347  f.proto = IPPROTO_TCP;
2348  f.flags |= FLOW_IPV4;
2349  f.alproto = ALPROTO_HTTP1;
2350 
2351  p1->flow = &f;
2355 
2356  p2->flow = &f;
2360 
2361  StreamTcpInitConfig(true);
2362 
2365  de_ctx->flags |= DE_QUIET;
2366 
2368  FAIL_IF_NULL(s);
2369 
2371  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2372 
2373  int r = AppLayerParserParse(
2374  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2375  FAIL_IF(r != 0);
2376  HtpState *http_state = f.alstate;
2377  FAIL_IF_NULL(http_state);
2378 
2379  /* do detect for p1 */
2380  SCLogInfo("p1");
2381  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2382 
2383  FAIL_IF(PacketAlertCheck(p1, 1));
2384 
2385  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2386  FAIL_IF(r != 0);
2387  /* do detect for p2 */
2388  SCLogInfo("p2");
2389  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2390 
2391  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2392 
2393  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2394  FAIL_IF(id == 0);
2395 
2396  FlowVar *fv = FlowVarGet(&f, id);
2397  FAIL_IF_NULL(fv);
2398 
2399  FAIL_IF(fv->data.fv_int.value != 0);
2400 
2403 
2404  StreamTcpFreeConfig(true);
2405  FLOW_DESTROY(&f);
2406  UTHFreePackets(&p1, 1);
2407  UTHFreePackets(&p2, 1);
2408  PASS;
2409 }
2410 
2411 void DetectLuaRegisterTests(void)
2412 {
2413  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2414  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2415  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2416  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2417  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2418  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2419  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2420  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2421  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2422  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2423  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2424  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2425 }
2426 #endif
FLAG_MEMORY_LIMIT_LOGGED
#define FLAG_MEMORY_LIMIT_LOGGED
Definition: detect-lua.c:126
util-byte.h
DetectLuaData::bytevars
uint16_t bytevars
Definition: detect-lua.h:51
ConfGetInt
int ConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:399
DetectLuaData
Definition: detect-lua.h:40
SigTableElmt_::url
const char * url
Definition: detect.h:1329
SCLuaSbState::memory_limit_error
bool memory_limit_error
Definition: util-lua-sandbox.h:56
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:118
LuaStateSetThreadVars
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv)
Definition: util-lua.c:110
FLAG_DATATYPE_HTTP_RESPONSE_COOKIE
#define FLAG_DATATYPE_HTTP_RESPONSE_COOKIE
Definition: detect-lua.c:113
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:595
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
FLAG_DATATYPE_HTTP_REQUEST_LINE
#define FLAG_DATATYPE_HTTP_REQUEST_LINE
Definition: detect-lua.c:111
SigTableElmt_::desc
const char * desc
Definition: detect.h:1328
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:153
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1266
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1316
FLAG_BLOCKED_FUNCTION_LOGGED
#define FLAG_BLOCKED_FUNCTION_LOGGED
Definition: detect-lua.c:124
flow-util.h
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:47
FLAG_DATATYPE_SSH
#define FLAG_DATATYPE_SSH
Definition: detect-lua.c:119
SigTableElmt_::name
const char * name
Definition: detect.h:1326
ConfGetBool
int ConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition: conf.c:482
stream-tcp.h
DetectThreadCtxGetKeywordThreadCtx
void * DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id)
Retrieve thread local keyword ctx by id.
Definition: detect-engine.c:3829
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
Signature_::alproto
AppProto alproto
Definition: detect.h:623
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DetectLuaData::flags
uint32_t flags
Definition: detect-lua.h:44
SCLuaSbGetContext
SCLuaSbState * SCLuaSbGetContext(lua_State *L)
Definition: util-lua-sandbox.c:351
Flow_::proto
uint8_t proto
Definition: flow.h:376
util-lua.h
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:85
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
DetectEngineThreadCtx_::tx_id
uint64_t tx_id
Definition: detect.h:1193
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:40
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:362
Packet_::flags
uint32_t flags
Definition: decode.h:513
SCLuaSbState
Definition: util-lua-sandbox.h:40
FLAG_DATATYPE_HTTP_REQUEST_HEADERS
#define FLAG_DATATYPE_HTTP_REQUEST_HEADERS
Definition: detect-lua.c:107
FLAG_DATATYPE_DNS_RESPONSE
#define FLAG_DATATYPE_DNS_RESPONSE
Definition: detect-lua.c:118
Flow_
Flow data structure.
Definition: flow.h:354
DetectLuaData::allow_restricted_functions
int allow_restricted_functions
Definition: detect-lua.h:58
DetectLuaData::sid
uint32_t sid
Definition: detect-lua.h:53
FLAG_INSTRUCTION_LIMIT_LOGGED
#define FLAG_INSTRUCTION_LIMIT_LOGGED
Definition: detect-lua.c:125
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:860
DetectEngineThreadCtx_::lua_blocked_function_errors
uint16_t lua_blocked_function_errors
Definition: detect.h:1252
DEFAULT_LUA_INSTRUCTION_LIMIT
#define DEFAULT_LUA_INSTRUCTION_LIMIT
Definition: detect-lua.c:129
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:58
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2742
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1297
DETECT_LUA_MAX_FLOWVARS
#define DETECT_LUA_MAX_FLOWVARS
Definition: detect-lua.h:36
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:317
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:231
util-var-name.h
ConfSetFinal
int ConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:303
DE_QUIET
#define DE_QUIET
Definition: detect.h:324
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:359
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1963
DetectLuaData::flowvar
uint32_t flowvar[DETECT_LUA_MAX_FLOWVARS]
Definition: detect-lua.h:50
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
DetectLuaData::gid
uint32_t gid
Definition: detect-lua.h:55
ALPROTO_SSH
@ ALPROTO_SSH
Definition: app-layer-protos.h:40
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2822
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:507
DetectEngineThreadCtx_::lua_instruction_limit_errors
uint16_t lua_instruction_limit_errors
Definition: detect.h:1255
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine.c:1445
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:270
Flow_::protoctx
void * protoctx
Definition: flow.h:439
SigMatchData_
Data needed for Match()
Definition: detect.h:359
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1311
FLAG_DATATYPE_PACKET
#define FLAG_DATATYPE_PACKET
Definition: detect-lua.c:102
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:98
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:575
AppLayerParserGetTransactionInspectId
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:702
DetectByteIndexType
uint8_t DetectByteIndexType
Definition: detect-byte.h:28
FLAG_DATATYPE_HTTP_URI_RAW
#define FLAG_DATATYPE_HTTP_URI_RAW
Definition: detect-lua.c:106
util-unittest.h
HtpState_
Definition: app-layer-htp.h:244
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
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1114
DetectLuaThreadData::luastate
lua_State * luastate
Definition: detect-lua.h:31
lua_State
struct lua_State lua_State
Definition: suricata-common.h:515
Signature_::gid
uint32_t gid
Definition: detect.h:655
DetectEngineThreadCtx_::lua_rule_errors
uint16_t lua_rule_errors
Definition: detect.h:1249
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:59
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:476
DetectLuaData::buffername
char * buffername
Definition: detect-lua.h:46
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:42
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:269
app-layer-htp.h
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
FLAG_DATATYPE_HTTP_REQUEST_COOKIE
#define FLAG_DATATYPE_HTTP_REQUEST_COOKIE
Definition: detect-lua.c:109
DetectEngineThreadCtx_
Definition: detect.h:1116
DetectLuaData::thread_ctx_id
int thread_ctx_id
Definition: detect-lua.h:41
ALPROTO_DNP3
@ ALPROTO_DNP3
Definition: app-layer-protos.h:50
DetectLuaData::instruction_limit
uint64_t instruction_limit
Definition: detect-lua.h:57
ALPROTO_SMTP
@ ALPROTO_SMTP
Definition: app-layer-protos.h:38
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
DETECT_LUA
@ DETECT_LUA
Definition: detect-engine-register.h:94
SignatureInitData_::list
int list
Definition: detect.h:581
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:79
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3475
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:38
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:354
DetectLuaData::alproto
AppProto alproto
Definition: detect-lua.h:45
DETECT_LUA_MAX_FLOWINTS
#define DETECT_LUA_MAX_FLOWINTS
Definition: detect-lua.h:37
FLAG_DATATYPE_PAYLOAD
#define FLAG_DATATYPE_PAYLOAD
Definition: detect-lua.c:103
FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW
#define FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW
Definition: detect-lua.c:108
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:116
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:270
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:353
FLAG_DATATYPE_DNS_REQUEST
#define FLAG_DATATYPE_DNS_REQUEST
Definition: detect-lua.c:117
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:309
DetectLuaData::bytevar
uint32_t bytevar[DETECT_LUA_MAX_BYTEVARS]
Definition: detect-lua.h:52
DetectEngineThreadCtx_::lua_memory_limit_errors
uint16_t lua_memory_limit_errors
Definition: detect.h:1258
DetectLuaData::alloc_limit
uint64_t alloc_limit
Definition: detect-lua.h:56
DetectLuaData::flowints
uint16_t flowints
Definition: detect-lua.h:48
Packet_
Definition: decode.h:476
detect-engine-build.h
type
uint16_t type
Definition: decode-vlan.c:106
FLAG_DATATYPE_HTTP_REQUEST_UA
#define FLAG_DATATYPE_HTTP_REQUEST_UA
Definition: detect-lua.c:110
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:204
FLAG_DATATYPE_STREAM
#define FLAG_DATATYPE_STREAM
Definition: detect-lua.c:104
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:47
detect-engine-alert.h
conf.h
FLAG_ERROR_LOGGED
#define FLAG_ERROR_LOGGED
Definition: detect-lua.c:123
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:688
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1294
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:59
SCLuaSbState::blocked_function_error
bool blocked_function_error
Definition: util-lua-sandbox.h:54
DetectLuaThreadData
Definition: detect-lua.h:30
FLAG_DATATYPE_HTTP_URI
#define FLAG_DATATYPE_HTTP_URI
Definition: detect-lua.c:105
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:232
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:478
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1089
LuaDumpStack
void LuaDumpStack(lua_State *state, const char *prefix)
dump stack from lua state to screen
Definition: detect-lua.c:132
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:2113
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:290
DetectLuaData::rev
uint32_t rev
Definition: detect-lua.h:54
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:345
FLAG_DATATYPE_HTTP_RESPONSE_HEADERS_RAW
#define FLAG_DATATYPE_HTTP_RESPONSE_HEADERS_RAW
Definition: detect-lua.c:116
util-lua-sandbox.h
SCLuaSbLoadLibs
void SCLuaSbLoadLibs(lua_State *L)
Definition: util-lua-sandbox.c:279
FlowVar_::data
union FlowVar_::@107 data
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:39
Packet_::flow
struct Flow_ * flow
Definition: decode.h:515
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:1050
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:3759
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:1271
detect-lua-extensions.h
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:351
FLAG_DATATYPE_SMTP
#define FLAG_DATATYPE_SMTP
Definition: detect-lua.c:120
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
DEFAULT_LUA_ALLOC_LIMIT
#define DEFAULT_LUA_ALLOC_LIMIT
Definition: detect-lua.c:128
HtpState_::connp
htp_connp_t * connp
Definition: app-layer-htp.h:246
SCLuaSbResetInstructionCounter
void SCLuaSbResetInstructionCounter(lua_State *L)
Definition: util-lua-sandbox.c:387
Signature_::rev
uint32_t rev
Definition: detect.h:656
FLAG_DATATYPE_HTTP_RESPONSE_HEADERS
#define FLAG_DATATYPE_HTTP_RESPONSE_HEADERS
Definition: detect-lua.c:115
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:2152
FLAG_DATATYPE_HTTP_RESPONSE_BODY
#define FLAG_DATATYPE_HTTP_RESPONSE_BODY
Definition: detect-lua.c:114
DetectLuaPostSetup
void DetectLuaPostSetup(Signature *s)
post-sig parse function to set the sid,rev,gid into the ctx, as this isn't available yet during parsi...
Definition: detect-lua.c:1004
DetectLuaData::flowvars
uint16_t flowvars
Definition: detect-lua.h:49
str
#define str(s)
Definition: suricata-common.h:300
DetectEngineThreadCtx_::tv
ThreadVars * tv
Definition: detect.h:1124
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:122
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::alstate
void * alstate
Definition: flow.h:477
Signature_::id
uint32_t id
Definition: detect.h:654
Flow_::flags
uint32_t flags
Definition: flow.h:419
detect-parse.h
Signature_
Signature container.
Definition: detect.h:618
SigMatch_
a single match condition for a signature
Definition: detect.h:350
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:1008
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:38
DETECT_SM_LIST_MAX
@ DETECT_SM_LIST_MAX
Definition: detect.h:134
FLAG_DATATYPE_DNP3
#define FLAG_DATATYPE_DNP3
Definition: detect-lua.c:121
VAR_TYPE_FLOW_INT
@ VAR_TYPE_FLOW_INT
Definition: util-var.h:37
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:233
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2703
LuaRegisterExtensions
int LuaRegisterExtensions(lua_State *lua_state)
Register Suricata Lua functions.
Definition: detect-lua-extensions.c:511
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:63
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:462
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:862
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:3811
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
htp_tx_request_line
#define htp_tx_request_line(tx)
Definition: app-layer-htp-libhtp.h:164
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:448
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
flow-var.h
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1082
DetectLuaData::filename
char * filename
Definition: detect-lua.h:43
FlowVar_
Definition: flow-var.h:49
FLAG_DATATYPE_HTTP_REQUEST_BODY
#define FLAG_DATATYPE_HTTP_REQUEST_BODY
Definition: detect-lua.c:112
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1263
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1318
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:319
DetectLuaThreadData::alproto
int alproto
Definition: detect-lua.h:33
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:450