summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--go.mod2
-rw-r--r--ipn/ipnserver/conn_darwin.go56
-rw-r--r--ipn/ipnserver/conn_no_ucred.go2
-rw-r--r--safesocket/unixsocket.go5
4 files changed, 62 insertions, 3 deletions
diff --git a/go.mod b/go.mod
index c0266a0d0..214b6e1f7 100644
--- a/go.mod
+++ b/go.mod
@@ -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.
//