suricata
util-lua-rule.c
Go to the documentation of this file.
1 /* Copyright (C) 2025 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 #include "suricata-common.h"
19 #include "action-globals.h"
20 #include "app-layer.h"
21 #include "util-lua-rule.h"
22 #include "util-lua-common.h"
23 #include "util-lua.h"
24 
25 #include "lauxlib.h"
26 
27 static const char suricata_rule_mt[] = "suricata:rule:mt";
28 
29 /*
30  * The handle is a value copy, not a pointer: the Signature it came from
31  * is engine-owned and freed on rule reload (SigFree) while output states
32  * keep running, so a cached pointer handle would dangle.
33  */
34 typedef struct LuaRuleData_ {
35  uint32_t sid;
36  uint32_t gid;
37  uint32_t rev;
38  uint8_t action;
39  int prio;
40  /* point into the same userdata, behind the struct: allocated and
41  * counted by the Lua allocator and freed with the handle, so there
42  * is no finalizer a script could remove */
43  const char *msg;
44  const char *class_msg;
46 
47 static int LuaRuleGetRule(lua_State *L)
48 {
49  const PacketAlert *pa = LuaStateGetPacketAlert(L);
50  const Signature *s = NULL;
51  if (pa != NULL) {
52  s = pa->s;
53  } else {
54  s = LuaStateGetSignature(L);
55  }
56  if (s == NULL) {
57  return LuaCallbackError(L, "internal error: no packet alert or signature");
58  }
59 
60  const size_t msg_size = s->msg ? strlen(s->msg) + 1 : 0;
61  const size_t class_size = s->class_msg ? strlen(s->class_msg) + 1 : 0;
62  LuaRuleData *r = SCLuaNewUserData(L, SCLUA_TUD_RULE, sizeof(*r) + msg_size + class_size);
63  if (r == NULL) {
64  return LuaCallbackError(L, "error: failed to allocate user data");
65  }
66  r->sid = s->id;
67  r->gid = s->gid;
68  r->rev = s->rev;
69  r->action = s->action;
70  r->prio = s->prio;
71  char *strs = (char *)(r + 1);
72  r->msg = NULL;
73  if (msg_size > 0) {
74  memcpy(strs, s->msg, msg_size);
75  r->msg = strs;
76  strs += msg_size;
77  }
78  r->class_msg = NULL;
79  if (class_size > 0) {
80  memcpy(strs, s->class_msg, class_size);
81  r->class_msg = strs;
82  }
83 
84  luaL_getmetatable(L, suricata_rule_mt);
85  lua_setmetatable(L, -2);
86 
87  return 1;
88 }
89 
90 static int LuaRuleGetSid(lua_State *L)
91 {
92  LuaRuleData *r = SCLuaTestUserData(L, 1, suricata_rule_mt, SCLUA_TUD_RULE);
93  if (r == NULL) {
94  lua_pushnil(L);
95  return 1;
96  }
97  lua_pushinteger(L, r->sid);
98  return 1;
99 }
100 
101 static int LuaRuleGetGid(lua_State *L)
102 {
103  LuaRuleData *r = SCLuaTestUserData(L, 1, suricata_rule_mt, SCLUA_TUD_RULE);
104  if (r == NULL) {
105  lua_pushnil(L);
106  return 1;
107  }
108  lua_pushinteger(L, r->gid);
109  return 1;
110 }
111 
112 static int LuaRuleGetRev(lua_State *L)
113 {
114  LuaRuleData *r = SCLuaTestUserData(L, 1, suricata_rule_mt, SCLUA_TUD_RULE);
115  if (r == NULL) {
116  lua_pushnil(L);
117  return 1;
118  }
119  lua_pushinteger(L, r->rev);
120  return 1;
121 }
122 
123 static int LuaRuleGetAction(lua_State *L)
124 {
125  LuaRuleData *r = SCLuaTestUserData(L, 1, suricata_rule_mt, SCLUA_TUD_RULE);
126  if (r == NULL) {
127  lua_pushnil(L);
128  return 1;
129  }
130 
131  const char *action = "";
132  if (r->action & ACTION_PASS) {
133  action = "pass";
134  } else if ((r->action & ACTION_REJECT) || (r->action & ACTION_REJECT_BOTH) ||
135  (r->action & ACTION_REJECT_DST)) {
136  action = "reject";
137  } else if (r->action & ACTION_DROP) {
138  action = "drop";
139  } else if (r->action & ACTION_ALERT) {
140  action = "alert";
141  }
142  lua_pushstring(L, action);
143  return 1;
144 }
145 
146 static int LuaRuleGetMsg(lua_State *L)
147 {
148  LuaRuleData *r = SCLuaTestUserData(L, 1, suricata_rule_mt, SCLUA_TUD_RULE);
149  if (r == NULL) {
150  lua_pushnil(L);
151  return 1;
152  }
153  lua_pushstring(L, r->msg ? r->msg : "");
154  return 1;
155 }
156 
157 static int LuaRuleGetClassDescription(lua_State *L)
158 {
159  LuaRuleData *r = SCLuaTestUserData(L, 1, suricata_rule_mt, SCLUA_TUD_RULE);
160  if (r == NULL) {
161  lua_pushnil(L);
162  return 1;
163  }
164  lua_pushstring(L, r->class_msg ? r->class_msg : "");
165  return 1;
166 }
167 
168 static int LuaRuleGetPriority(lua_State *L)
169 {
170  LuaRuleData *r = SCLuaTestUserData(L, 1, suricata_rule_mt, SCLUA_TUD_RULE);
171  if (r == NULL) {
172  lua_pushnil(L);
173  return 1;
174  }
175  lua_pushinteger(L, r->prio);
176  return 1;
177 }
178 
179 static const struct luaL_Reg rulemt[] = {
180  // clang-format off
181  { "action", LuaRuleGetAction },
182  { "class_description", LuaRuleGetClassDescription, },
183  { "gid", LuaRuleGetGid, },
184  { "msg", LuaRuleGetMsg },
185  { "priority", LuaRuleGetPriority },
186  { "rev", LuaRuleGetRev, },
187  { "sid", LuaRuleGetSid, },
188  { NULL, NULL },
189  // clang-format on
190 };
191 
192 static const struct luaL_Reg rulelib[] = {
193  // clang-format off
194  { "get_rule", LuaRuleGetRule, },
195  { NULL, NULL, }
196  // clang-format on
197 };
198 
200 {
201  luaL_newmetatable(L, suricata_rule_mt);
202  lua_pushvalue(L, -1);
203  lua_setfield(L, -2, "__index");
204  luaL_setfuncs(L, rulemt, 0);
205 
206  luaL_newlib(L, rulelib);
207 
208  return 1;
209 }
LuaRuleData_::rev
uint32_t rev
Definition: util-lua-rule.c:37
PacketAlert_::s
const struct Signature_ * s
Definition: decode.h:254
util-lua-common.h
ACTION_PASS
#define ACTION_PASS
Definition: action-globals.h:34
ACTION_REJECT
#define ACTION_REJECT
Definition: action-globals.h:31
LuaStateGetSignature
Signature * LuaStateGetSignature(lua_State *luastate)
get signature pointer from the lua state
Definition: util-lua.c:285
util-lua.h
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:218
action-globals.h
LuaRuleData_::gid
uint32_t gid
Definition: util-lua-rule.c:36
lua_State
struct lua_State lua_State
Definition: suricata-common.h:527
Signature_::gid
uint32_t gid
Definition: detect.h:742
ACTION_REJECT_DST
#define ACTION_REJECT_DST
Definition: action-globals.h:32
LuaRuleData_::action
uint8_t action
Definition: util-lua-rule.c:38
LuaRuleData_::class_msg
const char * class_msg
Definition: util-lua-rule.c:44
Signature_::action
uint8_t action
Definition: detect.h:707
SCLuaTestUserData
void * SCLuaTestUserData(lua_State *L, int idx, const char *mt, uint32_t type_id)
Definition: util-lua-common.c:123
LuaRuleData
struct LuaRuleData_ LuaRuleData
ACTION_ALERT
#define ACTION_ALERT
Definition: action-globals.h:29
LuaRuleData_::sid
uint32_t sid
Definition: util-lua-rule.c:35
LuaRuleData_::msg
const char * msg
Definition: util-lua-rule.c:43
SCLuaNewUserData
void * SCLuaNewUserData(lua_State *L, uint32_t type_id, size_t size)
Definition: util-lua-common.c:42
Signature_::class_msg
char * class_msg
Definition: detect.h:767
ACTION_REJECT_BOTH
#define ACTION_REJECT_BOTH
Definition: action-globals.h:33
suricata-common.h
SCLUA_TUD_RULE
@ SCLUA_TUD_RULE
Definition: util-lua-common.h:57
LuaStateGetPacketAlert
PacketAlert * LuaStateGetPacketAlert(lua_State *luastate)
get packet alert pointer from the lua state
Definition: util-lua.c:274
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
Signature_::rev
uint32_t rev
Definition: detect.h:743
Signature_::prio
int prio
Definition: detect.h:744
Signature_::id
uint32_t id
Definition: detect.h:741
util-lua-rule.h
Signature_
Signature container.
Definition: detect.h:692
PacketAlert_
Definition: decode.h:249
LuaRuleData_::prio
int prio
Definition: util-lua-rule.c:39
Signature_::msg
char * msg
Definition: detect.h:764
LuaRuleData_
Definition: util-lua-rule.c:34
SCLuaLoadRuleLib
int SCLuaLoadRuleLib(lua_State *L)
Definition: util-lua-rule.c:199
app-layer.h