Skip to content

fix: Jump host authentication fails with empty SSH agent despite available key files #116

@inureyes

Description

@inureyes

Problem / Background

Jump host authentication fails when SSH agent is running but has no loaded identities, even though valid SSH key files exist on disk. This differs from OpenSSH behavior, which gracefully falls back to key files when the agent returns an empty identity list.

This is a common scenario where users have SSH_AUTH_SOCK set (agent running) but haven't loaded keys into the agent. OpenSSH handles this transparently, but bssh does not.

Steps to Reproduce

  1. Ensure SSH agent is running with SSH_AUTH_SOCK environment variable set
  2. Verify agent has no loaded keys: ssh-add -l returns "The agent has no identities"
  3. Have valid SSH key files in ~/.ssh/ (e.g., id_ed25519, id_rsa)
  4. Run: bssh -J 'user@jumphost:port' user@target 'command'

Expected Behavior

  • OpenSSH ssh -J works because it falls back to key files when agent is empty
  • bssh should also fall back to ~/.ssh/id_ed25519, ~/.ssh/id_rsa, etc.

Actual Behavior

  • bssh detects SSH_AUTH_SOCK and attempts agent authentication
  • Agent returns empty identity list: identities: [12, 0, 0, 0, 0]
  • Authentication fails with SshError(Disconnect)
  • Error message: "Failed to establish jump host connection"

Root Cause Analysis

In src/jump/chain/auth.rs, lines 55-61 and 96-100:

// Line 55-61
if use_agent {
    if std::env::var("SSH_AUTH_SOCK").is_ok() {
        return Ok(AuthMethod::Agent);  // Returns immediately without checking if agent has keys
    }
}

// Line 96-100 (fallback section)
if std::env::var("SSH_AUTH_SOCK").is_ok() {
    return Ok(AuthMethod::Agent);  // Same issue - no check for empty agent
}

The code returns AuthMethod::Agent when SSH_AUTH_SOCK exists, without verifying that the agent actually has loaded identities. When authentication is attempted with an empty agent, it fails.

Proposed Solution

  1. Query the agent for identities before returning AuthMethod::Agent
  2. If the agent has no identities, fall through to key file authentication
  3. This matches OpenSSH behavior: try agent first, then fall back to key files

Example fix approach:

if use_agent {
    if std::env::var("SSH_AUTH_SOCK").is_ok() {
        // Check if agent has any identities before using it
        if agent_has_identities().await? {
            return Ok(AuthMethod::Agent);
        }
        // Fall through to key file authentication
    }
}

Acceptance Criteria

  • Query SSH agent for identities before selecting agent authentication
  • Fall back to key file authentication when agent has no identities
  • Maintain existing behavior when agent has loaded keys
  • Add unit/integration tests for empty agent scenario
  • Matches OpenSSH ssh -J behavior in this scenario

Workarounds

  1. Add keys to agent before running bssh: ssh-add ~/.ssh/id_ed25519
  2. Specify key file explicitly: bssh -i ~/.ssh/id_ed25519 -J 'user@jump' ...

Technical Considerations

  • The agent identity check should be efficient (single request to agent)
  • Consider caching the identity check result if multiple authentication attempts are made
  • Ensure proper error handling if agent communication fails during identity check

Affected Code

  • src/jump/chain/auth.rs - determine_auth_method() function

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions