Update
This commit is contained in:
28
vendor/tailscale.com/ipn/ipnauth/ipnauth.go
generated
vendored
28
vendor/tailscale.com/ipn/ipnauth/ipnauth.go
generated
vendored
@@ -14,8 +14,8 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"github.com/tailscale/peercred"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/feature/buildfeatures"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/safesocket"
|
||||
"tailscale.com/types/logger"
|
||||
@@ -63,8 +63,8 @@ type ConnIdentity struct {
|
||||
notWindows bool // runtime.GOOS != "windows"
|
||||
|
||||
// Fields used when NotWindows:
|
||||
isUnixSock bool // Conn is a *net.UnixConn
|
||||
creds *peercred.Creds // or nil
|
||||
isUnixSock bool // Conn is a *net.UnixConn
|
||||
creds PeerCreds // or nil if peercred.Get was not implemented on this OS
|
||||
|
||||
// Used on Windows:
|
||||
// TODO(bradfitz): merge these into the peercreds package and
|
||||
@@ -78,6 +78,13 @@ type ConnIdentity struct {
|
||||
// It's suitable for passing to LookupUserFromID (os/user.LookupId) on any
|
||||
// operating system.
|
||||
func (ci *ConnIdentity) WindowsUserID() ipn.WindowsUserID {
|
||||
if !buildfeatures.HasDebug && runtime.GOOS != "windows" {
|
||||
// This function is only implemented on non-Windows for simulating
|
||||
// Windows in tests. But that test (per comments below) is broken
|
||||
// anyway. So disable this testing path in non-debug builds
|
||||
// and just do the thing that optimizes away.
|
||||
return ""
|
||||
}
|
||||
if envknob.GOOS() != "windows" {
|
||||
return ""
|
||||
}
|
||||
@@ -97,9 +104,18 @@ func (ci *ConnIdentity) WindowsUserID() ipn.WindowsUserID {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (ci *ConnIdentity) Pid() int { return ci.pid }
|
||||
func (ci *ConnIdentity) IsUnixSock() bool { return ci.isUnixSock }
|
||||
func (ci *ConnIdentity) Creds() *peercred.Creds { return ci.creds }
|
||||
func (ci *ConnIdentity) Pid() int { return ci.pid }
|
||||
func (ci *ConnIdentity) IsUnixSock() bool { return ci.isUnixSock }
|
||||
func (ci *ConnIdentity) Creds() PeerCreds { return ci.creds }
|
||||
|
||||
// PeerCreds is the interface for a github.com/tailscale/peercred.Creds,
|
||||
// if linked into the binary.
|
||||
//
|
||||
// (It's not used on some platforms, or if ts_omit_unixsocketidentity is set.)
|
||||
type PeerCreds interface {
|
||||
UserID() (uid string, ok bool)
|
||||
PID() (pid int, ok bool)
|
||||
}
|
||||
|
||||
var metricIssue869Workaround = clientmetric.NewCounter("issue_869_workaround")
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !windows
|
||||
//go:build !windows && ts_omit_unixsocketidentity
|
||||
|
||||
package ipnauth
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/tailscale/peercred"
|
||||
"tailscale.com/types/logger"
|
||||
)
|
||||
|
||||
@@ -16,12 +15,7 @@ import (
|
||||
// based on the user who owns the other end of the connection.
|
||||
// and couldn't. The returned connIdentity has NotWindows set to true.
|
||||
func GetConnIdentity(_ logger.Logf, c net.Conn) (ci *ConnIdentity, err error) {
|
||||
ci = &ConnIdentity{conn: c, notWindows: true}
|
||||
_, ci.isUnixSock = c.(*net.UnixConn)
|
||||
if ci.creds, _ = peercred.Get(c); ci.creds != nil {
|
||||
ci.pid, _ = ci.creds.PID()
|
||||
}
|
||||
return ci, nil
|
||||
return &ConnIdentity{conn: c, notWindows: true}, nil
|
||||
}
|
||||
|
||||
// WindowsToken is unsupported when GOOS != windows and always returns
|
||||
37
vendor/tailscale.com/ipn/ipnauth/ipnauth_unix_creds.go
generated
vendored
Normal file
37
vendor/tailscale.com/ipn/ipnauth/ipnauth_unix_creds.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !windows && !ts_omit_unixsocketidentity
|
||||
|
||||
package ipnauth
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/tailscale/peercred"
|
||||
"tailscale.com/types/logger"
|
||||
)
|
||||
|
||||
// GetConnIdentity extracts the identity information from the connection
|
||||
// based on the user who owns the other end of the connection.
|
||||
// and couldn't. The returned connIdentity has NotWindows set to true.
|
||||
func GetConnIdentity(_ logger.Logf, c net.Conn) (ci *ConnIdentity, err error) {
|
||||
ci = &ConnIdentity{conn: c, notWindows: true}
|
||||
_, ci.isUnixSock = c.(*net.UnixConn)
|
||||
if creds, err := peercred.Get(c); err == nil {
|
||||
ci.creds = creds
|
||||
ci.pid, _ = ci.creds.PID()
|
||||
} else if err == peercred.ErrNotImplemented {
|
||||
// peercred.Get is not implemented on this OS (such as OpenBSD)
|
||||
// Just leave creds as nil, as documented.
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
return ci, nil
|
||||
}
|
||||
|
||||
// WindowsToken is unsupported when GOOS != windows and always returns
|
||||
// ErrNotImplemented.
|
||||
func (ci *ConnIdentity) WindowsToken() (WindowsToken, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
29
vendor/tailscale.com/ipn/ipnauth/ipnauth_windows.go
generated
vendored
29
vendor/tailscale.com/ipn/ipnauth/ipnauth_windows.go
generated
vendored
@@ -25,6 +25,12 @@ func GetConnIdentity(logf logger.Logf, c net.Conn) (ci *ConnIdentity, err error)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("not a WindowsClientConn: %T", c)
|
||||
}
|
||||
if err := wcc.CheckToken(); err != nil {
|
||||
// Failure to obtain a token means the client cannot be authenticated.
|
||||
// We don't care about the exact error, but it typically means the client
|
||||
// attempted to connect at the Anonymous impersonation level.
|
||||
return nil, fmt.Errorf("authentication failed: %w", err)
|
||||
}
|
||||
ci.pid, err = wcc.ClientPID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -169,26 +175,13 @@ func (t *token) IsUID(uid ipn.WindowsUserID) bool {
|
||||
// WindowsToken returns the WindowsToken representing the security context
|
||||
// of the connection's client.
|
||||
func (ci *ConnIdentity) WindowsToken() (WindowsToken, error) {
|
||||
var wcc *safesocket.WindowsClientConn
|
||||
var ok bool
|
||||
if wcc, ok = ci.conn.(*safesocket.WindowsClientConn); !ok {
|
||||
wcc, ok := ci.conn.(*safesocket.WindowsClientConn)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("not a WindowsClientConn: %T", ci.conn)
|
||||
}
|
||||
|
||||
// We duplicate the token's handle so that the WindowsToken we return may have
|
||||
// a lifetime independent from the original connection.
|
||||
var h windows.Handle
|
||||
if err := windows.DuplicateHandle(
|
||||
windows.CurrentProcess(),
|
||||
windows.Handle(wcc.Token()),
|
||||
windows.CurrentProcess(),
|
||||
&h,
|
||||
0,
|
||||
false,
|
||||
windows.DUPLICATE_SAME_ACCESS,
|
||||
); err != nil {
|
||||
token, err := wcc.Token()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newToken(windows.Token(h)), nil
|
||||
return newToken(token), nil
|
||||
}
|
||||
|
||||
11
vendor/tailscale.com/ipn/ipnauth/policy.go
generated
vendored
11
vendor/tailscale.com/ipn/ipnauth/policy.go
generated
vendored
@@ -8,9 +8,11 @@ import (
|
||||
"fmt"
|
||||
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/feature/buildfeatures"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/util/syspolicy"
|
||||
"tailscale.com/util/syspolicy/pkey"
|
||||
"tailscale.com/util/syspolicy/policyclient"
|
||||
)
|
||||
|
||||
type actorWithPolicyChecks struct{ Actor }
|
||||
@@ -50,10 +52,13 @@ func (a actorWithPolicyChecks) CheckProfileAccess(profile ipn.LoginProfileView,
|
||||
// TODO(nickkhyl): unexport it when we move [ipn.Actor] implementations from [ipnserver]
|
||||
// and corp to this package.
|
||||
func CheckDisconnectPolicy(actor Actor, profile ipn.LoginProfileView, reason string, auditFn AuditLogFunc) error {
|
||||
if alwaysOn, _ := syspolicy.GetBoolean(syspolicy.AlwaysOn, false); !alwaysOn {
|
||||
if !buildfeatures.HasSystemPolicy {
|
||||
return nil
|
||||
}
|
||||
if allowWithReason, _ := syspolicy.GetBoolean(syspolicy.AlwaysOnOverrideWithReason, false); !allowWithReason {
|
||||
if alwaysOn, _ := policyclient.Get().GetBoolean(pkey.AlwaysOn, false); !alwaysOn {
|
||||
return nil
|
||||
}
|
||||
if allowWithReason, _ := policyclient.Get().GetBoolean(pkey.AlwaysOnOverrideWithReason, false); !allowWithReason {
|
||||
return errors.New("disconnect not allowed: always-on mode is enabled")
|
||||
}
|
||||
if reason == "" {
|
||||
|
||||
12
vendor/tailscale.com/ipn/ipnauth/self.go
generated
vendored
12
vendor/tailscale.com/ipn/ipnauth/self.go
generated
vendored
@@ -13,6 +13,11 @@ import (
|
||||
// has unlimited access.
|
||||
var Self Actor = unrestricted{}
|
||||
|
||||
// TODO is a caller identity used when the operation is performed on behalf of a user,
|
||||
// rather than by tailscaled itself, but the surrounding function is not yet extended
|
||||
// to accept an [Actor] parameter. It grants the same unrestricted access as [Self].
|
||||
var TODO Actor = unrestricted{}
|
||||
|
||||
// unrestricted is an [Actor] that has unlimited access to the currently running
|
||||
// tailscaled instance. It's typically used for operations performed by tailscaled
|
||||
// on its own, or upon a request from the control plane, rather on behalf of a user.
|
||||
@@ -49,3 +54,10 @@ func (unrestricted) IsLocalSystem() bool { return false }
|
||||
// Deprecated: this method exists for compatibility with the current (as of 2025-01-28)
|
||||
// permission model and will be removed as we progress on tailscale/corp#18342.
|
||||
func (unrestricted) IsLocalAdmin(operatorUID string) bool { return false }
|
||||
|
||||
// IsTailscaled reports whether the given Actor represents Tailscaled itself,
|
||||
// such as [Self] or a [TODO] placeholder actor.
|
||||
func IsTailscaled(a Actor) bool {
|
||||
_, ok := a.(unrestricted)
|
||||
return ok
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user