@@ -365,6 +365,11 @@ fn check_ssh_known_hosts_loaded(
365
365
// but a different hostname.
366
366
let mut other_hosts = Vec :: new ( ) ;
367
367
368
+ // `accepted_known_host_found` keeps track of whether we've found a matching
369
+ // line in the `known_hosts` file that we would accept. We can't return that
370
+ // immediately, because there may be a subsequent @revoked key.
371
+ let mut accepted_known_host_found = false ;
372
+
368
373
// Older versions of OpenSSH (before 6.8, March 2015) showed MD5
369
374
// fingerprints (see FingerprintHash ssh config option). Here we only
370
375
// support SHA256.
@@ -389,7 +394,7 @@ fn check_ssh_known_hosts_loaded(
389
394
match known_host. line_type {
390
395
KnownHostLineType :: Key => {
391
396
if key_matches {
392
- return Ok ( ( ) ) ;
397
+ accepted_known_host_found = true ;
393
398
}
394
399
395
400
// The host and key type matched, but the key itself did not.
@@ -424,6 +429,11 @@ fn check_ssh_known_hosts_loaded(
424
429
}
425
430
}
426
431
432
+ // We have an accepted host key and it hasn't been revoked.
433
+ if accepted_known_host_found {
434
+ return Ok ( ( ) ) ;
435
+ }
436
+
427
437
if latent_errors. len ( ) == 0 {
428
438
// FIXME: Ideally the error message should include the IP address of the
429
439
// remote host (to help the user validate that they are connecting to the
@@ -850,4 +860,36 @@ mod tests {
850
860
_ => panic ! ( "Expected error to be of type HostKeyHasChanged." ) ,
851
861
}
852
862
}
863
+
864
+ #[ test]
865
+ fn known_host_and_revoked ( ) {
866
+ let contents = r#"
867
+ example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKVYJpa0yUGaNk0NXQTPWa0tHjqRpx+7hl2diReH6DtR eric@host
868
+ # Later in the file the same host key is revoked
869
+ @revoked example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKVYJpa0yUGaNk0NXQTPWa0tHjqRpx+7hl2diReH6DtR eric@host
870
+ "# ;
871
+
872
+ let kh_path = Path :: new ( "/home/abc/.known_hosts" ) ;
873
+ let khs = load_hostfile_contents ( kh_path, contents) ;
874
+
875
+ match check_ssh_known_hosts_loaded (
876
+ & khs,
877
+ "example.com" ,
878
+ SshHostKeyType :: Ed255219 ,
879
+ & khs[ 0 ] . key ,
880
+ ) {
881
+ Err ( KnownHostError :: HostKeyRevoked { hostname, remote_host_key, location, .. } ) => {
882
+ assert_eq ! ( "example.com" , hostname) ;
883
+ assert_eq ! (
884
+ "AAAAC3NzaC1lZDI1NTE5AAAAIKVYJpa0yUGaNk0NXQTPWa0tHjqRpx+7hl2diReH6DtR" ,
885
+ remote_host_key
886
+ ) ;
887
+ assert ! ( matches!(
888
+ location,
889
+ KnownHostLocation :: File { lineno: 4 , .. }
890
+ ) ) ;
891
+ } ,
892
+ _ => panic ! ( "Expected host key to be reject with error HostKeyRevoked." ) ,
893
+ }
894
+ }
853
895
}
0 commit comments