]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
output-lua: add file callbacks
authorVictor Julien <victor@inliniac.net>
Wed, 19 Mar 2014 15:13:38 +0000 (16:13 +0100)
committerVictor Julien <victor@inliniac.net>
Fri, 15 Aug 2014 11:58:26 +0000 (13:58 +0200)
SCFileInfo: returns fileid (number), txid (number), name (string),
            size (number), magic (string), md5 in hex (string)

Example:

    function log(args)
        fileid, txid, name, size, magic, md5 = SCFileInfo()

SCFileState: returns state (string), stored (bool)

Example:
    function log(args)
        state, stored = SCFileState()

src/output-lua-common.c
src/output-lua.c
src/util-lua.c
src/util-lua.h

index 0770705c6c281634ebbafcb5d04ae484681e20b5..12fc3372257e1d3dc006087a20d92757050bc22c 100644 (file)
@@ -420,6 +420,95 @@ static int LuaCallbackLogError(lua_State *luastate)
     return 0;
 }
 
+/** \internal
+ *  \brief fill lua stack with file info
+ *  \param luastate the lua state
+ *  \param pa pointer to packet alert struct
+ *  \retval cnt number of data items placed on the stack
+ *
+ *  Places: fileid (number), txid (number), name (string),
+ *          size (number), magic (string), md5 in hex (string)
+ */
+static int LuaCallbackFileInfoPushToStackFromFile(lua_State *luastate, const File *file)
+{
+#ifdef HAVE_NSS
+    char md5[33] = "";
+    char *md5ptr = md5;
+    if (file->flags & FILE_MD5) {
+        size_t x;
+        for (x = 0; x < sizeof(file->md5); x++) {
+            char one[3] = "";
+            snprintf(one, sizeof(one), "%02x", file->md5[x]);
+            strlcat(md5, one, sizeof(md5));
+        }
+    }
+#else
+    char *md5ptr = NULL;
+#endif
+
+    lua_pushnumber(luastate, file->file_id);
+    lua_pushnumber(luastate, file->txid);
+    lua_pushlstring(luastate, (char *)file->name, file->name_len);
+    lua_pushnumber(luastate, file->size);
+    lua_pushstring (luastate, file->magic);
+    lua_pushstring(luastate, md5ptr);
+    return 6;
+}
+
+/** \internal
+ *  \brief Wrapper for getting tuple info into a lua script
+ *  \retval cnt number of items placed on the stack
+ */
+static int LuaCallbackFileInfo(lua_State *luastate)
+{
+    const File *file = LuaStateGetFile(luastate);
+    if (file == NULL)
+        return LuaCallbackError(luastate, "internal error: no file");
+
+    return LuaCallbackFileInfoPushToStackFromFile(luastate, file);
+}
+
+/** \internal
+ *  \brief fill lua stack with file info
+ *  \param luastate the lua state
+ *  \param pa pointer to packet alert struct
+ *  \retval cnt number of data items placed on the stack
+ *
+ *  Places: state (string), stored (bool)
+ */
+static int LuaCallbackFileStatePushToStackFromFile(lua_State *luastate, const File *file)
+{
+    const char *state = "UNKNOWN";
+    switch (file->state) {
+        case FILE_STATE_CLOSED:
+            state = "CLOSED";
+            break;
+        case FILE_STATE_TRUNCATED:
+            state = "TRUNCATED";
+            break;
+        case FILE_STATE_ERROR:
+            state = "ERROR";
+            break;
+    }
+
+    lua_pushstring (luastate, state);
+    lua_pushboolean (luastate, file->flags & FILE_STORED);
+    return 2;
+}
+
+/** \internal
+ *  \brief Wrapper for getting tuple info into a lua script
+ *  \retval cnt number of items placed on the stack
+ */
+static int LuaCallbackFileState(lua_State *luastate)
+{
+    const File *file = LuaStateGetFile(luastate);
+    if (file == NULL)
+        return LuaCallbackError(luastate, "internal error: no file");
+
+    return LuaCallbackFileStatePushToStackFromFile(luastate, file);
+}
+
 int LogLuaRegisterFunctions(lua_State *luastate)
 {
     /* registration of the callbacks */
@@ -451,6 +540,12 @@ int LogLuaRegisterFunctions(lua_State *luastate)
     lua_setglobal(luastate, "SCRuleMsg");
     lua_pushcfunction(luastate, LuaCallbackRuleClass);
     lua_setglobal(luastate, "SCRuleClass");
+
+    lua_pushcfunction(luastate, LuaCallbackFileInfo);
+    lua_setglobal(luastate, "SCFileInfo");
+    lua_pushcfunction(luastate, LuaCallbackFileState);
+    lua_setglobal(luastate, "SCFileState");
+
     return 0;
 }
 
