]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
lua: Fix SCRule functions for match scripts
authorBenjamin Wilkins <benjamin.wilkins@uwaterloo.ca>
Wed, 20 Oct 2021 20:21:08 +0000 (16:21 -0400)
committerVictor Julien <vjulien@oisf.net>
Mon, 22 Nov 2021 09:38:34 +0000 (10:38 +0100)
Save Signature structure to lua register so SCRule functions can work
in match scripts, where no PacketAlert is present

Resolves Feature #2450

src/detect-lua-extensions.c
src/detect-lua-extensions.h
src/detect-lua.c
src/util-lua-common.c
src/util-lua.c
src/util-lua.h

index aaeb0ce1564b55078355b411401ad6d64f3ef039..d03c022b705aa2b1f392747b0434725a84bda185 100644 (file)
@@ -481,8 +481,8 @@ static int LuaDecrFlowint(lua_State *luastate)
 
 }
 
-void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngineThreadCtx *det_ctx,
-        Flow *f, Packet *p, uint8_t flags)
+void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld,
+        DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p, const Signature *s, uint8_t flags)
 {
     SCLogDebug("det_ctx %p, f %p", det_ctx, f);
 
@@ -491,6 +491,8 @@ void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngi
     lua_pushlightuserdata(lua_state, (void *)ld);
     lua_settable(lua_state, LUA_REGISTRYINDEX);
 
+    LuaStateSetSignature(lua_state, s);
+
     LuaStateSetFlow(lua_state, f);
 
     if (det_ctx->tx_id_set) {
index 54a465783e2d0fa5728fad0169bd15d87cccd6e8..efd9416f1b3e732a8243e04007d18fe2023a684e 100644 (file)
@@ -27,9 +27,8 @@
 #ifdef HAVE_LUA
 int LuaRegisterExtensions(lua_State *);
 
-void LuaExtensionsMatchSetup(lua_State *lua_state,
-        DetectLuaData *, DetectEngineThreadCtx *det_ctx,
-        Flow *f, Packet *p, uint8_t flags);
+void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *, DetectEngineThreadCtx *det_ctx,
+        Flow *f, Packet *p, const Signature *s, uint8_t flags);
 
 #endif /* HAVE_LUA */
 #endif
index 673256709fdf408d8477b8babaa5360223fe0617..89bec7efc27c51dd9e1ff899407675ba1a7f0b82 100644 (file)
@@ -231,8 +231,7 @@ int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx,
     if (tlua == NULL)
         SCReturnInt(0);
 
-    LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx,
-            f, /* no packet in the ctx */NULL, 0);
+    LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
 
     /* prepare data to pass to script */
     lua_getglobal(tlua->luastate, "match");
@@ -347,8 +346,7 @@ static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
 
     LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
 
-    LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx,
-            p->flow, p, flags);
+    LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
 
     if ((tlua->flags & DATATYPE_PAYLOAD) && p->payload_len == 0)
         SCReturnInt(0);
@@ -480,8 +478,7 @@ static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
         SCReturnInt(0);
 
     /* setup extension data for use in lua c functions */
-    LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx,
-            f, NULL, flags);
+    LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
 
     if (tlua->alproto != ALPROTO_UNKNOWN) {
         int alproto = f->alproto;
index 0d46efad67553c5776d93bf33081a32c00765767..671904e0e527aa75b7ba4f4a124bd5952ef9ea1a 100644 (file)
@@ -548,54 +548,61 @@ static int LuaCallbackFlowId(lua_State *luastate)
 }
 
 /** \internal
- *  \brief fill lua stack with alert info
+ *  \brief fill lua stack with signature info
  *  \param luastate the lua state
- *  \param pa pointer to packet alert struct
+ *  \param s pointer to signature struct
  *  \retval cnt number of data items placed on the stack
  *
  *  Places: sid (number), rev (number), gid (number)
  */
-static int LuaCallbackRuleIdsPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa)
+static int LuaCallbackRuleIdsPushToStackFromSignature(lua_State *luastate, const Signature *s)
 {
-    lua_pushinteger(luastate, pa->s->id);
-    lua_pushinteger(luastate, pa->s->rev);
-    lua_pushinteger(luastate, pa->s->gid);
+    lua_pushinteger(luastate, s->id);
+    lua_pushinteger(luastate, s->rev);
+    lua_pushinteger(luastate, s->gid);
     return 3;
 }
 
 /** \internal
  *  \brief Wrapper for getting tuple info into a lua script
  *  \retval cnt number of items placed on the stack
+ *
+ *  Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
+ *  otherwise pulled from Signature in lua registry (for match scripts)
  */
 static int LuaCallbackRuleIds(lua_State *luastate)
 {
+    const Signature *s = NULL;
     const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
-    if (pa == NULL)
-        return LuaCallbackError(luastate, "internal error: no packet");
-
-    return LuaCallbackRuleIdsPushToStackFromPacketAlert(luastate, pa);
+    if (pa != NULL) {
+        s = pa->s;
+    } else {
+        s = LuaStateGetSignature(luastate);
+        if (s == NULL)
+            return LuaCallbackError(luastate, "internal error: no packet alert or signature");
+    }
+    return LuaCallbackRuleIdsPushToStackFromSignature(luastate, s);
 }
 
 /** \internal
- *  \brief fill lua stack with alert info
+ *  \brief fill lua stack with signature info
  *  \param luastate the lua state
- *  \param pa pointer to packet alert struct
+ *  \param s pointer to signature struct
  *  \retval cnt number of data items placed on the stack
  *
  *  Places: action (string)
  */
-static int LuaCallbackRuleActionPushToStackFromPacketAlert(
-        lua_State *luastate, const PacketAlert *pa)
+static int LuaCallbackRuleActionPushToStackFromSignature(lua_State *luastate, const Signature *s)
 {
     const char *action = "";
-    if (pa->s->action & ACTION_PASS) {
+    if (s->action & ACTION_PASS) {
         action = "pass";
-    } else if ((pa->s->action & ACTION_REJECT) || (pa->s->action & ACTION_REJECT_BOTH) ||
-               (pa->s->action & ACTION_REJECT_DST)) {
+    } else if ((s->action & ACTION_REJECT) || (s->action & ACTION_REJECT_BOTH) ||
+               (s->action & ACTION_REJECT_DST)) {
         action = "reject";
-    } else if (pa->s->action & ACTION_DROP) {
+    } else if (s->action & ACTION_DROP) {
         action = "drop";
-    } else if (pa->s->action & ACTION_ALERT) {
+    } else if (s->action & ACTION_ALERT) {
         action = "alert";
     }
     lua_pushstring(luastate, action);
@@ -605,69 +612,93 @@ static int LuaCallbackRuleActionPushToStackFromPacketAlert(
 /** \internal
  *  \brief Wrapper for getting tuple info into a lua script
  *  \retval cnt number of items placed on the stack
+ *
+ *  Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
+ *  otherwise pulled from Signature in lua registry (for match scripts)
  */
 static int LuaCallbackRuleAction(lua_State *luastate)
 {
+    const Signature *s = NULL;
     const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
-    if (pa == NULL)
-        return LuaCallbackError(luastate, "internal error: no packet");
-
-    return LuaCallbackRuleActionPushToStackFromPacketAlert(luastate, pa);
+    if (pa != NULL) {
+        s = pa->s;
+    } else {
+        s = LuaStateGetSignature(luastate);
+        if (s == NULL)
+            return LuaCallbackError(luastate, "internal error: no packet alert or signature");
+    }
+    return LuaCallbackRuleActionPushToStackFromSignature(luastate, s);
 }
 
 /** \internal
- *  \brief fill lua stack with alert info
+ *  \brief fill lua stack with signature info
  *  \param luastate the lua state
- *  \param pa pointer to packet alert struct
+ *  \param s pointer to signature struct
  *  \retval cnt number of data items placed on the stack
  *
  *  Places: msg (string)
  */
-static int LuaCallbackRuleMsgPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa)
+static int LuaCallbackRuleMsgPushToStackFromSignature(lua_State *luastate, const Signature *s)
 {
-    lua_pushstring (luastate, pa->s->msg);
+    lua_pushstring(luastate, s->msg);
     return 1;
 }
 
 /** \internal
  *  \brief Wrapper for getting tuple info into a lua script
  *  \retval cnt number of items placed on the stack
+ *
+ *  Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
+ *  otherwise pulled from Signature in lua registry (for match scripts)
  */
 static int LuaCallbackRuleMsg(lua_State *luastate)
 {
+    const Signature *s = NULL;
     const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
-    if (pa == NULL)
-        return LuaCallbackError(luastate, "internal error: no packet");
-
-    return LuaCallbackRuleMsgPushToStackFromPacketAlert(luastate, pa);
+    if (pa != NULL) {
+        s = pa->s;
+    } else {
+        s = LuaStateGetSignature(luastate);
+        if (s == NULL)
+            return LuaCallbackError(luastate, "internal error: no packet alert or signature");
+    }
+    return LuaCallbackRuleMsgPushToStackFromSignature(luastate, s);
 }
 
 /** \internal
- *  \brief fill lua stack with alert info
+ *  \brief fill lua stack with signature info
  *  \param luastate the lua state
- *  \param pa pointer to packet alert struct
+ *  \param s pointer to signature struct
  *  \retval cnt number of data items placed on the stack
  *
  *  Places: class (string), prio (number)
  */
-static int LuaCallbackRuleClassPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa)
+static int LuaCallbackRuleClassPushToStackFromSignature(lua_State *luastate, const Signature *s)
 {
-    lua_pushstring (luastate, pa->s->class_msg);
-    lua_pushnumber (luastate, pa->s->prio);
+    lua_pushstring(luastate, s->class_msg);
+    lua_pushinteger(luastate, s->prio);
     return 2;
 }
 
 /** \internal
  *  \brief Wrapper for getting tuple info into a lua script
  *  \retval cnt number of items placed on the stack
+ *
+ *  Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
+ *  otherwise pulled from Signature in lua registry (for match scripts)
  */
 static int LuaCallbackRuleClass(lua_State *luastate)
 {
+    const Signature *s = NULL;
     const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
-    if (pa == NULL)
-        return LuaCallbackError(luastate, "internal error: no packet");
-
-    return LuaCallbackRuleClassPushToStackFromPacketAlert(luastate, pa);
+    if (pa != NULL) {
+        s = pa->s;
+    } else {
+        s = LuaStateGetSignature(luastate);
+        if (s == NULL)
+            return LuaCallbackError(luastate, "internal error: no packet alert or signature");
+    }
+    return LuaCallbackRuleClassPushToStackFromSignature(luastate, s);
 }
 
 static int LuaCallbackLogPath(lua_State *luastate)
index f03216f85ad264a4c2454f91d358a97df5e95756..86969348f9d2fba13751532fedff2a61d7531493 100644 (file)
@@ -97,6 +97,8 @@ const char lua_ext_key_direction[] = "suricata:lua:direction";
 
 /* key for pa (packet alert) pointer */
 const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr";
+/* key for s (signature) pointer */
+const char lua_ext_key_s[] = "suricata:lua:signature:ptr";
 /* key for file pointer */
 const char lua_ext_key_file[] = "suricata:lua:file:ptr";
 /* key for streaming buffer pointer */
@@ -195,6 +197,22 @@ void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa)
     lua_settable(luastate, LUA_REGISTRYINDEX);
 }
 
