knownhosts: scope HostKeyAlgorithms to the target host - #1295
adonaicosta wants to merge 1 commit into
Conversation
hostKeyAlgorithms collected the key types of every entry in the known_hosts blob, without matching them against the host being dialled, and built the slice by ranging over a map. A blob covering several hosts with different key-type sets therefore advertised algorithms unknown for the host being connected to, in a random order on every call. The server may pick one of them, which checkAddr then rejects as a key mismatch, so verification succeeded or failed depending on the permutation. Match the entries against the target address, skip certificate authority entries, which hold the signing key rather than a host key algorithm the server can offer, and sort the result so the negotiation is deterministic. Return nil when no entry matches, leaving the negotiation to the defaults of golang.org/x/crypto/ssh. New() now takes the connection target, and gogit passes AuthOptions.Host. Regression from fluxcd#943, which is correct for a single host per blob. Signed-off-by: Adonai Costa <adonai.costa@gmail.com>
|
Fixes the non-deterministic
uniq := make(map[string]struct{})
for _, hk := range db.hostKeys { // every host in the blob
uniq[hk.key.Type()] = struct{}{}
}
for k := range uniq { // map range: random order
algos = append(algos, k)
}A blob covering several hosts with different key-type sets therefore advertises algorithms Changes
BehaviourSame
fluxcd/flux2#5385, the issue that #943 fixed, stays fixed: a blob holding only Tests
|
hostKeyAlgorithms collected the key types of every entry in the known_hosts
blob, without matching them against the host being dialled, and built the
slice by ranging over a map. A blob covering several hosts with different
key-type sets therefore advertised algorithms unknown for the host being
connected to, in a random order on every call. The server may pick one of
them, which checkAddr then rejects as a key mismatch, so verification
succeeded or failed depending on the permutation.
Match the entries against the target address, skip certificate authority
entries, which hold the signing key rather than a host key algorithm the
server can offer, and sort the result so the negotiation is deterministic.
Return nil when no entry matches, leaving the negotiation to the defaults of
golang.org/x/crypto/ssh.
New() now takes the connection target, and gogit passes AuthOptions.Host.
Regression from #943, which is correct for a single host per blob.
Signed-off-by: Adonai Costa adonai.costa@gmail.com