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).
This commit is contained in:
Alexander Tkachev 2016-08-01 14:55:58 +06:00
parent dd9e5a95dc
commit acfa1d1f10
9 changed files with 132 additions and 19 deletions

View file

@ -22,6 +22,7 @@
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "backends/saves/default/default-saves.h"
#include "common/archive.h"
#include "common/config-manager.h"
#include "common/file.h"
@ -98,6 +99,75 @@ Common::String HandlerUtils::readEverythingFromStream(Common::SeekableReadStream
return result;
}
Common::String HandlerUtils::normalizePath(const Common::String &path) {
Common::String normalized;
bool slash = false;
for (uint32 i = 0; i < path.size(); ++i) {
char c = path[i];
if (c == '\\' || c == '/') {
slash = true;
continue;
}
if (slash) {
normalized += '/';
slash = false;
}
if ('A' <= c && c <= 'Z') {
normalized += c - 'A' + 'a';
} else {
normalized += c;
}
}
if (slash) normalized += '/';
return normalized;
}
bool HandlerUtils::hasForbiddenCombinations(const Common::String &path) {
return (path.contains("../") || path.contains("..\\"));
}
bool HandlerUtils::isBlacklisted(const Common::String &path) {
const char *blacklist[] = {
"/etc",
"/bin",
"c:/windows" // just saying: I know guys who install windows on another drives
};
// normalize path
Common::String normalized = normalizePath(path);
uint32 size = sizeof(blacklist) / sizeof(const char *);
for (uint32 i = 0; i < size; ++i)
if (normalized.hasPrefix(blacklist[i]))
return true;
return false;
}
bool HandlerUtils::hasPermittedPrefix(const Common::String &path) {
// normalize path
Common::String normalized = normalizePath(path);
// prefix for /root/
Common::String prefix;
if (ConfMan.hasKey("rootpath", "cloud")) {
prefix = normalizePath(ConfMan.get("rootpath", "cloud"));
if (prefix == "/" || normalized.hasPrefix(prefix))
return true;
}
// prefix for /saves/
DefaultSaveFileManager *manager = dynamic_cast<DefaultSaveFileManager *>(g_system->getSavefileManager());
prefix = (manager ? manager->concatWithSavesPath("") : ConfMan.get("savepath"));
return (normalized.hasPrefix(normalizePath(prefix)));
}
bool HandlerUtils::permittedPath(const Common::String path) {
return hasPermittedPrefix(path) && !isBlacklisted(path);
}
void HandlerUtils::setMessageHandler(Client &client, Common::String message, Common::String redirectTo) {
Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>";