mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-10 00:51:07 +00:00
safesocket: make clear which net.Conns are winio types
Follow-up to earlier #9049. Updates #9049 Change-Id: I121fbd2468770233a23ab5ee3df42698ca1dabc2 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
95671b71a6
commit
b4be4f089f
@@ -57,27 +57,26 @@ func listen(path string) (net.Listener, error) {
|
||||
// the Windows access token associated with the connection's client. The
|
||||
// embedded net.Conn must be a go-winio PipeConn.
|
||||
type WindowsClientConn struct {
|
||||
net.Conn
|
||||
winioPipeConn
|
||||
token windows.Token
|
||||
}
|
||||
|
||||
// winioPipeHandle is fulfilled by the underlying code implementing go-winio's
|
||||
// PipeConn interface.
|
||||
type winioPipeHandle interface {
|
||||
// winioPipeConn is a subset of the interface implemented by the go-winio's
|
||||
// unexported *win32pipe type, as returned by go-winio's ListenPipe
|
||||
// net.Listener's Accept method. This type is used in places where we really are
|
||||
// assuming that specific unexported type and its Fd method.
|
||||
type winioPipeConn interface {
|
||||
net.Conn
|
||||
// Fd returns the Windows handle associated with the connection.
|
||||
Fd() uintptr
|
||||
}
|
||||
|
||||
func resolvePipeHandle(c net.Conn) windows.Handle {
|
||||
wph, ok := c.(winioPipeHandle)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return windows.Handle(wph.Fd())
|
||||
func resolvePipeHandle(pc winioPipeConn) windows.Handle {
|
||||
return windows.Handle(pc.Fd())
|
||||
}
|
||||
|
||||
func (conn *WindowsClientConn) handle() windows.Handle {
|
||||
return resolvePipeHandle(conn.Conn)
|
||||
return resolvePipeHandle(conn.winioPipeConn)
|
||||
}
|
||||
|
||||
// ClientPID returns the pid of conn's client, or else an error.
|
||||
@@ -99,11 +98,14 @@ func (conn *WindowsClientConn) Close() error {
|
||||
conn.token.Close()
|
||||
conn.token = 0
|
||||
}
|
||||
return conn.Conn.Close()
|
||||
return conn.winioPipeConn.Close()
|
||||
}
|
||||
|
||||
// winIOPipeListener is a net.Listener that wraps a go-winio PipeListener and
|
||||
// returns net.Conn values of type *WindowsClientConn with the associated
|
||||
// windows.Token.
|
||||
type winIOPipeListener struct {
|
||||
net.Listener
|
||||
net.Listener // must be from winio.ListenPipe
|
||||
}
|
||||
|
||||
func (lw *winIOPipeListener) Accept() (net.Conn, error) {
|
||||
@@ -112,22 +114,28 @@ func (lw *winIOPipeListener) Accept() (net.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
token, err := clientUserAccessToken(conn)
|
||||
pipeConn, ok := conn.(winioPipeConn)
|
||||
if !ok {
|
||||
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{
|
||||
Conn: conn,
|
||||
token: token,
|
||||
winioPipeConn: pipeConn,
|
||||
token: token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func clientUserAccessToken(c net.Conn) (windows.Token, error) {
|
||||
h := resolvePipeHandle(c)
|
||||
func clientUserAccessToken(pc winioPipeConn) (windows.Token, error) {
|
||||
h := resolvePipeHandle(pc)
|
||||
if h == 0 {
|
||||
return 0, fmt.Errorf("not a windows handle: %T", c)
|
||||
return 0, fmt.Errorf("clientUserAccessToken failed to get handle from pipeConn %T", pc)
|
||||
}
|
||||
|
||||
// Impersonation touches thread-local state, so we need to lock until the
|
||||
|
Reference in New Issue
Block a user