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