[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - wsd/FileServer.cpp wsd/FileServer.hpp
Jan Holesovsky
kendy at collabora.com
Mon Apr 10 09:26:18 UTC 2017
wsd/FileServer.cpp | 63 ++++++++++++++++++++++++++++++-----------------------
wsd/FileServer.hpp | 8 ++----
2 files changed, 39 insertions(+), 32 deletions(-)
New commits:
commit d4e1736a350a450baef1a4f56b79d6f224f33fcf
Author: Jan Holesovsky <kendy at 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);
};
More information about the Libreoffice-commits
mailing list