Update
This commit is contained in:
74
vendor/tailscale.com/safesocket/pipe_windows.go
generated
vendored
74
vendor/tailscale.com/safesocket/pipe_windows.go
generated
vendored
@@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/tailscale/go-winio"
|
||||
@@ -49,7 +50,9 @@ func listen(path string) (net.Listener, error) {
|
||||
// embedded net.Conn must be a go-winio PipeConn.
|
||||
type WindowsClientConn struct {
|
||||
winioPipeConn
|
||||
token windows.Token
|
||||
tokenOnce sync.Once
|
||||
token windows.Token // or zero, if we couldn't obtain the client's token
|
||||
tokenErr error
|
||||
}
|
||||
|
||||
// winioPipeConn is a subset of the interface implemented by the go-winio's
|
||||
@@ -79,12 +82,63 @@ func (conn *WindowsClientConn) ClientPID() (int, error) {
|
||||
return int(pid), nil
|
||||
}
|
||||
|
||||
// Token returns the Windows access token of the client user.
|
||||
func (conn *WindowsClientConn) Token() windows.Token {
|
||||
return conn.token
|
||||
// CheckToken returns an error if the client user's access token could not be retrieved,
|
||||
// for example when the client opens the pipe with an anonymous impersonation level.
|
||||
//
|
||||
// Deprecated: use [WindowsClientConn.Token] instead.
|
||||
func (conn *WindowsClientConn) CheckToken() error {
|
||||
_, err := conn.getToken()
|
||||
return err
|
||||
}
|
||||
|
||||
// getToken returns the Windows access token of the client user,
|
||||
// or an error if the token could not be retrieved, for example
|
||||
// when the client opens the pipe with an anonymous impersonation level.
|
||||
//
|
||||
// The connection retains ownership of the returned token handle;
|
||||
// the caller must not close it.
|
||||
//
|
||||
// TODO(nickkhyl): Remove this, along with [WindowsClientConn.CheckToken],
|
||||
// once [ipnauth.ConnIdentity] is removed in favor of [ipnauth.Actor].
|
||||
func (conn *WindowsClientConn) getToken() (windows.Token, error) {
|
||||
conn.tokenOnce.Do(func() {
|
||||
conn.token, conn.tokenErr = clientUserAccessToken(conn.winioPipeConn)
|
||||
})
|
||||
return conn.token, conn.tokenErr
|
||||
}
|
||||
|
||||
// Token returns the Windows access token of the client user,
|
||||
// or an error if the token could not be retrieved, for example
|
||||
// when the client opens the pipe with an anonymous impersonation level.
|
||||
//
|
||||
// The caller is responsible for closing the returned token handle.
|
||||
func (conn *WindowsClientConn) Token() (windows.Token, error) {
|
||||
token, err := conn.getToken()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var dupToken windows.Handle
|
||||
if err := windows.DuplicateHandle(
|
||||
windows.CurrentProcess(),
|
||||
windows.Handle(token),
|
||||
windows.CurrentProcess(),
|
||||
&dupToken,
|
||||
0,
|
||||
false,
|
||||
windows.DUPLICATE_SAME_ACCESS,
|
||||
); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return windows.Token(dupToken), nil
|
||||
}
|
||||
|
||||
func (conn *WindowsClientConn) Close() error {
|
||||
// Either wait for any pending [WindowsClientConn.Token] calls to complete,
|
||||
// or ensure that the token will never be opened.
|
||||
conn.tokenOnce.Do(func() {
|
||||
conn.tokenErr = net.ErrClosed
|
||||
})
|
||||
if conn.token != 0 {
|
||||
conn.token.Close()
|
||||
conn.token = 0
|
||||
@@ -110,17 +164,7 @@ func (lw *winIOPipeListener) Accept() (net.Conn, error) {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("unexpected type %T from winio.ListenPipe listener (itself a %T)", conn, lw.Listener)
|
||||
}
|
||||
|
||||
token, err := clientUserAccessToken(pipeConn)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &WindowsClientConn{
|
||||
winioPipeConn: pipeConn,
|
||||
token: token,
|
||||
}, nil
|
||||
return &WindowsClientConn{winioPipeConn: pipeConn}, nil
|
||||
}
|
||||
|
||||
func clientUserAccessToken(pc winioPipeConn) (windows.Token, error) {
|
||||
|
||||
16
vendor/tailscale.com/safesocket/safesocket.go
generated
vendored
16
vendor/tailscale.com/safesocket/safesocket.go
generated
vendored
@@ -11,6 +11,9 @@ import (
|
||||
"net"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"tailscale.com/feature"
|
||||
"tailscale.com/feature/buildfeatures"
|
||||
)
|
||||
|
||||
type closeable interface {
|
||||
@@ -31,7 +34,8 @@ func ConnCloseWrite(c net.Conn) error {
|
||||
}
|
||||
|
||||
var processStartTime = time.Now()
|
||||
var tailscaledProcExists = func() bool { return false } // set by safesocket_ps.go
|
||||
|
||||
var tailscaledProcExists feature.Hook[func() bool]
|
||||
|
||||
// tailscaledStillStarting reports whether tailscaled is probably
|
||||
// still starting up. That is, it reports whether the caller should
|
||||
@@ -50,7 +54,8 @@ func tailscaledStillStarting() bool {
|
||||
if d > 5*time.Second {
|
||||
return false
|
||||
}
|
||||
return tailscaledProcExists()
|
||||
f, ok := tailscaledProcExists.GetOk()
|
||||
return ok && f()
|
||||
}
|
||||
|
||||
// ConnectContext connects to tailscaled using a unix socket or named pipe.
|
||||
@@ -104,7 +109,12 @@ func LocalTCPPortAndToken() (port int, token string, err error) {
|
||||
|
||||
// PlatformUsesPeerCreds reports whether the current platform uses peer credentials
|
||||
// to authenticate connections.
|
||||
func PlatformUsesPeerCreds() bool { return GOOSUsesPeerCreds(runtime.GOOS) }
|
||||
func PlatformUsesPeerCreds() bool {
|
||||
if !buildfeatures.HasUnixSocketIdentity {
|
||||
return false
|
||||
}
|
||||
return GOOSUsesPeerCreds(runtime.GOOS)
|
||||
}
|
||||
|
||||
// GOOSUsesPeerCreds is like PlatformUsesPeerCreds but takes a
|
||||
// runtime.GOOS value instead of using the current one.
|
||||
|
||||
110
vendor/tailscale.com/safesocket/safesocket_plan9.go
generated
vendored
110
vendor/tailscale.com/safesocket/safesocket_plan9.go
generated
vendored
@@ -7,119 +7,13 @@ package safesocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/plan9"
|
||||
)
|
||||
|
||||
// Plan 9's devsrv srv(3) is a server registry and
|
||||
// it is conventionally bound to "/srv" in the default
|
||||
// namespace. It is "a one level directory for holding
|
||||
// already open channels to services". Post one end of
|
||||
// a pipe to "/srv/tailscale.sock" and use the other
|
||||
// end for communication with a requestor. Plan 9 pipes
|
||||
// are bidirectional.
|
||||
|
||||
type plan9SrvAddr string
|
||||
|
||||
func (sl plan9SrvAddr) Network() string {
|
||||
return "/srv"
|
||||
}
|
||||
|
||||
func (sl plan9SrvAddr) String() string {
|
||||
return string(sl)
|
||||
}
|
||||
|
||||
// There is no net.FileListener for Plan 9 at this time
|
||||
type plan9SrvListener struct {
|
||||
name string
|
||||
srvf *os.File
|
||||
file *os.File
|
||||
}
|
||||
|
||||
func (sl *plan9SrvListener) Accept() (net.Conn, error) {
|
||||
// sl.file is the server end of the pipe that's
|
||||
// connected to /srv/tailscale.sock
|
||||
return plan9FileConn{name: sl.name, file: sl.file}, nil
|
||||
}
|
||||
|
||||
func (sl *plan9SrvListener) Close() error {
|
||||
sl.file.Close()
|
||||
return sl.srvf.Close()
|
||||
}
|
||||
|
||||
func (sl *plan9SrvListener) Addr() net.Addr {
|
||||
return plan9SrvAddr(sl.name)
|
||||
}
|
||||
|
||||
type plan9FileConn struct {
|
||||
name string
|
||||
file *os.File
|
||||
}
|
||||
|
||||
func (fc plan9FileConn) Read(b []byte) (n int, err error) {
|
||||
return fc.file.Read(b)
|
||||
}
|
||||
func (fc plan9FileConn) Write(b []byte) (n int, err error) {
|
||||
return fc.file.Write(b)
|
||||
}
|
||||
func (fc plan9FileConn) Close() error {
|
||||
return fc.file.Close()
|
||||
}
|
||||
func (fc plan9FileConn) LocalAddr() net.Addr {
|
||||
return plan9SrvAddr(fc.name)
|
||||
}
|
||||
func (fc plan9FileConn) RemoteAddr() net.Addr {
|
||||
return plan9SrvAddr(fc.name)
|
||||
}
|
||||
func (fc plan9FileConn) SetDeadline(t time.Time) error {
|
||||
return syscall.EPLAN9
|
||||
}
|
||||
func (fc plan9FileConn) SetReadDeadline(t time.Time) error {
|
||||
return syscall.EPLAN9
|
||||
}
|
||||
func (fc plan9FileConn) SetWriteDeadline(t time.Time) error {
|
||||
return syscall.EPLAN9
|
||||
}
|
||||
|
||||
func connect(_ context.Context, path string) (net.Conn, error) {
|
||||
f, err := os.OpenFile(path, os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plan9FileConn{name: path, file: f}, nil
|
||||
return net.Dial("tcp", "localhost:5252")
|
||||
}
|
||||
|
||||
// Create an entry in /srv, open a pipe, write the
|
||||
// client end to the entry and return the server
|
||||
// end of the pipe to the caller. When the server
|
||||
// end of the pipe is closed, /srv name associated
|
||||
// with it will be removed (controlled by ORCLOSE flag)
|
||||
func listen(path string) (net.Listener, error) {
|
||||
const O_RCLOSE = 64 // remove on close; should be in plan9 package
|
||||
var pip [2]int
|
||||
|
||||
err := plan9.Pipe(pip[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer plan9.Close(pip[1])
|
||||
|
||||
srvfd, err := plan9.Create(path, plan9.O_WRONLY|plan9.O_CLOEXEC|O_RCLOSE, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srv := os.NewFile(uintptr(srvfd), path)
|
||||
|
||||
_, err = fmt.Fprintf(srv, "%d", pip[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &plan9SrvListener{name: path, srvf: srv, file: os.NewFile(uintptr(pip[0]), path)}, nil
|
||||
return net.Listen("tcp", "localhost:5252")
|
||||
}
|
||||
|
||||
6
vendor/tailscale.com/safesocket/safesocket_ps.go
generated
vendored
6
vendor/tailscale.com/safesocket/safesocket_ps.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build linux || windows || (darwin && !ios) || freebsd
|
||||
//go:build ((linux && !android) || windows || (darwin && !ios) || freebsd) && !ts_omit_cliconndiag
|
||||
|
||||
package safesocket
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
tailscaledProcExists = func() bool {
|
||||
tailscaledProcExists.Set(func() bool {
|
||||
procs, err := ps.Processes()
|
||||
if err != nil {
|
||||
return false
|
||||
@@ -30,5 +30,5 @@ func init() {
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user