summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 1a03c6bf3..aaf02ece4 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
105static char *
106order_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
104void 157void
105ssh_kex2(char *host, struct sockaddr *hostaddr) 158ssh_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;