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