[Libreoffice-commits] online.git: loolwsd.xml.in net/ServerSocket.hpp net/Socket.hpp wsd/LOOLWSD.cpp
YiiChang Yen
sadwind.yan at gmail.com
Mon Apr 30 16:50:25 UTC 2018
loolwsd.xml.in | 3 +++
net/ServerSocket.hpp | 15 ++++++++++++---
net/Socket.hpp | 6 ++++++
wsd/LOOLWSD.cpp | 38 ++++++++++++++++++++++++++++++++++++--
4 files changed, 57 insertions(+), 5 deletions(-)
New commits:
commit 910ae806efd69caa705c0f0426c26d72b9c16225
Author: YiiChang Yen <sadwind.yan at gmail.com>
Date: Wed Dec 13 13:31:29 2017 +0800
wsd: to filter clientAddress before POST action.
Change-Id: I293580f041bc46b36c57f63fe4a2c0131763b3c1
Reviewed-on: https://gerrit.libreoffice.org/50977
Reviewed-by: pranavk <pranavk at collabora.co.uk>
Tested-by: pranavk <pranavk at collabora.co.uk>
diff --git a/loolwsd.xml.in b/loolwsd.xml.in
index 456790005..7a2bb7d9d 100644
--- a/loolwsd.xml.in
+++ b/loolwsd.xml.in
@@ -64,6 +64,9 @@
<net desc="Network settings">
<proto type="string" default="all" desc="Protocol to use IPv4, IPv6 or all for both">all</proto>
+ <post_allow desc="Allow/deny client IP address for POST(REST)." allow="true">
+ <host desc="Regex pattern of ip address to allow.">192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
+ </post_allow>
</net>
<ssl desc="SSL settings">
diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp
index 7ae7e7141..abc018678 100644
--- a/net/ServerSocket.hpp
+++ b/net/ServerSocket.hpp
@@ -60,13 +60,22 @@ public:
std::shared_ptr<Socket> accept()
{
// Accept a connection (if any) and set it to non-blocking.
- // We don't care about the client's address, so ignored.
- const int rc = ::accept4(getFD(), nullptr, nullptr, SOCK_NONBLOCK);
+ // There still need the client's address to filter request from POST(call from REST) here.
+ struct sockaddr_in clientInfo;
+ socklen_t addrlen = sizeof(struct sockaddr_in);
+ const int rc = ::accept4(getFD(), (struct sockaddr *)&clientInfo, &addrlen, SOCK_NONBLOCK);
LOG_DBG("Accepted socket #" << rc << ", creating socket object.");
try
{
// Create a socket object using the factory.
- return rc != -1 ? _sockFactory->create(rc) : std::shared_ptr<Socket>(nullptr);
+ if (rc != -1)
+ {
+ std::string ip = inet_ntoa(clientInfo.sin_addr);
+ std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
+ _socket->_clientAddress = ip;
+ return _socket;
+ }
+ return std::shared_ptr<Socket>(nullptr);
}
catch (const std::exception& ex)
{
diff --git a/net/Socket.hpp b/net/Socket.hpp
index 7c8563358..d3d48128f 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -95,6 +95,7 @@ public:
static const int DefaultSendBufferSize = 16 * 1024;
static const int MaximumSendBufferSize = 128 * 1024;
static std::atomic<bool> InhibitThreadChecks;
+ std::string _clientAddress;
enum Type { IPv4, IPv6, All };
@@ -838,6 +839,11 @@ public:
recv = _bytesRecvd;
}
+ const std::string clientAddress()
+ {
+ return _clientAddress;
+ }
+
protected:
/// Called when a polling event is received.
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index d74e3465f..9d39ba2ce 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1877,8 +1877,42 @@ private:
if (!(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0) &&
reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
{
- // All post requests have url prefix 'lool'.
- handlePostRequest(request, message, disposition);
+ // allow/deny for POST
+ const auto& app = Poco::Util::Application::instance();
+ Util::RegexListMatcher hosts;
+ // Parse the host allow settings.
+ for (size_t i = 0; ; ++i)
+ {
+ const std::string path = "post_allow.host[" + std::to_string(i) + "]";
+ const auto host = app.config().getString(path, "");
+ if (!host.empty())
+ {
+ LOG_INF("Adding trusted POST_ALLOW host: [" << host << "].");
+ hosts.allow(host);
+ }
+ else if (!app.config().has(path))
+ {
+ break;
+ }
+ }
+ if (!hosts.match(socket->clientAddress()))
+ {
+ LOG_ERR("client address DENY: " << socket->clientAddress().c_str());
+
+ std::ostringstream oss;
+ oss << "HTTP/1.1 403\r\n"
+ << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
+ << "User-Agent: " << HTTP_AGENT_STRING << "\r\n"
+ << "Content-Length: 0\r\n"
+ << "\r\n";
+ socket->send(oss.str());
+ socket->shutdown();
+ }
+ else
+ {
+ // All post requests have url prefix 'lool'.
+ handlePostRequest(request, message, disposition);
+ }
}
else if (reqPathTokens.count() > 2 && reqPathTokens[0] == "lool" && reqPathTokens[2] == "ws" &&
request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0)
More information about the Libreoffice-commits
mailing list