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....@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 <pran...@collabora.co.uk> Tested-by: pranavk <pran...@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) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits