wsd/FileServer.cpp | 63 ++++++++++++++++++++++++++++++----------------------- wsd/FileServer.hpp | 8 ++---- 2 files changed, 39 insertions(+), 32 deletions(-)
New commits: commit d4e1736a350a450baef1a4f56b79d6f224f33fcf Author: Jan Holesovsky <ke...@collabora.com> Date: Mon Apr 10 11:24:04 2017 +0200 Revert "wsd: Fileserver cleanup" This breaks things as it changes the path where loleaflet.html is searched for from /usr/share/loolwsd/loleaflet/... to /usr/share/loleaflet/... This reverts commit de2bc17c04af088d9c7e18a97216b174494e1a9c. diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 70abae4a..29be66f6 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -44,8 +44,8 @@ using Poco::Net::HTTPBasicCredentials; using Poco::StreamCopier; using Poco::Util::Application; -bool FileServerRequestHandler::tryAdminLogin(const HTTPRequest& request, - HTTPResponse &response) +bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request, + HTTPResponse &response) { const auto& config = Application::instance().config(); const auto sslKeyPath = config.getString("ssl.key_file_path", ""); @@ -109,40 +109,53 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M { bool noCache = false; Poco::Net::HTTPResponse response; - const auto requestPathname = Poco::Path(getRequestPathname(request)); - const auto filePath = Poco::Path(LOOLWSD::FileServerRoot, requestPathname); - const auto file = Poco::File(filePath); - LOG_TRC("Fileserver request: " << requestPathname.toString() << ", " << - "Resolved file path: " << filePath.toString()); - - if (!file.exists() || - requestPathname[0] != "loleaflet" || - requestPathname[1] != "dist") + Poco::URI requestUri(request.getURI()); + LOG_TRC("Fileserver request: " << requestUri.toString()); + requestUri.normalize(); // avoid .'s and ..'s + + std::vector<std::string> requestSegments; + requestUri.getPathSegments(requestSegments); + if (requestSegments.size() < 1) { - throw Poco::FileNotFoundException("Invalid URI request: [" + filePath.toString() + "]."); + throw Poco::FileNotFoundException("Invalid URI request: [" + requestUri.toString() + "]."); } const auto& config = Application::instance().config(); const std::string loleafletHtml = config.getString("loleaflet_html", "loleaflet.html"); - if (filePath.getFileName() == loleafletHtml) + const std::string endPoint = requestSegments[requestSegments.size() - 1]; + if (endPoint == loleafletHtml) { - preprocessAndSendLoleafletHtml(request, message, socket); + preprocessFile(request, message, socket); return; } if (request.getMethod() == HTTPRequest::HTTP_GET) { - if (filePath.getFileName() == "admin.html" || - filePath.getFileName() == "adminSettings.html" || - filePath.getFileName() == "adminAnalytics.html") + if (endPoint == "admin.html" || + endPoint == "adminSettings.html" || + endPoint == "adminAnalytics.html") { noCache = true; - if (!FileServerRequestHandler::tryAdminLogin(request, response)) + if (!FileServerRequestHandler::isAdminLoggedIn(request, response)) throw Poco::Net::NotAuthenticatedException("Invalid admin login"); } - const std::string fileType = filePath.getExtension(); + const auto path = Poco::Path(LOOLWSD::FileServerRoot, getRequestPathname(request)); + const auto filepath = path.absolute().toString(); + if (filepath.find(LOOLWSD::FileServerRoot) != 0) + { + // Accessing unauthorized path. + throw Poco::FileAccessDeniedException("Invalid or forbidden file path: [" + filepath + "]."); + } + + const std::size_t extPoint = endPoint.find_last_of('.'); + if (extPoint == std::string::npos) + { + throw Poco::FileNotFoundException("Invalid file."); + } + + const std::string fileType = endPoint.substr(extPoint + 1); std::string mimeType; if (fileType == "js") mimeType = "application/javascript"; @@ -182,7 +195,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M response.setContentType(mimeType); bool deflate = request.hasToken("Accept-Encoding", "deflate"); - HttpHelper::sendFile(socket, filePath.toString(), response, noCache, deflate); + HttpHelper::sendFile(socket, filepath, response, noCache, deflate); } } catch (const Poco::Net::NotAuthenticatedException& exc) @@ -235,17 +248,13 @@ std::string FileServerRequestHandler::getRequestPathname(const HTTPRequest& requ std::string path(requestUri.getPath()); - // Remove first foreslash as the root ends in one. - if (path[0] == '/') - path = path.substr(1); - - // Convert version back to a real file name. - Poco::replaceInPlace(path, std::string("loleaflet/" LOOLWSD_VERSION_HASH "/"), std::string("loleaflet/dist/")); + // Convert version back to a real file name. Remove first foreslash as the root ends in one. + Poco::replaceInPlace(path, std::string("/loleaflet/" LOOLWSD_VERSION_HASH "/"), std::string("loleaflet/dist/")); return path; } -void FileServerRequestHandler::preprocessAndSendLoleafletHtml(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket) +void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket) { const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName); const auto params = Poco::URI(request.getURI()).getQueryParameters(); diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp index 3ba6803f..b27526f3 100644 --- a/wsd/FileServer.hpp +++ b/wsd/FileServer.hpp @@ -20,13 +20,11 @@ class FileServerRequestHandler { static std::string getRequestPathname(const Poco::Net::HTTPRequest& request); - static void preprocessAndSendLoleafletHtml(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket); + static void preprocessFile(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket); public: - /// If valid cookies exists in request, log the admin in (returns true) - /// If no cookie exist check the credentials, set the cookie and log the admin in - /// In case no valid cookie exists or invalid or no credentials exist, return false - static bool tryAdminLogin(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response); + /// Evaluate if the cookie exists, and if not, ask for the credentials. + static bool isAdminLoggedIn(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response); static void handleRequest(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket); }; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits