kex.c revision 1.149
1/* $OpenBSD: kex.c,v 1.149 2019/01/21 10:40:11 djm Exp $ */
2/*
3 * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26
27#include <sys/types.h>
28#include <errno.h>
29#include <signal.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34#include <poll.h>
35
36#ifdef WITH_OPENSSL
37#include <openssl/crypto.h>
38#endif
39
40#include "ssh.h"
41#include "ssh2.h"
42#include "atomicio.h"
43#include "version.h"
44#include "packet.h"
45#include "compat.h"
46#include "cipher.h"
47#include "sshkey.h"
48#include "kex.h"
49#include "log.h"
50#include "mac.h"
51#include "match.h"
52#include "misc.h"
53#include "dispatch.h"
54#include "monitor.h"
55
56#include "ssherr.h"
57#include "sshbuf.h"
58#include "digest.h"
59
60/* prototype */
61static int kex_choose_conf(struct ssh *);
62static int kex_input_newkeys(int, u_int32_t, struct ssh *);
63
64static const char *proposal_names[PROPOSAL_MAX] = {
65	"KEX algorithms",
66	"host key algorithms",
67	"ciphers ctos",
68	"ciphers stoc",
69	"MACs ctos",
70	"MACs stoc",
71	"compression ctos",
72	"compression stoc",
73	"languages ctos",
74	"languages stoc",
75};
76
77struct kexalg {
78	char *name;
79	u_int type;
80	int ec_nid;
81	int hash_alg;
82};
83static const struct kexalg kexalgs[] = {
84#ifdef WITH_OPENSSL
85	{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
86	{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
87	{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
88	{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
89	{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
90	{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
91	{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
92	{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
93	    NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
94	{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
95	    SSH_DIGEST_SHA384 },
96	{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
97	    SSH_DIGEST_SHA512 },
98#endif
99	{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
100	{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
101	{ KEX_SNTRUP4591761X25519_SHA512, KEX_KEM_SNTRUP4591761X25519_SHA512, 0,
102	    SSH_DIGEST_SHA512 },
103	{ NULL, -1, -1, -1},
104};
105
106char *
107kex_alg_list(char sep)
108{
109	char *ret = NULL, *tmp;
110	size_t nlen, rlen = 0;
111	const struct kexalg *k;
112
113	for (k = kexalgs; k->name != NULL; k++) {
114		if (ret != NULL)
115			ret[rlen++] = sep;
116		nlen = strlen(k->name);
117		if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
118			free(ret);
119			return NULL;
120		}
121		ret = tmp;
122		memcpy(ret + rlen, k->name, nlen + 1);
123		rlen += nlen;
124	}
125	return ret;
126}
127
128static const struct kexalg *
129kex_alg_by_name(const char *name)
130{
131	const struct kexalg *k;
132
133	for (k = kexalgs; k->name != NULL; k++) {
134		if (strcmp(k->name, name) == 0)
135			return k;
136	}
137	return NULL;
138}
139
140/* Validate KEX method name list */
141int
142kex_names_valid(const char *names)
143{
144	char *s, *cp, *p;
145
146	if (names == NULL || strcmp(names, "") == 0)
147		return 0;
148	if ((s = cp = strdup(names)) == NULL)
149		return 0;
150	for ((p = strsep(&cp, ",")); p && *p != '\0';
151	    (p = strsep(&cp, ","))) {
152		if (kex_alg_by_name(p) == NULL) {
153			error("Unsupported KEX algorithm \"%.100s\"", p);
154			free(s);
155			return 0;
156		}
157	}
158	debug3("kex names ok: [%s]", names);
159	free(s);
160	return 1;
161}
162
163/*
164 * Concatenate algorithm names, avoiding duplicates in the process.
165 * Caller must free returned string.
166 */
167char *
168kex_names_cat(const char *a, const char *b)
169{
170	char *ret = NULL, *tmp = NULL, *cp, *p, *m;
171	size_t len;
172
173	if (a == NULL || *a == '\0')
174		return strdup(b);
175	if (b == NULL || *b == '\0')
176		return strdup(a);
177	if (strlen(b) > 1024*1024)
178		return NULL;
179	len = strlen(a) + strlen(b) + 2;
180	if ((tmp = cp = strdup(b)) == NULL ||
181	    (ret = calloc(1, len)) == NULL) {
182		free(tmp);
183		return NULL;
184	}
185	strlcpy(ret, a, len);
186	for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
187		if ((m = match_list(ret, p, NULL)) != NULL) {
188			free(m);
189			continue; /* Algorithm already present */
190		}
191		if (strlcat(ret, ",", len) >= len ||
192		    strlcat(ret, p, len) >= len) {
193			free(tmp);
194			free(ret);
195			return NULL; /* Shouldn't happen */
196		}
197	}
198	free(tmp);
199	return ret;
200}
201
202/*
203 * Assemble a list of algorithms from a default list and a string from a
204 * configuration file. The user-provided string may begin with '+' to
205 * indicate that it should be appended to the default or '-' that the
206 * specified names should be removed.
207 */
208int
209kex_assemble_names(char **listp, const char *def, const char *all)
210{
211	char *cp, *tmp, *patterns;
212	char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL;
213	int r = SSH_ERR_INTERNAL_ERROR;
214
215	if (listp == NULL || *listp == NULL || **listp == '\0') {
216		if ((*listp = strdup(def)) == NULL)
217			return SSH_ERR_ALLOC_FAIL;
218		return 0;
219	}
220
221	list = *listp;
222	*listp = NULL;
223	if (*list == '+') {
224		/* Append names to default list */
225		if ((tmp = kex_names_cat(def, list + 1)) == NULL) {
226			r = SSH_ERR_ALLOC_FAIL;
227			goto fail;
228		}
229		free(list);
230		list = tmp;
231	} else if (*list == '-') {
232		/* Remove names from default list */
233		if ((*listp = match_filter_blacklist(def, list + 1)) == NULL) {
234			r = SSH_ERR_ALLOC_FAIL;
235			goto fail;
236		}
237		free(list);
238		/* filtering has already been done */
239		return 0;
240	} else {
241		/* Explicit list, overrides default - just use "list" as is */
242	}
243
244	/*
245	 * The supplied names may be a pattern-list. For the -list case,
246	 * the patterns are applied above. For the +list and explicit list
247	 * cases we need to do it now.
248	 */
249	ret = NULL;
250	if ((patterns = opatterns = strdup(list)) == NULL) {
251		r = SSH_ERR_ALLOC_FAIL;
252		goto fail;
253	}
254	/* Apply positive (i.e. non-negated) patterns from the list */
255	while ((cp = strsep(&patterns, ",")) != NULL) {
256		if (*cp == '!') {
257			/* negated matches are not supported here */
258			r = SSH_ERR_INVALID_ARGUMENT;
259			goto fail;
260		}
261		free(matching);
262		if ((matching = match_filter_whitelist(all, cp)) == NULL) {
263			r = SSH_ERR_ALLOC_FAIL;
264			goto fail;
265		}
266		if ((tmp = kex_names_cat(ret, matching)) == NULL) {
267			r = SSH_ERR_ALLOC_FAIL;
268			goto fail;
269		}
270		free(ret);
271		ret = tmp;
272	}
273	if (ret == NULL || *ret == '\0') {
274		/* An empty name-list is an error */
275		/* XXX better error code? */
276		r = SSH_ERR_INVALID_ARGUMENT;
277		goto fail;
278	}
279
280	/* success */
281	*listp = ret;
282	ret = NULL;
283	r = 0;
284
285 fail:
286	free(matching);
287	free(opatterns);
288	free(list);
289	free(ret);
290	return r;
291}
292
293/* put algorithm proposal into buffer */
294int
295kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
296{
297	u_int i;
298	int r;
299
300	sshbuf_reset(b);
301
302	/*
303	 * add a dummy cookie, the cookie will be overwritten by
304	 * kex_send_kexinit(), each time a kexinit is set
305	 */
306	for (i = 0; i < KEX_COOKIE_LEN; i++) {
307		if ((r = sshbuf_put_u8(b, 0)) != 0)
308			return r;
309	}
310	for (i = 0; i < PROPOSAL_MAX; i++) {
311		if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
312			return r;
313	}
314	if ((r = sshbuf_put_u8(b, 0)) != 0 ||	/* first_kex_packet_follows */
315	    (r = sshbuf_put_u32(b, 0)) != 0)	/* uint32 reserved */
316		return r;
317	return 0;
318}
319
320/* parse buffer and return algorithm proposal */
321int
322kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
323{
324	struct sshbuf *b = NULL;
325	u_char v;
326	u_int i;
327	char **proposal = NULL;
328	int r;
329
330	*propp = NULL;
331	if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
332		return SSH_ERR_ALLOC_FAIL;
333	if ((b = sshbuf_fromb(raw)) == NULL) {
334		r = SSH_ERR_ALLOC_FAIL;
335		goto out;
336	}
337	if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
338		goto out;
339	/* extract kex init proposal strings */
340	for (i = 0; i < PROPOSAL_MAX; i++) {
341		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
342			goto out;
343		debug2("%s: %s", proposal_names[i], proposal[i]);
344	}
345	/* first kex follows / reserved */
346	if ((r = sshbuf_get_u8(b, &v)) != 0 ||	/* first_kex_follows */
347	    (r = sshbuf_get_u32(b, &i)) != 0)	/* reserved */
348		goto out;
349	if (first_kex_follows != NULL)
350		*first_kex_follows = v;
351	debug2("first_kex_follows %d ", v);
352	debug2("reserved %u ", i);
353	r = 0;
354	*propp = proposal;
355 out:
356	if (r != 0 && proposal != NULL)
357		kex_prop_free(proposal);
358	sshbuf_free(b);
359	return r;
360}
361
362void
363kex_prop_free(char **proposal)
364{
365	u_int i;
366
367	if (proposal == NULL)
368		return;
369	for (i = 0; i < PROPOSAL_MAX; i++)
370		free(proposal[i]);
371	free(proposal);
372}
373
374/* ARGSUSED */
375static int
376kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
377{
378	int r;
379
380	error("kex protocol error: type %d seq %u", type, seq);
381	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
382	    (r = sshpkt_put_u32(ssh, seq)) != 0 ||
383	    (r = sshpkt_send(ssh)) != 0)
384		return r;
385	return 0;
386}
387
388static void
389kex_reset_dispatch(struct ssh *ssh)
390{
391	ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
392	    SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
393}
394
395static int
396kex_send_ext_info(struct ssh *ssh)
397{
398	int r;
399	char *algs;
400
401	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
402		return SSH_ERR_ALLOC_FAIL;
403	/* XXX filter algs list by allowed pubkey/hostbased types */
404	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
405	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
406	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
407	    (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
408	    (r = sshpkt_send(ssh)) != 0)
409		goto out;
410	/* success */
411	r = 0;
412 out:
413	free(algs);
414	return r;
415}
416
417int
418kex_send_newkeys(struct ssh *ssh)
419{
420	int r;
421
422	kex_reset_dispatch(ssh);
423	if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
424	    (r = sshpkt_send(ssh)) != 0)
425		return r;
426	debug("SSH2_MSG_NEWKEYS sent");
427	debug("expecting SSH2_MSG_NEWKEYS");
428	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
429	if (ssh->kex->ext_info_c)
430		if ((r = kex_send_ext_info(ssh)) != 0)
431			return r;
432	return 0;
433}
434
435int
436kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
437{
438	struct kex *kex = ssh->kex;
439	u_int32_t i, ninfo;
440	char *name;
441	u_char *val;
442	size_t vlen;
443	int r;
444
445	debug("SSH2_MSG_EXT_INFO received");
446	ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
447	if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
448		return r;
449	for (i = 0; i < ninfo; i++) {
450		if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
451			return r;
452		if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) {
453			free(name);
454			return r;
455		}
456		if (strcmp(name, "server-sig-algs") == 0) {
457			/* Ensure no \0 lurking in value */
458			if (memchr(val, '\0', vlen) != NULL) {
459				error("%s: nul byte in %s", __func__, name);
460				return SSH_ERR_INVALID_FORMAT;
461			}
462			debug("%s: %s=<%s>", __func__, name, val);
463			kex->server_sig_algs = val;
464			val = NULL;
465		} else
466			debug("%s: %s (unrecognised)", __func__, name);
467		free(name);
468		free(val);
469	}
470	return sshpkt_get_end(ssh);
471}
472
473static int
474kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
475{
476	struct kex *kex = ssh->kex;
477	int r;
478
479	debug("SSH2_MSG_NEWKEYS received");
480	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
481	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
482	if ((r = sshpkt_get_end(ssh)) != 0)
483		return r;
484	if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)
485		return r;
486	kex->done = 1;
487	kex->flags &= ~KEX_INITIAL;
488	sshbuf_reset(kex->peer);
489	/* sshbuf_reset(kex->my); */
490	kex->flags &= ~KEX_INIT_SENT;
491	free(kex->name);
492	kex->name = NULL;
493	return 0;
494}
495
496int
497kex_send_kexinit(struct ssh *ssh)
498{
499	u_char *cookie;
500	struct kex *kex = ssh->kex;
501	int r;
502
503	if (kex == NULL)
504		return SSH_ERR_INTERNAL_ERROR;
505	if (kex->flags & KEX_INIT_SENT)
506		return 0;
507	kex->done = 0;
508
509	/* generate a random cookie */
510	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
511		return SSH_ERR_INVALID_FORMAT;
512	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
513		return SSH_ERR_INTERNAL_ERROR;
514	arc4random_buf(cookie, KEX_COOKIE_LEN);
515
516	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
517	    (r = sshpkt_putb(ssh, kex->my)) != 0 ||
518	    (r = sshpkt_send(ssh)) != 0)
519		return r;
520	debug("SSH2_MSG_KEXINIT sent");
521	kex->flags |= KEX_INIT_SENT;
522	return 0;
523}
524
525/* ARGSUSED */
526int
527kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
528{
529	struct kex *kex = ssh->kex;
530	const u_char *ptr;
531	u_int i;
532	size_t dlen;
533	int r;
534
535	debug("SSH2_MSG_KEXINIT received");
536	if (kex == NULL)
537		return SSH_ERR_INVALID_ARGUMENT;
538
539	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
540	ptr = sshpkt_ptr(ssh, &dlen);
541	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
542		return r;
543
544	/* discard packet */
545	for (i = 0; i < KEX_COOKIE_LEN; i++)
546		if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
547			return r;
548	for (i = 0; i < PROPOSAL_MAX; i++)
549		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
550			return r;
551	/*
552	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
553	 * KEX method has the server move first, but a server might be using
554	 * a custom method or one that we otherwise don't support. We should
555	 * be prepared to remember first_kex_follows here so we can eat a
556	 * packet later.
557	 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
558	 * for cases where the server *doesn't* go first. I guess we should
559	 * ignore it when it is set for these cases, which is what we do now.
560	 */
561	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||	/* first_kex_follows */
562	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||	/* reserved */
563	    (r = sshpkt_get_end(ssh)) != 0)
564			return r;
565
566	if (!(kex->flags & KEX_INIT_SENT))
567		if ((r = kex_send_kexinit(ssh)) != 0)
568			return r;
569	if ((r = kex_choose_conf(ssh)) != 0)
570		return r;
571
572	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
573		return (kex->kex[kex->kex_type])(ssh);
574
575	return SSH_ERR_INTERNAL_ERROR;
576}
577
578struct kex *
579kex_new(void)
580{
581	struct kex *kex;
582
583	if ((kex = calloc(1, sizeof(*kex))) == NULL ||
584	    (kex->peer = sshbuf_new()) == NULL ||
585	    (kex->my = sshbuf_new()) == NULL ||
586	    (kex->client_version = sshbuf_new()) == NULL ||
587	    (kex->server_version = sshbuf_new()) == NULL) {
588		kex_free(kex);
589		return NULL;
590	}
591	return kex;
592}
593
594void
595kex_free_newkeys(struct newkeys *newkeys)
596{
597	if (newkeys == NULL)
598		return;
599	if (newkeys->enc.key) {
600		explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
601		free(newkeys->enc.key);
602		newkeys->enc.key = NULL;
603	}
604	if (newkeys->enc.iv) {
605		explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);
606		free(newkeys->enc.iv);
607		newkeys->enc.iv = NULL;
608	}
609	free(newkeys->enc.name);
610	explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
611	free(newkeys->comp.name);
612	explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
613	mac_clear(&newkeys->mac);
614	if (newkeys->mac.key) {
615		explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
616		free(newkeys->mac.key);
617		newkeys->mac.key = NULL;
618	}
619	free(newkeys->mac.name);
620	explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
621	explicit_bzero(newkeys, sizeof(*newkeys));
622	free(newkeys);
623}
624
625void
626kex_free(struct kex *kex)
627{
628	u_int mode;
629
630	if (kex == NULL)
631		return;
632
633#ifdef WITH_OPENSSL
634	DH_free(kex->dh);
635	EC_KEY_free(kex->ec_client_key);
636#endif
637	for (mode = 0; mode < MODE_MAX; mode++) {
638		kex_free_newkeys(kex->newkeys[mode]);
639		kex->newkeys[mode] = NULL;
640	}
641	sshbuf_free(kex->peer);
642	sshbuf_free(kex->my);
643	sshbuf_free(kex->client_version);
644	sshbuf_free(kex->server_version);
645	sshbuf_free(kex->client_pub);
646	free(kex->session_id);
647	free(kex->failed_choice);
648	free(kex->hostkey_alg);
649	free(kex->name);
650	free(kex);
651}
652
653int
654kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
655{
656	int r;
657
658	if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0)
659		return r;
660	ssh->kex->flags = KEX_INITIAL;
661	kex_reset_dispatch(ssh);
662	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
663	return 0;
664}
665
666int
667kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
668{
669	int r;
670
671	if ((r = kex_ready(ssh, proposal)) != 0)
672		return r;
673	if ((r = kex_send_kexinit(ssh)) != 0) {		/* we start */
674		kex_free(ssh->kex);
675		ssh->kex = NULL;
676		return r;
677	}
678	return 0;
679}
680
681/*
682 * Request key re-exchange, returns 0 on success or a ssherr.h error
683 * code otherwise. Must not be called if KEX is incomplete or in-progress.
684 */
685int
686kex_start_rekex(struct ssh *ssh)
687{
688	if (ssh->kex == NULL) {
689		error("%s: no kex", __func__);
690		return SSH_ERR_INTERNAL_ERROR;
691	}
692	if (ssh->kex->done == 0) {
693		error("%s: requested twice", __func__);
694		return SSH_ERR_INTERNAL_ERROR;
695	}
696	ssh->kex->done = 0;
697	return kex_send_kexinit(ssh);
698}
699
700static int
701choose_enc(struct sshenc *enc, char *client, char *server)
702{
703	char *name = match_list(client, server, NULL);
704
705	if (name == NULL)
706		return SSH_ERR_NO_CIPHER_ALG_MATCH;
707	if ((enc->cipher = cipher_by_name(name)) == NULL) {
708		free(name);
709		return SSH_ERR_INTERNAL_ERROR;
710	}
711	enc->name = name;
712	enc->enabled = 0;
713	enc->iv = NULL;
714	enc->iv_len = cipher_ivlen(enc->cipher);
715	enc->key = NULL;
716	enc->key_len = cipher_keylen(enc->cipher);
717	enc->block_size = cipher_blocksize(enc->cipher);
718	return 0;
719}
720
721static int
722choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
723{
724	char *name = match_list(client, server, NULL);
725
726	if (name == NULL)
727		return SSH_ERR_NO_MAC_ALG_MATCH;
728	if (mac_setup(mac, name) < 0) {
729		free(name);
730		return SSH_ERR_INTERNAL_ERROR;
731	}
732	mac->name = name;
733	mac->key = NULL;
734	mac->enabled = 0;
735	return 0;
736}
737
738static int
739choose_comp(struct sshcomp *comp, char *client, char *server)
740{
741	char *name = match_list(client, server, NULL);
742
743	if (name == NULL)
744		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
745	if (strcmp(name, "zlib@openssh.com") == 0) {
746		comp->type = COMP_DELAYED;
747	} else if (strcmp(name, "zlib") == 0) {
748		comp->type = COMP_ZLIB;
749	} else if (strcmp(name, "none") == 0) {
750		comp->type = COMP_NONE;
751	} else {
752		free(name);
753		return SSH_ERR_INTERNAL_ERROR;
754	}
755	comp->name = name;
756	return 0;
757}
758
759static int
760choose_kex(struct kex *k, char *client, char *server)
761{
762	const struct kexalg *kexalg;
763
764	k->name = match_list(client, server, NULL);
765
766	debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
767	if (k->name == NULL)
768		return SSH_ERR_NO_KEX_ALG_MATCH;
769	if ((kexalg = kex_alg_by_name(k->name)) == NULL)
770		return SSH_ERR_INTERNAL_ERROR;
771	k->kex_type = kexalg->type;
772	k->hash_alg = kexalg->hash_alg;
773	k->ec_nid = kexalg->ec_nid;
774	return 0;
775}
776
777static int
778choose_hostkeyalg(struct kex *k, char *client, char *server)
779{
780	k->hostkey_alg = match_list(client, server, NULL);
781
782	debug("kex: host key algorithm: %s",
783	    k->hostkey_alg ? k->hostkey_alg : "(no match)");
784	if (k->hostkey_alg == NULL)
785		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
786	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
787	if (k->hostkey_type == KEY_UNSPEC)
788		return SSH_ERR_INTERNAL_ERROR;
789	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
790	return 0;
791}
792
793static int
794proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
795{
796	static int check[] = {
797		PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
798	};
799	int *idx;
800	char *p;
801
802	for (idx = &check[0]; *idx != -1; idx++) {
803		if ((p = strchr(my[*idx], ',')) != NULL)
804			*p = '\0';
805		if ((p = strchr(peer[*idx], ',')) != NULL)
806			*p = '\0';
807		if (strcmp(my[*idx], peer[*idx]) != 0) {
808			debug2("proposal mismatch: my %s peer %s",
809			    my[*idx], peer[*idx]);
810			return (0);
811		}
812	}
813	debug2("proposals match");
814	return (1);
815}
816
817static int
818kex_choose_conf(struct ssh *ssh)
819{
820	struct kex *kex = ssh->kex;
821	struct newkeys *newkeys;
822	char **my = NULL, **peer = NULL;
823	char **cprop, **sprop;
824	int nenc, nmac, ncomp;
825	u_int mode, ctos, need, dh_need, authlen;
826	int r, first_kex_follows;
827
828	debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
829	if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
830		goto out;
831	debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
832	if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
833		goto out;
834
835	if (kex->server) {
836		cprop=peer;
837		sprop=my;
838	} else {
839		cprop=my;
840		sprop=peer;
841	}
842
843	/* Check whether client supports ext_info_c */
844	if (kex->server && (kex->flags & KEX_INITIAL)) {
845		char *ext;
846
847		ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
848		kex->ext_info_c = (ext != NULL);
849		free(ext);
850	}
851
852	/* Algorithm Negotiation */
853	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
854	    sprop[PROPOSAL_KEX_ALGS])) != 0) {
855		kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
856		peer[PROPOSAL_KEX_ALGS] = NULL;
857		goto out;
858	}
859	if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
860	    sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
861		kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
862		peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
863		goto out;
864	}
865	for (mode = 0; mode < MODE_MAX; mode++) {
866		if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
867			r = SSH_ERR_ALLOC_FAIL;
868			goto out;
869		}
870		kex->newkeys[mode] = newkeys;
871		ctos = (!kex->server && mode == MODE_OUT) ||
872		    (kex->server && mode == MODE_IN);
873		nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
874		nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
875		ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
876		if ((r = choose_enc(&newkeys->enc, cprop[nenc],
877		    sprop[nenc])) != 0) {
878			kex->failed_choice = peer[nenc];
879			peer[nenc] = NULL;
880			goto out;
881		}
882		authlen = cipher_authlen(newkeys->enc.cipher);
883		/* ignore mac for authenticated encryption */
884		if (authlen == 0 &&
885		    (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
886		    sprop[nmac])) != 0) {
887			kex->failed_choice = peer[nmac];
888			peer[nmac] = NULL;
889			goto out;
890		}
891		if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
892		    sprop[ncomp])) != 0) {
893			kex->failed_choice = peer[ncomp];
894			peer[ncomp] = NULL;
895			goto out;
896		}
897		debug("kex: %s cipher: %s MAC: %s compression: %s",
898		    ctos ? "client->server" : "server->client",
899		    newkeys->enc.name,
900		    authlen == 0 ? newkeys->mac.name : "<implicit>",
901		    newkeys->comp.name);
902	}
903	need = dh_need = 0;
904	for (mode = 0; mode < MODE_MAX; mode++) {
905		newkeys = kex->newkeys[mode];
906		need = MAXIMUM(need, newkeys->enc.key_len);
907		need = MAXIMUM(need, newkeys->enc.block_size);
908		need = MAXIMUM(need, newkeys->enc.iv_len);
909		need = MAXIMUM(need, newkeys->mac.key_len);
910		dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher));
911		dh_need = MAXIMUM(dh_need, newkeys->enc.block_size);
912		dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len);
913		dh_need = MAXIMUM(dh_need, newkeys->mac.key_len);
914	}
915	/* XXX need runden? */
916	kex->we_need = need;
917	kex->dh_need = dh_need;
918
919	/* ignore the next message if the proposals do not match */
920	if (first_kex_follows && !proposals_match(my, peer))
921		ssh->dispatch_skip_packets = 1;
922	r = 0;
923 out:
924	kex_prop_free(my);
925	kex_prop_free(peer);
926	return r;
927}
928
929static int
930derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
931    const struct sshbuf *shared_secret, u_char **keyp)
932{
933	struct kex *kex = ssh->kex;
934	struct ssh_digest_ctx *hashctx = NULL;
935	char c = id;
936	u_int have;
937	size_t mdsz;
938	u_char *digest;
939	int r;
940
941	if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
942		return SSH_ERR_INVALID_ARGUMENT;
943	if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) {
944		r = SSH_ERR_ALLOC_FAIL;
945		goto out;
946	}
947
948	/* K1 = HASH(K || H || "A" || session_id) */
949	if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
950	    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
951	    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
952	    ssh_digest_update(hashctx, &c, 1) != 0 ||
953	    ssh_digest_update(hashctx, kex->session_id,
954	    kex->session_id_len) != 0 ||
955	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
956		r = SSH_ERR_LIBCRYPTO_ERROR;
957		goto out;
958	}
959	ssh_digest_free(hashctx);
960	hashctx = NULL;
961
962	/*
963	 * expand key:
964	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
965	 * Key = K1 || K2 || ... || Kn
966	 */
967	for (have = mdsz; need > have; have += mdsz) {
968		if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
969		    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
970		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
971		    ssh_digest_update(hashctx, digest, have) != 0 ||
972		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
973			r = SSH_ERR_LIBCRYPTO_ERROR;
974			goto out;
975		}
976		ssh_digest_free(hashctx);
977		hashctx = NULL;
978	}
979#ifdef DEBUG_KEX
980	fprintf(stderr, "key '%c'== ", c);
981	dump_digest("key", digest, need);
982#endif
983	*keyp = digest;
984	digest = NULL;
985	r = 0;
986 out:
987	free(digest);
988	ssh_digest_free(hashctx);
989	return r;
990}
991
992#define NKEYS	6
993int
994kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
995    const struct sshbuf *shared_secret)
996{
997	struct kex *kex = ssh->kex;
998	u_char *keys[NKEYS];
999	u_int i, j, mode, ctos;
1000	int r;
1001
1002	/* save initial hash as session id */
1003	if (kex->session_id == NULL) {
1004		kex->session_id_len = hashlen;
1005		kex->session_id = malloc(kex->session_id_len);
1006		if (kex->session_id == NULL)
1007			return SSH_ERR_ALLOC_FAIL;
1008		memcpy(kex->session_id, hash, kex->session_id_len);
1009	}
1010	for (i = 0; i < NKEYS; i++) {
1011		if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
1012		    shared_secret, &keys[i])) != 0) {
1013			for (j = 0; j < i; j++)
1014				free(keys[j]);
1015			return r;
1016		}
1017	}
1018	for (mode = 0; mode < MODE_MAX; mode++) {
1019		ctos = (!kex->server && mode == MODE_OUT) ||
1020		    (kex->server && mode == MODE_IN);
1021		kex->newkeys[mode]->enc.iv  = keys[ctos ? 0 : 1];
1022		kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
1023		kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
1024	}
1025	return 0;
1026}
1027
1028int
1029kex_load_hostkey(struct ssh *ssh, struct sshkey **pubp, struct sshkey **prvp)
1030{
1031	struct kex *kex = ssh->kex;
1032
1033	*pubp = NULL;
1034	*prvp = NULL;
1035	if (kex->load_host_public_key == NULL ||
1036	    kex->load_host_private_key == NULL)
1037		return SSH_ERR_INVALID_ARGUMENT;
1038	*pubp = kex->load_host_public_key(kex->hostkey_type,
1039	    kex->hostkey_nid, ssh);
1040	*prvp = kex->load_host_private_key(kex->hostkey_type,
1041	    kex->hostkey_nid, ssh);
1042	if (*pubp == NULL)
1043		return SSH_ERR_NO_HOSTKEY_LOADED;
1044	return 0;
1045}
1046
1047int
1048kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key)
1049{
1050	struct kex *kex = ssh->kex;
1051
1052	if (kex->verify_host_key == NULL)
1053		return SSH_ERR_INVALID_ARGUMENT;
1054	if (server_host_key->type != kex->hostkey_type ||
1055	    (kex->hostkey_type == KEY_ECDSA &&
1056	    server_host_key->ecdsa_nid != kex->hostkey_nid))
1057		return SSH_ERR_KEY_TYPE_MISMATCH;
1058	if (kex->verify_host_key(server_host_key, ssh) == -1)
1059		return  SSH_ERR_SIGNATURE_INVALID;
1060	return 0;
1061}
1062
1063#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
1064void
1065dump_digest(const char *msg, const u_char *digest, int len)
1066{
1067	fprintf(stderr, "%s\n", msg);
1068	sshbuf_dump_data(digest, len, stderr);
1069}
1070#endif
1071
1072/*
1073 * Send a plaintext error message to the peer, suffixed by \r\n.
1074 * Only used during banner exchange, and there only for the server.
1075 */
1076static void
1077send_error(struct ssh *ssh, char *msg)
1078{
1079	char *crnl = "\r\n";
1080
1081	if (!ssh->kex->server)
1082		return;
1083
1084	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1085	    msg, strlen(msg)) != strlen(msg) ||
1086	    atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1087	    crnl, strlen(crnl)) != strlen(crnl))
1088		error("%s: write: %.100s", __func__, strerror(errno));
1089}
1090
1091/*
1092 * Sends our identification string and waits for the peer's. Will block for
1093 * up to timeout_ms (or indefinitely if timeout_ms <= 0).
1094 * Returns on 0 success or a ssherr.h code on failure.
1095 */
1096int
1097kex_exchange_identification(struct ssh *ssh, int timeout_ms,
1098    const char *version_addendum)
1099{
1100	int remote_major, remote_minor, mismatch;
1101	size_t len, i, n;
1102	int r, expect_nl;
1103	u_char c;
1104	struct sshbuf *our_version = ssh->kex->server ?
1105	    ssh->kex->server_version : ssh->kex->client_version;
1106	struct sshbuf *peer_version = ssh->kex->server ?
1107	    ssh->kex->client_version : ssh->kex->server_version;
1108	char *our_version_string = NULL, *peer_version_string = NULL;
1109	char *cp, *remote_version = NULL;
1110
1111	/* Prepare and send our banner */
1112	sshbuf_reset(our_version);
1113	if (version_addendum != NULL && *version_addendum == '\0')
1114		version_addendum = NULL;
1115	if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n",
1116	   PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
1117	    version_addendum == NULL ? "" : " ",
1118	    version_addendum == NULL ? "" : version_addendum)) != 0) {
1119		error("%s: sshbuf_putf: %s", __func__, ssh_err(r));
1120		goto out;
1121	}
1122
1123	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1124	    sshbuf_mutable_ptr(our_version),
1125	    sshbuf_len(our_version)) != sshbuf_len(our_version)) {
1126		error("%s: write: %.100s", __func__, strerror(errno));
1127		r = SSH_ERR_SYSTEM_ERROR;
1128		goto out;
1129	}
1130	if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */
1131		error("%s: sshbuf_consume_end: %s", __func__, ssh_err(r));
1132		goto out;
1133	}
1134	our_version_string = sshbuf_dup_string(our_version);
1135	if (our_version_string == NULL) {
1136		error("%s: sshbuf_dup_string failed", __func__);
1137		r = SSH_ERR_ALLOC_FAIL;
1138		goto out;
1139	}
1140	debug("Local version string %.100s", our_version_string);
1141
1142	/* Read other side's version identification. */
1143	for (n = 0; ; n++) {
1144		if (n >= SSH_MAX_PRE_BANNER_LINES) {
1145			send_error(ssh, "No SSH identification string "
1146			    "received.");
1147			error("%s: No SSH version received in first %u lines "
1148			    "from server", __func__, SSH_MAX_PRE_BANNER_LINES);
1149			r = SSH_ERR_INVALID_FORMAT;
1150			goto out;
1151		}
1152		sshbuf_reset(peer_version);
1153		expect_nl = 0;
1154		for (i = 0; ; i++) {
1155			if (timeout_ms > 0) {
1156				r = waitrfd(ssh_packet_get_connection_in(ssh),
1157				    &timeout_ms);
1158				if (r == -1 && errno == ETIMEDOUT) {
1159					send_error(ssh, "Timed out waiting "
1160					    "for SSH identification string.");
1161					error("Connection timed out during "
1162					    "banner exchange");
1163					r = SSH_ERR_CONN_TIMEOUT;
1164					goto out;
1165				} else if (r == -1) {
1166					error("%s: %s",
1167					    __func__, strerror(errno));
1168					r = SSH_ERR_SYSTEM_ERROR;
1169					goto out;
1170				}
1171			}
1172
1173			len = atomicio(read, ssh_packet_get_connection_in(ssh),
1174			    &c, 1);
1175			if (len != 1 && errno == EPIPE) {
1176				error("%s: Connection closed by remote host",
1177				    __func__);
1178				r = SSH_ERR_CONN_CLOSED;
1179				goto out;
1180			} else if (len != 1) {
1181				error("%s: read: %.100s",
1182				    __func__, strerror(errno));
1183				r = SSH_ERR_SYSTEM_ERROR;
1184				goto out;
1185			}
1186			if (c == '\r') {
1187				expect_nl = 1;
1188				continue;
1189			}
1190			if (c == '\n')
1191				break;
1192			if (c == '\0' || expect_nl) {
1193				error("%s: banner line contains invalid "
1194				    "characters", __func__);
1195				goto invalid;
1196			}
1197			if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
1198				error("%s: sshbuf_put: %s",
1199				    __func__, ssh_err(r));
1200				goto out;
1201			}
1202			if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
1203				error("%s: banner line too long", __func__);
1204				goto invalid;
1205			}
1206		}
1207		/* Is this an actual protocol banner? */
1208		if (sshbuf_len(peer_version) > 4 &&
1209		    memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0)
1210			break;
1211		/* If not, then just log the line and continue */
1212		if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
1213			error("%s: sshbuf_dup_string failed", __func__);
1214			r = SSH_ERR_ALLOC_FAIL;
1215			goto out;
1216		}
1217		/* Do not accept lines before the SSH ident from a client */
1218		if (ssh->kex->server) {
1219			error("%s: client sent invalid protocol identifier "
1220			    "\"%.256s\"", __func__, cp);
1221			free(cp);
1222			goto invalid;
1223		}
1224		debug("%s: banner line %zu: %s", __func__, n, cp);
1225		free(cp);
1226	}
1227	peer_version_string = sshbuf_dup_string(peer_version);
1228	if (peer_version_string == NULL)
1229		error("%s: sshbuf_dup_string failed", __func__);
1230	/* XXX must be same size for sscanf */
1231	if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
1232		error("%s: calloc failed", __func__);
1233		r = SSH_ERR_ALLOC_FAIL;
1234		goto out;
1235	}
1236
1237	/*
1238	 * Check that the versions match.  In future this might accept
1239	 * several versions and set appropriate flags to handle them.
1240	 */
1241	if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n",
1242	    &remote_major, &remote_minor, remote_version) != 3) {
1243		error("Bad remote protocol version identification: '%.100s'",
1244		    peer_version_string);
1245 invalid:
1246		send_error(ssh, "Invalid SSH identification string.");
1247		r = SSH_ERR_INVALID_FORMAT;
1248		goto out;
1249	}
1250	debug("Remote protocol version %d.%d, remote software version %.100s",
1251	    remote_major, remote_minor, remote_version);
1252	ssh->compat = compat_datafellows(remote_version);
1253
1254	mismatch = 0;
1255	switch (remote_major) {
1256	case 2:
1257		break;
1258	case 1:
1259		if (remote_minor != 99)
1260			mismatch = 1;
1261		break;
1262	default:
1263		mismatch = 1;
1264		break;
1265	}
1266	if (mismatch) {
1267		error("Protocol major versions differ: %d vs. %d",
1268		    PROTOCOL_MAJOR_2, remote_major);
1269		send_error(ssh, "Protocol major versions differ.");
1270		r = SSH_ERR_NO_PROTOCOL_VERSION;
1271		goto out;
1272	}
1273
1274	if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) {
1275		logit("probed from %s port %d with %s.  Don't panic.",
1276		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1277		    peer_version_string);
1278		r = SSH_ERR_CONN_CLOSED; /* XXX */
1279		goto out;
1280	}
1281	if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) {
1282		logit("scanned from %s port %d with %s.  Don't panic.",
1283		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1284		    peer_version_string);
1285		r = SSH_ERR_CONN_CLOSED; /* XXX */
1286		goto out;
1287	}
1288	if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
1289		logit("Remote version \"%.100s\" uses unsafe RSA signature "
1290		    "scheme; disabling use of RSA keys", remote_version);
1291	}
1292	/* success */
1293	r = 0;
1294 out:
1295	free(our_version_string);
1296	free(peer_version_string);
1297	free(remote_version);
1298	return r;
1299}
1300
1301