Skip to content

Commit

Permalink
Add UnixCredentials::new() to make portable use of ScmCredentials easy
Browse files Browse the repository at this point in the history
  • Loading branch information
valpackett committed Apr 14, 2020
1 parent 720e4fe commit ba031dd
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 10 deletions.
22 changes: 22 additions & 0 deletions src/sys/socket/mod.rs
Expand Up @@ -196,6 +196,15 @@ cfg_if! {
pub struct UnixCredentials(libc::ucred);

impl UnixCredentials {
/// Creates a new instance with the credentials of the current process
pub fn new() -> Self {
UnixCredentials(libc::ucred {
pid: crate::unistd::getpid().as_raw(),
uid: crate::unistd::getuid().as_raw(),
gid: crate::unistd::getgid().as_raw(),
})
}

/// Returns the process identifier
pub fn pid(&self) -> libc::pid_t {
self.0.pid
Expand Down Expand Up @@ -232,6 +241,19 @@ cfg_if! {
pub struct UnixCredentials(libc::cmsgcred);

impl UnixCredentials {
/// Creates a new instance with the credentials of the current process
pub fn new() -> Self {
// The kernel overwrites it when sending SCM_CREDS
UnixCredentials(libc::cmsgcred {
cmcred_pid: 0,
cmcred_uid: 0,
cmcred_euid: 0,
cmcred_gid: 0,
cmcred_ngroups: 0,
cmcred_groups: [0; libc::CMGROUP_MAX],
})
}

/// Returns the process identifier
pub fn pid(&self) -> libc::pid_t {
self.0.cmcred_pid
Expand Down
23 changes: 13 additions & 10 deletions test/sys/test_socket.rs
Expand Up @@ -540,28 +540,31 @@ pub fn test_sendmsg_empty_cmsgs() {
}
}

#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "linux",
target_os = "freebsd",
target_os = "dragonfly",
))]
#[test]
fn test_scm_credentials() {
use libc;
use nix::sys::uio::IoVec;
use nix::unistd::{close, getpid, getuid, getgid};
use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt,
AddressFamily, SockType, SockFlag,
ControlMessage, ControlMessageOwned, MsgFlags};
ControlMessage, ControlMessageOwned, MsgFlags,
UnixCredentials};
#[cfg(any(target_os = "android", target_os = "linux"))]
use nix::sys::socket::sockopt::PassCred;

let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
#[cfg(any(target_os = "android", target_os = "linux"))]
setsockopt(recv, PassCred, &true).unwrap();

{
let iov = [IoVec::from_slice(b"hello")];
let cred = libc::ucred {
pid: getpid().as_raw(),
uid: getuid().as_raw(),
gid: getgid().as_raw(),
}.into();
let cred = UnixCredentials::new();
let cmsg = ControlMessage::ScmCredentials(&cred);
assert_eq!(sendmsg(send, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5);
close(send).unwrap();
Expand All @@ -570,7 +573,7 @@ fn test_scm_credentials() {
{
let mut buf = [0u8; 5];
let iov = [IoVec::from_mut_slice(&mut buf[..])];
let mut cmsgspace = cmsg_space!(libc::ucred);
let mut cmsgspace = cmsg_space!(UnixCredentials);
let msg = recvmsg(recv, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
let mut received_cred = None;

Expand All @@ -582,7 +585,7 @@ fn test_scm_credentials() {
assert_eq!(cred.gid(), getgid().as_raw());
received_cred = Some(cred);
} else {
panic!("unexpected cmsg");
panic!("unexpected cmsg {:?}", cmsg);
}
}
received_cred.expect("no creds received");
Expand Down

0 comments on commit ba031dd

Please sign in to comment.