[Libreoffice-commits] online.git: 5 commits - common/Crypto.cpp common/Seccomp.cpp configure.ac .gitignore loleaflet/src Makefile.am tools/Config.cpp wsd/DocumentBroker.cpp wsd/LOOLWSD.cpp wsd/LOOLWSD.hpp

Jan Holesovsky kendy at collabora.com
Fri Oct 6 13:43:42 UTC 2017


 .gitignore                               |    1 
 Makefile.am                              |    4 +
 common/Crypto.cpp                        |   17 +-----
 common/Seccomp.cpp                       |   13 ++++-
 configure.ac                             |   20 +++++---
 loleaflet/src/control/Control.Menubar.js |   20 +++-----
 tools/Config.cpp                         |   56 +++++++++++++++-------
 wsd/DocumentBroker.cpp                   |    5 ++
 wsd/LOOLWSD.cpp                          |   76 ++++++++++++++++++++++++++-----
 wsd/LOOLWSD.hpp                          |    3 +
 10 files changed, 153 insertions(+), 62 deletions(-)

New commits:
commit 262916363d6e86beb4e40f0e97d19b539c8f5fb6
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Fri Oct 6 15:42:53 2017 +0200

    rlimits: The fsize and nofile need more tweaking...
    
    Change-Id: Ifdb4d24f103f54fd286b8ffa715c0a61c2cff94f

diff --git a/common/Seccomp.cpp b/common/Seccomp.cpp
index ac57d071..42922b55 100644
--- a/common/Seccomp.cpp
+++ b/common/Seccomp.cpp
@@ -272,6 +272,10 @@ bool handleSetrlimitCommand(const std::vector<std::string>& tokens)
             if (lim <= 0)
                 lim = RLIM_INFINITY;
 
+            /* FIXME Currently the RLIMIT_FSIZE handling is non-ideal, and can
+             * lead to crashes of the kit processes due to not handling signal
+             * 25 gracefully.  Let's disable for now before there's a more
+             * concrete plan.
             rlimit rlim = { lim, lim };
             if (setrlimit(RLIMIT_FSIZE, &rlim) != 0)
                 LOG_SYS("Failed to set RLIMIT_FSIZE to " << lim << " bytes.");
@@ -280,6 +284,8 @@ bool handleSetrlimitCommand(const std::vector<std::string>& tokens)
                 LOG_INF("RLIMIT_FSIZE is " << rlim.rlim_max << " bytes after setting it to " << lim << " bytes.");
             else
                 LOG_SYS("Failed to get RLIMIT_FSIZE.");
+            */
+            LOG_SYS("Ignored setting RLIMIT_FSIZE to " << lim << " bytes.");
 
             return true;
         }
@@ -289,14 +295,19 @@ bool handleSetrlimitCommand(const std::vector<std::string>& tokens)
             if (lim <= 0)
                 lim = RLIM_INFINITY;
 
+            /* FIXME Currently the RLIMIT_ is non-ideal, and can lead to
+             * problems.  Let's disable for now before there's a more
+             * concrete plan.
             rlimit rlim = { lim, lim };
             if (setrlimit(RLIMIT_NOFILE, &rlim) != 0)
-                LOG_SYS("Failed to set RLIMIT_NOFILE to " << lim << " bytes.");
+                LOG_SYS("Failed to set RLIMIT_NOFILE to " << lim << " files.");
 
             if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
                 LOG_INF("RLIMIT_NOFILE is " << rlim.rlim_max << " files after setting it to " << lim << " files.");
             else
                 LOG_SYS("Failed to get RLIMIT_NOFILE.");
+            */
+            LOG_SYS("Ignored setting RLIMIT_NOFILE to " << lim << " files.");
 
             return true;
         }
