From: Victor Julien Date: Wed, 19 Mar 2014 15:13:38 +0000 (+0100) Subject: output-lua: add file callbacks X-Git-Tag: suricata-2.1beta2~138 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=07ff85a44e89b225982c9830a2d7fed4d8cb4f27;p=thirdparty%2Fsuricata.git output-lua: add file callbacks 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() --- diff --git a/src/output-lua-common.c b/src/output-lua-common.c index 0770705c6c..12fc337225 100644 --- a/src/output-lua-common.c +++ b/src/output-lua-common.c @@ -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; } diff --git a/src/output-lua.c b/src/output-lua.c index 0d55b13041..4dff5e5556 100644 --- a/src/output-lua.c +++ b/src/output-lua.c @@ -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)); } diff --git a/src/util-lua.c b/src/util-lua.c index 7fae979ac8..06f5fec2a0 100644 --- a/src/util-lua.c +++ b/src/util-lua.c @@ -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); diff --git a/src/util-lua.h b/src/util-lua.h index d68970f354..39557a1583 100644 --- a/src/util-lua.h +++ b/src/util-lua.h @@ -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 */