wsd: to filter clientAddress before POST action.
Change-Id: I293580f041bc46b36c57f63fe4a2c0131763b3c1 Reviewed-on: https://gerrit.libreoffice.org/50977 Reviewed-by: pranavk <pranavk@collabora.co.uk> Tested-by: pranavk <pranavk@collabora.co.uk>private/kendy/monitoring-rebased
parent
a9c053fba4
commit
910ae806ef
|
@ -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">
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue