[Libreoffice-commits] online.git: loolwsd/FileServer.hpp loolwsd/LOOLWSD.cpp loolwsd/LOOLWSD.hpp loolwsd/loolwsd.xml.in loolwsd/Makefile.am loolwsd/Storage.cpp loolwsd/Util.hpp
Marco Cecchetti
marco.cecchetti at collabora.com
Tue Jul 19 09:00:08 UTC 2016
loolwsd/FileServer.hpp | 2
loolwsd/LOOLWSD.cpp | 107 ++++++++++++++++++++++++++++++++++++++-----------
loolwsd/LOOLWSD.hpp | 42 ++++++++++++++++---
loolwsd/Makefile.am | 4 -
loolwsd/Storage.cpp | 45 ++++++++++----------
loolwsd/Util.hpp | 39 +++++++++++++++++
loolwsd/loolwsd.xml.in | 1
7 files changed, 184 insertions(+), 56 deletions(-)
New commits:
commit 6e616b745f663898810de39141bdc65535c92601
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date: Mon Jul 18 13:45:36 2016 +0200
loolwsd: SSL support can be enabled/disabled on server start
SSL support is enabled by default, it can be disabled by passing the
`--disable-ssl` switch on the command line or by setting `ssl.enable`
property in loolwsd.xml config file.
It is still possible to build loolwsd with no SSL support at all.
Change-Id: I00f952edc64f87f61505af44fdc2a715780dc44c
Reviewed-on: https://gerrit.libreoffice.org/27288
Reviewed-by: Jan Holesovsky <kendy at collabora.com>
Tested-by: Jan Holesovsky <kendy at collabora.com>
diff --git a/loolwsd/FileServer.hpp b/loolwsd/FileServer.hpp
index 7c19e10..874db99 100644
--- a/loolwsd/FileServer.hpp
+++ b/loolwsd/FileServer.hpp
@@ -217,7 +217,7 @@ private:
{
HTMLForm form(request, request.stream());
- const auto host = (LOOLWSD::SSLEnabled ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName);
+ const auto host = (LOOLWSD::isSSLEnabled() ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName);
const auto path = Poco::Path(LOOLWSD::FileServerRoot, getRequestPathname(request));
Log::debug("Preprocessing file: " + path.toString());
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 97851ab..ff36b76 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -10,6 +10,16 @@
#include "LOOLWSD.hpp"
#include "config.h"
+/* Default host used in the start test URI */
+#define LOOLWSD_TEST_HOST "localhost"
+
+/* Default loleaflet UI used in the start test URI */
+#define LOOLWSD_TEST_LOLEAFLET_UI "/loleaflet/" LOOLWSD_VERSION_HASH "/loleaflet.html"
+
+/* Default document used in the start test URI */
+#define LOOLWSD_TEST_DOCUMENT_RELATIVE_PATH "test/data/hello-world.odt"
+
+
// This is the main source for the loolwsd program. LOOL uses several loolwsd processes: one main
// parent process that listens on the TCP port and accepts connections from LOOL clients, and a
// number of child processes, each which handles a viewing (editing) session for one document.
@@ -787,7 +797,7 @@ private:
const std::string urlsrc = "urlsrc";
const auto& config = Application::instance().config();
const std::string loleafletHtml = config.getString("loleaflet_html", "loleaflet.html");
- const std::string uriValue = (LOOLWSD::SSLEnabled ? "https://" : "http://") +
+ const std::string uriValue = (LOOLWSD::isSSLEnabled() ? "https://" : "http://") +
(LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName) +
"/loleaflet/" LOOLWSD_VERSION_HASH "/" + loleafletHtml + "?";
@@ -1207,6 +1217,35 @@ public:
}
};
+namespace {
+
+static inline
+ServerSocket* lcl_getServerSocket(int nClientPortNumber)
+{
+ return (LOOLWSD::isSSLEnabled()) ? new SecureServerSocket(nClientPortNumber)
+ : new ServerSocket(nClientPortNumber);
+}
+
+static inline
+std::string lcl_getLaunchURI()
+{
+ std::string aAbsTopSrcDir = Poco::Path(Application::instance().commandPath()).parent().toString();
+ aAbsTopSrcDir = Poco::Path(aAbsTopSrcDir).absolute().toString();
+
+ std::string aLaunchURI(" ");
+ aLaunchURI += ((LOOLWSD::isSSLEnabled()) ? "https://" : "http://");
+ aLaunchURI += LOOLWSD_TEST_HOST ":";
+ aLaunchURI += std::to_string(ClientPortNumber);
+ aLaunchURI += LOOLWSD_TEST_LOLEAFLET_UI;
+ aLaunchURI += "?file_path=file://";
+ aLaunchURI += aAbsTopSrcDir;
+ aLaunchURI += LOOLWSD_TEST_DOCUMENT_RELATIVE_PATH;
+
+ return aLaunchURI;
+}
+
+} // anonymous namespace
+
std::atomic<unsigned> LOOLWSD::NextSessionId;
int LOOLWSD::ForKitWritePipe = -1;
std::string LOOLWSD::Cache = LOOLWSD_CACHEDIR;
@@ -1216,12 +1255,8 @@ std::string LOOLWSD::ChildRoot;
std::string LOOLWSD::ServerName;
std::string LOOLWSD::FileServerRoot;
std::string LOOLWSD::LOKitVersion;
-bool LOOLWSD::SSLEnabled =
-#if ENABLE_SSL
- true;
-#else
- false;
-#endif
+Util::RuntimeCostant<bool> LOOLWSD::SSLEnabled;
+
static std::string UnitTestLibrary;
unsigned int LOOLWSD::NumPreSpawnedChildren = 0;
@@ -1279,6 +1314,7 @@ void LOOLWSD::initialize(Application& self)
{ "loleaflet_html", "loleaflet.html" },
{ "logging.color", "true" },
{ "logging.level", "trace" },
+ { "ssl.enable", "true" },
{ "ssl.cert_file_path", LOOLWSD_CONFIGDIR "/cert.pem" },
{ "ssl.key_file_path", LOOLWSD_CONFIGDIR "/key.pem" },
{ "ssl.ca_file_path", LOOLWSD_CONFIGDIR "/ca-chain.cert.pem" },
@@ -1309,20 +1345,38 @@ void LOOLWSD::initialize(Application& self)
// Allow UT to manipulate before using configuration values.
UnitWSD::get().configure(config());
+#if ENABLE_SSL
+ LOOLWSD::SSLEnabled.set(getConfigValue<bool>(conf, "ssl.enable", true));
+#else
+ LOOLWSD::SSLEnabled.set(false);
+#endif
+
+ if (LOOLWSD::isSSLEnabled())
+ {
+ Log::info("SSL support: SSL is enabled.");
+ }
+ else
+ {
+ Log::warn("SSL support: SSL is disabled.");
+ }
+
Cache = getPathFromConfig("tile_cache_path");
SysTemplate = getPathFromConfig("sys_template_path");
LoTemplate = getPathFromConfig("lo_template_path");
ChildRoot = getPathFromConfig("child_root_path");
ServerName = config().getString("server_name");
FileServerRoot = getPathFromConfig("file_server_root_path");
- NumPreSpawnedChildren = getUIntConfigValue(conf, "num_prespawn_children", 1);
+ NumPreSpawnedChildren = getConfigValue<unsigned int>(conf, "num_prespawn_children", 1);
- const auto maxConcurrency = getUIntConfigValue(conf, "per_document.max_concurrency", 4);
+ const auto maxConcurrency = getConfigValue<unsigned int>(conf, "per_document.max_concurrency", 4);
if (maxConcurrency > 0)
{
setenv("MAX_CONCURRENCY", std::to_string(maxConcurrency).c_str(), 1);
}
+ Log::warn("Launch this in your browser:");
+ Log::warn(lcl_getLaunchURI());
+
// In Trial Versions we might want to set some limits.
LOOLWSD::NumDocBrokers = 0;
LOOLWSD::NumConnections = 0;
@@ -1339,9 +1393,13 @@ void LOOLWSD::initialize(Application& self)
ServerApplication::initialize(self);
}
-#if ENABLE_SSL
void LOOLWSD::initializeSSL()
{
+ if (!LOOLWSD::isSSLEnabled())
+ {
+ return;
+ }
+
const auto ssl_cert_file_path = getPathFromConfig("ssl.cert_file_path");
Log::info("SSL Cert file: " + ssl_cert_file_path);
@@ -1378,7 +1436,6 @@ void LOOLWSD::initializeSSL()
Poco::Net::Context::Ptr sslClientContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, sslClientParams);
Poco::Net::SSLManager::instance().initializeClient(consoleClientHandler, invalidClientCertHandler, sslClientContext);
}
-#endif
void LOOLWSD::uninitialize()
{
@@ -1403,6 +1460,10 @@ void LOOLWSD::defineOptions(OptionSet& optionSet)
.repeatable(false)
.argument("port number"));
+ optionSet.addOption(Option("disable-ssl", "", "Disable SSL security layer.")
+ .required(false)
+ .repeatable(false));
+
optionSet.addOption(Option("override", "o", "Override any setting by providing fullxmlpath=value.")
.required(false)
.repeatable(true)
@@ -1439,6 +1500,8 @@ void LOOLWSD::handleOption(const std::string& optionName,
DisplayVersion = true;
else if (optionName == "port")
ClientPortNumber = std::stoi(value);
+ else if (optionName == "disable-ssl")
+ _overrideSettings["ssl.enable"] = "false";
else if (optionName == "override")
{
std::string optName;
@@ -1513,9 +1576,7 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
std::cout << "loolwsd " << version << " - " << hash << std::endl;
}
-#if ENABLE_SSL
initializeSSL();
-#endif
char *locale = setlocale(LC_ALL, nullptr);
if (locale == nullptr || std::strcmp(locale, "C") == 0)
@@ -1585,13 +1646,11 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
params2->setMaxThreads(MAX_SESSIONS);
// Start a server listening on the port for clients
-#if ENABLE_SSL
- SecureServerSocket svs(ClientPortNumber);
-#else
- ServerSocket svs(ClientPortNumber);
-#endif
+
+ std::unique_ptr<ServerSocket> psvs(lcl_getServerSocket(ClientPortNumber));
+
ThreadPool threadPool(NumPreSpawnedChildren*6, MAX_SESSIONS * 2);
- HTTPServer srv(new ClientRequestHandlerFactory(fileServer), threadPool, svs, params1);
+ HTTPServer srv(new ClientRequestHandlerFactory(fileServer), threadPool, *psvs, params1);
Log::info("Starting master server listening on " + std::to_string(ClientPortNumber));
srv.start();
@@ -1757,10 +1816,12 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
Util::removeFile(path, true);
}
-#if ENABLE_SSL
- Poco::Net::uninitializeSSL();
- Poco::Crypto::uninitializeCrypto();
-#endif
+ if (LOOLWSD::isSSLEnabled())
+ {
+ Poco::Net::uninitializeSSL();
+ Poco::Crypto::uninitializeCrypto();
+ }
+
Log::info("Process [loolwsd] finished.");
diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp
index b750bda..3a0fda6 100644
--- a/loolwsd/LOOLWSD.hpp
+++ b/loolwsd/LOOLWSD.hpp
@@ -43,7 +43,6 @@ public:
static std::string ServerName;
static std::string FileServerRoot;
static std::string LOKitVersion;
- static bool SSLEnabled;
static std::atomic<unsigned> NumDocBrokers;
static std::atomic<unsigned> NumConnections;
@@ -53,6 +52,12 @@ public:
return Util::encodeId(++NextSessionId, 4);
}
+ static
+ bool isSSLEnabled()
+ {
+ return LOOLWSD::SSLEnabled.get();
+ }
+
protected:
void initialize(Poco::Util::Application& self) override;
void uninitialize() override;
@@ -61,16 +66,37 @@ protected:
int main(const std::vector<std::string>& args) override;
private:
+ static Util::RuntimeCostant<bool> SSLEnabled;
+
void initializeSSL();
void displayHelp();
Poco::Process::PID createForKit();
+
+ class ConfigValueGetter
+ {
+ Poco::Util::LayeredConfiguration& mconfig;
+ const std::string& mname;
+
+ public:
+ ConfigValueGetter(Poco::Util::LayeredConfiguration& config,
+ const std::string& name)
+ : mconfig(config)
+ , mname(name)
+ {}
+
+ void operator()(unsigned int& value) { value = mconfig.getUInt(mname); }
+ void operator()(bool& value) { value = mconfig.getBool(mname); }
+ };
+
+ template<typename T>
static
- bool getSafeUIntConfig(Poco::Util::LayeredConfiguration& config, const std::string& name, unsigned int& value)
+ bool getSafeConfig(Poco::Util::LayeredConfiguration& config,
+ const std::string& name, T& value)
{
try
{
- value = config.getUInt(name);
+ ConfigValueGetter(config, name)(value);
return true;
}
catch (Poco::SyntaxException)
@@ -80,12 +106,14 @@ private:
return false;
}
+ template<typename T>
static
- unsigned int getUIntConfigValue(Poco::Util::LayeredConfiguration& config, const std::string& name, const unsigned int def)
+ T getConfigValue(Poco::Util::LayeredConfiguration& config,
+ const std::string& name, const T def)
{
- unsigned int value = def;
- if (getSafeUIntConfig(config, name, value) ||
- getSafeUIntConfig(config, name + "[@default]", value))
+ T value = def;
+ if (getSafeConfig(config, name, value) ||
+ getSafeConfig(config, name + "[@default]", value))
{
return value;
}
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index 5546181..5e7186d 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -138,10 +138,8 @@ clean-local:
if test "z at SYSTEMPLATE_PATH@" != "z"; then rm -rf "@SYSTEMPLATE_PATH@"; fi
run: all @JAILS_PATH@ @SYSTEMPLATE_PATH@/system_stamp
- @echo "Launching loolwsd - launch this in your browser:"
+ @echo "Launching loolwsd"
@cp $(abs_top_srcdir)/test/data/hello.odt $(abs_top_srcdir)/test/data/hello-world.odt
- @PROTOCOL="http" ; if test "z at ENABLE_SSL@" != "z"; then PROTOCOL="https" ; fi ; \
- echo " $$PROTOCOL://localhost:9980/loleaflet/@LOOLWSD_VERSION_HASH@/loleaflet.html?file_path=file://$(abs_top_srcdir)/test/data/hello-world.odt"
@echo
./loolwsd --o:sys_template_path="@SYSTEMPLATE_PATH@" --o:lo_template_path="@LO_PATH@" \
--o:child_root_path="@JAILS_PATH@" --o:storage.filesystem[@allow]=true \
diff --git a/loolwsd/Storage.cpp b/loolwsd/Storage.cpp
index 372ea2f..0b8bfda 100644
--- a/loolwsd/Storage.cpp
+++ b/loolwsd/Storage.cpp
@@ -28,6 +28,7 @@
#include "Auth.hpp"
#include "Common.hpp"
#include "Exceptions.hpp"
+#include "LOOLWSD.hpp"
#include "Log.hpp"
#include "Unit.hpp"
#include "Util.hpp"
@@ -236,6 +237,17 @@ bool LocalStorage::saveLocalFileToStorage()
return true;
}
+namespace {
+
+static inline
+Poco::Net::HTTPClientSession* lcl_getHTTPClientSession(const Poco::URI& uri)
+{
+ return (LOOLWSD::isSSLEnabled()) ? new Poco::Net::HTTPSClientSession(uri.getHost(), uri.getPort(), Poco::Net::SSLManager::instance().defaultClientContext())
+ : new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort());
+}
+
+} // anonymous namespace
+
///////////////////
// WopiStorage Impl
///////////////////
@@ -243,17 +255,14 @@ StorageBase::FileInfo WopiStorage::getFileInfo(const Poco::URI& uri)
{
Log::debug("Getting info for wopi uri [" + uri.toString() + "].");
-#if ENABLE_SSL
- Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
-#else
- Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
-#endif
+ std::unique_ptr<Poco::Net::HTTPClientSession> psession(lcl_getHTTPClientSession(uri));
+
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
request.set("User-Agent", "LOOLWSD WOPI Agent");
- session.sendRequest(request);
+ psession->sendRequest(request);
Poco::Net::HTTPResponse response;
- std::istream& rs = session.receiveResponse(response);
+ std::istream& rs = psession->receiveResponse(response);
auto logger = Log::trace();
logger << "WOPI::CheckFileInfo header for URI [" << uri.toString() << "]:\n";
@@ -303,17 +312,14 @@ std::string WopiStorage::loadStorageFileToLocal()
const auto url = uriObject.getPath() + "/contents?" + uriObject.getQuery();
Log::debug("Wopi requesting: " + url);
-#if ENABLE_SSL
- Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
-#else
- Poco::Net::HTTPClientSession session(uriObject.getHost(), uriObject.getPort());
-#endif
+ std::unique_ptr<Poco::Net::HTTPClientSession> psession(lcl_getHTTPClientSession(uriObject));
+
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, url, Poco::Net::HTTPMessage::HTTP_1_1);
request.set("User-Agent", "LOOLWSD WOPI Agent");
- session.sendRequest(request);
+ psession->sendRequest(request);
Poco::Net::HTTPResponse response;
- std::istream& rs = session.receiveResponse(response);
+ std::istream& rs = psession->receiveResponse(response);
auto logger = Log::trace();
logger << "WOPI::GetFile header for URI [" << _uri << "]:\n";
@@ -348,22 +354,19 @@ bool WopiStorage::saveLocalFileToStorage()
const auto url = uriObject.getPath() + "/contents?" + uriObject.getQuery();
Log::debug("Wopi posting: " + url);
-#if ENABLE_SSL
- Poco::Net::HTTPSClientSession session(uriObject.getHost(), uriObject.getPort(), Poco::Net::SSLManager::instance().defaultClientContext());
-#else
- Poco::Net::HTTPClientSession session(uriObject.getHost(), uriObject.getPort());
-#endif
+ std::unique_ptr<Poco::Net::HTTPClientSession> psession(lcl_getHTTPClientSession(uriObject));
+
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, url, Poco::Net::HTTPMessage::HTTP_1_1);
request.set("X-WOPIOverride", "PUT");
request.setContentType("application/octet-stream");
request.setContentLength(size);
- std::ostream& os = session.sendRequest(request);
+ std::ostream& os = psession->sendRequest(request);
std::ifstream ifs(_jailedFilePath);
Poco::StreamCopier::copyStream(ifs, os);
Poco::Net::HTTPResponse response;
- std::istream& rs = session.receiveResponse(response);
+ std::istream& rs = psession->receiveResponse(response);
std::ostringstream oss;
Poco::StreamCopier::copyStream(rs, oss);
diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp
index 138d791..8b866a3 100644
--- a/loolwsd/Util.hpp
+++ b/loolwsd/Util.hpp
@@ -185,7 +185,44 @@ namespace Util
std::set<std::string> _denied;
};
-};
+ template<typename T>
+ class RuntimeCostant
+ {
+ T mValue;
+ bool mInitialized;
+
+ public:
+ RuntimeCostant()
+ : mValue()
+ , mInitialized(false)
+ {}
+
+ const T& get()
+ {
+ if(mInitialized)
+ {
+ return mValue;
+ }
+ else
+ {
+ throw std::runtime_error("RuntimeCostant instance read before being initialized.");
+ }
+ }
+
+ void set(const T& value)
+ {
+ if(mInitialized)
+ {
+ throw std::runtime_error("RuntimeCostant instance already initialized.");
+ }
+ else
+ {
+ mInitialized = true;
+ mValue = value;
+ }
+ }
+ };
+} // end namespace Util
#endif
diff --git a/loolwsd/loolwsd.xml.in b/loolwsd/loolwsd.xml.in
index b3251e4..6366dd6 100644
--- a/loolwsd/loolwsd.xml.in
+++ b/loolwsd/loolwsd.xml.in
@@ -26,6 +26,7 @@
</logging>
<ssl desc="SSL settings">
+ <enable type="bool" default="true">true</enable>
<cert_file_path desc="Path to the cert file" relative="false">/etc/loolwsd/cert.pem</cert_file_path>
<key_file_path desc="Path to the key file" relative="false">/etc/loolwsd/key.pem</key_file_path>
<ca_file_path desc="Path to the ca file" relative="false">/etc/loolwsd/ca-chain.cert.pem</ca_file_path>
More information about the Libreoffice-commits
mailing list