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 <pran...@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.me...@collabora.com> Reviewed-by: pranavk <pran...@collabora.co.uk> Tested-by: pranavk <pran...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits