// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package persist contains the Persist type. package persist import ( "fmt" "reflect" "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/types/structs" ) //go:generate go run tailscale.com/cmd/viewer -type=Persist // Persist is the JSON type stored on disk on nodes to remember their // settings between runs. This is stored as part of ipn.Prefs and is // persisted per ipn.LoginProfile. type Persist struct { _ structs.Incomparable // LegacyFrontendPrivateMachineKey is here temporarily // (starting 2020-09-28) during migration of Windows users' // machine keys from frontend storage to the backend. On the // first LocalBackend.Start call, the backend will initialize // the real (backend-owned) machine key from the frontend's // provided value (if non-zero), picking a new random one if // needed. This field should be considered read-only from GUI // frontends. The real value should not be written back in // this field, lest the frontend persist it to disk. LegacyFrontendPrivateMachineKey key.MachinePrivate `json:"PrivateMachineKey"` PrivateNodeKey key.NodePrivate OldPrivateNodeKey key.NodePrivate // needed to request key rotation Provider string LoginName string UserProfile tailcfg.UserProfile NetworkLockKey key.NLPrivate NodeID tailcfg.StableNodeID // DisallowedTKAStateIDs stores the tka.State.StateID values which // this node will not operate network lock on. This is used to // prevent bootstrapping TKA onto a key authority which was forcibly // disabled. DisallowedTKAStateIDs []string } // PublicNodeKey returns the public key for the node key. func (p *Persist) PublicNodeKey() key.NodePublic { return p.PrivateNodeKey.Public() } // PublicNodeKey returns the public key for the node key. func (p PersistView) PublicNodeKey() key.NodePublic { return p.ж.PublicNodeKey() } func (p PersistView) Equals(p2 PersistView) bool { return p.ж.Equals(p2.ж) } func (p *Persist) Equals(p2 *Persist) bool { if p == nil && p2 == nil { return true } if p == nil || p2 == nil { return false } return p.LegacyFrontendPrivateMachineKey.Equal(p2.LegacyFrontendPrivateMachineKey) && p.PrivateNodeKey.Equal(p2.PrivateNodeKey) && p.OldPrivateNodeKey.Equal(p2.OldPrivateNodeKey) && p.Provider == p2.Provider && p.LoginName == p2.LoginName && p.UserProfile == p2.UserProfile && p.NetworkLockKey.Equal(p2.NetworkLockKey) && p.NodeID == p2.NodeID && reflect.DeepEqual(p.DisallowedTKAStateIDs, p2.DisallowedTKAStateIDs) } func (p *Persist) Pretty() string { var ( mk key.MachinePublic ok, nk key.NodePublic ) if !p.LegacyFrontendPrivateMachineKey.IsZero() { mk = p.LegacyFrontendPrivateMachineKey.Public() } if !p.OldPrivateNodeKey.IsZero() { ok = p.OldPrivateNodeKey.Public() } if !p.PrivateNodeKey.IsZero() { nk = p.PublicNodeKey() } return fmt.Sprintf("Persist{lm=%v, o=%v, n=%v u=%#v}", mk.ShortString(), ok.ShortString(), nk.ShortString(), p.LoginName) }