Skip to content

Commit 1164ea7

Browse files
maghoffcarllerche
authored andcommitted
Implement support for getsockopt of peer credentials using the Linux specific SO_PEERCRED
1 parent 1ce4eee commit 1164ea7

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/sys/socket/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use errno::Errno;
66
use features;
77
use fcntl::{fcntl, FD_CLOEXEC, O_NONBLOCK};
88
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
9-
use libc::{c_void, c_int, socklen_t, size_t};
9+
use libc::{c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
1010
use std::{mem, ptr, slice};
1111
use std::os::unix::io::RawFd;
1212
use sys::uio::IoVec;
@@ -581,6 +581,14 @@ pub struct linger {
581581
pub l_linger: c_int
582582
}
583583

584+
#[repr(C)]
585+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
586+
pub struct ucred {
587+
pid: pid_t,
588+
uid: uid_t,
589+
gid: gid_t,
590+
}
591+
584592
/*
585593
*
586594
* ===== Socket Options =====

src/sys/socket/sockopt.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ sockopt_impl!(Both, Broadcast, consts::SOL_SOCKET, consts::SO_BROADCAST, bool);
137137
sockopt_impl!(Both, OobInline, consts::SOL_SOCKET, consts::SO_OOBINLINE, bool);
138138
sockopt_impl!(GetOnly, SocketError, consts::SOL_SOCKET, consts::SO_ERROR, i32);
139139
sockopt_impl!(Both, KeepAlive, consts::SOL_SOCKET, consts::SO_KEEPALIVE, bool);
140+
#[cfg(target_os = "linux")]
141+
sockopt_impl!(GetOnly, PeerCredentials, consts::SOL_SOCKET, consts::SO_PEERCRED, super::ucred);
140142
#[cfg(any(target_os = "macos",
141143
target_os = "ios"))]
142144
sockopt_impl!(Both, TcpKeepAlive, consts::IPPROTO_TCP, consts::TCP_KEEPALIVE, u32);
@@ -300,3 +302,19 @@ impl<'a> Set<'a, u8> for SetU8 {
300302
mem::size_of::<c_int>() as socklen_t
301303
}
302304
}
305+
306+
307+
#[cfg(test)]
308+
mod test {
309+
#[cfg(target_os = "linux")]
310+
#[test]
311+
fn can_get_peercred_on_unix_socket() {
312+
use super::super::*;
313+
314+
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
315+
let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
316+
let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
317+
assert_eq!(a_cred, b_cred);
318+
assert!(a_cred.pid != 0);
319+
}
320+
}

0 commit comments

Comments
 (0)