[Libreoffice-commits] online.git: loolwsd/Admin.cpp loolwsd/FileServer.hpp

Jan Holesovsky kendy at collabora.com
Wed Apr 6 18:17:57 UTC 2016


 loolwsd/Admin.cpp      |   33 ++------------
 loolwsd/FileServer.hpp |  114 +++++++++++++++++++++++++++++--------------------
 2 files changed, 74 insertions(+), 73 deletions(-)

New commits:
commit 204a9c742f921816a1a5b658a40d9f43390223ac
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Apr 6 20:14:03 2016 +0200

    loolwsd: Allow asking for credentials even during websocket setup.
    
    It may happen that admin.html is cached, which leads to the cookie not being
    set up, which then leads to endless amount of attempts to log in.

diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp
index 275434e..83d0312 100644
--- a/loolwsd/Admin.cpp
+++ b/loolwsd/Admin.cpp
@@ -30,6 +30,7 @@
 #include "Admin.hpp"
 #include "AdminModel.hpp"
 #include "Common.hpp"
+#include "FileServer.hpp"
 #include "TileCache.hpp"
 #include "Storage.hpp"
 #include "LOOLProtocol.hpp"
@@ -347,34 +348,10 @@ void AdminRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerRe
 
         if (request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0)
         {
-            if (request.find("Cookie") != request.end())
-            {
-                // FIXME: Handle other cookie params like '; httponly; secure'
-                const std::size_t pos = request["Cookie"].find_first_of("=");
-                if (pos == std::string::npos)
-                    throw Poco::Net::NotAuthenticatedException("Missing JWT");
-
-                const std::string jwtToken = request["Cookie"].substr(pos + 1);
-                Log::info("Verifying JWT token: " + jwtToken);
-                // TODO: Read key from configuration file
-                const std::string keyPath = "/etc/loolwsd/" + std::string(SSL_KEY_FILE);
-                JWTAuth authAgent(keyPath, "admin", "admin", "admin");
-                if (authAgent.verify(jwtToken))
-                {
-                    Log::trace("JWT token is valid");
-                    handleWSRequests(request, response, nSessionId);
-                }
-                else
-                {
-                    Log::info("Invalid JWT token");
-                    throw Poco::Net::NotAuthenticatedException("Invalid Token");
-                }
-            }
-            else
-            {
-                Log::info("Missing authentication cookie. Handshake declined.");
-                throw Poco::Net::NotAuthenticatedException("Missing token");
-            }
+            if (!FileServerRequestHandler::isAdminLoggedIn(request, response))
+                throw Poco::Net::NotAuthenticatedException("Invalid admin login");
+
+            handleWSRequests(request, response, nSessionId);
         }
     }
     catch(const Poco::Net::NotAuthenticatedException& exc)
