Skip to content

Expose functionality to get peer credentials for a Unix socket on Linux #101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 16, 2015

Conversation

maghoff
Copy link
Contributor

@maghoff maghoff commented Dec 16, 2015

Caveat: I put this rather randomly in unix/notbsd/linux/other/mod.rs. I know nothing about mips and musl, and I have no idea if this thing also applies to Android. I would guess "yes", but I don't know how to go about testing that assumption. Superficial googling seems to indicate that the constant and struct in question are present in android linux.

Further work: There is a roughly corresponding getsockopt for freebsd and osx (and possibly more bsds?) called LOCAL_PEERCRED. It would be neat to have that supported as well.

@maghoff
Copy link
Contributor Author

maghoff commented Dec 16, 2015

Usage example:

extern crate libc;
extern crate unix_socket;

use std::mem;
use std::io::{self, Write};
use std::os::unix::io::AsRawFd;
use unix_socket::{UnixStream, UnixListener};

fn get_peer_credentials(stream: &UnixStream) -> io::Result<libc::ucred> {
    let fd = stream.as_raw_fd();

    unsafe {
        let mut credentials: libc::ucred = mem::zeroed();
        let mut size = mem::size_of::<libc::ucred>() as libc::socklen_t;
        match libc::getsockopt(
                fd,
                libc::SOL_SOCKET,
                libc::SO_PEERCRED,
                &mut credentials as *mut _ as *mut _,
                &mut size as *mut _ as *mut _
        ) {
            val if val < 0 => Err(io::Error::last_os_error()),
            _ => Ok(credentials)
        }
    }
}

fn main() {
    let listener = UnixListener::bind("socket").unwrap();
    println!("Connect to `socket` with for example: nc -U socket");

    for maybe_stream in listener.incoming() {
        let stream = maybe_stream.unwrap();
        let ucred = get_peer_credentials(&stream).unwrap();
        println!("Connected with user {} from process {}", ucred.uid, ucred.pid);
        writeln!(&stream, "Hello {}!", ucred.uid).unwrap();
    }
}

@maghoff
Copy link
Contributor Author

maghoff commented Dec 16, 2015

To the failing AppVeyor build, this fails similarly to how it fails on master (doesn't find kernel32.lib), which probably is, and definitely should be, unrelated to this pull request :) (But you probably already realized)

@alexcrichton
Copy link
Member

Thanks!

alexcrichton added a commit that referenced this pull request Dec 16, 2015
Expose functionality to get peer credentials for a Unix socket on Linux
@alexcrichton alexcrichton merged commit 4920c7e into rust-lang:master Dec 16, 2015
danielverkamp pushed a commit to danielverkamp/libc that referenced this pull request Apr 28, 2020
The i586 targets on x86 are defined to be 32-bit and lacking in sse/sse2 unlike
the i686 target which has sse2 turned on by default. I was mostly curious what
would happen when turning on this target, and it turns out quite a few tests
failed!

Most of the tests here had to do with calling functions with ABI mismatches
where the callee wasn't `#[inline(always)]`. Various pieces have been updated
now and we should be passing all tests.

Only one instruction assertion ended up changing where the function generates a
different instruction with sse2 ambiently enabled and without it enabled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants