[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - common/Crypto.cpp configure.ac Makefile.am tools/Config.cpp wsd/LOOLWSD.cpp wsd/LOOLWSD.hpp
Jan Holesovsky
kendy at collabora.com
Tue Oct 3 19:57:32 UTC 2017
Makefile.am | 4 ++-
common/Crypto.cpp | 16 +++++++++---
configure.ac | 13 ++++++---
tools/Config.cpp | 61 ++++++++++++++++++++++++++++++++++------------
wsd/LOOLWSD.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++---------
wsd/LOOLWSD.hpp | 2 +
6 files changed, 130 insertions(+), 37 deletions(-)
New commits:
commit d545ae8f46fb93273ac4089765600752c470c35f
Author: Jan Holesovsky <kendy at collabora.com>
Date: Tue Oct 3 21:48:28 2017 +0200
Support key logic in loolws + improvements in loolconfig.
To be able to set the support key directly from the command line, and to show
the option, etc.
Change-Id: Iac93bc47a6f4b9d5a5ad0ac8b06bda978e01b760
Reviewed-on: https://gerrit.libreoffice.org/43098
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
Tested-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/Makefile.am b/Makefile.am
index 311fefd0..ec73f8f9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -64,7 +64,8 @@ if ENABLE_SSL
shared_sources += net/Ssl.cpp
endif
-loolwsd_sources = wsd/Admin.cpp \
+loolwsd_sources = common/Crypto.cpp \
+ wsd/Admin.cpp \
wsd/AdminModel.cpp \
wsd/Auth.cpp \
wsd/DocumentBroker.cpp \
@@ -147,6 +148,7 @@ wsd_headers = wsd/Admin.hpp \
wsd/UserMessages.hpp
shared_headers = common/Common.hpp \
+ common/Crypto.hpp \
common/IoUtil.hpp \
common/FileUtil.hpp \
common/Log.hpp \
diff --git a/common/Crypto.cpp b/common/Crypto.cpp
index aa268ae3..a8e84c2d 100644
--- a/common/Crypto.cpp
+++ b/common/Crypto.cpp
@@ -54,7 +54,7 @@ struct SupportKeyImpl
_signature = key.substr(lastColon + 1,
key.length() - lastColon);
_data = key.substr(0, lastColon);
- std::cout << "signature '" << _signature << "' data '" << _data << "'\n";
+ LOG_INF("Support key signature '" << _signature << "' data '" << _data << "'");
_invalid = false;
}
@@ -83,15 +83,23 @@ bool SupportKey::verify()
}
std::ifstream pubStream;
+ std::string supportKeyFilename =
+#if ENABLE_DEBUG
+ SUPPORT_KEY_FILE
+#else
+ LOOLWSD_CONFIGDIR "/" SUPPORT_KEY_FILE
+#endif
+ ;
+
try {
- pubStream.open ("pubKey.pub", std::ifstream::in);
+ pubStream.open(supportKeyFilename, std::ifstream::in);
if (pubStream.fail())
{
- LOG_ERR("Failed to open support public key.");
+ LOG_ERR("Failed to open support public key '" << supportKeyFilename << "'.");
return false;
}
} catch (...) {
- LOG_ERR("Exception opening public key");
+ LOG_ERR("Exception opening public key '" << supportKeyFilename << "'.");
return false;
}
try {
diff --git a/configure.ac b/configure.ac
index ecd86ead..19348d73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -96,9 +96,9 @@ AC_ARG_ENABLE([ssl],
AS_HELP_STRING([--disable-ssl],
[Compile without SSL support]))
-AC_ARG_ENABLE([support-key],
- AS_HELP_STRING([--enable-support-key],
- [Implements signed key with expiration required for support. Almost certainly you don't want to enable this.]))
+AC_ARG_WITH([support-key],
+ AS_HELP_STRING([--with-support-key=<support-key-name.pub>],
+ [Implements signed key with expiration required for support. Almost certainly you don not want to use this.]))
AC_ARG_WITH([max-connections],
AS_HELP_STRING([--max-connections],
@@ -294,10 +294,13 @@ fi
AC_SUBST(ENABLE_SSL)
-AS_IF([test "$enable_support_key" == "yes"],
- [AC_DEFINE([ENABLE_SUPPORT_KEY],1,[Whether to enable support key])],
+SUPPORT_KEY_FILE=
+AS_IF([test "x$with_support_key" != "x"],
+ [AC_DEFINE([ENABLE_SUPPORT_KEY],1,[Whether to enable support key])
+ AC_DEFINE_UNQUOTED([SUPPORT_KEY_FILE],[["$with_support_key"]],[LibreOffice Online WebSocket server version])],
[AC_DEFINE([ENABLE_SUPPORT_KEY],0,[Whether to enable support key])])
AC_SUBST(ENABLE_SUPPORT_KEY)
+AC_SUBST(SUPPORT_KEY_FILE)
LIBS="$LIBS -lPocoNet${POCO_DEBUG_SUFFIX} -lPocoUtil${POCO_DEBUG_SUFFIX} -lPocoJSON${POCO_DEBUG_SUFFIX} -lPocoFoundation${POCO_DEBUG_SUFFIX} -lPocoXML${POCO_DEBUG_SUFFIX} -lPocoNetSSL${POCO_DEBUG_SUFFIX} -lPocoCrypto${POCO_DEBUG_SUFFIX}"
diff --git a/tools/Config.cpp b/tools/Config.cpp
index 468bea66..d6a9d666 100644
--- a/tools/Config.cpp
+++ b/tools/Config.cpp
@@ -18,6 +18,7 @@
#include <Poco/Exception.h>
#include <Poco/Util/Application.h>
+#include <Poco/Util/HelpFormatter.h>
#include <Poco/Util/Option.h>
#include <Poco/Util/OptionSet.h>
#include <Poco/Util/XMLConfiguration.h>
@@ -26,6 +27,7 @@
#include "Crypto.hpp"
using Poco::Util::Application;
+using Poco::Util::HelpFormatter;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::XMLConfiguration;
@@ -61,6 +63,8 @@ class Config: public Application
public:
static std::string ConfigFile;
+ static std::string SupportKeyString;
+ static bool SupportKeyStringProvided;
protected:
void defineOptions(OptionSet&) override;
@@ -69,41 +73,55 @@ protected:
};
std::string Config::ConfigFile = LOOLWSD_CONFIGDIR "/loolwsd.xml";
+std::string Config::SupportKeyString = "";
+bool Config::SupportKeyStringProvided = false;
void Config::displayHelp()
{
- std::cout << "loolconfig - Configuration tool for LibreOffice Online." << std::endl
- << "Commands:" << std::endl
- << " set-admin-password" << std::endl
+ HelpFormatter helpFormatter(options());
+ helpFormatter.setCommand(commandName());
+
+ std::string usage = "set-admin-password";
#if ENABLE_SUPPORT_KEY
- << " set-support-key" << std::endl
+ usage = "(set-admin-password|set-support-key)";
#endif
- ;
+
+ helpFormatter.setUsage(usage + " 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.");
+ helpFormatter.format(std::cout);
}
void Config::defineOptions(OptionSet& optionSet)
{
Application::defineOptions(optionSet);
- optionSet.addOption(Option("help", "", "Config helper tool to set loolwsd configuration")
+ optionSet.addOption(Option("help", "h", "Show this usage information.")
.required(false)
.repeatable(false));
- optionSet.addOption(Option("pwd-salt-length", "", "Length of the salt to use to hash password")
+ optionSet.addOption(Option("config-file", "", "Specify configuration file path manually.")
+ .required(false)
+ .repeatable(false)
+ .argument("path"));
+
+ optionSet.addOption(Option("pwd-salt-length", "", "Length of the salt to use to hash password [set-admin-password].")
.required(false)
.repeatable(false).
argument("number"));
- optionSet.addOption(Option("pwd-iterations", "", "Number of iterations to do in PKDBF2 password hashing")
+ optionSet.addOption(Option("pwd-iterations", "", "Number of iterations to do in PKDBF2 password hashing [set-admin-password].")
.required(false)
.repeatable(false)
.argument("number"));
- optionSet.addOption(Option("pwd-hash-length", "", "Length of password hash to generate")
+ optionSet.addOption(Option("pwd-hash-length", "", "Length of password hash to generate [set-admin-password].")
.required(false)
.repeatable(false)
.argument("number"));
- optionSet.addOption(Option("config-file", "", "Specify configuration file path manually.")
+
+ optionSet.addOption(Option("support-key", "", "Specify the support key [set-support-key].")
.required(false)
.repeatable(false)
- .argument("path"));
+ .argument("key"));
}
void Config::handleOption(const std::string& optionName, const std::string& optionValue)
@@ -148,6 +166,11 @@ void Config::handleOption(const std::string& optionName, const std::string& opti
}
_adminConfig.pwdHashLength = len;
}
+ else if (optionName == "support-key")
+ {
+ SupportKeyString = optionValue;
+ SupportKeyStringProvided = true;
+ }
}
int Config::main(const std::vector<std::string>& args)
@@ -181,10 +204,10 @@ int Config::main(const std::vector<std::string>& args)
tcsetattr(STDIN_FILENO, TCSANOW, &newTermios);
std::string adminPwd;
std::cout << "Enter admin password: ";
- std::cin >> adminPwd;
+ std::getline(std::cin, adminPwd);
std::string reAdminPwd;
std::cout << std::endl << "Confirm admin password: ";
- std::cin >> reAdminPwd;
+ std::getline(std::cin, reAdminPwd);
std::cout << std::endl;
// Set the termios to old state
tcsetattr(STDIN_FILENO, TCSANOW, &oldTermios);
@@ -232,9 +255,15 @@ int Config::main(const std::vector<std::string>& args)
else if (args[i] == "set-support-key")
{
std::string supportKeyString;
- std::cout << "Enter support key: ";
- std::cin >> supportKeyString;
- if (supportKeyString.length() > 0)
+ if (SupportKeyStringProvided)
+ supportKeyString = SupportKeyString;
+ else
+ {
+ std::cout << "Enter support key: ";
+ std::getline(std::cin, supportKeyString);
+ }
+
+ if (!supportKeyString.empty())
{
SupportKey key(supportKeyString);
if (!key.verify())
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index c9a44397..2c3c5486 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -89,6 +89,7 @@
#include "Auth.hpp"
#include "ClientSession.hpp"
#include "Common.hpp"
+#include "Crypto.hpp"
#include "DocumentBroker.hpp"
#include "Exceptions.hpp"
#include "FileServer.hpp"
@@ -188,7 +189,7 @@ namespace
inline void shutdownLimitReached(WebSocketHandler& ws)
{
- const std::string error = Poco::format(PAYLOAD_UNAVAILABLE_LIMIT_REACHED, MAX_DOCUMENTS, MAX_CONNECTIONS);
+ const std::string error = Poco::format(PAYLOAD_UNAVAILABLE_LIMIT_REACHED, LOOLWSD::MaxDocuments, LOOLWSD::MaxConnections);
LOG_INF("Sending client limit-reached message: " << error);
try
@@ -553,6 +554,8 @@ std::string LOOLWSD::ConfigFile = LOOLWSD_CONFIGDIR "/loolwsd.xml";
Util::RuntimeConstant<bool> LOOLWSD::SSLEnabled;
Util::RuntimeConstant<bool> LOOLWSD::SSLTermination;
std::set<std::string> LOOLWSD::EditFileExtensions;
+unsigned LOOLWSD::MaxConnections;
+unsigned LOOLWSD::MaxDocuments;
static std::string UnitTestLibrary;
@@ -770,11 +773,58 @@ void LOOLWSD::initialize(Application& self)
setenv("SAL_DISABLE_OPENCL", "true", 1);
// Log the connection and document limits.
- static_assert(MAX_CONNECTIONS >= 3, "MAX_CONNECTIONS must be at least 3");
- static_assert(MAX_DOCUMENTS > 0 && MAX_DOCUMENTS <= MAX_CONNECTIONS,
- "max_documents must be positive and no more than max_connections");
- LOG_INF("Maximum concurrent open Documents limit: " << MAX_DOCUMENTS);
- LOG_INF("Maximum concurrent client Connections limit: " << MAX_CONNECTIONS);
+ LOOLWSD::MaxConnections = MAX_CONNECTIONS;
+ LOOLWSD::MaxDocuments = MAX_DOCUMENTS;
+
+#if ENABLE_SUPPORT_KEY
+ const std::string supportKeyString = getConfigValue<std::string>(conf, "support_key", "");
+
+ if (supportKeyString.empty())
+ {
+ LOG_WRN("Support key not set, please use 'loolconfig set-support-key'.");
+ std::cerr << "Support key not set, please use 'loolconfig set-support-key'." << std::endl;
+ }
+ else
+ {
+ SupportKey key(supportKeyString);
+
+ if (!key.verify())
+ {
+ LOG_WRN("Invalid support key, please use 'loolconfig set-support-key'.");
+ std::cerr << "Invalid support key, please use 'loolconfig set-support-key'." << std::endl;
+ }
+ else
+ {
+ int validDays = key.validDaysRemaining();
+ if (validDays <= 0)
+ {
+ LOG_WRN("Your support key has expired, please ask for a new one, and use 'loolconfig set-support-key'.");
+ std::cerr << "Your support key has expired, please ask for a new one, and use 'loolconfig set-support-key'." << std::endl;
+ }
+ else
+ {
+ LOG_INF("Your support key is valid for " << validDays << " days");
+ LOOLWSD::MaxConnections = 1000;
+ LOOLWSD::MaxDocuments = 200;
+ }
+ }
+ }
+#endif
+
+ if (LOOLWSD::MaxConnections < 3)
+ {
+ LOG_ERR("MAX_CONNECTIONS must be at least 3");
+ LOOLWSD::MaxConnections = 3;
+ }
+
+ if (LOOLWSD::MaxDocuments > LOOLWSD::MaxConnections)
+ {
+ LOG_ERR("MAX_DOCUMENTS cannot be bigger than MAX_CONNECTIONS");
+ LOOLWSD::MaxDocuments = LOOLWSD::MaxConnections;
+ }
+
+ LOG_INF("Maximum concurrent open Documents limit: " << LOOLWSD::MaxDocuments);
+ LOG_INF("Maximum concurrent client Connections limit: " << LOOLWSD::MaxConnections);
LOOLWSD::NumConnections = 0;
@@ -1329,10 +1379,9 @@ static std::shared_ptr<DocumentBroker> findOrCreateDocBroker(WebSocketHandler& w
{
Util::assertIsLocked(DocBrokersMutex);
- static_assert(MAX_DOCUMENTS > 0, "MAX_DOCUMENTS must be positive");
- if (DocBrokers.size() + 1 > MAX_DOCUMENTS)
+ if (DocBrokers.size() + 1 > LOOLWSD::MaxDocuments)
{
- LOG_ERR("Maximum number of open documents of " << MAX_DOCUMENTS << " reached.");
+ LOG_ERR("Maximum number of open documents of " << LOOLWSD::MaxDocuments << " reached.");
shutdownLimitReached(ws);
return nullptr;
}
@@ -2103,9 +2152,9 @@ private:
// Response to clients beyond this point is done via WebSocket.
try
{
- if (LOOLWSD::NumConnections >= MAX_CONNECTIONS)
+ if (LOOLWSD::NumConnections >= LOOLWSD::MaxConnections)
{
- LOG_ERR("Limit on maximum number of connections of " << MAX_CONNECTIONS << " reached.");
+ LOG_ERR("Limit on maximum number of connections of " << LOOLWSD::MaxConnections << " reached.");
shutdownLimitReached(ws);
return;
}
diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp
index 86f8dbcb..88318c5e 100644
--- a/wsd/LOOLWSD.hpp
+++ b/wsd/LOOLWSD.hpp
@@ -56,6 +56,8 @@ public:
static bool TileCachePersistent;
static std::unique_ptr<TraceFileWriter> TraceDumper;
static std::set<std::string> EditFileExtensions;
+ static unsigned MaxConnections;
+ static unsigned MaxDocuments;
/// Flag to shutdown the server.
std::atomic<bool> ShutdownFlag;
More information about the Libreoffice-commits
mailing list