mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-14 23:17:29 +00:00
cmd/tailscale/cli,ipn/ipnlocal: restrict logout when AlwaysOn mode is enabled
In this PR, we start passing a LocalAPI actor to (*LocalBackend).Logout to make it subject to the same access check as disconnects made via tailscale down or the GUI. We then update the CLI to allow `tailscale logout` to accept a reason, similar to `tailscale down`. Updates tailscale/corp#26249 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
@@ -1077,7 +1077,7 @@ func (b *LocalBackend) Shutdown() {
|
||||
ctx, cancel := context.WithTimeout(b.ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
t0 := time.Now()
|
||||
err := b.Logout(ctx) // best effort
|
||||
err := b.Logout(ctx, ipnauth.Self) // best effort
|
||||
td := time.Since(t0).Round(time.Millisecond)
|
||||
if err != nil {
|
||||
b.logf("failed to log out ephemeral node on shutdown after %v: %v", td, err)
|
||||
@@ -5884,7 +5884,7 @@ func (b *LocalBackend) ShouldHandleViaIP(ip netip.Addr) bool {
|
||||
|
||||
// Logout logs out the current profile, if any, and waits for the logout to
|
||||
// complete.
|
||||
func (b *LocalBackend) Logout(ctx context.Context) error {
|
||||
func (b *LocalBackend) Logout(ctx context.Context, actor ipnauth.Actor) error {
|
||||
unlock := b.lockAndGetUnlock()
|
||||
defer unlock()
|
||||
|
||||
@@ -5898,11 +5898,8 @@ func (b *LocalBackend) Logout(ctx context.Context) error {
|
||||
// delete it later.
|
||||
profile := b.pm.CurrentProfile()
|
||||
|
||||
// TODO(nickkhyl): change [LocalBackend.Logout] to accept an [ipnauth.Actor].
|
||||
// This will allow enforcing Always On mode when a user tries to log out
|
||||
// while logged in and connected. See tailscale/corp#26249.
|
||||
_, err := b.editPrefsLockedOnEntry(
|
||||
ipnauth.TODO,
|
||||
actor,
|
||||
&ipn.MaskedPrefs{
|
||||
WantRunningSet: true,
|
||||
LoggedOutSet: true,
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"tailscale.com/control/controlclient"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnauth"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/ipn/store/mem"
|
||||
"tailscale.com/net/dns"
|
||||
@@ -607,7 +608,7 @@ func TestStateMachine(t *testing.T) {
|
||||
store.awaitWrite()
|
||||
t.Logf("\n\nLogout")
|
||||
notifies.expect(5)
|
||||
b.Logout(context.Background())
|
||||
b.Logout(context.Background(), ipnauth.Self)
|
||||
{
|
||||
nn := notifies.drain(5)
|
||||
previousCC.assertCalls("pause", "Logout", "unpause", "Shutdown")
|
||||
@@ -637,7 +638,7 @@ func TestStateMachine(t *testing.T) {
|
||||
// A second logout should be a no-op as we are in the NeedsLogin state.
|
||||
t.Logf("\n\nLogout2")
|
||||
notifies.expect(0)
|
||||
b.Logout(context.Background())
|
||||
b.Logout(context.Background(), ipnauth.Self)
|
||||
{
|
||||
notifies.drain(0)
|
||||
cc.assertCalls()
|
||||
@@ -650,7 +651,7 @@ func TestStateMachine(t *testing.T) {
|
||||
// AuthCantContinue state.
|
||||
t.Logf("\n\nLogout3")
|
||||
notifies.expect(3)
|
||||
b.Logout(context.Background())
|
||||
b.Logout(context.Background(), ipnauth.Self)
|
||||
{
|
||||
notifies.drain(0)
|
||||
cc.assertCalls()
|
||||
|
Reference in New Issue
Block a user