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()
pull/1112/head
Victor Julien 12 years ago
parent 3343060d85
commit 07ff85a44e

@ -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;
}

@ -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));
}

@ -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);

@ -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 */

Loading…
Cancel
Save