+/** \brief get signature pointer from the lua state */
+Signature *LuaStateGetSignature(lua_State *luastate)
+{
+    lua_pushlightuserdata(luastate, (void *)&lua_ext_key_s);
+    lua_gettable(luastate, LUA_REGISTRYINDEX);
+    void *s = lua_touserdata(luastate, -1);
+    return (Signature *)s;
+}
+
+void LuaStateSetSignature(lua_State *luastate, const Signature *s)
+{
+    lua_pushlightuserdata(luastate, (void *)&lua_ext_key_s);
+    lua_pushlightuserdata(luastate, (void *)s);
+    lua_settable(luastate, LUA_REGISTRYINDEX);
+}
+
 /** \brief get file pointer from the lua state */
 File *LuaStateGetFile(lua_State *luastate)
 {
index 7d655a6aab57c926e436c6ab564c3b8f54fcec89..273b786eae28c76603c4c48b7becd07a1653b519 100644 (file)
@@ -63,6 +63,8 @@ Flow *LuaStateGetFlow(lua_State *luastate);
 
 PacketAlert *LuaStateGetPacketAlert(lua_State *luastate);
 
+Signature *LuaStateGetSignature(lua_State *luastate);
+
 /** \brief get file pointer from the lua state */
 File *LuaStateGetFile(lua_State *luastate);
 
@@ -83,6 +85,8 @@ void LuaStateSetFlow(lua_State *luastate, Flow *f);
 
 void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa);
 
+void LuaStateSetSignature(lua_State *luastate, const Signature *s);
+
 void LuaStateSetFile(lua_State *luastate, File *file);
 
 void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv);