tools/Config.cpp | 234 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 136 insertions(+), 98 deletions(-)
New commits: commit f942e5a29ecb7aecdc0b085f8bafa7ac6a5d6f86 Author: Pranav Kant <pran...@collabora.co.uk> Date: Fri Jan 26 18:29:12 2018 +0530 loolconfig: Allow changing loolwsd.xml eg: `loolconfig set-raw-config admin_console.password admin` And while at it, stop processing all the arguments given to the command. Regard the first argument (without any "--") as command and let the specific-command handling routine handle the remaining arguments the way it wants. Change-Id: I6cc406c56701dba2b99e0a3c4a98c505df70ee60 diff --git a/tools/Config.cpp b/tools/Config.cpp index e12bbf4e..79f4398b 100644 --- a/tools/Config.cpp +++ b/tools/Config.cpp @@ -72,7 +72,14 @@ protected: int main(const std::vector<std::string>&) override; }; -std::string Config::ConfigFile = LOOLWSD_CONFIGDIR "/loolwsd.xml"; +std::string Config::ConfigFile = +#if ENABLE_DEBUG + DEBUG_ABSSRCDIR +#else + LOOLWSD_CONFIGDIR +#endif + "/loolwsd.xml"; + std::string Config::SupportKeyString; bool Config::SupportKeyStringProvided = false; @@ -80,17 +87,22 @@ void Config::displayHelp() { HelpFormatter helpFormatter(options()); helpFormatter.setCommand(commandName()); - - std::string usage = "set-admin-password"; -#if ENABLE_SUPPORT_KEY - usage = "(set-admin-password|set-support-key)"; -#endif - - helpFormatter.setUsage(usage + " OPTIONS"); + helpFormatter.setUsage("COMMAND [OPTIONS]"); helpFormatter.setHeader("loolconfig - Configuration tool for LibreOffice Online.\n" "\n" - "Some options make sense only with a concrete command, in that case the command name is specified in brackets."); + "Some options make sense only with a specific command.\n\n" + "Options:"); + helpFormatter.format(std::cout); + + // Command list + std::cout << std::endl + << "Commands: " << std::endl + << " set-admin-password\n" +#if ENABLE_SUPPORT_KEY + << " set-support-key\n" +#endif + << " set-raw-config <key> <value>" << std::endl; } void Config::defineOptions(OptionSet& optionSet) @@ -187,109 +199,135 @@ int Config::main(const std::vector<std::string>& args) bool changed = false; _loolConfig.load(ConfigFile); - for (unsigned long i = 0; i < args.size(); i++) + if (args[0] == "set-admin-password") { - if (args[i] == "set-admin-password") - { #if HAVE_PKCS5_PBKDF2_HMAC - unsigned char pwdhash[_adminConfig.pwdHashLength]; - unsigned char salt[_adminConfig.pwdSaltLength]; - RAND_bytes(salt, _adminConfig.pwdSaltLength); - std::stringstream stream; - - // Ask for user password - termios oldTermios; - tcgetattr(STDIN_FILENO, &oldTermios); - termios newTermios = oldTermios; - // Disable user input mirroring on console for password input - newTermios.c_lflag &= ~ECHO; - tcsetattr(STDIN_FILENO, TCSANOW, &newTermios); - std::string adminPwd; - std::cout << "Enter admin password: "; - std::getline(std::cin, adminPwd); - std::string reAdminPwd; - std::cout << std::endl << "Confirm admin password: "; - std::getline(std::cin, reAdminPwd); - std::cout << std::endl; - // Set the termios to old state - tcsetattr(STDIN_FILENO, TCSANOW, &oldTermios); - if (adminPwd != reAdminPwd) - { - std::cout << "Password mismatch." << std::endl; - return Application::EXIT_DATAERR; - } + unsigned char pwdhash[_adminConfig.pwdHashLength]; + unsigned char salt[_adminConfig.pwdSaltLength]; + RAND_bytes(salt, _adminConfig.pwdSaltLength); + std::stringstream stream; + + // Ask for user password + termios oldTermios; + tcgetattr(STDIN_FILENO, &oldTermios); + termios newTermios = oldTermios; + // Disable user input mirroring on console for password input + newTermios.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &newTermios); + std::string adminPwd; + std::cout << "Enter admin password: "; + std::getline(std::cin, adminPwd); + std::string reAdminPwd; + std::cout << std::endl << "Confirm admin password: "; + std::getline(std::cin, reAdminPwd); + std::cout << std::endl; + // Set the termios to old state + tcsetattr(STDIN_FILENO, TCSANOW, &oldTermios); + if (adminPwd != reAdminPwd) + { + std::cout << "Password mismatch." << std::endl; + return Application::EXIT_DATAERR; + } - // Do the magic ! - PKCS5_PBKDF2_HMAC(adminPwd.c_str(), -1, - salt, _adminConfig.pwdSaltLength, - _adminConfig.pwdIterations, - EVP_sha512(), - _adminConfig.pwdHashLength, pwdhash); - - // Make salt randomness readable - for (unsigned j = 0; j < _adminConfig.pwdSaltLength; ++j) - stream << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(salt[j]); - const std::string saltHash = stream.str(); - - // Clear our used hex stream to make space for password hash - stream.str(""); - stream.clear(); - - // Make the hashed password readable - for (unsigned j = 0; j < _adminConfig.pwdHashLength; ++j) - stream << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(pwdhash[j]); - const std::string passwordHash = stream.str(); - - std::stringstream pwdConfigValue("pbkdf2.sha512.", std::ios_base::in | std::ios_base::out | std::ios_base::ate); - pwdConfigValue << std::to_string(_adminConfig.pwdIterations) << "."; - pwdConfigValue << saltHash << "." << passwordHash; - _loolConfig.setString("admin_console.secure_password[@desc]", - "Salt and password hash combination generated using PBKDF2 with SHA512 digest."); - _loolConfig.setString("admin_console.secure_password", pwdConfigValue.str()); - - changed = true; + // Do the magic ! + PKCS5_PBKDF2_HMAC(adminPwd.c_str(), -1, + salt, _adminConfig.pwdSaltLength, + _adminConfig.pwdIterations, + EVP_sha512(), + _adminConfig.pwdHashLength, pwdhash); + + // Make salt randomness readable + for (unsigned j = 0; j < _adminConfig.pwdSaltLength; ++j) + stream << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(salt[j]); + const std::string saltHash = stream.str(); + + // Clear our used hex stream to make space for password hash + stream.str(""); + stream.clear(); + + // Make the hashed password readable + for (unsigned j = 0; j < _adminConfig.pwdHashLength; ++j) + stream << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(pwdhash[j]); + const std::string passwordHash = stream.str(); + + std::stringstream pwdConfigValue("pbkdf2.sha512.", std::ios_base::in | std::ios_base::out | std::ios_base::ate); + pwdConfigValue << std::to_string(_adminConfig.pwdIterations) << "."; + pwdConfigValue << saltHash << "." << passwordHash; + _loolConfig.setString("admin_console.secure_password[@desc]", + "Salt and password hash combination generated using PBKDF2 with SHA512 digest."); + _loolConfig.setString("admin_console.secure_password", pwdConfigValue.str()); + + changed = true; #else - std::cerr << "This application was compiled with old OpenSSL. Operation not supported. You can use plain text password in /etc/loolwsd/loolwsd.xml." << std::endl; - return Application::EXIT_UNAVAILABLE; + std::cerr << "This application was compiled with old OpenSSL. Operation not supported. You can use plain text password in /etc/loolwsd/loolwsd.xml." << std::endl; + return Application::EXIT_UNAVAILABLE; #endif - } + } #if ENABLE_SUPPORT_KEY - else if (args[i] == "set-support-key") + else if (args[0] == "set-support-key") + { + std::string supportKeyString; + if (SupportKeyStringProvided) + supportKeyString = SupportKeyString; + else { - std::string supportKeyString; - if (SupportKeyStringProvided) - supportKeyString = SupportKeyString; - else - { - std::cout << "Enter support key: "; - std::getline(std::cin, supportKeyString); - } + std::cout << "Enter support key: "; + std::getline(std::cin, supportKeyString); + } - if (!supportKeyString.empty()) - { - SupportKey key(supportKeyString); - if (!key.verify()) - std::cerr << "Invalid key\n"; - else { - int validDays = key.validDaysRemaining(); - if (validDays <= 0) - std::cerr << "Valid but expired key\n"; - else - { - std::cerr << "Valid for " << validDays << " days - setting to config\n"; - _loolConfig.setString("support_key", supportKeyString); - } + if (!supportKeyString.empty()) + { + SupportKey key(supportKeyString); + if (!key.verify()) + std::cerr << "Invalid key\n"; + else { + int validDays = key.validDaysRemaining(); + if (validDays <= 0) + std::cerr << "Valid but expired key\n"; + else + { + std::cerr << "Valid for " << validDays << " days - setting to config\n"; + _loolConfig.setString("support_key", supportKeyString); } } - else + } + else + { + std::cerr << "Removing empty support key\n"; + _loolConfig.remove("support_key"); + } + changed = true; + } +#endif + else if (args[0] == "set-raw-config") + { + if (args.size() == 3) + { + // args[1] = key + // args[2] = value + if (_loolConfig.has(args[1])) { - std::cerr << "Removing empty support key\n"; - _loolConfig.remove("support_key"); + const std::string val = _loolConfig.getString(args[1]); + std::cout << "Previous value found in config file: \"" << val << "\"" << std::endl; + std::cout << "Changing value to: \"" << args[2] << "\"" << std::endl; + _loolConfig.setString(args[1], args[2]); + changed = true; } - changed = true; + else + std::cerr << "No property, \"" << args[1] << "\"," << " found in config file." << std::endl; } -#endif + else + std::cerr << "set-raw-config expects a key and value as arguments" << std::endl + << "Eg: " << std::endl + << " set-raw-config logging.level trace" << std::endl; + } + else + { + std::cerr << "No such command, \"" << args[0] << "\"" << std::endl; + displayHelp(); + } + if (changed) { std::cout << "Saving configuration to : " << ConfigFile << " ..." << std::endl; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits