From aa27709e602ffd39727fb2b8b3ed95d650fce74a Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Fri, 25 Jun 2021 18:57:08 +0200 Subject: [PATCH] Update code to Tailscale 1.10 --- api.go | 27 +++++++++++++-------------- app.go | 8 ++++---- cli.go | 4 ++-- machine.go | 10 +++++----- namespaces.go | 1 - utils.go | 12 ++++++------ 6 files changed, 30 insertions(+), 32 deletions(-) diff --git a/api.go b/api.go index 845a3201..92501a4e 100644 --- a/api.go +++ b/api.go @@ -16,7 +16,7 @@ import ( "gorm.io/gorm" "inet.af/netaddr" "tailscale.com/tailcfg" - "tailscale.com/wgengine/wgcfg" + "tailscale.com/types/wgkey" ) // KeyHandler provides the Headscale pub key @@ -61,7 +61,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) { func (h *Headscale) RegistrationHandler(c *gin.Context) { body, _ := io.ReadAll(c.Request.Body) mKeyStr := c.Param("id") - mKey, err := wgcfg.ParseHexKey(mKeyStr) + mKey, err := wgkey.ParseHex(mKeyStr) if err != nil { log.Printf("Cannot parse machine key: %s", err) c.String(http.StatusInternalServerError, "Sad!") @@ -89,7 +89,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { Expiry: &req.Expiry, MachineKey: mKey.HexString(), Name: req.Hostinfo.Hostname, - NodeKey: wgcfg.Key(req.NodeKey).HexString(), + NodeKey: wgkey.Key(req.NodeKey).HexString(), } if err := db.Create(&m).Error; err != nil { log.Printf("Could not create row: %s", err) @@ -105,7 +105,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { resp := tailcfg.RegisterResponse{} // We have the updated key! - if m.NodeKey == wgcfg.Key(req.NodeKey).HexString() { + if m.NodeKey == wgkey.Key(req.NodeKey).HexString() { if m.Registered { log.Printf("[%s] Client is registered and we have the current NodeKey. All clear to /map", m.Name) resp.AuthURL = "" @@ -135,9 +135,9 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { } // The NodeKey we have matches OldNodeKey, which means this is a refresh after an key expiration - if m.NodeKey == wgcfg.Key(req.OldNodeKey).HexString() { + if m.NodeKey == wgkey.Key(req.OldNodeKey).HexString() { log.Printf("[%s] We have the OldNodeKey in the database. This is a key refresh", m.Name) - m.NodeKey = wgcfg.Key(req.NodeKey).HexString() + m.NodeKey = wgkey.Key(req.NodeKey).HexString() db.Save(&m) resp.AuthURL = "" @@ -192,7 +192,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { func (h *Headscale) PollNetMapHandler(c *gin.Context) { body, _ := io.ReadAll(c.Request.Body) mKeyStr := c.Param("id") - mKey, err := wgcfg.ParseHexKey(mKeyStr) + mKey, err := wgkey.ParseHex(mKeyStr) if err != nil { log.Printf("Cannot parse client key: %s", err) return @@ -218,7 +218,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { hostinfo, _ := json.Marshal(req.Hostinfo) m.Name = req.Hostinfo.Hostname m.HostInfo = datatypes.JSON(hostinfo) - m.DiscoKey = wgcfg.Key(req.DiscoKey).HexString() + m.DiscoKey = wgkey.Key(req.DiscoKey).HexString() now := time.Now().UTC() // From Tailscale client: @@ -334,7 +334,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { }) } -func (h *Headscale) keepAlive(cancel chan []byte, pollData chan []byte, mKey wgcfg.Key, req tailcfg.MapRequest, m Machine) { +func (h *Headscale) keepAlive(cancel chan []byte, pollData chan []byte, mKey wgkey.Key, req tailcfg.MapRequest, m Machine) { for { select { case <-cancel: @@ -355,7 +355,7 @@ func (h *Headscale) keepAlive(cancel chan []byte, pollData chan []byte, mKey wgc } } -func (h *Headscale) getMapResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) { +func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) { node, err := m.toNode() if err != nil { log.Printf("Cannot convert to node: %s", err) @@ -376,7 +376,6 @@ func (h *Headscale) getMapResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Mac PacketFilter: tailcfg.FilterAllowAll, DERPMap: h.cfg.DerpMap, UserProfiles: []tailcfg.UserProfile{}, - Roles: []tailcfg.Role{}, } var respBody []byte @@ -402,7 +401,7 @@ func (h *Headscale) getMapResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Mac return &data, nil } -func (h *Headscale) getMapKeepAliveResponse(mKey wgcfg.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) { +func (h *Headscale) getMapKeepAliveResponse(mKey wgkey.Key, req tailcfg.MapRequest, m Machine) (*[]byte, error) { resp := tailcfg.MapResponse{ KeepAlive: true, } @@ -428,7 +427,7 @@ func (h *Headscale) getMapKeepAliveResponse(mKey wgcfg.Key, req tailcfg.MapReque return &data, nil } -func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgcfg.Key, req tailcfg.RegisterRequest, m Machine) { +func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgkey.Key, req tailcfg.RegisterRequest, m Machine) { resp := tailcfg.RegisterResponse{} pak, err := h.checkKeyValidity(req.Auth.AuthKey) if err != nil { @@ -452,7 +451,7 @@ func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgcfg.Key, m.AuthKeyID = uint(pak.ID) m.IPAddress = ip.String() m.NamespaceID = pak.NamespaceID - m.NodeKey = wgcfg.Key(req.NodeKey).HexString() // we update it just in case + m.NodeKey = wgkey.Key(req.NodeKey).HexString() // we update it just in case m.Registered = true m.RegisterMethod = "authKey" db.Save(&m) diff --git a/app.go b/app.go index 4a846e23..0cdc3105 100644 --- a/app.go +++ b/app.go @@ -13,7 +13,7 @@ import ( "github.com/gin-gonic/gin" "golang.org/x/crypto/acme/autocert" "tailscale.com/tailcfg" - "tailscale.com/wgengine/wgcfg" + "tailscale.com/types/wgkey" ) // Config contains the initial Headscale configuration @@ -46,8 +46,8 @@ type Headscale struct { dbString string dbType string dbDebug bool - publicKey *wgcfg.Key - privateKey *wgcfg.PrivateKey + publicKey *wgkey.Key + privateKey *wgkey.Private pollMu sync.Mutex clientsPolling map[uint64]chan []byte // this is by all means a hackity hack @@ -59,7 +59,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) { if err != nil { return nil, err } - privKey, err := wgcfg.ParsePrivateKey(string(content)) + privKey, err := wgkey.ParsePrivate(string(content)) if err != nil { return nil, err } diff --git a/cli.go b/cli.go index 31419f3e..2ab1061f 100644 --- a/cli.go +++ b/cli.go @@ -5,7 +5,7 @@ import ( "log" "gorm.io/gorm" - "tailscale.com/wgengine/wgcfg" + "tailscale.com/types/wgkey" ) // RegisterMachine is executed from the CLI to register a new Machine using its MachineKey @@ -14,7 +14,7 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err if err != nil { return nil, err } - mKey, err := wgcfg.ParseHexKey(key) + mKey, err := wgkey.ParseHex(key) if err != nil { return nil, err } diff --git a/machine.go b/machine.go index 9b15b1a1..59dbf16f 100644 --- a/machine.go +++ b/machine.go @@ -11,7 +11,7 @@ import ( "gorm.io/datatypes" "inet.af/netaddr" "tailscale.com/tailcfg" - "tailscale.com/wgengine/wgcfg" + "tailscale.com/types/wgkey" ) // Machine is a Headscale client @@ -23,7 +23,7 @@ type Machine struct { IPAddress string Name string NamespaceID uint - Namespace Namespace + Namespace Namespace `gorm:"foreignKey:NamespaceID"` Registered bool // temp RegisterMethod string @@ -48,18 +48,18 @@ func (m Machine) isAlreadyRegistered() bool { } func (m Machine) toNode() (*tailcfg.Node, error) { - nKey, err := wgcfg.ParseHexKey(m.NodeKey) + nKey, err := wgkey.ParseHex(m.NodeKey) if err != nil { return nil, err } - mKey, err := wgcfg.ParseHexKey(m.MachineKey) + mKey, err := wgkey.ParseHex(m.MachineKey) if err != nil { return nil, err } var discoKey tailcfg.DiscoKey if m.DiscoKey != "" { - dKey, err := wgcfg.ParseHexKey(m.DiscoKey) + dKey, err := wgkey.ParseHex(m.DiscoKey) if err != nil { return nil, err } diff --git a/namespaces.go b/namespaces.go index 0eedad76..afdbb9fb 100644 --- a/namespaces.go +++ b/namespaces.go @@ -144,7 +144,6 @@ func (n *Namespace) toUser() *tailcfg.User { ProfilePicURL: "", Domain: "", Logins: []tailcfg.LoginID{}, - Roles: []tailcfg.RoleID{}, Created: time.Time{}, } return &u diff --git a/utils.go b/utils.go index eff20e2d..c2271aa9 100644 --- a/utils.go +++ b/utils.go @@ -19,7 +19,7 @@ import ( "golang.org/x/crypto/nacl/box" "gorm.io/gorm" - "tailscale.com/wgengine/wgcfg" + "tailscale.com/types/wgkey" ) // Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors @@ -27,11 +27,11 @@ type Error string func (e Error) Error() string { return string(e) } -func decode(msg []byte, v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) error { +func decode(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error { return decodeMsg(msg, v, pubKey, privKey) } -func decodeMsg(msg []byte, v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) error { +func decodeMsg(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error { decrypted, err := decryptMsg(msg, pubKey, privKey) if err != nil { return err @@ -43,7 +43,7 @@ func decodeMsg(msg []byte, v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.Priv return nil } -func decryptMsg(msg []byte, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte, error) { +func decryptMsg(msg []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) { var nonce [24]byte if len(msg) < len(nonce)+1 { return nil, fmt.Errorf("response missing nonce, len=%d", len(msg)) @@ -59,7 +59,7 @@ func decryptMsg(msg []byte, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byt return decrypted, nil } -func encode(v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte, error) { +func encode(v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) { b, err := json.Marshal(v) if err != nil { return nil, err @@ -67,7 +67,7 @@ func encode(v interface{}, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte return encodeMsg(b, pubKey, privKey) } -func encodeMsg(b []byte, pubKey *wgcfg.Key, privKey *wgcfg.PrivateKey) ([]byte, error) { +func encodeMsg(b []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, error) { var nonce [24]byte if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { panic(err)