Repository navigation
Sign in through keyboard-interactive, explain rejections, and dial each address with its own timeout - #177
Open
Sadykhzadeh wants to merge 6 commits into
Open
Sign in through keyboard-interactive, explain rejections, and dial each address with its own timeout#177Sadykhzadeh wants to merge 6 commits into
Sadykhzadeh wants to merge 6 commits into
Conversation
russh's connect tries the resolved addresses one after another with no per-address bound, so a host whose first address is a black-holed IPv6 route spent the whole 20 s connect timeout there and never reached its working IPv4 address. Resolve the name ourselves, give each address 5 s, keep the overall cap, and hand the stream to connect_stream. A failed dial now says which addresses were tried and why each failed. The dialed socket also gets TCP_NODELAY, as OpenSSH sets for interactive sessions; with Nagle on, keystrokes waited on the server's delayed ACK and typing lagged noticeably on high-latency links.
Password hosts only ever tried the password method, so servers that disable it and take the password through keyboard-interactive (FreeBSD's default sshd, many PAM setups) refused them outright. Probe with "none" first like OpenSSH, then use password and/or keyboard-interactive as the server offers them. The password is only given to a single hidden prompt, once; prompts for anything more, such as a one-time code, are refused with an explanation instead of being sent the password. A rejection used to read "authentication rejected by server" and nothing else. It now names the methods the server still accepts, says when the server does not offer password or publickey sign-in at all, and reports a partial success as a further step Clavyn cannot complete yet.
A server that offers password and rejects it would check the same credential through keyboard-interactive, so the retry could not succeed and only counted twice against MaxAuthTries and fail2ban.
PR Summary by QodoSupport keyboard-interactive SSH sign-in and bounded address dialing
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
The loop answered five rounds but never looked at the reply to the fifth, so a server that accepted there was reported as asking for too many rounds.
… a credential nobody sent Only an address with a fallback after it needs the per-address cap; the last or only one was cut off at 5 s where it used to get the full 20. A server that named no method at all was reported as having rejected the password, even when the password was never sent.
They rely on an address that swallows the handshake; a network that refuses it quickly would make them pass or fail for the wrong reason.
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.
Closes #176. All changes are in
core/src/connection.rsand its tests;session.rsis untouched, so this doesn't overlap the #140 stack.Sign-in
Which methods the server accepts: a Password host first sends a
nonerequest, as OpenSSH does, to learn the server's methods.passwordis offered, it is used.keyboard-interactiveis used.Keyboard-interactive is answered the way OpenSSH answers a PAM password prompt:
the server asks for more than the password ("Password:", "Verification code:"); Clavyn cannot answer additional sign-in prompts such as one-time codes yet.A rejected password is not retried through keyboard-interactive. Both methods check the same credential, so a second attempt can't succeed. It would only count twice against
MaxAuthTriesand fail2ban.Why a sign-in failed: the message keeps the
authentication rejected by server:prefix, then says one of:the server rejected the password (it accepts: password, publickey)the server does not accept password sign-in (it accepts: publickey)the server accepted this step but requires another: publickey; Clavyn cannot complete multi-step sign-in yetThe frontend only displays this text and never matches on it.
Connecting
lookup_host, and each address gets its own 5 s in resolver order. The overall 20 s cap still covers resolve, dial and the handshake. The stream then goes torussh::client::connect_stream, so host key checking is unchanged.[2001:db8::1]:22: timed out after 5s; 192.0.2.7:22: Connection refused.config.nodelayfor a stream it didn't open itself.Tests
Each fails against
main(or, for the resend test, against the earlier commit on this branch):ssh_roundtrip.rs):a_password_is_answered_through_keyboard_interactivea_second_factor_prompt_is_refused_without_sending_the_passworda_rejected_password_is_not_sent_a_second_timea_rejected_password_names_the_methods_the_server_acceptsa_server_without_password_sign_in_says_soa_partial_success_is_reported_as_a_further_stepconnection.rs):a_silent_address_does_not_hold_up_the_next_one: a black-hole address, then a loopback listener; must finish in under 10 s.dialed_streams_disable_naglea_failed_dial_names_every_addressTrade-offs and limits
noneprobe costs one round trip per password sign-in.Test plan
cargo test -p clavyn-core: 121 + 5 + 32 + 15 passedcargo clippy -p clavyn-core --all-targets: nothing newnode scripts/verify/check-comments.mjs: okNeed help on this PR? Tag
@codesmith-botwith what you need.