From 30788e1a70969f541bfa699d93f675b24775a5bb Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Wed, 13 Oct 2021 18:13:26 +0200 Subject: [PATCH 1/3] Add AlreadyUsed field to Auth Keys (fixes #157 and #158) --- api.go | 3 +++ cmd/headscale/cli/preauthkeys.go | 3 ++- preauth_keys.go | 4 ++-- preauth_keys_test.go | 13 +++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/api.go b/api.go index 13955d39..f68852dd 100644 --- a/api.go +++ b/api.go @@ -395,6 +395,9 @@ func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgkey.Key, m.RegisterMethod = "authKey" db.Save(&m) + pak.AlreadyUsed = true + db.Save(&pak) + resp.MachineAuthorized = true resp.User = *pak.Namespace.toUser() respBody, err := encode(resp, &idKey, h.privateKey) diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 1340267e..28bbb7e7 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -57,7 +57,7 @@ var listPreAuthKeys = &cobra.Command{ return } - d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Expiration", "Created"}} + d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "AlreadyUsed", "Expiration", "Created"}} for _, k := range *keys { expiration := "-" if k.Expiration != nil { @@ -76,6 +76,7 @@ var listPreAuthKeys = &cobra.Command{ k.Key, reusable, strconv.FormatBool(k.Ephemeral), + fmt.Sprintf("%v", k.AlreadyUsed), expiration, k.CreatedAt.Format("2006-01-02 15:04:05"), }) diff --git a/preauth_keys.go b/preauth_keys.go index cc849fc0..babc2ff6 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -21,6 +21,7 @@ type PreAuthKey struct { Namespace Namespace Reusable bool Ephemeral bool `gorm:"default:false"` + AlreadyUsed bool `gorm:"default:false"` CreatedAt *time.Time Expiration *time.Time @@ -110,11 +111,10 @@ func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { return nil, err } - if len(machines) != 0 { + if len(machines) != 0 || pak.AlreadyUsed { return nil, errorAuthKeyNotReusableAlreadyUsed } - // missing here validation on current usage return &pak, nil } diff --git a/preauth_keys_test.go b/preauth_keys_test.go index 37f2e4dd..80d24e37 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -180,3 +180,16 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { c.Assert(err, check.Equals, errorAuthKeyExpired) c.Assert(p, check.IsNil) } + +func (*Suite) TestNotReusableMarkedAsAlreadyUsed(c *check.C) { + n, err := h.CreateNamespace("test6") + c.Assert(err, check.IsNil) + + pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) + c.Assert(err, check.IsNil) + pak.AlreadyUsed = true + h.db.Save(&pak) + + _, err = h.checkKeyValidity(pak.Key) + c.Assert(err, check.Equals, errorAuthKeyNotReusableAlreadyUsed) +} From 93517aa6f897c37902a5cb3c24c16296cc09d0be Mon Sep 17 00:00:00 2001 From: Juan Font Date: Wed, 13 Oct 2021 22:51:55 +0200 Subject: [PATCH 2/3] Apply suggestions from code review Renamed AlreadyUsed to Used Co-authored-by: Kristoffer Dalby --- api.go | 2 +- cmd/headscale/cli/preauthkeys.go | 4 ++-- preauth_keys.go | 4 ++-- preauth_keys_test.go | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api.go b/api.go index f68852dd..0aad5ee9 100644 --- a/api.go +++ b/api.go @@ -395,7 +395,7 @@ func (h *Headscale) handleAuthKey(c *gin.Context, db *gorm.DB, idKey wgkey.Key, m.RegisterMethod = "authKey" db.Save(&m) - pak.AlreadyUsed = true + pak.Used = true db.Save(&pak) resp.MachineAuthorized = true diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 28bbb7e7..cb75b287 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -57,7 +57,7 @@ var listPreAuthKeys = &cobra.Command{ return } - d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "AlreadyUsed", "Expiration", "Created"}} + d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"}} for _, k := range *keys { expiration := "-" if k.Expiration != nil { @@ -76,7 +76,7 @@ var listPreAuthKeys = &cobra.Command{ k.Key, reusable, strconv.FormatBool(k.Ephemeral), - fmt.Sprintf("%v", k.AlreadyUsed), + fmt.Sprintf("%v", k.Used), expiration, k.CreatedAt.Format("2006-01-02 15:04:05"), }) diff --git a/preauth_keys.go b/preauth_keys.go index babc2ff6..05af9260 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -21,7 +21,7 @@ type PreAuthKey struct { Namespace Namespace Reusable bool Ephemeral bool `gorm:"default:false"` - AlreadyUsed bool `gorm:"default:false"` + Used bool `gorm:"default:false"` CreatedAt *time.Time Expiration *time.Time @@ -111,7 +111,7 @@ func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { return nil, err } - if len(machines) != 0 || pak.AlreadyUsed { + if len(machines) != 0 || pak.Used { return nil, errorAuthKeyNotReusableAlreadyUsed } diff --git a/preauth_keys_test.go b/preauth_keys_test.go index 80d24e37..364733af 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -181,13 +181,13 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { c.Assert(p, check.IsNil) } -func (*Suite) TestNotReusableMarkedAsAlreadyUsed(c *check.C) { +func (*Suite) TestNotReusableMarkedAsUsed(c *check.C) { n, err := h.CreateNamespace("test6") c.Assert(err, check.IsNil) pak, err := h.CreatePreAuthKey(n.Name, false, false, nil) c.Assert(err, check.IsNil) - pak.AlreadyUsed = true + pak.Used = true h.db.Save(&pak) _, err = h.checkKeyValidity(pak.Key) From 9a6ac6e3e6dc610293670c68429c8361de195978 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Wed, 13 Oct 2021 23:23:07 +0200 Subject: [PATCH 3/3] Reword errSingleUseAuthKeyHasBeenUsed --- preauth_keys.go | 4 ++-- preauth_keys_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/preauth_keys.go b/preauth_keys.go index cc849fc0..ed832538 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -11,7 +11,7 @@ import ( const errorAuthKeyNotFound = Error("AuthKey not found") const errorAuthKeyExpired = Error("AuthKey expired") -const errorAuthKeyNotReusableAlreadyUsed = Error("AuthKey not reusable already used") +const errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") // PreAuthKey describes a pre-authorization key usable in a particular namespace type PreAuthKey struct { @@ -111,7 +111,7 @@ func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { } if len(machines) != 0 { - return nil, errorAuthKeyNotReusableAlreadyUsed + return nil, errSingleUseAuthKeyHasBeenUsed } // missing here validation on current usage diff --git a/preauth_keys_test.go b/preauth_keys_test.go index 37f2e4dd..53616bb1 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -87,7 +87,7 @@ func (*Suite) TestAlreadyUsedKey(c *check.C) { h.db.Save(&m) p, err := h.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errorAuthKeyNotReusableAlreadyUsed) + c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) c.Assert(p, check.IsNil) }