kex.c revision 1.160
1/* $OpenBSD: kex.c,v 1.160 2020/10/18 11:32:01 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, 0, -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, '-' that the
206 * specified names should be removed, or '^' that they should be placed
207 * at the head.
208 */
209int
210kex_assemble_names(char **listp, const char *def, const char *all)
211{
212	char *cp, *tmp, *patterns;
213	char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL;
214	int r = SSH_ERR_INTERNAL_ERROR;
215
216	if (listp == NULL || def == NULL || all == NULL)
217		return SSH_ERR_INVALID_ARGUMENT;
218
219	if (*listp == NULL || **listp == '\0') {
220		if ((*listp = strdup(def)) == NULL)
221			return SSH_ERR_ALLOC_FAIL;
222		return 0;
223	}
224
225	list = *listp;
226	*listp = NULL;
227	if (*list == '+') {
228		/* Append names to default list */
229		if ((tmp = kex_names_cat(def, list + 1)) == NULL) {
230			r = SSH_ERR_ALLOC_FAIL;
231			goto fail;
232		}
233		free(list);
234		list = tmp;
235	} else if (*list == '-') {
236		/* Remove names from default list */
237		if ((*listp = match_filter_denylist(def, list + 1)) == NULL) {
238			r = SSH_ERR_ALLOC_FAIL;
239			goto fail;
240		}
241		free(list);
242		/* filtering has already been done */
243		return 0;
244	} else if (*list == '^') {
245		/* Place names at head of default list */
246		if ((tmp = kex_names_cat(list + 1, def)) == NULL) {
247			r = SSH_ERR_ALLOC_FAIL;
248			goto fail;
249		}
250		free(list);
251		list = tmp;
252	} else {
253		/* Explicit list, overrides default - just use "list" as is */
254	}
255
256	/*
257	 * The supplied names may be a pattern-list. For the -list case,
258	 * the patterns are applied above. For the +list and explicit list
259	 * cases we need to do it now.
260	 */
261	ret = NULL;
262	if ((patterns = opatterns = strdup(list)) == NULL) {
263		r = SSH_ERR_ALLOC_FAIL;
264		goto fail;
265	}
266	/* Apply positive (i.e. non-negated) patterns from the list */
267	while ((cp = strsep(&patterns, ",")) != NULL) {
268		if (*cp == '!') {
269			/* negated matches are not supported here */
270			r = SSH_ERR_INVALID_ARGUMENT;
271			goto fail;
272		}
273		free(matching);
274		if ((matching = match_filter_allowlist(all, cp)) == NULL) {
275			r = SSH_ERR_ALLOC_FAIL;
276			goto fail;
277		}
278		if ((tmp = kex_names_cat(ret, matching)) == NULL) {
279			r = SSH_ERR_ALLOC_FAIL;
280			goto fail;
281		}
282		free(ret);
283		ret = tmp;
284	}
285	if (ret == NULL || *ret == '\0') {
286		/* An empty name-list is an error */
287		/* XXX better error code? */
288		r = SSH_ERR_INVALID_ARGUMENT;
289		goto fail;
290	}
291
292	/* success */
293	*listp = ret;
294	ret = NULL;
295	r = 0;
296
297 fail:
298	free(matching);
299	free(opatterns);
300	free(list);
301	free(ret);
302	return r;
303}
304
305/* put algorithm proposal into buffer */
306int
307kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
308{
309	u_int i;
310	int r;
311
312	sshbuf_reset(b);
313
314	/*
315	 * add a dummy cookie, the cookie will be overwritten by
316	 * kex_send_kexinit(), each time a kexinit is set
317	 */
318	for (i = 0; i < KEX_COOKIE_LEN; i++) {
319		if ((r = sshbuf_put_u8(b, 0)) != 0)
320			return r;
321	}
322	for (i = 0; i < PROPOSAL_MAX; i++) {
323		if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
324			return r;
325	}
326	if ((r = sshbuf_put_u8(b, 0)) != 0 ||	/* first_kex_packet_follows */
327	    (r = sshbuf_put_u32(b, 0)) != 0)	/* uint32 reserved */
328		return r;
329	return 0;
330}
331
332/* parse buffer and return algorithm proposal */
333int
334kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
335{
336	struct sshbuf *b = NULL;
337	u_char v;
338	u_int i;
339	char **proposal = NULL;
340	int r;
341
342	*propp = NULL;
343	if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
344		return SSH_ERR_ALLOC_FAIL;
345	if ((b = sshbuf_fromb(raw)) == NULL) {
346		r = SSH_ERR_ALLOC_FAIL;
347		goto out;
348	}
349	if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
350		error_fr(r, "consume cookie");
351		goto out;
352	}
353	/* extract kex init proposal strings */
354	for (i = 0; i < PROPOSAL_MAX; i++) {
355		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {
356			error_fr(r, "parse proposal %u", i);
357			goto out;
358		}
359		debug2("%s: %s", proposal_names[i], proposal[i]);
360	}
361	/* first kex follows / reserved */
362	if ((r = sshbuf_get_u8(b, &v)) != 0 ||	/* first_kex_follows */
363	    (r = sshbuf_get_u32(b, &i)) != 0) {	/* reserved */
364		error_fr(r, "parse");
365		goto out;
366	}
367	if (first_kex_follows != NULL)
368		*first_kex_follows = v;
369	debug2("first_kex_follows %d ", v);
370	debug2("reserved %u ", i);
371	r = 0;
372	*propp = proposal;
373 out:
374	if (r != 0 && proposal != NULL)
375		kex_prop_free(proposal);
376	sshbuf_free(b);
377	return r;
378}
379
380void
381kex_prop_free(char **proposal)
382{
383	u_int i;
384
385	if (proposal == NULL)
386		return;
387	for (i = 0; i < PROPOSAL_MAX; i++)
388		free(proposal[i]);
389	free(proposal);
390}
391
392/* ARGSUSED */
393static int
394kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
395{
396	int r;
397
398	error("kex protocol error: type %d seq %u", type, seq);
399	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
400	    (r = sshpkt_put_u32(ssh, seq)) != 0 ||
401	    (r = sshpkt_send(ssh)) != 0)
402		return r;
403	return 0;
404}
405
406static void
407kex_reset_dispatch(struct ssh *ssh)
408{
409	ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
410	    SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
411}
412
413static int
414kex_send_ext_info(struct ssh *ssh)
415{
416	int r;
417	char *algs;
418
419	debug("Sending SSH2_MSG_EXT_INFO");
420	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
421		return SSH_ERR_ALLOC_FAIL;
422	/* XXX filter algs list by allowed pubkey/hostbased types */
423	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
424	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
425	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
426	    (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
427	    (r = sshpkt_send(ssh)) != 0) {
428		error_fr(r, "compose");
429		goto out;
430	}
431	/* success */
432	r = 0;
433 out:
434	free(algs);
435	return r;
436}
437
438int
439kex_send_newkeys(struct ssh *ssh)
440{
441	int r;
442
443	kex_reset_dispatch(ssh);
444	if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
445	    (r = sshpkt_send(ssh)) != 0)
446		return r;
447	debug("SSH2_MSG_NEWKEYS sent");
448	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
449	if (ssh->kex->ext_info_c && (ssh->kex->flags & KEX_INITIAL) != 0)
450		if ((r = kex_send_ext_info(ssh)) != 0)
451			return r;
452	debug("expecting SSH2_MSG_NEWKEYS");
453	return 0;
454}
455
456int
457kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
458{
459	struct kex *kex = ssh->kex;
460	u_int32_t i, ninfo;
461	char *name;
462	u_char *val;
463	size_t vlen;
464	int r;
465
466	debug("SSH2_MSG_EXT_INFO received");
467	ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
468	if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
469		return r;
470	for (i = 0; i < ninfo; i++) {
471		if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
472			return r;
473		if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) {
474			free(name);
475			return r;
476		}
477		if (strcmp(name, "server-sig-algs") == 0) {
478			/* Ensure no \0 lurking in value */
479			if (memchr(val, '\0', vlen) != NULL) {
480				error_f("nul byte in %s", name);
481				return SSH_ERR_INVALID_FORMAT;
482			}
483			debug_f("%s=<%s>", name, val);
484			kex->server_sig_algs = val;
485			val = NULL;
486		} else
487			debug_f("%s (unrecognised)", name);
488		free(name);
489		free(val);
490	}
491	return sshpkt_get_end(ssh);
492}
493
494static int
495kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
496{
497	struct kex *kex = ssh->kex;
498	int r;
499
500	debug("SSH2_MSG_NEWKEYS received");
501	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
502	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
503	if ((r = sshpkt_get_end(ssh)) != 0)
504		return r;
505	if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)
506		return r;
507	kex->done = 1;
508	kex->flags &= ~KEX_INITIAL;
509	sshbuf_reset(kex->peer);
510	/* sshbuf_reset(kex->my); */
511	kex->flags &= ~KEX_INIT_SENT;
512	free(kex->name);
513	kex->name = NULL;
514	return 0;
515}
516
517int
518kex_send_kexinit(struct ssh *ssh)
519{
520	u_char *cookie;
521	struct kex *kex = ssh->kex;
522	int r;
523
524	if (kex == NULL) {
525		error_f("no hex");
526		return SSH_ERR_INTERNAL_ERROR;
527	}
528	if (kex->flags & KEX_INIT_SENT)
529		return 0;
530	kex->done = 0;
531
532	/* generate a random cookie */
533	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
534		error_f("bad kex length: %zu < %d",
535		    sshbuf_len(kex->my), KEX_COOKIE_LEN);
536		return SSH_ERR_INVALID_FORMAT;
537	}
538	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) {
539		error_f("buffer error");
540		return SSH_ERR_INTERNAL_ERROR;
541	}
542	arc4random_buf(cookie, KEX_COOKIE_LEN);
543
544	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
545	    (r = sshpkt_putb(ssh, kex->my)) != 0 ||
546	    (r = sshpkt_send(ssh)) != 0) {
547		error_fr(r, "compose reply");
548		return r;
549	}
550	debug("SSH2_MSG_KEXINIT sent");
551	kex->flags |= KEX_INIT_SENT;
552	return 0;
553}
554
555/* ARGSUSED */
556int
557kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
558{
559	struct kex *kex = ssh->kex;
560	const u_char *ptr;
561	u_int i;
562	size_t dlen;
563	int r;
564
565	debug("SSH2_MSG_KEXINIT received");
566	if (kex == NULL) {
567		error_f("no hex");
568		return SSH_ERR_INTERNAL_ERROR;
569	}
570	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
571	ptr = sshpkt_ptr(ssh, &dlen);
572	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
573		return r;
574
575	/* discard packet */
576	for (i = 0; i < KEX_COOKIE_LEN; i++) {
577		if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
578			error_fr(r, "discard cookie");
579			return r;
580		}
581	}
582	for (i = 0; i < PROPOSAL_MAX; i++) {
583		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
584			error_fr(r, "discard proposal");
585			return r;
586		}
587	}
588	/*
589	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
590	 * KEX method has the server move first, but a server might be using
591	 * a custom method or one that we otherwise don't support. We should
592	 * be prepared to remember first_kex_follows here so we can eat a
593	 * packet later.
594	 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
595	 * for cases where the server *doesn't* go first. I guess we should
596	 * ignore it when it is set for these cases, which is what we do now.
597	 */
598	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||	/* first_kex_follows */
599	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||	/* reserved */
600	    (r = sshpkt_get_end(ssh)) != 0)
601			return r;
602
603	if (!(kex->flags & KEX_INIT_SENT))
604		if ((r = kex_send_kexinit(ssh)) != 0)
605			return r;
606	if ((r = kex_choose_conf(ssh)) != 0)
607		return r;
608
609	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
610		return (kex->kex[kex->kex_type])(ssh);
611
612	error_f("unknown kex type %u", kex->kex_type);
613	return SSH_ERR_INTERNAL_ERROR;
614}
615
616struct kex *
617kex_new(void)
618{
619	struct kex *kex;
620
621	if ((kex = calloc(1, sizeof(*kex))) == NULL ||
622	    (kex->peer = sshbuf_new()) == NULL ||
623	    (kex->my = sshbuf_new()) == NULL ||
624	    (kex->client_version = sshbuf_new()) == NULL ||
625	    (kex->server_version = sshbuf_new()) == NULL) {
626		kex_free(kex);
627		return NULL;
628	}
629	return kex;
630}
631
632void
633kex_free_newkeys(struct newkeys *newkeys)
634{
635	if (newkeys == NULL)
636		return;
637	if (newkeys->enc.key) {
638		explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
639		free(newkeys->enc.key);
640		newkeys->enc.key = NULL;
641	}
642	if (newkeys->enc.iv) {
643		explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);
644		free(newkeys->enc.iv);
645		newkeys->enc.iv = NULL;
646	}
647	free(newkeys->enc.name);
648	explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
649	free(newkeys->comp.name);
650	explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
651	mac_clear(&newkeys->mac);
652	if (newkeys->mac.key) {
653		explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
654		free(newkeys->mac.key);
655		newkeys->mac.key = NULL;
656	}
657	free(newkeys->mac.name);
658	explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
659	freezero(newkeys, sizeof(*newkeys));
660}
661
662void
663kex_free(struct kex *kex)
664{
665	u_int mode;
666
667	if (kex == NULL)
668		return;
669
670#ifdef WITH_OPENSSL
671	DH_free(kex->dh);
672	EC_KEY_free(kex->ec_client_key);
673#endif
674	for (mode = 0; mode < MODE_MAX; mode++) {
675		kex_free_newkeys(kex->newkeys[mode]);
676		kex->newkeys[mode] = NULL;
677	}
678	sshbuf_free(kex->peer);
679	sshbuf_free(kex->my);
680	sshbuf_free(kex->client_version);
681	sshbuf_free(kex->server_version);
682	sshbuf_free(kex->client_pub);
683	free(kex->session_id);
684	free(kex->failed_choice);
685	free(kex->hostkey_alg);
686	free(kex->name);
687	free(kex);
688}
689
690int
691kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
692{
693	int r;
694
695	if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0)
696		return r;
697	ssh->kex->flags = KEX_INITIAL;
698	kex_reset_dispatch(ssh);
699	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
700	return 0;
701}
702
703int
704kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
705{
706	int r;
707
708	if ((r = kex_ready(ssh, proposal)) != 0)
709		return r;
710	if ((r = kex_send_kexinit(ssh)) != 0) {		/* we start */
711		kex_free(ssh->kex);
712		ssh->kex = NULL;
713		return r;
714	}
715	return 0;
716}
717
718/*
719 * Request key re-exchange, returns 0 on success or a ssherr.h error
720 * code otherwise. Must not be called if KEX is incomplete or in-progress.
721 */
722int
723kex_start_rekex(struct ssh *ssh)
724{
725	if (ssh->kex == NULL) {
726		error_f("no kex");
727		return SSH_ERR_INTERNAL_ERROR;
728	}
729	if (ssh->kex->done == 0) {
730		error_f("requested twice");
731		return SSH_ERR_INTERNAL_ERROR;
732	}
733	ssh->kex->done = 0;
734	return kex_send_kexinit(ssh);
735}
736
737static int
738choose_enc(struct sshenc *enc, char *client, char *server)
739{
740	char *name = match_list(client, server, NULL);
741
742	if (name == NULL)
743		return SSH_ERR_NO_CIPHER_ALG_MATCH;
744	if ((enc->cipher = cipher_by_name(name)) == NULL) {
745		error_f("unsupported cipher %s", name);
746		free(name);
747		return SSH_ERR_INTERNAL_ERROR;
748	}
749	enc->name = name;
750	enc->enabled = 0;
751	enc->iv = NULL;
752	enc->iv_len = cipher_ivlen(enc->cipher);
753	enc->key = NULL;
754	enc->key_len = cipher_keylen(enc->cipher);
755	enc->block_size = cipher_blocksize(enc->cipher);
756	return 0;
757}
758
759static int
760choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
761{
762	char *name = match_list(client, server, NULL);
763
764	if (name == NULL)
765		return SSH_ERR_NO_MAC_ALG_MATCH;
766	if (mac_setup(mac, name) < 0) {
767		error_f("unsupported MAC %s", name);
768		free(name);
769		return SSH_ERR_INTERNAL_ERROR;
770	}
771	mac->name = name;
772	mac->key = NULL;
773	mac->enabled = 0;
774	return 0;
775}
776
777static int
778choose_comp(struct sshcomp *comp, char *client, char *server)
779{
780	char *name = match_list(client, server, NULL);
781
782	if (name == NULL)
783		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
784#ifdef WITH_ZLIB
785	if (strcmp(name, "zlib@openssh.com") == 0) {
786		comp->type = COMP_DELAYED;
787	} else if (strcmp(name, "zlib") == 0) {
788		comp->type = COMP_ZLIB;
789	} else
790#endif	/* WITH_ZLIB */
791	if (strcmp(name, "none") == 0) {
792		comp->type = COMP_NONE;
793	} else {
794		error_f("unsupported compression scheme %s", name);
795		free(name);
796		return SSH_ERR_INTERNAL_ERROR;
797	}
798	comp->name = name;
799	return 0;
800}
801
802static int
803choose_kex(struct kex *k, char *client, char *server)
804{
805	const struct kexalg *kexalg;
806
807	k->name = match_list(client, server, NULL);
808
809	debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
810	if (k->name == NULL)
811		return SSH_ERR_NO_KEX_ALG_MATCH;
812	if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
813		error_f("unsupported KEX method %s", k->name);
814		return SSH_ERR_INTERNAL_ERROR;
815	}
816	k->kex_type = kexalg->type;
817	k->hash_alg = kexalg->hash_alg;
818	k->ec_nid = kexalg->ec_nid;
819	return 0;
820}
821
822static int
823choose_hostkeyalg(struct kex *k, char *client, char *server)
824{
825	k->hostkey_alg = match_list(client, server, NULL);
826
827	debug("kex: host key algorithm: %s",
828	    k->hostkey_alg ? k->hostkey_alg : "(no match)");
829	if (k->hostkey_alg == NULL)
830		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
831	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
832	if (k->hostkey_type == KEY_UNSPEC) {
833		error_f("unsupported hostkey algorithm %s", k->hostkey_alg);
834		return SSH_ERR_INTERNAL_ERROR;
835	}
836	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
837	return 0;
838}
839
840static int
841proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
842{
843	static int check[] = {
844		PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
845	};
846	int *idx;
847	char *p;
848
849	for (idx = &check[0]; *idx != -1; idx++) {
850		if ((p = strchr(my[*idx], ',')) != NULL)
851			*p = '\0';
852		if ((p = strchr(peer[*idx], ',')) != NULL)
853			*p = '\0';
854		if (strcmp(my[*idx], peer[*idx]) != 0) {
855			debug2("proposal mismatch: my %s peer %s",
856			    my[*idx], peer[*idx]);
857			return (0);
858		}
859	}
860	debug2("proposals match");
861	return (1);
862}
863
864static int
865kex_choose_conf(struct ssh *ssh)
866{
867	struct kex *kex = ssh->kex;
868	struct newkeys *newkeys;
869	char **my = NULL, **peer = NULL;
870	char **cprop, **sprop;
871	int nenc, nmac, ncomp;
872	u_int mode, ctos, need, dh_need, authlen;
873	int r, first_kex_follows;
874
875	debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
876	if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
877		goto out;
878	debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
879	if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
880		goto out;
881
882	if (kex->server) {
883		cprop=peer;
884		sprop=my;
885	} else {
886		cprop=my;
887		sprop=peer;
888	}
889
890	/* Check whether client supports ext_info_c */
891	if (kex->server && (kex->flags & KEX_INITIAL)) {
892		char *ext;
893
894		ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
895		kex->ext_info_c = (ext != NULL);
896		free(ext);
897	}
898
899	/* Algorithm Negotiation */
900	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
901	    sprop[PROPOSAL_KEX_ALGS])) != 0) {
902		kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
903		peer[PROPOSAL_KEX_ALGS] = NULL;
904		goto out;
905	}
906	if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
907	    sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
908		kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
909		peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
910		goto out;
911	}
912	for (mode = 0; mode < MODE_MAX; mode++) {
913		if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
914			r = SSH_ERR_ALLOC_FAIL;
915			goto out;
916		}
917		kex->newkeys[mode] = newkeys;
918		ctos = (!kex->server && mode == MODE_OUT) ||
919		    (kex->server && mode == MODE_IN);
920		nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
921		nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
922		ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
923		if ((r = choose_enc(&newkeys->enc, cprop[nenc],
924		    sprop[nenc])) != 0) {
925			kex->failed_choice = peer[nenc];
926			peer[nenc] = NULL;
927			goto out;
928		}
929		authlen = cipher_authlen(newkeys->enc.cipher);
930		/* ignore mac for authenticated encryption */
931		if (authlen == 0 &&
932		    (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
933		    sprop[nmac])) != 0) {
934			kex->failed_choice = peer[nmac];
935			peer[nmac] = NULL;
936			goto out;
937		}
938		if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
939		    sprop[ncomp])) != 0) {
940			kex->failed_choice = peer[ncomp];
941			peer[ncomp] = NULL;
942			goto out;
943		}
944		debug("kex: %s cipher: %s MAC: %s compression: %s",
945		    ctos ? "client->server" : "server->client",
946		    newkeys->enc.name,
947		    authlen == 0 ? newkeys->mac.name : "<implicit>",
948		    newkeys->comp.name);
949	}
950	need = dh_need = 0;
951	for (mode = 0; mode < MODE_MAX; mode++) {
952		newkeys = kex->newkeys[mode];
953		need = MAXIMUM(need, newkeys->enc.key_len);
954		need = MAXIMUM(need, newkeys->enc.block_size);
955		need = MAXIMUM(need, newkeys->enc.iv_len);
956		need = MAXIMUM(need, newkeys->mac.key_len);
957		dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher));
958		dh_need = MAXIMUM(dh_need, newkeys->enc.block_size);
959		dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len);
960		dh_need = MAXIMUM(dh_need, newkeys->mac.key_len);
961	}
962	/* XXX need runden? */
963	kex->we_need = need;
964	kex->dh_need = dh_need;
965
966	/* ignore the next message if the proposals do not match */
967	if (first_kex_follows && !proposals_match(my, peer))
968		ssh->dispatch_skip_packets = 1;
969	r = 0;
970 out:
971	kex_prop_free(my);
972	kex_prop_free(peer);
973	return r;
974}
975
976static int
977derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
978    const struct sshbuf *shared_secret, u_char **keyp)
979{
980	struct kex *kex = ssh->kex;
981	struct ssh_digest_ctx *hashctx = NULL;
982	char c = id;
983	u_int have;
984	size_t mdsz;
985	u_char *digest;
986	int r;
987
988	if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
989		return SSH_ERR_INVALID_ARGUMENT;
990	if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) {
991		r = SSH_ERR_ALLOC_FAIL;
992		goto out;
993	}
994
995	/* K1 = HASH(K || H || "A" || session_id) */
996	if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
997	    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
998	    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
999	    ssh_digest_update(hashctx, &c, 1) != 0 ||
1000	    ssh_digest_update(hashctx, kex->session_id,
1001	    kex->session_id_len) != 0 ||
1002	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
1003		r = SSH_ERR_LIBCRYPTO_ERROR;
1004		error_f("KEX hash failed");
1005		goto out;
1006	}
1007	ssh_digest_free(hashctx);
1008	hashctx = NULL;
1009
1010	/*
1011	 * expand key:
1012	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
1013	 * Key = K1 || K2 || ... || Kn
1014	 */
1015	for (have = mdsz; need > have; have += mdsz) {
1016		if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
1017		    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
1018		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
1019		    ssh_digest_update(hashctx, digest, have) != 0 ||
1020		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
1021			error_f("KDF failed");
1022			r = SSH_ERR_LIBCRYPTO_ERROR;
1023			goto out;
1024		}
1025		ssh_digest_free(hashctx);
1026		hashctx = NULL;
1027	}
1028#ifdef DEBUG_KEX
1029	fprintf(stderr, "key '%c'== ", c);
1030	dump_digest("key", digest, need);
1031#endif
1032	*keyp = digest;
1033	digest = NULL;
1034	r = 0;
1035 out:
1036	free(digest);
1037	ssh_digest_free(hashctx);
1038	return r;
1039}
1040
1041#define NKEYS	6
1042int
1043kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
1044    const struct sshbuf *shared_secret)
1045{
1046	struct kex *kex = ssh->kex;
1047	u_char *keys[NKEYS];
1048	u_int i, j, mode, ctos;
1049	int r;
1050
1051	/* save initial hash as session id */
1052	if (kex->session_id == NULL) {
1053		kex->session_id_len = hashlen;
1054		kex->session_id = malloc(kex->session_id_len);
1055		if (kex->session_id == NULL)
1056			return SSH_ERR_ALLOC_FAIL;
1057		memcpy(kex->session_id, hash, kex->session_id_len);
1058	}
1059	for (i = 0; i < NKEYS; i++) {
1060		if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
1061		    shared_secret, &keys[i])) != 0) {
1062			for (j = 0; j < i; j++)
1063				free(keys[j]);
1064			return r;
1065		}
1066	}
1067	for (mode = 0; mode < MODE_MAX; mode++) {
1068		ctos = (!kex->server && mode == MODE_OUT) ||
1069		    (kex->server && mode == MODE_IN);
1070		kex->newkeys[mode]->enc.iv  = keys[ctos ? 0 : 1];
1071		kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
1072		kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
1073	}
1074	return 0;
1075}
1076
1077int
1078kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp)
1079{
1080	struct kex *kex = ssh->kex;
1081
1082	*pubp = NULL;
1083	*prvp = NULL;
1084	if (kex->load_host_public_key == NULL ||
1085	    kex->load_host_private_key == NULL) {
1086		error_f("missing hostkey loader");
1087		return SSH_ERR_INVALID_ARGUMENT;
1088	}
1089	*pubp = kex->load_host_public_key(kex->hostkey_type,
1090	    kex->hostkey_nid, ssh);
1091	*prvp = kex->load_host_private_key(kex->hostkey_type,
1092	    kex->hostkey_nid, ssh);
1093	if (*pubp == NULL)
1094		return SSH_ERR_NO_HOSTKEY_LOADED;
1095	return 0;
1096}
1097
1098int
1099kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key)
1100{
1101	struct kex *kex = ssh->kex;
1102
1103	if (kex->verify_host_key == NULL) {
1104		error_f("missing hostkey verifier");
1105		return SSH_ERR_INVALID_ARGUMENT;
1106	}
1107	if (server_host_key->type != kex->hostkey_type ||
1108	    (kex->hostkey_type == KEY_ECDSA &&
1109	    server_host_key->ecdsa_nid != kex->hostkey_nid))
1110		return SSH_ERR_KEY_TYPE_MISMATCH;
1111	if (kex->verify_host_key(server_host_key, ssh) == -1)
1112		return  SSH_ERR_SIGNATURE_INVALID;
1113	return 0;
1114}
1115
1116#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
1117void
1118dump_digest(const char *msg, const u_char *digest, int len)
1119{
1120	fprintf(stderr, "%s\n", msg);
1121	sshbuf_dump_data(digest, len, stderr);
1122}
1123#endif
1124
1125/*
1126 * Send a plaintext error message to the peer, suffixed by \r\n.
1127 * Only used during banner exchange, and there only for the server.
1128 */
1129static void
1130send_error(struct ssh *ssh, char *msg)
1131{
1132	char *crnl = "\r\n";
1133
1134	if (!ssh->kex->server)
1135		return;
1136
1137	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1138	    msg, strlen(msg)) != strlen(msg) ||
1139	    atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1140	    crnl, strlen(crnl)) != strlen(crnl))
1141		error_f("write: %.100s", strerror(errno));
1142}
1143
1144/*
1145 * Sends our identification string and waits for the peer's. Will block for
1146 * up to timeout_ms (or indefinitely if timeout_ms <= 0).
1147 * Returns on 0 success or a ssherr.h code on failure.
1148 */
1149int
1150kex_exchange_identification(struct ssh *ssh, int timeout_ms,
1151    const char *version_addendum)
1152{
1153	int remote_major, remote_minor, mismatch, oerrno = 0;
1154	size_t len, i, n;
1155	int r, expect_nl;
1156	u_char c;
1157	struct sshbuf *our_version = ssh->kex->server ?
1158	    ssh->kex->server_version : ssh->kex->client_version;
1159	struct sshbuf *peer_version = ssh->kex->server ?
1160	    ssh->kex->client_version : ssh->kex->server_version;
1161	char *our_version_string = NULL, *peer_version_string = NULL;
1162	char *cp, *remote_version = NULL;
1163
1164	/* Prepare and send our banner */
1165	sshbuf_reset(our_version);
1166	if (version_addendum != NULL && *version_addendum == '\0')
1167		version_addendum = NULL;
1168	if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n",
1169	   PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
1170	    version_addendum == NULL ? "" : " ",
1171	    version_addendum == NULL ? "" : version_addendum)) != 0) {
1172		oerrno = errno;
1173		error_fr(r, "sshbuf_putf");
1174		goto out;
1175	}
1176
1177	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1178	    sshbuf_mutable_ptr(our_version),
1179	    sshbuf_len(our_version)) != sshbuf_len(our_version)) {
1180		oerrno = errno;
1181		debug_f("write: %.100s", strerror(errno));
1182		r = SSH_ERR_SYSTEM_ERROR;
1183		goto out;
1184	}
1185	if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */
1186		oerrno = errno;
1187		error_fr(r, "sshbuf_consume_end");
1188		goto out;
1189	}
1190	our_version_string = sshbuf_dup_string(our_version);
1191	if (our_version_string == NULL) {
1192		error_f("sshbuf_dup_string failed");
1193		r = SSH_ERR_ALLOC_FAIL;
1194		goto out;
1195	}
1196	debug("Local version string %.100s", our_version_string);
1197
1198	/* Read other side's version identification. */
1199	for (n = 0; ; n++) {
1200		if (n >= SSH_MAX_PRE_BANNER_LINES) {
1201			send_error(ssh, "No SSH identification string "
1202			    "received.");
1203			error_f("No SSH version received in first %u lines "
1204			    "from server", SSH_MAX_PRE_BANNER_LINES);
1205			r = SSH_ERR_INVALID_FORMAT;
1206			goto out;
1207		}
1208		sshbuf_reset(peer_version);
1209		expect_nl = 0;
1210		for (i = 0; ; i++) {
1211			if (timeout_ms > 0) {
1212				r = waitrfd(ssh_packet_get_connection_in(ssh),
1213				    &timeout_ms);
1214				if (r == -1 && errno == ETIMEDOUT) {
1215					send_error(ssh, "Timed out waiting "
1216					    "for SSH identification string.");
1217					error("Connection timed out during "
1218					    "banner exchange");
1219					r = SSH_ERR_CONN_TIMEOUT;
1220					goto out;
1221				} else if (r == -1) {
1222					oerrno = errno;
1223					error_f("%s", strerror(errno));
1224					r = SSH_ERR_SYSTEM_ERROR;
1225					goto out;
1226				}
1227			}
1228
1229			len = atomicio(read, ssh_packet_get_connection_in(ssh),
1230			    &c, 1);
1231			if (len != 1 && errno == EPIPE) {
1232				error_f("Connection closed by remote host");
1233				r = SSH_ERR_CONN_CLOSED;
1234				goto out;
1235			} else if (len != 1) {
1236				oerrno = errno;
1237				error_f("read: %.100s", strerror(errno));
1238				r = SSH_ERR_SYSTEM_ERROR;
1239				goto out;
1240			}
1241			if (c == '\r') {
1242				expect_nl = 1;
1243				continue;
1244			}
1245			if (c == '\n')
1246				break;
1247			if (c == '\0' || expect_nl) {
1248				error_f("banner line contains invalid "
1249				    "characters");
1250				goto invalid;
1251			}
1252			if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
1253				oerrno = errno;
1254				error_fr(r, "sshbuf_put");
1255				goto out;
1256			}
1257			if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
1258				error_f("banner line too long");
1259				goto invalid;
1260			}
1261		}
1262		/* Is this an actual protocol banner? */
1263		if (sshbuf_len(peer_version) > 4 &&
1264		    memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0)
1265			break;
1266		/* If not, then just log the line and continue */
1267		if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
1268			error_f("sshbuf_dup_string failed");
1269			r = SSH_ERR_ALLOC_FAIL;
1270			goto out;
1271		}
1272		/* Do not accept lines before the SSH ident from a client */
1273		if (ssh->kex->server) {
1274			error_f("client sent invalid protocol identifier "
1275			    "\"%.256s\"", cp);
1276			free(cp);
1277			goto invalid;
1278		}
1279		debug_f("banner line %zu: %s", n, cp);
1280		free(cp);
1281	}
1282	peer_version_string = sshbuf_dup_string(peer_version);
1283	if (peer_version_string == NULL)
1284		error_f("sshbuf_dup_string failed");
1285	/* XXX must be same size for sscanf */
1286	if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
1287		error_f("calloc failed");
1288		r = SSH_ERR_ALLOC_FAIL;
1289		goto out;
1290	}
1291
1292	/*
1293	 * Check that the versions match.  In future this might accept
1294	 * several versions and set appropriate flags to handle them.
1295	 */
1296	if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n",
1297	    &remote_major, &remote_minor, remote_version) != 3) {
1298		error("Bad remote protocol version identification: '%.100s'",
1299		    peer_version_string);
1300 invalid:
1301		send_error(ssh, "Invalid SSH identification string.");
1302		r = SSH_ERR_INVALID_FORMAT;
1303		goto out;
1304	}
1305	debug("Remote protocol version %d.%d, remote software version %.100s",
1306	    remote_major, remote_minor, remote_version);
1307	ssh->compat = compat_datafellows(remote_version);
1308
1309	mismatch = 0;
1310	switch (remote_major) {
1311	case 2:
1312		break;
1313	case 1:
1314		if (remote_minor != 99)
1315			mismatch = 1;
1316		break;
1317	default:
1318		mismatch = 1;
1319		break;
1320	}
1321	if (mismatch) {
1322		error("Protocol major versions differ: %d vs. %d",
1323		    PROTOCOL_MAJOR_2, remote_major);
1324		send_error(ssh, "Protocol major versions differ.");
1325		r = SSH_ERR_NO_PROTOCOL_VERSION;
1326		goto out;
1327	}
1328
1329	if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) {
1330		logit("probed from %s port %d with %s.  Don't panic.",
1331		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1332		    peer_version_string);
1333		r = SSH_ERR_CONN_CLOSED; /* XXX */
1334		goto out;
1335	}
1336	if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) {
1337		logit("scanned from %s port %d with %s.  Don't panic.",
1338		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1339		    peer_version_string);
1340		r = SSH_ERR_CONN_CLOSED; /* XXX */
1341		goto out;
1342	}
1343	if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
1344		logit("Remote version \"%.100s\" uses unsafe RSA signature "
1345		    "scheme; disabling use of RSA keys", remote_version);
1346	}
1347	/* success */
1348	r = 0;
1349 out:
1350	free(our_version_string);
1351	free(peer_version_string);
1352	free(remote_version);
1353	if (r == SSH_ERR_SYSTEM_ERROR)
1354		errno = oerrno;
1355	return r;
1356}
1357
1358