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