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

Reply via email to