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_RRNAME BIT_U32(15)
118 #define FLAG_DATATYPE_DNS_REQUEST BIT_U32(16)
119 #define FLAG_DATATYPE_DNS_RESPONSE BIT_U32(17)
120 #define FLAG_DATATYPE_SSH BIT_U32(19)
121 #define FLAG_DATATYPE_SMTP BIT_U32(20)
122 #define FLAG_DATATYPE_DNP3 BIT_U32(21)
123 #define FLAG_DATATYPE_BUFFER BIT_U32(22)
124 #define FLAG_ERROR_LOGGED BIT_U32(23)
125 #define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
126 #define FLAG_INSTRUCTION_LIMIT_LOGGED BIT_U32(25)
127 #define FLAG_MEMORY_LIMIT_LOGGED BIT_U32(26)
128 
129 #define DEFAULT_LUA_ALLOC_LIMIT 500000
130 #define DEFAULT_LUA_INSTRUCTION_LIMIT 500000
131 
132 /** \brief dump stack from lua state to screen */
133 void LuaDumpStack(lua_State *state, const char *prefix)
134 {
135  int size = lua_gettop(state);
136  printf("%s: size %d\n", prefix, size);
137 
138  for (int i = 1; i <= size; i++) {
139  int type = lua_type(state, i);
140  printf("- %s: Stack size=%d, level=%d, type=%d, ", prefix, size, i, type);
141 
142  switch (type) {
143  case LUA_TFUNCTION:
144  printf("function %s", lua_tostring(state, i));
145  break;
146  case LUA_TBOOLEAN:
147  printf("bool %s", lua_toboolean(state, i) ? "true" : "false");
148  break;
149  case LUA_TNUMBER:
150  printf("number %g", lua_tonumber(state, i));
151  break;
152  case LUA_TSTRING:
153  printf("string `%s'", lua_tostring(state, i));
154  break;
155  case LUA_TTABLE:
156  printf("table `%s'", lua_tostring(state, i));
157  break;
158  default:
159  printf("other %s", lua_typename(state, type));
160  break;
161 
162  }
163  printf("\n");
164  }
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  if (tlua->alproto != ALPROTO_UNKNOWN) {
346  if (p->flow == NULL)
347  SCReturnInt(0);
348 
349  AppProto alproto = p->flow->alproto;
350  if (tlua->alproto != alproto)
351  SCReturnInt(0);
352  }
353 
354  lua_getglobal(tlua->luastate, "match");
355  lua_newtable(tlua->luastate); /* stack at -1 */
356 
357  if (tlua->alproto == ALPROTO_HTTP1) {
358  HtpState *htp_state = p->flow->alstate;
359  if (htp_state != NULL && htp_state->connp != NULL) {
360  htp_tx_t *tx = NULL;
362  STREAM_TOSERVER);
363  uint64_t total_txs= AppLayerParserGetTxCnt(p->flow, htp_state);
364  for ( ; idx < total_txs; idx++) {
365  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, idx);
366  if (tx == NULL)
367  continue;
368 
369  if ((tlua->flags & FLAG_DATATYPE_HTTP_REQUEST_LINE) &&
370  htp_tx_request_line(tx) != NULL && bstr_len(htp_tx_request_line(tx)) > 0) {
371  lua_pushliteral(tlua->luastate, "http.request_line"); /* stack at -2 */
373  (const uint8_t *)bstr_ptr(htp_tx_request_line(tx)),
374  bstr_len(htp_tx_request_line(tx)));
375  lua_settable(tlua->luastate, -3);
376  }
377  }
378  }
379  }
380 
381  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
382 }
383 
384 static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
385  Flow *f, uint8_t flags, void *state,
386  const Signature *s, const SigMatchCtx *ctx)
387 {
388  SCEnter();
389  DetectLuaData *lua = (DetectLuaData *)ctx;
390  if (lua == NULL)
391  SCReturnInt(0);
392 
394  if (tlua == NULL)
395  SCReturnInt(0);
396 
397  /* setup extension data for use in lua c functions */
398  LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
399 
400  if (tlua->alproto != ALPROTO_UNKNOWN) {
401  int alproto = f->alproto;
402  if (tlua->alproto != alproto)
403  SCReturnInt(0);
404  }
405 
406  lua_getglobal(tlua->luastate, "match");
407  lua_newtable(tlua->luastate); /* stack at -1 */
408 
409  if (tlua->alproto == ALPROTO_HTTP1) {
410  HtpState *htp_state = state;
411  if (htp_state != NULL && htp_state->connp != NULL) {
412  htp_tx_t *tx = NULL;
413  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, det_ctx->tx_id);
414  if (tx != NULL) {
415  if ((tlua->flags & FLAG_DATATYPE_HTTP_REQUEST_LINE) &&
416  htp_tx_request_line(tx) != NULL && bstr_len(htp_tx_request_line(tx)) > 0) {
417  lua_pushliteral(tlua->luastate, "http.request_line"); /* stack at -2 */
419  (const uint8_t *)bstr_ptr(htp_tx_request_line(tx)),
420  bstr_len(htp_tx_request_line(tx)));
421  lua_settable(tlua->luastate, -3);
422  }
423  }
424  }
425  }
426 
427  SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
428 }
429 
430 /**
431  * \brief match the specified lua script in a list with a tx
432  *
433  * \param t thread local vars
434  * \param det_ctx pattern matcher thread local data
435  * \param s signature being inspected
436  * \param m sigmatch that we will cast into DetectLuaData
437  *
438  * \retval 0 no match
439  * \retval 1 match
440  */
441 static int DetectLuaAppTxMatch (DetectEngineThreadCtx *det_ctx,
442  Flow *f, uint8_t flags,
443  void *state, void *txv, const Signature *s,
444  const SigMatchCtx *ctx)
445 {
446  return DetectLuaAppMatchCommon(det_ctx, f, flags, state, s, ctx);
447 }
448 
449 #ifdef UNITTESTS
450 /* if this ptr is set the lua setup functions will use this buffer as the
451  * lua script instead of calling luaL_loadfile on the filename supplied. */
452 static const char *ut_script = NULL;
453 #endif
454 
455 static void *DetectLuaThreadInit(void *data)
456 {
457  int status;
458  DetectLuaData *lua = (DetectLuaData *)data;
459  BUG_ON(lua == NULL);
460 
462  if (unlikely(t == NULL)) {
463  SCLogError("couldn't alloc ctx memory");
464  return NULL;
465  }
466 
467  t->alproto = lua->alproto;
468  t->flags = lua->flags;
469 
471  if (t->luastate == NULL) {
472  SCLogError("luastate pool depleted");
473  goto error;
474  }
475 
476  if (lua->allow_restricted_functions) {
477  luaL_openlibs(t->luastate);
479  } else {
481  }
482 
484 
485  lua_pushinteger(t->luastate, (lua_Integer)(lua->sid));
486  lua_setglobal(t->luastate, "SCRuleSid");
487  lua_pushinteger(t->luastate, (lua_Integer)(lua->rev));
488  lua_setglobal(t->luastate, "SCRuleRev");
489  lua_pushinteger(t->luastate, (lua_Integer)(lua->gid));
490  lua_setglobal(t->luastate, "SCRuleGid");
491 
492  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
493 #ifdef UNITTESTS
494  if (ut_script != NULL) {
495  status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest");
496  if (status) {
497  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
498  goto error;
499  }
500  } else {
501 #endif
502  status = luaL_loadfile(t->luastate, lua->filename);
503  if (status) {
504  SCLogError("couldn't load file: %s", lua_tostring(t->luastate, -1));
505  goto error;
506  }
507 #ifdef UNITTESTS
508  }
509 #endif
510 
511  /* prime the script (or something) */
512  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
513  SCLogError("couldn't prime file: %s", lua_tostring(t->luastate, -1));
514  goto error;
515  }
516 
517  /* thread_init call */
518  lua_getglobal(t->luastate, "thread_init");
519  if (lua_isfunction(t->luastate, -1)) {
520  if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
521  SCLogError("couldn't run script 'thread_init' function: %s",
522  lua_tostring(t->luastate, -1));
523  goto error;
524  }
525  } else {
526  lua_pop(t->luastate, 1);
527  }
528 
529  return (void *)t;
530 
531 error:
532  if (t->luastate != NULL)
534  SCFree(t);
535  return NULL;
536 }
537 
538 static void DetectLuaThreadFree(void *ctx)
539 {
540  if (ctx != NULL) {
542  if (t->luastate != NULL)
544  SCFree(t);
545  }
546 }
547 
548 /**
549  * \brief Parse the lua keyword
550  *
551  * \param de_ctx Pointer to the detection engine context
552  * \param str Pointer to the user provided option
553  *
554  * \retval lua pointer to DetectLuaData on success
555  * \retval NULL on failure
556  */
557 static DetectLuaData *DetectLuaParse (DetectEngineCtx *de_ctx, const char *str)
558 {
559  DetectLuaData *lua = NULL;
560 
561  /* We have a correct lua option */
562  lua = SCCalloc(1, sizeof(DetectLuaData));
563  if (unlikely(lua == NULL))
564  goto error;
565 
566  if (strlen(str) && str[0] == '!') {
567  lua->negated = 1;
568  str++;
569  }
570 
571  /* get full filename */
573  if (lua->filename == NULL) {
574  goto error;
575  }
576 
577  return lua;
578 
579 error:
580  if (lua != NULL)
581  DetectLuaFree(de_ctx, lua);
582  return NULL;
583 }
584 
585 static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
586 {
587  int status;
588 
590  if (luastate == NULL)
591  return -1;
592  if (ld->allow_restricted_functions) {
593  luaL_openlibs(luastate);
594  SCLuaRequirefBuiltIns(luastate);
595  } else {
596  SCLuaSbLoadLibs(luastate);
597  }
598 
599  /* hackish, needed to allow unittests to pass buffers as scripts instead of files */
600 #ifdef UNITTESTS
601  if (ut_script != NULL) {
602  status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest");
603  if (status) {
604  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
605  goto error;
606  }
607  } else {
608 #endif
609  status = luaL_loadfile(luastate, ld->filename);
610  if (status) {
611  SCLogError("couldn't load file: %s", lua_tostring(luastate, -1));
612  goto error;
613  }
614 #ifdef UNITTESTS
615  }
616 #endif
617 
618  /* prime the script (or something) */
619  if (lua_pcall(luastate, 0, 0, 0) != 0) {
620  SCLogError("couldn't prime file: %s", lua_tostring(luastate, -1));
621  goto error;
622  }
623 
624  lua_getglobal(luastate, "init");
625  if (lua_type(luastate, -1) != LUA_TFUNCTION) {
626  SCLogError("no init function in script");
627  goto error;
628  }
629 
630  lua_newtable(luastate); /* stack at -1 */
631  if (lua_gettop(luastate) == 0 || lua_type(luastate, 2) != LUA_TTABLE) {
632  SCLogError("no table setup");
633  goto error;
634  }
635 
636  lua_pushliteral(luastate, "script_api_ver"); /* stack at -2 */
637  lua_pushnumber (luastate, 1); /* stack at -3 */
638  lua_settable(luastate, -3);
639 
640  if (lua_pcall(luastate, 1, 1, 0) != 0) {
641  SCLogError("couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
642  goto error;
643  }
644 
645  /* process returns from script */
646  if (lua_gettop(luastate) == 0) {
647  SCLogError("init function in script should return table, nothing returned");
648  goto error;
649  }
650  if (lua_type(luastate, 1) != LUA_TTABLE) {
651  SCLogError("init function in script should return table, returned is not table");
652  goto error;
653  }
654 
655  lua_pushnil(luastate);
656  const char *k, *v;
657  while (lua_next(luastate, -2)) {
658  k = lua_tostring(luastate, -2);
659  if (k == NULL)
660  continue;
661 
662  /* handle flowvar and bytes separately as they have a table as value */
663  if (strcmp(k, "flowvar") == 0) {
664  if (lua_istable(luastate, -1)) {
665  lua_pushnil(luastate);
666  while (lua_next(luastate, -2) != 0) {
667  /* value at -1, key is at -2 which we ignore */
668  const char *value = lua_tostring(luastate, -1);
669  SCLogDebug("value %s", value);
670  /* removes 'value'; keeps 'key' for next iteration */
671  lua_pop(luastate, 1);
672 
673  if (ld->flowvars == DETECT_LUA_MAX_FLOWVARS) {
674  SCLogError("too many flowvars registered");
675  goto error;
676  }
677 
678  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_VAR);
679  ld->flowvar[ld->flowvars++] = idx;
680  SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1);
681  }
682  }
683  lua_pop(luastate, 1);
684  continue;
685  } else if (strcmp(k, "flowint") == 0) {
686  if (lua_istable(luastate, -1)) {
687  lua_pushnil(luastate);
688  while (lua_next(luastate, -2) != 0) {
689  /* value at -1, key is at -2 which we ignore */
690  const char *value = lua_tostring(luastate, -1);
691  SCLogDebug("value %s", value);
692  /* removes 'value'; keeps 'key' for next iteration */
693  lua_pop(luastate, 1);
694 
695  if (ld->flowints == DETECT_LUA_MAX_FLOWINTS) {
696  SCLogError("too many flowints registered");
697  goto error;
698  }
699 
700  uint32_t idx = VarNameStoreRegister(value, VAR_TYPE_FLOW_INT);
701  ld->flowint[ld->flowints++] = idx;
702  SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1);
703  }
704  }
705  lua_pop(luastate, 1);
706  continue;
707  } else if (strcmp(k, "bytevar") == 0) {
708  if (lua_istable(luastate, -1)) {
709  lua_pushnil(luastate);
710  while (lua_next(luastate, -2) != 0) {
711  /* value at -1, key is at -2 which we ignore */
712  const char *value = lua_tostring(luastate, -1);
713  SCLogDebug("value %s", value);
714  /* removes 'value'; keeps 'key' for next iteration */
715  lua_pop(luastate, 1);
716 
717  if (ld->bytevars == DETECT_LUA_MAX_BYTEVARS) {
718  SCLogError("too many bytevars registered");
719  goto error;
720  }
721 
723  if (!DetectByteRetrieveSMVar(value, s, &idx)) {
724  SCLogError("Unknown byte_extract or byte_math var "
725  "requested by lua script - %s",
726  value);
727  goto error;
728  }
729  ld->bytevar[ld->bytevars++] = idx;
730  SCLogDebug("script uses bytevar %u with script id %u", idx, ld->bytevars - 1);
731  }
732  }
733  lua_pop(luastate, 1);
734  continue;
735  }
736 
737  v = lua_tostring(luastate, -1);
738  lua_pop(luastate, 1);
739  if (v == NULL)
740  continue;
741 
742  SCLogDebug("k='%s', v='%s'", k, v);
743  if (strcmp(k, "packet") == 0 && strcmp(v, "true") == 0) {
745  } else if (strcmp(k, "payload") == 0 && strcmp(v, "true") == 0) {
747  } else if (strcmp(k, "buffer") == 0 && strcmp(v, "true") == 0) {
749 
750  ld->buffername = SCStrdup("buffer");
751  if (ld->buffername == NULL) {
752  SCLogError("alloc error");
753  goto error;
754  }
755  } else if (strcmp(k, "stream") == 0 && strcmp(v, "true") == 0) {
757 
758  ld->buffername = SCStrdup("stream");
759  if (ld->buffername == NULL) {
760  SCLogError("alloc error");
761  goto error;
762  }
763 
764  } else if (strncmp(k, "http", 4) == 0 && strcmp(v, "true") == 0) {
765  if (ld->alproto != ALPROTO_UNKNOWN && ld->alproto != ALPROTO_HTTP1) {
766  SCLogError(
767  "can just inspect script against one app layer proto like HTTP at a time");
768  goto error;
769  }
770  if (ld->flags != 0) {
771  SCLogError("when inspecting HTTP buffers only a single buffer can be inspected");
772  goto error;
773  }
774 
775  /* http types */
776  ld->alproto = ALPROTO_HTTP1;
777 
778  if (strcmp(k, "http.uri") == 0)
780 
781  else if (strcmp(k, "http.uri.raw") == 0)
783 
784  else if (strcmp(k, "http.request_line") == 0)
786 
787  else if (strcmp(k, "http.request_headers") == 0)
789 
790  else if (strcmp(k, "http.request_headers.raw") == 0)
792 
793  else if (strcmp(k, "http.request_cookie") == 0)
795 
796  else if (strcmp(k, "http.request_user_agent") == 0)
798 
799  else if (strcmp(k, "http.request_body") == 0)
801 
802  else if (strcmp(k, "http.response_body") == 0)
804 
805  else if (strcmp(k, "http.response_cookie") == 0)
807 
808  else if (strcmp(k, "http.response_headers") == 0)
810 
811  else if (strcmp(k, "http.response_headers.raw") == 0)
813 
814  else {
815  SCLogError("unsupported http data type %s", k);
816  goto error;
817  }
818 
819  ld->buffername = SCStrdup(k);
820  if (ld->buffername == NULL) {
821  SCLogError("alloc error");
822  goto error;
823  }
824  } else if (strncmp(k, "dns", 3) == 0 && strcmp(v, "true") == 0) {
825 
826  ld->alproto = ALPROTO_DNS;
827 
828  if (strcmp(k, "dns.rrname") == 0)
830  else if (strcmp(k, "dns.request") == 0)
832  else if (strcmp(k, "dns.response") == 0)
834 
835  else {
836  SCLogError("unsupported dns data type %s", k);
837  goto error;
838  }
839  ld->buffername = SCStrdup(k);
840  if (ld->buffername == NULL) {
841  SCLogError("alloc error");
842  goto error;
843  }
844  } else if (strncmp(k, "tls", 3) == 0 && strcmp(v, "true") == 0) {
845 
846  ld->alproto = ALPROTO_TLS;
847 
848  } else if (strncmp(k, "ssh", 3) == 0 && strcmp(v, "true") == 0) {
849 
850  ld->alproto = ALPROTO_SSH;
851 
852  ld->flags |= FLAG_DATATYPE_SSH;
853 
854  } else if (strncmp(k, "smtp", 4) == 0 && strcmp(v, "true") == 0) {
855 
856  ld->alproto = ALPROTO_SMTP;
857 
858  ld->flags |= FLAG_DATATYPE_SMTP;
859 
860  } else if (strncmp(k, "dnp3", 4) == 0 && strcmp(v, "true") == 0) {
861 
862  ld->alproto = ALPROTO_DNP3;
863 
864  ld->flags |= FLAG_DATATYPE_DNP3;
865 
866  } else {
867  SCLogError("unsupported data type %s", k);
868  goto error;
869  }
870  }
871 
872  /* pop the table */
873  lua_pop(luastate, 1);
874  SCLuaSbStateClose(luastate);
875  return 0;
876 error:
877  SCLuaSbStateClose(luastate);
878  return -1;
879 }
880 
881 /**
882  * \brief this function is used to parse lua options
883  * \brief into the current signature
884  *
885  * \param de_ctx pointer to the Detection Engine Context
886  * \param s pointer to the Current Signature
887  * \param str pointer to the user provided "lua" option
888  *
889  * \retval 0 on Success
890  * \retval -1 on Failure
891  */
892 static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
893 {
894  /* First check if Lua rules are enabled, by default Lua in rules
895  * is disabled. */
896  int enabled = 0;
897  (void)ConfGetBool("security.lua.allow-rules", &enabled);
898  if (!enabled) {
899  SCLogError("Lua rules disabled by security configuration: security.lua.allow-rules");
900  return -1;
901  }
902 
903  DetectLuaData *lua = DetectLuaParse(de_ctx, str);
904  if (lua == NULL)
905  return -1;
906 
907  /* Load lua sandbox configurations */
908  intmax_t lua_alloc_limit = DEFAULT_LUA_ALLOC_LIMIT;
909  intmax_t lua_instruction_limit = DEFAULT_LUA_INSTRUCTION_LIMIT;
910  (void)ConfGetInt("security.lua.max-bytes", &lua_alloc_limit);
911  (void)ConfGetInt("security.lua.max-instructions", &lua_instruction_limit);
912  lua->alloc_limit = lua_alloc_limit;
913  lua->instruction_limit = lua_instruction_limit;
914 
915  int allow_restricted_functions = 0;
916  (void)ConfGetBool("security.lua.allow-restricted-functions", &allow_restricted_functions);
917  lua->allow_restricted_functions = allow_restricted_functions;
918 
919  if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
920  goto error;
921  }
922 
924  DetectLuaThreadInit, (void *)lua,
925  DetectLuaThreadFree, 0);
926  if (lua->thread_ctx_id == -1)
927  goto error;
928 
929  if (lua->alproto != ALPROTO_UNKNOWN) {
930  if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, lua->alproto)) {
931  goto error;
932  }
933  s->alproto = lua->alproto;
934  }
935 
936  /* Okay so far so good, lets get this into a SigMatch
937  * and put it in the Signature. */
938 
939  int list = -1;
940  if (lua->alproto == ALPROTO_UNKNOWN) {
941  if (lua->flags & FLAG_DATATYPE_STREAM)
942  list = DETECT_SM_LIST_PMATCH;
943  else {
944  if (lua->flags & FLAG_DATATYPE_BUFFER) {
945  if (DetectBufferGetActiveList(de_ctx, s) != -1) {
946  list = s->init_data->list;
947  } else {
948  SCLogError("Lua and sticky buffer failure");
949  goto error;
950  }
951  } else
952  list = DETECT_SM_LIST_MATCH;
953  }
954 
955  } else if (lua->alproto == ALPROTO_HTTP1) {
957  list = DetectBufferTypeGetByName("file_data");
958  } else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_BODY) {
959  list = DetectBufferTypeGetByName("http_client_body");
960  } else if (lua->flags & FLAG_DATATYPE_HTTP_URI) {
961  list = DetectBufferTypeGetByName("http_uri");
962  } else if (lua->flags & FLAG_DATATYPE_HTTP_URI_RAW) {
963  list = DetectBufferTypeGetByName("http_raw_uri");
964  } else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_COOKIE ||
966  list = DetectBufferTypeGetByName("http_cookie");
967  } else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_UA) {
968  list = DetectBufferTypeGetByName("http_user_agent");
969  } else if (lua->flags &
971  list = DetectBufferTypeGetByName("http_header");
972  } else if (lua->flags & (FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW |
974  list = DetectBufferTypeGetByName("http_raw_header");
975  } else {
976  list = DetectBufferTypeGetByName("http_request_line");
977  }
978  } else if (lua->alproto == ALPROTO_DNS) {
979  if (lua->flags & FLAG_DATATYPE_DNS_RRNAME) {
980  list = DetectBufferTypeGetByName("dns_query");
981  } else if (lua->flags & FLAG_DATATYPE_DNS_REQUEST) {
982  list = DetectBufferTypeGetByName("dns_request");
983  } else if (lua->flags & FLAG_DATATYPE_DNS_RESPONSE) {
984  list = DetectBufferTypeGetByName("dns_response");
985  }
986  } else if (lua->alproto == ALPROTO_TLS) {
987  list = DetectBufferTypeGetByName("tls_generic");
988  } else if (lua->alproto == ALPROTO_SSH) {
989  list = DetectBufferTypeGetByName("ssh_banner");
990  } else if (lua->alproto == ALPROTO_SMTP) {
991  list = g_smtp_generic_list_id;
992  } else if (lua->alproto == ALPROTO_DNP3) {
993  list = DetectBufferTypeGetByName("dnp3");
994  } else {
995  SCLogError("lua can't be used with protocol %s", AppLayerGetProtoName(lua->alproto));
996  goto error;
997  }
998 
999  if (list == -1) {
1000  SCLogError("lua can't be used with protocol %s", AppLayerGetProtoName(lua->alproto));
1001  goto error;
1002  }
1003 
1004  if (SigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
1005  goto error;
1006  }
1007 
1008  return 0;
1009 
1010 error:
1011  if (lua != NULL)
1012  DetectLuaFree(de_ctx, lua);
1013  return -1;
1014 }
1015 
1016 /** \brief post-sig parse function to set the sid,rev,gid into the
1017  * ctx, as this isn't available yet during parsing.
1018  */
1020 {
1021  int i;
1022  SigMatch *sm;
1023 
1024  for (i = 0; i < DETECT_SM_LIST_MAX; i++) {
1025  for (sm = s->init_data->smlists[i]; sm != NULL; sm = sm->next) {
1026  if (sm->type != DETECT_LUA)
1027  continue;
1028 
1029  DetectLuaData *ld = (DetectLuaData *)sm->ctx;
1030  ld->sid = s->id;
1031  ld->rev = s->rev;
1032  ld->gid = s->gid;
1033  }
1034  }
1035 }
1036 
1037 /**
1038  * \brief this function will free memory associated with DetectLuaData
1039  *
1040  * \param ptr pointer to DetectLuaData
1041  */
1042 static void DetectLuaFree(DetectEngineCtx *de_ctx, void *ptr)
1043 {
1044  if (ptr != NULL) {
1045  DetectLuaData *lua = (DetectLuaData *)ptr;
1046 
1047  if (lua->buffername)
1048  SCFree(lua->buffername);
1049  if (lua->filename)
1050  SCFree(lua->filename);
1051 
1052  for (uint16_t i = 0; i < lua->flowints; i++) {
1054  }
1055  for (uint16_t i = 0; i < lua->flowvars; i++) {
1057  }
1058 
1060 
1061  SCFree(lua);
1062  }
1063 }
1064 
1065 #ifdef UNITTESTS
1066 #include "detect-engine-alert.h"
1067 
1068 /** \test http buffer */
1069 static int LuaMatchTest01(void)
1070 {
1071  ConfSetFinal("security.lua.allow-rules", "true");
1072 
1073  const char script[] =
1074  "function init (args)\n"
1075  " local needs = {}\n"
1076  " needs[\"http.request_headers\"] = tostring(true)\n"
1077  " needs[\"flowvar\"] = {\"cnt\"}\n"
1078  " return needs\n"
1079  "end\n"
1080  "\n"
1081  "function match(args)\n"
1082  " a = ScFlowvarGet(0)\n"
1083  " if a then\n"
1084  " a = tostring(tonumber(a)+1)\n"
1085  " print (a)\n"
1086  " ScFlowvarSet(0, a, #a)\n"
1087  " else\n"
1088  " a = tostring(1)\n"
1089  " print (a)\n"
1090  " ScFlowvarSet(0, a, #a)\n"
1091  " end\n"
1092  " \n"
1093  " print (\"pre check: \" .. (a))\n"
1094  " if tonumber(a) == 2 then\n"
1095  " print \"match\"\n"
1096  " return 1\n"
1097  " end\n"
1098  " return 0\n"
1099  "end\n"
1100  "return 0\n";
1101  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1102  uint8_t httpbuf1[] =
1103  "POST / HTTP/1.1\r\n"
1104  "Host: www.emergingthreats.net\r\n\r\n";
1105  uint8_t httpbuf2[] =
1106  "POST / HTTP/1.1\r\n"
1107  "Host: www.openinfosecfoundation.org\r\n\r\n";
1108  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1109  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1110  TcpSession ssn;
1111  Flow f;
1112  ThreadVars th_v;
1113  DetectEngineThreadCtx *det_ctx;
1114 
1116 
1117  ut_script = script;
1118 
1119  memset(&th_v, 0, sizeof(th_v));
1120  memset(&f, 0, sizeof(f));
1121  memset(&ssn, 0, sizeof(ssn));
1122 
1123  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1124  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1125 
1126  FLOW_INITIALIZE(&f);
1127  f.protoctx = (void *)&ssn;
1128  f.proto = IPPROTO_TCP;
1129  f.flags |= FLOW_IPV4;
1130  f.alproto = ALPROTO_HTTP1;
1131 
1132  p1->flow = &f;
1136  p2->flow = &f;
1140 
1141  StreamTcpInitConfig(true);
1142 
1145  de_ctx->flags |= DE_QUIET;
1146 
1148  FAIL_IF_NULL(s);
1149 
1151  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1152 
1153  int r = AppLayerParserParse(
1154  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1155  FAIL_IF(r != 0);
1156  HtpState *http_state = f.alstate;
1157  FAIL_IF_NULL(http_state);
1158 
1159  /* do detect for p1 */
1160  SCLogDebug("inspecting p1");
1161  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1162 
1163  FAIL_IF(PacketAlertCheck(p1, 1));
1164 
1165  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1166  FAIL_IF(r != 0);
1167 
1168  /* do detect for p2 */
1169  SCLogDebug("inspecting p2");
1170  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1171 
1172  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1173 
1174  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1175  FAIL_IF(id == 0);
1176 
1177  FlowVar *fv = FlowVarGet(&f, id);
1178  FAIL_IF_NULL(fv);
1179 
1180  FAIL_IF(fv->data.fv_str.value_len != 1);
1181 
1182  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1183 
1186 
1187  StreamTcpFreeConfig(true);
1188  FLOW_DESTROY(&f);
1189  UTHFreePackets(&p1, 1);
1190  UTHFreePackets(&p2, 1);
1191  PASS;
1192 }
1193 
1194 static int LuaMatchTest01a(void)
1195 {
1196  const char script[] = "function init (args)\n"
1197  " local needs = {}\n"
1198  " needs[\"http.request_headers\"] = tostring(true)\n"
1199  " needs[\"flowvar\"] = {\"cnt\"}\n"
1200  " return needs\n"
1201  "end\n"
1202  "\n"
1203  "function match(args)\n"
1204  " a = SCFlowvarGet(0)\n"
1205  " if a then\n"
1206  " a = tostring(tonumber(a)+1)\n"
1207  " print (a)\n"
1208  " SCFlowvarSet(0, a, #a)\n"
1209  " else\n"
1210  " a = tostring(1)\n"
1211  " print (a)\n"
1212  " SCFlowvarSet(0, a, #a)\n"
1213  " end\n"
1214  " \n"
1215  " print (\"pre check: \" .. (a))\n"
1216  " if tonumber(a) == 2 then\n"
1217  " print \"match\"\n"
1218  " return 1\n"
1219  " end\n"
1220  " return 0\n"
1221  "end\n"
1222  "return 0\n";
1223  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1224  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1225  "Host: www.emergingthreats.net\r\n\r\n";
1226  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1227  "Host: www.openinfosecfoundation.org\r\n\r\n";
1228  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1229  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1230  TcpSession ssn;
1231  Flow f;
1232  ThreadVars th_v;
1233  DetectEngineThreadCtx *det_ctx;
1234 
1236 
1237  ut_script = script;
1238 
1239  memset(&th_v, 0, sizeof(th_v));
1240  memset(&f, 0, sizeof(f));
1241  memset(&ssn, 0, sizeof(ssn));
1242 
1243  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1244  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1245 
1246  FLOW_INITIALIZE(&f);
1247  f.protoctx = (void *)&ssn;
1248  f.proto = IPPROTO_TCP;
1249  f.flags |= FLOW_IPV4;
1250  f.alproto = ALPROTO_HTTP1;
1251 
1252  p1->flow = &f;
1256  p2->flow = &f;
1260 
1261  StreamTcpInitConfig(true);
1262 
1265  de_ctx->flags |= DE_QUIET;
1266 
1268  FAIL_IF_NULL(s);
1269 
1271  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1272 
1273  int r = AppLayerParserParse(
1274  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1275  FAIL_IF(r != 0);
1276 
1277  HtpState *http_state = f.alstate;
1278  FAIL_IF_NULL(http_state);
1279 
1280  /* do detect for p1 */
1281  SCLogDebug("inspecting p1");
1282  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1283 
1284  FAIL_IF(PacketAlertCheck(p1, 1));
1285 
1286  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1287  FAIL_IF(r != 0);
1288  /* do detect for p2 */
1289  SCLogDebug("inspecting p2");
1290  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1291 
1292  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1293 
1294  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1295  FAIL_IF(id == 0);
1296 
1297  FlowVar *fv = FlowVarGet(&f, id);
1298  FAIL_IF_NULL(fv);
1299 
1300  FAIL_IF(fv->data.fv_str.value_len != 1);
1301 
1302  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1303 
1306 
1307  StreamTcpFreeConfig(true);
1308  FLOW_DESTROY(&f);
1309  UTHFreePackets(&p1, 1);
1310  UTHFreePackets(&p2, 1);
1311  PASS;
1312 }
1313 
1314 /** \test payload buffer */
1315 static int LuaMatchTest02(void)
1316 {
1317  const char script[] = "function init (args)\n"
1318  " local needs = {}\n"
1319  " needs[\"payload\"] = tostring(true)\n"
1320  " needs[\"flowvar\"] = {\"cnt\"}\n"
1321  " return needs\n"
1322  "end\n"
1323  "\n"
1324  "function match(args)\n"
1325  " a = ScFlowvarGet(0)\n"
1326  " if a then\n"
1327  " a = tostring(tonumber(a)+1)\n"
1328  " print (a)\n"
1329  " ScFlowvarSet(0, a, #a)\n"
1330  " else\n"
1331  " a = tostring(1)\n"
1332  " print (a)\n"
1333  " ScFlowvarSet(0, a, #a)\n"
1334  " end\n"
1335  " \n"
1336  " print (\"pre check: \" .. (a))\n"
1337  " if tonumber(a) == 2 then\n"
1338  " print \"match\"\n"
1339  " return 1\n"
1340  " end\n"
1341  " return 0\n"
1342  "end\n"
1343  "return 0\n";
1344  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1345  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1346  "Host: www.emergingthreats.net\r\n\r\n";
1347  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1348  "Host: www.openinfosecfoundation.org\r\n\r\n";
1349  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1350  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1351  TcpSession ssn;
1352  Flow f;
1353  ThreadVars th_v;
1354  DetectEngineThreadCtx *det_ctx;
1355 
1356  ut_script = script;
1357 
1358  memset(&th_v, 0, sizeof(th_v));
1359  memset(&f, 0, sizeof(f));
1360  memset(&ssn, 0, sizeof(ssn));
1361 
1362  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1363  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1364 
1365  FLOW_INITIALIZE(&f);
1366  f.protoctx = (void *)&ssn;
1367  f.proto = IPPROTO_TCP;
1368  f.flags |= FLOW_IPV4;
1369  f.alproto = ALPROTO_HTTP1;
1370 
1371  p1->flow = &f;
1375  p2->flow = &f;
1379 
1380  StreamTcpInitConfig(true);
1381 
1384  de_ctx->flags |= DE_QUIET;
1385 
1387  FAIL_IF_NULL(s);
1388 
1390  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1391 
1392  /* do detect for p1 */
1393  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1394 
1395  FAIL_IF(PacketAlertCheck(p1, 1));
1396 
1397  /* do detect for p2 */
1398  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1399 
1400  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1401 
1402  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1403  FAIL_IF(id == 0);
1404 
1405  FlowVar *fv = FlowVarGet(&f, id);
1406  FAIL_IF_NULL(fv);
1407 
1408  FAIL_IF(fv->data.fv_str.value_len != 1);
1409 
1410  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1411 
1413 
1414  StreamTcpFreeConfig(true);
1415  FLOW_DESTROY(&f);
1416  UTHFreePackets(&p1, 1);
1417  UTHFreePackets(&p2, 1);
1418  PASS;
1419 }
1420 
1421 /** \test payload buffer */
1422 static int LuaMatchTest02a(void)
1423 {
1424  const char script[] = "function init (args)\n"
1425  " local needs = {}\n"
1426  " needs[\"payload\"] = tostring(true)\n"
1427  " needs[\"flowvar\"] = {\"cnt\"}\n"
1428  " return needs\n"
1429  "end\n"
1430  "\n"
1431  "function match(args)\n"
1432  " a = SCFlowvarGet(0)\n"
1433  " if a then\n"
1434  " a = tostring(tonumber(a)+1)\n"
1435  " print (a)\n"
1436  " SCFlowvarSet(0, a, #a)\n"
1437  " else\n"
1438  " a = tostring(1)\n"
1439  " print (a)\n"
1440  " SCFlowvarSet(0, 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 
1506  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1507 
1508  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1509  FAIL_IF(id == 0);
1510 
1511  FlowVar *fv = FlowVarGet(&f, id);
1512  FAIL_IF_NULL(fv);
1513 
1514  FAIL_IF(fv->data.fv_str.value_len != 1);
1515 
1516  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1517 
1519 
1520  StreamTcpFreeConfig(true);
1521  FLOW_DESTROY(&f);
1522  UTHFreePackets(&p1, 1);
1523  UTHFreePackets(&p2, 1);
1524  PASS;
1525 }
1526 
1527 /** \test packet buffer */
1528 static int LuaMatchTest03(void)
1529 {
1530  const char script[] = "function init (args)\n"
1531  " local needs = {}\n"
1532  " needs[\"packet\"] = tostring(true)\n"
1533  " needs[\"flowvar\"] = {\"cnt\"}\n"
1534  " return needs\n"
1535  "end\n"
1536  "\n"
1537  "function match(args)\n"
1538  " a = ScFlowvarGet(0)\n"
1539  " if a then\n"
1540  " a = tostring(tonumber(a)+1)\n"
1541  " print (a)\n"
1542  " ScFlowvarSet(0, a, #a)\n"
1543  " else\n"
1544  " a = tostring(1)\n"
1545  " print (a)\n"
1546  " ScFlowvarSet(0, a, #a)\n"
1547  " end\n"
1548  " \n"
1549  " print (\"pre check: \" .. (a))\n"
1550  " if tonumber(a) == 2 then\n"
1551  " print \"match\"\n"
1552  " return 1\n"
1553  " end\n"
1554  " return 0\n"
1555  "end\n"
1556  "return 0\n";
1557  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; 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 
1569  ut_script = script;
1570 
1571  memset(&th_v, 0, sizeof(th_v));
1572  memset(&f, 0, sizeof(f));
1573  memset(&ssn, 0, sizeof(ssn));
1574 
1575  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1576  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1577 
1578  FLOW_INITIALIZE(&f);
1579  f.protoctx = (void *)&ssn;
1580  f.proto = IPPROTO_TCP;
1581  f.flags |= FLOW_IPV4;
1582  f.alproto = ALPROTO_HTTP1;
1583 
1584  p1->flow = &f;
1588  p2->flow = &f;
1592 
1593  StreamTcpInitConfig(true);
1594 
1597  de_ctx->flags |= DE_QUIET;
1598 
1600  FAIL_IF_NULL(s);
1601 
1603  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1604 
1605  /* do detect for p1 */
1606  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1607  FAIL_IF(PacketAlertCheck(p1, 1));
1608 
1609  /* do detect for p2 */
1610  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1611 
1612  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1613 
1614  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1615  FAIL_IF(id == 0);
1616 
1617  FlowVar *fv = FlowVarGet(&f, id);
1618  FAIL_IF_NULL(fv);
1619 
1620  FAIL_IF(fv->data.fv_str.value_len != 1);
1621 
1622  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1623 
1625 
1626  StreamTcpFreeConfig(true);
1627  FLOW_DESTROY(&f);
1628  UTHFreePackets(&p1, 1);
1629  UTHFreePackets(&p2, 1);
1630  PASS;
1631 }
1632 
1633 /** \test packet buffer */
1634 static int LuaMatchTest03a(void)
1635 {
1636  const char script[] = "function init (args)\n"
1637  " local needs = {}\n"
1638  " needs[\"packet\"] = tostring(true)\n"
1639  " needs[\"flowvar\"] = {\"cnt\"}\n"
1640  " return needs\n"
1641  "end\n"
1642  "\n"
1643  "function match(args)\n"
1644  " a = SCFlowvarGet(0)\n"
1645  " if a then\n"
1646  " a = tostring(tonumber(a)+1)\n"
1647  " print (a)\n"
1648  " SCFlowvarSet(0, a, #a)\n"
1649  " else\n"
1650  " a = tostring(1)\n"
1651  " print (a)\n"
1652  " SCFlowvarSet(0, a, #a)\n"
1653  " end\n"
1654  " \n"
1655  " print (\"pre check: \" .. (a))\n"
1656  " if tonumber(a) == 2 then\n"
1657  " print \"match\"\n"
1658  " return 1\n"
1659  " end\n"
1660  " return 0\n"
1661  "end\n"
1662  "return 0\n";
1663  char sig[] = "alert tcp any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1664  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1665  "Host: www.emergingthreats.net\r\n\r\n";
1666  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1667  "Host: www.openinfosecfoundation.org\r\n\r\n";
1668  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1669  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1670  TcpSession ssn;
1671  Flow f;
1672  ThreadVars th_v;
1673  DetectEngineThreadCtx *det_ctx;
1674 
1675  ut_script = script;
1676 
1677  memset(&th_v, 0, sizeof(th_v));
1678  memset(&f, 0, sizeof(f));
1679  memset(&ssn, 0, sizeof(ssn));
1680 
1681  Packet *p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP);
1682  Packet *p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP);
1683 
1684  FLOW_INITIALIZE(&f);
1685  f.protoctx = (void *)&ssn;
1686  f.proto = IPPROTO_TCP;
1687  f.flags |= FLOW_IPV4;
1688  f.alproto = ALPROTO_HTTP1;
1689 
1690  p1->flow = &f;
1694  p2->flow = &f;
1698 
1699  StreamTcpInitConfig(true);
1700 
1703  de_ctx->flags |= DE_QUIET;
1704 
1706  FAIL_IF_NULL(s);
1707 
1709  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1710 
1711  /* do detect for p1 */
1712  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1713  FAIL_IF(PacketAlertCheck(p1, 1));
1714 
1715  /* do detect for p2 */
1716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1717  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1718 
1719  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_VAR);
1720  FAIL_IF(id == 0);
1721 
1722  FlowVar *fv = FlowVarGet(&f, id);
1723  FAIL_IF_NULL(fv);
1724 
1725  FAIL_IF(fv->data.fv_str.value_len != 1);
1726 
1727  FAIL_IF(memcmp(fv->data.fv_str.value, "2", 1) != 0);
1728 
1730 
1731  StreamTcpFreeConfig(true);
1732  FLOW_DESTROY(&f);
1733  UTHFreePackets(&p1, 1);
1734  UTHFreePackets(&p2, 1);
1735  PASS;
1736 }
1737 
1738 /** \test http buffer, flowints */
1739 static int LuaMatchTest04(void)
1740 {
1741  const char script[] = "function init (args)\n"
1742  " local needs = {}\n"
1743  " needs[\"http.request_headers\"] = tostring(true)\n"
1744  " needs[\"flowint\"] = {\"cnt\"}\n"
1745  " return needs\n"
1746  "end\n"
1747  "\n"
1748  "function match(args)\n"
1749  " print \"inspecting\""
1750  " a = ScFlowintGet(0)\n"
1751  " if a then\n"
1752  " ScFlowintSet(0, a + 1)\n"
1753  " else\n"
1754  " ScFlowintSet(0, 1)\n"
1755  " end\n"
1756  " \n"
1757  " a = ScFlowintGet(0)\n"
1758  " if a == 2 then\n"
1759  " print \"match\"\n"
1760  " return 1\n"
1761  " end\n"
1762  " return 0\n"
1763  "end\n"
1764  "return 0\n";
1765  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1766  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"
1767  "Host: www.emergingthreats.net\r\n\r\n";
1768  uint8_t httpbuf2[] = "POST / HTTP/1.1\r\n"
1769  "Host: www.openinfosecfoundation.org\r\n\r\n";
1770  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1771  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1772  TcpSession ssn;
1773  Flow f;
1774  ThreadVars th_v;
1775  DetectEngineThreadCtx *det_ctx;
1776 
1778 
1779  ut_script = script;
1780 
1781  memset(&th_v, 0, sizeof(th_v));
1782  memset(&f, 0, sizeof(f));
1783  memset(&ssn, 0, sizeof(ssn));
1784 
1785  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1786  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1787 
1788  FLOW_INITIALIZE(&f);
1789  f.protoctx = (void *)&ssn;
1790  f.proto = IPPROTO_TCP;
1791  f.flags |= FLOW_IPV4;
1792  f.alproto = ALPROTO_HTTP1;
1793 
1794  p1->flow = &f;
1798 
1799  p2->flow = &f;
1803 
1804  StreamTcpInitConfig(true);
1805 
1808  de_ctx->flags |= DE_QUIET;
1809 
1811  FAIL_IF_NULL(s);
1812 
1814  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1815 
1816  int r = AppLayerParserParse(
1817  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1818  FAIL_IF(r != 0);
1819  HtpState *http_state = f.alstate;
1820  FAIL_IF_NULL(http_state);
1821 
1822  /* do detect for p1 */
1823  SCLogInfo("p1");
1824  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1825 
1826  FAIL_IF(PacketAlertCheck(p1, 1));
1827 
1828  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1829  FAIL_IF(r != 0);
1830  /* do detect for p2 */
1831  SCLogInfo("p2");
1832  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1833 
1834  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1835 
1836  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1837  FAIL_IF(id == 0);
1838 
1839  FlowVar *fv = FlowVarGet(&f, id);
1840  FAIL_IF_NULL(fv);
1841 
1842  FAIL_IF(fv->data.fv_int.value != 2);
1843 
1846 
1847  StreamTcpFreeConfig(true);
1848  FLOW_DESTROY(&f);
1849  UTHFreePackets(&p1, 1);
1850  UTHFreePackets(&p2, 1);
1851  PASS;
1852 }
1853 
1854 /** \test http buffer, flowints */
1855 static int LuaMatchTest04a(void)
1856 {
1857  const char script[] = "function init (args)\n"
1858  " local needs = {}\n"
1859  " needs[\"http.request_headers\"] = tostring(true)\n"
1860  " needs[\"flowint\"] = {\"cnt\"}\n"
1861  " return needs\n"
1862  "end\n"
1863  "\n"
1864  "function match(args)\n"
1865  " print \"inspecting\""
1866  " a = SCFlowintGet(0)\n"
1867  " if a then\n"
1868  " SCFlowintSet(0, a + 1)\n"
1869  " else\n"
1870  " SCFlowintSet(0, 1)\n"
1871  " end\n"
1872  " \n"
1873  " a = SCFlowintGet(0)\n"
1874  " if a == 2 then\n"
1875  " print \"match\"\n"
1876  " return 1\n"
1877  " end\n"
1878  " return 0\n"
1879  "end\n"
1880  "return 0\n";
1881  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1882  uint8_t httpbuf1[] =
1883  "POST / HTTP/1.1\r\n"
1884  "Host: www.emergingthreats.net\r\n\r\n";
1885  uint8_t httpbuf2[] =
1886  "POST / HTTP/1.1\r\n"
1887  "Host: www.openinfosecfoundation.org\r\n\r\n";
1888  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1889  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1890  TcpSession ssn;
1891  Flow f;
1892  ThreadVars th_v;
1893  DetectEngineThreadCtx *det_ctx;
1894 
1896 
1897  ut_script = script;
1898 
1899  memset(&th_v, 0, sizeof(th_v));
1900  memset(&f, 0, sizeof(f));
1901  memset(&ssn, 0, sizeof(ssn));
1902 
1903  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1904  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1905 
1906  FLOW_INITIALIZE(&f);
1907  f.protoctx = (void *)&ssn;
1908  f.proto = IPPROTO_TCP;
1909  f.flags |= FLOW_IPV4;
1910  f.alproto = ALPROTO_HTTP1;
1911 
1912  p1->flow = &f;
1916 
1917  p2->flow = &f;
1921 
1922  StreamTcpInitConfig(true);
1923 
1926  de_ctx->flags |= DE_QUIET;
1927 
1929  FAIL_IF_NULL(s);
1930 
1932  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1933 
1934  int r = AppLayerParserParse(
1935  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
1936  FAIL_IF(r != 0);
1937  HtpState *http_state = f.alstate;
1938  FAIL_IF_NULL(http_state);
1939 
1940  /* do detect for p1 */
1941  SCLogInfo("p1");
1942  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1943 
1944  FAIL_IF(PacketAlertCheck(p1, 1));
1945 
1946  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1947  FAIL_IF(r != 0);
1948  /* do detect for p2 */
1949  SCLogInfo("p2");
1950  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1951 
1952  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
1953 
1954  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
1955  FAIL_IF(id == 0);
1956 
1957  FlowVar *fv = FlowVarGet(&f, id);
1958  FAIL_IF_NULL(fv);
1959 
1960  FAIL_IF(fv->data.fv_int.value != 2);
1961 
1964 
1965  StreamTcpFreeConfig(true);
1966  FLOW_DESTROY(&f);
1967  UTHFreePackets(&p1, 1);
1968  UTHFreePackets(&p2, 1);
1969  PASS;
1970 }
1971 
1972 /** \test http buffer, flowints */
1973 static int LuaMatchTest05(void)
1974 {
1975  const char script[] = "function init (args)\n"
1976  " local needs = {}\n"
1977  " needs[\"http.request_headers\"] = tostring(true)\n"
1978  " needs[\"flowint\"] = {\"cnt\"}\n"
1979  " return needs\n"
1980  "end\n"
1981  "\n"
1982  "function match(args)\n"
1983  " print \"inspecting\""
1984  " a = ScFlowintIncr(0)\n"
1985  " if a == 2 then\n"
1986  " print \"match\"\n"
1987  " return 1\n"
1988  " end\n"
1989  " return 0\n"
1990  "end\n"
1991  "return 0\n";
1992  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
1993  uint8_t httpbuf1[] =
1994  "POST / HTTP/1.1\r\n"
1995  "Host: www.emergingthreats.net\r\n\r\n";
1996  uint8_t httpbuf2[] =
1997  "POST / HTTP/1.1\r\n"
1998  "Host: www.openinfosecfoundation.org\r\n\r\n";
1999  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2000  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2001  TcpSession ssn;
2002  Flow f;
2003  ThreadVars th_v;
2004  DetectEngineThreadCtx *det_ctx;
2005 
2007 
2008  ut_script = script;
2009 
2010  memset(&th_v, 0, sizeof(th_v));
2011  memset(&f, 0, sizeof(f));
2012  memset(&ssn, 0, sizeof(ssn));
2013 
2014  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2015  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2016 
2017  FLOW_INITIALIZE(&f);
2018  f.protoctx = (void *)&ssn;
2019  f.proto = IPPROTO_TCP;
2020  f.flags |= FLOW_IPV4;
2021  f.alproto = ALPROTO_HTTP1;
2022 
2023  p1->flow = &f;
2027 
2028  p2->flow = &f;
2032 
2033  StreamTcpInitConfig(true);
2034 
2037  de_ctx->flags |= DE_QUIET;
2038 
2040  FAIL_IF_NULL(s);
2041 
2043  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2044 
2045  int r = AppLayerParserParse(
2046  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2047  FAIL_IF(r != 0);
2048  HtpState *http_state = f.alstate;
2049  FAIL_IF_NULL(http_state);
2050 
2051  /* do detect for p1 */
2052  SCLogInfo("p1");
2053  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2054 
2055  FAIL_IF(PacketAlertCheck(p1, 1));
2056 
2057  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2058  FAIL_IF(r != 0);
2059  /* do detect for p2 */
2060  SCLogInfo("p2");
2061  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2062 
2063  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2064 
2065  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2066  FAIL_IF(id == 0);
2067 
2068  FlowVar *fv = FlowVarGet(&f, id);
2069  FAIL_IF_NULL(fv);
2070 
2071  FAIL_IF(fv->data.fv_int.value != 2);
2072 
2075 
2076  StreamTcpFreeConfig(true);
2077  FLOW_DESTROY(&f);
2078  UTHFreePackets(&p1, 1);
2079  UTHFreePackets(&p2, 1);
2080  PASS;
2081 }
2082 
2083 /** \test http buffer, flowints */
2084 static int LuaMatchTest05a(void)
2085 {
2086  const char script[] = "function init (args)\n"
2087  " local needs = {}\n"
2088  " needs[\"http.request_headers\"] = tostring(true)\n"
2089  " needs[\"flowint\"] = {\"cnt\"}\n"
2090  " return needs\n"
2091  "end\n"
2092  "\n"
2093  "function match(args)\n"
2094  " print \"inspecting\""
2095  " a = SCFlowintIncr(0)\n"
2096  " if a == 2 then\n"
2097  " print \"match\"\n"
2098  " return 1\n"
2099  " end\n"
2100  " return 0\n"
2101  "end\n"
2102  "return 0\n";
2103  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
2104  uint8_t httpbuf1[] =
2105  "POST / HTTP/1.1\r\n"
2106  "Host: www.emergingthreats.net\r\n\r\n";
2107  uint8_t httpbuf2[] =
2108  "POST / HTTP/1.1\r\n"
2109  "Host: www.openinfosecfoundation.org\r\n\r\n";
2110  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2111  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2112  TcpSession ssn;
2113  Flow f;
2114  ThreadVars th_v;
2115  DetectEngineThreadCtx *det_ctx;
2116 
2118 
2119  ut_script = script;
2120 
2121  memset(&th_v, 0, sizeof(th_v));
2122  memset(&f, 0, sizeof(f));
2123  memset(&ssn, 0, sizeof(ssn));
2124 
2125  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2126  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2127 
2128  FLOW_INITIALIZE(&f);
2129  f.protoctx = (void *)&ssn;
2130  f.proto = IPPROTO_TCP;
2131  f.flags |= FLOW_IPV4;
2132  f.alproto = ALPROTO_HTTP1;
2133 
2134  p1->flow = &f;
2138 
2139  p2->flow = &f;
2143 
2144  StreamTcpInitConfig(true);
2145 
2148  de_ctx->flags |= DE_QUIET;
2149 
2151  FAIL_IF_NULL(s);
2152 
2154  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2155 
2156  int r = AppLayerParserParse(
2157  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2158  FAIL_IF(r != 0);
2159  HtpState *http_state = f.alstate;
2160  FAIL_IF_NULL(http_state);
2161 
2162  /* do detect for p1 */
2163  SCLogInfo("p1");
2164  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2165 
2166  FAIL_IF(PacketAlertCheck(p1, 1));
2167 
2168  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2169  FAIL_IF(r != 0);
2170  /* do detect for p2 */
2171  SCLogInfo("p2");
2172  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2173 
2174  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2175 
2176  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2177  FAIL_IF(id == 0);
2178 
2179  FlowVar *fv = FlowVarGet(&f, id);
2180  FAIL_IF_NULL(fv);
2181 
2182  FAIL_IF(fv->data.fv_int.value != 2);
2183 
2186 
2187  StreamTcpFreeConfig(true);
2188  FLOW_DESTROY(&f);
2189  UTHFreePackets(&p1, 1);
2190  UTHFreePackets(&p2, 1);
2191  PASS;
2192 }
2193 
2194 /** \test http buffer, flowints */
2195 static int LuaMatchTest06(void)
2196 {
2197  const char script[] = "function init (args)\n"
2198  " local needs = {}\n"
2199  " needs[\"http.request_headers\"] = tostring(true)\n"
2200  " needs[\"flowint\"] = {\"cnt\"}\n"
2201  " return needs\n"
2202  "end\n"
2203  "\n"
2204  "function match(args)\n"
2205  " print \"inspecting\""
2206  " a = ScFlowintGet(0)\n"
2207  " if a == nil then\n"
2208  " print \"new var set to 2\""
2209  " ScFlowintSet(0, 2)\n"
2210  " end\n"
2211  " a = ScFlowintDecr(0)\n"
2212  " if a == 0 then\n"
2213  " print \"match\"\n"
2214  " return 1\n"
2215  " end\n"
2216  " return 0\n"
2217  "end\n"
2218  "return 0\n";
2219  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
2220  uint8_t httpbuf1[] =
2221  "POST / HTTP/1.1\r\n"
2222  "Host: www.emergingthreats.net\r\n\r\n";
2223  uint8_t httpbuf2[] =
2224  "POST / HTTP/1.1\r\n"
2225  "Host: www.openinfosecfoundation.org\r\n\r\n";
2226  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2227  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2228  TcpSession ssn;
2229  Flow f;
2230  ThreadVars th_v;
2231  DetectEngineThreadCtx *det_ctx;
2232 
2234 
2235  ut_script = script;
2236 
2237  memset(&th_v, 0, sizeof(th_v));
2238  memset(&f, 0, sizeof(f));
2239  memset(&ssn, 0, sizeof(ssn));
2240 
2241  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2242  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2243 
2244  FLOW_INITIALIZE(&f);
2245  f.protoctx = (void *)&ssn;
2246  f.proto = IPPROTO_TCP;
2247  f.flags |= FLOW_IPV4;
2248  f.alproto = ALPROTO_HTTP1;
2249 
2250  p1->flow = &f;
2254 
2255  p2->flow = &f;
2259 
2260  StreamTcpInitConfig(true);
2261 
2264  de_ctx->flags |= DE_QUIET;
2265 
2267  FAIL_IF_NULL(s);
2268 
2270  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2271 
2272  int r = AppLayerParserParse(
2273  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2274  FAIL_IF(r != 0);
2275  HtpState *http_state = f.alstate;
2276  FAIL_IF_NULL(http_state);
2277 
2278  /* do detect for p1 */
2279  SCLogInfo("p1");
2280  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2281 
2282  FAIL_IF(PacketAlertCheck(p1, 1));
2283 
2284  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2285  FAIL_IF(r != 0);
2286  /* do detect for p2 */
2287  SCLogInfo("p2");
2288  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2289 
2290  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2291 
2292  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2293  FAIL_IF(id == 0);
2294 
2295  FlowVar *fv = FlowVarGet(&f, id);
2296  FAIL_IF_NULL(fv);
2297 
2298  FAIL_IF(fv->data.fv_int.value != 0);
2299 
2302 
2303  StreamTcpFreeConfig(true);
2304  FLOW_DESTROY(&f);
2305  UTHFreePackets(&p1, 1);
2306  UTHFreePackets(&p2, 1);
2307  PASS;
2308 }
2309 
2310 /** \test http buffer, flowints */
2311 static int LuaMatchTest06a(void)
2312 {
2313  const char script[] = "function init (args)\n"
2314  " local needs = {}\n"
2315  " needs[\"http.request_headers\"] = tostring(true)\n"
2316  " needs[\"flowint\"] = {\"cnt\"}\n"
2317  " return needs\n"
2318  "end\n"
2319  "\n"
2320  "function match(args)\n"
2321  " print \"inspecting\""
2322  " a = SCFlowintGet(0)\n"
2323  " if a == nil then\n"
2324  " print \"new var set to 2\""
2325  " SCFlowintSet(0, 2)\n"
2326  " end\n"
2327  " a = SCFlowintDecr(0)\n"
2328  " if a == 0 then\n"
2329  " print \"match\"\n"
2330  " return 1\n"
2331  " end\n"
2332  " return 0\n"
2333  "end\n"
2334  "return 0\n";
2335  char sig[] = "alert http any any -> any any (flow:to_server; lua:unittest; sid:1;)";
2336  uint8_t httpbuf1[] =
2337  "POST / HTTP/1.1\r\n"
2338  "Host: www.emergingthreats.net\r\n\r\n";
2339  uint8_t httpbuf2[] =
2340  "POST / HTTP/1.1\r\n"
2341  "Host: www.openinfosecfoundation.org\r\n\r\n";
2342  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
2343  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
2344  TcpSession ssn;
2345  Flow f;
2346  ThreadVars th_v;
2347  DetectEngineThreadCtx *det_ctx;
2348 
2350 
2351  ut_script = script;
2352 
2353  memset(&th_v, 0, sizeof(th_v));
2354  memset(&f, 0, sizeof(f));
2355  memset(&ssn, 0, sizeof(ssn));
2356 
2357  Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2358  Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2359 
2360  FLOW_INITIALIZE(&f);
2361  f.protoctx = (void *)&ssn;
2362  f.proto = IPPROTO_TCP;
2363  f.flags |= FLOW_IPV4;
2364  f.alproto = ALPROTO_HTTP1;
2365 
2366  p1->flow = &f;
2370 
2371  p2->flow = &f;
2375 
2376  StreamTcpInitConfig(true);
2377 
2380  de_ctx->flags |= DE_QUIET;
2381 
2383  FAIL_IF_NULL(s);
2384 
2386  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2387 
2388  int r = AppLayerParserParse(
2389  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
2390  FAIL_IF(r != 0);
2391  HtpState *http_state = f.alstate;
2392  FAIL_IF_NULL(http_state);
2393 
2394  /* do detect for p1 */
2395  SCLogInfo("p1");
2396  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
2397 
2398  FAIL_IF(PacketAlertCheck(p1, 1));
2399 
2400  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
2401  FAIL_IF(r != 0);
2402  /* do detect for p2 */
2403  SCLogInfo("p2");
2404  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
2405 
2406  FAIL_IF_NOT(PacketAlertCheck(p2, 1));
2407 
2408  uint32_t id = VarNameStoreLookupByName("cnt", VAR_TYPE_FLOW_INT);
2409  FAIL_IF(id == 0);
2410 
2411  FlowVar *fv = FlowVarGet(&f, id);
2412  FAIL_IF_NULL(fv);
2413 
2414  FAIL_IF(fv->data.fv_int.value != 0);
2415 
2418 
2419  StreamTcpFreeConfig(true);
2420  FLOW_DESTROY(&f);
2421  UTHFreePackets(&p1, 1);
2422  UTHFreePackets(&p2, 1);
2423  PASS;
2424 }
2425 
2426 void DetectLuaRegisterTests(void)
2427 {
2428  UtRegisterTest("LuaMatchTest01", LuaMatchTest01);
2429  UtRegisterTest("LuaMatchTest01a", LuaMatchTest01a);
2430  UtRegisterTest("LuaMatchTest02", LuaMatchTest02);
2431  UtRegisterTest("LuaMatchTest02a", LuaMatchTest02a);
2432  UtRegisterTest("LuaMatchTest03", LuaMatchTest03);
2433  UtRegisterTest("LuaMatchTest03a", LuaMatchTest03a);
2434  UtRegisterTest("LuaMatchTest04", LuaMatchTest04);
2435  UtRegisterTest("LuaMatchTest04a", LuaMatchTest04a);
2436  UtRegisterTest("LuaMatchTest05", LuaMatchTest05);
2437  UtRegisterTest("LuaMatchTest05a", LuaMatchTest05a);
2438  UtRegisterTest("LuaMatchTest06", LuaMatchTest06);
2439  UtRegisterTest("LuaMatchTest06a", LuaMatchTest06a);
2440 }
2441 #endif
FLAG_MEMORY_LIMIT_LOGGED
#define FLAG_MEMORY_LIMIT_LOGGED
Definition: detect-lua.c:127
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:1322
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
FlowVar_::data
union FlowVar_::@109 data
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:591
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:1321
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:1309
FLAG_BLOCKED_FUNCTION_LOGGED
#define FLAG_BLOCKED_FUNCTION_LOGGED
Definition: detect-lua.c:125
flow-util.h
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:47
FLAG_DATATYPE_SSH
#define FLAG_DATATYPE_SSH
Definition: detect-lua.c:120
SigTableElmt_::name
const char * name
Definition: detect.h:1319
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:3743
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:619
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:1186
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:39
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:363
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:119
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:126
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:854
DetectEngineThreadCtx_::lua_blocked_function_errors
uint16_t lua_blocked_function_errors
Definition: detect.h:1245
DEFAULT_LUA_INSTRUCTION_LIMIT
#define DEFAULT_LUA_INSTRUCTION_LIMIT
Definition: detect-lua.c:130
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:57
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2648
detect-lua.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1290
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:312
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:325
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:1969
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:2694
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:507
DetectEngineThreadCtx_::lua_instruction_limit_errors
uint16_t lua_instruction_limit_errors
Definition: detect.h:1248
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine.c:1430
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:360
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1304
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:697
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:1099
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:650
DetectEngineThreadCtx_::lua_rule_errors
uint16_t lua_rule_errors
Definition: detect.h:1242
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:58
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:473
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:1109
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:95
SignatureInitData_::list
int list
Definition: detect.h:577
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:3389
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:355
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:271
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:354
FLAG_DATATYPE_DNS_REQUEST
#define FLAG_DATATYPE_DNS_REQUEST
Definition: detect-lua.c:118
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:1251
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:124
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:683
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1287
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:53
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:1092
LuaDumpStack
void LuaDumpStack(lua_State *state, const char *prefix)
dump stack from lua state to screen
Definition: detect-lua.c:133
FlowVarTypeInt_::value
uint32_t value
Definition: flow-var.h:44
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:285
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:346
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
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:38
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:1035
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:3673
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:1274
detect-lua-extensions.h
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:352
FLAG_DATATYPE_SMTP
#define FLAG_DATATYPE_SMTP
Definition: detect-lua.c:121
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
DEFAULT_LUA_ALLOC_LIMIT
#define DEFAULT_LUA_ALLOC_LIMIT
Definition: detect-lua.c:129
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:651
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:2137
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:1019
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:1117
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:123
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::alstate
void * alstate
Definition: flow.h:474
Signature_::id
uint32_t id
Definition: detect.h:649
Flow_::flags
uint32_t flags
Definition: flow.h:419
detect-parse.h
Signature_
Signature container.
Definition: detect.h:614
SigMatch_
a single match condition for a signature
Definition: detect.h:351
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:1006
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:122
VAR_TYPE_FLOW_INT
@ VAR_TYPE_FLOW_INT
Definition: util-var.h:37
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
FLAG_DATATYPE_DNS_RRNAME
#define FLAG_DATATYPE_DNS_RRNAME
Definition: detect-lua.c:117
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:233
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2609
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:62
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:856
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:3725
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:1085
DetectLuaData::filename
char * filename
Definition: detect-lua.h:43
FlowVar_
Definition: flow-var.h:48
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:1311
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