diff options
| author | Brad Fitzpatrick <bradfitz@tailscale.com> | 2021-02-15 20:50:20 -0800 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@tailscale.com> | 2021-02-15 20:50:20 -0800 |
| commit | 9baca2e8335119a55f4a040398c5aed43513c985 (patch) | |
| tree | e98e844c26f608799cf27124d09bb3f59ccb0b54 | |
| parent | 4ec01323c135c44f4f85acd8e2330a8e8542de71 (diff) | |
| download | tailscale-bradfitz/darwin_creds.tar.xz tailscale-bradfitz/darwin_creds.zip | |
safesocket, ipn/ipnserver: look up peer creds on Darwinbradfitz/darwin_creds
And open up socket permissions like Linux, now that we know who connections are from.
WIP DO NOT SUBMIT
Updates #1347
Fixes #1348
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | ipn/ipnserver/conn_darwin.go | 56 | ||||
| -rw-r--r-- | ipn/ipnserver/conn_no_ucred.go | 2 | ||||
| -rw-r--r-- | safesocket/unixsocket.go | 5 |
4 files changed, 62 insertions, 3 deletions
@@ -42,3 +42,5 @@ require ( inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d rsc.io/goversion v1.2.0 ) + +replace golang.org/x/sys => /Users/bradfitz/src/golang.org/x/sys diff --git a/ipn/ipnserver/conn_darwin.go b/ipn/ipnserver/conn_darwin.go new file mode 100644 index 000000000..594025fc1 --- /dev/null +++ b/ipn/ipnserver/conn_darwin.go @@ -0,0 +1,56 @@ +// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin,!redo + +package ipnserver + +import ( + "net" + + "golang.org/x/sys/unix" + "tailscale.com/types/logger" +) + +const ( + xLOCAL_PEERCRED = 0x1 + xLOCAL_PEEREPID = 0x3 + xLOCAL_PEEREUUID = 0x5 + xLOCAL_PEERPID = 0x2 + xLOCAL_PEERUUID = 0x4 +) + +func isReadonlyConn(c net.Conn, logf logger.Logf) (ro bool) { + ro = true // conservative default for naked returns below + uc, ok := c.(*net.UnixConn) + if !ok { + logf("unexpected connection type %T", c) + return + } + raw, err := uc.SyscallConn() + if err != nil { + logf("SyscallConn: %v", err) + return + } + + var cred unix.Xucred + cerr := raw.Control(func(fd uintptr) { + err = unix.GetsockoptXucred(int(fd), unix.SOL_LOCAL, unix.LOCAL_PEERCRED, &cred) + }) + if cerr != nil { + logf("raw.Control: %v", err) + return + } + if err != nil { + logf("raw.GetsockoptXucred: %v", err) + return + } + logf("XXX got creds %+v", cred) + if cred.Uid == 0 { + // root is not read-only. + return false + } + logf("non-root connection from %v (read-only)", cred.Uid) + return true +} diff --git a/ipn/ipnserver/conn_no_ucred.go b/ipn/ipnserver/conn_no_ucred.go index c50e4778d..e0899b5c6 100644 --- a/ipn/ipnserver/conn_no_ucred.go +++ b/ipn/ipnserver/conn_no_ucred.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !linux +// +build !linux,!darwin darwin,redo package ipnserver diff --git a/safesocket/unixsocket.go b/safesocket/unixsocket.go index 8128bef57..8d8b6f176 100644 --- a/safesocket/unixsocket.go +++ b/safesocket/unixsocket.go @@ -103,8 +103,9 @@ func tailscaledRunningUnderLaunchd() bool { // socketPermissionsForOS returns the permissions to use for the // tailscaled.sock. func socketPermissionsForOS() os.FileMode { - if runtime.GOOS == "linux" { - // On Linux, the ipn/ipnserver package looks at the Unix peer creds + switch runtime.GOOS { + case "linux", "darwin": + // On Linux and Farwin, the ipn/ipnserver package looks at the Unix peer creds // and only permits read-only actions from non-root users, so we want // this opened up wider. // |
