mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	fix preauth key logging in as previous user (#1920)
* 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>
This commit is contained in:
		
							parent
							
								
									55b35f4160
								
							
						
					
					
						commit
						1c6bfc503c
					
				
							
								
								
									
										1
									
								
								.github/workflows/test-integration.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/test-integration.yaml
									
									
									
									
										vendored
									
									
								
							@ -26,6 +26,7 @@ jobs:
 | 
				
			|||||||
          - TestPreAuthKeyCommand
 | 
					          - TestPreAuthKeyCommand
 | 
				
			||||||
          - TestPreAuthKeyCommandWithoutExpiry
 | 
					          - TestPreAuthKeyCommandWithoutExpiry
 | 
				
			||||||
          - TestPreAuthKeyCommandReusableEphemeral
 | 
					          - TestPreAuthKeyCommandReusableEphemeral
 | 
				
			||||||
 | 
					          - TestPreAuthKeyCorrectUserLoggedInCommand
 | 
				
			||||||
          - TestApiKeyCommand
 | 
					          - TestApiKeyCommand
 | 
				
			||||||
          - TestNodeTagCommand
 | 
					          - TestNodeTagCommand
 | 
				
			||||||
          - TestNodeAdvertiseTagNoACLCommand
 | 
					          - TestNodeAdvertiseTagNoACLCommand
 | 
				
			||||||
 | 
				
			|||||||
@ -315,13 +315,16 @@ func (h *Headscale) handleAuthKey(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		node.NodeKey = nodeKey
 | 
							node.NodeKey = nodeKey
 | 
				
			||||||
		node.AuthKeyID = uint(pak.ID)
 | 
							node.AuthKeyID = uint(pak.ID)
 | 
				
			||||||
		err := h.db.NodeSetExpiry(node.ID, registerRequest.Expiry)
 | 
							node.Expiry = ®isterRequest.Expiry
 | 
				
			||||||
 | 
							node.User = pak.User
 | 
				
			||||||
 | 
							node.UserID = pak.UserID
 | 
				
			||||||
 | 
							err := h.db.DB.Save(node).Error
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Error().
 | 
								log.Error().
 | 
				
			||||||
				Caller().
 | 
									Caller().
 | 
				
			||||||
				Str("node", node.Hostname).
 | 
									Str("node", node.Hostname).
 | 
				
			||||||
				Err(err).
 | 
									Err(err).
 | 
				
			||||||
				Msg("Failed to refresh node")
 | 
									Msg("failed to save node after logging in with auth key")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -344,7 +347,7 @@ func (h *Headscale) handleAuthKey(
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx := types.NotifyCtx(context.Background(), "handle-authkey", "na")
 | 
							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 {
 | 
						} else {
 | 
				
			||||||
		now := time.Now().UTC()
 | 
							now := time.Now().UTC()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -388,6 +388,101 @@ func TestPreAuthKeyCommandReusableEphemeral(t *testing.T) {
 | 
				
			|||||||
	assert.Len(t, listedPreAuthKeys, 3)
 | 
						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) {
 | 
					func TestApiKeyCommand(t *testing.T) {
 | 
				
			||||||
	IntegrationSkip(t)
 | 
						IntegrationSkip(t)
 | 
				
			||||||
	t.Parallel()
 | 
						t.Parallel()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user