peercred_openbsd.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334
  1. //go:build openbsd
  2. package localapi
  3. import (
  4. "net"
  5. "golang.org/x/sys/unix"
  6. )
  7. // peerCheckSupported reports that this platform can identify a connecting process.
  8. const peerCheckSupported = true
  9. // peerUID returns the uid of the process on the other end of conn.
  10. //
  11. // OpenBSD reports the peer through SO_PEERCRED at SOL_SOCKET, filling a
  12. // `struct sockpeercred { uid_t uid; gid_t gid; pid_t pid; }`. System calls here have to
  13. // go through libc, so the raw getsockopt netbsd uses is not an option, and
  14. // golang.org/x/sys/unix has no typed wrapper for this struct. It does export
  15. // GetsockoptInt, which goes through its libc trampoline with a 4 byte buffer, and the
  16. // kernel copies out min(caller's length, option length): the first four bytes, which are
  17. // the uid. That is a dependence on the field order, the same one netbsd's offset carries.
  18. func peerUID(conn net.Conn) (uid uint32, err error) {
  19. err = withPeerFD(conn, func(fd int) error {
  20. v, credErr := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_PEERCRED)
  21. if credErr != nil {
  22. return credErr
  23. }
  24. // A uid_t is 32 bits; GetsockoptInt read exactly that many and widened it.
  25. uid = uint32(v)
  26. return nil
  27. })
  28. return uid, err
  29. }