commit dec231da0fba698d089b986712410236de5cc817
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Oct 4 06:36:29 2017 +0200

    Move the language menus one level up.
    
    Change-Id: I01f5d985ac3ebd9265200ecc161b861dc582ad69
    Reviewed-on: https://gerrit.libreoffice.org/43113
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 0abeea34..2132417e 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -173,15 +173,13 @@ L.Control.Menubar = L.Control.extend({
 					{name: _('Merge cells'), type: 'unocommand', uno: '.uno:MergeCells'}]
 			},
 			{name: _('Tools'), id: 'tools', type: 'menu', menu: [
-				{name: _('Automatic Spell Checking'), type: 'unocommand', uno: '.uno:SpellOnline'},
-				{name: _('Language'), type: 'menu', menu: [
-					{name: _('For Selection'), type: 'menu', menu: [
-						{name: _('Reset to Default Language'), id: 'resetselection', type: 'unocommand', uno: '.uno:LanguageStatus?Language:string=Current_RESET_LANGUAGES'}]},
-					{name: _('For Paragraph'), type: 'menu', menu: [
-						{name: _('Reset to Default Language'), id: 'resetparagraph', type: 'unocommand', uno: '.uno:LanguageStatus?Language:string=Paragraph_RESET_LANGUAGES'}]},
-					{name: _('For all Text'), type: 'menu', menu: [
-						{name: _('Reset to Default Language'), id: 'resetlanguage', type: 'unocommand', uno:'.uno:LanguageStatus?Language:string=Default_RESET_LANGUAGES'}]}
-				]}
+				{name: _('Automatic spell checking'), type: 'unocommand', uno: '.uno:SpellOnline'},
+				{name: _('Language for selection'), type: 'menu', menu: [
+					{name: _('Reset to Default Language'), id: 'resetselection', type: 'unocommand', uno: '.uno:LanguageStatus?Language:string=Current_RESET_LANGUAGES'}]},
+				{name: _('Language for paragraph'), type: 'menu', menu: [
+					{name: _('Reset to Default Language'), id: 'resetparagraph', type: 'unocommand', uno: '.uno:LanguageStatus?Language:string=Paragraph_RESET_LANGUAGES'}]},
+				{name: _('Language for entire document'), type: 'menu', menu: [
+					{name: _('Reset to Default Language'), id: 'resetlanguage', type: 'unocommand', uno:'.uno:LanguageStatus?Language:string=Default_RESET_LANGUAGES'}]}
 			]},
 			{name: _('Help'), id: 'help', type: 'menu', menu: [
 				{name: _('Keyboard shortcuts'), id: 'keyboard-shortcuts', type: 'action'},
@@ -246,7 +244,7 @@ L.Control.Menubar = L.Control.extend({
 				{name: _('Fullscreen presentation'), id: 'fullscreen-presentation', type: 'action'}]
 			},
 			{name: _('Tools'), id: 'tools', type: 'menu', menu: [
-				{name: _('Automatic Spell Checking'), type: 'unocommand', uno: '.uno:SpellOnline'}
+				{name: _('Automatic spell checking'), type: 'unocommand', uno: '.uno:SpellOnline'}
 			]},
 			{name: _('Help'), id: 'help', type: 'menu', menu: [
 				{name: _('Keyboard shortcuts'), id: 'keyboard-shortcuts', type: 'action'},
@@ -298,7 +296,7 @@ L.Control.Menubar = L.Control.extend({
 				{name: _('Delete column'), type: 'unocommand', uno: '.uno:DeleteColumns'}]
 			},
 			{name: _('Tools'), id: 'tools', type: 'menu', menu: [
-				{name: _('Automatic Spell Checking'), type: 'unocommand', uno: '.uno:SpellOnline'}
+				{name: _('Automatic spell checking'), type: 'unocommand', uno: '.uno:SpellOnline'}
 			]},
 			{name: _('Help'), id: 'help', type: 'menu', menu: [
 				{name: _('Keyboard shortcuts'), id: 'keyboard-shortcuts', type: 'action'},
commit 92aca7f2dd35249ff1f82bf4947932582e88b534
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Fri Oct 6 10:54:11 2017 +0200

    Compile the support key in (when configured to use one).
    
    Change-Id: Iffff0b95b245b91d9732a774a6026a3cec2b2222
    Reviewed-on: https://gerrit.libreoffice.org/43185
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/.gitignore b/.gitignore
index 35ce86c1..7ca272f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ missing
 stamp-h1
 m4
 debian/loolwsd.postinst
+common/support-public-key.hpp
 
 # Test stuff
 systemplate
diff --git a/common/Crypto.cpp b/common/Crypto.cpp
index a8e84c2d..2c125a2f 100644
--- a/common/Crypto.cpp
+++ b/common/Crypto.cpp
@@ -22,6 +22,7 @@
 
 #include "Log.hpp"
 #include "Crypto.hpp"
+#include "support-public-key.hpp"
 
 using namespace Poco;
 using namespace Poco::Crypto;
@@ -82,27 +83,9 @@ bool SupportKey::verify()
         return false;
     }
 
-    std::ifstream pubStream;
-    std::string supportKeyFilename =
-#if ENABLE_DEBUG
-        SUPPORT_KEY_FILE
-#else
-        LOOLWSD_CONFIGDIR "/" SUPPORT_KEY_FILE
-#endif
-        ;
+    std::istringstream pubStream(SUPPORT_PUBLIC_KEY);
 
     try {
-        pubStream.open(supportKeyFilename, std::ifstream::in);
-        if (pubStream.fail())
-        {
-            LOG_ERR("Failed to open support public key '" << supportKeyFilename << "'.");
-            return false;
-        }
-    } catch (...) {
-        LOG_ERR("Exception opening public key '" << supportKeyFilename << "'.");
-        return false;
-    }
-    try {
         RSAKey keyPub(&pubStream);
         RSADigestEngine rsaEngine(keyPub, RSADigestEngine::DigestType::DIGEST_SHA1);
         rsaEngine.update(_impl->_data);
diff --git a/configure.ac b/configure.ac
index 748b3d5e..8c405778 100644
--- a/configure.ac
+++ b/configure.ac
@@ -96,8 +96,8 @@ AC_ARG_ENABLE([ssl],
             AS_HELP_STRING([--disable-ssl],
                            [Compile without SSL support]))
 
-AC_ARG_WITH([support-key],
-            AS_HELP_STRING([--with-support-key=<support-key-name.pub>],
+AC_ARG_WITH([support-public-key],
+            AS_HELP_STRING([--with-support-public-key=<public-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],
@@ -295,13 +295,18 @@ fi
 
 AC_SUBST(ENABLE_SSL)
 
-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])])
+if test "x$with_support_public_key" != "x"; then
+    AC_DEFINE([ENABLE_SUPPORT_KEY],1,[Whether to enable support key])
+
+    # generate the public key include
+    echo -e "#ifndef INCLUDED_SUPPORT_PUBLIC_KEY_HPP\n#define INCLUDED_SUPPORT_PUBLIC_KEY_HPP\n#include <string>\nconst static std::string SUPPORT_PUBLIC_KEY(" > "${srcdir}/common/support-public-key.hpp"
+    sed 's/\(.*\)/"\1\\n"/' "$with_support_public_key" >> "${srcdir}/common/support-public-key.hpp"
+    echo -e ");\n#endif" >> "${srcdir}/common/support-public-key.hpp"
+else
+    AC_DEFINE([ENABLE_SUPPORT_KEY],0,[Whether to enable support key])
+    rm -f "${srcdir}/common/support-public-key.hpp"
+fi
 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}"
 
commit 557479e288e84093b9c7bf927328e21972649ae4
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Oct 4 05:54:05 2017 +0200

    More information about the support key state.
    
    Change-Id: I0fb7792df3c0ba97497b7d9f5281640c40eb49a4
    Reviewed-on: https://gerrit.libreoffice.org/43112
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 7a72393d..5025240b 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -508,6 +508,11 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
         }
     }
 
+#if ENABLE_SUPPORT_KEY
+    if (!LOOLWSD::OverrideWatermark.empty())
+        watermarkText = LOOLWSD::OverrideWatermark;
+#endif
+
     LOG_DBG("Setting username [" << username << "] and userId [" << userid << "] for session [" << sessionId << "]");
     session->setUserId(userid);
     session->setUserName(username);
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 85cd283c..f1e4c800 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -563,6 +563,7 @@ Util::RuntimeConstant<bool> LOOLWSD::SSLTermination;
 std::set<std::string> LOOLWSD::EditFileExtensions;
 unsigned LOOLWSD::MaxConnections;
 unsigned LOOLWSD::MaxDocuments;
+std::string LOOLWSD::OverrideWatermark;
 
 static std::string UnitTestLibrary;
 
@@ -790,6 +791,7 @@ void LOOLWSD::initialize(Application& self)
     {
         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;
+        LOOLWSD::OverrideWatermark = "Unsupported, the support key is missing.";
     }
     else
     {
@@ -799,6 +801,7 @@ void LOOLWSD::initialize(Application& self)
         {
             LOG_WRN("Invalid support key, please use 'loolconfig set-support-key'.");
             std::cerr << "Invalid support key, please use 'loolconfig set-support-key'." << std::endl;
+            LOOLWSD::OverrideWatermark = "Unsupported, the support key is invalid.";
         }
         else
         {
@@ -807,12 +810,14 @@ void LOOLWSD::initialize(Application& self)
             {
                 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;
+                LOOLWSD::OverrideWatermark = "Unsupported, the support key has expired.";
             }
             else
             {
                 LOG_INF("Your support key is valid for " << validDays << " days");
                 LOOLWSD::MaxConnections = 1000;
                 LOOLWSD::MaxDocuments = 200;
+                LOOLWSD::OverrideWatermark = "";
             }
         }
     }
diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp
index f3a838b9..c61956a1 100644
--- a/wsd/LOOLWSD.hpp
+++ b/wsd/LOOLWSD.hpp
@@ -58,6 +58,7 @@ public:
     static std::set<std::string> EditFileExtensions;
     static unsigned MaxConnections;
     static unsigned MaxDocuments;
+    static std::string OverrideWatermark;
 
     static std::vector<int> getKitPids();
 
commit 783e3552c092fd7bb74f1f39c6f89ddc097e15cc
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 0d2d4884..7f8d0ca0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 \
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 f5b8a4a0..748b3d5e 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],
@@ -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}"
 
diff --git a/tools/Config.cpp b/tools/Config.cpp
index 986940c7..6de6597f 100644
--- a/tools/Config.cpp
+++ b/tools/Config.cpp
@@ -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())
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index f6537efc..85cd283c 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"
@@ -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;
             }
diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp
index 4c7579f9..f3a838b9 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;
 
     static std::vector<int> getKitPids();
 


More information about the Libreoffice-commits mailing list