output-lua: lua module search path configuration

By default, use an empty search path. This gives us a predictable
default. If a user needs access to external modules, the search path
must be set in the configuration file.

Ticket: #7169
pull/12581/head
Jason Ish 9 months ago committed by Victor Julien
parent 8402d79962
commit c3716ac56b

@ -51,7 +51,14 @@
* it's parent_ctx->data ptr.
*/
typedef struct LogLuaMasterCtx_ {
char script_dir[PATH_MAX]; /**< contains script-dir */
/** \brief Path to script directory. */
char script_dir[PATH_MAX];
/** \brief Lua search path for Lua modules. */
char path[PATH_MAX];
/** \brief Lua search path for C modules. */
char cpath[PATH_MAX];
} LogLuaMasterCtx;
typedef struct LogLuaCtx_ {
@ -396,6 +403,33 @@ typedef struct LogLuaScriptOptions_ {
int stats;
} LogLuaScriptOptions;
/** \brief Setup or clear Lua module search paths.
*
* If search paths are provided by the configuration, set them up,
* otherwise clear the default search paths.
*/
static void LuaSetPaths(lua_State *L, LogLuaMasterCtx *ctx)
{
lua_getglobal(L, "package");
if (strlen(ctx->path) > 0) {
lua_pushstring(L, ctx->path);
} else {
lua_pushstring(L, "");
}
lua_setfield(L, -2, "path");
if (strlen(ctx->cpath) > 0) {
lua_pushstring(L, ctx->cpath);
} else {
lua_pushstring(L, "");
}
lua_setfield(L, -2, "cpath");
/* Pop package. */
lua_pop(L, 1);
}
/** \brief load and evaluate the script
*
* This function parses the script, checks if all the required functions
@ -406,12 +440,14 @@ typedef struct LogLuaScriptOptions_ {
* \param options struct to pass script requirements/options back to caller
* \retval errcode 0 ok, -1 error
*/
static int LuaScriptInit(const char *filename, LogLuaScriptOptions *options) {
static int LuaScriptInit(const char *filename, LogLuaScriptOptions *options, LogLuaMasterCtx *ctx)
{
lua_State *luastate = LuaGetState();
if (luastate == NULL)
goto error;
luaL_openlibs(luastate);
SCLuaRequirefBuiltIns(luastate);
LuaSetPaths(luastate, ctx);
int status = luaL_loadfile(luastate, filename);
if (status) {
@ -537,7 +573,7 @@ error:
*
* \retval state Returns the set up luastate on success, NULL on error
*/
static lua_State *LuaScriptSetup(const char *filename)
static lua_State *LuaScriptSetup(const char *filename, LogLuaMasterCtx *ctx)
{
lua_State *luastate = LuaGetState();
if (luastate == NULL) {
@ -547,6 +583,7 @@ static lua_State *LuaScriptSetup(const char *filename)
luaL_openlibs(luastate);
SCLuaRequirefBuiltIns(luastate);
LuaSetPaths(luastate, ctx);
int status = luaL_loadfile(luastate, filename);
if (status) {
@ -615,12 +652,11 @@ static OutputInitResult OutputLuaLogInitSub(ConfNode *conf, OutputCtx *parent_ct
SCMutexInit(&lua_ctx->m, NULL);
const char *dir = "";
if (parent_ctx && parent_ctx->data) {
LogLuaMasterCtx *mc = parent_ctx->data;
dir = mc->script_dir;
}
BUG_ON(parent_ctx == NULL);
LogLuaMasterCtx *mc = parent_ctx->data;
BUG_ON(mc == NULL);
const char *dir = mc->script_dir;
char path[PATH_MAX] = "";
int ret = snprintf(path, sizeof(path),"%s%s%s", dir, strlen(dir) ? "/" : "", conf->val);
if (ret < 0 || ret == sizeof(path)) {
@ -630,7 +666,7 @@ static OutputInitResult OutputLuaLogInitSub(ConfNode *conf, OutputCtx *parent_ct
SCLogDebug("script full path %s", path);
SCMutexLock(&lua_ctx->m);
lua_ctx->luastate = LuaScriptSetup(path);
lua_ctx->luastate = LuaScriptSetup(path, mc);
SCMutexUnlock(&lua_ctx->m);
if (lua_ctx->luastate == NULL)
goto error;
@ -696,6 +732,17 @@ static OutputInitResult OutputLuaLogInit(ConfNode *conf)
}
LogLuaMasterCtx *master_config = output_ctx->data;
strlcpy(master_config->script_dir, dir, sizeof(master_config->script_dir));
const char *lua_path = ConfNodeLookupChildValue(conf, "path");
if (lua_path && strlen(lua_path) > 0) {
strlcpy(master_config->path, lua_path, sizeof(master_config->path));
}
const char *lua_cpath = ConfNodeLookupChildValue(conf, "cpath");
if (lua_cpath && strlen(lua_cpath) > 0) {
strlcpy(master_config->cpath, lua_cpath, sizeof(master_config->cpath));
}
TAILQ_INIT(&output_ctx->submodules);
/* check the enables scripts and set them up as submodules */
@ -709,7 +756,7 @@ static OutputInitResult OutputLuaLogInit(ConfNode *conf)
snprintf(path, sizeof(path),"%s%s%s", dir, strlen(dir) ? "/" : "", script->val);
SCLogDebug("script full path %s", path);
int r = LuaScriptInit(path, &opts);
int r = LuaScriptInit(path, &opts, master_config);
if (r != 0) {
SCLogError("couldn't initialize script");
goto error;

@ -555,6 +555,15 @@ outputs:
# https://docs.suricata.io/en/latest/output/lua-output.html
- lua:
enabled: no
# By default the Lua module search paths are empty. If you plan
# to use external modules these paths will need to be set. The
# examples below are likely suitable for finding modules
# installed with a package manager on a 64 bit Linux system, but
# may need tweaking.
#path: "/usr/share/lua/5.4/?.lua;/usr/share/lua/5.4/?/init.lua;/usr/lib64/lua/5.4/?.lua;/usr/lib64/lua/5.4/?/init.lua;./?.lua;./?/init.lua"
#cpath: "/usr/lib64/lua/5.4/?.so;/usr/lib64/lua/5.4/loadall.so;./?.so"
#scripts-dir: /etc/suricata/lua-output/
scripts:
# - script1.lua

Loading…
Cancel
Save