Ask for login passwords, log in by keyboard-interactive, stop agent hangs - #112
Merged
Merged
Conversation
This was referenced Sep 26, 2026
Closed
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 waysshdoes (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 byuser@host:portplus 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, likessh. 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_LOGcould 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 quoteshosts.toml(which may hold a saved password).Contract
tech-gui.mdgains a resolved CONTRACT GAP: eventpassword-required { requestId, hostName, login, retry, newHostKey }, commandanswer_password { requestId, password | null }. Password inbound only; no DTO change.Verified
Failed passwordon 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(newtests/login.rsagainst an in-process server),svelte-check, Vitest, Playwright.Notes for review
tests/tunnel.rsis flaky on main too (ephemeral-port races infree_port, sharedknown_hosts);e2e/terminal.specexpects "Close web-1 · terminal" while the session label is the host only.