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) +}