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