From a91fcc88138cceb4f891f5338f2b28d80bb81b9c Mon Sep 17 00:00:00 2001 From: Anton Tolchanov Date: Wed, 18 Jun 2025 11:38:18 +0100 Subject: [PATCH] ipn/ipnlocal: make pricing restriction message for Tailnet Lock clearer Fixes tailscale/corp#24417 Signed-off-by: Anton Tolchanov --- ipn/ipnlocal/network-lock.go | 15 +++++++++------ ipn/localapi/localapi.go | 5 +++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ipn/ipnlocal/network-lock.go b/ipn/ipnlocal/network-lock.go index 36d39a465..10f0cc827 100644 --- a/ipn/ipnlocal/network-lock.go +++ b/ipn/ipnlocal/network-lock.go @@ -600,18 +600,14 @@ func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byt var ourNodeKey key.NodePublic var nlPriv key.NLPrivate - b.mu.Lock() - - if !b.capTailnetLock { - b.mu.Unlock() - return errors.New("not permitted to enable tailnet lock") - } + b.mu.Lock() if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() { ourNodeKey = p.Persist().PublicNodeKey() nlPriv = p.Persist().NetworkLockKey() } b.mu.Unlock() + if ourNodeKey.IsZero() || nlPriv.IsZero() { return errors.New("no node-key: is tailscale logged in?") } @@ -671,6 +667,13 @@ func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byt return err } +// NetworkLockAllowed reports whether the node is allowed to use Tailnet Lock. +func (b *LocalBackend) NetworkLockAllowed() bool { + b.mu.Lock() + defer b.mu.Unlock() + return b.capTailnetLock +} + // Only use is in tests. func (b *LocalBackend) NetworkLockVerifySignatureForTest(nks tkatype.MarshaledSignature, nodeKey key.NodePublic) error { b.mu.Lock() diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go index 6344da42d..a90ae5d84 100644 --- a/ipn/localapi/localapi.go +++ b/ipn/localapi/localapi.go @@ -1970,6 +1970,11 @@ func (h *Handler) serveTKAInit(w http.ResponseWriter, r *http.Request) { return } + if !h.b.NetworkLockAllowed() { + http.Error(w, "Tailnet Lock is not supported on your pricing plan", http.StatusForbidden) + return + } + if err := h.b.NetworkLockInit(req.Keys, req.DisablementValues, req.SupportDisablement); err != nil { http.Error(w, "initialization failed: "+err.Error(), http.StatusInternalServerError) return