Skip to content

Ask for login passwords, log in by keyboard-interactive, stop agent hangs - #112

Merged
timhartmann7 merged 15 commits into
mainfrom
fix/password-login-and-auth-hangs
Sep 26, 2026
Merged

timhartmann7 merged 15 commits into
mainfrom
fix/password-login-and-auth-hangs

Conversation

@timhartmann7

Copy link
Copy Markdown
Owner

What this fixes

Asking for the login password. A host without a working key and without a saved password — typically one imported from ~/.ssh/config — failed with "SSH authentication failed" and offered no way in short of saving its password to disk. A terminal now asks inside the tab, the way ssh does (user@host's password:); a file session asks in a dialog (GUI) or popup (TUI). Three tries, Ctrl+C / Cancel ends it. A password the server accepted is kept in process memory only, keyed by user@host:port plus the ProxyJump chain; pollers and tunnels never ask, they pick it up and reconnect. On first contact the prompt shows the host key fingerprint it just recorded, and a remembered password is never sent to a host key first seen on that connection.

Servers that take the password only by keyboard-interactive (UniFi consoles, PasswordAuthentication no). The saved or typed password is now also offered by keyboard-interactive. russh 0.46 only handles keyboard-interactive as the first method of a connection, so that runs on a fresh connection (reused across retries); which method a login takes is remembered, so a wrong password costs one failed login, like ssh. A prompt for a one-time code never gets the password.

Logins that hung forever. Every login asks the SSH agent first and nothing bounded it: an agent that never answers, or one that refuses a signature (declined 1Password/Secretive approval, ssh-add -c), parked russh and left every host "connecting". The agent now gets 5 s to list keys and 60 s per signature; a refused signature hands russh the unsigned buffer so it moves on; the agent and keyboard-interactive phases run in tasks that own the connection, so a cancelled caller (restarted poller, stopped tunnel) can no longer leave russh spinning.

Why a host is down. The dashboard card shows the failure reason (hidden in streamer mode); the poller keeps the whole cause chain; a failed terminal in the TUI keeps its reason instead of "SSH session closed.".

Secrets in logs. omny -v / RUST_LOG could write the login password (russh dumps its first auth request at debug). Those dumps are filtered out whatever the level; a ProxyJump error no longer quotes hosts.toml (which may hold a saved password).

Contract

tech-gui.md gains a resolved CONTRACT GAP: event password-required { requestId, hostName, login, retry, newHostKey }, command answer_password { requestId, password | null }. Password inbound only; no DTO change.

Verified

  • Real OpenSSH 10 in Docker (password-only, keyboard-interactive-only, key-only), TUI on macOS 26 and the desktop app on Linux under Xvfb: keyboard-interactive host online with its saved password; inline terminal prompt (wrong → retry → shell, Ctrl+C); SFTP prompt; held tunnel wakes after a terminal login; hung and refusing agents; three wrong passwords = three Failed password on one connection; a connect cancelled mid-signature leaves no busy task; no password in the log at any level.
  • cargo fmt --check, cargo clippy --workspace --all-targets -D warnings, cargo test --workspace (new tests/login.rs against an in-process server), svelte-check, Vitest, Playwright.

Notes for review

  • Waived: the per-login method memo learns keyboard-interactive when both methods refused a password; an account that only the password method can log in while keyboard-interactive prompts for the same password is not handled (the alternative doubles failed logins per typo on common servers).
  • Limits of russh 0.46 (no remaining-methods list): a key-only server still gets a password prompt in a terminal; the real fix is a russh upgrade.
  • Key setup does not ask for a password; a password-only host without a saved password needs one terminal login first.
  • Pre-existing, not touched: tests/tunnel.rs is flaky on main too (ephemeral-port races in free_port, shared known_hosts); e2e/terminal.spec expects "Close web-1 · terminal" while the session label is the host only.

@timhartmann7
timhartmann7 merged commit 54eb5f1 into main Sep 26, 2026
6 checks passed
@timhartmann7
timhartmann7 deleted the fix/password-login-and-auth-hangs branch September 26, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant