diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | readconf.c | 69 | ||||
-rw-r--r-- | readconf.h | 13 | ||||
-rw-r--r-- | ssh.c | 28 | ||||
-rw-r--r-- | ssh_config.5 | 20 | ||||
-rw-r--r-- | sshconnect.c | 72 | ||||
-rw-r--r-- | sshconnect2.c | 11 |
7 files changed, 125 insertions, 94 deletions
@@ -24,6 +24,12 @@ | |||
24 | read in key comments for v.2 keys (though note that these are not | 24 | read in key comments for v.2 keys (though note that these are not |
25 | passed over the agent protocol); bz#439, based on patch from binder | 25 | passed over the agent protocol); bz#439, based on patch from binder |
26 | AT arago.de; ok markus@ | 26 | AT arago.de; ok markus@ |
27 | - djm@cvs.openbsd.org 2011/05/24 07:15:47 | ||
28 | [readconf.c readconf.h ssh.c ssh_config.5 sshconnect.c sshconnect2.c] | ||
29 | Remove undocumented legacy options UserKnownHostsFile2 and | ||
30 | GlobalKnownHostsFile2 by making UserKnownHostsFile/GlobalKnownHostsFile | ||
31 | accept multiple paths per line and making their defaults include | ||
32 | known_hosts2; ok markus | ||
27 | 33 | ||
28 | 20110520 | 34 | 20110520 |
29 | - (djm) [session.c] call setexeccon() before executing passwd for pw | 35 | - (djm) [session.c] call setexeccon() before executing passwd for pw |
diff --git a/readconf.c b/readconf.c index 4780ae289..91dfa566f 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.192 2011/05/06 21:34:32 djm Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.193 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 |
@@ -193,9 +193,9 @@ static struct { | |||
193 | { "host", oHost }, | 193 | { "host", oHost }, |
194 | { "escapechar", oEscapeChar }, | 194 | { "escapechar", oEscapeChar }, |
195 | { "globalknownhostsfile", oGlobalKnownHostsFile }, | 195 | { "globalknownhostsfile", oGlobalKnownHostsFile }, |
196 | { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */ | 196 | { "globalknownhostsfile2", oDeprecated }, |
197 | { "userknownhostsfile", oUserKnownHostsFile }, | 197 | { "userknownhostsfile", oUserKnownHostsFile }, |
198 | { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ | 198 | { "userknownhostsfile2", oDeprecated }, |
199 | { "connectionattempts", oConnectionAttempts }, | 199 | { "connectionattempts", oConnectionAttempts }, |
200 | { "batchmode", oBatchMode }, | 200 | { "batchmode", oBatchMode }, |
201 | { "checkhostip", oCheckHostIP }, | 201 | { "checkhostip", oCheckHostIP }, |
@@ -354,7 +354,9 @@ process_config_line(Options *options, const char *host, | |||
354 | char *line, const char *filename, int linenum, | 354 | char *line, const char *filename, int linenum, |
355 | int *activep) | 355 | int *activep) |
356 | { | 356 | { |
357 | char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; | 357 | char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; |
358 | char **cpptr, fwdarg[256]; | ||
359 | u_int *uintptr, max_entries = 0; | ||
358 | int negated, opcode, *intptr, value, value2, scale; | 360 | int negated, opcode, *intptr, value, value2, scale; |
359 | LogLevel *log_level_ptr; | 361 | LogLevel *log_level_ptr; |
360 | long long orig, val64; | 362 | long long orig, val64; |
@@ -598,26 +600,33 @@ parse_yesnoask: | |||
598 | parse_string: | 600 | parse_string: |
599 | arg = strdelim(&s); | 601 | arg = strdelim(&s); |
600 | if (!arg || *arg == '\0') | 602 | if (!arg || *arg == '\0') |
601 | fatal("%.200s line %d: Missing argument.", filename, linenum); | 603 | fatal("%.200s line %d: Missing argument.", |
604 | filename, linenum); | ||
602 | if (*activep && *charptr == NULL) | 605 | if (*activep && *charptr == NULL) |
603 | *charptr = xstrdup(arg); | 606 | *charptr = xstrdup(arg); |
604 | break; | 607 | break; |
605 | 608 | ||
606 | case oGlobalKnownHostsFile: | 609 | case oGlobalKnownHostsFile: |
607 | charptr = &options->system_hostfile; | 610 | cpptr = (char **)&options->system_hostfiles; |
608 | goto parse_string; | 611 | uintptr = &options->num_system_hostfiles; |
612 | max_entries = SSH_MAX_HOSTS_FILES; | ||
613 | parse_char_array: | ||
614 | if (*activep && *uintptr == 0) { | ||
615 | while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | ||
616 | if ((*uintptr) >= max_entries) | ||
617 | fatal("%s line %d: " | ||
618 | "too many authorized keys files.", | ||
619 | filename, linenum); | ||
620 | cpptr[(*uintptr)++] = xstrdup(arg); | ||
621 | } | ||
622 | } | ||
623 | return 0; | ||
609 | 624 | ||
610 | case oUserKnownHostsFile: | 625 | case oUserKnownHostsFile: |
611 | charptr = &options->user_hostfile; | 626 | cpptr = (char **)&options->user_hostfiles; |
612 | goto parse_string; | 627 | uintptr = &options->num_user_hostfiles; |
613 | 628 | max_entries = SSH_MAX_HOSTS_FILES; | |
614 | case oGlobalKnownHostsFile2: | 629 | goto parse_char_array; |
615 | charptr = &options->system_hostfile2; | ||
616 | goto parse_string; | ||
617 | |||
618 | case oUserKnownHostsFile2: | ||
619 | charptr = &options->user_hostfile2; | ||
620 | goto parse_string; | ||
621 | 630 | ||
622 | case oHostName: | 631 | case oHostName: |
623 | charptr = &options->hostname; | 632 | charptr = &options->hostname; |
@@ -1158,10 +1167,8 @@ initialize_options(Options * options) | |||
1158 | options->proxy_command = NULL; | 1167 | options->proxy_command = NULL; |
1159 | options->user = NULL; | 1168 | options->user = NULL; |
1160 | options->escape_char = -1; | 1169 | options->escape_char = -1; |
1161 | options->system_hostfile = NULL; | 1170 | options->num_system_hostfiles = 0; |
1162 | options->user_hostfile = NULL; | 1171 | options->num_user_hostfiles = 0; |
1163 | options->system_hostfile2 = NULL; | ||
1164 | options->user_hostfile2 = NULL; | ||
1165 | options->local_forwards = NULL; | 1172 | options->local_forwards = NULL; |
1166 | options->num_local_forwards = 0; | 1173 | options->num_local_forwards = 0; |
1167 | options->remote_forwards = NULL; | 1174 | options->remote_forwards = NULL; |
@@ -1301,14 +1308,18 @@ fill_default_options(Options * options) | |||
1301 | } | 1308 | } |
1302 | if (options->escape_char == -1) | 1309 | if (options->escape_char == -1) |
1303 | options->escape_char = '~'; | 1310 | options->escape_char = '~'; |
1304 | if (options->system_hostfile == NULL) | 1311 | if (options->num_system_hostfiles == 0) { |
1305 | options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; | 1312 | options->system_hostfiles[options->num_system_hostfiles++] = |
1306 | if (options->user_hostfile == NULL) | 1313 | xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); |
1307 | options->user_hostfile = _PATH_SSH_USER_HOSTFILE; | 1314 | options->system_hostfiles[options->num_system_hostfiles++] = |
1308 | if (options->system_hostfile2 == NULL) | 1315 | xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); |
1309 | options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; | 1316 | } |
1310 | if (options->user_hostfile2 == NULL) | 1317 | if (options->num_user_hostfiles == 0) { |
1311 | options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; | 1318 | options->user_hostfiles[options->num_user_hostfiles++] = |
1319 | xstrdup(_PATH_SSH_USER_HOSTFILE); | ||
1320 | options->user_hostfiles[options->num_user_hostfiles++] = | ||
1321 | xstrdup(_PATH_SSH_USER_HOSTFILE2); | ||
1322 | } | ||
1312 | if (options->log_level == SYSLOG_LEVEL_NOT_SET) | 1323 | if (options->log_level == SYSLOG_LEVEL_NOT_SET) |
1313 | options->log_level = SYSLOG_LEVEL_INFO; | 1324 | options->log_level = SYSLOG_LEVEL_INFO; |
1314 | if (options->clear_forwardings == 1) | 1325 | if (options->clear_forwardings == 1) |
diff --git a/readconf.h b/readconf.h index bc3e8c1bb..5944cff93 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.89 2011/05/06 21:34:32 djm Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.90 2011/05/24 07:15:47 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -27,7 +27,8 @@ typedef struct { | |||
27 | } Forward; | 27 | } Forward; |
28 | /* Data structure for representing option data. */ | 28 | /* Data structure for representing option data. */ |
29 | 29 | ||
30 | #define MAX_SEND_ENV 256 | 30 | #define MAX_SEND_ENV 256 |
31 | #define SSH_MAX_HOSTS_FILES 256 | ||
31 | 32 | ||
32 | typedef struct { | 33 | typedef struct { |
33 | int forward_agent; /* Forward authentication agent. */ | 34 | int forward_agent; /* Forward authentication agent. */ |
@@ -83,10 +84,10 @@ typedef struct { | |||
83 | char *user; /* User to log in as. */ | 84 | char *user; /* User to log in as. */ |
84 | int escape_char; /* Escape character; -2 = none */ | 85 | int escape_char; /* Escape character; -2 = none */ |
85 | 86 | ||
86 | char *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */ | 87 | u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */ |
87 | char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */ | 88 | char *system_hostfiles[SSH_MAX_HOSTS_FILES]; |
88 | char *system_hostfile2; | 89 | u_int num_user_hostfiles; /* Path for $HOME/.ssh/known_hosts */ |
89 | char *user_hostfile2; | 90 | char *user_hostfiles[SSH_MAX_HOSTS_FILES]; |
90 | char *preferred_authentications; | 91 | char *preferred_authentications; |
91 | char *bind_address; /* local socket address for connection to sshd */ | 92 | char *bind_address; /* local socket address for connection to sshd */ |
92 | char *pkcs11_provider; /* PKCS#11 provider */ | 93 | char *pkcs11_provider; /* PKCS#11 provider */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.360 2011/05/06 21:38:58 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.361 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 |
@@ -212,6 +212,20 @@ static void main_sigchld_handler(int); | |||
212 | void muxclient(const char *); | 212 | void muxclient(const char *); |
213 | void muxserver_listen(void); | 213 | void muxserver_listen(void); |
214 | 214 | ||
215 | /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */ | ||
216 | static void | ||
217 | tilde_expand_paths(char **paths, u_int num_paths) | ||
218 | { | ||
219 | u_int i; | ||
220 | char *cp; | ||
221 | |||
222 | for (i = 0; i < num_paths; i++) { | ||
223 | cp = tilde_expand_filename(paths[i], original_real_uid); | ||
224 | xfree(paths[i]); | ||
225 | paths[i] = cp; | ||
226 | } | ||
227 | } | ||
228 | |||
215 | /* | 229 | /* |
216 | * Main program for the ssh client. | 230 | * Main program for the ssh client. |
217 | */ | 231 | */ |
@@ -869,15 +883,9 @@ main(int ac, char **av) | |||
869 | load_public_identity_files(); | 883 | load_public_identity_files(); |
870 | 884 | ||
871 | /* Expand ~ in known host file names. */ | 885 | /* Expand ~ in known host file names. */ |
872 | /* XXX mem-leaks: */ | 886 | tilde_expand_paths(options.system_hostfiles, |
873 | options.system_hostfile = | 887 | options.num_system_hostfiles); |
874 | tilde_expand_filename(options.system_hostfile, original_real_uid); | 888 | tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles); |
875 | options.user_hostfile = | ||
876 | tilde_expand_filename(options.user_hostfile, original_real_uid); | ||
877 | options.system_hostfile2 = | ||
878 | tilde_expand_filename(options.system_hostfile2, original_real_uid); | ||
879 | options.user_hostfile2 = | ||
880 | tilde_expand_filename(options.user_hostfile2, original_real_uid); | ||
881 | 889 | ||
882 | signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ | 890 | signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ |
883 | signal(SIGCHLD, main_sigchld_handler); | 891 | signal(SIGCHLD, main_sigchld_handler); |
diff --git a/ssh_config.5 b/ssh_config.5 index 7a3b641ff..87574e381 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: ssh_config.5,v 1.150 2011/05/07 23:19:39 jmc Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.151 2011/05/24 07:15:47 djm Exp $ |
37 | .Dd $Mdocdate: May 7 2011 $ | 37 | .Dd $Mdocdate: May 24 2011 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -517,9 +517,11 @@ or | |||
517 | The default is | 517 | The default is |
518 | .Dq no . | 518 | .Dq no . |
519 | .It Cm GlobalKnownHostsFile | 519 | .It Cm GlobalKnownHostsFile |
520 | Specifies a file to use for the global | 520 | Specifies one or more files to use for the global |
521 | host key database instead of | 521 | host key database, separated by whitespace. |
522 | .Pa /etc/ssh/ssh_known_hosts . | 522 | The default is |
523 | .Pa /etc/ssh/ssh_known_hosts , | ||
524 | .Pa /etc/ssh/ssh_known_hosts2 . | ||
523 | .It Cm GSSAPIAuthentication | 525 | .It Cm GSSAPIAuthentication |
524 | Specifies whether user authentication based on GSSAPI is allowed. | 526 | Specifies whether user authentication based on GSSAPI is allowed. |
525 | The default is | 527 | The default is |
@@ -1171,9 +1173,11 @@ This can be useful when a different user name is used on different machines. | |||
1171 | This saves the trouble of | 1173 | This saves the trouble of |
1172 | having to remember to give the user name on the command line. | 1174 | having to remember to give the user name on the command line. |
1173 | .It Cm UserKnownHostsFile | 1175 | .It Cm UserKnownHostsFile |
1174 | Specifies a file to use for the user | 1176 | Specifies one or more files to use for the user |
1175 | host key database instead of | 1177 | host key database, separated by whitespace. |
1176 | .Pa ~/.ssh/known_hosts . | 1178 | The default is |
1179 | .Pa ~/.ssh/known_hosts , | ||
1180 | .Pa ~/.ssh/known_hosts2 . | ||
1177 | .It Cm VerifyHostKeyDNS | 1181 | .It Cm VerifyHostKeyDNS |
1178 | Specifies whether to verify the remote key using DNS and SSHFP resource | 1182 | Specifies whether to verify the remote key using DNS and SSHFP resource |
1179 | records. | 1183 | records. |
diff --git a/sshconnect.c b/sshconnect.c index 603445227..0ee726637 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.233 2011/05/23 03:52:55 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 | ||
@@ -1128,16 +1135,9 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | |||
1128 | } | 1135 | } |
1129 | } | 1136 | } |
1130 | 1137 | ||
1131 | /* return ok if the key can be found in an old keyfile */ | 1138 | return check_host_key(host, hostaddr, options.port, host_key, RDRW, |
1132 | if (stat(options.system_hostfile2, &st) == 0 || | 1139 | options.user_hostfiles, options.num_user_hostfiles, |
1133 | stat(options.user_hostfile2, &st) == 0) { | 1140 | options.system_hostfiles, options.num_system_hostfiles); |
1134 | if (check_host_key(host, hostaddr, options.port, host_key, | ||
1135 | RDONLY, options.user_hostfile2, | ||
1136 | options.system_hostfile2) == 0) | ||
1137 | return 0; | ||
1138 | } | ||
1139 | return check_host_key(host, hostaddr, options.port, host_key, | ||
1140 | RDRW, options.user_hostfile, options.system_hostfile); | ||
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | /* | 1143 | /* |
diff --git a/sshconnect2.c b/sshconnect2.c index 673bf1a4f..c24b20278 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.187 2011/05/06 02:05:41 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.188 2011/05/24 07:15:47 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -109,14 +109,15 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) | |||
109 | size_t maxlen; | 109 | size_t maxlen; |
110 | struct hostkeys *hostkeys; | 110 | struct hostkeys *hostkeys; |
111 | int ktype; | 111 | int ktype; |
112 | u_int i; | ||
112 | 113 | ||
113 | /* Find all hostkeys for this hostname */ | 114 | /* Find all hostkeys for this hostname */ |
114 | get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); | 115 | get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); |
115 | hostkeys = init_hostkeys(); | 116 | hostkeys = init_hostkeys(); |
116 | load_hostkeys(hostkeys, hostname, options.user_hostfile2); | 117 | for (i = 0; i < options.num_user_hostfiles; i++) |
117 | load_hostkeys(hostkeys, hostname, options.system_hostfile2); | 118 | load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]); |
118 | load_hostkeys(hostkeys, hostname, options.user_hostfile); | 119 | for (i = 0; i < options.num_system_hostfiles; i++) |
119 | load_hostkeys(hostkeys, hostname, options.system_hostfile); | 120 | load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); |
120 | 121 | ||
121 | oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); | 122 | oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); |
122 | maxlen = strlen(avail) + 1; | 123 | maxlen = strlen(avail) + 1; |