diff --git a/api.go b/api.go index 13955d39..0aad5ee9 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.Used = 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..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", "Expiration", "Created"}} + d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Used", "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.Used), expiration, k.CreatedAt.Format("2006-01-02 15:04:05"), }) diff --git a/preauth_keys.go b/preauth_keys.go index cc849fc0..de10cdb7 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 { @@ -21,6 +21,7 @@ type PreAuthKey struct { Namespace Namespace Reusable bool Ephemeral bool `gorm:"default:false"` + Used 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 { - return nil, errorAuthKeyNotReusableAlreadyUsed + if len(machines) != 0 || pak.Used { + return nil, errSingleUseAuthKeyHasBeenUsed } - // missing here validation on current usage return &pak, nil } diff --git a/preauth_keys_test.go b/preauth_keys_test.go index 37f2e4dd..f8973eaf 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) } @@ -180,3 +180,16 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { c.Assert(err, check.Equals, errorAuthKeyExpired) c.Assert(p, check.IsNil) } + +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.Used = true + h.db.Save(&pak) + + _, err = h.checkKeyValidity(pak.Key) + c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) +}