net/PeerCredentials: wrapper for struct ucred
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
#include "net/IPv6Address.hxx"
|
#include "net/IPv6Address.hxx"
|
||||||
#include "net/StaticSocketAddress.hxx"
|
#include "net/StaticSocketAddress.hxx"
|
||||||
#include "net/AllocatedSocketAddress.hxx"
|
#include "net/AllocatedSocketAddress.hxx"
|
||||||
|
#include "net/PeerCredentials.hxx"
|
||||||
#include "net/SocketUtil.hxx"
|
#include "net/SocketUtil.hxx"
|
||||||
#include "net/SocketError.hxx"
|
#include "net/SocketError.hxx"
|
||||||
#include "net/UniqueSocketDescriptor.hxx"
|
#include "net/UniqueSocketDescriptor.hxx"
|
||||||
@ -104,13 +105,6 @@ static constexpr Domain server_socket_domain("server_socket");
|
|||||||
static int
|
static int
|
||||||
get_remote_uid(SocketDescriptor s) noexcept
|
get_remote_uid(SocketDescriptor s) noexcept
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STRUCT_UCRED
|
|
||||||
const auto cred = s.GetPeerCredentials();
|
|
||||||
if (cred.pid < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return cred.uid;
|
|
||||||
#else
|
|
||||||
#ifdef HAVE_GETPEEREID
|
#ifdef HAVE_GETPEEREID
|
||||||
uid_t euid;
|
uid_t euid;
|
||||||
gid_t egid;
|
gid_t egid;
|
||||||
@ -118,9 +112,11 @@ get_remote_uid(SocketDescriptor s) noexcept
|
|||||||
if (getpeereid(s.Get(), &euid, &egid) == 0)
|
if (getpeereid(s.Get(), &euid, &egid) == 0)
|
||||||
return euid;
|
return euid;
|
||||||
#else
|
#else
|
||||||
(void)s;
|
const auto cred = s.GetPeerCredentials();
|
||||||
#endif
|
if (!cred.IsDefined())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
return cred.GetUid();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
src/net/PeerCredentials.hxx
Normal file
71
src/net/PeerCredentials.hxx
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Features.hxx" // for HAVE_STRUCT_UCRED
|
||||||
|
|
||||||
|
#include <type_traits> // for std::is_trivial_v
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
#include <sys/socket.h> // for struct ucred
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Portable wrapper for credentials of the process on the other side
|
||||||
|
* of a (local) socket.
|
||||||
|
*/
|
||||||
|
class SocketPeerCredentials {
|
||||||
|
friend class SocketDescriptor;
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
struct ucred cred;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr SocketPeerCredentials() noexcept = default;
|
||||||
|
|
||||||
|
static constexpr SocketPeerCredentials Undefined() noexcept {
|
||||||
|
SocketPeerCredentials c;
|
||||||
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
c.cred.pid = 0;
|
||||||
|
c.cred.uid = -1;
|
||||||
|
c.cred.gid = -1;
|
||||||
|
#endif
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsDefined() const noexcept {
|
||||||
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
return cred.pid > 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto GetPid() const noexcept {
|
||||||
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
return cred.pid;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto GetUid() const noexcept {
|
||||||
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
return cred.uid;
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto GetGid() const noexcept {
|
||||||
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
return cred.gid;
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(std::is_trivial_v<SocketPeerCredentials>);
|
@ -7,6 +7,7 @@
|
|||||||
#include "IPv4Address.hxx"
|
#include "IPv4Address.hxx"
|
||||||
#include "IPv6Address.hxx"
|
#include "IPv6Address.hxx"
|
||||||
#include "UniqueSocketDescriptor.hxx"
|
#include "UniqueSocketDescriptor.hxx"
|
||||||
|
#include "PeerCredentials.hxx"
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include "io/UniqueFileDescriptor.hxx"
|
#include "io/UniqueFileDescriptor.hxx"
|
||||||
@ -225,19 +226,19 @@ SocketDescriptor::GetIntOption(int level, int name, int fallback) const noexcept
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_UCRED
|
SocketPeerCredentials
|
||||||
|
|
||||||
struct ucred
|
|
||||||
SocketDescriptor::GetPeerCredentials() const noexcept
|
SocketDescriptor::GetPeerCredentials() const noexcept
|
||||||
{
|
{
|
||||||
struct ucred cred;
|
#ifdef HAVE_STRUCT_UCRED
|
||||||
|
SocketPeerCredentials cred;
|
||||||
if (GetOption(SOL_SOCKET, SO_PEERCRED,
|
if (GetOption(SOL_SOCKET, SO_PEERCRED,
|
||||||
&cred, sizeof(cred)) < sizeof(cred))
|
&cred.cred, sizeof(cred.cred)) < sizeof(cred.cred))
|
||||||
cred.pid = -1;
|
return SocketPeerCredentials::Undefined();
|
||||||
return cred;
|
return cred;
|
||||||
}
|
#else
|
||||||
|
return SocketPeerCredentials::Undefined();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Features.hxx"
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include "io/FileDescriptor.hxx"
|
#include "io/FileDescriptor.hxx"
|
||||||
#endif
|
#endif
|
||||||
@ -20,6 +18,7 @@
|
|||||||
|
|
||||||
struct msghdr;
|
struct msghdr;
|
||||||
struct iovec;
|
struct iovec;
|
||||||
|
class SocketPeerCredentials;
|
||||||
class SocketAddress;
|
class SocketAddress;
|
||||||
class StaticSocketAddress;
|
class StaticSocketAddress;
|
||||||
class IPv4Address;
|
class IPv4Address;
|
||||||
@ -221,14 +220,12 @@ public:
|
|||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
int GetIntOption(int level, int name, int fallback) const noexcept;
|
int GetIntOption(int level, int name, int fallback) const noexcept;
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_UCRED
|
|
||||||
/**
|
/**
|
||||||
* Receive peer credentials (SO_PEERCRED). On error, the pid
|
* Receive peer credentials (SO_PEERCRED). On error, an
|
||||||
* is -1.
|
* "undefined" object is returned.
|
||||||
*/
|
*/
|
||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
struct ucred GetPeerCredentials() const noexcept;
|
SocketPeerCredentials GetPeerCredentials() const noexcept;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user