diff options
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 73 |
1 files changed, 36 insertions, 37 deletions
diff --git a/sshconnect.c b/sshconnect.c index 1c066b641..aed4c0bc7 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.232 2011/01/16 11:50:36 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.234 2011/05/24 07:15:47 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -683,28 +683,30 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr, | |||
683 | 683 | ||
684 | /* | 684 | /* |
685 | * check whether the supplied host key is valid, return -1 if the key | 685 | * check whether the supplied host key is valid, return -1 if the key |
686 | * is not valid. the user_hostfile will not be updated if 'readonly' is true. | 686 | * is not valid. user_hostfile[0] will not be updated if 'readonly' is true. |
687 | */ | 687 | */ |
688 | #define RDRW 0 | 688 | #define RDRW 0 |
689 | #define RDONLY 1 | 689 | #define RDONLY 1 |
690 | #define ROQUIET 2 | 690 | #define ROQUIET 2 |
691 | static int | 691 | static int |
692 | check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | 692 | check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
693 | Key *host_key, int readonly, char *user_hostfile, | 693 | Key *host_key, int readonly, |
694 | char *system_hostfile) | 694 | char **user_hostfiles, u_int num_user_hostfiles, |
695 | char **system_hostfiles, u_int num_system_hostfiles) | ||
695 | { | 696 | { |
697 | HostStatus host_status; | ||
698 | HostStatus ip_status; | ||
696 | Key *raw_key = NULL; | 699 | Key *raw_key = NULL; |
697 | const char *type; | ||
698 | char *ip = NULL, *host = NULL; | 700 | char *ip = NULL, *host = NULL; |
699 | char hostline[1000], *hostp, *fp, *ra; | 701 | char hostline[1000], *hostp, *fp, *ra; |
700 | HostStatus host_status; | ||
701 | HostStatus ip_status; | ||
702 | int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; | ||
703 | int local = sockaddr_is_local(hostaddr); | ||
704 | char msg[1024]; | 702 | char msg[1024]; |
703 | const char *type; | ||
704 | const struct hostkey_entry *host_found, *ip_found; | ||
705 | int len, cancelled_forwarding = 0; | 705 | int len, cancelled_forwarding = 0; |
706 | int local = sockaddr_is_local(hostaddr); | ||
707 | int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; | ||
706 | struct hostkeys *host_hostkeys, *ip_hostkeys; | 708 | struct hostkeys *host_hostkeys, *ip_hostkeys; |
707 | const struct hostkey_entry *host_found, *ip_found; | 709 | u_int i; |
708 | 710 | ||
709 | /* | 711 | /* |
710 | * Force accepting of the host key for loopback/localhost. The | 712 | * Force accepting of the host key for loopback/localhost. The |
@@ -736,14 +738,18 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
736 | options.check_host_ip = 0; | 738 | options.check_host_ip = 0; |
737 | 739 | ||
738 | host_hostkeys = init_hostkeys(); | 740 | host_hostkeys = init_hostkeys(); |
739 | load_hostkeys(host_hostkeys, host, user_hostfile); | 741 | for (i = 0; i < num_user_hostfiles; i++) |
740 | load_hostkeys(host_hostkeys, host, system_hostfile); | 742 | load_hostkeys(host_hostkeys, host, user_hostfiles[i]); |
743 | for (i = 0; i < num_system_hostfiles; i++) | ||
744 | load_hostkeys(host_hostkeys, host, system_hostfiles[i]); | ||
741 | 745 | ||
742 | ip_hostkeys = NULL; | 746 | ip_hostkeys = NULL; |
743 | if (!want_cert && options.check_host_ip) { | 747 | if (!want_cert && options.check_host_ip) { |
744 | ip_hostkeys = init_hostkeys(); | 748 | ip_hostkeys = init_hostkeys(); |
745 | load_hostkeys(ip_hostkeys, ip, user_hostfile); | 749 | for (i = 0; i < num_user_hostfiles; i++) |
746 | load_hostkeys(ip_hostkeys, ip, system_hostfile); | 750 | load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]); |
751 | for (i = 0; i < num_system_hostfiles; i++) | ||
752 | load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]); | ||
747 | } | 753 | } |
748 | 754 | ||
749 | retry: | 755 | retry: |
@@ -788,11 +794,12 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
788 | logit("%s host key for IP address " | 794 | logit("%s host key for IP address " |
789 | "'%.128s' not in list of known hosts.", | 795 | "'%.128s' not in list of known hosts.", |
790 | type, ip); | 796 | type, ip); |
791 | else if (!add_host_to_hostfile(user_hostfile, ip, | 797 | else if (!add_host_to_hostfile(user_hostfiles[0], ip, |
792 | host_key, options.hash_known_hosts)) | 798 | host_key, options.hash_known_hosts)) |
793 | logit("Failed to add the %s host key for IP " | 799 | logit("Failed to add the %s host key for IP " |
794 | "address '%.128s' to the list of known " | 800 | "address '%.128s' to the list of known " |
795 | "hosts (%.30s).", type, ip, user_hostfile); | 801 | "hosts (%.30s).", type, ip, |
802 | user_hostfiles[0]); | ||
796 | else | 803 | else |
797 | logit("Warning: Permanently added the %s host " | 804 | logit("Warning: Permanently added the %s host " |
798 | "key for IP address '%.128s' to the list " | 805 | "key for IP address '%.128s' to the list " |
@@ -811,7 +818,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
811 | port != SSH_DEFAULT_PORT) { | 818 | port != SSH_DEFAULT_PORT) { |
812 | debug("checking without port identifier"); | 819 | debug("checking without port identifier"); |
813 | if (check_host_key(hostname, hostaddr, 0, host_key, | 820 | if (check_host_key(hostname, hostaddr, 0, host_key, |
814 | ROQUIET, user_hostfile, system_hostfile) == 0) { | 821 | ROQUIET, user_hostfiles, num_user_hostfiles, |
822 | system_hostfiles, num_system_hostfiles) == 0) { | ||
815 | debug("found matching key w/out port"); | 823 | debug("found matching key w/out port"); |
816 | break; | 824 | break; |
817 | } | 825 | } |
@@ -876,25 +884,25 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
876 | hostp = hostline; | 884 | hostp = hostline; |
877 | if (options.hash_known_hosts) { | 885 | if (options.hash_known_hosts) { |
878 | /* Add hash of host and IP separately */ | 886 | /* Add hash of host and IP separately */ |
879 | r = add_host_to_hostfile(user_hostfile, host, | 887 | r = add_host_to_hostfile(user_hostfiles[0], |
880 | host_key, options.hash_known_hosts) && | 888 | host, host_key, options.hash_known_hosts) && |
881 | add_host_to_hostfile(user_hostfile, ip, | 889 | add_host_to_hostfile(user_hostfiles[0], ip, |
882 | host_key, options.hash_known_hosts); | 890 | host_key, options.hash_known_hosts); |
883 | } else { | 891 | } else { |
884 | /* Add unhashed "host,ip" */ | 892 | /* Add unhashed "host,ip" */ |
885 | r = add_host_to_hostfile(user_hostfile, | 893 | r = add_host_to_hostfile(user_hostfiles[0], |
886 | hostline, host_key, | 894 | hostline, host_key, |
887 | options.hash_known_hosts); | 895 | options.hash_known_hosts); |
888 | } | 896 | } |
889 | } else { | 897 | } else { |
890 | r = add_host_to_hostfile(user_hostfile, host, host_key, | 898 | r = add_host_to_hostfile(user_hostfiles[0], host, |
891 | options.hash_known_hosts); | 899 | host_key, options.hash_known_hosts); |
892 | hostp = host; | 900 | hostp = host; |
893 | } | 901 | } |
894 | 902 | ||
895 | if (!r) | 903 | if (!r) |
896 | logit("Failed to add the host to the list of known " | 904 | logit("Failed to add the host to the list of known " |
897 | "hosts (%.500s).", user_hostfile); | 905 | "hosts (%.500s).", user_hostfiles[0]); |
898 | else | 906 | else |
899 | logit("Warning: Permanently added '%.200s' (%s) to the " | 907 | logit("Warning: Permanently added '%.200s' (%s) to the " |
900 | "list of known hosts.", hostp, type); | 908 | "list of known hosts.", hostp, type); |
@@ -955,7 +963,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
955 | /* The host key has changed. */ | 963 | /* The host key has changed. */ |
956 | warn_changed_key(host_key); | 964 | warn_changed_key(host_key); |
957 | error("Add correct host key in %.100s to get rid of this message.", | 965 | error("Add correct host key in %.100s to get rid of this message.", |
958 | user_hostfile); | 966 | user_hostfiles[0]); |
959 | error("Offending %s key in %s:%lu", key_type(host_found->key), | 967 | error("Offending %s key in %s:%lu", key_type(host_found->key), |
960 | host_found->file, host_found->line); | 968 | host_found->file, host_found->line); |
961 | 969 | ||
@@ -1100,7 +1108,6 @@ fail: | |||
1100 | int | 1108 | int |
1101 | verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | 1109 | verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) |
1102 | { | 1110 | { |
1103 | struct stat st; | ||
1104 | int flags = 0; | 1111 | int flags = 0; |
1105 | char *fp; | 1112 | char *fp; |
1106 | 1113 | ||
@@ -1111,7 +1118,6 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | |||
1111 | /* XXX certs are not yet supported for DNS */ | 1118 | /* XXX certs are not yet supported for DNS */ |
1112 | if (!key_is_cert(host_key) && options.verify_host_key_dns && | 1119 | if (!key_is_cert(host_key) && options.verify_host_key_dns && |
1113 | verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { | 1120 | verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { |
1114 | |||
1115 | if (flags & DNS_VERIFY_FOUND) { | 1121 | if (flags & DNS_VERIFY_FOUND) { |
1116 | 1122 | ||
1117 | if (options.verify_host_key_dns == 1 && | 1123 | if (options.verify_host_key_dns == 1 && |
@@ -1129,16 +1135,9 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | |||
1129 | } | 1135 | } |
1130 | } | 1136 | } |
1131 | 1137 | ||
1132 | /* return ok if the key can be found in an old keyfile */ | 1138 | return check_host_key(host, hostaddr, options.port, host_key, RDRW, |
1133 | if (stat(options.system_hostfile2, &st) == 0 || | 1139 | options.user_hostfiles, options.num_user_hostfiles, |
1134 | stat(options.user_hostfile2, &st) == 0) { | 1140 | options.system_hostfiles, options.num_system_hostfiles); |
1135 | if (check_host_key(host, hostaddr, options.port, host_key, | ||
1136 | RDONLY, options.user_hostfile2, | ||
1137 | options.system_hostfile2) == 0) | ||
1138 | return 0; | ||
1139 | } | ||
1140 | return check_host_key(host, hostaddr, options.port, host_key, | ||
1141 | RDRW, options.user_hostfile, options.system_hostfile); | ||
1142 | } | 1141 | } |
1143 | 1142 | ||
1144 | /* | 1143 | /* |