use std::os::unix::net::UnixStream;
use tracing::warn;
use uds::UnixStreamExt;
pub(super) fn peer_is_self(stream: &UnixStream, euid: u32) -> bool {
match stream.initial_peer_credentials() {
Ok(cred) if cred.euid() == euid => true,
Ok(cred) => {
warn!(
euid = cred.euid(),
"Rejected IPC connection from foreign uid"
);
false
}
Err(e) => {
warn!(%e, "Could not read peer credentials; rejecting");
false
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn peer_credentials_report_own_uid() {
let (a, b) = UnixStream::pair().expect("socketpair should succeed");
let euid = unsafe { libc::geteuid() };
let cred_a = a.initial_peer_credentials().expect("peer creds readable");
let cred_b = b.initial_peer_credentials().expect("peer creds readable");
assert_eq!(cred_a.euid(), euid);
assert_eq!(cred_b.euid(), euid);
}
#[test]
fn peer_is_self_accepts_same_user() {
let (a, _b) = UnixStream::pair().expect("socketpair should succeed");
let euid = unsafe { libc::geteuid() };
let accepted = peer_is_self(&a, euid);
assert!(accepted, "same-euid peer must be accepted");
}
#[test]
fn peer_is_self_rejects_foreign_uid() {
let (a, _b) = UnixStream::pair().expect("socketpair should succeed");
let euid = unsafe { libc::geteuid() };
let foreign = euid ^ 1;
let accepted = peer_is_self(&a, foreign);
assert!(!accepted, "peer with foreign uid must be rejected");
}
}