index 0d55b130414331031b820782f0e4c275c5d135d0..4dff5e55563f95f79bca9f028e53659343dec3d1 100644 (file)
@@ -254,19 +254,12 @@ static int LuaFileLogger(ThreadVars *tv, void *thread_data, const Packet *p, con
     LuaStateSetPacket(td->lua_ctx->luastate, (Packet *)p);
     LuaStateSetTX(td->lua_ctx->luastate, txptr);
     LuaStateSetFlow(td->lua_ctx->luastate, p->flow, /* locked */FALSE);
+    LuaStateSetFile(td->lua_ctx->luastate, (File *)ff);
 
     /* get the lua function to call */
     lua_getglobal(td->lua_ctx->luastate, "log");
 
-    /* prepare data to pass to script */
-    lua_newtable(td->lua_ctx->luastate);
-
-    LogLuaPushTableKeyValueArray(td->lua_ctx->luastate, "filename", ff->name, ff->name_len);
-    LogLuaPushTableKeyValueString(td->lua_ctx->luastate, "filemagic", ff->magic);
-    LogLuaPushTableKeyValueArray(td->lua_ctx->luastate, "filemd5", ff->md5, sizeof(ff->md5));
-
-    //LuaPrintStack(td->lua_ctx->luastate);
-    int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
+    int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0);
     if (retval != 0) {
         SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
     }
index 7fae979ac8f2473fd14702de4f04ce93bc2e7a06..06f5fec2a0a0c2e9ecff515579cbbe65b0f036ac 100644 (file)
@@ -65,6 +65,8 @@ const char lua_ext_key_flow_lock_hint[] = "suricata:lua:flow:lock_hint";
 
 /* key for pa (packet alert) pointer */
 const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr";
+/* key for file pointer */
+const char lua_ext_key_file[] = "suricata:lua:file:ptr";
 
 /** \brief get packet pointer from the lua state */
 Packet *LuaStateGetPacket(lua_State *luastate)
@@ -145,6 +147,22 @@ void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa)
     lua_settable(luastate, LUA_REGISTRYINDEX);
 }
 
+/** \brief get file pointer from the lua state */
+File *LuaStateGetFile(lua_State *luastate)
+{
+    lua_pushlightuserdata(luastate, (void *)&lua_ext_key_file);
+    lua_gettable(luastate, LUA_REGISTRYINDEX);
+    void *file = lua_touserdata(luastate, -1);
+    return (File *)file;
+}
+
+void LuaStateSetFile(lua_State *luastate, File *file)
+{
+    lua_pushlightuserdata(luastate, (void *)&lua_ext_key_file);
+    lua_pushlightuserdata(luastate, (void *)file);
+    lua_settable(luastate, LUA_REGISTRYINDEX);
+}
+
 /** \brief dump stack from lua state to screen */
 void LuaPrintStack(lua_State *state) {
     int size = lua_gettop(state);
index d68970f35425ab4241f1a57fdfb82b39acd00f77..39557a15831194c1405607e1ea305b9613900402 100644 (file)
@@ -42,6 +42,9 @@ Flow *LuaStateGetFlow(lua_State *luastate, int *lock_hint);
 
 PacketAlert *LuaStateGetPacketAlert(lua_State *luastate);
 
+/** \brief get file pointer from the lua state */
+File *LuaStateGetFile(lua_State *luastate);
+
 /* sets */
 
 void LuaStateSetPacket(lua_State *luastate, Packet *p);
@@ -57,6 +60,8 @@ void LuaStateSetFlow(lua_State *luastate, Flow *f, int need_flow_lock);
 
 void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa);
 
+void LuaStateSetFile(lua_State *luastate, File *file);
+
 void LuaPrintStack(lua_State *state);
 
 #endif /* HAVE_LUA */