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