From 91ecf759e3fb8d6dd081c5d0822021cadb2f40d7 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 23 Oct 2014 14:35:16 -0700 Subject: [PATCH] First implementation of read/write file access. We need better security for this though, you could potentially overwrite any file on the local machine the user of world has write access to atm. --- web_interface/method_handler.cpp | 3 +- world/remote_call.cpp | 59 ++++++++++++++++++++++++++++---- world/remote_call.h | 3 +- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/web_interface/method_handler.cpp b/web_interface/method_handler.cpp index 748497372..196e30924 100644 --- a/web_interface/method_handler.cpp +++ b/web_interface/method_handler.cpp @@ -17,7 +17,8 @@ void register_authorized_methods() authorized_methods["Zone.GetInitialEntityPositions"] = std::make_pair(10, handle_method_zone); authorized_methods["Zone.MoveEntity"] = std::make_pair(10, handle_method_zone); authorized_methods["Zone.Action"] = std::make_pair(10, handle_method_zone); - authorized_methods["Quest.GetScript"] = std::make_pair(10, handle_method_world); + authorized_methods["World.GetFileContents"] = std::make_pair(10, handle_method_world); + authorized_methods["World.SaveFileContents"] = std::make_pair(10, handle_method_world); } void register_unauthorized_methods() diff --git a/world/remote_call.cpp b/world/remote_call.cpp index c403d1c1c..ea0a5a6fd 100644 --- a/world/remote_call.cpp +++ b/world/remote_call.cpp @@ -56,7 +56,8 @@ void register_remote_call_handlers() { remote_call_methods["Zone.GetInitialEntityPositions"] = handle_rc_relay; remote_call_methods["Zone.MoveEntity"] = handle_rc_relay; remote_call_methods["Zone.Action"] = handle_rc_relay; - remote_call_methods["Quest.GetScript"] = handle_rc_quest_interface; + remote_call_methods["World.GetFileContents"] = handle_rc_get_file_contents; + remote_call_methods["World.SaveFileContents"] = handle_rc_save_file_contents; } void handle_rc_list_zones(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { @@ -162,13 +163,19 @@ void handle_rc_relay(const std::string &method, const std::string &connection_id safe_delete(pack); } -void handle_rc_quest_interface(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { +//TODO: We need to look at potential security concerns on direct file access like this. +void handle_rc_get_file_contents(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { std::string error; std::map res; + if(params.size() != 1) { + error = "Expected only one filename."; + RemoteCallResponse(connection_id, request_id, res, error); + return; + } - FILE *f = fopen("quests/global/Waypoint.pl", "rb"); + FILE *f = fopen(params[0].c_str(), "rb"); if(!f) { - error = "File not found"; + error = "File not found: " + params[0]; RemoteCallResponse(connection_id, request_id, res, error); return; } @@ -180,7 +187,7 @@ void handle_rc_quest_interface(const std::string &method, const std::string &con char *buffer = new char[sz + 1]; size_t r = fread(buffer, 1, sz, f); if(r != sz) { - error = "Unable to read file"; + error = "Unable to read file: " + params[0]; RemoteCallResponse(connection_id, request_id, res, error); fclose(f); delete[] buffer; @@ -190,6 +197,44 @@ void handle_rc_quest_interface(const std::string &method, const std::string &con fclose(f); buffer[sz] = '\0'; - res["quest_text"] = buffer; - RemoteCallResponse(connection_id, request_id, res, error); + res["quest_text"] = buffer; + res["file_name"] = params[0]; + delete[] buffer; + RemoteCallResponse(connection_id, request_id, res, error); +} + +void handle_rc_save_file_contents(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms) { + std::string error; + std::map res; + if(params.size() != 2) { + error = "Expected [filename, content]"; + RemoteCallResponse(connection_id, request_id, res, error); + return; + } + + FILE *f = fopen(params[0].c_str(), "wb"); + if(!f) { + error = "File not found: " + params[0]; + RemoteCallResponse(connection_id, request_id, res, error); + return; + } + + if(params[1].size() == 0) { + fclose(f); + res["status"] = "success"; + RemoteCallResponse(connection_id, request_id, res, error); + return; + } + + size_t r = fwrite(params[1].c_str(), 1, params[1].size(), f); + fclose(f); + + if(r != params[1].size()) { + error = "Unable to write file: " + params[0]; + RemoteCallResponse(connection_id, request_id, res, error); + return; + } + + res["status"] = "success"; + RemoteCallResponse(connection_id, request_id, res, error); } \ No newline at end of file diff --git a/world/remote_call.h b/world/remote_call.h index 09bc29dbf..56f660221 100644 --- a/world/remote_call.h +++ b/world/remote_call.h @@ -30,7 +30,8 @@ void register_remote_call_handlers(); void handle_rc_list_zones(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms); void handle_rc_get_zone_info(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms); void handle_rc_relay(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms); -void handle_rc_quest_interface(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms); +void handle_rc_get_file_contents(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms); +void handle_rc_save_file_contents(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector ¶ms); #endif