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 #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 #include "action-globals.h"
60 
61 int LuaCallbackError(lua_State *luastate, const char *msg)
62 {
63  lua_pushnil(luastate);
64  lua_pushstring(luastate, msg);
65  return 2;
66 }
67 
68 const char *LuaGetStringArgument(lua_State *luastate, int argc)
69 {
70  /* get argument */
71  if (!lua_isstring(luastate, argc))
72  return NULL;
73  const char *str = lua_tostring(luastate, argc);
74  if (str == NULL)
75  return NULL;
76  if (strlen(str) == 0)
77  return NULL;
78  return str;
79 }
80 
81 void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value)
82 {
83  lua_pushstring(luastate, key);
84  lua_pushnumber(luastate, value);
85  lua_settable(luastate, -3);
86 }
87 
88 /** \brief Push a key plus string value to the stack
89  *
90  * If value is NULL, string "(null")" will be put on the stack.
91  */
92 void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value)
93 {
94  lua_pushstring(luastate, key);
95  lua_pushstring(luastate, value ? value : "(null)");
96  lua_settable(luastate, -3);
97 }
98 
99 void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len)
100 {
101  lua_pushstring(luastate, key);
102  LuaPushStringBuffer(luastate, value, len);
103  lua_settable(luastate, -3);
104 }
105 
106 /** \internal
107  * \brief fill lua stack with payload
108  * \param luastate the lua state
109  * \param p packet
110  * \retval cnt number of data items placed on the stack
111  *
112  * Places: payload (string), open (bool), close (bool), toserver (bool), toclient (bool)
113  */
114 static int LuaCallbackStreamingBufferPushToStack(lua_State *luastate, const LuaStreamingBuffer *b)
115 {
116  //PrintRawDataFp(stdout, (uint8_t *)b->data, b->data_len);
117  lua_pushlstring (luastate, (const char *)b->data, b->data_len);
118  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_OPEN));
119  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_CLOSE));
120  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_TOSERVER));
121  lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_TOCLIENT));
122  return 5;
123 }
124 
125 /** \internal
126  * \brief Wrapper for getting payload into a lua script
127  * \retval cnt number of items placed on the stack
128  */
129 static int LuaCallbackStreamingBuffer(lua_State *luastate)
130 {
131  const LuaStreamingBuffer *b = LuaStateGetStreamingBuffer(luastate);
132  if (b == NULL)
133  return LuaCallbackError(luastate, "internal error: no buffer");
134 
135  return LuaCallbackStreamingBufferPushToStack(luastate, b);
136 }
137 
138 /** \internal
139  * \brief fill lua stack with payload
140  * \param luastate the lua state
141  * \param p packet
142  * \retval cnt number of data items placed on the stack
143  *
144  * Places: payload (string)
145  */
146 static int LuaCallbackPacketPayloadPushToStackFromPacket(lua_State *luastate, const Packet *p)
147 {
148  lua_pushlstring (luastate, (const char *)p->payload, p->payload_len);
149  return 1;
150 }
151 
152 /** \internal
153  * \brief Wrapper for getting payload into a lua script
154  * \retval cnt number of items placed on the stack
155  */
156 static int LuaCallbackPacketPayload(lua_State *luastate)
157 {
158  const Packet *p = LuaStateGetPacket(luastate);
159  if (p == NULL)
160  return LuaCallbackError(luastate, "internal error: no packet");
161 
162  return LuaCallbackPacketPayloadPushToStackFromPacket(luastate, p);
163 }
164 
165 /** \internal
166  * \brief fill lua stack with packet timestamp
167  * \param luastate the lua state
168  * \param p packet
169  * \retval cnt number of data items placed on the stack
170  *
171  * Places: seconds (number), microseconds (number)
172  */
173 static int LuaCallbackTimestampPushToStack(lua_State *luastate, const SCTime_t ts)
174 {
175  lua_pushnumber(luastate, (double)SCTIME_SECS(ts));
176  lua_pushnumber(luastate, (double)SCTIME_USECS(ts));
177  return 2;
178 }
179 
180 /** \internal
181  * \brief fill lua stack with header info
182  * \param luastate the lua state
183  * \param p packet
184  * \retval cnt number of data items placed on the stack
185  *
186  * Places: ts (string)
187  */
188 static int LuaCallbackTimeStringPushToStackFromPacket(lua_State *luastate, const Packet *p)
189 {
190  char timebuf[64];
191  CreateTimeString(p->ts, timebuf, sizeof(timebuf));
192  lua_pushstring (luastate, timebuf);
193  return 1;
194 }
195 
196 /** \internal
197  * \brief Wrapper for getting packet timestamp (as numbers) into a lua script
198  * \retval cnt number of items placed on the stack
199  */
200 static int LuaCallbackPacketTimestamp(lua_State *luastate)
201 {
202  const Packet *p = LuaStateGetPacket(luastate);
203  if (p == NULL)
204  return LuaCallbackError(luastate, "internal error: no packet");
205 
206  return LuaCallbackTimestampPushToStack(luastate, p->ts);
207 }
208 
209 /** \internal
210  * \brief Wrapper for getting tuple info into a lua script
211  * \retval cnt number of items placed on the stack
212  */
213 static int LuaCallbackPacketTimeString(lua_State *luastate)
214 {
215  const Packet *p = LuaStateGetPacket(luastate);
216  if (p == NULL)
217  return LuaCallbackError(luastate, "internal error: no packet");
218 
219  return LuaCallbackTimeStringPushToStackFromPacket(luastate, p);
220 }
221 
222 /** \internal
223  * \brief fill lua stack with flow timestamps
224  * \param luastate the lua state
225  * \param startts timestamp of first packet in the flow
226  * \param lastts timestamp of last packet in the flow
227  * \retval cnt number of data items placed on the stack
228  *
229  * Places: seconds (number), seconds (number), microseconds (number),
230  * microseconds (number)
231  */
232 static int LuaCallbackFlowTimestampsPushToStack(
233  lua_State *luastate, const SCTime_t startts, const SCTime_t lastts)
234 {
235  lua_pushnumber(luastate, (double)SCTIME_SECS(startts));
236  lua_pushnumber(luastate, (double)SCTIME_SECS(lastts));
237  lua_pushnumber(luastate, (double)SCTIME_USECS(startts));
238  lua_pushnumber(luastate, (double)SCTIME_USECS(lastts));
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, flow->lastts);
254 }
255 
256 /** \internal
257  * \brief fill lua stack with time string
258  * \param luastate the lua state
259  * \param flow flow
260  * \retval cnt number of data items placed on the stack
261  *
262  * Places: ts (string)
263  */
264 static int LuaCallbackTimeStringPushToStackFromFlow(lua_State *luastate, const Flow *flow)
265 {
266  char timebuf[64];
267  CreateTimeString(flow->startts, timebuf, sizeof(timebuf));
268  lua_pushstring (luastate, timebuf);
269  return 1;
270 }
271 
272 /** \internal
273  * \brief Wrapper for getting ts info into a lua script
274  * \retval cnt number of items placed on the stack
275  */
276 static int LuaCallbackFlowTimeString(lua_State *luastate)
277 {
278  int r = 0;
279  Flow *flow = LuaStateGetFlow(luastate);
280  if (flow == NULL)
281  return LuaCallbackError(luastate, "internal error: no flow");
282 
283  r = LuaCallbackTimeStringPushToStackFromFlow(luastate, flow);
284 
285  return r;
286 }
287 
288 /** \internal
289  * \brief fill lua stack with flow has alerts
290  * \param luastate the lua state
291  * \param flow flow
292  * \retval cnt number of data items placed on the stack
293  *
294  * Places alerts (bool)
295  */
296 static int LuaCallbackHasAlertsPushToStackFromFlow(lua_State *luastate, const Flow *flow)
297 {
298  lua_pushboolean(luastate, FlowHasAlerts(flow));
299 
300  return 1;
301 }
302 
303 /** \internal
304  * \brief Wrapper for getting flow has alerts info into a lua script
305  * \retval cnt number of items placed on the stack
306  */
307 static int LuaCallbackFlowHasAlerts(lua_State *luastate)
308 {
309  int r = 0;
310  Flow *flow = LuaStateGetFlow(luastate);
311  if (flow == NULL)
312  return LuaCallbackError(luastate, "internal error: no flow");
313 
314  r = LuaCallbackHasAlertsPushToStackFromFlow(luastate, flow);
315 
316  return r;
317 }
318 
319 /** \internal
320  * \brief fill lua stack with header info
321  * \param luastate the lua state
322  * \param p packet
323  * \retval cnt number of data items placed on the stack
324  *
325  * Places: ipver (number), src ip (string), dst ip (string), protocol (number),
326  * sp or icmp type (number), dp or icmp code (number).
327  */
328 static int LuaCallbackTuplePushToStackFromPacket(lua_State *luastate, const Packet *p)
329 {
330  int ipver = 0;
331  if (PKT_IS_IPV4(p)) {
332  ipver = 4;
333  } else if (PKT_IS_IPV6(p)) {
334  ipver = 6;
335  }
336  lua_pushinteger(luastate, ipver);
337  if (ipver == 0)
338  return 1;
339 
340  char srcip[46] = "", dstip[46] = "";
341  if (PKT_IS_IPV4(p)) {
342  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
343  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
344  } else if (PKT_IS_IPV6(p)) {
345  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
346  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
347  }
348 
349  lua_pushstring (luastate, srcip);
350  lua_pushstring (luastate, dstip);
351 
352  /* proto and ports (or type/code) */
353  lua_pushinteger(luastate, p->proto);
354  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) {
355  lua_pushinteger(luastate, p->sp);
356  lua_pushinteger(luastate, p->dp);
357 
358  } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) {
359  lua_pushinteger(luastate, p->icmp_s.type);
360  lua_pushinteger(luastate, p->icmp_s.code);
361  } else {
362  lua_pushinteger(luastate, 0);
363  lua_pushinteger(luastate, 0);
364  }
365 
366  return 6;
367 }
368 
369 /** \internal
370  * \brief Wrapper for getting tuple info into a lua script
371  * \retval cnt number of items placed on the stack
372  */
373 static int LuaCallbackTuple(lua_State *luastate)
374 {
375  const Packet *p = LuaStateGetPacket(luastate);
376  if (p == NULL)
377  return LuaCallbackError(luastate, "internal error: no packet");
378 
379  return LuaCallbackTuplePushToStackFromPacket(luastate, p);
380 }
381 
382 /** \internal
383  * \brief fill lua stack with header info
384  * \param luastate the lua state
385  * \param f flow, locked
386  * \retval cnt number of data items placed on the stack
387  *
388  * Places: ipver (number), src ip (string), dst ip (string), protocol (number),
389  * sp or icmp type (number), dp or icmp code (number).
390  */
391 static int LuaCallbackTuplePushToStackFromFlow(lua_State *luastate, const Flow *f)
392 {
393  int ipver = 0;
394  if (FLOW_IS_IPV4(f)) {
395  ipver = 4;
396  } else if (FLOW_IS_IPV6(f)) {
397  ipver = 6;
398  }
399  lua_pushinteger(luastate, ipver);
400  if (ipver == 0)
401  return 1;
402 
403  char srcip[46] = "", dstip[46] = "";
404  if (FLOW_IS_IPV4(f)) {
405  PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip));
406  PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip));
407  } else if (FLOW_IS_IPV6(f)) {
408  PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip));
409  PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip));
410  }
411 
412  lua_pushstring (luastate, srcip);
413  lua_pushstring (luastate, dstip);
414 
415  /* proto and ports (or type/code) */
416  lua_pushinteger(luastate, f->proto);
417  if (f->proto == IPPROTO_TCP || f->proto == IPPROTO_UDP) {
418  lua_pushinteger(luastate, f->sp);
419  lua_pushinteger(luastate, f->dp);
420 
421  } else if (f->proto == IPPROTO_ICMP || f->proto == IPPROTO_ICMPV6) {
422  lua_pushinteger(luastate, f->icmp_s.type);
423  lua_pushinteger(luastate, f->icmp_s.code);
424  } else {
425  lua_pushinteger(luastate, 0);
426  lua_pushinteger(luastate, 0);
427  }
428 
429  return 6;
430 }
431 
432 /** \internal
433  * \brief Wrapper for getting tuple info into a lua script
434  * \retval cnt number of items placed on the stack
435  */
436 static int LuaCallbackTupleFlow(lua_State *luastate)
437 {
438  int r = 0;
439  Flow *f = LuaStateGetFlow(luastate);
440  if (f == NULL)
441  return LuaCallbackError(luastate, "internal error: no flow");
442 
443  r = LuaCallbackTuplePushToStackFromFlow(luastate, f);
444 
445  return r;
446 }
447 
448 /** \internal
449  * \brief fill lua stack with AppLayerProto
450  * \param luastate the lua state
451  * \param alproto AppProto to push to stack as string
452  * \retval cnt number of data items placed on the stack
453  *
454  * Places: alproto as string (string)
455  */
456 static int LuaCallbackAppLayerProtoPushToStackFromFlow(lua_State *luastate, const AppProto alproto)
457 {
458  const char *string = AppProtoToString(alproto);
459  if (string == NULL)
460  string = "unknown";
461  lua_pushstring(luastate, string);
462  return 1;
463 }
464 
465 /** \internal
466  * \brief Wrapper for getting AppLayerProto info into a lua script
467  * \retval cnt number of items placed on the stack
468  */
469 static int LuaCallbackAppLayerProtoFlow(lua_State *luastate)
470 {
471  int r = 0;
472  Flow *f = LuaStateGetFlow(luastate);
473  if (f == NULL)
474  return LuaCallbackError(luastate, "internal error: no flow");
475 
476  r = LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto);
477  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_ts);
478  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_tc);
479  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_orig);
480  r += LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f->alproto_expect);
481 
482  return r;
483 }
484 
485 /** \internal
486  * \brief fill lua stack with flow stats
487  * \param luastate the lua state
488  * \param f flow, locked
489  * \retval cnt number of data items placed on the stack
490  *
491  * Places: ts pkts (number), ts bytes (number), tc pkts (number), tc bytes (number)
492  */
493 static int LuaCallbackStatsPushToStackFromFlow(lua_State *luastate, const Flow *f)
494 {
495  lua_pushinteger(luastate, f->todstpktcnt);
496  lua_pushinteger(luastate, f->todstbytecnt);
497  lua_pushinteger(luastate, f->tosrcpktcnt);
498  lua_pushinteger(luastate, f->tosrcbytecnt);
499  return 4;
500 }
501 
502 /** \internal
503  * \brief Wrapper for getting AppLayerProto info into a lua script
504  * \retval cnt number of items placed on the stack
505  */
506 static int LuaCallbackStatsFlow(lua_State *luastate)
507 {
508  int r = 0;
509  Flow *f = LuaStateGetFlow(luastate);
510  if (f == NULL)
511  return LuaCallbackError(luastate, "internal error: no flow");
512 
513  r = LuaCallbackStatsPushToStackFromFlow(luastate, f);
514 
515  return r;
516 }
517 
518 /** \internal
519  * \brief fill lua stack with flow id
520  * \param luastate the lua state
521  * \param f flow, locked
522  * \retval cnt number of data items placed on the stack
523  *
524  * Places: flow id (number)
525  */
526 static int LuaCallbackPushFlowIdToStackFromFlow(lua_State *luastate, const Flow *f)
527 {
528  int64_t id = FlowGetId(f);
529  lua_pushinteger(luastate, id);
530  return 1;
531 }
532 
533 /** \internal
534  * \brief Wrapper for getting FlowId into lua script
535  * \retval cnt number of items placed on the stack
536  */
537 static int LuaCallbackFlowId(lua_State *luastate)
538 {
539  int r = 0;
540  Flow *f = LuaStateGetFlow(luastate);
541  if (f == NULL)
542  return LuaCallbackError(luastate, "internal error: no flow");
543 
544  r = LuaCallbackPushFlowIdToStackFromFlow(luastate, f);
545 
546  return r;
547 }
548 
549 /** \internal
550  * \brief fill lua stack with signature info
551  * \param luastate the lua state
552  * \param s pointer to signature struct
553  * \retval cnt number of data items placed on the stack
554  *
555  * Places: sid (number), rev (number), gid (number)
556  */
557 static int LuaCallbackRuleIdsPushToStackFromSignature(lua_State *luastate, const Signature *s)
558 {
559  lua_pushinteger(luastate, s->id);
560  lua_pushinteger(luastate, s->rev);
561  lua_pushinteger(luastate, s->gid);
562  return 3;
563 }
564 
565 /** \internal
566  * \brief Wrapper for getting tuple info into a lua script
567  * \retval cnt number of items placed on the stack
568  *
569  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
570  * otherwise pulled from Signature in lua registry (for match scripts)
571  */
572 static int LuaCallbackRuleIds(lua_State *luastate)
573 {
574  const Signature *s = NULL;
575  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
576  if (pa != NULL) {
577  s = pa->s;
578  } else {
579  s = LuaStateGetSignature(luastate);
580  if (s == NULL)
581  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
582  }
583  return LuaCallbackRuleIdsPushToStackFromSignature(luastate, s);
584 }
585 
586 /** \internal
587  * \brief fill lua stack with signature info
588  * \param luastate the lua state
589  * \param s pointer to signature struct
590  * \retval cnt number of data items placed on the stack
591  *
592  * Places: action (string)
593  */
594 static int LuaCallbackRuleActionPushToStackFromSignature(lua_State *luastate, const Signature *s)
595 {
596  const char *action = "";
597  if (s->action & ACTION_PASS) {
598  action = "pass";
599  } else if ((s->action & ACTION_REJECT) || (s->action & ACTION_REJECT_BOTH) ||
600  (s->action & ACTION_REJECT_DST)) {
601  action = "reject";
602  } else if (s->action & ACTION_DROP) {
603  action = "drop";
604  } else if (s->action & ACTION_ALERT) {
605  action = "alert";
606  }
607  lua_pushstring(luastate, action);
608  return 1;
609 }
610 
611 /** \internal
612  * \brief Wrapper for getting tuple info into a lua script
613  * \retval cnt number of items placed on the stack
614  *
615  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
616  * otherwise pulled from Signature in lua registry (for match scripts)
617  */
618 static int LuaCallbackRuleAction(lua_State *luastate)
619 {
620  const Signature *s = NULL;
621  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
622  if (pa != NULL) {
623  s = pa->s;
624  } else {
625  s = LuaStateGetSignature(luastate);
626  if (s == NULL)
627  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
628  }
629  return LuaCallbackRuleActionPushToStackFromSignature(luastate, s);
630 }
631 
632 /** \internal
633  * \brief fill lua stack with signature info
634  * \param luastate the lua state
635  * \param s pointer to signature struct
636  * \retval cnt number of data items placed on the stack
637  *
638  * Places: msg (string)
639  */
640 static int LuaCallbackRuleMsgPushToStackFromSignature(lua_State *luastate, const Signature *s)
641 {
642  lua_pushstring(luastate, s->msg);
643  return 1;
644 }
645 
646 /** \internal
647  * \brief Wrapper for getting tuple info into a lua script
648  * \retval cnt number of items placed on the stack
649  *
650  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
651  * otherwise pulled from Signature in lua registry (for match scripts)
652  */
653 static int LuaCallbackRuleMsg(lua_State *luastate)
654 {
655  const Signature *s = NULL;
656  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
657  if (pa != NULL) {
658  s = pa->s;
659  } else {
660  s = LuaStateGetSignature(luastate);
661  if (s == NULL)
662  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
663  }
664  return LuaCallbackRuleMsgPushToStackFromSignature(luastate, s);
665 }
666 
667 /** \internal
668  * \brief fill lua stack with signature info
669  * \param luastate the lua state
670  * \param s pointer to signature struct
671  * \retval cnt number of data items placed on the stack
672  *
673  * Places: class (string), prio (number)
674  */
675 static int LuaCallbackRuleClassPushToStackFromSignature(lua_State *luastate, const Signature *s)
676 {
677  lua_pushstring(luastate, s->class_msg);
678  lua_pushinteger(luastate, s->prio);
679  return 2;
680 }
681 
682 /** \internal
683  * \brief Wrapper for getting tuple info into a lua script
684  * \retval cnt number of items placed on the stack
685  *
686  * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
687  * otherwise pulled from Signature in lua registry (for match scripts)
688  */
689 static int LuaCallbackRuleClass(lua_State *luastate)
690 {
691  const Signature *s = NULL;
692  const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
693  if (pa != NULL) {
694  s = pa->s;
695  } else {
696  s = LuaStateGetSignature(luastate);
697  if (s == NULL)
698  return LuaCallbackError(luastate, "internal error: no packet alert or signature");
699  }
700  return LuaCallbackRuleClassPushToStackFromSignature(luastate, s);
701 }
702 
703 static int LuaCallbackLogPath(lua_State *luastate)
704 {
705  const char *ld = ConfigGetLogDirectory();
706  if (ld == NULL)
707  return LuaCallbackError(luastate, "internal error: no log dir");
708 
709  return LuaPushStringBuffer(luastate, (const uint8_t *)ld, strlen(ld));
710 }
711 
712 static int LuaCallbackLogDebug(lua_State *luastate)
713 {
714  const char *msg = LuaGetStringArgument(luastate, 1);
715  if (msg == NULL)
716  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
717  SCLogDebug("%s", msg);
718  return 0;
719 }
720 
721 static int LuaCallbackLogInfo(lua_State *luastate)
722 {
723  const char *msg = LuaGetStringArgument(luastate, 1);
724  if (msg == NULL)
725  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
726 
727  lua_Debug ar;
728  lua_getstack(luastate, 1, &ar);
729  lua_getinfo(luastate, "nSl", &ar);
730  const char *funcname = ar.name ? ar.name : ar.what;
731  SCLogInfoRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
732  return 0;
733 }
734 
735 static int LuaCallbackLogNotice(lua_State *luastate)
736 {
737  const char *msg = LuaGetStringArgument(luastate, 1);
738  if (msg == NULL)
739  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
740 
741  lua_Debug ar;
742  lua_getstack(luastate, 1, &ar);
743  lua_getinfo(luastate, "nSl", &ar);
744  const char *funcname = ar.name ? ar.name : ar.what;
745  SCLogNoticeRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
746  return 0;
747 }
748 
749 static int LuaCallbackLogWarning(lua_State *luastate)
750 {
751  const char *msg = LuaGetStringArgument(luastate, 1);
752  if (msg == NULL)
753  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
754 
755  lua_Debug ar;
756  lua_getstack(luastate, 1, &ar);
757  lua_getinfo(luastate, "nSl", &ar);
758  const char *funcname = ar.name ? ar.name : ar.what;
759  SCLogWarningRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
760  return 0;
761 }
762 
763 static int LuaCallbackLogError(lua_State *luastate)
764 {
765  const char *msg = LuaGetStringArgument(luastate, 1);
766  if (msg == NULL)
767  return LuaCallbackError(luastate, "1st argument missing, empty or wrong type");
768  lua_Debug ar;
769  lua_getstack(luastate, 1, &ar);
770  lua_getinfo(luastate, "nSl", &ar);
771  const char *funcname = ar.name ? ar.name : ar.what;
772  SCLogErrorRaw(ar.short_src, funcname, ar.currentline, "%s", msg);
773  return 0;
774 }
775 
776 /** \internal
777  * \brief fill lua stack with file info
778  * \param luastate the lua state
779  * \param pa pointer to packet alert struct
780  * \retval cnt number of data items placed on the stack
781  *
782  * Places: fileid (number), txid (number), name (string),
783  * size (number), magic (string), md5 in hex (string),
784  * sha1 (string), sha256 (string)
785  */
786 static int LuaCallbackFileInfoPushToStackFromFile(lua_State *luastate, const File *file)
787 {
788  char *md5ptr = NULL;
789  char *sha1ptr = NULL;
790  char *sha256ptr = NULL;
791 
792  char md5[33] = "";
793  md5ptr = md5;
794  if (file->flags & FILE_MD5) {
795  size_t x;
796  for (x = 0; x < sizeof(file->md5); x++) {
797  char one[3] = "";
798  snprintf(one, sizeof(one), "%02x", file->md5[x]);
799  strlcat(md5, one, sizeof(md5));
800  }
801  }
802  char sha1[41] = "";
803  sha1ptr = sha1;
804  if (file->flags & FILE_SHA1) {
805  size_t x;
806  for (x = 0; x < sizeof(file->sha1); x++) {
807  char one[3] = "";
808  snprintf(one, sizeof(one), "%02x", file->sha1[x]);
809  strlcat(sha1, one, sizeof(sha1));
810  }
811  }
812  char sha256[65] = "";
813  sha256ptr = sha256;
814  if (file->flags & FILE_SHA256) {
815  size_t x;
816  for (x = 0; x < sizeof(file->sha256); x++) {
817  char one[3] = "";
818  snprintf(one, sizeof(one), "%02x", file->sha256[x]);
819  strlcat(sha256, one, sizeof(sha256));
820  }
821  }
822 
823  lua_Integer tx_id = LuaStateGetTxId(luastate);
824  lua_pushinteger(luastate, file->file_store_id);
825  lua_pushinteger(luastate, tx_id);
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 */
tm-threads.h
Packet_::proto
uint8_t proto
Definition: decode.h:459
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_::@31::@41 icmp_s
PacketAlert_::s
const struct Signature_ * s
Definition: decode.h:268
FLOW_IS_IPV6
#define FLOW_IS_IPV6(f)
Definition: flow.h:166
ThreadVars_::name
char name[16]
Definition: threadvars.h:64
util-lua-common.h
Flow_::startts
SCTime_t startts
Definition: flow.h:490
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:247
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
Flow_::proto
uint8_t proto
Definition: flow.h:373
util-lua.h
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:81
Packet_::payload
uint8_t * payload
Definition: decode.h:586
action-globals.h
threads.h
FILE_STATE_OPENED
@ FILE_STATE_OPENED
Definition: util-file.h:70
Flow_
Flow data structure.
Definition: flow.h:351
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:75
File_::file_store_id
uint32_t file_store_id
Definition: util-file.h:85
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:456
util-privs.h
FILE_STATE_TRUNCATED
@ FILE_STATE_TRUNCATED
Definition: util-file.h:73
Flow_::dp
Port dp
Definition: flow.h:367
File_::sha1
uint8_t sha1[SC_SHA1_LEN]
Definition: util-file.h:96
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:587
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:216
util-unittest.h
Signature_::gid
uint32_t gid
Definition: detect.h:632
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:495
Flow_::dst
FlowAddress dst
Definition: flow.h:354
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:211
strlcat
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
Flow_::todstpktcnt
uint32_t todstpktcnt
Definition: flow.h:492
Packet_::ts
SCTime_t ts
Definition: decode.h:485
Flow_::lastts
SCTime_t lastts
Definition: flow.h:410
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:241
pkt-var.h
Packet_::sp
Port sp
Definition: decode.h:444
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:494
Flow_::icmp_s
struct Flow_::@117::@123 icmp_s
FLOW_IS_IPV4
#define FLOW_IS_IPV4(f)
Definition: flow.h:164
Signature_::action
uint8_t action
Definition: detect.h:611
ACTION_ALERT
#define ACTION_ALERT
Definition: action-globals.h:29
Packet_
Definition: decode.h:437
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:459
Flow_::src
FlowAddress src
Definition: flow.h:354
SCGetThreadIdLong
#define SCGetThreadIdLong(...)
Definition: threads.h:255
Signature_::class_msg
char * class_msg
Definition: detect.h:657
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
util-conf.h
GET_IPV4_SRC_ADDR_PTR
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:210
suricata-common.h
OUTPUT_STREAMING_FLAG_OPEN
#define OUTPUT_STREAMING_FLAG_OPEN
Definition: output-streaming.h:29
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
lua_State
void lua_State
Definition: suricata-common.h:500
FILE_MD5
#define FILE_MD5
Definition: util-file.h:48
Signature_::rev
uint32_t rev
Definition: detect.h:633
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:634
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:215
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:451
SCLogNoticeRaw
#define SCLogNoticeRaw(file, func, line,...)
Definition: util-debug.h:239
util-logopenfile.h
Signature_::id
uint32_t id
Definition: detect.h:631
util-buffer.h
Signature_
Signature container.
Definition: detect.h:596
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:264
FlowHasAlerts
int FlowHasAlerts(const Flow *f)
Check if flow has alerts.
Definition: flow.c:189
Flow_::sp
Port sp
Definition: flow.h:356
Signature_::msg
char * msg
Definition: detect.h:654
SCLogErrorRaw
#define SCLogErrorRaw(file, func, line,...)
Definition: util-debug.h:263
Flow_::alproto_tc
AppProto alproto_tc
Definition: flow.h:452
msg
const char * msg
Definition: app-layer-htp.c:580
FlowAddress_::address
union FlowAddress_::@116 address
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
Packet_::dp
Port dp
Definition: decode.h:452
FILE_STATE_ERROR
@ FILE_STATE_ERROR
Definition: util-file.h:75
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:246
Flow_::tosrcpktcnt
uint32_t tosrcpktcnt
Definition: flow.h:493
CreateTimeString
void CreateTimeString(const SCTime_t ts, char *str, size_t size)
Definition: util-time.c:272
output.h
FILE_STATE_NONE
@ FILE_STATE_NONE
Definition: util-file.h:69
app-layer.h
SCTIME_USECS
#define SCTIME_USECS(t)
Definition: util-time.h:56