iop/apps/agent/internal/localcontrol/peercred_darwin.go

61 lines
1.5 KiB
Go

//go:build darwin
package localcontrol
import (
"fmt"
"net"
"os"
"syscall"
"golang.org/x/sys/unix"
)
func (kernelPeerCredentialSource) Supported() bool {
return true
}
// UID uses Darwin LOCAL_PEERCRED, the kernel credential primitive underlying
// the getpeereid same-user check, without requiring cgo.
func (kernelPeerCredentialSource) UID(conn net.Conn) (uint32, error) {
return getpeereidUID(conn)
}
func getpeereidUID(conn net.Conn) (uint32, error) {
syscallConn, ok := conn.(syscall.Conn)
if !ok {
return 0, fmt.Errorf("localcontrol: connection does not expose a syscall handle")
}
raw, err := syscallConn.SyscallConn()
if err != nil {
return 0, fmt.Errorf("localcontrol: obtain peer syscall handle: %w", err)
}
var (
credential *unix.Xucred
socketErr error
)
if err := raw.Control(func(fileDescriptor uintptr) {
credential, socketErr = unix.GetsockoptXucred(
int(fileDescriptor),
unix.SOL_LOCAL,
unix.LOCAL_PEERCRED,
)
}); err != nil {
return 0, fmt.Errorf("localcontrol: inspect peer credentials: %w", err)
}
if socketErr != nil {
return 0, fmt.Errorf("localcontrol: inspect LOCAL_PEERCRED: %w", socketErr)
}
if credential == nil {
return 0, fmt.Errorf("localcontrol: LOCAL_PEERCRED returned no identity")
}
return credential.Uid, nil
}
func fileOwnerUID(info os.FileInfo) (uint32, error) {
stat, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return 0, fmt.Errorf("localcontrol: filesystem owner is unavailable")
}
return stat.Uid, nil
}