aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_http.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/lua_api/l_http.cpp')
-rw-r--r--src/script/lua_api/l_http.cpp66
1 files changed, 23 insertions, 43 deletions
diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp
index 5ea3b3f99..bd359b3cc 100644
--- a/src/script/lua_api/l_http.cpp
+++ b/src/script/lua_api/l_http.cpp
@@ -21,14 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_converter.h"
#include "common/c_content.h"
#include "lua_api/l_http.h"
+#include "cpp_api/s_security.h"
#include "httpfetch.h"
#include "settings.h"
#include "debug.h"
#include "log.h"
-#include <algorithm>
#include <iomanip>
-#include <cctype>
#define HTTP_API(name) \
lua_pushstring(L, #name); \
@@ -42,12 +41,10 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req)
req.caller = httpfetch_caller_alloc_secure();
getstringfield(L, 1, "url", req.url);
- lua_getfield(L, 1, "user_agent");
- if (lua_isstring(L, -1))
- req.useragent = getstringfield_default(L, 1, "user_agent", "");
- lua_pop(L, 1);
+ getstringfield(L, 1, "user_agent", req.useragent);
req.multipart = getboolfield_default(L, 1, "multipart", false);
- req.timeout = getintfield_default(L, 1, "timeout", 3) * 1000;
+ if (getintfield(L, 1, "timeout", req.timeout))
+ req.timeout *= 1000;
lua_getfield(L, 1, "method");
if (lua_isstring(L, -1)) {
@@ -165,58 +162,40 @@ int ModApiHttp::l_http_fetch_async_get(lua_State *L)
return 1;
}
-int ModApiHttp::l_request_http_api(lua_State *L)
+int ModApiHttp::l_set_http_api_lua(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- // We have to make sure that this function is being called directly by
- // a mod, otherwise a malicious mod could override this function and
- // steal its return value.
- lua_Debug info;
-
- // Make sure there's only one item below this function on the stack...
- if (lua_getstack(L, 2, &info)) {
- return 0;
- }
- FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed");
- FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed");
-
- // ...and that that item is the main file scope.
- if (strcmp(info.what, "main") != 0) {
- return 0;
- }
-
- // Mod must be listed in secure.http_mods or secure.trusted_mods
- lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
- if (!lua_isstring(L, -1)) {
- return 0;
- }
+ // This is called by builtin to give us a function that will later
+ // populate the http_api table with additional method(s).
+ // We need this because access to the HTTP api is security-relevant and
+ // any mod could just mess with a global variable.
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
- std::string mod_name = readParam<std::string>(L, -1);
- std::string http_mods = g_settings->get("secure.http_mods");
- http_mods.erase(std::remove(http_mods.begin(), http_mods.end(), ' '), http_mods.end());
- std::vector<std::string> mod_list_http = str_split(http_mods, ',');
+ return 0;
+}
- std::string trusted_mods = g_settings->get("secure.trusted_mods");
- trusted_mods.erase(std::remove(trusted_mods.begin(), trusted_mods.end(), ' '), trusted_mods.end());
- std::vector<std::string> mod_list_trusted = str_split(trusted_mods, ',');
+int ModApiHttp::l_request_http_api(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
- mod_list_http.insert(mod_list_http.end(), mod_list_trusted.begin(), mod_list_trusted.end());
- if (std::find(mod_list_http.begin(), mod_list_http.end(), mod_name) == mod_list_http.end()) {
+ if (!ScriptApiSecurity::checkWhitelisted(L, "secure.http_mods") &&
+ !ScriptApiSecurity::checkWhitelisted(L, "secure.trusted_mods")) {
lua_pushnil(L);
return 1;
}
- lua_getglobal(L, "core");
- lua_getfield(L, -1, "http_add_fetch");
+ lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
+ assert(lua_isfunction(L, -1));
lua_newtable(L);
HTTP_API(fetch_async);
HTTP_API(fetch_async_get);
// Stack now looks like this:
- // <core.http_add_fetch> <table with fetch_async, fetch_async_get>
- // Now call core.http_add_fetch to append .fetch(request, callback) to table
+ // <function> <table with fetch_async, fetch_async_get>
+ // Now call it to append .fetch(request, callback) to table
lua_call(L, 1, 1);
return 1;
@@ -249,6 +228,7 @@ void ModApiHttp::Initialize(lua_State *L, int top)
API_FCT(get_http_api);
} else {
API_FCT(request_http_api);
+ API_FCT(set_http_api_lua);
}
#endif