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@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com>feature/lok_dialog
parent
b599bb0a31
commit
783e3552c0
|
@ -69,7 +69,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 \
|
||||
|
@ -152,6 +153,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 \
|
||||
|
|
|
@ -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 {
|
||||
|
|
13
configure.ac
13
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],
|
||||
|
@ -295,10 +295,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}"
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ class Config: public Application
|
|||
|
||||
public:
|
||||
static std::string ConfigFile;
|
||||
static std::string SupportKeyString;
|
||||
static bool SupportKeyStringProvided;
|
||||
|
||||
protected:
|
||||
void defineOptions(OptionSet&) override;
|
||||
|
@ -71,29 +73,31 @@ protected:
|
|||
};
|
||||
|
||||
std::string Config::ConfigFile = LOOLWSD_CONFIGDIR "/loolwsd.xml";
|
||||
std::string Config::SupportKeyString = "";
|
||||
bool Config::SupportKeyStringProvided = false;
|
||||
|
||||
void Config::displayHelp()
|
||||
{
|
||||
HelpFormatter helpFormatter(options());
|
||||
helpFormatter.setCommand(commandName());
|
||||
helpFormatter.setHeader("Configuration tool for LibreOffice Online.");
|
||||
helpFormatter.setUsage("OPTIONS COMMAND");
|
||||
helpFormatter.format(std::cout);
|
||||
std::cout << std::endl
|
||||
<< "Commands:" << std::endl
|
||||
<< " set-admin-password" << std::endl
|
||||
|
||||
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);
|
||||
|
||||
// global options
|
||||
optionSet.addOption(Option("help", "", "Prints help information")
|
||||
optionSet.addOption(Option("help", "h", "Show this usage information.")
|
||||
.required(false)
|
||||
.repeatable(false));
|
||||
optionSet.addOption(Option("config-file", "", "Specify configuration file path manually.")
|
||||
|
@ -101,20 +105,23 @@ void Config::defineOptions(OptionSet& optionSet)
|
|||
.repeatable(false)
|
||||
.argument("path"));
|
||||
|
||||
// Command specific option
|
||||
optionSet.addOption(Option("pwd-salt-length", "", "Length of the salt to use to hash password. To be used with set-admin-password command.")
|
||||
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. To be used with set-admin-password command.")
|
||||
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. To be used with set-admin-password command.")
|
||||
optionSet.addOption(Option("pwd-hash-length", "", "Length of password hash to generate [set-admin-password].")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("number"));
|
||||
|
||||
optionSet.addOption(Option("support-key", "", "Specify the support key [set-support-key].")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("key"));
|
||||
}
|
||||
|
||||
void Config::handleOption(const std::string& optionName, const std::string& optionValue)
|
||||
|
@ -159,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)
|
||||
|
@ -192,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);
|
||||
|
@ -243,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())
|
||||
|
|
|
@ -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"
|
||||
|
@ -192,7 +193,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
|
||||
|
@ -560,6 +561,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;
|
||||
|
||||
|
@ -777,11 +780,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;
|
||||
|
||||
|
@ -1342,10 +1392,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;
|
||||
}
|
||||
|
@ -2118,9 +2167,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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
static std::vector<int> getKitPids();
|
||||
|
||||
|
|
Loading…
Reference in New Issue