summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c73
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
691static int 691static int
692check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, 692check_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:
1100int 1108int
1101verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) 1109verify_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/*