mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
all: use named pipes on windows
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
45042a76cd
commit
adc302f428
@ -2,6 +2,9 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
|
|||||||
|
|
||||||
filippo.io/edwards25519 from github.com/hdevalence/ed25519consensus
|
filippo.io/edwards25519 from github.com/hdevalence/ed25519consensus
|
||||||
filippo.io/edwards25519/field from filippo.io/edwards25519
|
filippo.io/edwards25519/field from filippo.io/edwards25519
|
||||||
|
W 💣 github.com/Microsoft/go-winio from tailscale.com/safesocket
|
||||||
|
W 💣 github.com/Microsoft/go-winio/internal/socket from github.com/Microsoft/go-winio
|
||||||
|
W github.com/Microsoft/go-winio/pkg/guid from github.com/Microsoft/go-winio+
|
||||||
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/internal/common+
|
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/internal/common+
|
||||||
W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate
|
W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate
|
||||||
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
|
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -27,6 +28,7 @@
|
|||||||
|
|
||||||
"github.com/peterbourgon/ff/v3/ffcli"
|
"github.com/peterbourgon/ff/v3/ffcli"
|
||||||
"golang.org/x/net/http/httpproxy"
|
"golang.org/x/net/http/httpproxy"
|
||||||
|
"tailscale.com/client/tailscale/apitype"
|
||||||
"tailscale.com/control/controlhttp"
|
"tailscale.com/control/controlhttp"
|
||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
@ -261,13 +263,42 @@ func runLocalCreds(ctx context.Context, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
printf("curl http://localhost:%v/localapi/v0/status\n", safesocket.WindowsLocalPort)
|
runLocalAPIProxy()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
printf("curl --unix-socket %s http://local-tailscaled.sock/localapi/v0/status\n", paths.DefaultTailscaledSocket())
|
printf("curl --unix-socket %s http://local-tailscaled.sock/localapi/v0/status\n", paths.DefaultTailscaledSocket())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type localClientRoundTripper struct{}
|
||||||
|
|
||||||
|
func (localClientRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
return localClient.DoLocalRequest(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runLocalAPIProxy() {
|
||||||
|
rp := httputil.NewSingleHostReverseProxy(&url.URL{
|
||||||
|
Scheme: "http",
|
||||||
|
Host: apitype.LocalAPIHost,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
dir := rp.Director
|
||||||
|
rp.Director = func(req *http.Request) {
|
||||||
|
dir(req)
|
||||||
|
req.Host = ""
|
||||||
|
req.RequestURI = ""
|
||||||
|
}
|
||||||
|
rp.Transport = localClientRoundTripper{}
|
||||||
|
lc, err := net.Listen("tcp", "localhost:0")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Serving LocalAPI proxy on http://%s\n", lc.Addr())
|
||||||
|
fmt.Printf("curl.exe http://%v/localapi/v0/status\n", lc.Addr())
|
||||||
|
fmt.Printf("Ctrl+C to stop")
|
||||||
|
http.Serve(lc, rp)
|
||||||
|
}
|
||||||
|
|
||||||
var prefsArgs struct {
|
var prefsArgs struct {
|
||||||
pretty bool
|
pretty bool
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
|
|
||||||
filippo.io/edwards25519 from github.com/hdevalence/ed25519consensus
|
filippo.io/edwards25519 from github.com/hdevalence/ed25519consensus
|
||||||
filippo.io/edwards25519/field from filippo.io/edwards25519
|
filippo.io/edwards25519/field from filippo.io/edwards25519
|
||||||
|
W 💣 github.com/Microsoft/go-winio from tailscale.com/safesocket
|
||||||
|
W 💣 github.com/Microsoft/go-winio/internal/socket from github.com/Microsoft/go-winio
|
||||||
|
W github.com/Microsoft/go-winio/pkg/guid from github.com/Microsoft/go-winio+
|
||||||
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/negotiate+
|
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/negotiate+
|
||||||
W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate
|
W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate
|
||||||
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
|
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
|
||||||
@ -220,7 +223,8 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
net/http from expvar+
|
net/http from expvar+
|
||||||
net/http/cgi from tailscale.com/cmd/tailscale/cli
|
net/http/cgi from tailscale.com/cmd/tailscale/cli
|
||||||
net/http/httptrace from github.com/tcnksm/go-httpstat+
|
net/http/httptrace from github.com/tcnksm/go-httpstat+
|
||||||
net/http/internal from net/http
|
net/http/httputil from tailscale.com/cmd/tailscale/cli
|
||||||
|
net/http/internal from net/http+
|
||||||
net/netip from net+
|
net/netip from net+
|
||||||
net/textproto from golang.org/x/net/http/httpguts+
|
net/textproto from golang.org/x/net/http/httpguts+
|
||||||
net/url from crypto/x509+
|
net/url from crypto/x509+
|
||||||
|
@ -2,6 +2,9 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
|
|
||||||
filippo.io/edwards25519 from github.com/hdevalence/ed25519consensus
|
filippo.io/edwards25519 from github.com/hdevalence/ed25519consensus
|
||||||
filippo.io/edwards25519/field from filippo.io/edwards25519
|
filippo.io/edwards25519/field from filippo.io/edwards25519
|
||||||
|
W 💣 github.com/Microsoft/go-winio from tailscale.com/safesocket
|
||||||
|
W 💣 github.com/Microsoft/go-winio/internal/socket from github.com/Microsoft/go-winio
|
||||||
|
W github.com/Microsoft/go-winio/pkg/guid from github.com/Microsoft/go-winio+
|
||||||
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/internal/common+
|
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/internal/common+
|
||||||
W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate
|
W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate
|
||||||
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
|
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
|
||||||
@ -200,7 +203,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/health/healthmsg from tailscale.com/ipn/ipnlocal
|
tailscale.com/health/healthmsg from tailscale.com/ipn/ipnlocal
|
||||||
tailscale.com/hostinfo from tailscale.com/control/controlclient+
|
tailscale.com/hostinfo from tailscale.com/control/controlclient+
|
||||||
tailscale.com/ipn from tailscale.com/ipn/ipnlocal+
|
tailscale.com/ipn from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/ipn/ipnauth from tailscale.com/ipn/ipnserver+
|
💣 tailscale.com/ipn/ipnauth from tailscale.com/ipn/ipnserver+
|
||||||
tailscale.com/ipn/ipnlocal from tailscale.com/ssh/tailssh+
|
tailscale.com/ipn/ipnlocal from tailscale.com/ssh/tailssh+
|
||||||
tailscale.com/ipn/ipnserver from tailscale.com/cmd/tailscaled
|
tailscale.com/ipn/ipnserver from tailscale.com/cmd/tailscaled
|
||||||
tailscale.com/ipn/ipnstate from tailscale.com/control/controlclient+
|
tailscale.com/ipn/ipnstate from tailscale.com/control/controlclient+
|
||||||
@ -291,7 +294,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/util/mak from tailscale.com/control/controlclient+
|
tailscale.com/util/mak from tailscale.com/control/controlclient+
|
||||||
tailscale.com/util/multierr from tailscale.com/control/controlclient+
|
tailscale.com/util/multierr from tailscale.com/control/controlclient+
|
||||||
tailscale.com/util/osshare from tailscale.com/ipn/ipnlocal+
|
tailscale.com/util/osshare from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/util/pidowner from tailscale.com/ipn/ipnauth
|
W tailscale.com/util/pidowner from tailscale.com/ipn/ipnauth
|
||||||
tailscale.com/util/racebuild from tailscale.com/logpolicy
|
tailscale.com/util/racebuild from tailscale.com/logpolicy
|
||||||
tailscale.com/util/set from tailscale.com/health+
|
tailscale.com/util/set from tailscale.com/health+
|
||||||
tailscale.com/util/singleflight from tailscale.com/control/controlclient+
|
tailscale.com/util/singleflight from tailscale.com/control/controlclient+
|
||||||
|
4
go.mod
4
go.mod
@ -4,6 +4,7 @@ go 1.19
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/mkcert v1.4.3
|
filippo.io/mkcert v1.4.3
|
||||||
|
github.com/Microsoft/go-winio v0.6.0
|
||||||
github.com/akutz/memconn v0.1.0
|
github.com/akutz/memconn v0.1.0
|
||||||
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74
|
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74
|
||||||
github.com/andybalholm/brotli v1.0.3
|
github.com/andybalholm/brotli v1.0.3
|
||||||
@ -71,7 +72,7 @@ require (
|
|||||||
golang.org/x/term v0.1.0
|
golang.org/x/term v0.1.0
|
||||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11
|
||||||
golang.org/x/tools v0.1.12
|
golang.org/x/tools v0.1.12
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20220904105730-b51010ba13f0
|
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c
|
||||||
golang.zx2c4.com/wireguard/windows v0.5.3
|
golang.zx2c4.com/wireguard/windows v0.5.3
|
||||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5
|
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5
|
||||||
honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238
|
honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238
|
||||||
@ -92,7 +93,6 @@ require (
|
|||||||
github.com/Masterminds/semver v1.5.0 // indirect
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
|
||||||
github.com/OpenPeeDeeP/depguard v1.0.1 // indirect
|
github.com/OpenPeeDeeP/depguard v1.0.1 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20211112122917-428f8eabeeb3 // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20211112122917-428f8eabeeb3 // indirect
|
||||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||||
|
8
go.sum
8
go.sum
@ -84,8 +84,8 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB
|
|||||||
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us=
|
github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us=
|
||||||
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
|
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
|
||||||
@ -1656,8 +1656,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20220904105730-b51010ba13f0 h1:5ZkdpbduT/g+9OtbSDvbF3KvfQG45CtH/ppO8FUmvCQ=
|
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c h1:Okh6a1xpnJslG9Mn84pId1Mn+Q8cvpo4HCeeFWHo0cA=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20220904105730-b51010ba13f0/go.mod h1:enML0deDxY1ux+B6ANGiwtg0yAJi1rctkTpcHNAVPyg=
|
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c/go.mod h1:enML0deDxY1ux+B6ANGiwtg0yAJi1rctkTpcHNAVPyg=
|
||||||
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
|
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
|
||||||
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
|
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
package ipnauth
|
package ipnauth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
@ -23,7 +22,6 @@
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
"tailscale.com/util/groupmember"
|
"tailscale.com/util/groupmember"
|
||||||
"tailscale.com/util/pidowner"
|
|
||||||
"tailscale.com/util/winutil"
|
"tailscale.com/util/winutil"
|
||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
)
|
)
|
||||||
@ -73,55 +71,6 @@ func (ci *ConnIdentity) Pid() int { return ci.pid }
|
|||||||
func (ci *ConnIdentity) IsUnixSock() bool { return ci.isUnixSock }
|
func (ci *ConnIdentity) IsUnixSock() bool { return ci.isUnixSock }
|
||||||
func (ci *ConnIdentity) Creds() *peercred.Creds { return ci.creds }
|
func (ci *ConnIdentity) Creds() *peercred.Creds { return ci.creds }
|
||||||
|
|
||||||
// GetConnIdentity returns the localhost TCP connection's identity information
|
|
||||||
// (pid, userid, user). If it's not Windows (for now), it returns a nil error
|
|
||||||
// and a ConnIdentity with NotWindows set true. It's only an error if we expected
|
|
||||||
// to be able to map it and couldn't.
|
|
||||||
func GetConnIdentity(logf logger.Logf, c net.Conn) (ci *ConnIdentity, err error) {
|
|
||||||
ci = &ConnIdentity{conn: c}
|
|
||||||
if runtime.GOOS != "windows" { // for now; TODO: expand to other OSes
|
|
||||||
ci.notWindows = true
|
|
||||||
_, ci.isUnixSock = c.(*net.UnixConn)
|
|
||||||
ci.creds, _ = peercred.Get(c)
|
|
||||||
return ci, nil
|
|
||||||
}
|
|
||||||
la, err := netip.ParseAddrPort(c.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
return ci, fmt.Errorf("parsing local address: %w", err)
|
|
||||||
}
|
|
||||||
ra, err := netip.ParseAddrPort(c.RemoteAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
return ci, fmt.Errorf("parsing local remote: %w", err)
|
|
||||||
}
|
|
||||||
if !la.Addr().IsLoopback() || !ra.Addr().IsLoopback() {
|
|
||||||
return ci, errors.New("non-loopback connection")
|
|
||||||
}
|
|
||||||
tab, err := netstat.Get()
|
|
||||||
if err != nil {
|
|
||||||
return ci, fmt.Errorf("failed to get local connection table: %w", err)
|
|
||||||
}
|
|
||||||
pid := peerPid(tab.Entries, la, ra)
|
|
||||||
if pid == 0 {
|
|
||||||
return ci, errors.New("no local process found matching localhost connection")
|
|
||||||
}
|
|
||||||
ci.pid = pid
|
|
||||||
uid, err := pidowner.OwnerOfPID(pid)
|
|
||||||
if err != nil {
|
|
||||||
var hint string
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
hint = " (WSL?)"
|
|
||||||
}
|
|
||||||
return ci, fmt.Errorf("failed to map connection's pid to a user%s: %w", hint, err)
|
|
||||||
}
|
|
||||||
ci.userID = ipn.WindowsUserID(uid)
|
|
||||||
u, err := LookupUserFromID(logf, uid)
|
|
||||||
if err != nil {
|
|
||||||
return ci, fmt.Errorf("failed to look up user from userid: %w", err)
|
|
||||||
}
|
|
||||||
ci.user = u
|
|
||||||
return ci, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var metricIssue869Workaround = clientmetric.NewCounter("issue_869_workaround")
|
var metricIssue869Workaround = clientmetric.NewCounter("issue_869_workaround")
|
||||||
|
|
||||||
// LookupUserFromID is a wrapper around os/user.LookupId that works around some
|
// LookupUserFromID is a wrapper around os/user.LookupId that works around some
|
||||||
|
24
ipn/ipnauth/ipnauth_notwindows.go
Normal file
24
ipn/ipnauth/ipnauth_notwindows.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) 2022 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.
|
||||||
|
|
||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package ipnauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"inet.af/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)
|
||||||
|
ci.creds, _ = peercred.Get(c)
|
||||||
|
return ci, nil
|
||||||
|
}
|
59
ipn/ipnauth/ipnauth_windows.go
Normal file
59
ipn/ipnauth/ipnauth_windows.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (c) 2022 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.
|
||||||
|
|
||||||
|
package ipnauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
"tailscale.com/ipn"
|
||||||
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/util/pidowner"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
procGetNamedPipeClientProcessId = kernel32.NewProc("GetNamedPipeClientProcessId")
|
||||||
|
)
|
||||||
|
|
||||||
|
func getNamedPipeClientProcessId(h windows.Handle) (pid uint32, err error) {
|
||||||
|
r1, _, err := procGetNamedPipeClientProcessId.Call(uintptr(h), uintptr(unsafe.Pointer(&pid)))
|
||||||
|
if r1 > 0 {
|
||||||
|
return pid, nil
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConnIdentity extracts the identity information from the connection
|
||||||
|
// based on the user who owns the other end of the connection.
|
||||||
|
// If c is not backed by a named pipe, an error is returned.
|
||||||
|
func GetConnIdentity(logf logger.Logf, c net.Conn) (ci *ConnIdentity, err error) {
|
||||||
|
ci = &ConnIdentity{conn: c}
|
||||||
|
h, ok := c.(interface {
|
||||||
|
Fd() uintptr
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return ci, fmt.Errorf("not a windows handle: %T", c)
|
||||||
|
}
|
||||||
|
pid, err := getNamedPipeClientProcessId(windows.Handle(h.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
return ci, fmt.Errorf("getNamedPipeClientProcessId: %v", err)
|
||||||
|
}
|
||||||
|
ci.pid = int(pid)
|
||||||
|
uid, err := pidowner.OwnerOfPID(ci.pid)
|
||||||
|
if err != nil {
|
||||||
|
return ci, fmt.Errorf("failed to map connection's pid to a user (WSL?): %w", err)
|
||||||
|
}
|
||||||
|
ci.userID = ipn.WindowsUserID(uid)
|
||||||
|
u, err := LookupUserFromID(logf, uid)
|
||||||
|
if err != nil {
|
||||||
|
return ci, fmt.Errorf("failed to look up user from userid: %w", err)
|
||||||
|
}
|
||||||
|
ci.user = u
|
||||||
|
return ci, nil
|
||||||
|
}
|
@ -23,7 +23,7 @@
|
|||||||
// or the empty string if there's no reasonable default.
|
// or the empty string if there's no reasonable default.
|
||||||
func DefaultTailscaledSocket() string {
|
func DefaultTailscaledSocket() string {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
return ""
|
return `\\.\pipe\ProtectedPrefix\Administrators\Tailscale\tailscaled`
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
return "/var/run/tailscaled.socket"
|
return "/var/run/tailscaled.socket"
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,7 +15,12 @@ func TestBasics(t *testing.T) {
|
|||||||
// Make the socket in a temp dir rather than the cwd
|
// Make the socket in a temp dir rather than the cwd
|
||||||
// so that the test can be run from a mounted filesystem (#2367).
|
// so that the test can be run from a mounted filesystem (#2367).
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
sock := filepath.Join(dir, "test")
|
var sock string
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
sock = filepath.Join(dir, "test")
|
||||||
|
} else {
|
||||||
|
sock = fmt.Sprintf(`\\.\pipe\tailscale-test`)
|
||||||
|
}
|
||||||
|
|
||||||
l, port, err := Listen(sock, 0)
|
l, port, err := Listen(sock, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -5,18 +5,15 @@
|
|||||||
package safesocket
|
package safesocket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/Microsoft/go-winio"
|
||||||
)
|
)
|
||||||
|
|
||||||
func connect(s *ConnectionStrategy) (net.Conn, error) {
|
func connect(s *ConnectionStrategy) (net.Conn, error) {
|
||||||
pipe, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", s.port))
|
return winio.DialPipe(s.path, nil)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return pipe, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func setFlags(network, address string, c syscall.RawConn) error {
|
func setFlags(network, address string, c syscall.RawConn) error {
|
||||||
@ -26,20 +23,21 @@ func setFlags(network, address string, c syscall.RawConn) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(apenwarr): use named pipes instead of sockets?
|
// windowsSDDL is the Security Descriptor set on the namedpipe.
|
||||||
//
|
// It provides read/write access to all users and the local system.
|
||||||
// I tried to use winio.ListenPipe() here, but that code is a disaster,
|
const windowsSDDL = "O:BAG:BAD:PAI(A;OICI;GWGR;;;BU)(A;OICI;GWGR;;;SY)"
|
||||||
// built on top of an API that's a disaster. So for now we'll hack it by
|
|
||||||
// just always using a TCP session on a fixed port on localhost. As a
|
|
||||||
// result, on Windows we ignore the vendor and name strings.
|
|
||||||
// NOTE(bradfitz): Jason did a new pipe package: https://go-review.googlesource.com/c/sys/+/299009
|
|
||||||
func listen(path string, port uint16) (_ net.Listener, gotPort uint16, _ error) {
|
func listen(path string, port uint16) (_ net.Listener, gotPort uint16, _ error) {
|
||||||
lc := net.ListenConfig{
|
lc, err := winio.ListenPipe(
|
||||||
Control: setFlags,
|
path,
|
||||||
}
|
&winio.PipeConfig{
|
||||||
pipe, err := lc.Listen(context.Background(), "tcp", fmt.Sprintf("127.0.0.1:%d", port))
|
SecurityDescriptor: windowsSDDL,
|
||||||
|
InputBufferSize: 256 * 1024,
|
||||||
|
OutputBufferSize: 256 * 1024,
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, fmt.Errorf("namedpipe.Listen: %w", err)
|
||||||
}
|
}
|
||||||
return pipe, uint16(pipe.Addr().(*net.TCPAddr).Port), err
|
return lc, 0, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user