summaryrefslogtreecommitdiff
path: root/src/sys/socket
diff options
context:
space:
mode:
authorAlan Somers <asomers@gmail.com>2021-08-06 20:15:24 -0600
committerAlan Somers <asomers@gmail.com>2021-08-10 17:57:32 -0600
commit0d3bc089d53a126716b4ed8f6b629c5b8c76964a (patch)
tree9ec5a162143216cd7daa3dc1fe6c8d61a9bbcba6 /src/sys/socket
parentba42d04aa8d3e23ba7aaa5cd4675e906a3d8bdfb (diff)
downloadnix-0d3bc089d53a126716b4ed8f6b629c5b8c76964a.zip
Add support for LOCAL_PEER_CRED
On FreeBSD and its derivatives, this socket option gets the credentials of the connected peer.
Diffstat (limited to 'src/sys/socket')
-rw-r--r--src/sys/socket/mod.rs32
-rw-r--r--src/sys/socket/sockopt.rs48
2 files changed, 60 insertions, 20 deletions
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 0f54ef0c..733bd660 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -358,6 +358,38 @@ cfg_if! {
}
}
+cfg_if!{
+ if #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "macos",
+ target_os = "ios"
+ ))] {
+ /// Return type of [`LocalPeerCred`](crate::sys::socket::sockopt::LocalPeerCred)
+ #[repr(transparent)]
+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+ pub struct XuCred(libc::xucred);
+
+ impl XuCred {
+ /// Structure layout version
+ pub fn version(&self) -> u32 {
+ self.0.cr_version
+ }
+
+ /// Effective user ID
+ pub fn uid(&self) -> libc::uid_t {
+ self.0.cr_uid
+ }
+
+ /// Returns a list of group identifiers (the first one being the
+ /// effective GID)
+ pub fn groups(&self) -> &[libc::gid_t] {
+ &self.0.cr_groups
+ }
+ }
+ }
+}
+
/// Request for multicast socket operations
///
/// This is a wrapper type around `ip_mreq`.
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 69fe479a..82df7f87 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -30,7 +30,7 @@ const TCP_CA_NAME_MAX: usize = 16;
/// # Arguments
///
/// * `$name:ident`: name of the type you want to implement `SetSockOpt` for.
-/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets*
+/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets*
/// (`libc::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
/// and more. Please refer to your system manual for more options. Will be passed as the second
/// argument (`level`) to the `setsockopt` call.
@@ -41,7 +41,7 @@ const TCP_CA_NAME_MAX: usize = 16;
/// * Type that implements the `Set` trait for the type from the previous item (like `SetBool` for
/// `bool`, `SetUsize` for `usize`, etc.).
macro_rules! setsockopt_impl {
- ($name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => {
+ ($name:ident, $level:expr, $flag:path, $ty:ty, $setter:ty) => {
impl SetSockOpt for $name {
type Val = $ty;
@@ -82,7 +82,7 @@ macro_rules! setsockopt_impl {
/// * Type that implements the `Get` trait for the type from the previous item (`GetBool` for
/// `bool`, `GetUsize` for `usize`, etc.).
macro_rules! getsockopt_impl {
- ($name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => {
+ ($name:ident, $level:expr, $flag:path, $ty:ty, $getter:ty) => {
impl GetSockOpt for $name {
type Val = $ty;
@@ -117,7 +117,7 @@ macro_rules! getsockopt_impl {
/// * `GetOnly`, `SetOnly` or `Both`: whether you want to implement only getter, only setter or
/// both of them.
/// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for.
-/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets*
+/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets*
/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
/// and more. Please refer to your system manual for more options. Will be passed as the second
/// argument (`level`) to the `getsockopt`/`setsockopt` call.
@@ -128,43 +128,43 @@ macro_rules! getsockopt_impl {
/// * `$getter:ty`: `Get` implementation; optional; only for `GetOnly` and `Both`.
/// * `$setter:ty`: `Set` implementation; optional; only for `SetOnly` and `Both`.
macro_rules! sockopt_impl {
- (GetOnly, $name:ident, $level:path, $flag:path, bool) => {
+ (GetOnly, $name:ident, $level:expr, $flag:path, bool) => {
sockopt_impl!(GetOnly, $name, $level, $flag, bool, GetBool);
};
- (GetOnly, $name:ident, $level:path, $flag:path, u8) => {
+ (GetOnly, $name:ident, $level:expr, $flag:path, u8) => {
sockopt_impl!(GetOnly, $name, $level, $flag, u8, GetU8);
};
- (GetOnly, $name:ident, $level:path, $flag:path, usize) => {
+ (GetOnly, $name:ident, $level:expr, $flag:path, usize) => {
sockopt_impl!(GetOnly, $name, $level, $flag, usize, GetUsize);
};
- (SetOnly, $name:ident, $level:path, $flag:path, bool) => {
+ (SetOnly, $name:ident, $level:expr, $flag:path, bool) => {
sockopt_impl!(SetOnly, $name, $level, $flag, bool, SetBool);
};
- (SetOnly, $name:ident, $level:path, $flag:path, u8) => {
+ (SetOnly, $name:ident, $level:expr, $flag:path, u8) => {
sockopt_impl!(SetOnly, $name, $level, $flag, u8, SetU8);
};
- (SetOnly, $name:ident, $level:path, $flag:path, usize) => {
+ (SetOnly, $name:ident, $level:expr, $flag:path, usize) => {
sockopt_impl!(SetOnly, $name, $level, $flag, usize, SetUsize);
};
- (Both, $name:ident, $level:path, $flag:path, bool) => {
+ (Both, $name:ident, $level:expr, $flag:path, bool) => {
sockopt_impl!(Both, $name, $level, $flag, bool, GetBool, SetBool);
};
- (Both, $name:ident, $level:path, $flag:path, u8) => {
+ (Both, $name:ident, $level:expr, $flag:path, u8) => {
sockopt_impl!(Both, $name, $level, $flag, u8, GetU8, SetU8);
};
- (Both, $name:ident, $level:path, $flag:path, usize) => {
+ (Both, $name:ident, $level:expr, $flag:path, usize) => {
sockopt_impl!(Both, $name, $level, $flag, usize, GetUsize, SetUsize);
};
- (Both, $name:ident, $level:path, $flag:path, OsString<$array:ty>) => {
+ (Both, $name:ident, $level:expr, $flag:path, OsString<$array:ty>) => {
sockopt_impl!(Both, $name, $level, $flag, OsString, GetOsString<$array>, SetOsString);
};
@@ -172,29 +172,29 @@ macro_rules! sockopt_impl {
* Matchers with generic getter types must be placed at the end, so
* they'll only match _after_ specialized matchers fail
*/
- (GetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
+ (GetOnly, $name:ident, $level:expr, $flag:path, $ty:ty) => {
sockopt_impl!(GetOnly, $name, $level, $flag, $ty, GetStruct<$ty>);
};
- (GetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => {
+ (GetOnly, $name:ident, $level:expr, $flag:path, $ty:ty, $getter:ty) => {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct $name;
getsockopt_impl!($name, $level, $flag, $ty, $getter);
};
- (SetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
+ (SetOnly, $name:ident, $level:expr, $flag:path, $ty:ty) => {
sockopt_impl!(SetOnly, $name, $level, $flag, $ty, SetStruct<$ty>);
};
- (SetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => {
+ (SetOnly, $name:ident, $level:expr, $flag:path, $ty:ty, $setter:ty) => {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct $name;
setsockopt_impl!($name, $level, $flag, $ty, $setter);
};
- (Both, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty, $setter:ty) => {
+ (Both, $name:ident, $level:expr, $flag:path, $ty:ty, $getter:ty, $setter:ty) => {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct $name;
@@ -202,7 +202,7 @@ macro_rules! sockopt_impl {
getsockopt_impl!($name, $level, $flag, $ty, $getter);
};
- (Both, $name:ident, $level:path, $flag:path, $ty:ty) => {
+ (Both, $name:ident, $level:expr, $flag:path, $ty:ty) => {
sockopt_impl!(Both, $name, $level, $flag, $ty, GetStruct<$ty>, SetStruct<$ty>);
};
}
@@ -246,6 +246,14 @@ sockopt_impl!(Both, Broadcast, libc::SOL_SOCKET, libc::SO_BROADCAST, bool);
sockopt_impl!(Both, OobInline, libc::SOL_SOCKET, libc::SO_OOBINLINE, bool);
sockopt_impl!(GetOnly, SocketError, libc::SOL_SOCKET, libc::SO_ERROR, i32);
sockopt_impl!(Both, KeepAlive, libc::SOL_SOCKET, libc::SO_KEEPALIVE, bool);
+#[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "macos",
+ target_os = "ios"
+))]
+// Get the credentials of the peer process of a connected unix domain socket.
+sockopt_impl!(GetOnly, LocalPeerCred, 0, libc::LOCAL_PEERCRED, super::XuCred);
#[cfg(any(target_os = "android", target_os = "linux"))]
sockopt_impl!(GetOnly, PeerCredentials, libc::SOL_SOCKET, libc::SO_PEERCRED, super::UnixCredentials);
#[cfg(any(target_os = "ios",