diff --git a/src/Makefile.am b/src/Makefile.am index c2cf2dd93ab5..82155d7f825d 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -506,6 +506,7 @@ noinst_HEADERS = \ util-logopenfile.h \ util-log-redis.h \ util-lua-common.h \ + util-lua-dataset.h \ util-lua-dnp3.h \ util-lua-dnp3-objects.h \ util-lua-dns.h \ @@ -1053,6 +1054,7 @@ libsuricata_c_a_SOURCES = \ util-log-redis.c \ util-lua.c \ util-lua-common.c \ + util-lua-dataset.c \ util-lua-dnp3.c \ util-lua-dnp3-objects.c \ util-lua-dns.c \ diff --git a/src/detect-lua-extensions.c b/src/detect-lua-extensions.c index 715e16d2e3cb..0dad83749c67 100644 --- a/src/detect-lua-extensions.c +++ b/src/detect-lua-extensions.c @@ -24,40 +24,17 @@ */ #include "suricata-common.h" -#include "conf.h" -#include "threads.h" #include "decode.h" -#include "datasets.h" - #include "detect.h" -#include "detect-parse.h" -#include "detect-flowvar.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" #include "flow.h" #include "flow-var.h" -#include "flow-util.h" #include "util-debug.h" -#include "util-spm-bm.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" - -#include "stream-tcp.h" #include "detect-lua.h" -#include "queue.h" -#include "util-cpu.h" - #include "app-layer-parser.h" #include "util-lua.h" @@ -74,13 +51,6 @@ static const char luaext_key_ld[] = "suricata:luadata"; -/* hack to please scan-build. Even though LuaCallbackError *always* - * returns 2, scan-build doesn't accept it and generates false - * positives */ -#define LUA_ERROR(msg) \ - LuaCallbackError(luastate, (msg)); \ - return 2 - static int GetLuaData(lua_State *luastate, DetectLuaData **ret_ld) { *ret_ld = NULL; @@ -415,110 +385,6 @@ static int LuaSetFlowint(lua_State *luastate) return 0; } -struct LuaDataset { - Dataset *set; -}; - -static int LuaDatasetGC(lua_State *luastate) -{ - SCLogDebug("gc:start"); - struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); - SCLogDebug("deref %s", s->set->name); - s->set = NULL; - SCLogDebug("gc:done"); - return 0; -} - -static int LuaDatasetGetRef(lua_State *luastate) -{ - SCLogDebug("get"); - struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); - if (s == NULL) { - LUA_ERROR("dataset is not initialized"); - } - - const char *name = lua_tostring(luastate, 2); - if (name == NULL) { - LUA_ERROR("null string"); - } - - Dataset *dataset = DatasetFind(name, DATASET_TYPE_STRING); - if (dataset == NULL) { - LUA_ERROR("dataset not found"); - } - s->set = dataset; - return 0; -} - -static int LuaDatasetAdd(lua_State *luastate) -{ - SCLogDebug("add:start"); - struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); - if (s == NULL) { - LUA_ERROR("dataset is not initialized"); - } - if (!lua_isstring(luastate, 2)) { - LUA_ERROR("1st arg is not a string"); - } - if (!lua_isnumber(luastate, 3)) { - LUA_ERROR("2nd arg is not a number"); - } - - const uint8_t *str = (const uint8_t *)lua_tostring(luastate, 2); - if (str == NULL) { - LUA_ERROR("1st arg is not null string"); - } - - uint32_t str_len = lua_tonumber(luastate, 3); - - int r = DatasetAdd(s->set, (const uint8_t *)str, str_len); - /* return value through luastate, as a luanumber */ - lua_pushnumber(luastate, (lua_Number)r); - SCLogDebug("add:end"); - return 1; -} - -static int LuaDatasetNew(lua_State *luastate) -{ - SCLogDebug("new:start"); - struct LuaDataset *s = (struct LuaDataset *)lua_newuserdata(luastate, sizeof(*s)); - if (s == NULL) { - LUA_ERROR("failed to get userdata"); - } - luaL_getmetatable(luastate, "dataset::metatable"); - lua_setmetatable(luastate, -2); - SCLogDebug("new:done"); - return 1; -} - -// clang-format off -const luaL_Reg datasetlib[] = { - { "new", LuaDatasetNew }, - { "get", LuaDatasetGetRef }, - { "add", LuaDatasetAdd }, - { "__gc", LuaDatasetGC }, - { NULL, NULL } -}; -// clang-format on - -static void SetFuncs(lua_State *luastate, const luaL_Reg *lib) -{ - for (; lib->name != NULL; lib++) { - lua_pushstring(luastate, lib->name); - lua_pushcfunction(luastate, lib->func); - lua_settable(luastate, -3); - } -} - -void LuaLoadDatasetLib(lua_State *luastate) -{ - luaL_newmetatable(luastate, "dataset::metatable"); - lua_pushvalue(luastate, -1); - lua_setfield(luastate, -2, "__index"); - luaL_setfuncs(luastate, datasetlib, 0); - luaL_newlib(luastate, datasetlib); -} - static int LuaIncrFlowint(lua_State *luastate) { uint32_t idx; diff --git a/src/util-lua-common.h b/src/util-lua-common.h index 5d6ea41f4be4..02e62b829ebe 100644 --- a/src/util-lua-common.h +++ b/src/util-lua-common.h @@ -35,4 +35,11 @@ int LuaRegisterFunctions(lua_State *luastate); int LuaStateNeedProto(lua_State *luastate, AppProto alproto); +/* hack to please scan-build. Even though LuaCallbackError *always* + * returns 2, scan-build doesn't accept it and generates false + * positives */ +#define LUA_ERROR(msg) \ + LuaCallbackError(luastate, (msg)); \ + return 2 + #endif /* SURICATA_UTIL_LUA_COMMON_H */ diff --git a/src/util-lua-dataset.c b/src/util-lua-dataset.c new file mode 100644 index 000000000000..6af9ba5901e7 --- /dev/null +++ b/src/util-lua-dataset.c @@ -0,0 +1,130 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * Dataset API for Lua. + * + * local dataset = require("suricata.dataset") + */ + +#include "suricata-common.h" + +#include "util-lua-dataset.h" + +#include "app-layer-protos.h" /* Required by util-lua-common. */ +#include "util-lua-common.h" +#include "util-lua.h" +#include "util-debug.h" + +#include "datasets.h" + +struct LuaDataset { + Dataset *set; +}; + +static int LuaDatasetGC(lua_State *luastate) +{ + SCLogDebug("gc:start"); + struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); + SCLogDebug("deref %s", s->set->name); + s->set = NULL; + SCLogDebug("gc:done"); + return 0; +} + +static int LuaDatasetGetRef(lua_State *luastate) +{ + SCLogDebug("get"); + struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); + if (s == NULL) { + LUA_ERROR("dataset is not initialized"); + } + + const char *name = lua_tostring(luastate, 2); + if (name == NULL) { + LUA_ERROR("null string"); + } + + Dataset *dataset = DatasetFind(name, DATASET_TYPE_STRING); + if (dataset == NULL) { + LUA_ERROR("dataset not found"); + } + s->set = dataset; + return 0; +} + +static int LuaDatasetAdd(lua_State *luastate) +{ + SCLogDebug("add:start"); + struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); + if (s == NULL) { + LUA_ERROR("dataset is not initialized"); + } + if (!lua_isstring(luastate, 2)) { + LUA_ERROR("1st arg is not a string"); + } + if (!lua_isnumber(luastate, 3)) { + LUA_ERROR("2nd arg is not a number"); + } + + const uint8_t *str = (const uint8_t *)lua_tostring(luastate, 2); + if (str == NULL) { + LUA_ERROR("1st arg is not null string"); + } + + uint32_t str_len = lua_tonumber(luastate, 3); + + int r = DatasetAdd(s->set, (const uint8_t *)str, str_len); + /* return value through luastate, as a luanumber */ + lua_pushnumber(luastate, (lua_Number)r); + SCLogDebug("add:end"); + return 1; +} + +static int LuaDatasetNew(lua_State *luastate) +{ + SCLogDebug("new:start"); + struct LuaDataset *s = (struct LuaDataset *)lua_newuserdata(luastate, sizeof(*s)); + if (s == NULL) { + LUA_ERROR("failed to get userdata"); + } + luaL_getmetatable(luastate, "dataset::metatable"); + lua_setmetatable(luastate, -2); + SCLogDebug("new:done"); + return 1; +} + +// clang-format off +static const luaL_Reg datasetlib[] = { + { "new", LuaDatasetNew }, + { "get", LuaDatasetGetRef }, + { "add", LuaDatasetAdd }, + { "__gc", LuaDatasetGC }, + { NULL, NULL } +}; +// clang-format on + +void LuaLoadDatasetLib(lua_State *luastate) +{ + luaL_newmetatable(luastate, "dataset::metatable"); + lua_pushvalue(luastate, -1); + lua_setfield(luastate, -2, "__index"); + luaL_setfuncs(luastate, datasetlib, 0); + luaL_newlib(luastate, datasetlib); +} diff --git a/src/util-lua-dataset.h b/src/util-lua-dataset.h new file mode 100644 index 000000000000..2bf0efdddc75 --- /dev/null +++ b/src/util-lua-dataset.h @@ -0,0 +1,25 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef SURICATA_UTIL_LUA_DATASET_H +#define SURICATA_UTIL_LUA_DATASET_H + +#include "lua.h" + +void LuaLoadDatasetLib(lua_State *luastate); + +#endif /* SURICATA_UTIL_LUA_DATASET_H */ diff --git a/src/util-lua-sandbox.c b/src/util-lua-sandbox.c index 6b6a97f4c3b9..4c4838418f39 100644 --- a/src/util-lua-sandbox.c +++ b/src/util-lua-sandbox.c @@ -31,12 +31,7 @@ #include "util-debug.h" #include "util-validate.h" #include "util-lua-sandbox.h" - -/* TODO: Need to get Lua dataset support out of detect-lua-extensions, - * shouldn't need to pull in detect-engine, if via another include. */ -#include "detect-lua.h" -#include "detect-engine.h" -#include "detect-lua-extensions.h" +#include "util-lua-dataset.h" #define SANDBOX_CTX "SANDBOX_CTX"