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