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