mirror of
https://github.com/zap-proto/zip.git
synced 2026-10-19 15:38:57 +00:00
attest unix peers on darwin, where the kernel has an answer
peerOf was implemented for Linux and stubbed everywhere else, and the stub says the host "does not hand us a peer credential" — which is not true of Darwin. It reports the same thing SO_PEERCRED does, split across two socket options: LOCAL_PEERCRED carries the user and groups, LOCAL_PEERPID the process. The consequence was quiet. A caller identity is either attested by the kernel or asserted by the caller, and every Mac silently had only the second kind, so a check that fails closed on a developer's machine passes in CI for a reason unrelated to the code under test. A credential without a group is refused whole rather than reported with GID 0, for the same reason the stub returns nil instead of an empty Peer: every field of a non-nil Peer came from the kernel. x/sys was already in the module graph and is now a direct requirement at the version it was already resolved to. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
//go:build darwin
|
||||
|
||||
package zip
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// peerOf reads the credential the KERNEL recorded for the process at the far
|
||||
// end of a unix connection — the same attestation SO_PEERCRED gives on Linux,
|
||||
// and the same guarantee: it is not a value the peer sends, so there is
|
||||
// nothing for it to forge.
|
||||
//
|
||||
// It takes two socket options because Darwin splits what Linux returns at
|
||||
// once: LOCAL_PEERCRED carries the user and groups, LOCAL_PEERPID the process.
|
||||
//
|
||||
// A non-unix conn has no answer: a tcp peer is an address, and an address is
|
||||
// not an identity. That case returns nil rather than a zero Peer, so "not
|
||||
// attested" is never mistaken for "attested as root" — which is also why a
|
||||
// credential arriving without a group is refused whole rather than reported
|
||||
// with GID 0. Every field of a non-nil Peer came from the kernel.
|
||||
func peerOf(c net.Conn) *Peer {
|
||||
uc, ok := c.(*net.UnixConn)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
raw, err := uc.SyscallConn()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var cred *unix.Xucred
|
||||
var pid int
|
||||
var sockErr error
|
||||
if err := raw.Control(func(fd uintptr) {
|
||||
if cred, sockErr = unix.GetsockoptXucred(int(fd), unix.SOL_LOCAL, unix.LOCAL_PEERCRED); sockErr != nil {
|
||||
return
|
||||
}
|
||||
pid, sockErr = unix.GetsockoptInt(int(fd), unix.SOL_LOCAL, unix.LOCAL_PEERPID)
|
||||
}); err != nil || sockErr != nil || cred == nil || cred.Ngroups < 1 {
|
||||
return nil
|
||||
}
|
||||
return &Peer{PID: pid, UID: int(cred.Uid), GID: int(cred.Groups[0])}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//go:build !linux
|
||||
//go:build !linux && !darwin
|
||||
|
||||
package zip
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ require (
|
||||
github.com/zap-proto/mcp v1.0.5
|
||||
golang.org/x/crypto v0.52.0 // indirect
|
||||
golang.org/x/net v0.55.0 // indirect
|
||||
golang.org/x/sys v0.45.0 // indirect
|
||||
golang.org/x/sys v0.45.0
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
)
|
||||
|
||||
@@ -87,12 +87,6 @@ github.com/zap-proto/fiber/v3 v3.2.1 h1:k45oKyTwySPtGt8sPz2Ao8OUHc7pDEhai8Np2Ym6
|
||||
github.com/zap-proto/fiber/v3 v3.2.1/go.mod h1:eDm2z+ufJrkuE4MeX0Mea4oc/p7/HpXiZjVB+BXCKOA=
|
||||
github.com/zap-proto/go v1.3.0 h1:S3rMoawwhH/BbSZ4G8zG05hJoQnMSMDPzIq75diCTqE=
|
||||
github.com/zap-proto/go v1.3.0/go.mod h1:914SNGTH6Rv3Yu1MweWJBPEN8FZlo5C39QyhaB0C7Q0=
|
||||
github.com/zap-proto/http v0.3.1 h1:A2rCPWYCX866eAsdiWuns0dvWnBmViZtGm4pwX7jwlY=
|
||||
github.com/zap-proto/http v0.3.1/go.mod h1:UYfGhDDCetgxs65XSev8Lpf65COg5vKQK+cWwZGh4zQ=
|
||||
github.com/zap-proto/http v0.3.2 h1:4VCAoGUQWNXuO3cXl20rYi7D+GoCObKy1BoienVXam8=
|
||||
github.com/zap-proto/http v0.3.2/go.mod h1:UYfGhDDCetgxs65XSev8Lpf65COg5vKQK+cWwZGh4zQ=
|
||||
github.com/zap-proto/http v0.3.3 h1:waa89Ya26jSHUOeGWhcmak2hecdsnyq4z0oF4JUItFs=
|
||||
github.com/zap-proto/http v0.3.3/go.mod h1:UYfGhDDCetgxs65XSev8Lpf65COg5vKQK+cWwZGh4zQ=
|
||||
github.com/zap-proto/http v0.3.5 h1:ezSuUbF05jxFGpfmScBnzIVTeH1ZGhcDSm7d5yL8Byc=
|
||||
github.com/zap-proto/http v0.3.5/go.mod h1:UYfGhDDCetgxs65XSev8Lpf65COg5vKQK+cWwZGh4zQ=
|
||||
github.com/zap-proto/mcp v1.0.5 h1:1Hi0KNi4YlWW2zkQUMDK9n3jP3wZaRJ1rseMW9p9F0c=
|
||||
|
||||
Reference in New Issue
Block a user