[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - common/Util.cpp common/Util.hpp tools/Config.cpp wsd/FileServer.cpp

Pranav Kant pranavk at collabora.co.uk
Fri May 26 10:29:32 UTC 2017


 common/Util.cpp    |   21 +++++++++++++++++++++
 common/Util.hpp    |    2 ++
 tools/Config.cpp   |    1 +
 wsd/FileServer.cpp |   46 ++++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 66 insertions(+), 4 deletions(-)

New commits:
commit 711ee96432e40fe6b1432672afa440c07a5a0090
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Thu May 25 01:07:20 2017 +0530

    admin-console: Check the password against hashed value in config
    
    The new password hash property is called secure_password in the config
    file. `loolconfig` tool should be used to set the password hash in
    appropriate format with desired salt length, password length, number of
    iterations in PBKDF2.
    
    To be backward compatible, plain-text password for admin-console in
    config file is still accepted in case secure_password property is
    missing from the config file.
    
    Change-Id: If229999dac62856e368555c0242c4aa6f8061fba
    (cherry picked from commit 7a4bc5b95a9722a23048a7cd076bd1c4a954a9e9)
    Reviewed-on: https://gerrit.libreoffice.org/38019
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Reviewed-by: pranavk <pranavk at collabora.co.uk>
    Tested-by: pranavk <pranavk at collabora.co.uk>

diff --git a/common/Util.cpp b/common/Util.cpp
index 612f971e..23a74c6f 100644
--- a/common/Util.cpp
+++ b/common/Util.cpp
@@ -111,6 +111,27 @@ namespace Util
         }
     }
 
+    bool dataFromHexString(const std::string& hexString, std::vector<unsigned char>& data)
+    {
+        if (hexString.length() % 2 != 0)
+        {
+            return false;
+        }
+
+        data.clear();
+        std::stringstream stream;
+        unsigned value;
+        for (unsigned offset = 0; offset < hexString.size(); offset += 2)
+        {
+            stream.clear();
+            stream << std::hex << hexString.substr(offset, 2);
+            stream >> value;
+            data.push_back(static_cast<unsigned char>(value));
+        }
+
+        return true;
+    }
+
     std::string encodeId(const unsigned number, const int padding)
     {
         std::ostringstream oss;
diff --git a/common/Util.hpp b/common/Util.hpp
index 63bffc97..22173634 100644
--- a/common/Util.hpp
+++ b/common/Util.hpp
@@ -42,6 +42,8 @@ namespace Util
         std::string getFilename(const size_t length);
     }
 
+    /// Hex to unsigned char
+    bool dataFromHexString(const std::string& hexString, std::vector<unsigned char>& data);
     /// Encode an integral ID into a string, with padding support.
     std::string encodeId(const unsigned number, const int padding = 5);
     /// Decode an integral ID from a string.
diff --git a/tools/Config.cpp b/tools/Config.cpp
index 60be997c..1692453d 100644
--- a/tools/Config.cpp
+++ b/tools/Config.cpp
@@ -216,6 +216,7 @@ int Config::main(const std::vector<std::string>& args)
 
             std::cout << "Saving configuration to : " << ConfigFile << " ..." << std::endl;
             _loolConfig.save(ConfigFile);
+            std::cout << "Saved" << std::endl;
         }
     }
 
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index db7a38e3..058f6816 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -9,9 +9,12 @@
 
 #include "config.h"
 
+#include <iomanip>
 #include <string>
 #include <vector>
 
+#include <openssl/evp.h>
+
 #include <Poco/DateTime.h>
 #include <Poco/DateTimeFormat.h>
 #include <Poco/DateTimeFormatter.h>
@@ -32,6 +35,7 @@
 #include "Auth.hpp"
 #include "Common.hpp"
 #include "FileServer.hpp"
+#include "Protocol.hpp"
 #include "LOOLWSD.hpp"
 #include "Log.hpp"
 
@@ -70,18 +74,52 @@ bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request,
         LOG_INF("No existing JWT cookie found");
     }
 
+    HTTPBasicCredentials credentials(request);
+    std::string userProvidedPwd = credentials.getPassword();
+
     // If no cookie found, or is invalid, let admin re-login
-    const auto user = config.getString("admin_console.username", "");
-    const auto pass = config.getString("admin_console.password", "");
+    const std::string user = config.getString("admin_console.username", "");
+    std::string pass = config.getString("admin_console.password", "");
+    if (config.has("admin_console.secure_password"))
+    {
+        pass = config.getString("admin_console.secure_password");
+        // Extract the salt from the config
+        std::vector<unsigned char> saltData;
+        std::vector<std::string> tokens = LOOLProtocol::tokenize(pass, '.');
+        if (tokens.size() != 5 ||
+            tokens[0] != "pbkdf2" ||
+            tokens[1] != "sha512" ||
+            !Util::dataFromHexString(tokens[3], saltData))
+        {
+            LOG_ERR("Incorrect format detected for secure_password in config file."
+                    << "Denying access until correctly set."
+                    << "Use loolconfig to configure admin password.");
+            return false;
+        }
+
+        unsigned char userProvidedPwdHash[tokens[4].size() / 2];
+        PKCS5_PBKDF2_HMAC(userProvidedPwd.c_str(), -1,
+                          saltData.data(), saltData.size(),
+                          std::stoi(tokens[2]),
+                          EVP_sha512(),
+                          sizeof userProvidedPwdHash, userProvidedPwdHash);
+
+        std::stringstream stream;
+        for (unsigned j = 0; j < sizeof userProvidedPwdHash; ++j)
+            stream << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(userProvidedPwdHash[j]);
+
+        userProvidedPwd = stream.str();
+        pass = tokens[4];
+    }
+
     if (user.empty() || pass.empty())
     {
         LOG_ERR("Admin Console credentials missing. Denying access until set.");
         return false;
     }
 
-    HTTPBasicCredentials credentials(request);
     if (credentials.getUsername() == user &&
-        credentials.getPassword() == pass)
+        userProvidedPwd == pass)
     {
         const std::string htmlMimeType = "text/html";
         // generate and set the cookie


More information about the Libreoffice-commits mailing list