Skip to content

Commit

Permalink
Ephemeral keys can now be reusable and non-reusable
Browse files Browse the repository at this point in the history
Fixes the issue reported in juanfont#1712. In Tailscale SaaS, ephemeral keys can be single-user or reusable. Until now, our ephemerals were only reusable. This PR makes us adhere to the .com behaviour.
  • Loading branch information
juanfont committed Mar 3, 2024
1 parent e15a083 commit a244eab
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
9 changes: 1 addition & 8 deletions cmd/headscale/cli/preauthkeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,6 @@ var listPreAuthKeys = &cobra.Command{
expiration = ColourTime(key.GetExpiration().AsTime())
}

var reusable string
if key.GetEphemeral() {
reusable = "N/A"
} else {
reusable = fmt.Sprintf("%v", key.GetReusable())
}

aclTags := ""

for _, tag := range key.GetAclTags() {
Expand All @@ -125,7 +118,7 @@ var listPreAuthKeys = &cobra.Command{
tableData = append(tableData, []string{
key.GetId(),
key.GetKey(),
reusable,
strconv.FormatBool(key.GetReusable()),
strconv.FormatBool(key.GetEphemeral()),
strconv.FormatBool(key.GetUsed()),
expiration,
Expand Down
2 changes: 1 addition & 1 deletion hscontrol/db/preauth_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func ValidatePreAuthKey(tx *gorm.DB, k string) (*types.PreAuthKey, error) {
return nil, ErrPreAuthKeyExpired
}

if pak.Reusable || pak.Ephemeral { // we don't need to check if has been used before
if pak.Reusable { // we don't need to check if has been used before
return &pak, nil
}

Expand Down
39 changes: 36 additions & 3 deletions hscontrol/db/preauth_keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ func (*Suite) TestNotReusableNotBeingUsedKey(c *check.C) {
c.Assert(key.ID, check.Equals, pak.ID)
}

func (*Suite) TestEphemeralKey(c *check.C) {
func (*Suite) TestEphemeralKeyReusable(c *check.C) {
user, err := db.CreateUser("test7")
c.Assert(err, check.IsNil)

pak, err := db.CreatePreAuthKey(user.Name, false, true, nil, nil)
pak, err := db.CreatePreAuthKey(user.Name, true, true, nil, nil)
c.Assert(err, check.IsNil)

now := time.Now().Add(-time.Second * 30)
Expand All @@ -142,7 +142,6 @@ func (*Suite) TestEphemeralKey(c *check.C) {
db.DB.Save(&node)

_, err = db.ValidatePreAuthKey(pak.Key)
// Ephemeral keys are by definition reusable
c.Assert(err, check.IsNil)

_, err = db.getNode("test7", "testest")
Expand All @@ -158,6 +157,40 @@ func (*Suite) TestEphemeralKey(c *check.C) {
c.Assert(err, check.NotNil)
}

func (*Suite) TestEphemeralKeyNotReusable(c *check.C) {
user, err := db.CreateUser("test7")
c.Assert(err, check.IsNil)

pak, err := db.CreatePreAuthKey(user.Name, false, true, nil, nil)
c.Assert(err, check.IsNil)

now := time.Now().Add(-time.Second * 30)
node := types.Node{
ID: 0,
Hostname: "testest",
UserID: user.ID,
RegisterMethod: util.RegisterMethodAuthKey,
LastSeen: &now,
AuthKeyID: uint(pak.ID),
}
db.DB.Save(&node)

_, err = db.ValidatePreAuthKey(pak.Key)
c.Assert(err, check.NotNil)

_, err = db.getNode("test7", "testest")
c.Assert(err, check.IsNil)

db.DB.Transaction(func(tx *gorm.DB) error {
ExpireEphemeralNodes(tx, time.Second*20)
return nil
})

// The machine record should have been deleted
_, err = db.getNode("test7", "testest")
c.Assert(err, check.NotNil)
}

func (*Suite) TestExpirePreauthKey(c *check.C) {
user, err := db.CreateUser("test3")
c.Assert(err, check.IsNil)
Expand Down

0 comments on commit a244eab

Please sign in to comment.