mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	rename handler files
This commit renames a bunch of files to try to make it a bit less confusing; protocol_ is now auth as they contained registration, auth and login/out flow protocol_.*_poll is now poll.go api.go and other generic handlers are now handlers.go Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
		
							parent
							
								
									c1218ad3c2
								
							
						
					
					
						commit
						0562260fe0
					
				| @ -1,11 +1,9 @@ | |||||||
| package hscontrol | package hscontrol | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" |  | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strconv" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| @ -18,86 +16,10 @@ import ( | |||||||
| 	"tailscale.com/types/key" | 	"tailscale.com/types/key" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | // handleRegister is the common logic for registering a client in the legacy and Noise protocols
 | ||||||
| 	// The CapabilityVersion is used by Tailscale clients to indicate
 |  | ||||||
| 	// their codebase version. Tailscale clients can communicate over TS2021
 |  | ||||||
| 	// from CapabilityVersion 28, but we only have good support for it
 |  | ||||||
| 	// since https://github.com/tailscale/tailscale/pull/4323 (Noise in any HTTPS port).
 |  | ||||||
| 	//
 |  | ||||||
| 	// Related to this change, there is https://github.com/tailscale/tailscale/pull/5379,
 |  | ||||||
| 	// where CapabilityVersion 39 is introduced to indicate #4323 was merged.
 |  | ||||||
| 	//
 |  | ||||||
| 	// See also https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go
 |  | ||||||
| 	NoiseCapabilityVersion = 39 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // KeyHandler provides the Headscale pub key
 |  | ||||||
| // Listens in /key.
 |  | ||||||
| func (h *Headscale) KeyHandler( |  | ||||||
| 	writer http.ResponseWriter, |  | ||||||
| 	req *http.Request, |  | ||||||
| ) { |  | ||||||
| 	// New Tailscale clients send a 'v' parameter to indicate the CurrentCapabilityVersion
 |  | ||||||
| 	clientCapabilityStr := req.URL.Query().Get("v") |  | ||||||
| 	if clientCapabilityStr != "" { |  | ||||||
| 		log.Debug(). |  | ||||||
| 			Str("handler", "/key"). |  | ||||||
| 			Str("v", clientCapabilityStr). |  | ||||||
| 			Msg("New noise client") |  | ||||||
| 		clientCapabilityVersion, err := strconv.Atoi(clientCapabilityStr) |  | ||||||
| 		if err != nil { |  | ||||||
| 			writer.Header().Set("Content-Type", "text/plain; charset=utf-8") |  | ||||||
| 			writer.WriteHeader(http.StatusBadRequest) |  | ||||||
| 			_, err := writer.Write([]byte("Wrong params")) |  | ||||||
| 			if err != nil { |  | ||||||
| 				log.Error(). |  | ||||||
| 					Caller(). |  | ||||||
| 					Err(err). |  | ||||||
| 					Msg("Failed to write response") |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// TS2021 (Tailscale v2 protocol) requires to have a different key
 |  | ||||||
| 		if clientCapabilityVersion >= NoiseCapabilityVersion { |  | ||||||
| 			resp := tailcfg.OverTLSPublicKeyResponse{ |  | ||||||
| 				LegacyPublicKey: h.privateKey2019.Public(), |  | ||||||
| 				PublicKey:       h.noisePrivateKey.Public(), |  | ||||||
| 			} |  | ||||||
| 			writer.Header().Set("Content-Type", "application/json") |  | ||||||
| 			writer.WriteHeader(http.StatusOK) |  | ||||||
| 			err = json.NewEncoder(writer).Encode(resp) |  | ||||||
| 			if err != nil { |  | ||||||
| 				log.Error(). |  | ||||||
| 					Caller(). |  | ||||||
| 					Err(err). |  | ||||||
| 					Msg("Failed to write response") |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	log.Debug(). |  | ||||||
| 		Str("handler", "/key"). |  | ||||||
| 		Msg("New legacy client") |  | ||||||
| 
 |  | ||||||
| 	// Old clients don't send a 'v' parameter, so we send the legacy public key
 |  | ||||||
| 	writer.Header().Set("Content-Type", "text/plain; charset=utf-8") |  | ||||||
| 	writer.WriteHeader(http.StatusOK) |  | ||||||
| 	_, err := writer.Write([]byte(util.MachinePublicKeyStripPrefix(h.privateKey2019.Public()))) |  | ||||||
| 	if err != nil { |  | ||||||
| 		log.Error(). |  | ||||||
| 			Caller(). |  | ||||||
| 			Err(err). |  | ||||||
| 			Msg("Failed to write response") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // handleRegisterCommon is the common logic for registering a client in the legacy and Noise protocols
 |  | ||||||
| //
 | //
 | ||||||
| // When using Noise, the machineKey is Zero.
 | // When using Noise, the machineKey is Zero.
 | ||||||
| func (h *Headscale) handleRegisterCommon( | func (h *Headscale) handleRegister( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	req *http.Request, | 	req *http.Request, | ||||||
| 	registerRequest tailcfg.RegisterRequest, | 	registerRequest tailcfg.RegisterRequest, | ||||||
| @ -109,7 +31,7 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 	if errors.Is(err, gorm.ErrRecordNotFound) { | 	if errors.Is(err, gorm.ErrRecordNotFound) { | ||||||
| 		// If the machine has AuthKey set, handle registration via PreAuthKeys
 | 		// If the machine has AuthKey set, handle registration via PreAuthKeys
 | ||||||
| 		if registerRequest.Auth.AuthKey != "" { | 		if registerRequest.Auth.AuthKey != "" { | ||||||
| 			h.handleAuthKeyCommon(writer, registerRequest, machineKey, isNoise) | 			h.handleAuthKey(writer, registerRequest, machineKey, isNoise) | ||||||
| 
 | 
 | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| @ -138,7 +60,7 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 				case <-req.Context().Done(): | 				case <-req.Context().Done(): | ||||||
| 					return | 					return | ||||||
| 				case <-time.After(registrationHoldoff): | 				case <-time.After(registrationHoldoff): | ||||||
| 					h.handleNewMachineCommon(writer, registerRequest, machineKey, isNoise) | 					h.handleNewMachine(writer, registerRequest, machineKey, isNoise) | ||||||
| 
 | 
 | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| @ -198,7 +120,7 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 			registerCacheExpiration, | 			registerCacheExpiration, | ||||||
| 		) | 		) | ||||||
| 
 | 
 | ||||||
| 		h.handleNewMachineCommon(writer, registerRequest, machineKey, isNoise) | 		h.handleNewMachine(writer, registerRequest, machineKey, isNoise) | ||||||
| 
 | 
 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @ -238,7 +160,7 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 			//   https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648
 | 			//   https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648
 | ||||||
| 			if !registerRequest.Expiry.IsZero() && | 			if !registerRequest.Expiry.IsZero() && | ||||||
| 				registerRequest.Expiry.UTC().Before(now) { | 				registerRequest.Expiry.UTC().Before(now) { | ||||||
| 				h.handleMachineLogOutCommon(writer, *machine, machineKey, isNoise) | 				h.handleMachineLogOut(writer, *machine, machineKey, isNoise) | ||||||
| 
 | 
 | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| @ -246,7 +168,7 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 			// If machine is not expired, and it is register, we have a already accepted this machine,
 | 			// If machine is not expired, and it is register, we have a already accepted this machine,
 | ||||||
| 			// let it proceed with a valid registration
 | 			// let it proceed with a valid registration
 | ||||||
| 			if !machine.IsExpired() { | 			if !machine.IsExpired() { | ||||||
| 				h.handleMachineValidRegistrationCommon(writer, *machine, machineKey, isNoise) | 				h.handleMachineWithValidRegistration(writer, *machine, machineKey, isNoise) | ||||||
| 
 | 
 | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| @ -255,7 +177,7 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 		// The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration
 | 		// The NodeKey we have matches OldNodeKey, which means this is a refresh after a key expiration
 | ||||||
| 		if machine.NodeKey == util.NodePublicKeyStripPrefix(registerRequest.OldNodeKey) && | 		if machine.NodeKey == util.NodePublicKeyStripPrefix(registerRequest.OldNodeKey) && | ||||||
| 			!machine.IsExpired() { | 			!machine.IsExpired() { | ||||||
| 			h.handleMachineRefreshKeyCommon( | 			h.handleMachineKeyRefresh( | ||||||
| 				writer, | 				writer, | ||||||
| 				registerRequest, | 				registerRequest, | ||||||
| 				*machine, | 				*machine, | ||||||
| @ -275,7 +197,7 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// The machine has expired or it is logged out
 | 		// The machine has expired or it is logged out
 | ||||||
| 		h.handleMachineExpiredOrLoggedOutCommon(writer, registerRequest, *machine, machineKey, isNoise) | 		h.handleMachineExpiredOrLoggedOut(writer, registerRequest, *machine, machineKey, isNoise) | ||||||
| 
 | 
 | ||||||
| 		// TODO(juan): RegisterRequest includes an Expiry time, that we could optionally use
 | 		// TODO(juan): RegisterRequest includes an Expiry time, that we could optionally use
 | ||||||
| 		machine.Expiry = &time.Time{} | 		machine.Expiry = &time.Time{} | ||||||
| @ -295,19 +217,19 @@ func (h *Headscale) handleRegisterCommon( | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // handleAuthKeyCommon contains the logic to manage auth key client registration
 | // handleAuthKey contains the logic to manage auth key client registration
 | ||||||
| // It is used both by the legacy and the new Noise protocol.
 | // It is used both by the legacy and the new Noise protocol.
 | ||||||
| // When using Noise, the machineKey is Zero.
 | // When using Noise, the machineKey is Zero.
 | ||||||
| //
 | //
 | ||||||
| // TODO: check if any locks are needed around IP allocation.
 | // TODO: check if any locks are needed around IP allocation.
 | ||||||
| func (h *Headscale) handleAuthKeyCommon( | func (h *Headscale) handleAuthKey( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	registerRequest tailcfg.RegisterRequest, | 	registerRequest tailcfg.RegisterRequest, | ||||||
| 	machineKey key.MachinePublic, | 	machineKey key.MachinePublic, | ||||||
| 	isNoise bool, | 	isNoise bool, | ||||||
| ) { | ) { | ||||||
| 	log.Debug(). | 	log.Debug(). | ||||||
| 		Str("func", "handleAuthKeyCommon"). | 		Caller(). | ||||||
| 		Str("machine", registerRequest.Hostinfo.Hostname). | 		Str("machine", registerRequest.Hostinfo.Hostname). | ||||||
| 		Bool("noise", isNoise). | 		Bool("noise", isNoise). | ||||||
| 		Msgf("Processing auth key for %s", registerRequest.Hostinfo.Hostname) | 		Msgf("Processing auth key for %s", registerRequest.Hostinfo.Hostname) | ||||||
| @ -317,7 +239,6 @@ func (h *Headscale) handleAuthKeyCommon( | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error(). | 		log.Error(). | ||||||
| 			Caller(). | 			Caller(). | ||||||
| 			Str("func", "handleAuthKeyCommon"). |  | ||||||
| 			Bool("noise", isNoise). | 			Bool("noise", isNoise). | ||||||
| 			Str("machine", registerRequest.Hostinfo.Hostname). | 			Str("machine", registerRequest.Hostinfo.Hostname). | ||||||
| 			Err(err). | 			Err(err). | ||||||
| @ -328,7 +249,6 @@ func (h *Headscale) handleAuthKeyCommon( | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error(). | 			log.Error(). | ||||||
| 				Caller(). | 				Caller(). | ||||||
| 				Str("func", "handleAuthKeyCommon"). |  | ||||||
| 				Bool("noise", isNoise). | 				Bool("noise", isNoise). | ||||||
| 				Str("machine", registerRequest.Hostinfo.Hostname). | 				Str("machine", registerRequest.Hostinfo.Hostname). | ||||||
| 				Err(err). | 				Err(err). | ||||||
| @ -353,7 +273,6 @@ func (h *Headscale) handleAuthKeyCommon( | |||||||
| 
 | 
 | ||||||
| 		log.Error(). | 		log.Error(). | ||||||
| 			Caller(). | 			Caller(). | ||||||
| 			Str("func", "handleAuthKeyCommon"). |  | ||||||
| 			Bool("noise", isNoise). | 			Bool("noise", isNoise). | ||||||
| 			Str("machine", registerRequest.Hostinfo.Hostname). | 			Str("machine", registerRequest.Hostinfo.Hostname). | ||||||
| 			Msg("Failed authentication via AuthKey") | 			Msg("Failed authentication via AuthKey") | ||||||
| @ -369,7 +288,7 @@ func (h *Headscale) handleAuthKeyCommon( | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	log.Debug(). | 	log.Debug(). | ||||||
| 		Str("func", "handleAuthKeyCommon"). | 		Caller(). | ||||||
| 		Bool("noise", isNoise). | 		Bool("noise", isNoise). | ||||||
| 		Str("machine", registerRequest.Hostinfo.Hostname). | 		Str("machine", registerRequest.Hostinfo.Hostname). | ||||||
| 		Msg("Authentication key was valid, proceeding to acquire IP addresses") | 		Msg("Authentication key was valid, proceeding to acquire IP addresses") | ||||||
| @ -489,7 +408,6 @@ func (h *Headscale) handleAuthKeyCommon( | |||||||
| 		log.Error(). | 		log.Error(). | ||||||
| 			Caller(). | 			Caller(). | ||||||
| 			Bool("noise", isNoise). | 			Bool("noise", isNoise). | ||||||
| 			Str("func", "handleAuthKeyCommon"). |  | ||||||
| 			Str("machine", registerRequest.Hostinfo.Hostname). | 			Str("machine", registerRequest.Hostinfo.Hostname). | ||||||
| 			Err(err). | 			Err(err). | ||||||
| 			Msg("Cannot encode message") | 			Msg("Cannot encode message") | ||||||
| @ -513,16 +431,15 @@ func (h *Headscale) handleAuthKeyCommon( | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	log.Info(). | 	log.Info(). | ||||||
| 		Str("func", "handleAuthKeyCommon"). |  | ||||||
| 		Bool("noise", isNoise). | 		Bool("noise", isNoise). | ||||||
| 		Str("machine", registerRequest.Hostinfo.Hostname). | 		Str("machine", registerRequest.Hostinfo.Hostname). | ||||||
| 		Str("ips", strings.Join(machine.IPAddresses.StringSlice(), ", ")). | 		Str("ips", strings.Join(machine.IPAddresses.StringSlice(), ", ")). | ||||||
| 		Msg("Successfully authenticated via AuthKey") | 		Msg("Successfully authenticated via AuthKey") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // handleNewMachineCommon exposes for both legacy and Noise the functionality to get a URL
 | // handleNewMachine exposes for both legacy and Noise the functionality to get a URL
 | ||||||
| // for authorizing the machine. This url is then showed to the user by the local Tailscale client.
 | // for authorizing the machine. This url is then showed to the user by the local Tailscale client.
 | ||||||
| func (h *Headscale) handleNewMachineCommon( | func (h *Headscale) handleNewMachine( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	registerRequest tailcfg.RegisterRequest, | 	registerRequest tailcfg.RegisterRequest, | ||||||
| 	machineKey key.MachinePublic, | 	machineKey key.MachinePublic, | ||||||
| @ -580,7 +497,7 @@ func (h *Headscale) handleNewMachineCommon( | |||||||
| 		Msg("Successfully sent auth url") | 		Msg("Successfully sent auth url") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *Headscale) handleMachineLogOutCommon( | func (h *Headscale) handleMachineLogOut( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	machine types.Machine, | 	machine types.Machine, | ||||||
| 	machineKey key.MachinePublic, | 	machineKey key.MachinePublic, | ||||||
| @ -598,7 +515,6 @@ func (h *Headscale) handleMachineLogOutCommon( | |||||||
| 		log.Error(). | 		log.Error(). | ||||||
| 			Caller(). | 			Caller(). | ||||||
| 			Bool("noise", isNoise). | 			Bool("noise", isNoise). | ||||||
| 			Str("func", "handleMachineLogOutCommon"). |  | ||||||
| 			Err(err). | 			Err(err). | ||||||
| 			Msg("Failed to expire machine") | 			Msg("Failed to expire machine") | ||||||
| 		http.Error(writer, "Internal server error", http.StatusInternalServerError) | 		http.Error(writer, "Internal server error", http.StatusInternalServerError) | ||||||
| @ -654,7 +570,7 @@ func (h *Headscale) handleMachineLogOutCommon( | |||||||
| 		Msg("Successfully logged out") | 		Msg("Successfully logged out") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *Headscale) handleMachineValidRegistrationCommon( | func (h *Headscale) handleMachineWithValidRegistration( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	machine types.Machine, | 	machine types.Machine, | ||||||
| 	machineKey key.MachinePublic, | 	machineKey key.MachinePublic, | ||||||
| @ -708,7 +624,7 @@ func (h *Headscale) handleMachineValidRegistrationCommon( | |||||||
| 		Msg("Machine successfully authorized") | 		Msg("Machine successfully authorized") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *Headscale) handleMachineRefreshKeyCommon( | func (h *Headscale) handleMachineKeyRefresh( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	registerRequest tailcfg.RegisterRequest, | 	registerRequest tailcfg.RegisterRequest, | ||||||
| 	machine types.Machine, | 	machine types.Machine, | ||||||
| @ -768,7 +684,7 @@ func (h *Headscale) handleMachineRefreshKeyCommon( | |||||||
| 		Msg("Node key successfully refreshed") | 		Msg("Node key successfully refreshed") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *Headscale) handleMachineExpiredOrLoggedOutCommon( | func (h *Headscale) handleMachineExpiredOrLoggedOut( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	registerRequest tailcfg.RegisterRequest, | 	registerRequest tailcfg.RegisterRequest, | ||||||
| 	machine types.Machine, | 	machine types.Machine, | ||||||
| @ -778,7 +694,7 @@ func (h *Headscale) handleMachineExpiredOrLoggedOutCommon( | |||||||
| 	resp := tailcfg.RegisterResponse{} | 	resp := tailcfg.RegisterResponse{} | ||||||
| 
 | 
 | ||||||
| 	if registerRequest.Auth.AuthKey != "" { | 	if registerRequest.Auth.AuthKey != "" { | ||||||
| 		h.handleAuthKeyCommon(writer, registerRequest, machineKey, isNoise) | 		h.handleAuthKey(writer, registerRequest, machineKey, isNoise) | ||||||
| 
 | 
 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @ -57,5 +57,5 @@ func (h *Headscale) RegistrationHandler( | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	h.handleRegisterCommon(writer, req, registerRequest, machineKey, false) | 	h.handleRegister(writer, req, registerRequest, machineKey, false) | ||||||
| } | } | ||||||
| @ -40,5 +40,5 @@ func (ns *noiseServer) NoiseRegistrationHandler( | |||||||
| 
 | 
 | ||||||
| 	ns.nodeKey = registerRequest.NodeKey | 	ns.nodeKey = registerRequest.NodeKey | ||||||
| 
 | 
 | ||||||
| 	ns.headscale.handleRegisterCommon(writer, req, registerRequest, ns.conn.Peer(), true) | 	ns.headscale.handleRegister(writer, req, registerRequest, ns.conn.Peer(), true) | ||||||
| } | } | ||||||
| @ -6,15 +6,28 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
| 	"html/template" | 	"html/template" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gorilla/mux" | 	"github.com/gorilla/mux" | ||||||
| 	"github.com/juanfont/headscale/hscontrol/util" | 	"github.com/juanfont/headscale/hscontrol/util" | ||||||
| 	"github.com/rs/zerolog/log" | 	"github.com/rs/zerolog/log" | ||||||
|  | 	"tailscale.com/tailcfg" | ||||||
| 	"tailscale.com/types/key" | 	"tailscale.com/types/key" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | 	// The CapabilityVersion is used by Tailscale clients to indicate
 | ||||||
|  | 	// their codebase version. Tailscale clients can communicate over TS2021
 | ||||||
|  | 	// from CapabilityVersion 28, but we only have good support for it
 | ||||||
|  | 	// since https://github.com/tailscale/tailscale/pull/4323 (Noise in any HTTPS port).
 | ||||||
|  | 	//
 | ||||||
|  | 	// Related to this change, there is https://github.com/tailscale/tailscale/pull/5379,
 | ||||||
|  | 	// where CapabilityVersion 39 is introduced to indicate #4323 was merged.
 | ||||||
|  | 	//
 | ||||||
|  | 	// See also https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go
 | ||||||
|  | 	NoiseCapabilityVersion = 39 | ||||||
|  | 
 | ||||||
| 	// TODO(juan): remove this once https://github.com/juanfont/headscale/issues/727 is fixed.
 | 	// TODO(juan): remove this once https://github.com/juanfont/headscale/issues/727 is fixed.
 | ||||||
| 	registrationHoldoff        = time.Second * 5 | 	registrationHoldoff        = time.Second * 5 | ||||||
| 	reservedResponseHeaderSize = 4 | 	reservedResponseHeaderSize = 4 | ||||||
| @ -24,6 +37,69 @@ var ErrRegisterMethodCLIDoesNotSupportExpire = errors.New( | |||||||
| 	"machines registered with CLI does not support expire", | 	"machines registered with CLI does not support expire", | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // KeyHandler provides the Headscale pub key
 | ||||||
|  | // Listens in /key.
 | ||||||
|  | func (h *Headscale) KeyHandler( | ||||||
|  | 	writer http.ResponseWriter, | ||||||
|  | 	req *http.Request, | ||||||
|  | ) { | ||||||
|  | 	// New Tailscale clients send a 'v' parameter to indicate the CurrentCapabilityVersion
 | ||||||
|  | 	clientCapabilityStr := req.URL.Query().Get("v") | ||||||
|  | 	if clientCapabilityStr != "" { | ||||||
|  | 		log.Debug(). | ||||||
|  | 			Str("handler", "/key"). | ||||||
|  | 			Str("v", clientCapabilityStr). | ||||||
|  | 			Msg("New noise client") | ||||||
|  | 		clientCapabilityVersion, err := strconv.Atoi(clientCapabilityStr) | ||||||
|  | 		if err != nil { | ||||||
|  | 			writer.Header().Set("Content-Type", "text/plain; charset=utf-8") | ||||||
|  | 			writer.WriteHeader(http.StatusBadRequest) | ||||||
|  | 			_, err := writer.Write([]byte("Wrong params")) | ||||||
|  | 			if err != nil { | ||||||
|  | 				log.Error(). | ||||||
|  | 					Caller(). | ||||||
|  | 					Err(err). | ||||||
|  | 					Msg("Failed to write response") | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// TS2021 (Tailscale v2 protocol) requires to have a different key
 | ||||||
|  | 		if clientCapabilityVersion >= NoiseCapabilityVersion { | ||||||
|  | 			resp := tailcfg.OverTLSPublicKeyResponse{ | ||||||
|  | 				LegacyPublicKey: h.privateKey2019.Public(), | ||||||
|  | 				PublicKey:       h.noisePrivateKey.Public(), | ||||||
|  | 			} | ||||||
|  | 			writer.Header().Set("Content-Type", "application/json") | ||||||
|  | 			writer.WriteHeader(http.StatusOK) | ||||||
|  | 			err = json.NewEncoder(writer).Encode(resp) | ||||||
|  | 			if err != nil { | ||||||
|  | 				log.Error(). | ||||||
|  | 					Caller(). | ||||||
|  | 					Err(err). | ||||||
|  | 					Msg("Failed to write response") | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	log.Debug(). | ||||||
|  | 		Str("handler", "/key"). | ||||||
|  | 		Msg("New legacy client") | ||||||
|  | 
 | ||||||
|  | 	// Old clients don't send a 'v' parameter, so we send the legacy public key
 | ||||||
|  | 	writer.Header().Set("Content-Type", "text/plain; charset=utf-8") | ||||||
|  | 	writer.WriteHeader(http.StatusOK) | ||||||
|  | 	_, err := writer.Write([]byte(util.MachinePublicKeyStripPrefix(h.privateKey2019.Public()))) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Error(). | ||||||
|  | 			Caller(). | ||||||
|  | 			Err(err). | ||||||
|  | 			Msg("Failed to write response") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (h *Headscale) HealthHandler( | func (h *Headscale) HealthHandler( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	req *http.Request, | 	req *http.Request, | ||||||
| @ -21,9 +21,9 @@ type contextKey string | |||||||
| 
 | 
 | ||||||
| const machineNameContextKey = contextKey("machineName") | const machineNameContextKey = contextKey("machineName") | ||||||
| 
 | 
 | ||||||
| // handlePollCommon is the common code for the legacy and Noise protocols to
 | // handlePoll is the common code for the legacy and Noise protocols to
 | ||||||
| // managed the poll loop.
 | // managed the poll loop.
 | ||||||
| func (h *Headscale) handlePollCommon( | func (h *Headscale) handlePoll( | ||||||
| 	writer http.ResponseWriter, | 	writer http.ResponseWriter, | ||||||
| 	ctx context.Context, | 	ctx context.Context, | ||||||
| 	machine *types.Machine, | 	machine *types.Machine, | ||||||
| @ -93,5 +93,5 @@ func (h *Headscale) PollNetMapHandler( | |||||||
| 		Str("machine", machine.Hostname). | 		Str("machine", machine.Hostname). | ||||||
| 		Msg("A machine is entering polling via the legacy protocol") | 		Msg("A machine is entering polling via the legacy protocol") | ||||||
| 
 | 
 | ||||||
| 	h.handlePollCommon(writer, req.Context(), machine, mapRequest, false) | 	h.handlePoll(writer, req.Context(), machine, mapRequest, false) | ||||||
| } | } | ||||||
| @ -74,5 +74,5 @@ func (ns *noiseServer) NoisePollNetMapHandler( | |||||||
| 		Str("machine", machine.Hostname). | 		Str("machine", machine.Hostname). | ||||||
| 		Msg("A machine is entering polling via the Noise protocol") | 		Msg("A machine is entering polling via the Noise protocol") | ||||||
| 
 | 
 | ||||||
| 	ns.headscale.handlePollCommon(writer, req.Context(), machine, mapRequest, true) | 	ns.headscale.handlePoll(writer, req.Context(), machine, mapRequest, true) | ||||||
| } | } | ||||||
| @ -1 +0,0 @@ | |||||||
| package hscontrol |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user