safesocket, version: fix safesocket_darwin behavior for cmd/tailscale (#15275)

fixes tailscale/tailscale#15269

Fixes the various CLIs for all of the various flavors of tailscaled on
darwin.  The logic in version is updated so that we have methods that
return true only for the actual GUI app (which can beCLI) and the
order of the checks in localTCPPortAndTokenDarwin are corrected so
that the logic works with all 5 combinations of CLI and tailscaled.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit is contained in:
Jonathan Nobels
2025-03-11 13:24:11 -04:00
committed by GitHub
parent a6e19f2881
commit 660b0515b9
3 changed files with 104 additions and 48 deletions

View File

@@ -62,26 +62,21 @@ func IsSandboxedMacOS() bool {
// Tailscale for macOS, either the main GUI process (non-sandboxed) or the
// system extension (sandboxed).
func IsMacSys() bool {
return IsMacSysExt() || IsMacSysApp()
return IsMacSysExt() || IsMacSysGUI()
}
var isMacSysApp lazy.SyncValue[bool]
// IsMacSysApp reports whether this process is the main, non-sandboxed GUI process
// IsMacSysGUI reports whether this process is the main, non-sandboxed GUI process
// that ships with the Standalone variant of Tailscale for macOS.
func IsMacSysApp() bool {
func IsMacSysGUI() bool {
if runtime.GOOS != "darwin" {
return false
}
return isMacSysApp.Get(func() bool {
exe, err := os.Executable()
if err != nil {
return false
}
// Check that this is the GUI binary, and it is not sandboxed. The GUI binary
// shipped in the App Store will always have the App Sandbox enabled.
return strings.HasSuffix(exe, "/Contents/MacOS/Tailscale") && !IsMacAppStore()
return strings.Contains(os.Getenv("HOME"), "/Containers/io.tailscale.ipn.macsys/") ||
strings.Contains(os.Getenv("XPC_SERVICE_NAME"), "io.tailscale.ipn.macsys")
})
}
@@ -95,10 +90,6 @@ func IsMacSysExt() bool {
return false
}
return isMacSysExt.Get(func() bool {
if strings.Contains(os.Getenv("HOME"), "/Containers/io.tailscale.ipn.macsys/") ||
strings.Contains(os.Getenv("XPC_SERVICE_NAME"), "io.tailscale.ipn.macsys") {
return true
}
exe, err := os.Executable()
if err != nil {
return false
@@ -109,8 +100,8 @@ func IsMacSysExt() bool {
var isMacAppStore lazy.SyncValue[bool]
// IsMacAppStore whether this binary is from the App Store version of Tailscale
// for macOS.
// IsMacAppStore returns whether this binary is from the App Store version of Tailscale
// for macOS. Returns true for both the network extension and the GUI app.
func IsMacAppStore() bool {
if runtime.GOOS != "darwin" {
return false
@@ -124,6 +115,25 @@ func IsMacAppStore() bool {
})
}
var isMacAppStoreGUI lazy.SyncValue[bool]
// IsMacAppStoreGUI reports whether this binary is the GUI app from the App Store
// version of Tailscale for macOS.
func IsMacAppStoreGUI() bool {
if runtime.GOOS != "darwin" {
return false
}
return isMacAppStoreGUI.Get(func() bool {
exe, err := os.Executable()
if err != nil {
return false
}
// Check that this is the GUI binary, and it is not sandboxed. The GUI binary
// shipped in the App Store will always have the App Sandbox enabled.
return strings.Contains(exe, "/Tailscale") && !IsMacSysGUI()
})
}
var isAppleTV lazy.SyncValue[bool]
// IsAppleTV reports whether this binary is part of the Tailscale network extension for tvOS.