Skip to content

Commit

Permalink
fix preauth key logging in as previous user (#1920)
Browse files Browse the repository at this point in the history
* add test case to reproduce #1885

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>

* fix preauth key issue logging in as wrong user

Fixes #1885

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>

* add test to gh

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>

---------

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
  • Loading branch information
kradalby authored May 2, 2024
1 parent 55b35f4 commit 1c6bfc5
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
- TestPreAuthKeyCommand
- TestPreAuthKeyCommandWithoutExpiry
- TestPreAuthKeyCommandReusableEphemeral
- TestPreAuthKeyCorrectUserLoggedInCommand
- TestApiKeyCommand
- TestNodeTagCommand
- TestNodeAdvertiseTagNoACLCommand
Expand Down
9 changes: 6 additions & 3 deletions hscontrol/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,16 @@ func (h *Headscale) handleAuthKey(

node.NodeKey = nodeKey
node.AuthKeyID = uint(pak.ID)
err := h.db.NodeSetExpiry(node.ID, registerRequest.Expiry)
node.Expiry = &registerRequest.Expiry
node.User = pak.User
node.UserID = pak.UserID
err := h.db.DB.Save(node).Error
if err != nil {
log.Error().
Caller().
Str("node", node.Hostname).
Err(err).
Msg("Failed to refresh node")
Msg("failed to save node after logging in with auth key")

return
}
Expand All @@ -344,7 +347,7 @@ func (h *Headscale) handleAuthKey(
}

ctx := types.NotifyCtx(context.Background(), "handle-authkey", "na")
h.nodeNotifier.NotifyWithIgnore(ctx, types.StateUpdateExpire(node.ID, registerRequest.Expiry), node.ID)
h.nodeNotifier.NotifyAll(ctx, types.StateUpdate{Type: types.StatePeerChanged, ChangeNodes: []types.NodeID{node.ID}})
} else {
now := time.Now().UTC()

Expand Down
95 changes: 95 additions & 0 deletions integration/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,101 @@ func TestPreAuthKeyCommandReusableEphemeral(t *testing.T) {
assert.Len(t, listedPreAuthKeys, 3)
}

func TestPreAuthKeyCorrectUserLoggedInCommand(t *testing.T) {
IntegrationSkip(t)
t.Parallel()

user1 := "user1"
user2 := "user2"

scenario, err := NewScenario(dockertestMaxWait())
assertNoErr(t, err)
defer scenario.Shutdown()

spec := map[string]int{
user1: 1,
user2: 0,
}

err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clipak"))
assertNoErr(t, err)

headscale, err := scenario.Headscale()
assertNoErr(t, err)

var user2Key v1.PreAuthKey

err = executeAndUnmarshal(
headscale,
[]string{
"headscale",
"preauthkeys",
"--user",
user2,
"create",
"--reusable",
"--expiration",
"24h",
"--output",
"json",
"--tags",
"tag:test1,tag:test2",
},
&user2Key,
)
assertNoErr(t, err)

allClients, err := scenario.ListTailscaleClients()
assertNoErrListClients(t, err)

assert.Len(t, allClients, 1)

client := allClients[0]

// Log out from user1
err = client.Logout()
assertNoErr(t, err)

err = scenario.WaitForTailscaleLogout()
assertNoErr(t, err)

status, err := client.Status()
assertNoErr(t, err)
if status.BackendState == "Starting" || status.BackendState == "Running" {
t.Fatalf("expected node to be logged out, backend state: %s", status.BackendState)
}

err = client.Login(headscale.GetEndpoint(), user2Key.GetKey())
assertNoErr(t, err)

status, err = client.Status()
assertNoErr(t, err)
if status.BackendState != "Running" {
t.Fatalf("expected node to be logged in, backend state: %s", status.BackendState)
}

if status.Self.UserID.String() != "userid:2" {
t.Fatalf("expected node to be logged in as userid:2, got: %s", status.Self.UserID.String())
}

var listNodes []v1.Node
err = executeAndUnmarshal(
headscale,
[]string{
"headscale",
"nodes",
"list",
"--output",
"json",
},
&listNodes,
)
assert.Nil(t, err)
assert.Len(t, listNodes, 1)

assert.Equal(t, "user2", listNodes[0].User.Name)
}

func TestApiKeyCommand(t *testing.T) {
IntegrationSkip(t)
t.Parallel()
Expand Down

0 comments on commit 1c6bfc5

Please sign in to comment.