diff --git a/doc/lua_api.txt b/doc/lua_api.txt index c82208286..0e1dc487f 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2290,13 +2290,20 @@ These functions return the leftover itemstack. * `minetest.forceload_block(pos)` * forceloads the position `pos`. * returns `true` if area could be forceloaded + * Please note that forceloaded areas are saved when the server restarts. * `minetest.forceload_free_block(pos)` * stops forceloading the position `pos` -Please note that forceloaded areas are saved when the server restarts. -minetest.global_exists(name) -^ Checks if a global variable has been set, without triggering a warning. +* `minetest.request_insecure_environment()`: returns an environment containing + insecure functions if the calling mod has been listed as trusted in the + `secure.trusted_mods` setting or security is disabled, otherwise returns `nil`. + * Only works at init time. + * **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED ENVIRONMENT, STORE IT IN + A LOCAL VARIABLE!** + +* `minetest.global_exists(name)` + * Checks if a global variable has been set, without triggering a warning. ### Global objects * `minetest.env`: `EnvRef` of the server environment and world. diff --git a/minetest.conf.example b/minetest.conf.example index 6474289bd..392bd55bb 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -571,4 +571,7 @@ # Prevent mods from doing insecure things like running shell commands. #secure.enable_security = false +# Comma-separated list of trusted mods that are allowed to access insecure +# functions even when mod security is on (via request_insecure_environment()). +#secure.trusted_mods = diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index f26b4c8ad..af1aa4140 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -273,6 +273,7 @@ void set_default_settings(Settings *settings) settings->setDefault("emergequeue_limit_generate", "32"); settings->setDefault("num_emerge_threads", "1"); settings->setDefault("secure.enable_security", "false"); + settings->setDefault("secure.trusted_mods", ""); // physics stuff settings->setDefault("movement_acceleration_default", "3"); diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index e16b6feab..2bcc114e2 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "settings.h" #include "util/auth.h" +#include // debug(...) // Writes a line to dstream @@ -316,7 +317,7 @@ int ModApiUtil::l_compress(lua_State *L) int ModApiUtil::l_decompress(lua_State *L) { size_t size; - const char * data = luaL_checklstring(L, 1, &size); + const char *data = luaL_checklstring(L, 1, &size); std::istringstream is(std::string(data, size)); std::ostringstream os; @@ -339,6 +340,30 @@ int ModApiUtil::l_mkdir(lua_State *L) } +int ModApiUtil::l_request_insecure_environment(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + if (!ScriptApiSecurity::isSecure(L)) { + lua_getglobal(L, "_G"); + return 1; + } + lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD); + if (!lua_isstring(L, -1)) { + lua_pushnil(L); + return 1; + } + const char *mod_name = lua_tostring(L, -1); + std::string trusted_mods = g_settings->get("secure.trusted_mods"); + std::vector mod_list = str_split(trusted_mods, ','); + if (std::find(mod_list.begin(), mod_list.end(), mod_name) == mod_list.end()) { + lua_pushnil(L); + return 1; + } + lua_getfield(L, LUA_REGISTRYINDEX, "globals_backup"); + return 1; +} + + void ModApiUtil::Initialize(lua_State *L, int top) { API_FCT(debug); @@ -366,6 +391,8 @@ void ModApiUtil::Initialize(lua_State *L, int top) API_FCT(decompress); API_FCT(mkdir); + + API_FCT(request_insecure_environment); } void ModApiUtil::InitializeAsync(AsyncEngine& engine) diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h index bf7cd71d3..336173664 100644 --- a/src/script/lua_api/l_util.h +++ b/src/script/lua_api/l_util.h @@ -90,6 +90,9 @@ private: // mkdir(path) static int l_mkdir(lua_State *L); + // request_insecure_environment() + static int l_request_insecure_environment(lua_State *L); + public: static void Initialize(lua_State *L, int top); @@ -98,3 +101,4 @@ public: }; #endif /* L_UTIL_H_ */ +