diff options
author | Alexander Tkachev | 2016-08-01 14:55:58 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | acfa1d1f1069e4a4bbed8599d0e6b4e9b2ea37fe (patch) | |
tree | e9d57e3797ac334df20794c10bfec2a049e974b0 /backends/networking/sdl_net/handlers | |
parent | dd9e5a95dc5bbae20d3da05d638139120f3113f4 (diff) | |
download | scummvm-rg350-acfa1d1f1069e4a4bbed8599d0e6b4e9b2ea37fe.tar.gz scummvm-rg350-acfa1d1f1069e4a4bbed8599d0e6b4e9b2ea37fe.tar.bz2 scummvm-rg350-acfa1d1f1069e4a4bbed8599d0e6b4e9b2ea37fe.zip |
CLOUD: Handle paths in marked places
Paths containing '../' are forbidden to use in Files Manager. There is
also a special inner black list of paths which are not used and a check
that specified path is under "savepath" or "rootpath" (from "cloud"
domain).
Diffstat (limited to 'backends/networking/sdl_net/handlers')
6 files changed, 50 insertions, 18 deletions
diff --git a/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp index c539525820..284bf16651 100644 --- a/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp +++ b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp @@ -61,6 +61,12 @@ void CreateDirectoryHandler::handle(Client &client) { return; } + // check that <path> contains no '../' + if (HandlerUtils::hasForbiddenCombinations(path)) { + handleError(client, _("Invalid path!")); + return; + } + // transform virtual path to actual file system one Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd) || path.empty()) { @@ -68,10 +74,12 @@ void CreateDirectoryHandler::handle(Client &client) { return; } - // TODO: handle <path> - - // check that <path> exists and is directory + // check that <path> exists, is directory and isn't forbidden AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); + if (!HandlerUtils::permittedPath(node->getPath())) { + handleError(client, _("Invalid path!")); + return; + } if (!node->exists()) { handleError(client, _("Parent directory doesn't exists!")); return; diff --git a/backends/networking/sdl_net/handlers/downloadfilehandler.cpp b/backends/networking/sdl_net/handlers/downloadfilehandler.cpp index 8f5633c6be..9e212b1a6c 100644 --- a/backends/networking/sdl_net/handlers/downloadfilehandler.cpp +++ b/backends/networking/sdl_net/handlers/downloadfilehandler.cpp @@ -44,6 +44,12 @@ void DownloadFileHandler::handle(Client &client) { return; } + // check that <path> contains no '../' + if (HandlerUtils::hasForbiddenCombinations(path)) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + // transform virtual path to actual file system one Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) { @@ -51,10 +57,12 @@ void DownloadFileHandler::handle(Client &client) { return; } - // TODO: handle <path> - - // check that <path> exists and is directory + // check that <path> exists, is directory and isn't forbidden AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); + if (!HandlerUtils::permittedPath(node->getPath())) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } if (!node->exists()) { HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The file doesn't exist!")); return; diff --git a/backends/networking/sdl_net/handlers/filesbasehandler.cpp b/backends/networking/sdl_net/handlers/filesbasehandler.cpp index 68d7919d4a..5e5787b624 100644 --- a/backends/networking/sdl_net/handlers/filesbasehandler.cpp +++ b/backends/networking/sdl_net/handlers/filesbasehandler.cpp @@ -52,12 +52,16 @@ bool FilesBaseHandler::transformPath(Common::String &path, Common::String &prefi if (path.hasPrefix("/root")) { prefixToAdd = "/root/"; - prefixToRemove = ""; + prefixToRemove = (ConfMan.hasKey("rootpath", "cloud") ? ConfMan.get("rootpath", "cloud") : ""); + if (prefixToRemove.size() && prefixToRemove.lastChar() != '/' && prefixToRemove.lastChar() != '\\') + prefixToRemove += '/'; + if (prefixToRemove == "/") prefixToRemove = ""; path.erase(0, 5); + if (path.size() && (path[0] == '/' || path[0] == '\\')) + path.deleteChar(0); // if that was "/root/ab/c", it becomes "/ab/c", but we need "ab/c" + path = prefixToRemove + path; if (path == "") path = "/"; // absolute root is '/' - if (path != "/") - path.deleteChar(0); // if that was "/root/ab/c", it becomes "/ab/c", but we need "ab/c" return true; } diff --git a/backends/networking/sdl_net/handlers/filespagehandler.cpp b/backends/networking/sdl_net/handlers/filespagehandler.cpp index 56b0551ed7..0bc9237805 100644 --- a/backends/networking/sdl_net/handlers/filespagehandler.cpp +++ b/backends/networking/sdl_net/handlers/filespagehandler.cpp @@ -81,17 +81,19 @@ bool FilesPageHandler::listDirectory(Common::String path, Common::String &conten return true; } + if (HandlerUtils::hasForbiddenCombinations(path)) + return false; + Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd)) return false; - // TODO: handle <path> - Common::FSNode node = Common::FSNode(path); if (path == "/") node = node.getParent(); // absolute root - // TODO: handle <path> + if (!HandlerUtils::permittedPath(node.getPath())) + return false; if (!node.isDirectory()) return false; diff --git a/backends/networking/sdl_net/handlers/listajaxhandler.cpp b/backends/networking/sdl_net/handlers/listajaxhandler.cpp index ad8907cf27..57fa04d10d 100644 --- a/backends/networking/sdl_net/handlers/listajaxhandler.cpp +++ b/backends/networking/sdl_net/handlers/listajaxhandler.cpp @@ -46,17 +46,19 @@ Common::JSONObject ListAjaxHandler::listDirectory(Common::String path) { return successResult; } + if (HandlerUtils::hasForbiddenCombinations(path)) + return errorResult; + Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd)) return errorResult; - // TODO: handle <path> - Common::FSNode node = Common::FSNode(path); if (path == "/") node = node.getParent(); // absolute root - // TODO: handle <path> + if (!HandlerUtils::permittedPath(node.getPath())) + return errorResult; if (!node.isDirectory()) return errorResult; diff --git a/backends/networking/sdl_net/handlers/uploadfilehandler.cpp b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp index 22896a25f0..a0e992c25e 100644 --- a/backends/networking/sdl_net/handlers/uploadfilehandler.cpp +++ b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp @@ -44,6 +44,12 @@ void UploadFileHandler::handle(Client &client) { return; } + // check that <path> contains no '../' + if (HandlerUtils::hasForbiddenCombinations(path)) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + // transform virtual path to actual file system one Common::String prefixToRemove = "", prefixToAdd = ""; if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) { @@ -51,10 +57,12 @@ void UploadFileHandler::handle(Client &client) { return; } - // TODO: handle <path> - - // check that <path> exists and is directory + // check that <path> exists, is directory and isn't forbidden AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); + if (!HandlerUtils::permittedPath(node->getPath())) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } if (!node->exists()) { HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The parent directory doesn't exist!")); return; |