mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-24 20:27:51 +00:00
ipn/localapi: only perform local-admin check in serveServeConfig (#10163)
On unix systems, the check involves executing sudo, which is slow. Instead of doing it for every incoming request, move the logic into localapi serveServeConfig handler and do it as needed. Updates tailscale/corp#15405 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
@@ -156,49 +156,17 @@ func TestWhoIsJustIP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShouldDenyServeConfigForGOOSAndUserContext(t *testing.T) {
|
||||
newHandler := func(connIsLocalAdmin bool) *Handler {
|
||||
return &Handler{testConnIsLocalAdmin: &connIsLocalAdmin}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
goos string
|
||||
configIn *ipn.ServeConfig
|
||||
h *Handler
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "linux",
|
||||
goos: "linux",
|
||||
configIn: &ipn.ServeConfig{},
|
||||
h: &Handler{CallerIsLocalAdmin: false},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "linux-path-handler-admin",
|
||||
goos: "linux",
|
||||
configIn: &ipn.ServeConfig{
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
||||
"foo.test.ts.net:443": {Handlers: map[string]*ipn.HTTPHandler{
|
||||
"/": {Path: "/tmp"},
|
||||
}},
|
||||
},
|
||||
},
|
||||
h: &Handler{CallerIsLocalAdmin: true},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "linux-path-handler-not-admin",
|
||||
goos: "linux",
|
||||
configIn: &ipn.ServeConfig{
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
||||
"foo.test.ts.net:443": {Handlers: map[string]*ipn.HTTPHandler{
|
||||
"/": {Path: "/tmp"},
|
||||
}},
|
||||
},
|
||||
},
|
||||
h: &Handler{CallerIsLocalAdmin: false},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "windows-not-path-handler",
|
||||
goos: "windows",
|
||||
name: "not-path-handler",
|
||||
configIn: &ipn.ServeConfig{
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
||||
"foo.test.ts.net:443": {Handlers: map[string]*ipn.HTTPHandler{
|
||||
@@ -206,12 +174,11 @@ func TestShouldDenyServeConfigForGOOSAndUserContext(t *testing.T) {
|
||||
}},
|
||||
},
|
||||
},
|
||||
h: &Handler{CallerIsLocalAdmin: false},
|
||||
h: newHandler(false),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "windows-path-handler-admin",
|
||||
goos: "windows",
|
||||
name: "path-handler-admin",
|
||||
configIn: &ipn.ServeConfig{
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
||||
"foo.test.ts.net:443": {Handlers: map[string]*ipn.HTTPHandler{
|
||||
@@ -219,12 +186,11 @@ func TestShouldDenyServeConfigForGOOSAndUserContext(t *testing.T) {
|
||||
}},
|
||||
},
|
||||
},
|
||||
h: &Handler{CallerIsLocalAdmin: true},
|
||||
h: newHandler(true),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "windows-path-handler-not-admin",
|
||||
goos: "windows",
|
||||
name: "path-handler-not-admin",
|
||||
configIn: &ipn.ServeConfig{
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
||||
"foo.test.ts.net:443": {Handlers: map[string]*ipn.HTTPHandler{
|
||||
@@ -232,20 +198,36 @@ func TestShouldDenyServeConfigForGOOSAndUserContext(t *testing.T) {
|
||||
}},
|
||||
},
|
||||
},
|
||||
h: &Handler{CallerIsLocalAdmin: false},
|
||||
h: newHandler(false),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := authorizeServeConfigForGOOSAndUserContext(tt.goos, tt.configIn, tt.h)
|
||||
gotErr := err != nil
|
||||
if gotErr != tt.wantErr {
|
||||
t.Errorf("authorizeServeConfigForGOOSAndUserContext() got error = %v, want error %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
for _, goos := range []string{"linux", "windows", "darwin"} {
|
||||
t.Run(goos+"-"+tt.name, func(t *testing.T) {
|
||||
err := authorizeServeConfigForGOOSAndUserContext(goos, tt.configIn, tt.h)
|
||||
gotErr := err != nil
|
||||
if gotErr != tt.wantErr {
|
||||
t.Errorf("authorizeServeConfigForGOOSAndUserContext() got error = %v, want error %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
t.Run("other-goos", func(t *testing.T) {
|
||||
configIn := &ipn.ServeConfig{
|
||||
Web: map[ipn.HostPort]*ipn.WebServerConfig{
|
||||
"foo.test.ts.net:443": {Handlers: map[string]*ipn.HTTPHandler{
|
||||
"/": {Path: "/tmp"},
|
||||
}},
|
||||
},
|
||||
}
|
||||
h := newHandler(false)
|
||||
err := authorizeServeConfigForGOOSAndUserContext("dos", configIn, h)
|
||||
if err != nil {
|
||||
t.Errorf("authorizeServeConfigForGOOSAndUserContext() got error = %v, want nil", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestServeWatchIPNBus(t *testing.T) {
|
||||
|
Reference in New Issue
Block a user