diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2002-08-01 01:21:56 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2002-08-01 01:21:56 +0000 |
commit | 3ed6640532ea53bc37182262141c9e917a448025 (patch) | |
tree | 88ad1d4bbb9cd865c154f24ad12feafd7e302ccd /sshconnect.c | |
parent | 18d2b5d399a6ee97c65a058c14054fd2da2b891a (diff) |
- markus@cvs.openbsd.org 2002/07/24 16:11:18
[hostfile.c hostfile.h sshconnect.c]
print out all known keys for a host if we get a unknown host key,
see discussion at http://marc.theaimsgroup.com/?t=101069210100016&r=1&w=4
the ssharp mitm tool attacks users in a similar way, so i'd like to
pointed out again:
A MITM attack is always possible if the ssh client prints:
The authenticity of host 'bla' can't be established.
(protocol version 2 with pubkey authentication allows you to detect
MITM attacks)
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/sshconnect.c b/sshconnect.c index 9f8458dc7..8599684e5 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.131 2002/07/12 13:29:09 itojun Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.132 2002/07/24 16:11:18 markus Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -46,6 +46,8 @@ extern uid_t original_effective_uid; | |||
46 | #define INET6_ADDRSTRLEN 46 | 46 | #define INET6_ADDRSTRLEN 46 |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | static int show_other_keys(const char *, Key *); | ||
50 | |||
49 | /* | 51 | /* |
50 | * Connect to the given ssh server using a proxy command. | 52 | * Connect to the given ssh server using a proxy command. |
51 | */ | 53 | */ |
@@ -494,7 +496,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
494 | int salen; | 496 | int salen; |
495 | char ntop[NI_MAXHOST]; | 497 | char ntop[NI_MAXHOST]; |
496 | char msg[1024]; | 498 | char msg[1024]; |
497 | int len, host_line, ip_line; | 499 | int len, host_line, ip_line, has_keys; |
498 | const char *host_file = NULL, *ip_file = NULL; | 500 | const char *host_file = NULL, *ip_file = NULL; |
499 | 501 | ||
500 | /* | 502 | /* |
@@ -638,14 +640,19 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
638 | "have requested strict checking.", type, host); | 640 | "have requested strict checking.", type, host); |
639 | goto fail; | 641 | goto fail; |
640 | } else if (options.strict_host_key_checking == 2) { | 642 | } else if (options.strict_host_key_checking == 2) { |
643 | has_keys = show_other_keys(host, host_key); | ||
641 | /* The default */ | 644 | /* The default */ |
642 | fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); | 645 | fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); |
643 | snprintf(msg, sizeof(msg), | 646 | snprintf(msg, sizeof(msg), |
644 | "The authenticity of host '%.200s (%s)' can't be " | 647 | "The authenticity of host '%.200s (%s)' can't be " |
645 | "established.\n" | 648 | "established%s\n" |
646 | "%s key fingerprint is %s.\n" | 649 | "%s key fingerprint is %s.\n" |
647 | "Are you sure you want to continue connecting " | 650 | "Are you sure you want to continue connecting " |
648 | "(yes/no)? ", host, ip, type, fp); | 651 | "(yes/no)? ", |
652 | host, ip, | ||
653 | has_keys ? ",\nbut keys of different type are already " | ||
654 | "known for this host." : ".", | ||
655 | type, fp); | ||
649 | xfree(fp); | 656 | xfree(fp); |
650 | if (!confirm(msg)) | 657 | if (!confirm(msg)) |
651 | goto fail; | 658 | goto fail; |
@@ -748,6 +755,9 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, | |||
748 | * accept the authentication. | 755 | * accept the authentication. |
749 | */ | 756 | */ |
750 | break; | 757 | break; |
758 | case HOST_FOUND: | ||
759 | fatal("internal error"); | ||
760 | break; | ||
751 | } | 761 | } |
752 | 762 | ||
753 | if (options.check_host_ip && host_status != HOST_CHANGED && | 763 | if (options.check_host_ip && host_status != HOST_CHANGED && |
@@ -859,3 +869,58 @@ ssh_put_password(char *password) | |||
859 | memset(padded, 0, size); | 869 | memset(padded, 0, size); |
860 | xfree(padded); | 870 | xfree(padded); |
861 | } | 871 | } |
872 | |||
873 | static int | ||
874 | show_key_from_file(const char *file, const char *host, int keytype) | ||
875 | { | ||
876 | Key *found; | ||
877 | char *fp; | ||
878 | int line, ret; | ||
879 | |||
880 | found = key_new(keytype); | ||
881 | if ((ret = lookup_key_in_hostfile_by_type(file, host, | ||
882 | keytype, found, &line))) { | ||
883 | fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); | ||
884 | log("WARNING: %s key found for host %s\n" | ||
885 | "in file %s line %d with\n" | ||
886 | "%s key fingerprint %s.", | ||
887 | key_type(found), host, file, line, | ||
888 | key_type(found), fp); | ||
889 | xfree(fp); | ||
890 | } | ||
891 | key_free(found); | ||
892 | return (ret); | ||
893 | } | ||
894 | |||
895 | /* print all known host keys for a given host, but skip keys of given type */ | ||
896 | static int | ||
897 | show_other_keys(const char *host, Key *key) | ||
898 | { | ||
899 | int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, -1}; | ||
900 | int i, found = 0; | ||
901 | |||
902 | for (i = 0; type[i] != -1; i++) { | ||
903 | if (type[i] == key->type) | ||
904 | continue; | ||
905 | if (type[i] != KEY_RSA1 && | ||
906 | show_key_from_file(options.user_hostfile2, host, type[i])) { | ||
907 | found = 1; | ||
908 | continue; | ||
909 | } | ||
910 | if (type[i] != KEY_RSA1 && | ||
911 | show_key_from_file(options.system_hostfile2, host, type[i])) { | ||
912 | found = 1; | ||
913 | continue; | ||
914 | } | ||
915 | if (show_key_from_file(options.user_hostfile, host, type[i])) { | ||
916 | found = 1; | ||
917 | continue; | ||
918 | } | ||
919 | if (show_key_from_file(options.system_hostfile, host, type[i])) { | ||
920 | found = 1; | ||
921 | continue; | ||
922 | } | ||
923 | debug2("no key of type %d for host %s", type[i], host); | ||
924 | } | ||
925 | return (found); | ||
926 | } | ||