[Libreoffice-commits] online.git: kit/Kit.cpp net/ServerSocket.hpp net/Socket.cpp net/Socket.hpp wsd/LOOLWSD.cpp
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Sat Mar 30 21:37:25 UTC 2019
kit/Kit.cpp | 8 ---
net/ServerSocket.hpp | 55 +----------------------
net/Socket.cpp | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++-
net/Socket.hpp | 3 +
wsd/LOOLWSD.cpp | 13 +----
5 files changed, 131 insertions(+), 69 deletions(-)
New commits:
commit 201bcb0762c838e75b61f030725c9bf0ba59c1c3
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sat Mar 30 21:07:58 2019 +0000
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Sat Mar 30 21:37:05 2019 +0000
Use peercreds to identify processes connecting rather than URL params.
Change-Id: I241e80962fb8cf2f3fff1bb4be81d9f0ee74c648
diff --git a/kit/Kit.cpp b/kit/Kit.cpp
index 819fb2698..ff4a3a7ed 100644
--- a/kit/Kit.cpp
+++ b/kit/Kit.cpp
@@ -2485,11 +2485,8 @@ void lokit_main(
LOG_INF("Process is ready.");
- static const std::string pid = std::to_string(Process::id());
std::string pathAndQuery(NEW_CHILD_URI);
- pathAndQuery.append("?pid=");
- pathAndQuery.append(pid);
- pathAndQuery.append("&jailid=");
+ pathAndQuery.append("?jailid=");
pathAndQuery.append(jailId);
if (queryVersion)
{
@@ -2522,7 +2519,6 @@ void lokit_main(
// Dummies
const std::string jailId = "jailid";
- const std::string pid = "101";
#endif // MOBILEAPP
@@ -2530,7 +2526,7 @@ void lokit_main(
mainKit.runOnClientThread(); // We will do the polling on this thread.
std::shared_ptr<SocketHandlerInterface> websocketHandler =
- std::make_shared<KitWebSocketHandler>("child_ws_" + pid, loKit, jailId, mainKit);
+ std::make_shared<KitWebSocketHandler>("child_ws", loKit, jailId, mainKit);
#if !MOBILEAPP
mainKit.insertNewUnixSocket(MasterLocation, pathAndQuery, websocketHandler);
#else
diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp
index 79a7795bc..dd07af4fe 100644
--- a/net/ServerSocket.hpp
+++ b/net/ServerSocket.hpp
@@ -61,58 +61,7 @@ public:
/// Accepts an incoming connection (Servers only).
/// Does not retry on error.
/// Returns a valid Socket shared_ptr on success only.
- std::shared_ptr<Socket> accept()
- {
- // Accept a connection (if any) and set it to non-blocking.
- // There still need the client's address to filter request from POST(call from REST) here.
-#if !MOBILEAPP
- struct sockaddr_in6 clientInfo;
- socklen_t addrlen = sizeof(clientInfo);
- const int rc = ::accept4(getFD(), (struct sockaddr *)&clientInfo, &addrlen, SOCK_NONBLOCK);
-#else
- const int rc = fakeSocketAccept4(getFD());
-#endif
- LOG_DBG("Accepted socket #" << rc << ", creating socket object.");
- try
- {
- // Create a socket object using the factory.
- if (rc != -1)
- {
-#if !MOBILEAPP
- char addrstr[INET6_ADDRSTRLEN];
-
- const void *inAddr;
- if (clientInfo.sin6_family == AF_INET)
- {
- auto ipv4 = (struct sockaddr_in *)&clientInfo;
- inAddr = &(ipv4->sin_addr);
- }
- else
- {
- auto ipv6 = (struct sockaddr_in6 *)&clientInfo;
- inAddr = &(ipv6->sin6_addr);
- }
-
- inet_ntop(clientInfo.sin6_family, inAddr, addrstr, sizeof(addrstr));
- std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
- _socket->setClientAddress(addrstr);
- LOG_DBG("Accepted socket has family " << clientInfo.sin6_family <<
- " address " << _socket->clientAddress());
-#else
- std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
- _socket->setClientAddress("dummy");
-#endif
- return _socket;
- }
- return std::shared_ptr<Socket>(nullptr);
- }
- catch (const std::exception& ex)
- {
- LOG_SYS("Failed to create client socket #" << rc << ". Error: " << ex.what());
- }
-
- return nullptr;
- }
+ virtual std::shared_ptr<Socket> accept();
int getPollEvents(std::chrono::steady_clock::time_point /* now */,
int & /* timeoutMaxMs */) override
@@ -143,6 +92,7 @@ public:
private:
Socket::Type _type;
SocketPoll& _clientPoller;
+protected:
std::shared_ptr<SocketFactory> _sockFactory;
};
@@ -155,6 +105,7 @@ public:
{
}
virtual bool bind(Type, int) { assert(false); return false; }
+ virtual std::shared_ptr<Socket> accept() override;
std::string bind();
private:
diff --git a/net/Socket.cpp b/net/Socket.cpp
index a1762352e..02fb7f972 100644
--- a/net/Socket.cpp
+++ b/net/Socket.cpp
@@ -16,6 +16,7 @@
#include <iomanip>
#include <stdio.h>
#include <unistd.h>
+#include <sys/types.h>
#include <zlib.h>
#include <Poco/DateTime.h>
@@ -398,7 +399,8 @@ void StreamSocket::dumpState(std::ostream& os)
int events = getPollEvents(std::chrono::steady_clock::now(), timeoutMaxMs);
os << "\t" << getFD() << "\t" << events << "\t"
<< _inBuffer.size() << "\t" << _outBuffer.size() << "\t"
- << " r: " << _bytesRecvd << "\t w: " << _bytesSent << "\t";
+ << " r: " << _bytesRecvd << "\t w: " << _bytesSent << "\t"
+ << clientAddress() << "\t";
_socketHandler->dumpState(os);
if (_inBuffer.size() > 0)
Util::dumpHex(os, "\t\tinBuffer:\n", "\t\t", _inBuffer);
@@ -483,6 +485,123 @@ bool ServerSocket::bind(Type type, int port)
#endif
}
+std::shared_ptr<Socket> ServerSocket::accept()
+{
+ // Accept a connection (if any) and set it to non-blocking.
+ // There still need the client's address to filter request from POST(call from REST) here.
+#if !MOBILEAPP
+ assert(_type != Socket::Type::Unix);
+
+ struct sockaddr_in6 clientInfo;
+ socklen_t addrlen = sizeof(clientInfo);
+ const int rc = ::accept4(getFD(), (struct sockaddr *)&clientInfo, &addrlen, SOCK_NONBLOCK);
+#else
+ const int rc = fakeSocketAccept4(getFD());
+#endif
+ LOG_DBG("Accepted socket #" << rc << ", creating socket object.");
+ try
+ {
+ // Create a socket object using the factory.
+ if (rc != -1)
+ {
+ std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
+
+#if !MOBILEAPP
+ char addrstr[INET6_ADDRSTRLEN];
+
+ const void *inAddr;
+ if (clientInfo.sin6_family == AF_INET)
+ {
+ auto ipv4 = (struct sockaddr_in *)&clientInfo;
+ inAddr = &(ipv4->sin_addr);
+ }
+ else
+ {
+ auto ipv6 = (struct sockaddr_in6 *)&clientInfo;
+ inAddr = &(ipv6->sin6_addr);
+ }
+
+ inet_ntop(clientInfo.sin6_family, inAddr, addrstr, sizeof(addrstr));
+ _socket->setClientAddress(addrstr);
+
+ LOG_DBG("Accepted socket has family " << clientInfo.sin6_family <<
+ " address " << _socket->clientAddress());
+#endif
+ return _socket;
+ }
+ return std::shared_ptr<Socket>(nullptr);
+ }
+ catch (const std::exception& ex)
+ {
+ LOG_SYS("Failed to create client socket #" << rc << ". Error: " << ex.what());
+ }
+
+ return nullptr;
+}
+
+int Socket::getPid() const
+{
+ struct ucred creds;
+ socklen_t credSize = sizeof(struct ucred);
+ if (getsockopt(_fd, SOL_SOCKET, SO_PEERCRED, &creds, &credSize) < 0)
+ {
+ LOG_TRC("Failed to get pid via peer creds on " << _fd << " " << strerror(errno));
+ return -1;
+ }
+ return creds.pid;
+}
+
+std::shared_ptr<Socket> LocalServerSocket::accept()
+{
+#if !MOBILEAPP
+ const int rc = ::accept4(getFD(), nullptr, nullptr, SOCK_NONBLOCK);
+#else
+ const int rc = fakeSocketAccept4(getFD());
+#endif
+ try
+ {
+ LOG_DBG("Accepted prisoner socket #" << rc << ", creating socket object.");
+ if (rc < 0)
+ return std::shared_ptr<Socket>(nullptr);
+
+ std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
+#if MOBILEAPP
+ // Sanity check this incoming socket
+ struct ucred creds;
+ socklen_t credSize = sizeof(struct ucred);
+ if (getsockopt(GetFD(), SOL_SOCKET, SO_PEERCRED, &creds, &credSize) < 0)
+ {
+ LOG_ERR("Failed to get peer creds on " << GetFD() << " " << strerror(errno));
+ ::close(rc);
+ return std::shared_ptr<Socket>(nullptr);
+ }
+
+ int uid = getuid();
+ int gid = getgid();
+ if (creds.uid != uid || cred.gid != gid)
+ {
+ LOG_ERR("Peercred mis-match on domain socket - closing connection. uid: " <<
+ creds.uid << "vs." << uid << " gid: " << creds.gid << "vs." << gid);
+ ::close(rc);
+ return std::shared_ptr<Socket>(nullptr);
+ }
+ std::string addr("uds-to-pid-");
+ addr.append(std::to_string(creds.pid));
+ _socket->setClientAddress(addr);
+
+ std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
+ LOG_DBG("Accepted socket is UDS - address " << addr <<
+ " and pid/gid " << creds.pid << "/" << creds.gid);
+#endif
+ return _socket;
+ }
+ catch (const std::exception& ex)
+ {
+ LOG_SYS("Failed to create client socket #" << rc << ". Error: " << ex.what());
+ return std::shared_ptr<Socket>(nullptr);
+ }
+}
+
/// Returns true on success only.
std::string LocalServerSocket::bind()
{
diff --git a/net/Socket.hpp b/net/Socket.hpp
index 10460fe4b..c2355b7b7 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -173,6 +173,9 @@ public:
}
#if !MOBILEAPP
+ /// Uses peercreds to get prisoner PID if present or -1
+ int getPid() const;
+
/// Sets the kernel socket send buffer in size bytes.
/// Note: TCP will allocate twice this size for admin purposes,
/// so a subsequent call to getSendBufferSize will return
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 0b3ccfe86..b4060d643 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1825,22 +1825,15 @@ private:
// New Child is spawned.
const Poco::URI::QueryParameters params = requestURI.getQueryParameters();
- Poco::Process::PID pid = -1;
+ int pid = socket->getPid();
std::string jailId;
for (const auto& param : params)
{
- if (param.first == "pid")
- {
- pid = std::stoi(param.second);
- }
- else if (param.first == "jailid")
- {
+ if (param.first == "jailid")
jailId = param.second;
- }
+
else if (param.first == "version")
- {
LOOLWSD::LOKitVersion = param.second;
- }
}
if (pid <= 0)
More information about the Libreoffice-commits
mailing list