diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index 8a9887a2e..e01721b73 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.183 2010/04/26 22:28:24 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.186 2010/11/29 23:45:51 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. |
@@ -69,6 +69,7 @@ | |||
69 | #include "msg.h" | 69 | #include "msg.h" |
70 | #include "pathnames.h" | 70 | #include "pathnames.h" |
71 | #include "uidswap.h" | 71 | #include "uidswap.h" |
72 | #include "hostfile.h" | ||
72 | #include "schnorr.h" | 73 | #include "schnorr.h" |
73 | #include "jpake.h" | 74 | #include "jpake.h" |
74 | 75 | ||
@@ -101,8 +102,60 @@ verify_host_key_callback(Key *hostkey) | |||
101 | return 0; | 102 | return 0; |
102 | } | 103 | } |
103 | 104 | ||
105 | static char * | ||
106 | order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) | ||
107 | { | ||
108 | char *oavail, *avail, *first, *last, *alg, *hostname, *ret; | ||
109 | size_t maxlen; | ||
110 | struct hostkeys *hostkeys; | ||
111 | int ktype; | ||
112 | |||
113 | /* Find all hostkeys for this hostname */ | ||
114 | get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); | ||
115 | hostkeys = init_hostkeys(); | ||
116 | load_hostkeys(hostkeys, hostname, options.user_hostfile2); | ||
117 | load_hostkeys(hostkeys, hostname, options.system_hostfile2); | ||
118 | load_hostkeys(hostkeys, hostname, options.user_hostfile); | ||
119 | load_hostkeys(hostkeys, hostname, options.system_hostfile); | ||
120 | |||
121 | oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); | ||
122 | maxlen = strlen(avail) + 1; | ||
123 | first = xmalloc(maxlen); | ||
124 | last = xmalloc(maxlen); | ||
125 | *first = *last = '\0'; | ||
126 | |||
127 | #define ALG_APPEND(to, from) \ | ||
128 | do { \ | ||
129 | if (*to != '\0') \ | ||
130 | strlcat(to, ",", maxlen); \ | ||
131 | strlcat(to, from, maxlen); \ | ||
132 | } while (0) | ||
133 | |||
134 | while ((alg = strsep(&avail, ",")) && *alg != '\0') { | ||
135 | if ((ktype = key_type_from_name(alg)) == KEY_UNSPEC) | ||
136 | fatal("%s: unknown alg %s", __func__, alg); | ||
137 | if (lookup_key_in_hostkeys_by_type(hostkeys, | ||
138 | key_type_plain(ktype), NULL)) | ||
139 | ALG_APPEND(first, alg); | ||
140 | else | ||
141 | ALG_APPEND(last, alg); | ||
142 | } | ||
143 | #undef ALG_APPEND | ||
144 | xasprintf(&ret, "%s%s%s", first, *first == '\0' ? "" : ",", last); | ||
145 | if (*first != '\0') | ||
146 | debug3("%s: prefer hostkeyalgs: %s", __func__, first); | ||
147 | |||
148 | xfree(first); | ||
149 | xfree(last); | ||
150 | xfree(hostname); | ||
151 | xfree(oavail); | ||
152 | free_hostkeys(hostkeys); | ||
153 | |||
154 | return ret; | ||
155 | } | ||
156 | |||
104 | void | 157 | void |
105 | ssh_kex2(char *host, struct sockaddr *hostaddr) | 158 | ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) |
106 | { | 159 | { |
107 | Kex *kex; | 160 | Kex *kex; |
108 | 161 | ||
@@ -160,6 +213,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
160 | if (options.hostkeyalgorithms != NULL) | 213 | if (options.hostkeyalgorithms != NULL) |
161 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = | 214 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = |
162 | options.hostkeyalgorithms; | 215 | options.hostkeyalgorithms; |
216 | else { | ||
217 | /* Prefer algorithms that we already have keys for */ | ||
218 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = | ||
219 | order_hostkeyalgs(host, hostaddr, port); | ||
220 | } | ||
221 | if (options.kex_algorithms != NULL) | ||
222 | myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; | ||
163 | 223 | ||
164 | #ifdef GSSAPI | 224 | #ifdef GSSAPI |
165 | /* If we've got GSSAPI algorithms, then we also support the | 225 | /* If we've got GSSAPI algorithms, then we also support the |
@@ -181,6 +241,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
181 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; | 241 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; |
182 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | 242 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
183 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; | 243 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
244 | kex->kex[KEX_ECDH_SHA2] = kexecdh_client; | ||
184 | #ifdef GSSAPI | 245 | #ifdef GSSAPI |
185 | if (options.gss_keyex) { | 246 | if (options.gss_keyex) { |
186 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; | 247 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; |
@@ -197,7 +258,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
197 | kex->gss_deleg_creds = options.gss_deleg_creds; | 258 | kex->gss_deleg_creds = options.gss_deleg_creds; |
198 | kex->gss_trust_dns = options.gss_trust_dns; | 259 | kex->gss_trust_dns = options.gss_trust_dns; |
199 | kex->gss_client = options.gss_client_identity; | 260 | kex->gss_client = options.gss_client_identity; |
200 | kex->gss_host = gss_host; | 261 | if (options.gss_server_identity) { |
262 | kex->gss_host = options.gss_server_identity; | ||
263 | } else { | ||
264 | kex->gss_host = gss_host; | ||
265 | } | ||
201 | } | 266 | } |
202 | #endif | 267 | #endif |
203 | 268 | ||
@@ -624,7 +689,9 @@ userauth_gssapi(Authctxt *authctxt) | |||
624 | int ok = 0; | 689 | int ok = 0; |
625 | const char *gss_host; | 690 | const char *gss_host; |
626 | 691 | ||
627 | if (options.gss_trust_dns) | 692 | if (options.gss_server_identity) |
693 | gss_host = options.gss_server_identity; | ||
694 | else if (options.gss_trust_dns) | ||
628 | gss_host = get_canonical_hostname(1); | 695 | gss_host = get_canonical_hostname(1); |
629 | else | 696 | else |
630 | gss_host = authctxt->host; | 697 | gss_host = authctxt->host; |