@ -46,13 +46,21 @@ type tkaState struct {
filtered [ ] ipnstate . TKAFilteredPeer
filtered [ ] ipnstate . TKAFilteredPeer
}
}
// permitTKAInitLocked returns true if tailnet lock initialization may
// occur.
// b.mu must be held.
func ( b * LocalBackend ) permitTKAInitLocked ( ) bool {
return envknob . UseWIPCode ( ) || b . capTailnetLock
}
// tkaFilterNetmapLocked checks the signatures on each node key, dropping
// tkaFilterNetmapLocked checks the signatures on each node key, dropping
// nodes from the netmap whose signature does not verify.
// nodes from the netmap whose signature does not verify.
//
//
// b.mu must be held.
// b.mu must be held.
func ( b * LocalBackend ) tkaFilterNetmapLocked ( nm * netmap . NetworkMap ) {
func ( b * LocalBackend ) tkaFilterNetmapLocked ( nm * netmap . NetworkMap ) {
if ! envknob . UseWIPCode ( ) {
// TODO(tom): Remove this guard for 1.35 and later.
return // Feature-flag till network-lock is in Alpha.
if b . tka == nil && ! b . permitTKAInitLocked ( ) {
return
}
}
if b . tka == nil {
if b . tka == nil {
return // TKA not enabled.
return // TKA not enabled.
@ -61,7 +69,7 @@ func (b *LocalBackend) tkaFilterNetmapLocked(nm *netmap.NetworkMap) {
var toDelete map [ int ] bool // peer index => true
var toDelete map [ int ] bool // peer index => true
for i , p := range nm . Peers {
for i , p := range nm . Peers {
if p . UnsignedPeerAPIOnly {
if p . UnsignedPeerAPIOnly {
// Not subject to TKA .
// Not subject to tailnet lock .
continue
continue
}
}
if len ( p . KeySignature ) == 0 {
if len ( p . KeySignature ) == 0 {
@ -123,18 +131,18 @@ func (b *LocalBackend) tkaFilterNetmapLocked(nm *netmap.NetworkMap) {
// tkaSyncIfNeeded immediately takes b.takeSyncLock which is held throughout,
// tkaSyncIfNeeded immediately takes b.takeSyncLock which is held throughout,
// and may take b.mu as required.
// and may take b.mu as required.
func ( b * LocalBackend ) tkaSyncIfNeeded ( nm * netmap . NetworkMap , prefs ipn . PrefsView ) error {
func ( b * LocalBackend ) tkaSyncIfNeeded ( nm * netmap . NetworkMap , prefs ipn . PrefsView ) error {
if ! envknob . UseWIPCode ( ) {
// If the feature flag is not enabled, pretend we don't exist.
return nil
}
b . logf ( "tkaSyncIfNeeded: enabled=%v, head=%v" , nm . TKAEnabled , nm . TKAHead )
b . tkaSyncLock . Lock ( ) // take tkaSyncLock to make this function an exclusive section.
b . tkaSyncLock . Lock ( ) // take tkaSyncLock to make this function an exclusive section.
defer b . tkaSyncLock . Unlock ( )
defer b . tkaSyncLock . Unlock ( )
b . mu . Lock ( ) // take mu to protect access to synchronized fields.
b . mu . Lock ( ) // take mu to protect access to synchronized fields.
defer b . mu . Unlock ( )
defer b . mu . Unlock ( )
// TODO(tom): Remove this guard for 1.35 and later.
if b . tka == nil && ! b . permitTKAInitLocked ( ) {
return nil
}
b . logf ( "tkaSyncIfNeeded: enabled=%v, head=%v" , nm . TKAEnabled , nm . TKAHead )
ourNodeKey := prefs . Persist ( ) . PublicNodeKey ( )
ourNodeKey := prefs . Persist ( ) . PublicNodeKey ( )
isEnabled := b . tka != nil
isEnabled := b . tka != nil
@ -352,10 +360,6 @@ func (b *LocalBackend) tkaBootstrapFromGenesisLocked(g tkatype.MarshaledAUM, per
// CanSupportNetworkLock returns nil if tailscaled is able to operate
// CanSupportNetworkLock returns nil if tailscaled is able to operate
// a local tailnet key authority (and hence enforce network lock).
// a local tailnet key authority (and hence enforce network lock).
func ( b * LocalBackend ) CanSupportNetworkLock ( ) error {
func ( b * LocalBackend ) CanSupportNetworkLock ( ) error {
if ! envknob . UseWIPCode ( ) {
return errors . New ( "this feature is not yet complete, a later release may support this functionality" )
}
if b . tka != nil {
if b . tka != nil {
// If the TKA is being used, it is supported.
// If the TKA is being used, it is supported.
return nil
return nil
@ -453,6 +457,13 @@ func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byt
var ourNodeKey key . NodePublic
var ourNodeKey key . NodePublic
var nlPriv key . NLPrivate
var nlPriv key . NLPrivate
b . mu . Lock ( )
b . mu . Lock ( )
// TODO(tom): Remove this guard for 1.35 and later.
if ! b . permitTKAInitLocked ( ) {
b . mu . Unlock ( )
return errors . New ( "this feature is not yet complete, a later release may support this functionality" )
}
if p := b . pm . CurrentPrefs ( ) ; p . Valid ( ) && p . Persist ( ) . Valid ( ) && ! p . Persist ( ) . PrivateNodeKey ( ) . IsZero ( ) {
if p := b . pm . CurrentPrefs ( ) ; p . Valid ( ) && p . Persist ( ) . Valid ( ) && ! p . Persist ( ) . PrivateNodeKey ( ) . IsZero ( ) {
ourNodeKey = p . Persist ( ) . PublicNodeKey ( )
ourNodeKey = p . Persist ( ) . PublicNodeKey ( )
nlPriv = p . Persist ( ) . NetworkLockKey ( )
nlPriv = p . Persist ( ) . NetworkLockKey ( )
@ -631,9 +642,6 @@ func (b *LocalBackend) NetworkLockModify(addKeys, removeKeys []tka.Key) (err err
return errors . New ( "no node-key: is tailscale logged in?" )
return errors . New ( "no node-key: is tailscale logged in?" )
}
}
if err := b . CanSupportNetworkLock ( ) ; err != nil {
return err
}
var nlPriv key . NLPrivate
var nlPriv key . NLPrivate
if p := b . pm . CurrentPrefs ( ) ; p . Valid ( ) && p . Persist ( ) . Valid ( ) {
if p := b . pm . CurrentPrefs ( ) ; p . Valid ( ) && p . Persist ( ) . Valid ( ) {
nlPriv = p . Persist ( ) . NetworkLockKey ( )
nlPriv = p . Persist ( ) . NetworkLockKey ( )
@ -690,10 +698,6 @@ func (b *LocalBackend) NetworkLockModify(addKeys, removeKeys []tka.Key) (err err
// NetworkLockDisable disables network-lock using the provided disablement secret.
// NetworkLockDisable disables network-lock using the provided disablement secret.
func ( b * LocalBackend ) NetworkLockDisable ( secret [ ] byte ) error {
func ( b * LocalBackend ) NetworkLockDisable ( secret [ ] byte ) error {
if err := b . CanSupportNetworkLock ( ) ; err != nil {
return err
}
var (
var (
ourNodeKey key . NodePublic
ourNodeKey key . NodePublic
head tka . AUMHash
head tka . AUMHash