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") - } - 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