[Libreoffice-commits] online.git: loolwsd.xml.in net/Socket.cpp net/Socket.hpp wsd/LOOLWSD.cpp wsd/LOOLWSD.hpp wsd/ProxyProtocol.cpp
Michael Meeks (via logerrit)
logerrit at kemper.freedesktop.org
Fri May 8 16:05:32 UTC 2020
loolwsd.xml.in | 1 +
net/Socket.cpp | 12 ++++++++++++
net/Socket.hpp | 3 +++
wsd/LOOLWSD.cpp | 13 +++++++++++++
wsd/LOOLWSD.hpp | 1 +
wsd/ProxyProtocol.cpp | 5 +++++
6 files changed, 35 insertions(+)
New commits:
commit 2cbf6d12a0d4e4b6c76d3e9419ce67cda67f6c6e
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Thu May 7 21:11:38 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Fri May 8 18:05:14 2020 +0200
Proxy: only accept request from localhost.
Also - add net.proxy_prefix setting to enable this.
Change-Id: I87f5aab2316c053ea1bc8cc177e4a54ba0455697
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93682
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/loolwsd.xml.in b/loolwsd.xml.in
index bbd37ec35..e66f3526d 100644
--- a/loolwsd.xml.in
+++ b/loolwsd.xml.in
@@ -77,6 +77,7 @@
<proto type="string" default="all" desc="Protocol to use IPv4, IPv6 or all for both">all</proto>
<listen type="string" default="any" desc="Listen address that loolwsd binds to. Can be 'any' or 'loopback'.">any</listen>
<service_root type="path" default="" desc="Prefix all the pages, websockets, etc. with this path."></service_root>
+ <proxy_prefix type="bool" default="false" desc="Enable a ProxyPrefix to be passed int through which to redirect requests"></proxy_prefix>
<post_allow desc="Allow/deny client IP address for POST(REST)." allow="true">
<host desc="The IPv4 private 192.168 block as plain IPv4 dotted decimal addresses.">192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
<host desc="Ditto, but as IPv4-mapped IPv6 addresses">::ffff:192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
diff --git a/net/Socket.cpp b/net/Socket.cpp
index 5e96ab2ac..568fcca5e 100644
--- a/net/Socket.cpp
+++ b/net/Socket.cpp
@@ -694,6 +694,18 @@ int Socket::getPid() const
return creds.pid;
}
+// Does this socket come from the localhost ?
+bool Socket::isLocal() const
+{
+ if (_clientAddress.size() < 1)
+ return false;
+ if (_clientAddress[0] == '/') // Unix socket
+ return true;
+ if (_clientAddress == "::1")
+ return true;
+ return _clientAddress.rfind("127.0.0.", 0);
+}
+
std::shared_ptr<Socket> LocalServerSocket::accept()
{
const int rc = ::accept4(getFD(), nullptr, nullptr, SOCK_NONBLOCK);
diff --git a/net/Socket.hpp b/net/Socket.hpp
index 37e289a63..c004a1748 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -274,6 +274,9 @@ public:
}
#endif
+ // Does this socket come from the localhost ?
+ bool isLocal() const;
+
virtual void dumpState(std::ostream&) {}
/// Set the thread-id we're bound to
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 18d8469ef..d024ee436 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -725,6 +725,7 @@ std::string LOOLWSD::ConfigDir = LOOLWSD_CONFIGDIR "/conf.d";
std::string LOOLWSD::LogLevel = "trace";
bool LOOLWSD::AnonymizeUserData = false;
bool LOOLWSD::CheckLoolUser = true;
+bool LOOLWSD::IsProxyPrefixEnabled = false;
#if ENABLE_SSL
Util::RuntimeConstant<bool> LOOLWSD::SSLEnabled;
Util::RuntimeConstant<bool> LOOLWSD::SSLTermination;
@@ -901,6 +902,7 @@ void LOOLWSD::initialize(Application& self)
{ "net.listen", "any" },
{ "net.proto", "all" },
{ "net.service_root", "" },
+ { "net.proxy_prefix", "false" },
{ "num_prespawn_children", "1" },
{ "per_document.always_save_on_exit", "false" },
{ "per_document.autosave_duration_secs", "300" },
@@ -1120,6 +1122,8 @@ void LOOLWSD::initialize(Application& self)
while (ServiceRoot.length() > 0 && ServiceRoot[ServiceRoot.length() - 1] == '/')
ServiceRoot.pop_back();
+ IsProxyPrefixEnabled = getConfigValue<bool>(conf, "net.proxy_prefix", false);
+
#if ENABLE_SSL
LOOLWSD::SSLEnabled.set(getConfigValue<bool>(conf, "ssl.enable", true));
#endif
@@ -2256,6 +2260,15 @@ private:
if (!Util::startsWith(request.getURI(), LOOLWSD::ServiceRoot))
throw BadRequestException("The request does not start with prefix: " + LOOLWSD::ServiceRoot);
+ // Config & security ...
+ if (request.has("ProxyPrefix"))
+ {
+ if (!LOOLWSD::IsProxyPrefixEnabled)
+ throw BadRequestException("ProxyPrefix present but net.proxy_prefix is not enabled");
+ else if (!socket->isLocal())
+ throw BadRequestException("ProxyPrefix request from non-local socket");
+ }
+
std::string requestURIString(request.getURI().substr(LOOLWSD::ServiceRoot.length()));
request.setURI(requestURIString);
diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp
index 3172f8bb7..f5cb6c69d 100644
--- a/wsd/LOOLWSD.hpp
+++ b/wsd/LOOLWSD.hpp
@@ -242,6 +242,7 @@ public:
static std::string LogLevel;
static bool AnonymizeUserData;
static bool CheckLoolUser;
+ static bool IsProxyPrefixEnabled;
static std::atomic<unsigned> NumConnections;
static std::unique_ptr<TraceFileWriter> TraceDumper;
#if !MOBILEAPP
diff --git a/wsd/ProxyProtocol.cpp b/wsd/ProxyProtocol.cpp
index 26ea53e39..7c03d65e8 100644
--- a/wsd/ProxyProtocol.cpp
+++ b/wsd/ProxyProtocol.cpp
@@ -31,6 +31,11 @@ void DocumentBroker::handleProxyRequest(
std::shared_ptr<ClientSession> clientSession;
if (sessionId == "fetchsession")
{
+ bool isLocal = socket->isLocal();
+ LOG_TRC("proxy: validate that socket is from localhost: " << isLocal);
+ if (!isLocal)
+ throw BadRequestException("invalid host - only connect from localhost");
+
LOG_TRC("proxy: Create session for " << _docKey);
clientSession = createNewClientSession(
std::make_shared<ProxyProtocolHandler>(),
More information about the Libreoffice-commits
mailing list