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