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