1 /* $OpenBSD: sshd-auth.c,v 1.3 2025/01/16 06:37:10 dtucker Exp $ */ 2 /* 3 * SSH2 implementation: 4 * Privilege Separation: 5 * 6 * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. 7 * Copyright (c) 2002 Niels Provos. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "includes.h" 31 32 #include <sys/types.h> 33 #include <sys/ioctl.h> 34 #include <sys/wait.h> 35 #include <sys/stat.h> 36 #include <sys/socket.h> 37 #include <sys/time.h> 38 39 #include "openbsd-compat/sys-tree.h" 40 #include "openbsd-compat/sys-queue.h" 41 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <netdb.h> 45 #ifdef HAVE_PATHS_H 46 # include <paths.h> 47 #endif 48 #include <pwd.h> 49 #include <grp.h> 50 #include <signal.h> 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include <stdarg.h> 55 #include <unistd.h> 56 #include <limits.h> 57 58 #ifdef WITH_OPENSSL 59 #include <openssl/bn.h> 60 #include <openssl/evp.h> 61 #endif 62 63 #include "xmalloc.h" 64 #include "ssh.h" 65 #include "ssh2.h" 66 #include "sshpty.h" 67 #include "packet.h" 68 #include "log.h" 69 #include "sshbuf.h" 70 #include "misc.h" 71 #include "match.h" 72 #include "servconf.h" 73 #include "uidswap.h" 74 #include "compat.h" 75 #include "cipher.h" 76 #include "digest.h" 77 #include "sshkey.h" 78 #include "kex.h" 79 #include "authfile.h" 80 #include "pathnames.h" 81 #include "atomicio.h" 82 #include "canohost.h" 83 #include "hostfile.h" 84 #include "auth.h" 85 #include "authfd.h" 86 #include "msg.h" 87 #include "dispatch.h" 88 #include "channels.h" 89 #include "session.h" 90 #include "monitor.h" 91 #ifdef GSSAPI 92 #include "ssh-gss.h" 93 #endif 94 #include "monitor_wrap.h" 95 #include "auth-options.h" 96 #include "version.h" 97 #include "ssherr.h" 98 #include "sk-api.h" 99 #include "srclimit.h" 100 #include "ssh-sandbox.h" 101 #include "dh.h" 102 103 /* Privsep fds */ 104 #define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) 105 #define PRIVSEP_LOG_FD (STDERR_FILENO + 2) 106 #define PRIVSEP_MIN_FREE_FD (STDERR_FILENO + 3) 107 108 extern char *__progname; 109 110 /* Server configuration options. */ 111 ServerOptions options; 112 113 /* Name of the server configuration file. */ 114 char *config_file_name = _PATH_SERVER_CONFIG_FILE; 115 116 /* 117 * Debug mode flag. This can be set on the command line. If debug 118 * mode is enabled, extra debugging output will be sent to the system 119 * log, the daemon will not go to background, and will exit after processing 120 * the first connection. 121 */ 122 int debug_flag = 0; 123 124 /* Flag indicating that the daemon is being started from inetd. */ 125 static int inetd_flag = 0; 126 127 /* Saved arguments to main(). */ 128 static char **saved_argv; 129 static int saved_argc; 130 131 132 /* Daemon's agent connection */ 133 int auth_sock = -1; 134 static int have_agent = 0; 135 136 u_int num_hostkeys; 137 struct sshkey **host_pubkeys; /* all public host keys */ 138 struct sshkey **host_certificates; /* all public host certificates */ 139 140 /* record remote hostname or ip */ 141 u_int utmp_len = HOST_NAME_MAX+1; 142 143 /* variables used for privilege separation */ 144 struct monitor *pmonitor = NULL; 145 int privsep_is_preauth = 1; 146 static int privsep_chroot = 1; 147 148 /* global connection state and authentication contexts */ 149 Authctxt *the_authctxt = NULL; 150 struct ssh *the_active_state; 151 152 /* global key/cert auth options. XXX move to permanent ssh->authctxt? */ 153 struct sshauthopt *auth_opts = NULL; 154 155 /* sshd_config buffer */ 156 struct sshbuf *cfg; 157 158 /* Included files from the configuration file */ 159 struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); 160 161 /* message to be displayed after login */ 162 struct sshbuf *loginmsg; 163 164 /* Prototypes for various functions defined later in this file. */ 165 static void do_ssh2_kex(struct ssh *); 166 167 /* Unprivileged user */ 168 struct passwd *privsep_pw = NULL; 169 170 #ifndef HAVE_PLEDGE 171 static struct ssh_sandbox *box; 172 #endif 173 174 /* XXX stub */ 175 int 176 mm_is_monitor(void) 177 { 178 return 0; 179 } 180 181 static void 182 privsep_child_demote(void) 183 { 184 gid_t gidset[1]; 185 186 #ifndef HAVE_PLEDGE 187 if ((box = ssh_sandbox_init(pmonitor)) == NULL) 188 fatal_f("ssh_sandbox_init failed"); 189 #endif 190 /* Demote the child */ 191 if (privsep_chroot) { 192 /* Change our root directory */ 193 if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) 194 fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, 195 strerror(errno)); 196 if (chdir("/") == -1) 197 fatal("chdir(\"/\"): %s", strerror(errno)); 198 199 /* 200 * Drop our privileges 201 * NB. Can't use setusercontext() after chroot. 202 */ 203 debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, 204 (u_int)privsep_pw->pw_gid); 205 gidset[0] = privsep_pw->pw_gid; 206 if (setgroups(1, gidset) == -1) 207 fatal("setgroups: %.100s", strerror(errno)); 208 permanently_set_uid(privsep_pw); 209 } 210 211 /* sandbox ourselves */ 212 #ifdef HAVE_PLEDGE 213 if (pledge("stdio", NULL) == -1) 214 fatal_f("pledge()"); 215 #else 216 ssh_sandbox_child(box); 217 #endif 218 } 219 220 static void 221 append_hostkey_type(struct sshbuf *b, const char *s) 222 { 223 int r; 224 225 if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { 226 debug3_f("%s key not permitted by HostkeyAlgorithms", s); 227 return; 228 } 229 if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) 230 fatal_fr(r, "sshbuf_putf"); 231 } 232 233 static char * 234 list_hostkey_types(void) 235 { 236 struct sshbuf *b; 237 struct sshkey *key; 238 char *ret; 239 u_int i; 240 241 if ((b = sshbuf_new()) == NULL) 242 fatal_f("sshbuf_new failed"); 243 for (i = 0; i < options.num_host_key_files; i++) { 244 key = host_pubkeys[i]; 245 if (key == NULL) 246 continue; 247 switch (key->type) { 248 case KEY_RSA: 249 /* for RSA we also support SHA2 signatures */ 250 append_hostkey_type(b, "rsa-sha2-512"); 251 append_hostkey_type(b, "rsa-sha2-256"); 252 /* FALLTHROUGH */ 253 case KEY_DSA: 254 case KEY_ECDSA: 255 case KEY_ED25519: 256 case KEY_ECDSA_SK: 257 case KEY_ED25519_SK: 258 case KEY_XMSS: 259 append_hostkey_type(b, sshkey_ssh_name(key)); 260 break; 261 } 262 /* If the private key has a cert peer, then list that too */ 263 key = host_certificates[i]; 264 if (key == NULL) 265 continue; 266 switch (key->type) { 267 case KEY_RSA_CERT: 268 /* for RSA we also support SHA2 signatures */ 269 append_hostkey_type(b, 270 "rsa-sha2-512-cert-v01@openssh.com"); 271 append_hostkey_type(b, 272 "rsa-sha2-256-cert-v01@openssh.com"); 273 /* FALLTHROUGH */ 274 case KEY_DSA_CERT: 275 case KEY_ECDSA_CERT: 276 case KEY_ED25519_CERT: 277 case KEY_ECDSA_SK_CERT: 278 case KEY_ED25519_SK_CERT: 279 case KEY_XMSS_CERT: 280 append_hostkey_type(b, sshkey_ssh_name(key)); 281 break; 282 } 283 } 284 if ((ret = sshbuf_dup_string(b)) == NULL) 285 fatal_f("sshbuf_dup_string failed"); 286 sshbuf_free(b); 287 debug_f("%s", ret); 288 return ret; 289 } 290 291 struct sshkey * 292 get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) 293 { 294 u_int i; 295 struct sshkey *key; 296 297 for (i = 0; i < options.num_host_key_files; i++) { 298 switch (type) { 299 case KEY_RSA_CERT: 300 case KEY_DSA_CERT: 301 case KEY_ECDSA_CERT: 302 case KEY_ED25519_CERT: 303 case KEY_ECDSA_SK_CERT: 304 case KEY_ED25519_SK_CERT: 305 case KEY_XMSS_CERT: 306 key = host_certificates[i]; 307 break; 308 default: 309 key = host_pubkeys[i]; 310 break; 311 } 312 if (key == NULL || key->type != type) 313 continue; 314 switch (type) { 315 case KEY_ECDSA: 316 case KEY_ECDSA_SK: 317 case KEY_ECDSA_CERT: 318 case KEY_ECDSA_SK_CERT: 319 if (key->ecdsa_nid != nid) 320 continue; 321 /* FALLTHROUGH */ 322 default: 323 return key; 324 } 325 } 326 return NULL; 327 } 328 329 /* XXX remove */ 330 struct sshkey * 331 get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) 332 { 333 return NULL; 334 } 335 336 /* XXX remove */ 337 struct sshkey * 338 get_hostkey_by_index(int ind) 339 { 340 return NULL; 341 } 342 343 struct sshkey * 344 get_hostkey_public_by_index(int ind, struct ssh *ssh) 345 { 346 if (ind < 0 || (u_int)ind >= options.num_host_key_files) 347 return (NULL); 348 return host_pubkeys[ind]; 349 } 350 351 int 352 get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) 353 { 354 u_int i; 355 356 for (i = 0; i < options.num_host_key_files; i++) { 357 if (sshkey_is_cert(key)) { 358 if (key == host_certificates[i] || 359 (compare && host_certificates[i] && 360 sshkey_equal(key, host_certificates[i]))) 361 return (i); 362 } else { 363 if (key == host_pubkeys[i] || 364 (compare && host_pubkeys[i] && 365 sshkey_equal(key, host_pubkeys[i]))) 366 return (i); 367 } 368 } 369 return (-1); 370 } 371 372 static void 373 usage(void) 374 { 375 fprintf(stderr, "%s, %s\n", SSH_VERSION, SSH_OPENSSL_VERSION); 376 fprintf(stderr, 377 "usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n" 378 " [-E log_file] [-f config_file] [-g login_grace_time]\n" 379 " [-h host_key_file] [-o option] [-p port] [-u len]\n" 380 ); 381 exit(1); 382 } 383 384 static void 385 parse_hostkeys(struct sshbuf *hostkeys) 386 { 387 int r; 388 u_int num_keys = 0; 389 struct sshkey *k; 390 const u_char *cp; 391 size_t len; 392 393 while (sshbuf_len(hostkeys) != 0) { 394 if (num_keys > 2048) 395 fatal_f("too many hostkeys"); 396 host_pubkeys = xrecallocarray(host_pubkeys, 397 num_keys, num_keys + 1, sizeof(*host_pubkeys)); 398 host_certificates = xrecallocarray(host_certificates, 399 num_keys, num_keys + 1, sizeof(*host_certificates)); 400 /* public key */ 401 k = NULL; 402 if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) 403 fatal_fr(r, "extract pubkey"); 404 if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) 405 fatal_fr(r, "parse pubkey"); 406 host_pubkeys[num_keys] = k; 407 if (k) 408 debug2_f("key %u: %s", num_keys, sshkey_ssh_name(k)); 409 /* certificate */ 410 k = NULL; 411 if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) 412 fatal_fr(r, "extract pubkey"); 413 if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) 414 fatal_fr(r, "parse pubkey"); 415 host_certificates[num_keys] = k; 416 if (k) 417 debug2_f("cert %u: %s", num_keys, sshkey_ssh_name(k)); 418 num_keys++; 419 } 420 num_hostkeys = num_keys; 421 } 422 423 static void 424 recv_privsep_state(struct ssh *ssh, struct sshbuf *conf, 425 uint64_t *timing_secretp) 426 { 427 struct sshbuf *hostkeys; 428 429 debug3_f("begin"); 430 431 mm_get_state(ssh, &includes, conf, NULL, timing_secretp, 432 &hostkeys, NULL, NULL, NULL, NULL); 433 parse_hostkeys(hostkeys); 434 435 sshbuf_free(hostkeys); 436 437 debug3_f("done"); 438 } 439 440 /* 441 * Main program for the daemon. 442 */ 443 int 444 main(int ac, char **av) 445 { 446 struct ssh *ssh = NULL; 447 extern char *optarg; 448 extern int optind; 449 int r, opt, have_key = 0; 450 int sock_in = -1, sock_out = -1, rexeced_flag = 0; 451 char *line, *logfile = NULL; 452 u_int i; 453 mode_t new_umask; 454 Authctxt *authctxt; 455 struct connection_info *connection_info = NULL; 456 sigset_t sigmask; 457 uint64_t timing_secret = 0; 458 459 closefrom(PRIVSEP_MIN_FREE_FD); 460 sigemptyset(&sigmask); 461 sigprocmask(SIG_SETMASK, &sigmask, NULL); 462 463 #ifdef HAVE_SECUREWARE 464 (void)set_auth_parameters(ac, av); 465 #endif 466 __progname = ssh_get_progname(av[0]); 467 468 /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ 469 saved_argc = ac; 470 saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); 471 for (i = 0; (int)i < ac; i++) 472 saved_argv[i] = xstrdup(av[i]); 473 saved_argv[i] = NULL; 474 475 seed_rng(); 476 477 #ifndef HAVE_SETPROCTITLE 478 /* Prepare for later setproctitle emulation */ 479 compat_init_setproctitle(ac, av); 480 av = saved_argv; 481 #endif 482 483 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 484 sanitise_stdfd(); 485 486 /* Initialize configuration options to their default values. */ 487 initialize_server_options(&options); 488 489 /* Parse command-line arguments. */ 490 while ((opt = getopt(ac, av, 491 "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { 492 switch (opt) { 493 case '4': 494 options.address_family = AF_INET; 495 break; 496 case '6': 497 options.address_family = AF_INET6; 498 break; 499 case 'f': 500 config_file_name = optarg; 501 break; 502 case 'c': 503 servconf_add_hostcert("[command-line]", 0, 504 &options, optarg); 505 break; 506 case 'd': 507 if (debug_flag == 0) { 508 debug_flag = 1; 509 options.log_level = SYSLOG_LEVEL_DEBUG1; 510 } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) 511 options.log_level++; 512 break; 513 case 'D': 514 /* ignore */ 515 break; 516 case 'E': 517 logfile = optarg; 518 /* FALLTHROUGH */ 519 case 'e': 520 /* ignore */ 521 break; 522 case 'i': 523 inetd_flag = 1; 524 break; 525 case 'r': 526 /* ignore */ 527 break; 528 case 'R': 529 rexeced_flag = 1; 530 break; 531 case 'Q': 532 /* ignored */ 533 break; 534 case 'q': 535 options.log_level = SYSLOG_LEVEL_QUIET; 536 break; 537 case 'b': 538 /* protocol 1, ignored */ 539 break; 540 case 'p': 541 options.ports_from_cmdline = 1; 542 if (options.num_ports >= MAX_PORTS) { 543 fprintf(stderr, "too many ports.\n"); 544 exit(1); 545 } 546 options.ports[options.num_ports++] = a2port(optarg); 547 if (options.ports[options.num_ports-1] <= 0) { 548 fprintf(stderr, "Bad port number.\n"); 549 exit(1); 550 } 551 break; 552 case 'g': 553 if ((options.login_grace_time = convtime(optarg)) == -1) { 554 fprintf(stderr, "Invalid login grace time.\n"); 555 exit(1); 556 } 557 break; 558 case 'k': 559 /* protocol 1, ignored */ 560 break; 561 case 'h': 562 servconf_add_hostkey("[command-line]", 0, 563 &options, optarg, 1); 564 break; 565 case 't': 566 case 'T': 567 case 'G': 568 fatal("test/dump modes not supported"); 569 break; 570 case 'C': 571 connection_info = server_get_connection_info(ssh, 0, 0); 572 if (parse_server_match_testspec(connection_info, 573 optarg) == -1) 574 exit(1); 575 break; 576 case 'u': 577 utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); 578 if (utmp_len > HOST_NAME_MAX+1) { 579 fprintf(stderr, "Invalid utmp length.\n"); 580 exit(1); 581 } 582 break; 583 case 'o': 584 line = xstrdup(optarg); 585 if (process_server_config_line(&options, line, 586 "command-line", 0, NULL, NULL, &includes) != 0) 587 exit(1); 588 free(line); 589 break; 590 case 'V': 591 fprintf(stderr, "%s, %s\n", 592 SSH_VERSION, SSH_OPENSSL_VERSION); 593 exit(0); 594 default: 595 usage(); 596 break; 597 } 598 } 599 600 if (!rexeced_flag) 601 fatal("sshd-auth should not be executed directly"); 602 603 #ifdef WITH_OPENSSL 604 OpenSSL_add_all_algorithms(); 605 #endif 606 607 /* If requested, redirect the logs to the specified logfile. */ 608 if (logfile != NULL) { 609 char *cp, pid_s[32]; 610 611 snprintf(pid_s, sizeof(pid_s), "%ld", (unsigned long)getpid()); 612 cp = percent_expand(logfile, 613 "p", pid_s, 614 "P", "sshd-auth", 615 (char *)NULL); 616 log_redirect_stderr_to(cp); 617 free(cp); 618 } 619 620 log_init(__progname, 621 options.log_level == SYSLOG_LEVEL_NOT_SET ? 622 SYSLOG_LEVEL_INFO : options.log_level, 623 options.log_facility == SYSLOG_FACILITY_NOT_SET ? 624 SYSLOG_FACILITY_AUTH : options.log_facility, 1); 625 626 /* XXX can't use monitor_init(); it makes fds */ 627 pmonitor = xcalloc(1, sizeof(*pmonitor)); 628 pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; 629 pmonitor->m_recvfd = PRIVSEP_MONITOR_FD; 630 pmonitor->m_log_sendfd = PRIVSEP_LOG_FD; 631 set_log_handler(mm_log_handler, pmonitor); 632 633 /* Check that there are no remaining arguments. */ 634 if (optind < ac) { 635 fprintf(stderr, "Extra argument %s.\n", av[optind]); 636 exit(1); 637 } 638 639 /* Connection passed by stdin/out */ 640 if (inetd_flag) { 641 /* 642 * NB. must be different fd numbers for the !socket case, 643 * as packet_connection_is_on_socket() depends on this. 644 */ 645 sock_in = dup(STDIN_FILENO); 646 sock_out = dup(STDOUT_FILENO); 647 } else { 648 /* rexec case; accept()ed socket in ancestor listener */ 649 sock_in = sock_out = dup(STDIN_FILENO); 650 } 651 652 if (stdfd_devnull(1, 1, 0) == -1) 653 error("stdfd_devnull failed"); 654 debug("network sockets: %d, %d", sock_in, sock_out); 655 656 /* 657 * Register our connection. This turns encryption off because we do 658 * not have a key. 659 */ 660 if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL) 661 fatal("Unable to create connection"); 662 the_active_state = ssh; 663 ssh_packet_set_server(ssh); 664 pmonitor->m_pkex = &ssh->kex; 665 666 /* Fetch our configuration */ 667 if ((cfg = sshbuf_new()) == NULL) 668 fatal("sshbuf_new config buf failed"); 669 setproctitle("%s", "[session-auth early]"); 670 recv_privsep_state(ssh, cfg, &timing_secret); 671 parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); 672 /* Fill in default values for those options not explicitly set. */ 673 fill_default_server_options(&options); 674 options.timing_secret = timing_secret; /* XXX eliminate from unpriv */ 675 676 /* Reinit logging in case config set Level, Facility or Verbose. */ 677 log_init(__progname, options.log_level, options.log_facility, 1); 678 679 debug("sshd-auth version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); 680 681 /* Store privilege separation user for later use if required. */ 682 privsep_chroot = (getuid() == 0 || geteuid() == 0); 683 if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { 684 if (privsep_chroot || options.kerberos_authentication) 685 fatal("Privilege separation user %s does not exist", 686 SSH_PRIVSEP_USER); 687 } else { 688 privsep_pw = pwcopy(privsep_pw); 689 freezero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd)); 690 privsep_pw->pw_passwd = xstrdup("*"); 691 } 692 endpwent(); 693 694 #ifdef WITH_OPENSSL 695 if (options.moduli_file != NULL) 696 dh_set_moduli_file(options.moduli_file); 697 #endif 698 699 if (options.host_key_agent) { 700 if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) 701 setenv(SSH_AUTHSOCKET_ENV_NAME, 702 options.host_key_agent, 1); 703 if ((r = ssh_get_authentication_socket(NULL)) == 0) 704 have_agent = 1; 705 else 706 error_r(r, "Could not connect to agent \"%s\"", 707 options.host_key_agent); 708 } 709 710 if (options.num_host_key_files != num_hostkeys) { 711 fatal("internal error: hostkeys confused (config %u recvd %u)", 712 options.num_host_key_files, num_hostkeys); 713 } 714 715 for (i = 0; i < options.num_host_key_files; i++) { 716 if (host_pubkeys[i] != NULL) { 717 have_key = 1; 718 break; 719 } 720 } 721 if (!have_key) 722 fatal("internal error: received no hostkeys"); 723 724 /* Ensure that umask disallows at least group and world write */ 725 new_umask = umask(0077) | 0022; 726 (void) umask(new_umask); 727 728 /* Initialize the log (it is reinitialized below in case we forked). */ 729 log_init(__progname, options.log_level, options.log_facility, 1); 730 set_log_handler(mm_log_handler, pmonitor); 731 for (i = 0; i < options.num_log_verbose; i++) 732 log_verbose_add(options.log_verbose[i]); 733 734 /* 735 * Chdir to the root directory so that the current disk can be 736 * unmounted if desired. 737 */ 738 if (chdir("/") == -1) 739 error("chdir(\"/\"): %s", strerror(errno)); 740 741 /* This is the child authenticating a new connection. */ 742 setproctitle("%s", "[session-auth]"); 743 744 /* Executed child processes don't need these. */ 745 fcntl(sock_out, F_SETFD, FD_CLOEXEC); 746 fcntl(sock_in, F_SETFD, FD_CLOEXEC); 747 748 ssh_signal(SIGPIPE, SIG_IGN); 749 ssh_signal(SIGALRM, SIG_DFL); 750 ssh_signal(SIGHUP, SIG_DFL); 751 ssh_signal(SIGTERM, SIG_DFL); 752 ssh_signal(SIGQUIT, SIG_DFL); 753 ssh_signal(SIGCHLD, SIG_DFL); 754 755 /* Prepare the channels layer */ 756 channel_init_channels(ssh); 757 channel_set_af(ssh, options.address_family); 758 server_process_channel_timeouts(ssh); 759 server_process_permitopen(ssh); 760 761 ssh_packet_set_nonblocking(ssh); 762 763 /* allocate authentication context */ 764 authctxt = xcalloc(1, sizeof(*authctxt)); 765 ssh->authctxt = authctxt; 766 767 /* XXX global for cleanup, access from other modules */ 768 the_authctxt = authctxt; 769 770 /* Set default key authentication options */ 771 if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL) 772 fatal("allocation failed"); 773 774 /* prepare buffer to collect messages to display to user after login */ 775 if ((loginmsg = sshbuf_new()) == NULL) 776 fatal("sshbuf_new loginmsg failed"); 777 auth_debug_reset(); 778 779 /* Enable challenge-response authentication for privilege separation */ 780 privsep_challenge_enable(); 781 782 #ifdef GSSAPI 783 /* Cache supported mechanism OIDs for later use */ 784 ssh_gssapi_prepare_supported_oids(); 785 #endif 786 787 privsep_child_demote(); 788 789 /* perform the key exchange */ 790 /* authenticate user and start session */ 791 do_ssh2_kex(ssh); 792 do_authentication2(ssh); 793 794 /* 795 * The unprivileged child now transfers the current keystate and exits. 796 */ 797 mm_send_keystate(ssh, pmonitor); 798 ssh_packet_clear_keys(ssh); 799 exit(0); 800 } 801 802 int 803 sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, 804 struct sshkey *pubkey, u_char **signature, size_t *slenp, 805 const u_char *data, size_t dlen, const char *alg) 806 { 807 if (privkey) { 808 if (mm_sshkey_sign(ssh, privkey, signature, slenp, 809 data, dlen, alg, options.sk_provider, NULL, 810 ssh->compat) < 0) 811 fatal_f("privkey sign failed"); 812 } else { 813 if (mm_sshkey_sign(ssh, pubkey, signature, slenp, 814 data, dlen, alg, options.sk_provider, NULL, 815 ssh->compat) < 0) 816 fatal_f("pubkey sign failed"); 817 } 818 return 0; 819 } 820 821 /* SSH2 key exchange */ 822 static void 823 do_ssh2_kex(struct ssh *ssh) 824 { 825 char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; 826 const char *compression = NULL; 827 struct kex *kex; 828 int r; 829 830 if (options.rekey_limit || options.rekey_interval) 831 ssh_packet_set_rekey_limits(ssh, options.rekey_limit, 832 options.rekey_interval); 833 834 if (options.compression == COMP_NONE) 835 compression = "none"; 836 hkalgs = list_hostkey_types(); 837 838 kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, 839 options.ciphers, options.macs, compression, hkalgs); 840 841 free(hkalgs); 842 843 /* start key exchange */ 844 if ((r = kex_setup(ssh, myproposal)) != 0) 845 fatal_r(r, "kex_setup"); 846 kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); 847 kex = ssh->kex; 848 849 #ifdef WITH_OPENSSL 850 kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; 851 kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; 852 kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; 853 kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; 854 kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; 855 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 856 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 857 # ifdef OPENSSL_HAS_ECC 858 kex->kex[KEX_ECDH_SHA2] = kex_gen_server; 859 # endif /* OPENSSL_HAS_ECC */ 860 #endif /* WITH_OPENSSL */ 861 kex->kex[KEX_C25519_SHA256] = kex_gen_server; 862 kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; 863 kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; 864 kex->load_host_public_key=&get_hostkey_public_by_type; 865 kex->load_host_private_key=&get_hostkey_private_by_type; 866 kex->host_key_index=&get_hostkey_index; 867 kex->sign = sshd_hostkey_sign; 868 869 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); 870 kex_proposal_free_entries(myproposal); 871 872 #ifdef DEBUG_KEXDH 873 /* send 1st encrypted/maced/compressed message */ 874 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || 875 (r = sshpkt_put_cstring(ssh, "markus")) != 0 || 876 (r = sshpkt_send(ssh)) != 0 || 877 (r = ssh_packet_write_wait(ssh)) != 0) 878 fatal_fr(r, "send test"); 879 #endif 880 debug("KEX done"); 881 } 882 883 /* server specific fatal cleanup */ 884 void 885 cleanup_exit(int i) 886 { 887 _exit(i); 888 } 889