diff --git a/loolwsd/FileServer.hpp b/loolwsd/FileServer.hpp
index c1c8dd7..52d4429 100644
--- a/loolwsd/FileServer.hpp
+++ b/loolwsd/FileServer.hpp
@@ -48,6 +48,55 @@ using Poco::Util::Application;
 class FileServerRequestHandler: public HTTPRequestHandler
 {
 public:
+    /// Evaluate if the cookie exists, and if not, ask for the credentials.
+    static bool isAdminLoggedIn(HTTPServerRequest& request, HTTPServerResponse& response)
+    {
+        if (request.find("Cookie") != request.end())
+        {
+            // FIXME: Handle other cookie params like '; httponly; secure'
+            const std::size_t pos = request["Cookie"].find_first_of("=");
+            if (pos == std::string::npos)
+                throw Poco::Net::NotAuthenticatedException("Missing JWT");
+
+            const std::string jwtToken = request["Cookie"].substr(pos + 1);
+            Log::info("Verifying JWT token: " + jwtToken);
+            // TODO: Read key from configuration file
+            const std::string keyPath = "/etc/loolwsd/" + std::string(SSL_KEY_FILE);
+            JWTAuth authAgent(keyPath, "admin", "admin", "admin");
+            if (authAgent.verify(jwtToken))
+            {
+                Log::trace("JWT token is valid");
+                return true;
+            }
+
+            Log::info("Invalid JWT token, let the administrator re-login");
+        }
+
+        HTTPBasicCredentials credentials(request);
+
+        // TODO: Read username and password from config file
+        if (credentials.getUsername() == "admin"
+                && credentials.getPassword() == "admin")
+        {
+            const std::string htmlMimeType = "text/html";
+            // generate and set the cookie
+            // TODO: Read key from configuration file
+            const std::string keyPath = "/etc/loolwsd/" + std::string(SSL_KEY_FILE);
+            JWTAuth authAgent(keyPath, "admin", "admin", "admin");
+            const std::string jwtToken = authAgent.getAccessToken();
+            Poco::Net::HTTPCookie cookie("jwt", jwtToken);
+            cookie.setPath("/adminws/");
+            cookie.setSecure(true);
+            cookie.setHttpOnly(true);
+            response.addCookie(cookie);
+
+            return true;
+        }
+
+        Log::info("Wrong admin credentials.");
+        return false;
+    }
+
     void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) override
     {
         try
@@ -62,57 +111,32 @@ public:
 
             if (request.getMethod() == HTTPRequest::HTTP_GET)
             {
-                // FIXME: Some nice way to ask for credentials for protected files
                 if (endPoint == "admin.html" ||
                     endPoint == "adminSettings.html" ||
                     endPoint == "adminAnalytics.html")
                 {
-                    HTTPBasicCredentials credentials(request);
-                    // TODO: Read username and password from config file
-                    if (credentials.getUsername() == "admin"
-                        && credentials.getPassword() == "admin")
-                    {
-                        const std::string htmlMimeType = "text/html";
-                        // generate and set the cookie
-                        // TODO: Read key from configuration file
-                        const std::string keyPath = "/etc/loolwsd/" + std::string(SSL_KEY_FILE);
-                        JWTAuth authAgent(keyPath, "admin", "admin", "admin");
-                        const std::string jwtToken = authAgent.getAccessToken();
-                        Poco::Net::HTTPCookie cookie("jwt", jwtToken);
-                        cookie.setPath("/adminws/");
-                        cookie.setSecure(true);
-                        cookie.setHttpOnly(true);
-                        response.addCookie(cookie);
-                        response.setContentType(htmlMimeType);
-                        response.sendFile(LOOLWSD::FileServerRoot + requestUri.getPath(), htmlMimeType);
-                    }
-                    else
-                    {
-                        Log::info("Wrong admin credentials.");
-                        throw Poco::Net::NotAuthenticatedException("Wrong credentials.");
-                    }
+                    if (!FileServerRequestHandler::isAdminLoggedIn(request, response))
+                        throw Poco::Net::NotAuthenticatedException("Invalid admin login");
                 }
+
+                const std::string filePath = requestUri.getPath();
+                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";
+                else if (fileType == "css")
+                    mimeType = "text/css";
+                else if (fileType == "html")
+                    mimeType = "text/html";
                 else
-                {
-                    const std::string filePath = requestUri.getPath();
-                    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";
-                    else if (fileType == "css")
-                        mimeType = "text/css";
-                    else if (fileType == "html")
-                        mimeType = "text/html";
-                    else
-                        mimeType = "text/plain";
-
-                    response.setContentType(mimeType);
-                    response.sendFile(LOOLWSD::FileServerRoot + requestUri.getPath(), mimeType);
-                }
+                    mimeType = "text/plain";
+
+                response.setContentType(mimeType);
+                response.sendFile(LOOLWSD::FileServerRoot + requestUri.getPath(), mimeType);
             }
         }
         catch (Poco::Net::NotAuthenticatedException& exc)


More information about the Libreoffice-commits mailing list