From 4581dbaed31291bd53ff84897768378bfe14e532 Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Mon, 15 Apr 2024 19:44:24 +0000 Subject: [PATCH 1/2] Add Socket::passcred/set_passcred for working with SO_PASSCRED. --- src/socket.rs | 31 +++++++++++++++++++++++++++++++ src/sys/unix.rs | 2 ++ 2 files changed, 33 insertions(+) diff --git a/src/socket.rs b/src/socket.rs index 3291707c..21bcfcb2 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -965,6 +965,37 @@ impl Socket { } } + /// Get value for the `SO_PASSCRED` option on this socket. + /// + /// For more information about this option, see [`set_passcred`]. + /// + /// [`set_passcred`]: Socket::set_passcred + #[cfg(all(unix, target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all(unix, target_os = "linux"))))] + pub fn passcred(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), sys::SOL_SOCKET, sys::SO_PASSCRED) + .map(|passcred| passcred != 0) + } + } + + /// Set value for the `SO_PASSCRED` option on this socket. + /// + /// If this option is enabled, enables the receiving of the `SCM_CREDENTIALS` + /// control messages. + #[cfg(all(unix, target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all(unix, target_os = "linux"))))] + pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + sys::SOL_SOCKET, + sys::SO_PASSCRED, + passcred as c_int, + ) + } + } + /// Get value for the `SO_RCVBUF` option on this socket. /// /// For more information about this option, see [`set_recv_buffer_size`]. diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 562cd60f..ae2d7b84 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -179,6 +179,8 @@ pub(crate) use libc::{ SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_RCVBUF, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO, SO_TYPE, TCP_NODELAY, }; +#[cfg(target_os = "linux")] +pub(crate) use libc::SO_PASSCRED; #[cfg(not(any( target_os = "dragonfly", target_os = "haiku", From 0785527ace372a71e2c5eb91aed122a08722eaf8 Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Wed, 17 Apr 2024 00:08:30 +0000 Subject: [PATCH 2/2] Add test for Socket::passcred/set_passcred and fix formatting. --- src/sys/unix.rs | 4 ++-- tests/socket.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index ae2d7b84..98c1024b 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -172,6 +172,8 @@ pub(crate) use libc::SO_LINGER; target_os = "watchos", ))] pub(crate) use libc::SO_LINGER_SEC as SO_LINGER; +#[cfg(target_os = "linux")] +pub(crate) use libc::SO_PASSCRED; pub(crate) use libc::{ ip_mreq as IpMreq, linger, IPPROTO_IP, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_IF, IPV6_MULTICAST_LOOP, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, @@ -179,8 +181,6 @@ pub(crate) use libc::{ SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_RCVBUF, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO, SO_TYPE, TCP_NODELAY, }; -#[cfg(target_os = "linux")] -pub(crate) use libc::SO_PASSCRED; #[cfg(not(any( target_os = "dragonfly", target_os = "haiku", diff --git a/tests/socket.rs b/tests/socket.rs index 1c83321a..89b79f5f 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1680,3 +1680,19 @@ fn cookie() { Err(err) => panic!("Could not get socket cookie a second time, err: {err}"), } } + +#[cfg(all(unix, target_os = "linux"))] +#[test] +fn set_passcred() { + let socket = Socket::new(Domain::UNIX, Type::DGRAM, None).unwrap(); + assert!(!socket.passcred().unwrap()); + + socket.set_passcred(true).unwrap(); + assert!(socket.passcred().unwrap()); + + let socket = Socket::new(Domain::UNIX, Type::STREAM, None).unwrap(); + assert!(!socket.passcred().unwrap()); + + socket.set_passcred(true).unwrap(); + assert!(socket.passcred().unwrap()); +}