suricata
util-lua-common.c
Go to the documentation of this file.
1 /* Copyright (C) 2014-2021 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  * Common function for Lua Output
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "pkt-var.h"
29 #include "conf.h"
30 
31 #include "threads.h"
32 #include "threadvars.h"
33 #include "tm-threads.h"
34 
35 #include "util-print.h"
36 #include "util-unittest.h"
37 
38 #include "util-debug.h"
39 
40 #include "output.h"
41 #include "app-layer-htp.h"
42 #include "app-layer.h"
43 #include "app-layer-parser.h"
44 #include "util-privs.h"
45 #include "util-buffer.h"
46 #include "util-proto-name.h"
47 #include "util-logopenfile.h"
48 #include "util-time.h"
49 #include "util-conf.h"
50 
51 #include "lua.h"
52 #include "lualib.h"
53 #include "lauxlib.h"
54 
55 #include "util-lua.h"
56 #include "util-lua-common.h"
57 #include "action-globals.h"
58 
59 int LuaCallbackError(lua_State *luastate, const char *msg)
60 {
61  lua_pushnil(luastate);
62  lua_pushstring(luastate, msg);
63  return 2;
64 }
65 
66 const char *LuaGetStringArgument(lua_State *luastate, int argc)
67 {
68  /* get argument */
69  if (!lua_isstring(luastate, argc))
70  return NULL;
71  const char *str = lua_tostring(luastate, argc);
72  if (str == NULL)
73  return NULL;
74  if (strlen(str) == 0)
75  return NULL;
76  return str;
77 }
78 
79 void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value)
80 {
81  lua_pushstring(luastate, key);
82  lua_pushnumber(luastate, value);
83  lua_settable(luastate, -3);
84 }
85 
86 /** \brief Push a key plus string value to the stack
87  *
88  * If value is NULL, string "(null")" will be put on the stack.
89  */
90 void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value)
91 {
92  lua_pushstring(luastate, key);
93  lua_pushstring(luastate, value ? value : "(null)");
94  lua_settable(luastate, -3);
95 }
96 
97 void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len)
98 {
99  lua_pushstring(luastate, key);
100  LuaPushStringBuffer(luastate, value, len);
101  lua_settable(luastate, -3);
102 }
103 
104 /** \internal
105  * \brief fill lua stack with payload
106  * \param luastate the lua state
107  * \param p packet
108  * \retval cnt number of data items placed on the stack
109  *
110  * Places: payload (string), open (bool), close (bool), toserver (bool), toclient (bool)
111  */
112 static int LuaCallbackStreamingBufferPushToStack(lua_State *luastate, const LuaStreamingBuffer *b)
113 {
114  //PrintRawDataFp(stdout, (uint8_t *)b->data, b->data_len);
115  lua_pushlstring (luastate, (const char *)b->data, b->data_len);
116  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_OPEN));
117  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_CLOSE));
118  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_TOSERVER));
119  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_TOCLIENT));
120  return 5;
121 }
122 
123 /** \internal
124  * \brief Wrapper for getting payload into a lua script
125  * \retval cnt number of items placed on the stack
126  */
127 static int LuaCallbackStreamingBuffer(lua_State *luastate)
128 {
129  const LuaStreamingBuffer *b = LuaStateGetStreamingBuffer(luastate);
130  if (b == NULL)
131  return LuaCallbackError(luastate, "internal error: no buffer");
132 
133  return LuaCallbackStreamingBufferPushToStack(luastate, b);
134 }
135 
136 /** \internal
137  * \brief fill lua stack with payload
138  * \param luastate the lua state
139  * \param p packet
140  * \retval cnt number of data items placed on the stack
141  *
142  * Places: payload (string)
143  */
144 static int LuaCallbackPacketPayloadPushToStackFromPacket(lua_State *luastate, const Packet *p)
145 {
146  lua_pushlstring (luastate, (const char *)p->payload, p->payload_len);
147  return 1;
148 }
149 
150 /** \internal
151  * \brief Wrapper for getting payload into a lua script
152  * \retval cnt number of items placed on the stack
153  */
154 static int LuaCallbackPacketPayload(lua_State *luastate)
155 {
156  const Packet *p = LuaStateGetPacket(luastate);
157  if (p == NULL)
158  return LuaCallbackError(luastate, "internal error: no packet");
159 
160  return LuaCallbackPacketPayloadPushToStackFromPacket(luastate, p);
161 }
162 
163 /** \internal
164  * \brief fill lua stack with packet timestamp
165  * \param luastate the lua state
166  * \param p packet
167  * \retval cnt number of data items placed on the stack
168  *
169  * Places: seconds (number), microseconds (number)
170  */
171 static int LuaCallbackTimestampPushToStack(lua_State *luastate, const SCTime_t ts)
172 {
173  lua_pushnumber(luastate, (double)SCTIME_SECS(ts));
174  lua_pushnumber(luastate, (double)SCTIME_USECS(ts));
175  return 2;
176 }
177 
178 /** \internal
179  * \brief fill lua stack with header info
180  * \param luastate the lua state
181  * \param p packet
182  * \retval cnt number of data items placed on the stack
183  *
184  * Places: ts (string)
185  */
186 static int LuaCallbackTimeStringPushToStackFromPacket(lua_State *luastate, const Packet *p)
187 {
188  char timebuf[64];
189  CreateTimeString(p->ts, timebuf, sizeof(timebuf));
190  lua_pushstring (luastate, timebuf);
191  return 1;
192 }
193 
194 /** \internal
195  * \brief Wrapper for getting packet timestamp (as numbers) into a lua script
196  * \retval cnt number of items placed on the stack
197  */
198 static int LuaCallbackPacketTimestamp(lua_State *luastate)
199 {
200  const Packet *p = LuaStateGetPacket(luastate);
201  if (p == NULL)
202  return LuaCallbackError(luastate, "internal error: no packet");
203 
204  return LuaCallbackTimestampPushToStack(luastate, p->ts);
205 }
206 
207 /** \internal
208  * \brief Wrapper for getting tuple info into a lua script
209  * \retval cnt number of items placed on the stack
210  */
211 static int LuaCallbackPacketTimeString(lua_State *luastate)
212 {
213  const Packet *p = LuaStateGetPacket(luastate);
214  if (p == NULL)
215  return LuaCallbackError(luastate, "internal error: no packet");
216 
217  return LuaCallbackTimeStringPushToStackFromPacket(luastate, p);
218 }
219 
220 /** \internal
221  * \brief fill lua stack with flow timestamps
222  * \param luastate the lua state
223  * \param startts timestamp of first packet in the flow
224  * \param lastts timestamp of last packet in the flow
225  * \retval cnt number of data items placed on the stack
226  *
227  * Places: seconds (number), seconds (number), microseconds (number),
228  * microseconds (number)
229  */
230 static int LuaCallbackFlowTimestampsPushToStack(
231  lua_State *luastate, const SCTime_t startts, const SCTime_t lastts)
232 {
233  lua_pushnumber(luastate, (double)SCTIME_SECS(startts));
234  lua_pushnumber(luastate, (double)SCTIME_SECS(lastts));
235  lua_pushnumber(luastate, (double)SCTIME_USECS(startts));
236  lua_pushnumber(luastate, (double)SCTIME_USECS(lastts));
237  return 4;
238 }
239 
240 /** \internal
241  * \brief Wrapper for getting flow timestamp (as numbers) into a lua script
242  * \retval cnt number of items placed on the stack
243  */
244 static int LuaCallbackFlowTimestamps(lua_State *luastate)
245 {
246  Flow *flow = LuaStateGetFlow(luastate);
247  if (flow == NULL) {
248  return LuaCallbackError(luastate, "internal error: no flow");
249  }
250 
251  return LuaCallbackFlowTimestampsPushToStack(luastate, flow->startts, flow->lastts);
252 }
253 
254 /** \internal
255  * \brief fill lua stack with time string
256  * \param luastate the lua state
257  * \param flow flow
258  * \retval cnt number of data items placed on the stack
259  *
260  * Places: ts (string)
261  */
262 static int LuaCallbackTimeStringPushToStackFromFlow(lua_State *luastate, const Flow *flow)
263 {
264  char timebuf[64];
265  CreateTimeString(flow->startts, timebuf, sizeof(timebuf));
266  lua_pushstring (luastate, timebuf);
267  return 1;
268 }
269 
270 /** \internal
271  * \brief Wrapper for getting ts info into a lua script
272  * \retval cnt number of items placed on the stack
273  */
274 static int LuaCallbackFlowTimeString(lua_State *luastate)
275 {
276  int r = 0;
277  Flow *flow = LuaStateGetFlow(luastate);
278  if (flow == NULL)
279  return LuaCallbackError(luastate, "internal error: no flow");
280 
281  r = LuaCallbackTimeStringPushToStackFromFlow(luastate, flow);
282 
283  return r;
284 }
285 
286 /** \internal
287  * \brief fill lua stack with flow has alerts
288  * \param luastate the lua state
289  * \param flow flow
290  * \retval cnt number of data items placed on the stack
291  *
292  * Places alerts (bool)
293  */
294 static int LuaCallbackHasAlertsPushToStackFromFlow(lua_State *luastate, const Flow *flow)
295 {
296  lua_pushboolean(luastate, FlowHasAlerts(flow));
297 
298  return 1;
299 }
300 
301 /** \internal
302  * \brief Wrapper for getting flow has alerts info into a lua script
303  * \retval cnt number of items placed on the stack
304  */
305 static int LuaCallbackFlowHasAlerts(lua_State *luastate)
306 {
307  int r = 0;
308  Flow *flow = LuaStateGetFlow(luastate);
309  if (flow == NULL)
310  return LuaCallbackError(luastate, "internal error: no flow");
311 
312  r = LuaCallbackHasAlertsPushToStackFromFlow(luastate, flow);
313 
314  return r;
315 }
316 
317 /** \internal
318  * \brief fill lua stack with header info
319  * \param luastate the lua state
320  * \param p packet
321  * \retval cnt number of data items placed on the stack
322  *
323  * Places: ipver (number), src ip (string), dst ip (string), protocol (number),
324  * sp or icmp type (number), dp or icmp code (number).
325  */
326 static int LuaCallbackTuplePushToStackFromPacket(lua_State *luastate, const Packet *p)
327 {
328  int ipver = 0;
329  if (PacketIsIPv4(p)) {
330  ipver = 4;
331  } else if (PacketIsIPv6(p)) {
332  ipver = 6;
333  }
334  lua_pushinteger(luastate, ipver);
335  if (ipver == 0)
336  return 1;
337 
338  char srcip[46] = "", dstip[46] = "";
339  if (PacketIsIPv4(p)) {
340  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
341  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
342  } else if (PacketIsIPv6(p)) {
343  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
344  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
345  }
346 
347  lua_pushstring (luastate, srcip);
348  lua_pushstring (luastate, dstip);
349 
350  /* proto and ports (or type/code) */
351  lua_pushinteger(luastate, p->proto);
352  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) {
353  lua_pushinteger(luastate, p->sp);
354  lua_pushinteger(luastate, p->dp);
355 
356  } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) {
357  lua_pushinteger(luastate, p->icmp_s.type);
358  lua_pushinteger(luastate, p->icmp_s.code);
359  } else {
360  lua_pushinteger(luastate, 0);
361  lua_pushinteger(luastate, 0);
362  }
363 
364  return 6;
365 }
366 
367 /** \internal
368  * \brief Wrapper for getting tuple info into a lua script
369  * \retval cnt number of items placed on the stack
370  */
371 static int LuaCallbackTuple(lua_State *luastate)
372 {
373  const Packet *p = LuaStateGetPacket(luastate);
374  if (p == NULL)
375  return LuaCallbackError(luastate, "internal error: no packet");
376 
377  return LuaCallbackTuplePushToStackFromPacket(luastate, p);
378 }
379 
380 /** \internal
381  * \brief fill lua stack with header info
382  * \param luastate the lua state
383  * \param f flow, locked
384  * \retval cnt number of data items placed on the stack
385  *
386  * Places: ipver (number), src ip (string), dst ip (string), protocol (number),
387  * sp or icmp type (number), dp or icmp code (number).
388  */
389 static int LuaCallbackTuplePushToStackFromFlow(lua_State *luastate, const Flow *f)
390 {
391  int ipver = 0;
392  if (FLOW_IS_IPV4(f)) {
393  ipver = 4;
394  } else if (FLOW_IS_IPV6(f)) {
395  ipver = 6;
396  }
397  lua_pushinteger(luastate, ipver);
398  if (ipver == 0)
399  return 1;
400 
401  char srcip[46] = "", dstip[46] = "";
402  if (FLOW_IS_IPV4(f)) {
403  PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip));
404  PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip));
405  } else if (FLOW_IS_IPV6(f)) {
406  PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip));
407  PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip));
408  }
409 
410  lua_pushstring (luastate, srcip);
411  lua_pushstring (luastate, dstip);
412 
413  /* proto and ports (or type/code) */
414  lua_pushinteger(luastate, f->proto);
415  if (f->proto == IPPROTO_TCP || f->proto == IPPROTO_UDP) {
416  lua_pushinteger(luastate, f->sp);
417  lua_pushinteger(luastate, f->dp);
418 
419  } else if (f->proto == IPPROTO_ICMP || f->proto == IPPROTO_ICMPV6) {
420  lua_pushinteger(luastate, f->icmp_s.type);
421  lua_pushinteger(luastate, f->icmp_s.code);
422  } else {
423  lua_pushinteger(luastate, 0);
424  lua_pushinteger(luastate, 0);
425  }
426 
427  return 6;
428 }
429 
430 /** \internal
431  * \brief Wrapper for getting tuple info into a lua script
432  * \retval cnt number of items placed on the stack
433  */
434 static int LuaCallbackTupleFlow(lua_State *luastate)
435 {
436  int r = 0;
437  Flow *f = LuaStateGetFlow(luastate);
438  if (f == NULL)
439  return LuaCallbackError(luastate, "internal error: no flow");
440 
441  r = LuaCallbackTuplePushToStackFromFlow(luastate, f);
442 
443  return r;
444 }
445 
446 /** \internal
447  * \brief fill lua stack with AppLayerProto
448  * \param luastate the lua state
449  * \param alproto AppProto to push to stack as string
450  * \retval cnt number of data items placed on the stack
451  *
452  * Places: alproto as string (string)
453  */
454 static int LuaCallbackAppLayerProtoPushToStackFromFlow(lua_State *luastate, const AppProto alproto)
455 {
456  const char *string = AppProtoToString(alproto);
457  if (string == NULL)
458  string = "unknown";
459  lua_pushstring(luastate, string);
460  return 1;
461 }
462 
463 /** \internal
464  * \brief Wrapper for getting AppLayerProto info into a lua script
465  * \retval cnt number of items placed on the stack
466  */
467 static int LuaCallbackAppLayerProtoFlow(lua_State *luastate)
468 {
469  int r = 0;
470  Flow *f = LuaStateGetFlow(luastate);
471  if (f == NULL)
472  return LuaCallbackError(luastate, "internal error: no flow");
473 
474  r = LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto);
475  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_ts);
476  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_tc);
477  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_orig);
478  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_expect);
479 
480  return r;
481 }
482 
483 /** \internal
484  * \brief fill lua stack with flow stats
485  * \param luastate the lua state
486  * \param f flow, locked
487  * \retval cnt number of data items placed on the stack
488  *
489  * Places: ts pkts (number), ts bytes (number), tc pkts (number), tc bytes (number)
490  */
491 static int LuaCallbackStatsPushToStackFromFlow(lua_State *luastate, const Flow *f)
492 {
493  lua_pushinteger(luastate, f->todstpktcnt);
494  lua_pushinteger(luastate, f->todstbytecnt);
495  lua_pushinteger(luastate, f->tosrcpktcnt);
496  lua_pushinteger(luastate, f->tosrcbytecnt);
497  return 4;
498 }
499 
500 /** \internal
501  * \brief Wrapper for getting AppLayerProto info into a lua script
502  * \retval cnt number of items placed on the stack
503  */
504 static int LuaCallbackStatsFlow(lua_State *luastate)
505 {
506  int r = 0;
507  Flow *f = LuaStateGetFlow(luastate);
508  if (f == NULL)
509  return LuaCallbackError(luastate, "internal error: no flow");
510 
511  r = LuaCallbackStatsPushToStackFromFlow(luastate, f);
512 
513  return r;
514 }
515 
516 /** \internal
517  * \brief fill lua stack with flow id
518  * \param luastate the lua state
519  * \param f flow, locked
520  * \retval cnt number of data items placed on the stack
521  *
522  * Places: flow id (number)
523  */
524 static int LuaCallbackPushFlowIdToStackFromFlow(lua_State *luastate, const Flow *f)
525 {
526  int64_t id = FlowGetId(f);
527  lua_pushinteger(luastate, id);
528  return 1;
529 }
530 
531 /** \internal
532  * \brief Wrapper for getting FlowId into lua script
533  * \retval cnt number of items placed on the stack
534  */
535 static int LuaCallbackFlowId(lua_State *luastate)
536 {
537  int r = 0;
538  Flow *f = LuaStateGetFlow(luastate);
539  if (f == NULL)
540  return LuaCallbackError(luastate, "internal error: no flow");
541 
542  r = LuaCallbackPushFlowIdToStackFromFlow(luastate, f);
543 
544  return r;
545 }
546 
547 /** \internal
548  * \brief fill lua stack with signature info
549  * \param luastate the lua state
550  * \param s pointer to signature struct
551  * \retval cnt number of data items placed on the stack
552  *
553  * Places: sid (number), rev (number), gid (number)
554  */
555 static int LuaCallbackRuleIdsPushToStackFromSignature(lua_State *luastate, const Signature *s)
556 {
557  lua_pushinteger(luastate, s->id);
558  lua_pushinteger(luastate, s->rev);
559  lua_pushinteger(luastate, s->gid);
560  return 3;
561 }
562 
563 /** \internal
564  * \brief Wrapper for getting tuple info into a lua script
565  * \retval cnt number of items placed on the stack
566  *
567  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
568  * otherwise pulled from Signature in lua registry (for match scripts)
569  */
570 static int LuaCallbackRuleIds(lua_State *luastate)
571 {
572  const Signature *s = NULL;
573  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
574  if (pa != NULL) {
575  s = pa->s;
576  } else {
577  s = LuaStateGetSignature(luastate);
578  if (s == NULL)
579  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
580  }
581  return LuaCallbackRuleIdsPushToStackFromSignature(luastate, s);
582 }
583 
584 /** \internal
585  * \brief fill lua stack with signature info
586  * \param luastate the lua state
587  * \param s pointer to signature struct
588  * \retval cnt number of data items placed on the stack
589  *
590  * Places: action (string)
591  */
592 static int LuaCallbackRuleActionPushToStackFromSignature(lua_State *luastate, const Signature *s)
593 {
594  const char *action = "";
595  if (s->action & ACTION_PASS) {
596  action = "pass";
597  } else if ((s->action & ACTION_REJECT) || (s->action & ACTION_REJECT_BOTH) ||
598  (s->action & ACTION_REJECT_DST)) {
599  action = "reject";
600  } else if (s->action & ACTION_DROP) {
601  action = "drop";
602  } else if (s->action & ACTION_ALERT) {
603  action = "alert";
604  }
605  lua_pushstring(luastate, action);
606  return 1;
607 }
608 
609 /** \internal
610  * \brief Wrapper for getting tuple info into a lua script
611  * \retval cnt number of items placed on the stack
612  *
613  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
614  * otherwise pulled from Signature in lua registry (for match scripts)
615  */
616 static int LuaCallbackRuleAction(lua_State *luastate)
617 {
618  const Signature *s = NULL;
619  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
620  if (pa != NULL) {
621  s = pa->s;
622  } else {
623  s = LuaStateGetSignature(luastate);
624  if (s == NULL)
625  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
626  }
627  return LuaCallbackRuleActionPushToStackFromSignature(luastate, s);
628 }
629 
630 /** \internal
631  * \brief fill lua stack with signature info
632  * \param luastate the lua state
633  * \param s pointer to signature struct
634  * \retval cnt number of data items placed on the stack
635  *
636  * Places: msg (string)
637  */
638 static int LuaCallbackRuleMsgPushToStackFromSignature(lua_State *luastate, const Signature *s)
639 {
640  lua_pushstring(luastate, s->msg);
641  return 1;
642 }
643 
644 /** \internal
645  * \brief Wrapper for getting tuple info into a lua script
646  * \retval cnt number of items placed on the stack
647  *
648  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
649  * otherwise pulled from Signature in lua registry (for match scripts)
650  */
651 static int LuaCallbackRuleMsg(lua_State *luastate)
652 {
653  const Signature *s = NULL;
654  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
655  if (pa != NULL) {
656  s = pa->s;
657  } else {
658  s = LuaStateGetSignature(luastate);
659  if (s == NULL)
660  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
661  }
662  return LuaCallbackRuleMsgPushToStackFromSignature(luastate, s);
663 }
664 
665 /** \internal
666  * \brief fill lua stack with signature info
667  * \param luastate the lua state
668  * \param s pointer to signature struct
669  * \retval cnt number of data items placed on the stack
670  *
671  * Places: class (string), prio (number)
672  */
673 static int LuaCallbackRuleClassPushToStackFromSignature(lua_State *luastate, const Signature *s)
674 {
675  lua_pushstring(luastate, s->class_msg);
676  lua_pushinteger(luastate, s->prio);
677  return 2;
678 }
679 
680 /** \internal
681  * \brief Wrapper for getting tuple info into a lua script
682  * \retval cnt number of items placed on the stack
683  *
684  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
685  * otherwise pulled from Signature in lua registry (for match scripts)
686  */
687 static int LuaCallbackRuleClass(lua_State *luastate)
688 {
689  const Signature *s = NULL;
690  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
691  if (pa != NULL) {
692  s = pa->s;
693  } else {
694  s = LuaStateGetSignature(luastate);
695  if (s == NULL)
696  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
697  }
698  return LuaCallbackRuleClassPushToStackFromSignature(luastate, s);
699 }
700 
701 static int LuaCallbackLogPath(lua_State *luastate)
702 {
703  const char *ld = ConfigGetLogDirectory();
704  if (ld == NULL)
705  return LuaCallbackError(luastate, "internal error: no log dir");
706 
707  return LuaPushStringBuffer(luastate, (const uint8_t *)ld, strlen(ld));
708 }
709 
710 static int LuaCallbackLogDebug(lua_State *luastate)
711 {
712  const char *msg = LuaGetStringArgument(luastate, 1);
713  if (msg == NULL)
714  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
715  SCLogDebug("%s", msg);
716  return 0;
717 }
718 
719 static int LuaCallbackLogInfo(lua_State *luastate)
720 {
721  const char *msg = LuaGetStringArgument(luastate, 1);
722  if (msg == NULL)
723  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
724 
725  lua_Debug ar;
726  lua_getstack(luastate, 1, &ar);
727  lua_getinfo(luastate, "nSl", &ar);
728  const char *funcname = ar.name ? ar.name : ar.what;
729  SCLogInfoRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
730  return 0;
731 }
732 
733 static int LuaCallbackLogNotice(lua_State *luastate)
734 {
735  const char *msg = LuaGetStringArgument(luastate, 1);
736  if (msg == NULL)
737  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
738 
739  lua_Debug ar;
740  lua_getstack(luastate, 1, &ar);
741  lua_getinfo(luastate, "nSl", &ar);
742  const char *funcname = ar.name ? ar.name : ar.what;
743  SCLogNoticeRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
744  return 0;
745 }
746 
747 static int LuaCallbackLogWarning(lua_State *luastate)
748 {
749  const char *msg = LuaGetStringArgument(luastate, 1);
750  if (msg == NULL)
751  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
752 
753  lua_Debug ar;
754  lua_getstack(luastate, 1, &ar);
755  lua_getinfo(luastate, "nSl", &ar);
756  const char *funcname = ar.name ? ar.name : ar.what;
757  SCLogWarningRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
758  return 0;
759 }
760 
761 static int LuaCallbackLogError(lua_State *luastate)
762 {
763  const char *msg = LuaGetStringArgument(luastate, 1);
764  if (msg == NULL)
765  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
766  lua_Debug ar;
767  lua_getstack(luastate, 1, &ar);
768  lua_getinfo(luastate, "nSl", &ar);
769  const char *funcname = ar.name ? ar.name : ar.what;
770  SCLogErrorRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
771  return 0;
772 }
773 
774 /** \internal
775  * \brief fill lua stack with file info
776  * \param luastate the lua state
777  * \param pa pointer to packet alert struct
778  * \retval cnt number of data items placed on the stack
779  *
780  * Places: fileid (number), txid (number), name (string),
781  * size (number), magic (string), md5 in hex (string),
782  * sha1 (string), sha256 (string)
783  */
784 static int LuaCallbackFileInfoPushToStackFromFile(lua_State *luastate, const File *file)
785 {
786  char *md5ptr = NULL;
787  char *sha1ptr = NULL;
788  char *sha256ptr = NULL;
789 
790  char md5[33] = "";
791  md5ptr = md5;
792  if (file->flags & FILE_MD5) {
793  size_t x;
794  for (x = 0; x < sizeof(file->md5); x++) {
795  char one[3] = "";
796  snprintf(one, sizeof(one), "%02x", file->md5[x]);
797  strlcat(md5, one, sizeof(md5));
798  }
799  }
800  char sha1[41] = "";
801  sha1ptr = sha1;
802  if (file->flags & FILE_SHA1) {
803  size_t x;
804  for (x = 0; x < sizeof(file->sha1); x++) {
805  char one[3] = "";
806  snprintf(one, sizeof(one), "%02x", file->sha1[x]);
807  strlcat(sha1, one, sizeof(sha1));
808  }
809  }
810  char sha256[65] = "";
811  sha256ptr = sha256;
812  if (file->flags & FILE_SHA256) {
813  size_t x;
814  for (x = 0; x < sizeof(file->sha256); x++) {
815  char one[3] = "";
816  snprintf(one, sizeof(one), "%02x", file->sha256[x]);
817  strlcat(sha256, one, sizeof(sha256));
818  }
819  }
820 
821  lua_Integer tx_id = LuaStateGetTxId(luastate);
822  lua_pushinteger(luastate, file->file_store_id);
823  lua_pushinteger(luastate, tx_id);
824  lua_pushlstring(luastate, (char *)file->name, file->name_len);
825  lua_pushinteger(luastate, FileTrackedSize(file));
826  lua_pushstring (luastate,
827 #ifdef HAVE_MAGIC
828  file->magic
829 #else
830  "nomagic"
831 #endif
832  );
833  lua_pushstring(luastate, md5ptr);
834  lua_pushstring(luastate, sha1ptr);
835  lua_pushstring(luastate, sha256ptr);
836  return 8;
837 }
838 
839 /** \internal
840  * \brief Wrapper for getting tuple info into a lua script
841  * \retval cnt number of items placed on the stack
842  */
843 static int LuaCallbackFileInfo(lua_State *luastate)
844 {
845  const File *file = LuaStateGetFile(luastate);
846  if (file == NULL)
847  return LuaCallbackError(luastate, "internal error: no file");
848 
849  return LuaCallbackFileInfoPushToStackFromFile(luastate, file);
850 }
851 
852 /** \internal
853  * \brief fill lua stack with file info
854  * \param luastate the lua state
855  * \param pa pointer to packet alert struct
856  * \retval cnt number of data items placed on the stack
857  *
858  * Places: state (string), stored (bool)
859  */
860 static int LuaCallbackFileStatePushToStackFromFile(lua_State *luastate, const File *file)
861 {
862  const char *state = "UNKNOWN";
863  switch (file->state) {
864  case FILE_STATE_CLOSED:
865  state = "CLOSED";
866  break;
868  state = "TRUNCATED";
869  break;
870  case FILE_STATE_ERROR:
871  state = "ERROR";
872  break;
873  case FILE_STATE_OPENED:
874  state = "OPENED";
875  break;
876  case FILE_STATE_NONE:
877  state = "NONE";
878  break;
879  case FILE_STATE_MAX:
880  break;
881  }
882 
883  lua_pushstring (luastate, state);
884  lua_pushboolean (luastate, file->flags & FILE_STORED);
885  return 2;
886 }
887 
888 /** \internal
889  * \brief Wrapper for getting tuple info into a lua script
890  * \retval cnt number of items placed on the stack
891  */
892 static int LuaCallbackFileState(lua_State *luastate)
893 {
894  const File *file = LuaStateGetFile(luastate);
895  if (file == NULL)
896  return LuaCallbackError(luastate, "internal error: no file");
897 
898  return LuaCallbackFileStatePushToStackFromFile(luastate, file);
899 }
900 
901 /** \internal
902  * \brief fill lua stack with thread info
903  * \param luastate the lua state
904  * \param pa pointer to packet alert struct
905  * \retval cnt number of data items placed on the stack
906  *
907  * Places: thread id (number), thread name (string, thread group name (string)
908  */
909 static int LuaCallbackThreadInfoPushToStackFromThreadVars(lua_State *luastate, const ThreadVars *tv)
910 {
911  unsigned long tid = SCGetThreadIdLong();
912  lua_pushinteger (luastate, (lua_Integer)tid);
913  lua_pushstring (luastate, tv->name);
914  lua_pushstring (luastate, tv->thread_group_name);
915  return 3;
916 }
917 
918 /** \internal
919  * \brief Wrapper for getting tuple info into a lua script
920  * \retval cnt number of items placed on the stack
921  */
922 static int LuaCallbackThreadInfo(lua_State *luastate)
923 {
924  const ThreadVars *tv = LuaStateGetThreadVars(luastate);
925  if (tv == NULL)
926  return LuaCallbackError(luastate, "internal error: no tv");
927 
928  return LuaCallbackThreadInfoPushToStackFromThreadVars(luastate, tv);
929 }
930 
932 {
933  /* registration of the callbacks */
934  lua_pushcfunction(luastate, LuaCallbackPacketPayload);
935  lua_setglobal(luastate, "SCPacketPayload");
936  lua_pushcfunction(luastate, LuaCallbackPacketTimestamp);
937  lua_setglobal(luastate, "SCPacketTimestamp");
938  lua_pushcfunction(luastate, LuaCallbackPacketTimeString);
939  lua_setglobal(luastate, "SCPacketTimeString");
940  lua_pushcfunction(luastate, LuaCallbackTuple);
941  lua_setglobal(luastate, "SCPacketTuple");
942 
943  lua_pushcfunction(luastate, LuaCallbackFlowTimestamps);
944  lua_setglobal(luastate, "SCFlowTimestamps");
945  lua_pushcfunction(luastate, LuaCallbackFlowTimeString);
946  lua_setglobal(luastate, "SCFlowTimeString");
947  lua_pushcfunction(luastate, LuaCallbackTupleFlow);
948  lua_setglobal(luastate, "SCFlowTuple");
949  lua_pushcfunction(luastate, LuaCallbackAppLayerProtoFlow);
950  lua_setglobal(luastate, "SCFlowAppLayerProto");
951  lua_pushcfunction(luastate, LuaCallbackStatsFlow);
952  lua_setglobal(luastate, "SCFlowStats");
953  lua_pushcfunction(luastate, LuaCallbackFlowHasAlerts);
954  lua_setglobal(luastate, "SCFlowHasAlerts");
955  lua_pushcfunction(luastate, LuaCallbackFlowId);
956  lua_setglobal(luastate, "SCFlowId");
957 
958  lua_pushcfunction(luastate, LuaCallbackStreamingBuffer);
959  lua_setglobal(luastate, "SCStreamingBuffer");
960 
961  lua_pushcfunction(luastate, LuaCallbackLogPath);
962  lua_setglobal(luastate, "SCLogPath");
963 
964  lua_pushcfunction(luastate, LuaCallbackLogDebug);
965  lua_setglobal(luastate, "SCLogDebug");
966  lua_pushcfunction(luastate, LuaCallbackLogInfo);
967  lua_setglobal(luastate, "SCLogInfo");
968  lua_pushcfunction(luastate, LuaCallbackLogNotice);
969  lua_setglobal(luastate, "SCLogNotice");
970  lua_pushcfunction(luastate, LuaCallbackLogWarning);
971  lua_setglobal(luastate, "SCLogWarning");
972  lua_pushcfunction(luastate, LuaCallbackLogError);
973  lua_setglobal(luastate, "SCLogError");
974 
975 
976  lua_pushcfunction(luastate, LuaCallbackRuleIds);
977  lua_setglobal(luastate, "SCRuleIds");
978  lua_pushcfunction(luastate, LuaCallbackRuleAction);
979  lua_setglobal(luastate, "SCRuleAction");
980  lua_pushcfunction(luastate, LuaCallbackRuleMsg);
981  lua_setglobal(luastate, "SCRuleMsg");
982  lua_pushcfunction(luastate, LuaCallbackRuleClass);
983  lua_setglobal(luastate, "SCRuleClass");
984 
985  lua_pushcfunction(luastate, LuaCallbackFileInfo);
986  lua_setglobal(luastate, "SCFileInfo");
987  lua_pushcfunction(luastate, LuaCallbackFileState);
988  lua_setglobal(luastate, "SCFileState");
989 
990  lua_pushcfunction(luastate, LuaCallbackThreadInfo);
991  lua_setglobal(luastate, "SCThreadInfo");
992  return 0;
993 }
994 
995 int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
996 {
997  AppProto flow_alproto = 0;
998  Flow *flow = LuaStateGetFlow(luastate);
999  if (flow == NULL)
1000  return LuaCallbackError(luastate, "internal error: no flow");
1001 
1002  flow_alproto = flow->alproto;
1003 
1004  return (alproto == flow_alproto);
1005 }
tm-threads.h
Packet_::proto
uint8_t proto
Definition: decode.h:501
len
uint8_t len
Definition: app-layer-dnp3.h:2
ts
uint64_t ts
Definition: source-erf-file.c:55
LuaStateGetStreamingBuffer
LuaStreamingBuffer * LuaStateGetStreamingBuffer(lua_State *luastate)
Definition: util-lua.c:254
PacketAlert_::s
const struct Signature_ * s
Definition: decode.h:249
FLOW_IS_IPV6
#define FLOW_IS_IPV6(f)
Definition: flow.h:171
ThreadVars_::name
char name[16]
Definition: threadvars.h:64
util-lua-common.h
LuaPushTableKeyValueInt
void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value)
Definition: util-lua-common.c:79
Flow_::startts
SCTime_t startts
Definition: flow.h:499
LuaStreamingBuffer_
Definition: util-lua.h:34
SCLogWarningRaw
#define SCLogWarningRaw(file, func, line,...)
Definition: util-debug.h:251
FILE_SHA256
#define FILE_SHA256
Definition: util-file.h:52
ACTION_PASS
#define ACTION_PASS
Definition: action-globals.h:34
ACTION_REJECT
#define ACTION_REJECT
Definition: action-globals.h:31
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
LuaStateGetSignature
Signature * LuaStateGetSignature(lua_State *luastate)
get signature pointer from the lua state
Definition: util-lua.c:207
Flow_::proto
uint8_t proto
Definition: flow.h:382
util-lua.h
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:84
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:59
Packet_::payload
uint8_t * payload
Definition: decode.h:580
action-globals.h
threads.h
FILE_STATE_OPENED
@ FILE_STATE_OPENED
Definition: util-file.h:70
Flow_
Flow data structure.
Definition: flow.h:360
File_::state
FileState state
Definition: util-file.h:82
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:78
File_::file_store_id
uint32_t file_store_id
Definition: util-file.h:85
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:465
util-privs.h
FILE_STATE_TRUNCATED
@ FILE_STATE_TRUNCATED
Definition: util-file.h:73
Packet_::icmp_s
struct Packet_::@29::@36 icmp_s
Flow_::dp
Port dp
Definition: flow.h:376
File_::sha1
uint8_t sha1[SC_SHA1_LEN]
Definition: util-file.h:96
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:581
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:206
util-unittest.h
Flow_::icmp_s
struct Flow_::@115::@121 icmp_s
lua_State
struct lua_State lua_State
Definition: suricata-common.h:500
Signature_::gid
uint32_t gid
Definition: detect.h:637
File_::name_len
uint16_t name_len
Definition: util-file.h:81
ACTION_REJECT_DST
#define ACTION_REJECT_DST
Definition: action-globals.h:32
Flow_::tosrcbytecnt
uint64_t tosrcbytecnt
Definition: flow.h:504
Flow_::dst
FlowAddress dst
Definition: flow.h:363
LuaStateGetThreadVars
ThreadVars * LuaStateGetThreadVars(lua_State *luastate)
get tv pointer from the lua state
Definition: util-lua.c:102
app-layer-htp.h
File_::md5
uint8_t md5[SC_MD5_LEN]
Definition: util-file.h:94
util-debug.h
GET_IPV4_DST_ADDR_PTR
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:201
strlcat
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
Flow_::todstpktcnt
uint32_t todstpktcnt
Definition: flow.h:501
Packet_::ts
SCTime_t ts
Definition: decode.h:527
Flow_::lastts
SCTime_t lastts
Definition: flow.h:419
util-print.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:231
pkt-var.h
Packet_::sp
Port sp
Definition: decode.h:486
FileTrackedSize
uint64_t FileTrackedSize(const File *file)
get the size of the file
Definition: util-file.c:343
util-time.h
app-layer-parser.h
Flow_::todstbytecnt
uint64_t todstbytecnt
Definition: flow.h:503
FLOW_IS_IPV4
#define FLOW_IS_IPV4(f)
Definition: flow.h:169
Signature_::action
uint8_t action
Definition: detect.h:616
ACTION_ALERT
#define ACTION_ALERT
Definition: action-globals.h:29
Packet_
Definition: decode.h:479
FlowAddress_::address
union FlowAddress_::@114 address
conf.h
ThreadVars_::thread_group_name
char * thread_group_name
Definition: threadvars.h:66
SCTime_t
Definition: util-time.h:40
FILE_STATE_MAX
@ FILE_STATE_MAX
Definition: util-file.h:76
File_::name
uint8_t * name
Definition: util-file.h:88
util-proto-name.h
Flow_::alproto_expect
AppProto alproto_expect
Definition: flow.h:468
Flow_::src
FlowAddress src
Definition: flow.h:363
SCGetThreadIdLong
#define SCGetThreadIdLong(...)
Definition: threads.h:255
Signature_::class_msg
char * class_msg
Definition: detect.h:662
ACTION_REJECT_BOTH
#define ACTION_REJECT_BOTH
Definition: action-globals.h:33
File_::flags
uint16_t flags
Definition: util-file.h:80
FILE_STATE_CLOSED
@ FILE_STATE_CLOSED
Definition: util-file.h:71
File_
Definition: util-file.h:79
LuaPushTableKeyValueArray
void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len)
Definition: util-lua-common.c:97
util-conf.h
GET_IPV4_SRC_ADDR_PTR
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:200
LuaStateGetTxId
uint64_t LuaStateGetTxId(lua_State *luastate)
get tx id from the lua state
Definition: util-lua.c:143
suricata-common.h
OUTPUT_STREAMING_FLAG_OPEN
#define OUTPUT_STREAMING_FLAG_OPEN
Definition: output-streaming.h:29
LuaStreamingBuffer_::data_len
uint32_t data_len
Definition: util-lua.h:36
LuaStateGetPacketAlert
PacketAlert * LuaStateGetPacketAlert(lua_State *luastate)
get packet alert pointer from the lua state
Definition: util-lua.c:191
LuaStreamingBuffer_::data
const uint8_t * data
Definition: util-lua.h:35
FILE_STORED
#define FILE_STORED
Definition: util-file.h:56
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
FILE_MD5
#define FILE_MD5
Definition: util-file.h:48
Signature_::rev
uint32_t rev
Definition: detect.h:638
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
File_::sha256
uint8_t sha256[SC_SHA256_LEN]
Definition: util-file.h:98
Signature_::prio
int prio
Definition: detect.h:639
threadvars.h
ConfigGetLogDirectory
const char * ConfigGetLogDirectory(void)
Definition: util-conf.c:38
OUTPUT_STREAMING_FLAG_TOSERVER
#define OUTPUT_STREAMING_FLAG_TOSERVER
Definition: output-streaming.h:31
str
#define str(s)
Definition: suricata-common.h:291
GET_IPV6_SRC_ADDR
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:205
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:460
SCLogNoticeRaw
#define SCLogNoticeRaw(file, func, line,...)
Definition: util-debug.h:239
util-logopenfile.h
Signature_::id
uint32_t id
Definition: detect.h:636
LuaStateGetFile
File * LuaStateGetFile(lua_State *luastate)
get file pointer from the lua state
Definition: util-lua.c:223
util-buffer.h
Signature_
Signature container.
Definition: detect.h:601
LuaStateGetFlow
Flow * LuaStateGetFlow(lua_State *luastate)
get flow pointer from lua state
Definition: util-lua.c:161
OUTPUT_STREAMING_FLAG_CLOSE
#define OUTPUT_STREAMING_FLAG_CLOSE
Definition: output-streaming.h:30
FILE_SHA1
#define FILE_SHA1
Definition: util-file.h:50
OUTPUT_STREAMING_FLAG_TOCLIENT
#define OUTPUT_STREAMING_FLAG_TOCLIENT
Definition: output-streaming.h:32
SCLogInfoRaw
#define SCLogInfoRaw(file, func, line,...)
Definition: util-debug.h:225
PacketAlert_
Definition: decode.h:245
LuaGetStringArgument
const char * LuaGetStringArgument(lua_State *luastate, int argc)
Definition: util-lua-common.c:66
FlowHasAlerts
int FlowHasAlerts(const Flow *f)
Check if flow has alerts.
Definition: flow.c:171
Flow_::sp
Port sp
Definition: flow.h:365
LuaPushTableKeyValueString
void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value)
Push a key plus string value to the stack.
Definition: util-lua-common.c:90
Signature_::msg
char * msg
Definition: detect.h:659
SCLogErrorRaw
#define SCLogErrorRaw(file, func, line,...)
Definition: util-debug.h:263
Flow_::alproto_tc
AppProto alproto_tc
Definition: flow.h:461
msg
const char * msg
Definition: app-layer-htp.c:564
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:459
Packet_::dp
Port dp
Definition: decode.h:494
FILE_STATE_ERROR
@ FILE_STATE_ERROR
Definition: util-file.h:75
LuaRegisterFunctions
int LuaRegisterFunctions(lua_State *luastate)
Definition: util-lua-common.c:931
LuaStateNeedProto
int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
Definition: util-lua-common.c:995
LuaStateGetPacket
Packet * LuaStateGetPacket(lua_State *luastate)
get packet pointer from the lua state
Definition: util-lua.c:118
Flow_::tosrcpktcnt
uint32_t tosrcpktcnt
Definition: flow.h:502
CreateTimeString
void CreateTimeString(const SCTime_t ts, char *str, size_t size)
Definition: util-time.c:272
LuaStreamingBuffer_::flags
uint8_t flags
Definition: util-lua.h:37
output.h
FILE_STATE_NONE
@ FILE_STATE_NONE
Definition: util-file.h:69
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:319
app-layer.h
SCTIME_USECS
#define SCTIME_USECS(t)
Definition: util-time.h:56