mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-29 04:22:24 +00:00
ipn: don't Logout when Windows GUI disconnects
Logout used to be a no-op, so the ipnserver previously synthensized a Logout on disconnect. Now that Logout actually invalidates the node key that was forcing all GUI closes to log people out. Instead, add a method to LocalBackend to specifically mean "the Windows GUI closed, please forget all the state". Fixes tailscale/corp#1591 (ignoring the notification issues, tracked elsewhere) Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
158328ba24
commit
f99e63bb17
@ -298,7 +298,7 @@ func run() error {
|
|||||||
Port: 41112,
|
Port: 41112,
|
||||||
StatePath: args.statepath,
|
StatePath: args.statepath,
|
||||||
AutostartStateKey: globalStateKey,
|
AutostartStateKey: globalStateKey,
|
||||||
SurviveDisconnects: true,
|
SurviveDisconnects: runtime.GOOS != "windows",
|
||||||
DebugMux: debugMux,
|
DebugMux: debugMux,
|
||||||
}
|
}
|
||||||
err = ipnserver.Run(ctx, logf, pol.PublicID.String(), ipnserver.FixedEngine(e), opts)
|
err = ipnserver.Run(ctx, logf, pol.PublicID.String(), ipnserver.FixedEngine(e), opts)
|
||||||
|
@ -2082,6 +2082,30 @@ func (b *LocalBackend) requestEngineStatusAndWait() {
|
|||||||
b.statusLock.Unlock()
|
b.statusLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResetForClientDisconnect resets the backend for GUI clients running
|
||||||
|
// in interactive (non-headless) mode. This is currently used only by
|
||||||
|
// Windows. This causes all state to be cleared, lest an unrelated user
|
||||||
|
// connect to tailscaled next. But it does not trigger a logout; we
|
||||||
|
// don't want to the user to have to reauthenticate in the future
|
||||||
|
// when they restart the GUI.
|
||||||
|
func (b *LocalBackend) ResetForClientDisconnect() {
|
||||||
|
defer b.enterState(ipn.Stopped)
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
b.logf("LocalBackend.ResetForClientDisconnect")
|
||||||
|
|
||||||
|
if b.cc != nil {
|
||||||
|
go b.cc.Shutdown()
|
||||||
|
b.cc = nil
|
||||||
|
}
|
||||||
|
b.stateKey = ""
|
||||||
|
b.userID = ""
|
||||||
|
b.setNetMapLocked(nil)
|
||||||
|
b.prefs = new(ipn.Prefs)
|
||||||
|
b.authURL = ""
|
||||||
|
b.activeLogin = ""
|
||||||
|
}
|
||||||
|
|
||||||
// Logout tells the controlclient that we want to log out, and
|
// Logout tells the controlclient that we want to log out, and
|
||||||
// transitions the local engine to the logged-out state without
|
// transitions the local engine to the logged-out state without
|
||||||
// waiting for controlclient to be in that state.
|
// waiting for controlclient to be in that state.
|
||||||
@ -2105,7 +2129,7 @@ func (b *LocalBackend) logout(ctx context.Context, sync bool) error {
|
|||||||
|
|
||||||
b.EditPrefs(&ipn.MaskedPrefs{
|
b.EditPrefs(&ipn.MaskedPrefs{
|
||||||
WantRunningSet: true,
|
WantRunningSet: true,
|
||||||
Prefs: ipn.Prefs{WantRunning: true},
|
Prefs: ipn.Prefs{WantRunning: false},
|
||||||
})
|
})
|
||||||
|
|
||||||
if cc == nil {
|
if cc == nil {
|
||||||
|
@ -476,9 +476,7 @@ func (s *server) addConn(c net.Conn, isHTTP bool) (ci connIdentity, err error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if doReset {
|
if doReset {
|
||||||
s.logf("identity changed; resetting server")
|
s.logf("identity changed; resetting server")
|
||||||
s.bsMu.Lock()
|
s.b.ResetForClientDisconnect()
|
||||||
s.bs.Reset(context.TODO())
|
|
||||||
s.bsMu.Unlock()
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -528,9 +526,7 @@ func (s *server) removeAndCloseConn(c net.Conn) {
|
|||||||
s.logf("client disconnected; staying alive in server mode")
|
s.logf("client disconnected; staying alive in server mode")
|
||||||
} else {
|
} else {
|
||||||
s.logf("client disconnected; stopping server")
|
s.logf("client disconnected; stopping server")
|
||||||
s.bsMu.Lock()
|
s.b.ResetForClientDisconnect()
|
||||||
s.bs.Reset(context.TODO())
|
|
||||||
s.bsMu.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.Close()
|
c.Close()
|
||||||
|
@ -143,11 +143,6 @@ func (bs *BackendServer) GotCommandMsg(ctx context.Context, b []byte) error {
|
|||||||
return bs.GotCommand(ctx, cmd)
|
return bs.GotCommand(ctx, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BackendServer) GotFakeCommand(ctx context.Context, cmd *Command) error {
|
|
||||||
cmd.Version = version.Long
|
|
||||||
return bs.GotCommand(ctx, cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrMsgPermissionDenied is the Notify.ErrMessage value used an
|
// ErrMsgPermissionDenied is the Notify.ErrMessage value used an
|
||||||
// operation was done from a user/context that didn't have permission.
|
// operation was done from a user/context that didn't have permission.
|
||||||
const ErrMsgPermissionDenied = "permission denied"
|
const ErrMsgPermissionDenied = "permission denied"
|
||||||
@ -211,12 +206,6 @@ func (bs *BackendServer) GotCommand(ctx context.Context, cmd *Command) error {
|
|||||||
return fmt.Errorf("BackendServer.Do: no command specified")
|
return fmt.Errorf("BackendServer.Do: no command specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BackendServer) Reset(ctx context.Context) error {
|
|
||||||
// Tell the backend we got a Logout command, which will cause it
|
|
||||||
// to forget all its authentication information.
|
|
||||||
return bs.GotFakeCommand(ctx, &Command{Logout: &NoArgs{}})
|
|
||||||
}
|
|
||||||
|
|
||||||
type BackendClient struct {
|
type BackendClient struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
sendCommandMsg func(jsonb []byte)
|
sendCommandMsg func(jsonb []byte)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user