Repository navigation
Conversation
`Entry::from_str` split the line with `split_once(' ')`, which only
recognises a line whose fields are separated by exactly one ASCII space.
OpenSSH's known_hosts format separates fields by any run of whitespace, so
three shapes that OpenSSH reads correctly were rejected outright:
* tab-separated: `host\tssh-ed25519\t<base64>` -> FormatEncoding
* indented: ` host ssh-ed25519 <base64>` -> FormatEncoding
* runs of spaces: `host ssh-ed25519 <base64>` -> Encoding(Length)
Because the error is per-line, `KnownHosts::new(..)` silently yields an
`Err` for such a line and a caller that stops at the first error never
sees the rest of the file.
Reproduced against `ssh-key` 0.7.0-rc.12; OpenSSH 8.2p1 accepts all three
shapes (`ssh-keygen -F` matches each of them).
The fix splits on `char::is_whitespace` instead, taking the optional marker
as a token rather than assuming a single space follows it, and re-joins the
remainder with single spaces before handing it to `PublicKey`'s parser --
which does require exactly one space between `keytype` and the base64 body
(`decode_segment` in public/ssh_format.rs stops only on `b' '`).
`marker` is therefore now built as `format!("@{marker_str}")` from the
token with the `@` already stripped.
Tests added for all three shapes plus a marker followed by a tab.
Member
|
A couple suggestions:
Otherwise looks good, thanks! |
This branch has not been deployed
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
Entry::from_strsplit each line withsplit_once(' '), so it only accepted a line whose fields are separated by exactly one ASCII space. Theknown_hostsformat separates fields by any run of whitespace, so three shapes OpenSSH reads correctly were rejected outright:ssh-keygen -F)ssh-key0.7.0-rc.12 (before)host\tssh-ed25519\t<base64>Err(FormatEncoding)host ssh-ed25519 <base64>Err(FormatEncoding)host ssh-ed25519 <base64>Err(Encoding(Length))@revoked\thost\t...Err(FormatEncoding)Because the error is per-line,
KnownHosts::new(..)yieldsErrfor such a line, and a caller that stops at the first error never reaches the rest of the file — so one hand-edited line can make an entireknown_hostsunreadable.This matters in practice because files in the wild are hand-edited and tabs/indentation are common; I hit it reading real
known_hostsfiles with a port-forward manager that uses this crate.The fix
Split on
char::is_whitespaceand treat the optional marker as a token, instead of assuming a single space follows it.Two details are load-bearing:
PublicKey's parser.decode_segmentinpublic/ssh_format.rsterminates only onb' ', sossh-ed25519\t<base64>is not parseable byPublicKeyeven though it is validknown_hosts. Normalising the separators at this boundary keepsPublicKey's stricter contract intact.markeris rebuilt asformat!("@{marker_str}")from the token after the@has been stripped, soMarker::from_strstill receives the spelling it expects.Tests
Four unit tests added in
known_hosts.rs(tab-separated, indented, runs of spaces, marker followed by a tab). Each fails before the change and passes after.Verification
cargo test -p ssh-key— all suites pass, 0 failurescargo clippy -p ssh-key --all-targets -- -D warnings— no errorscargo fmt -p ssh-key --check— cleancargo check -p ssh-key --no-default-features— clean (noalloc-only APIs used)Note on scope
I have deliberately not changed the matching semantics in this crate —
HostPatternsis still returned as raw patterns and matching remains the caller's job, as documented. This PR is limited to accepting the input shapes OpenSSH accepts.AI usage
AI-assisted. The defect was found and reproduced by the author, the fix and tests were AI-drafted and then reviewed, compiled, and tested locally by the author. Reproductions were validated against a real OpenSSH 8.2p1 installation (
ssh-keygen -F) rather than against assumptions about the format.