@@ -82,9 +82,9 @@ type Direct struct {
8282
8383 dialPlan ControlDialPlanner // can be nil
8484
85- mu sync.Mutex // mutex guards the following fields
86- serverKey key.MachinePublic // original ("legacy") nacl crypto_box-based public key
87- serverNoiseKey key.MachinePublic
85+ mu sync.Mutex // mutex guards the following fields
86+ serverLegacyKey key.MachinePublic // original ("legacy") nacl crypto_box-based public key; only used for signRegisterRequest on Windows now
87+ serverNoiseKey key.MachinePublic
8888
8989 sfGroup singleflight.Group [struct {}, * NoiseClient ] // protects noiseClient creation.
9090 noiseClient * NoiseClient
@@ -436,12 +436,6 @@ type loginOpt struct {
436436 OldNodeKeySignature tkatype.MarshaledSignature
437437}
438438
439- // httpClient provides a common interface for the noiseClient and
440- // the NaCl box http.Client.
441- type httpClient interface {
442- Do (req * http.Request ) (* http.Response , error )
443- }
444-
445439// hostInfoLocked returns a Clone of c.hostinfo and c.netinfo.
446440// It must only be called with c.mu held.
447441func (c * Direct ) hostInfoLocked () * tailcfg.Hostinfo {
@@ -454,7 +448,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
454448 c .mu .Lock ()
455449 persist := c .persist .AsStruct ()
456450 tryingNewKey := c .tryingNewKey
457- serverKey := c .serverKey
451+ serverKey := c .serverLegacyKey
458452 serverNoiseKey := c .serverNoiseKey
459453 authKey , isWrapped , wrappedSig , wrappedKey := decodeWrappedAuthkey (c .authKey , c .logf )
460454 hi := c .hostInfoLocked ()
@@ -494,20 +488,22 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
494488 c .logf ("control server key from %s: ts2021=%s, legacy=%v" , c .serverURL , keys .PublicKey .ShortString (), keys .LegacyPublicKey .ShortString ())
495489
496490 c .mu .Lock ()
497- c .serverKey = keys .LegacyPublicKey
491+ c .serverLegacyKey = keys .LegacyPublicKey
498492 c .serverNoiseKey = keys .PublicKey
499493 c .mu .Unlock ()
500494 serverKey = keys .LegacyPublicKey
501495 serverNoiseKey = keys .PublicKey
502496
503- // For servers supporting the Noise transport,
504- // proactively shut down our TLS TCP connection.
497+ // Proactively shut down our TLS TCP connection.
505498 // We're not going to need it and it's nicer to the
506499 // server.
507- if ! serverNoiseKey .IsZero () {
508- c .httpc .CloseIdleConnections ()
509- }
500+ c .httpc .CloseIdleConnections ()
501+ }
502+
503+ if serverNoiseKey .IsZero () {
504+ return false , "" , nil , errors .New ("control server is too old; no noise key" )
510505 }
506+
511507 var oldNodeKey key.NodePublic
512508 switch {
513509 case opt .Logout :
@@ -594,7 +590,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
594590 request .Auth .Provider = persist .Provider
595591 request .Auth .LoginName = persist .UserProfile .LoginName
596592 request .Auth .AuthKey = authKey
597- err = signRegisterRequest (& request , c .serverURL , c .serverKey , machinePrivKey .Public ())
593+ err = signRegisterRequest (& request , c .serverURL , c .serverLegacyKey , machinePrivKey .Public ())
598594 if err != nil {
599595 // If signing failed, clear all related fields
600596 request .SignatureType = tailcfg .SignatureNone
@@ -614,21 +610,16 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
614610 }
615611
616612 // URL and httpc are protocol specific.
617- var url string
618- var httpc httpClient
619- if serverNoiseKey .IsZero () {
620- httpc = c .httpc
621- url = fmt .Sprintf ("%s/machine/%s" , c .serverURL , machinePrivKey .Public ().UntypedHexString ())
622- } else {
623- request .Version = tailcfg .CurrentCapabilityVersion
624- httpc , err = c .getNoiseClient ()
625- if err != nil {
626- return regen , opt .URL , nil , fmt .Errorf ("getNoiseClient: %w" , err )
627- }
628- url = fmt .Sprintf ("%s/machine/register" , c .serverURL )
629- url = strings .Replace (url , "http:" , "https:" , 1 )
613+
614+ request .Version = tailcfg .CurrentCapabilityVersion
615+ httpc , err := c .getNoiseClient ()
616+ if err != nil {
617+ return regen , opt .URL , nil , fmt .Errorf ("getNoiseClient: %w" , err )
630618 }
631- bodyData , err := encode (request , serverKey , serverNoiseKey , machinePrivKey )
619+ url := fmt .Sprintf ("%s/machine/register" , c .serverURL )
620+ url = strings .Replace (url , "http:" , "https:" , 1 )
621+
622+ bodyData , err := encode (request )
632623 if err != nil {
633624 return regen , opt .URL , nil , err
634625 }
@@ -650,7 +641,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
650641 res .StatusCode , strings .TrimSpace (string (msg )))
651642 }
652643 resp := tailcfg.RegisterResponse {}
653- if err := decode (res , & resp , serverKey , serverNoiseKey , machinePrivKey ); err != nil {
644+ if err := decode (res , & resp ); err != nil {
654645 c .logf ("error decoding RegisterResponse with server key %s and machine key %s: %v" , serverKey , machinePrivKey .Public (), err )
655646 return regen , opt .URL , nil , fmt .Errorf ("register request: %v" , err )
656647 }
@@ -844,7 +835,6 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
844835 c .mu .Lock ()
845836 persist := c .persist
846837 serverURL := c .serverURL
847- serverKey := c .serverKey
848838 serverNoiseKey := c .serverNoiseKey
849839 hi := c .hostInfoLocked ()
850840 backendLogID := hi .BackendLogID
@@ -858,6 +848,10 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
858848 }
859849 c .mu .Unlock ()
860850
851+ if serverNoiseKey .IsZero () {
852+ return errors .New ("control server is too old; no noise key" )
853+ }
854+
861855 machinePrivKey , err := c .getMachinePrivKey ()
862856 if err != nil {
863857 return fmt .Errorf ("getMachinePrivKey: %w" , err )
@@ -914,7 +908,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
914908 }
915909 request .Compress = "zstd"
916910
917- bodyData , err := encode (request , serverKey , serverNoiseKey , machinePrivKey )
911+ bodyData , err := encode (request )
918912 if err != nil {
919913 vlogf ("netmap: encode: %v" , err )
920914 return err
@@ -926,20 +920,12 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
926920 machinePubKey := machinePrivKey .Public ()
927921 t0 := c .clock .Now ()
928922
929- // Url and httpc are protocol specific.
930- var url string
931- var httpc httpClient
932- if serverNoiseKey .IsZero () {
933- httpc = c .httpc
934- url = fmt .Sprintf ("%s/machine/%s/map" , serverURL , machinePubKey .UntypedHexString ())
935- } else {
936- httpc , err = c .getNoiseClient ()
937- if err != nil {
938- return fmt .Errorf ("getNoiseClient: %w" , err )
939- }
940- url = fmt .Sprintf ("%s/machine/map" , serverURL )
941- url = strings .Replace (url , "http:" , "https:" , 1 )
923+ httpc , err := c .getNoiseClient ()
924+ if err != nil {
925+ return fmt .Errorf ("getNoiseClient: %w" , err )
942926 }
927+ url := fmt .Sprintf ("%s/machine/map" , serverURL )
928+ url = strings .Replace (url , "http:" , "https:" , 1 )
943929
944930 // Create a watchdog timer that breaks the connection if we don't receive a
945931 // MapResponse from the network at least once every two minutes. The
@@ -1047,7 +1033,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
10471033 vlogf ("netmap: read body after %v" , time .Since (t0 ).Round (time .Millisecond ))
10481034
10491035 var resp tailcfg.MapResponse
1050- if err := c .decodeMsg (msg , & resp , machinePrivKey ); err != nil {
1036+ if err := c .decodeMsg (msg , & resp ); err != nil {
10511037 vlogf ("netmap: decode error: %v" , err )
10521038 return err
10531039 }
@@ -1164,9 +1150,8 @@ func initDisplayNames(selfNode tailcfg.NodeView, resp *tailcfg.MapResponse) {
11641150 }
11651151}
11661152
1167- // decode JSON decodes the res.Body into v. If serverNoiseKey is not specified,
1168- // it uses the serverKey and mkey to decode the message from the NaCl-crypto-box.
1169- func decode (res * http.Response , v any , serverKey , serverNoiseKey key.MachinePublic , mkey key.MachinePrivate ) error {
1153+ // decode JSON decodes the res.Body into v.
1154+ func decode (res * http.Response , v any ) error {
11701155 defer res .Body .Close ()
11711156 msg , err := io .ReadAll (io .LimitReader (res .Body , 1 << 20 ))
11721157 if err != nil {
@@ -1175,10 +1160,7 @@ func decode(res *http.Response, v any, serverKey, serverNoiseKey key.MachinePubl
11751160 if res .StatusCode != 200 {
11761161 return fmt .Errorf ("%d: %v" , res .StatusCode , string (msg ))
11771162 }
1178- if ! serverNoiseKey .IsZero () {
1179- return json .Unmarshal (msg , v )
1180- }
1181- return decodeMsg (msg , v , serverKey , mkey )
1163+ return json .Unmarshal (msg , v )
11821164}
11831165
11841166var (
@@ -1189,25 +1171,8 @@ var (
11891171var jsonEscapedZero = []byte (`\u0000` )
11901172
11911173// decodeMsg is responsible for uncompressing msg and unmarshaling into v.
1192- // If c.serverNoiseKey is not specified, it uses the c.serverKey and mkey
1193- // to first the decrypt msg from the NaCl-crypto-box.
1194- func (c * Direct ) decodeMsg (msg []byte , v any , mkey key.MachinePrivate ) error {
1195- c .mu .Lock ()
1196- serverKey := c .serverKey
1197- serverNoiseKey := c .serverNoiseKey
1198- c .mu .Unlock ()
1199-
1200- var decrypted []byte
1201- if serverNoiseKey .IsZero () {
1202- var ok bool
1203- decrypted , ok = mkey .OpenFrom (serverKey , msg )
1204- if ! ok {
1205- return errors .New ("cannot decrypt response" )
1206- }
1207- } else {
1208- decrypted = msg
1209- }
1210- b , err := zstdframe .AppendDecode (nil , decrypted )
1174+ func (c * Direct ) decodeMsg (compressedMsg []byte , v any ) error {
1175+ b , err := zstdframe .AppendDecode (nil , compressedMsg )
12111176 if err != nil {
12121177 return err
12131178 }
@@ -1224,26 +1189,11 @@ func (c *Direct) decodeMsg(msg []byte, v any, mkey key.MachinePrivate) error {
12241189 return fmt .Errorf ("response: %v" , err )
12251190 }
12261191 return nil
1227-
1228- }
1229-
1230- func decodeMsg (msg []byte , v any , serverKey key.MachinePublic , machinePrivKey key.MachinePrivate ) error {
1231- decrypted , ok := machinePrivKey .OpenFrom (serverKey , msg )
1232- if ! ok {
1233- return errors .New ("cannot decrypt response" )
1234- }
1235- if bytes .Contains (decrypted , jsonEscapedZero ) {
1236- log .Printf ("[unexpected] zero byte in controlclient decodeMsg into %T: %q" , v , decrypted )
1237- }
1238- if err := json .Unmarshal (decrypted , v ); err != nil {
1239- return fmt .Errorf ("response: %v" , err )
1240- }
1241- return nil
12421192}
12431193
1244- // encode JSON encodes v. If serverNoiseKey is not specified, it uses the serverKey and mkey to
1245- // seal the message into a NaCl-crypto-box .
1246- func encode (v any , serverKey , serverNoiseKey key. MachinePublic , mkey key. MachinePrivate ) ([]byte , error ) {
1194+ // encode JSON encodes v as JSON, logging tailcfg.MapRequest values if
1195+ // debugMap is set .
1196+ func encode (v any ) ([]byte , error ) {
12471197 b , err := json .Marshal (v )
12481198 if err != nil {
12491199 return nil , err
@@ -1253,10 +1203,7 @@ func encode(v any, serverKey, serverNoiseKey key.MachinePublic, mkey key.Machine
12531203 log .Printf ("MapRequest: %s" , b )
12541204 }
12551205 }
1256- if ! serverNoiseKey .IsZero () {
1257- return b , nil
1258- }
1259- return mkey .SealTo (serverKey , b ), nil
1206+ return b , nil
12601207}
12611208
12621209func loadServerPubKeys (ctx context.Context , httpc * http.Client , serverURL string ) (* tailcfg.OverTLSPublicKeyResponse , error ) {
@@ -1353,7 +1300,7 @@ func (c *Direct) isUniquePingRequest(pr *tailcfg.PingRequest) bool {
13531300
13541301func (c * Direct ) answerPing (pr * tailcfg.PingRequest ) {
13551302 httpc := c .httpc
1356- useNoise := pr .URLIsNoise || pr .Types == "c2n" && c . noiseConfigured ()
1303+ useNoise := pr .URLIsNoise || pr .Types == "c2n"
13571304 if useNoise {
13581305 nc , err := c .getNoiseClient ()
13591306 if err != nil {
@@ -1554,14 +1501,6 @@ func (c *Direct) setDNSNoise(ctx context.Context, req *tailcfg.SetDNSRequest) er
15541501 return nil
15551502}
15561503
1557- // noiseConfigured reports whether the client can communicate with Control
1558- // over Noise.
1559- func (c * Direct ) noiseConfigured () bool {
1560- c .mu .Lock ()
1561- defer c .mu .Unlock ()
1562- return ! c .serverNoiseKey .IsZero ()
1563- }
1564-
15651504// SetDNS sends the SetDNSRequest request to the control plane server,
15661505// requesting a DNS record be created or updated.
15671506func (c * Direct ) SetDNS (ctx context.Context , req * tailcfg.SetDNSRequest ) (err error ) {
@@ -1571,53 +1510,7 @@ func (c *Direct) SetDNS(ctx context.Context, req *tailcfg.SetDNSRequest) (err er
15711510 metricSetDNSError .Add (1 )
15721511 }
15731512 }()
1574- if c .noiseConfigured () {
1575- return c .setDNSNoise (ctx , req )
1576- }
1577- c .mu .Lock ()
1578- serverKey := c .serverKey
1579- c .mu .Unlock ()
1580-
1581- if serverKey .IsZero () {
1582- return errors .New ("zero serverKey" )
1583- }
1584- machinePrivKey , err := c .getMachinePrivKey ()
1585- if err != nil {
1586- return fmt .Errorf ("getMachinePrivKey: %w" , err )
1587- }
1588- if machinePrivKey .IsZero () {
1589- return errors .New ("getMachinePrivKey returned zero key" )
1590- }
1591-
1592- // TODO(maisem): dedupe this codepath from SetDNSNoise.
1593- var serverNoiseKey key.MachinePublic
1594- bodyData , err := encode (req , serverKey , serverNoiseKey , machinePrivKey )
1595- if err != nil {
1596- return err
1597- }
1598- body := bytes .NewReader (bodyData )
1599-
1600- u := fmt .Sprintf ("%s/machine/%s/set-dns" , c .serverURL , machinePrivKey .Public ().UntypedHexString ())
1601- hreq , err := http .NewRequestWithContext (ctx , "POST" , u , body )
1602- if err != nil {
1603- return err
1604- }
1605- res , err := c .httpc .Do (hreq )
1606- if err != nil {
1607- return err
1608- }
1609- defer res .Body .Close ()
1610- if res .StatusCode != 200 {
1611- msg , _ := io .ReadAll (res .Body )
1612- return fmt .Errorf ("set-dns response: %v, %.200s" , res .Status , strings .TrimSpace (string (msg )))
1613- }
1614- var setDNSRes tailcfg.SetDNSResponse
1615- if err := decode (res , & setDNSRes , serverKey , serverNoiseKey , machinePrivKey ); err != nil {
1616- c .logf ("error decoding SetDNSResponse with server key %s and machine key %s: %v" , serverKey , machinePrivKey .Public (), err )
1617- return fmt .Errorf ("set-dns-response: %w" , err )
1618- }
1619-
1620- return nil
1513+ return c .setDNSNoise (ctx , req )
16211514}
16221515
16231516func (c * Direct ) DoNoiseRequest (req * http.Request ) (* http.Response , error ) {
0 commit comments