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