1296853Sdes/* $OpenBSD: sshd.c,v 1.465 2016/02/15 09:47:49 dtucker Exp $ */ 257429Smarkm/* 357429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 457429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 557429Smarkm * All rights reserved 665674Skris * This program is the ssh daemon. It listens for connections from clients, 765674Skris * and performs authentication, executes use commands or shell, and forwards 857429Smarkm * information to/from the application to the user client over an encrypted 965674Skris * connection. This can also handle forwarding of X11, TCP/IP, and 1065674Skris * authentication agent connections. 1160576Skris * 1265674Skris * As far as I am concerned, the code I have written for this software 1365674Skris * can be used freely for any purpose. Any derived versions of this 1465674Skris * software must be clearly marked as such, and if the derived work is 1565674Skris * incompatible with the protocol description in the RFC file, it must be 1665674Skris * called by a name other than "ssh" or "Secure Shell". 1760576Skris * 1865674Skris * SSH2 implementation: 1998684Sdes * Privilege Separation: 2065674Skris * 2198684Sdes * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. 2298684Sdes * Copyright (c) 2002 Niels Provos. All rights reserved. 2365674Skris * 2465674Skris * Redistribution and use in source and binary forms, with or without 2565674Skris * modification, are permitted provided that the following conditions 2665674Skris * are met: 2765674Skris * 1. Redistributions of source code must retain the above copyright 2865674Skris * notice, this list of conditions and the following disclaimer. 2965674Skris * 2. Redistributions in binary form must reproduce the above copyright 3065674Skris * notice, this list of conditions and the following disclaimer in the 3165674Skris * documentation and/or other materials provided with the distribution. 3265674Skris * 3365674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 3465674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 3565674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 3665674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3765674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3865674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3965674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 4065674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 4165674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 4265674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4357429Smarkm */ 4457429Smarkm 4557429Smarkm#include "includes.h" 46162856Sdes__RCSID("$FreeBSD: releng/10.3/crypto/openssh/sshd.c 296853 2016-03-14 13:05:13Z des $"); 4757429Smarkm 48162856Sdes#include <sys/types.h> 49162856Sdes#include <sys/ioctl.h> 50199804Sattilio#include <sys/mman.h> 51162856Sdes#include <sys/socket.h> 52162856Sdes#ifdef HAVE_SYS_STAT_H 53162856Sdes# include <sys/stat.h> 54162856Sdes#endif 55162856Sdes#ifdef HAVE_SYS_TIME_H 56162856Sdes# include <sys/time.h> 57162856Sdes#endif 58162856Sdes#include "openbsd-compat/sys-tree.h" 59181111Sdes#include "openbsd-compat/sys-queue.h" 60162856Sdes#include <sys/wait.h> 61162856Sdes 62162856Sdes#include <errno.h> 63162856Sdes#include <fcntl.h> 64162856Sdes#include <netdb.h> 65162856Sdes#ifdef HAVE_PATHS_H 66162856Sdes#include <paths.h> 67162856Sdes#endif 68162856Sdes#include <grp.h> 69162856Sdes#include <pwd.h> 70162856Sdes#include <signal.h> 71162856Sdes#include <stdarg.h> 72162856Sdes#include <stdio.h> 73162856Sdes#include <stdlib.h> 74162856Sdes#include <string.h> 75162856Sdes#include <unistd.h> 76295367Sdes#include <limits.h> 77162856Sdes 78295367Sdes#ifdef WITH_OPENSSL 7976262Sgreen#include <openssl/dh.h> 8076262Sgreen#include <openssl/bn.h> 8198684Sdes#include <openssl/rand.h> 82181111Sdes#include "openbsd-compat/openssl-compat.h" 83295367Sdes#endif 84181111Sdes 8598941Sdes#ifdef HAVE_SECUREWARE 8698941Sdes#include <sys/security.h> 8798941Sdes#include <prot.h> 8898941Sdes#endif 8976262Sgreen 90109683Sdes#ifdef __FreeBSD__ 91109683Sdes#include <resolv.h> 92255829Sdes#if defined(GSSAPI) && defined(HAVE_GSSAPI_GSSAPI_H) 93255829Sdes#include <gssapi/gssapi.h> 94255829Sdes#elif defined(GSSAPI) && defined(HAVE_GSSAPI_H) 95162984Sdes#include <gssapi.h> 96109683Sdes#endif 97153838Sdfr#endif 98109683Sdes 99162856Sdes#include "xmalloc.h" 10076262Sgreen#include "ssh.h" 10176262Sgreen#include "ssh1.h" 10276262Sgreen#include "ssh2.h" 10357429Smarkm#include "rsa.h" 10476262Sgreen#include "sshpty.h" 10557429Smarkm#include "packet.h" 10676262Sgreen#include "log.h" 107162856Sdes#include "buffer.h" 108295367Sdes#include "misc.h" 109295367Sdes#include "match.h" 11057429Smarkm#include "servconf.h" 11157429Smarkm#include "uidswap.h" 11257429Smarkm#include "compat.h" 11376262Sgreen#include "cipher.h" 114264377Sdes#include "digest.h" 115162856Sdes#include "key.h" 11660576Skris#include "kex.h" 11760576Skris#include "myproposal.h" 11860576Skris#include "authfile.h" 11976262Sgreen#include "pathnames.h" 12076262Sgreen#include "atomicio.h" 12176262Sgreen#include "canohost.h" 122162856Sdes#include "hostfile.h" 12376262Sgreen#include "auth.h" 124255767Sdes#include "authfd.h" 125137019Sdes#include "msg.h" 12676262Sgreen#include "dispatch.h" 12792559Sdes#include "channels.h" 12898684Sdes#include "session.h" 12998684Sdes#include "monitor_mm.h" 13098684Sdes#include "monitor.h" 131162856Sdes#ifdef GSSAPI 132162856Sdes#include "ssh-gss.h" 133162856Sdes#endif 13498684Sdes#include "monitor_wrap.h" 135226046Sdes#include "ssh-sandbox.h" 136162856Sdes#include "version.h" 137295367Sdes#include "ssherr.h" 13860576Skris 13957429Smarkm#ifdef LIBWRAP 14057429Smarkm#include <tcpd.h> 14157429Smarkm#include <syslog.h> 142181111Sdesint allow_severity; 143181111Sdesint deny_severity; 14457429Smarkm#endif /* LIBWRAP */ 14557429Smarkm 14657429Smarkm#ifndef O_NOCTTY 14757429Smarkm#define O_NOCTTY 0 14857429Smarkm#endif 14957429Smarkm 150137019Sdes/* Re-exec fds */ 151137019Sdes#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) 152137019Sdes#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) 153137019Sdes#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) 154137019Sdes#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) 155137019Sdes 15676262Sgreenextern char *__progname; 15776262Sgreen 15857429Smarkm/* Server configuration options. */ 15957429SmarkmServerOptions options; 16057429Smarkm 16157429Smarkm/* Name of the server configuration file. */ 16276262Sgreenchar *config_file_name = _PATH_SERVER_CONFIG_FILE; 16357429Smarkm 16460576Skris/* 16557429Smarkm * Debug mode flag. This can be set on the command line. If debug 16657429Smarkm * mode is enabled, extra debugging output will be sent to the system 16757429Smarkm * log, the daemon will not go to background, and will exit after processing 16857429Smarkm * the first connection. 16957429Smarkm */ 17057429Smarkmint debug_flag = 0; 17157429Smarkm 17292559Sdes/* Flag indicating that the daemon should only test the configuration and keys. */ 17392559Sdesint test_flag = 0; 17492559Sdes 17557429Smarkm/* Flag indicating that the daemon is being started from inetd. */ 17657429Smarkmint inetd_flag = 0; 17757429Smarkm 17876262Sgreen/* Flag indicating that sshd should not detach and become a daemon. */ 17976262Sgreenint no_daemon_flag = 0; 18076262Sgreen 18157429Smarkm/* debug goes to stderr unless inetd_flag is set */ 18257429Smarkmint log_stderr = 0; 18357429Smarkm 18457429Smarkm/* Saved arguments to main(). */ 18557429Smarkmchar **saved_argv; 18698941Sdesint saved_argc; 18757429Smarkm 188137019Sdes/* re-exec */ 189137019Sdesint rexeced_flag = 0; 190137019Sdesint rexec_flag = 1; 191137019Sdesint rexec_argc = 0; 192137019Sdeschar **rexec_argv; 193137019Sdes 19457429Smarkm/* 19557429Smarkm * The sockets that the server is listening; this is used in the SIGHUP 19657429Smarkm * signal handler. 19757429Smarkm */ 19857429Smarkm#define MAX_LISTEN_SOCKS 16 19957429Smarkmint listen_socks[MAX_LISTEN_SOCKS]; 20057429Smarkmint num_listen_socks = 0; 20157429Smarkm 20257429Smarkm/* 20357429Smarkm * the client's version string, passed by sshd2 in compat mode. if != NULL, 20457429Smarkm * sshd will skip the version-number exchange 20557429Smarkm */ 20657429Smarkmchar *client_version_string = NULL; 20760576Skrischar *server_version_string = NULL; 20857429Smarkm 209255767Sdes/* Daemon's agent connection */ 210295367Sdesint auth_sock = -1; 211255767Sdesint have_agent = 0; 212255767Sdes 21357429Smarkm/* 21457429Smarkm * Any really sensitive data in the application is contained in this 21557429Smarkm * structure. The idea is that this structure could be locked into memory so 21657429Smarkm * that the pages do not get written into swap. However, there are some 21757429Smarkm * problems. The private key contains BIGNUMs, and we do not (in principle) 21857429Smarkm * have access to the internals of them, and locking just the structure is 21957429Smarkm * not very useful. Currently, memory locking is not implemented. 22057429Smarkm */ 22157429Smarkmstruct { 22276262Sgreen Key *server_key; /* ephemeral server key */ 22376262Sgreen Key *ssh1_host_key; /* ssh1 host key */ 22476262Sgreen Key **host_keys; /* all private host keys */ 225255767Sdes Key **host_pubkeys; /* all public host keys */ 226204917Sdes Key **host_certificates; /* all public host certificates */ 22776262Sgreen int have_ssh1_key; 22876262Sgreen int have_ssh2_key; 22976262Sgreen u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; 23057429Smarkm} sensitive_data; 23157429Smarkm 23257429Smarkm/* 23376262Sgreen * Flag indicating whether the RSA server key needs to be regenerated. 23476262Sgreen * Is set in the SIGALRM handler and cleared when the key is regenerated. 23557429Smarkm */ 23692559Sdesstatic volatile sig_atomic_t key_do_regen = 0; 23757429Smarkm 23892559Sdes/* This is set to true when a signal is received. */ 23992559Sdesstatic volatile sig_atomic_t received_sighup = 0; 24092559Sdesstatic volatile sig_atomic_t received_sigterm = 0; 24157429Smarkm 24260576Skris/* session identifier, used by RSA-auth */ 24376262Sgreenu_char session_id[16]; 24460576Skris 24560576Skris/* same for ssh2 */ 24676262Sgreenu_char *session_id2 = NULL; 247124211Sdesu_int session_id2_len = 0; 24860576Skris 24965674Skris/* record remote hostname or ip */ 250295367Sdesu_int utmp_len = HOST_NAME_MAX+1; 25165674Skris 25292559Sdes/* options.max_startup sized array of fd ints */ 25392559Sdesint *startup_pipes = NULL; 25492559Sdesint startup_pipe; /* in child */ 25592559Sdes 25698684Sdes/* variables used for privilege separation */ 257162856Sdesint use_privsep = -1; 258126277Sdesstruct monitor *pmonitor = NULL; 259240075Sdesint privsep_is_preauth = 1; 26098684Sdes 261137019Sdes/* global authentication context */ 262137019SdesAuthctxt *the_authctxt = NULL; 263137019Sdes 264162856Sdes/* sshd_config buffer */ 265162856SdesBuffer cfg; 266162856Sdes 267124211Sdes/* message to be displayed after login */ 268124211SdesBuffer loginmsg; 269124211Sdes 270162856Sdes/* Unprivileged user */ 271162856Sdesstruct passwd *privsep_pw = NULL; 272162856Sdes 27357429Smarkm/* Prototypes for various functions defined later in this file. */ 27492559Sdesvoid destroy_sensitive_data(void); 27598684Sdesvoid demote_sensitive_data(void); 27657429Smarkm 277295367Sdes#ifdef WITH_SSH1 27892559Sdesstatic void do_ssh1_kex(void); 279295367Sdes#endif 28092559Sdesstatic void do_ssh2_kex(void); 28169591Sgreen 28257429Smarkm/* 28357429Smarkm * Close all listening sockets 28457429Smarkm */ 28592559Sdesstatic void 28657429Smarkmclose_listen_socks(void) 28757429Smarkm{ 28857429Smarkm int i; 28999063Sdes 29057429Smarkm for (i = 0; i < num_listen_socks; i++) 29157429Smarkm close(listen_socks[i]); 29257429Smarkm num_listen_socks = -1; 29357429Smarkm} 29457429Smarkm 29592559Sdesstatic void 29692559Sdesclose_startup_pipes(void) 29792559Sdes{ 29892559Sdes int i; 29999063Sdes 30092559Sdes if (startup_pipes) 30192559Sdes for (i = 0; i < options.max_startups; i++) 30292559Sdes if (startup_pipes[i] != -1) 30392559Sdes close(startup_pipes[i]); 30492559Sdes} 30592559Sdes 30657429Smarkm/* 30757429Smarkm * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; 30857429Smarkm * the effect is to reread the configuration file (and to regenerate 30957429Smarkm * the server key). 31057429Smarkm */ 311162856Sdes 312162856Sdes/*ARGSUSED*/ 31392559Sdesstatic void 31457429Smarkmsighup_handler(int sig) 31557429Smarkm{ 31692559Sdes int save_errno = errno; 31792559Sdes 31857429Smarkm received_sighup = 1; 31957429Smarkm signal(SIGHUP, sighup_handler); 32092559Sdes errno = save_errno; 32157429Smarkm} 32257429Smarkm 32357429Smarkm/* 32457429Smarkm * Called from the main program after receiving SIGHUP. 32557429Smarkm * Restarts the server. 32657429Smarkm */ 32792559Sdesstatic void 32876262Sgreensighup_restart(void) 32957429Smarkm{ 330124211Sdes logit("Received SIGHUP; restarting."); 331262566Sdes platform_pre_restart(); 33257429Smarkm close_listen_socks(); 33392559Sdes close_startup_pipes(); 334181111Sdes alarm(0); /* alarm timer persists across exec */ 335204917Sdes signal(SIGHUP, SIG_IGN); /* will be restored after exec */ 33657429Smarkm execv(saved_argv[0], saved_argv); 337124211Sdes logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], 33899063Sdes strerror(errno)); 33957429Smarkm exit(1); 34057429Smarkm} 34157429Smarkm 34257429Smarkm/* 34357429Smarkm * Generic signal handler for terminating signals in the master daemon. 34457429Smarkm */ 345162856Sdes/*ARGSUSED*/ 34692559Sdesstatic void 34757429Smarkmsigterm_handler(int sig) 34857429Smarkm{ 34992559Sdes received_sigterm = sig; 35057429Smarkm} 35157429Smarkm 35257429Smarkm/* 35357429Smarkm * SIGCHLD handler. This is called whenever a child dies. This will then 35492559Sdes * reap any zombies left by exited children. 35557429Smarkm */ 356162856Sdes/*ARGSUSED*/ 35792559Sdesstatic void 35857429Smarkmmain_sigchld_handler(int sig) 35957429Smarkm{ 36099063Sdes int save_errno = errno; 36198684Sdes pid_t pid; 36257429Smarkm int status; 36357429Smarkm 36498684Sdes while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || 36598684Sdes (pid < 0 && errno == EINTR)) 36657429Smarkm ; 36757429Smarkm 36857429Smarkm signal(SIGCHLD, main_sigchld_handler); 36957429Smarkm errno = save_errno; 37057429Smarkm} 37157429Smarkm 37257429Smarkm/* 37357429Smarkm * Signal handler for the alarm after the login grace period has expired. 37457429Smarkm */ 375162856Sdes/*ARGSUSED*/ 37692559Sdesstatic void 37757429Smarkmgrace_alarm_handler(int sig) 37857429Smarkm{ 379126277Sdes if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0) 380126277Sdes kill(pmonitor->m_pid, SIGALRM); 381126277Sdes 382248619Sdes /* 383248619Sdes * Try to kill any processes that we have spawned, E.g. authorized 384248619Sdes * keys command helpers. 385248619Sdes */ 386248619Sdes if (getpgid(0) == getpid()) { 387248619Sdes signal(SIGTERM, SIG_IGN); 388262566Sdes kill(0, SIGTERM); 389248619Sdes } 390248619Sdes 39157429Smarkm /* Log error and exit. */ 392162856Sdes sigdie("Timeout before authentication for %s", get_remote_ipaddr()); 39357429Smarkm} 39457429Smarkm 39557429Smarkm/* 39657429Smarkm * Signal handler for the key regeneration alarm. Note that this 39757429Smarkm * alarm only occurs in the daemon waiting for connections, and it does not 39857429Smarkm * do anything with the private key or random state before forking. 39957429Smarkm * Thus there should be no concurrency control/asynchronous execution 40057429Smarkm * problems. 40157429Smarkm */ 40292559Sdesstatic void 40376262Sgreengenerate_ephemeral_server_key(void) 40457429Smarkm{ 40576262Sgreen verbose("Generating %s%d bit RSA key.", 40676262Sgreen sensitive_data.server_key ? "new " : "", options.server_key_bits); 40776262Sgreen if (sensitive_data.server_key != NULL) 40876262Sgreen key_free(sensitive_data.server_key); 40976262Sgreen sensitive_data.server_key = key_generate(KEY_RSA1, 41076262Sgreen options.server_key_bits); 41176262Sgreen verbose("RSA key generation complete."); 41257429Smarkm 413181111Sdes arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); 41476262Sgreen} 41557429Smarkm 416162856Sdes/*ARGSUSED*/ 41792559Sdesstatic void 41876262Sgreenkey_regeneration_alarm(int sig) 41976262Sgreen{ 42076262Sgreen int save_errno = errno; 42199063Sdes 42276262Sgreen signal(SIGALRM, SIG_DFL); 42357429Smarkm errno = save_errno; 42476262Sgreen key_do_regen = 1; 42557429Smarkm} 42657429Smarkm 42792559Sdesstatic void 42860576Skrissshd_exchange_identification(int sock_in, int sock_out) 42960576Skris{ 430149753Sdes u_int i; 431149753Sdes int mismatch; 43260576Skris int remote_major, remote_minor; 43360576Skris int major, minor; 434181111Sdes char *s, *newline = "\n"; 43560576Skris char buf[256]; /* Must not be larger than remote_version. */ 43660576Skris char remote_version[256]; /* Must be at least as big as buf. */ 43760576Skris 43860576Skris if ((options.protocol & SSH_PROTO_1) && 43960576Skris (options.protocol & SSH_PROTO_2)) { 44060576Skris major = PROTOCOL_MAJOR_1; 44160576Skris minor = 99; 44260576Skris } else if (options.protocol & SSH_PROTO_2) { 44360576Skris major = PROTOCOL_MAJOR_2; 44460576Skris minor = PROTOCOL_MINOR_2; 445181111Sdes newline = "\r\n"; 44660576Skris } else { 44760576Skris major = PROTOCOL_MAJOR_1; 44860576Skris minor = PROTOCOL_MINOR_1; 44960576Skris } 45060576Skris 451294693Sdes xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", 452240075Sdes major, minor, SSH_VERSION, 453240075Sdes *options.version_addendum == '\0' ? "" : " ", 454240075Sdes options.version_addendum, newline); 455240075Sdes 456124211Sdes /* Send our protocol version identification. */ 457296853Sdes if (atomicio(vwrite, sock_out, server_version_string, 458124211Sdes strlen(server_version_string)) 459124211Sdes != strlen(server_version_string)) { 460124211Sdes logit("Could not write ident string to %s", get_remote_ipaddr()); 461126277Sdes cleanup_exit(255); 462124211Sdes } 463124211Sdes 464124211Sdes /* Read other sides version identification. */ 465124211Sdes memset(buf, 0, sizeof(buf)); 466124211Sdes for (i = 0; i < sizeof(buf) - 1; i++) { 467296853Sdes if (atomicio(read, sock_in, &buf[i], 1) != 1) { 468124211Sdes logit("Did not receive identification string from %s", 469124211Sdes get_remote_ipaddr()); 470126277Sdes cleanup_exit(255); 47160576Skris } 472124211Sdes if (buf[i] == '\r') { 473124211Sdes buf[i] = 0; 474124211Sdes /* Kludge for F-Secure Macintosh < 1.0.2 */ 475124211Sdes if (i == 12 && 476124211Sdes strncmp(buf, "SSH-1.5-W1.0", 12) == 0) 47760576Skris break; 478124211Sdes continue; 47960576Skris } 480124211Sdes if (buf[i] == '\n') { 481124211Sdes buf[i] = 0; 482124211Sdes break; 483124211Sdes } 48460576Skris } 485124211Sdes buf[sizeof(buf) - 1] = 0; 486124211Sdes client_version_string = xstrdup(buf); 48760576Skris 48860576Skris /* 48960576Skris * Check that the versions match. In future this might accept 49060576Skris * several versions and set appropriate flags to handle them. 49160576Skris */ 49260576Skris if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", 49360576Skris &remote_major, &remote_minor, remote_version) != 3) { 49460576Skris s = "Protocol mismatch.\n"; 495124211Sdes (void) atomicio(vwrite, sock_out, s, strlen(s)); 496262566Sdes logit("Bad protocol version identification '%.100s' " 497262566Sdes "from %s port %d", client_version_string, 498262566Sdes get_remote_ipaddr(), get_remote_port()); 49960576Skris close(sock_in); 50060576Skris close(sock_out); 501126277Sdes cleanup_exit(255); 50260576Skris } 50360576Skris debug("Client protocol version %d.%d; client software version %.100s", 50492559Sdes remote_major, remote_minor, remote_version); 50560576Skris 506295367Sdes active_state->compat = compat_datafellows(remote_version); 50760576Skris 508262566Sdes if ((datafellows & SSH_BUG_PROBE) != 0) { 509124211Sdes logit("probed from %s with %s. Don't panic.", 510106130Sdes get_remote_ipaddr(), client_version_string); 511126277Sdes cleanup_exit(255); 512106130Sdes } 513262566Sdes if ((datafellows & SSH_BUG_SCANNER) != 0) { 514124211Sdes logit("scanned from %s with %s. Don't panic.", 51576262Sgreen get_remote_ipaddr(), client_version_string); 516126277Sdes cleanup_exit(255); 51776262Sgreen } 518262566Sdes if ((datafellows & SSH_BUG_RSASIGMD5) != 0) { 519262566Sdes logit("Client version \"%.100s\" uses unsafe RSA signature " 520262566Sdes "scheme; disabling use of RSA keys", remote_version); 521262566Sdes } 522262566Sdes if ((datafellows & SSH_BUG_DERIVEKEY) != 0) { 523262566Sdes fatal("Client version \"%.100s\" uses unsafe key agreement; " 524262566Sdes "refusing connection", remote_version); 525262566Sdes } 52676262Sgreen 52760576Skris mismatch = 0; 52892559Sdes switch (remote_major) { 52960576Skris case 1: 53060576Skris if (remote_minor == 99) { 53160576Skris if (options.protocol & SSH_PROTO_2) 53260576Skris enable_compat20(); 53360576Skris else 53460576Skris mismatch = 1; 53560576Skris break; 53660576Skris } 53760576Skris if (!(options.protocol & SSH_PROTO_1)) { 53860576Skris mismatch = 1; 53960576Skris break; 54060576Skris } 54160576Skris if (remote_minor < 3) { 54265674Skris packet_disconnect("Your ssh version is too old and " 54360576Skris "is no longer supported. Please install a newer version."); 54460576Skris } else if (remote_minor == 3) { 54560576Skris /* note that this disables agent-forwarding */ 54660576Skris enable_compat13(); 54760576Skris } 54860576Skris break; 54960576Skris case 2: 55060576Skris if (options.protocol & SSH_PROTO_2) { 55160576Skris enable_compat20(); 55260576Skris break; 55360576Skris } 55460576Skris /* FALLTHROUGH */ 55560576Skris default: 55660576Skris mismatch = 1; 55760576Skris break; 55860576Skris } 55960576Skris chop(server_version_string); 56060576Skris debug("Local version string %.200s", server_version_string); 56160576Skris 56260576Skris if (mismatch) { 56360576Skris s = "Protocol major versions differ.\n"; 564124211Sdes (void) atomicio(vwrite, sock_out, s, strlen(s)); 56560576Skris close(sock_in); 56660576Skris close(sock_out); 567124211Sdes logit("Protocol major versions differ for %s: %.200s vs. %.200s", 56860576Skris get_remote_ipaddr(), 56960576Skris server_version_string, client_version_string); 570126277Sdes cleanup_exit(255); 57160576Skris } 57260576Skris} 57360576Skris 57476262Sgreen/* Destroy the host and server keys. They will no longer be needed. */ 57560576Skrisvoid 57660576Skrisdestroy_sensitive_data(void) 57760576Skris{ 57876262Sgreen int i; 57976262Sgreen 58076262Sgreen if (sensitive_data.server_key) { 58176262Sgreen key_free(sensitive_data.server_key); 58276262Sgreen sensitive_data.server_key = NULL; 58376262Sgreen } 58492559Sdes for (i = 0; i < options.num_host_key_files; i++) { 58576262Sgreen if (sensitive_data.host_keys[i]) { 58676262Sgreen key_free(sensitive_data.host_keys[i]); 58776262Sgreen sensitive_data.host_keys[i] = NULL; 58876262Sgreen } 589204917Sdes if (sensitive_data.host_certificates[i]) { 590204917Sdes key_free(sensitive_data.host_certificates[i]); 591204917Sdes sensitive_data.host_certificates[i] = NULL; 592204917Sdes } 59376262Sgreen } 59476262Sgreen sensitive_data.ssh1_host_key = NULL; 595264377Sdes explicit_bzero(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); 59660576Skris} 59760576Skris 59898684Sdes/* Demote private to public keys for network child */ 59998684Sdesvoid 60098684Sdesdemote_sensitive_data(void) 60198684Sdes{ 60298684Sdes Key *tmp; 60398684Sdes int i; 60498684Sdes 60598684Sdes if (sensitive_data.server_key) { 60698684Sdes tmp = key_demote(sensitive_data.server_key); 60798684Sdes key_free(sensitive_data.server_key); 60898684Sdes sensitive_data.server_key = tmp; 60998684Sdes } 61098684Sdes 61198684Sdes for (i = 0; i < options.num_host_key_files; i++) { 61298684Sdes if (sensitive_data.host_keys[i]) { 61398684Sdes tmp = key_demote(sensitive_data.host_keys[i]); 61498684Sdes key_free(sensitive_data.host_keys[i]); 61598684Sdes sensitive_data.host_keys[i] = tmp; 61698684Sdes if (tmp->type == KEY_RSA1) 61798684Sdes sensitive_data.ssh1_host_key = tmp; 61898684Sdes } 619204917Sdes /* Certs do not need demotion */ 62098684Sdes } 62198684Sdes 62298684Sdes /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ 62398684Sdes} 62498684Sdes 62598684Sdesstatic void 62698684Sdesprivsep_preauth_child(void) 62798684Sdes{ 628197679Sdes u_int32_t rnd[256]; 629106130Sdes gid_t gidset[1]; 63098684Sdes 63198684Sdes /* Enable challenge-response authentication for privilege separation */ 63298684Sdes privsep_challenge_enable(); 63398684Sdes 634264377Sdes#ifdef GSSAPI 635264377Sdes /* Cache supported mechanism OIDs for later use */ 636264377Sdes if (options.gss_authentication) 637264377Sdes ssh_gssapi_prepare_supported_oids(); 638264377Sdes#endif 639264377Sdes 640181111Sdes arc4random_stir(); 641181111Sdes arc4random_buf(rnd, sizeof(rnd)); 642295367Sdes#ifdef WITH_OPENSSL 643106130Sdes RAND_seed(rnd, sizeof(rnd)); 644295367Sdes if ((RAND_bytes((u_char *)rnd, 1)) != 1) 645295367Sdes fatal("%s: RAND_bytes failed", __func__); 646295367Sdes#endif 647264377Sdes explicit_bzero(rnd, sizeof(rnd)); 64898684Sdes 64998684Sdes /* Demote the private keys to public keys. */ 65098684Sdes demote_sensitive_data(); 65198684Sdes 652296853Sdes /* Demote the child */ 653296853Sdes if (getuid() == 0 || geteuid() == 0) { 654296853Sdes /* Change our root directory */ 655296853Sdes if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) 656296853Sdes fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, 657296853Sdes strerror(errno)); 658296853Sdes if (chdir("/") == -1) 659296853Sdes fatal("chdir(\"/\"): %s", strerror(errno)); 66098684Sdes 661296853Sdes /* Drop our privileges */ 662296853Sdes debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, 663296853Sdes (u_int)privsep_pw->pw_gid); 664296853Sdes gidset[0] = privsep_pw->pw_gid; 665296853Sdes if (setgroups(1, gidset) < 0) 666296853Sdes fatal("setgroups: %.100s", strerror(errno)); 667296853Sdes permanently_set_uid(privsep_pw); 668296853Sdes } 66998684Sdes} 67098684Sdes 671126277Sdesstatic int 672126277Sdesprivsep_preauth(Authctxt *authctxt) 67398684Sdes{ 674295367Sdes int status, r; 67598684Sdes pid_t pid; 676226046Sdes struct ssh_sandbox *box = NULL; 67798684Sdes 67898684Sdes /* Set up unprivileged child process to deal with network data */ 67998684Sdes pmonitor = monitor_init(); 68098684Sdes /* Store a pointer to the kex for later rekeying */ 681295367Sdes pmonitor->m_pkex = &active_state->kex; 68298684Sdes 683240075Sdes if (use_privsep == PRIVSEP_ON) 684262566Sdes box = ssh_sandbox_init(pmonitor); 68598684Sdes pid = fork(); 68698684Sdes if (pid == -1) { 68798684Sdes fatal("fork of unprivileged child failed"); 68898684Sdes } else if (pid != 0) { 68998684Sdes debug2("Network child is on pid %ld", (long)pid); 69098684Sdes 691240075Sdes pmonitor->m_pid = pid; 692295367Sdes if (have_agent) { 693295367Sdes r = ssh_get_authentication_socket(&auth_sock); 694295367Sdes if (r != 0) { 695295367Sdes error("Could not get agent socket: %s", 696295367Sdes ssh_err(r)); 697295367Sdes have_agent = 0; 698295367Sdes } 699295367Sdes } 700226046Sdes if (box != NULL) 701226046Sdes ssh_sandbox_parent_preauth(box, pid); 702126277Sdes monitor_child_preauth(authctxt, pmonitor); 70398684Sdes 70498684Sdes /* Sync memory */ 70598684Sdes monitor_sync(pmonitor); 70698684Sdes 70798684Sdes /* Wait for the child's exit status */ 708226046Sdes while (waitpid(pid, &status, 0) < 0) { 709240075Sdes if (errno == EINTR) 710240075Sdes continue; 711240075Sdes pmonitor->m_pid = -1; 712240075Sdes fatal("%s: waitpid: %s", __func__, strerror(errno)); 713226046Sdes } 714240075Sdes privsep_is_preauth = 0; 715240075Sdes pmonitor->m_pid = -1; 716226046Sdes if (WIFEXITED(status)) { 717226046Sdes if (WEXITSTATUS(status) != 0) 718226046Sdes fatal("%s: preauth child exited with status %d", 719226046Sdes __func__, WEXITSTATUS(status)); 720226046Sdes } else if (WIFSIGNALED(status)) 721226046Sdes fatal("%s: preauth child terminated by signal %d", 722226046Sdes __func__, WTERMSIG(status)); 723226046Sdes if (box != NULL) 724226046Sdes ssh_sandbox_parent_finish(box); 725226046Sdes return 1; 72698684Sdes } else { 72798684Sdes /* child */ 72898684Sdes close(pmonitor->m_sendfd); 729226046Sdes close(pmonitor->m_log_recvfd); 73098684Sdes 731226046Sdes /* Arrange for logging to be sent to the monitor */ 732226046Sdes set_log_handler(mm_log_handler, pmonitor); 733226046Sdes 734296853Sdes privsep_preauth_child(); 73598684Sdes setproctitle("%s", "[net]"); 736226046Sdes if (box != NULL) 737226046Sdes ssh_sandbox_child(box); 738226046Sdes 739226046Sdes return 0; 74098684Sdes } 74198684Sdes} 74298684Sdes 74398684Sdesstatic void 74498684Sdesprivsep_postauth(Authctxt *authctxt) 74598684Sdes{ 746181111Sdes u_int32_t rnd[256]; 747181111Sdes 748106130Sdes#ifdef DISABLE_FD_PASSING 74999063Sdes if (1) { 75099063Sdes#else 75198684Sdes if (authctxt->pw->pw_uid == 0 || options.use_login) { 75299063Sdes#endif 75398684Sdes /* File descriptor passing is broken or root login */ 75498684Sdes use_privsep = 0; 755157019Sdes goto skip; 75698684Sdes } 75798684Sdes 75898684Sdes /* New socket pair */ 75998684Sdes monitor_reinit(pmonitor); 76098684Sdes 76198684Sdes pmonitor->m_pid = fork(); 76298684Sdes if (pmonitor->m_pid == -1) 76398684Sdes fatal("fork of unprivileged child failed"); 76498684Sdes else if (pmonitor->m_pid != 0) { 765181111Sdes verbose("User child is on pid %ld", (long)pmonitor->m_pid); 766137019Sdes buffer_clear(&loginmsg); 76798684Sdes monitor_child_postauth(pmonitor); 76898684Sdes 76998684Sdes /* NEVERREACHED */ 77098684Sdes exit(0); 77198684Sdes } 77298684Sdes 773226046Sdes /* child */ 774226046Sdes 77598684Sdes close(pmonitor->m_sendfd); 776226046Sdes pmonitor->m_sendfd = -1; 77798684Sdes 77898684Sdes /* Demote the private keys to public keys. */ 77998684Sdes demote_sensitive_data(); 78098684Sdes 781181111Sdes arc4random_stir(); 782181111Sdes arc4random_buf(rnd, sizeof(rnd)); 783295367Sdes#ifdef WITH_OPENSSL 784181111Sdes RAND_seed(rnd, sizeof(rnd)); 785295367Sdes if ((RAND_bytes((u_char *)rnd, 1)) != 1) 786295367Sdes fatal("%s: RAND_bytes failed", __func__); 787295367Sdes#endif 788264377Sdes explicit_bzero(rnd, sizeof(rnd)); 789181111Sdes 79098684Sdes /* Drop privileges */ 79198684Sdes do_setusercontext(authctxt->pw); 79298684Sdes 793157019Sdes skip: 79498684Sdes /* It is safe now to apply the key state */ 79598684Sdes monitor_apply_keystate(pmonitor); 796149753Sdes 797149753Sdes /* 798149753Sdes * Tell the packet layer that authentication was successful, since 799149753Sdes * this information is not part of the key state. 800149753Sdes */ 801149753Sdes packet_set_authenticated(); 80298684Sdes} 80398684Sdes 80492559Sdesstatic char * 80576262Sgreenlist_hostkey_types(void) 80676262Sgreen{ 80792559Sdes Buffer b; 808126277Sdes const char *p; 809126277Sdes char *ret; 81076262Sgreen int i; 811204917Sdes Key *key; 81292559Sdes 81392559Sdes buffer_init(&b); 81492559Sdes for (i = 0; i < options.num_host_key_files; i++) { 815204917Sdes key = sensitive_data.host_keys[i]; 81676262Sgreen if (key == NULL) 817255767Sdes key = sensitive_data.host_pubkeys[i]; 818295367Sdes if (key == NULL || key->type == KEY_RSA1) 81976262Sgreen continue; 820295367Sdes /* Check that the key is accepted in HostkeyAlgorithms */ 821295367Sdes if (match_pattern_list(sshkey_ssh_name(key), 822295367Sdes options.hostkeyalgorithms, 0) != 1) { 823295367Sdes debug3("%s: %s key not permitted by HostkeyAlgorithms", 824295367Sdes __func__, sshkey_ssh_name(key)); 825295367Sdes continue; 826295367Sdes } 82792559Sdes switch (key->type) { 82876262Sgreen case KEY_RSA: 82976262Sgreen case KEY_DSA: 830221420Sdes case KEY_ECDSA: 831262566Sdes case KEY_ED25519: 83292559Sdes if (buffer_len(&b) > 0) 83392559Sdes buffer_append(&b, ",", 1); 83492559Sdes p = key_ssh_name(key); 83592559Sdes buffer_append(&b, p, strlen(p)); 836296853Sdes 837296853Sdes /* for RSA we also support SHA2 signatures */ 838296853Sdes if (key->type == KEY_RSA) { 839296853Sdes p = ",rsa-sha2-512,rsa-sha2-256"; 840296853Sdes buffer_append(&b, p, strlen(p)); 841296853Sdes } 84276262Sgreen break; 84376262Sgreen } 844204917Sdes /* If the private key has a cert peer, then list that too */ 845204917Sdes key = sensitive_data.host_certificates[i]; 846204917Sdes if (key == NULL) 847204917Sdes continue; 848204917Sdes switch (key->type) { 849204917Sdes case KEY_RSA_CERT: 850204917Sdes case KEY_DSA_CERT: 851221420Sdes case KEY_ECDSA_CERT: 852262566Sdes case KEY_ED25519_CERT: 853204917Sdes if (buffer_len(&b) > 0) 854204917Sdes buffer_append(&b, ",", 1); 855204917Sdes p = key_ssh_name(key); 856204917Sdes buffer_append(&b, p, strlen(p)); 857204917Sdes break; 858204917Sdes } 85976262Sgreen } 86092559Sdes buffer_append(&b, "\0", 1); 861126277Sdes ret = xstrdup(buffer_ptr(&b)); 86292559Sdes buffer_free(&b); 863126277Sdes debug("list_hostkey_types: %s", ret); 864126277Sdes return ret; 86576262Sgreen} 86676262Sgreen 867204917Sdesstatic Key * 868295367Sdesget_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) 86976262Sgreen{ 87076262Sgreen int i; 871204917Sdes Key *key; 87299063Sdes 87392559Sdes for (i = 0; i < options.num_host_key_files; i++) { 874215116Sdes switch (type) { 875215116Sdes case KEY_RSA_CERT: 876215116Sdes case KEY_DSA_CERT: 877221420Sdes case KEY_ECDSA_CERT: 878262566Sdes case KEY_ED25519_CERT: 879204917Sdes key = sensitive_data.host_certificates[i]; 880215116Sdes break; 881215116Sdes default: 882204917Sdes key = sensitive_data.host_keys[i]; 883255767Sdes if (key == NULL && !need_private) 884255767Sdes key = sensitive_data.host_pubkeys[i]; 885215116Sdes break; 886215116Sdes } 887295367Sdes if (key != NULL && key->type == type && 888295367Sdes (key->type != KEY_ECDSA || key->ecdsa_nid == nid)) 889204917Sdes return need_private ? 890204917Sdes sensitive_data.host_keys[i] : key; 89176262Sgreen } 89276262Sgreen return NULL; 89376262Sgreen} 89476262Sgreen 89598684SdesKey * 896295367Sdesget_hostkey_public_by_type(int type, int nid, struct ssh *ssh) 897204917Sdes{ 898295367Sdes return get_hostkey_by_type(type, nid, 0, ssh); 899204917Sdes} 900204917Sdes 901204917SdesKey * 902295367Sdesget_hostkey_private_by_type(int type, int nid, struct ssh *ssh) 903204917Sdes{ 904295367Sdes return get_hostkey_by_type(type, nid, 1, ssh); 905204917Sdes} 906204917Sdes 907204917SdesKey * 90898684Sdesget_hostkey_by_index(int ind) 90998684Sdes{ 91098684Sdes if (ind < 0 || ind >= options.num_host_key_files) 91198684Sdes return (NULL); 91298684Sdes return (sensitive_data.host_keys[ind]); 91398684Sdes} 91498684Sdes 915255767SdesKey * 916295367Sdesget_hostkey_public_by_index(int ind, struct ssh *ssh) 917255767Sdes{ 918255767Sdes if (ind < 0 || ind >= options.num_host_key_files) 919255767Sdes return (NULL); 920255767Sdes return (sensitive_data.host_pubkeys[ind]); 921255767Sdes} 922255767Sdes 92398684Sdesint 924295367Sdesget_hostkey_index(Key *key, int compare, struct ssh *ssh) 92598684Sdes{ 92698684Sdes int i; 92799063Sdes 92898684Sdes for (i = 0; i < options.num_host_key_files; i++) { 929204917Sdes if (key_is_cert(key)) { 930295367Sdes if (key == sensitive_data.host_certificates[i] || 931295367Sdes (compare && sensitive_data.host_certificates[i] && 932295367Sdes sshkey_equal(key, 933295367Sdes sensitive_data.host_certificates[i]))) 934204917Sdes return (i); 935204917Sdes } else { 936295367Sdes if (key == sensitive_data.host_keys[i] || 937295367Sdes (compare && sensitive_data.host_keys[i] && 938295367Sdes sshkey_equal(key, sensitive_data.host_keys[i]))) 939204917Sdes return (i); 940295367Sdes if (key == sensitive_data.host_pubkeys[i] || 941295367Sdes (compare && sensitive_data.host_pubkeys[i] && 942295367Sdes sshkey_equal(key, sensitive_data.host_pubkeys[i]))) 943255767Sdes return (i); 944204917Sdes } 94598684Sdes } 94698684Sdes return (-1); 94798684Sdes} 94898684Sdes 949295367Sdes/* Inform the client of all hostkeys */ 950295367Sdesstatic void 951295367Sdesnotify_hostkeys(struct ssh *ssh) 952295367Sdes{ 953295367Sdes struct sshbuf *buf; 954295367Sdes struct sshkey *key; 955295367Sdes int i, nkeys, r; 956295367Sdes char *fp; 957295367Sdes 958295367Sdes /* Some clients cannot cope with the hostkeys message, skip those. */ 959295367Sdes if (datafellows & SSH_BUG_HOSTKEYS) 960295367Sdes return; 961295367Sdes 962295367Sdes if ((buf = sshbuf_new()) == NULL) 963295367Sdes fatal("%s: sshbuf_new", __func__); 964295367Sdes for (i = nkeys = 0; i < options.num_host_key_files; i++) { 965295367Sdes key = get_hostkey_public_by_index(i, ssh); 966295367Sdes if (key == NULL || key->type == KEY_UNSPEC || 967295367Sdes key->type == KEY_RSA1 || sshkey_is_cert(key)) 968295367Sdes continue; 969295367Sdes fp = sshkey_fingerprint(key, options.fingerprint_hash, 970295367Sdes SSH_FP_DEFAULT); 971295367Sdes debug3("%s: key %d: %s %s", __func__, i, 972295367Sdes sshkey_ssh_name(key), fp); 973295367Sdes free(fp); 974295367Sdes if (nkeys == 0) { 975295367Sdes packet_start(SSH2_MSG_GLOBAL_REQUEST); 976295367Sdes packet_put_cstring("hostkeys-00@openssh.com"); 977295367Sdes packet_put_char(0); /* want-reply */ 978295367Sdes } 979295367Sdes sshbuf_reset(buf); 980295367Sdes if ((r = sshkey_putb(key, buf)) != 0) 981295367Sdes fatal("%s: couldn't put hostkey %d: %s", 982295367Sdes __func__, i, ssh_err(r)); 983295367Sdes packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); 984295367Sdes nkeys++; 985295367Sdes } 986295367Sdes debug3("%s: sent %d hostkeys", __func__, nkeys); 987295367Sdes if (nkeys == 0) 988295367Sdes fatal("%s: no hostkeys", __func__); 989295367Sdes packet_send(); 990295367Sdes sshbuf_free(buf); 991295367Sdes} 992295367Sdes 99357429Smarkm/* 99465674Skris * returns 1 if connection should be dropped, 0 otherwise. 99565674Skris * dropping starts at connection #max_startups_begin with a probability 99665674Skris * of (max_startups_rate/100). the probability increases linearly until 99765674Skris * all connections are dropped for startups > max_startups 99865674Skris */ 99992559Sdesstatic int 100065674Skrisdrop_connection(int startups) 100165674Skris{ 1002147005Sdes int p, r; 100365674Skris 100465674Skris if (startups < options.max_startups_begin) 100565674Skris return 0; 100665674Skris if (startups >= options.max_startups) 100765674Skris return 1; 100865674Skris if (options.max_startups_rate == 100) 100965674Skris return 1; 101065674Skris 101165674Skris p = 100 - options.max_startups_rate; 101265674Skris p *= startups - options.max_startups_begin; 1013147005Sdes p /= options.max_startups - options.max_startups_begin; 101465674Skris p += options.max_startups_rate; 1015181111Sdes r = arc4random_uniform(100); 101665674Skris 1017147005Sdes debug("drop_connection: p %d, r %d", p, r); 101865674Skris return (r < p) ? 1 : 0; 101965674Skris} 102065674Skris 102192559Sdesstatic void 102292559Sdesusage(void) 102392559Sdes{ 1024240075Sdes if (options.version_addendum && *options.version_addendum != '\0') 1025294693Sdes fprintf(stderr, "%s %s, %s\n", 1026294693Sdes SSH_RELEASE, 1027295367Sdes options.version_addendum, OPENSSL_VERSION); 1028240075Sdes else 1029294693Sdes fprintf(stderr, "%s, %s\n", 1030295367Sdes SSH_RELEASE, OPENSSL_VERSION); 1031128460Sdes fprintf(stderr, 1032204917Sdes"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" 1033255767Sdes" [-E log_file] [-f config_file] [-g login_grace_time]\n" 1034255767Sdes" [-h host_key_file] [-k key_gen_time] [-o option] [-p port]\n" 1035255767Sdes" [-u len]\n" 1036128460Sdes ); 103792559Sdes exit(1); 103892559Sdes} 103965674Skris 1040137019Sdesstatic void 1041137019Sdessend_rexec_state(int fd, Buffer *conf) 1042137019Sdes{ 1043137019Sdes Buffer m; 1044137019Sdes 1045137019Sdes debug3("%s: entering fd = %d config len %d", __func__, fd, 1046137019Sdes buffer_len(conf)); 1047137019Sdes 1048137019Sdes /* 1049137019Sdes * Protocol from reexec master to child: 1050137019Sdes * string configuration 1051137019Sdes * u_int ephemeral_key_follows 1052137019Sdes * bignum e (only if ephemeral_key_follows == 1) 1053137019Sdes * bignum n " 1054137019Sdes * bignum d " 1055137019Sdes * bignum iqmp " 1056137019Sdes * bignum p " 1057137019Sdes * bignum q " 1058157019Sdes * string rngseed (only if OpenSSL is not self-seeded) 1059137019Sdes */ 1060137019Sdes buffer_init(&m); 1061137019Sdes buffer_put_cstring(&m, buffer_ptr(conf)); 1062137019Sdes 1063295367Sdes#ifdef WITH_SSH1 1064137019Sdes if (sensitive_data.server_key != NULL && 1065137019Sdes sensitive_data.server_key->type == KEY_RSA1) { 1066137019Sdes buffer_put_int(&m, 1); 1067137019Sdes buffer_put_bignum(&m, sensitive_data.server_key->rsa->e); 1068137019Sdes buffer_put_bignum(&m, sensitive_data.server_key->rsa->n); 1069137019Sdes buffer_put_bignum(&m, sensitive_data.server_key->rsa->d); 1070137019Sdes buffer_put_bignum(&m, sensitive_data.server_key->rsa->iqmp); 1071137019Sdes buffer_put_bignum(&m, sensitive_data.server_key->rsa->p); 1072137019Sdes buffer_put_bignum(&m, sensitive_data.server_key->rsa->q); 1073137019Sdes } else 1074295367Sdes#endif 1075137019Sdes buffer_put_int(&m, 0); 1076137019Sdes 1077295367Sdes#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) 1078157019Sdes rexec_send_rng_seed(&m); 1079157019Sdes#endif 1080157019Sdes 1081137019Sdes if (ssh_msg_send(fd, 0, &m) == -1) 1082137019Sdes fatal("%s: ssh_msg_send failed", __func__); 1083137019Sdes 1084137019Sdes buffer_free(&m); 1085137019Sdes 1086137019Sdes debug3("%s: done", __func__); 1087137019Sdes} 1088137019Sdes 1089137019Sdesstatic void 1090137019Sdesrecv_rexec_state(int fd, Buffer *conf) 1091137019Sdes{ 1092137019Sdes Buffer m; 1093137019Sdes char *cp; 1094137019Sdes u_int len; 1095137019Sdes 1096137019Sdes debug3("%s: entering fd = %d", __func__, fd); 1097137019Sdes 1098137019Sdes buffer_init(&m); 1099137019Sdes 1100137019Sdes if (ssh_msg_recv(fd, &m) == -1) 1101137019Sdes fatal("%s: ssh_msg_recv failed", __func__); 1102137019Sdes if (buffer_get_char(&m) != 0) 1103137019Sdes fatal("%s: rexec version mismatch", __func__); 1104137019Sdes 1105137019Sdes cp = buffer_get_string(&m, &len); 1106137019Sdes if (conf != NULL) 1107137019Sdes buffer_append(conf, cp, len + 1); 1108255767Sdes free(cp); 1109137019Sdes 1110137019Sdes if (buffer_get_int(&m)) { 1111295367Sdes#ifdef WITH_SSH1 1112137019Sdes if (sensitive_data.server_key != NULL) 1113137019Sdes key_free(sensitive_data.server_key); 1114137019Sdes sensitive_data.server_key = key_new_private(KEY_RSA1); 1115137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->e); 1116137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->n); 1117137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->d); 1118137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); 1119137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); 1120137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); 1121295367Sdes if (rsa_generate_additional_parameters( 1122295367Sdes sensitive_data.server_key->rsa) != 0) 1123295367Sdes fatal("%s: rsa_generate_additional_parameters " 1124295367Sdes "error", __func__); 1125295367Sdes#endif 1126137019Sdes } 1127157019Sdes 1128295367Sdes#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) 1129157019Sdes rexec_recv_rng_seed(&m); 1130157019Sdes#endif 1131157019Sdes 1132137019Sdes buffer_free(&m); 1133137019Sdes 1134137019Sdes debug3("%s: done", __func__); 1135137019Sdes} 1136137019Sdes 1137162856Sdes/* Accept a connection from inetd */ 1138162856Sdesstatic void 1139162856Sdesserver_accept_inetd(int *sock_in, int *sock_out) 1140162856Sdes{ 1141162856Sdes int fd; 1142162856Sdes 1143162856Sdes startup_pipe = -1; 1144162856Sdes if (rexeced_flag) { 1145162856Sdes close(REEXEC_CONFIG_PASS_FD); 1146162856Sdes *sock_in = *sock_out = dup(STDIN_FILENO); 1147162856Sdes if (!debug_flag) { 1148162856Sdes startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); 1149162856Sdes close(REEXEC_STARTUP_PIPE_FD); 1150162856Sdes } 1151162856Sdes } else { 1152162856Sdes *sock_in = dup(STDIN_FILENO); 1153162856Sdes *sock_out = dup(STDOUT_FILENO); 1154162856Sdes } 1155162856Sdes /* 1156162856Sdes * We intentionally do not close the descriptors 0, 1, and 2 1157162856Sdes * as our code for setting the descriptors won't work if 1158162856Sdes * ttyfd happens to be one of those. 1159162856Sdes */ 1160162856Sdes if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 1161162856Sdes dup2(fd, STDIN_FILENO); 1162162856Sdes dup2(fd, STDOUT_FILENO); 1163255767Sdes if (!log_stderr) 1164255767Sdes dup2(fd, STDERR_FILENO); 1165255767Sdes if (fd > (log_stderr ? STDERR_FILENO : STDOUT_FILENO)) 1166162856Sdes close(fd); 1167162856Sdes } 1168162856Sdes debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out); 1169162856Sdes} 1170162856Sdes 117165674Skris/* 1172162856Sdes * Listen for TCP connections 1173162856Sdes */ 1174162856Sdesstatic void 1175162856Sdesserver_listen(void) 1176162856Sdes{ 1177162856Sdes int ret, listen_sock, on = 1; 1178162856Sdes struct addrinfo *ai; 1179162856Sdes char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 1180224638Sbrooks int socksize; 1181224638Sbrooks socklen_t len; 1182162856Sdes 1183162856Sdes for (ai = options.listen_addrs; ai; ai = ai->ai_next) { 1184162856Sdes if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 1185162856Sdes continue; 1186162856Sdes if (num_listen_socks >= MAX_LISTEN_SOCKS) 1187162856Sdes fatal("Too many listen sockets. " 1188162856Sdes "Enlarge MAX_LISTEN_SOCKS"); 1189162856Sdes if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, 1190162856Sdes ntop, sizeof(ntop), strport, sizeof(strport), 1191162856Sdes NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 1192162856Sdes error("getnameinfo failed: %.100s", 1193181111Sdes ssh_gai_strerror(ret)); 1194162856Sdes continue; 1195162856Sdes } 1196162856Sdes /* Create socket for listening. */ 1197162856Sdes listen_sock = socket(ai->ai_family, ai->ai_socktype, 1198162856Sdes ai->ai_protocol); 1199162856Sdes if (listen_sock < 0) { 1200162856Sdes /* kernel may not support ipv6 */ 1201162856Sdes verbose("socket: %.100s", strerror(errno)); 1202162856Sdes continue; 1203162856Sdes } 1204162856Sdes if (set_nonblock(listen_sock) == -1) { 1205162856Sdes close(listen_sock); 1206162856Sdes continue; 1207162856Sdes } 1208162856Sdes /* 1209162856Sdes * Set socket options. 1210162856Sdes * Allow local port reuse in TIME_WAIT. 1211162856Sdes */ 1212162856Sdes if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, 1213162856Sdes &on, sizeof(on)) == -1) 1214162856Sdes error("setsockopt SO_REUSEADDR: %s", strerror(errno)); 1215162856Sdes 1216181111Sdes /* Only communicate in IPv6 over AF_INET6 sockets. */ 1217204917Sdes if (ai->ai_family == AF_INET6) 1218204917Sdes sock_set_v6only(listen_sock); 1219181111Sdes 1220162856Sdes debug("Bind to port %s on %s.", strport, ntop); 1221162856Sdes 1222224638Sbrooks len = sizeof(socksize); 1223224638Sbrooks getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &socksize, &len); 1224224638Sbrooks debug("Server TCP RWIN socket size: %d", socksize); 1225224638Sbrooks 1226162856Sdes /* Bind the socket to the desired port. */ 1227162856Sdes if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { 1228162856Sdes error("Bind to port %s on %s failed: %.200s.", 1229162856Sdes strport, ntop, strerror(errno)); 1230162856Sdes close(listen_sock); 1231162856Sdes continue; 1232162856Sdes } 1233162856Sdes listen_socks[num_listen_socks] = listen_sock; 1234162856Sdes num_listen_socks++; 1235162856Sdes 1236162856Sdes /* Start listening on the port. */ 1237162856Sdes if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0) 1238162856Sdes fatal("listen on [%s]:%s: %.100s", 1239162856Sdes ntop, strport, strerror(errno)); 1240162856Sdes logit("Server listening on %s port %s.", ntop, strport); 1241162856Sdes } 1242162856Sdes freeaddrinfo(options.listen_addrs); 1243162856Sdes 1244162856Sdes if (!num_listen_socks) 1245162856Sdes fatal("Cannot bind any address."); 1246162856Sdes} 1247162856Sdes 1248162856Sdes/* 1249162856Sdes * The main TCP accept loop. Note that, for the non-debug case, returns 1250162856Sdes * from this function are in a forked subprocess. 1251162856Sdes */ 1252162856Sdesstatic void 1253162856Sdesserver_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) 1254162856Sdes{ 1255162856Sdes fd_set *fdset; 1256162856Sdes int i, j, ret, maxfd; 1257162856Sdes int key_used = 0, startups = 0; 1258162856Sdes int startup_p[2] = { -1 , -1 }; 1259162856Sdes struct sockaddr_storage from; 1260162856Sdes socklen_t fromlen; 1261162856Sdes pid_t pid; 1262262566Sdes u_char rnd[256]; 1263162856Sdes 1264162856Sdes /* setup fd set for accept */ 1265162856Sdes fdset = NULL; 1266162856Sdes maxfd = 0; 1267162856Sdes for (i = 0; i < num_listen_socks; i++) 1268162856Sdes if (listen_socks[i] > maxfd) 1269162856Sdes maxfd = listen_socks[i]; 1270162856Sdes /* pipes connected to unauthenticated childs */ 1271162856Sdes startup_pipes = xcalloc(options.max_startups, sizeof(int)); 1272162856Sdes for (i = 0; i < options.max_startups; i++) 1273162856Sdes startup_pipes[i] = -1; 1274162856Sdes 1275162856Sdes /* 1276162856Sdes * Stay listening for connections until the system crashes or 1277162856Sdes * the daemon is killed with a signal. 1278162856Sdes */ 1279162856Sdes for (;;) { 1280162856Sdes if (received_sighup) 1281162856Sdes sighup_restart(); 1282296853Sdes free(fdset); 1283295367Sdes fdset = xcalloc(howmany(maxfd + 1, NFDBITS), 1284162856Sdes sizeof(fd_mask)); 1285162856Sdes 1286162856Sdes for (i = 0; i < num_listen_socks; i++) 1287162856Sdes FD_SET(listen_socks[i], fdset); 1288162856Sdes for (i = 0; i < options.max_startups; i++) 1289162856Sdes if (startup_pipes[i] != -1) 1290162856Sdes FD_SET(startup_pipes[i], fdset); 1291162856Sdes 1292162856Sdes /* Wait in select until there is a connection. */ 1293162856Sdes ret = select(maxfd+1, fdset, NULL, NULL, NULL); 1294162856Sdes if (ret < 0 && errno != EINTR) 1295162856Sdes error("select: %.100s", strerror(errno)); 1296162856Sdes if (received_sigterm) { 1297162856Sdes logit("Received signal %d; terminating.", 1298162856Sdes (int) received_sigterm); 1299162856Sdes close_listen_socks(); 1300295367Sdes if (options.pid_file != NULL) 1301295367Sdes unlink(options.pid_file); 1302226046Sdes exit(received_sigterm == SIGTERM ? 0 : 255); 1303162856Sdes } 1304162856Sdes if (key_used && key_do_regen) { 1305162856Sdes generate_ephemeral_server_key(); 1306162856Sdes key_used = 0; 1307162856Sdes key_do_regen = 0; 1308162856Sdes } 1309162856Sdes if (ret < 0) 1310162856Sdes continue; 1311162856Sdes 1312162856Sdes for (i = 0; i < options.max_startups; i++) 1313162856Sdes if (startup_pipes[i] != -1 && 1314162856Sdes FD_ISSET(startup_pipes[i], fdset)) { 1315162856Sdes /* 1316162856Sdes * the read end of the pipe is ready 1317162856Sdes * if the child has closed the pipe 1318162856Sdes * after successful authentication 1319162856Sdes * or if the child has died 1320162856Sdes */ 1321162856Sdes close(startup_pipes[i]); 1322162856Sdes startup_pipes[i] = -1; 1323162856Sdes startups--; 1324162856Sdes } 1325162856Sdes for (i = 0; i < num_listen_socks; i++) { 1326162856Sdes if (!FD_ISSET(listen_socks[i], fdset)) 1327162856Sdes continue; 1328162856Sdes fromlen = sizeof(from); 1329162856Sdes *newsock = accept(listen_socks[i], 1330162856Sdes (struct sockaddr *)&from, &fromlen); 1331162856Sdes if (*newsock < 0) { 1332255767Sdes if (errno != EINTR && errno != EWOULDBLOCK && 1333255767Sdes errno != ECONNABORTED && errno != EAGAIN) 1334240075Sdes error("accept: %.100s", 1335240075Sdes strerror(errno)); 1336240075Sdes if (errno == EMFILE || errno == ENFILE) 1337240075Sdes usleep(100 * 1000); 1338162856Sdes continue; 1339162856Sdes } 1340162856Sdes if (unset_nonblock(*newsock) == -1) { 1341162856Sdes close(*newsock); 1342162856Sdes continue; 1343162856Sdes } 1344162856Sdes if (drop_connection(startups) == 1) { 1345162856Sdes debug("drop connection #%d", startups); 1346162856Sdes close(*newsock); 1347162856Sdes continue; 1348162856Sdes } 1349162856Sdes if (pipe(startup_p) == -1) { 1350162856Sdes close(*newsock); 1351162856Sdes continue; 1352162856Sdes } 1353162856Sdes 1354162856Sdes if (rexec_flag && socketpair(AF_UNIX, 1355162856Sdes SOCK_STREAM, 0, config_s) == -1) { 1356162856Sdes error("reexec socketpair: %s", 1357162856Sdes strerror(errno)); 1358162856Sdes close(*newsock); 1359162856Sdes close(startup_p[0]); 1360162856Sdes close(startup_p[1]); 1361162856Sdes continue; 1362162856Sdes } 1363162856Sdes 1364162856Sdes for (j = 0; j < options.max_startups; j++) 1365162856Sdes if (startup_pipes[j] == -1) { 1366162856Sdes startup_pipes[j] = startup_p[0]; 1367162856Sdes if (maxfd < startup_p[0]) 1368162856Sdes maxfd = startup_p[0]; 1369162856Sdes startups++; 1370162856Sdes break; 1371162856Sdes } 1372162856Sdes 1373162856Sdes /* 1374162856Sdes * Got connection. Fork a child to handle it, unless 1375162856Sdes * we are in debugging mode. 1376162856Sdes */ 1377162856Sdes if (debug_flag) { 1378162856Sdes /* 1379162856Sdes * In debugging mode. Close the listening 1380162856Sdes * socket, and start processing the 1381162856Sdes * connection without forking. 1382162856Sdes */ 1383162856Sdes debug("Server will not fork when running in debugging mode."); 1384162856Sdes close_listen_socks(); 1385162856Sdes *sock_in = *newsock; 1386162856Sdes *sock_out = *newsock; 1387162856Sdes close(startup_p[0]); 1388162856Sdes close(startup_p[1]); 1389162856Sdes startup_pipe = -1; 1390162856Sdes pid = getpid(); 1391162856Sdes if (rexec_flag) { 1392162856Sdes send_rexec_state(config_s[0], 1393162856Sdes &cfg); 1394162856Sdes close(config_s[0]); 1395162856Sdes } 1396162856Sdes break; 1397162856Sdes } 1398162856Sdes 1399162856Sdes /* 1400162856Sdes * Normal production daemon. Fork, and have 1401162856Sdes * the child process the connection. The 1402162856Sdes * parent continues listening. 1403162856Sdes */ 1404162856Sdes platform_pre_fork(); 1405162856Sdes if ((pid = fork()) == 0) { 1406162856Sdes /* 1407162856Sdes * Child. Close the listening and 1408162856Sdes * max_startup sockets. Start using 1409162856Sdes * the accepted socket. Reinitialize 1410162856Sdes * logging (since our pid has changed). 1411162856Sdes * We break out of the loop to handle 1412162856Sdes * the connection. 1413162856Sdes */ 1414162856Sdes platform_post_fork_child(); 1415162856Sdes startup_pipe = startup_p[1]; 1416162856Sdes close_startup_pipes(); 1417162856Sdes close_listen_socks(); 1418162856Sdes *sock_in = *newsock; 1419162856Sdes *sock_out = *newsock; 1420162856Sdes log_init(__progname, 1421162856Sdes options.log_level, 1422162856Sdes options.log_facility, 1423162856Sdes log_stderr); 1424162856Sdes if (rexec_flag) 1425162856Sdes close(config_s[0]); 1426162856Sdes break; 1427162856Sdes } 1428162856Sdes 1429162856Sdes /* Parent. Stay in the loop. */ 1430162856Sdes platform_post_fork_parent(pid); 1431162856Sdes if (pid < 0) 1432162856Sdes error("fork: %.100s", strerror(errno)); 1433162856Sdes else 1434162856Sdes debug("Forked child %ld.", (long)pid); 1435162856Sdes 1436162856Sdes close(startup_p[1]); 1437162856Sdes 1438162856Sdes if (rexec_flag) { 1439162856Sdes send_rexec_state(config_s[0], &cfg); 1440162856Sdes close(config_s[0]); 1441162856Sdes close(config_s[1]); 1442162856Sdes } 1443162856Sdes 1444162856Sdes /* 1445162856Sdes * Mark that the key has been used (it 1446162856Sdes * was "given" to the child). 1447162856Sdes */ 1448162856Sdes if ((options.protocol & SSH_PROTO_1) && 1449162856Sdes key_used == 0) { 1450162856Sdes /* Schedule server key regeneration alarm. */ 1451162856Sdes signal(SIGALRM, key_regeneration_alarm); 1452162856Sdes alarm(options.key_regeneration_time); 1453162856Sdes key_used = 1; 1454162856Sdes } 1455162856Sdes 1456162856Sdes close(*newsock); 1457162856Sdes 1458162856Sdes /* 1459162856Sdes * Ensure that our random state differs 1460162856Sdes * from that of the child 1461162856Sdes */ 1462162856Sdes arc4random_stir(); 1463262566Sdes arc4random_buf(rnd, sizeof(rnd)); 1464295367Sdes#ifdef WITH_OPENSSL 1465262566Sdes RAND_seed(rnd, sizeof(rnd)); 1466295367Sdes if ((RAND_bytes((u_char *)rnd, 1)) != 1) 1467295367Sdes fatal("%s: RAND_bytes failed", __func__); 1468295367Sdes#endif 1469264377Sdes explicit_bzero(rnd, sizeof(rnd)); 1470162856Sdes } 1471162856Sdes 1472162856Sdes /* child process check (or debug mode) */ 1473162856Sdes if (num_listen_socks < 0) 1474162856Sdes break; 1475162856Sdes } 1476162856Sdes} 1477162856Sdes 1478162856Sdes 1479162856Sdes/* 148057429Smarkm * Main program for the daemon. 148157429Smarkm */ 148257429Smarkmint 148357429Smarkmmain(int ac, char **av) 148457429Smarkm{ 148557429Smarkm extern char *optarg; 148657429Smarkm extern int optind; 1487295367Sdes int r, opt, i, j, on = 1; 1488137019Sdes int sock_in = -1, sock_out = -1, newsock = -1; 148957429Smarkm const char *remote_ip; 149057429Smarkm int remote_port; 1491295367Sdes char *fp, *line, *laddr, *logfile = NULL; 1492162856Sdes int config_s[2] = { -1 , -1 }; 1493248619Sdes u_int n; 1494181111Sdes u_int64_t ibytes, obytes; 1495181111Sdes mode_t new_umask; 1496126277Sdes Key *key; 1497255767Sdes Key *pubkey; 1498255767Sdes int keytype; 149998684Sdes Authctxt *authctxt; 1500240075Sdes struct connection_info *connection_info = get_connection_info(0, 0); 150157429Smarkm 1502296853Sdes ssh_malloc_init(); /* must be called before any mallocs */ 1503296853Sdes 150498941Sdes#ifdef HAVE_SECUREWARE 150598941Sdes (void)set_auth_parameters(ac, av); 150698941Sdes#endif 1507124211Sdes __progname = ssh_get_progname(av[0]); 150898941Sdes 1509113911Sdes /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ 151098941Sdes saved_argc = ac; 1511137019Sdes rexec_argc = ac; 1512162856Sdes saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); 1513113911Sdes for (i = 0; i < ac; i++) 1514113911Sdes saved_argv[i] = xstrdup(av[i]); 1515124211Sdes saved_argv[i] = NULL; 151657429Smarkm 1517113911Sdes#ifndef HAVE_SETPROCTITLE 1518113911Sdes /* Prepare for later setproctitle emulation */ 1519113911Sdes compat_init_setproctitle(ac, av); 1520124211Sdes av = saved_argv; 1521113911Sdes#endif 1522113911Sdes 1523128460Sdes if (geteuid() == 0 && setgroups(0, NULL) == -1) 1524128460Sdes debug("setgroups(): %.200s", strerror(errno)); 1525128460Sdes 1526157019Sdes /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1527157019Sdes sanitise_stdfd(); 1528157019Sdes 152957429Smarkm /* Initialize configuration options to their default values. */ 153057429Smarkm initialize_server_options(&options); 153157429Smarkm 153257429Smarkm /* Parse command-line arguments. */ 1533295367Sdes while ((opt = getopt(ac, av, 1534295367Sdes "C:E:b:c:f:g:h:k:o:p:u:46DQRTdeiqrt")) != -1) { 153557429Smarkm switch (opt) { 153657429Smarkm case '4': 1537147005Sdes options.address_family = AF_INET; 153857429Smarkm break; 153957429Smarkm case '6': 1540147005Sdes options.address_family = AF_INET6; 154157429Smarkm break; 154257429Smarkm case 'f': 154357429Smarkm config_file_name = optarg; 154457429Smarkm break; 1545204917Sdes case 'c': 1546204917Sdes if (options.num_host_cert_files >= MAX_HOSTCERTS) { 1547204917Sdes fprintf(stderr, "too many host certificates.\n"); 1548204917Sdes exit(1); 1549204917Sdes } 1550204917Sdes options.host_cert_files[options.num_host_cert_files++] = 1551204917Sdes derelativise_path(optarg); 1552204917Sdes break; 155357429Smarkm case 'd': 1554124211Sdes if (debug_flag == 0) { 155569591Sgreen debug_flag = 1; 155669591Sgreen options.log_level = SYSLOG_LEVEL_DEBUG1; 1557124211Sdes } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) 155869591Sgreen options.log_level++; 155957429Smarkm break; 156076262Sgreen case 'D': 156176262Sgreen no_daemon_flag = 1; 156276262Sgreen break; 1563255767Sdes case 'E': 1564296853Sdes logfile = optarg; 1565255767Sdes /* FALLTHROUGH */ 156676262Sgreen case 'e': 156776262Sgreen log_stderr = 1; 156876262Sgreen break; 156957429Smarkm case 'i': 157057429Smarkm inetd_flag = 1; 157157429Smarkm break; 1572137019Sdes case 'r': 1573137019Sdes rexec_flag = 0; 1574137019Sdes break; 1575137019Sdes case 'R': 1576137019Sdes rexeced_flag = 1; 1577137019Sdes inetd_flag = 1; 1578137019Sdes break; 157957429Smarkm case 'Q': 158076262Sgreen /* ignored */ 158157429Smarkm break; 158257429Smarkm case 'q': 158357429Smarkm options.log_level = SYSLOG_LEVEL_QUIET; 158457429Smarkm break; 158557429Smarkm case 'b': 1586162856Sdes options.server_key_bits = (int)strtonum(optarg, 256, 1587162856Sdes 32768, NULL); 158857429Smarkm break; 158957429Smarkm case 'p': 159057429Smarkm options.ports_from_cmdline = 1; 159169591Sgreen if (options.num_ports >= MAX_PORTS) { 159269591Sgreen fprintf(stderr, "too many ports.\n"); 159369591Sgreen exit(1); 159469591Sgreen } 159576262Sgreen options.ports[options.num_ports++] = a2port(optarg); 1596192595Sdes if (options.ports[options.num_ports-1] <= 0) { 159776262Sgreen fprintf(stderr, "Bad port number.\n"); 159876262Sgreen exit(1); 159976262Sgreen } 160057429Smarkm break; 160157429Smarkm case 'g': 160292559Sdes if ((options.login_grace_time = convtime(optarg)) == -1) { 160392559Sdes fprintf(stderr, "Invalid login grace time.\n"); 160492559Sdes exit(1); 160592559Sdes } 160657429Smarkm break; 160757429Smarkm case 'k': 160892559Sdes if ((options.key_regeneration_time = convtime(optarg)) == -1) { 160992559Sdes fprintf(stderr, "Invalid key regeneration interval.\n"); 161092559Sdes exit(1); 161192559Sdes } 161257429Smarkm break; 161357429Smarkm case 'h': 161476262Sgreen if (options.num_host_key_files >= MAX_HOSTKEYS) { 161576262Sgreen fprintf(stderr, "too many host keys.\n"); 161676262Sgreen exit(1); 161776262Sgreen } 1618204917Sdes options.host_key_files[options.num_host_key_files++] = 1619204917Sdes derelativise_path(optarg); 162057429Smarkm break; 162192559Sdes case 't': 162292559Sdes test_flag = 1; 162392559Sdes break; 1624181111Sdes case 'T': 1625181111Sdes test_flag = 2; 1626181111Sdes break; 1627181111Sdes case 'C': 1628240075Sdes if (parse_server_match_testspec(connection_info, 1629240075Sdes optarg) == -1) 1630240075Sdes exit(1); 1631181111Sdes break; 163265674Skris case 'u': 1633295367Sdes utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); 1634295367Sdes if (utmp_len > HOST_NAME_MAX+1) { 1635106130Sdes fprintf(stderr, "Invalid utmp length.\n"); 1636106130Sdes exit(1); 1637106130Sdes } 163865674Skris break; 163992559Sdes case 'o': 1640126277Sdes line = xstrdup(optarg); 1641126277Sdes if (process_server_config_line(&options, line, 1642240075Sdes "command-line", 0, NULL, NULL) != 0) 164392559Sdes exit(1); 1644255767Sdes free(line); 164592559Sdes break; 164657429Smarkm case '?': 164757429Smarkm default: 164892559Sdes usage(); 164992559Sdes break; 165057429Smarkm } 165157429Smarkm } 1652137019Sdes if (rexeced_flag || inetd_flag) 1653137019Sdes rexec_flag = 0; 1654181111Sdes if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/'))) 1655137019Sdes fatal("sshd re-exec requires execution with an absolute path"); 1656137019Sdes if (rexeced_flag) 1657137019Sdes closefrom(REEXEC_MIN_FREE_FD); 1658137019Sdes else 1659137019Sdes closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); 1660137019Sdes 1661295367Sdes#ifdef WITH_OPENSSL 1662221420Sdes OpenSSL_add_all_algorithms(); 1663295367Sdes#endif 166457429Smarkm 1665255767Sdes /* If requested, redirect the logs to the specified logfile. */ 1666296853Sdes if (logfile != NULL) 1667255767Sdes log_redirect_stderr_to(logfile); 166857429Smarkm /* 166957429Smarkm * Force logging to stderr until we have loaded the private host 167057429Smarkm * key (unless started from inetd) 167157429Smarkm */ 167276262Sgreen log_init(__progname, 167392559Sdes options.log_level == SYSLOG_LEVEL_NOT_SET ? 167492559Sdes SYSLOG_LEVEL_INFO : options.log_level, 167592559Sdes options.log_facility == SYSLOG_FACILITY_NOT_SET ? 167692559Sdes SYSLOG_FACILITY_AUTH : options.log_facility, 1677113911Sdes log_stderr || !inetd_flag); 167857429Smarkm 1679128460Sdes /* 1680128460Sdes * Unset KRB5CCNAME, otherwise the user's session may inherit it from 1681128460Sdes * root's environment 1682149753Sdes */ 1683147005Sdes if (getenv("KRB5CCNAME") != NULL) 1684240075Sdes (void) unsetenv("KRB5CCNAME"); 1685147005Sdes 1686106130Sdes#ifdef _UNICOS 1687137019Sdes /* Cray can define user privs drop all privs now! 168898941Sdes * Not needed on PRIV_SU systems! 168998941Sdes */ 169098941Sdes drop_cray_privs(); 169198941Sdes#endif 169298941Sdes 1693137019Sdes sensitive_data.server_key = NULL; 1694137019Sdes sensitive_data.ssh1_host_key = NULL; 1695137019Sdes sensitive_data.have_ssh1_key = 0; 1696137019Sdes sensitive_data.have_ssh2_key = 0; 169757429Smarkm 1698181111Sdes /* 1699181111Sdes * If we're doing an extended config test, make sure we have all of 1700181111Sdes * the parameters we need. If we're not doing an extended test, 1701181111Sdes * do not silently ignore connection test params. 1702181111Sdes */ 1703240075Sdes if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0) 1704181111Sdes fatal("user, host and addr are all required when testing " 1705181111Sdes "Match configs"); 1706240075Sdes if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0) 1707181111Sdes fatal("Config test connection parameter (-C) provided without " 1708181111Sdes "test mode (-T)"); 1709181111Sdes 1710137019Sdes /* Fetch our configuration */ 1711137019Sdes buffer_init(&cfg); 1712137019Sdes if (rexeced_flag) 1713137019Sdes recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg); 1714295367Sdes else if (strcasecmp(config_file_name, "none") != 0) 1715137019Sdes load_server_config(config_file_name, &cfg); 1716137019Sdes 1717162856Sdes parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, 1718240075Sdes &cfg, NULL); 1719137019Sdes 1720157019Sdes seed_rng(); 1721157019Sdes 172257429Smarkm /* Fill in default values for those options not explicitly set. */ 172357429Smarkm fill_default_server_options(&options); 172457429Smarkm 1725181111Sdes /* challenge-response is implemented via keyboard interactive */ 1726181111Sdes if (options.challenge_response_authentication) 1727181111Sdes options.kbd_interactive_authentication = 1; 1728181111Sdes 1729248619Sdes /* Check that options are sensible */ 1730248619Sdes if (options.authorized_keys_command_user == NULL && 1731248619Sdes (options.authorized_keys_command != NULL && 1732248619Sdes strcasecmp(options.authorized_keys_command, "none") != 0)) 1733248619Sdes fatal("AuthorizedKeysCommand set without " 1734248619Sdes "AuthorizedKeysCommandUser"); 1735295367Sdes if (options.authorized_principals_command_user == NULL && 1736295367Sdes (options.authorized_principals_command != NULL && 1737295367Sdes strcasecmp(options.authorized_principals_command, "none") != 0)) 1738295367Sdes fatal("AuthorizedPrincipalsCommand set without " 1739295367Sdes "AuthorizedPrincipalsCommandUser"); 1740248619Sdes 1741248619Sdes /* 1742248619Sdes * Check whether there is any path through configured auth methods. 1743248619Sdes * Unfortunately it is not possible to verify this generally before 1744248619Sdes * daemonisation in the presence of Match block, but this catches 1745248619Sdes * and warns for trivial misconfigurations that could break login. 1746248619Sdes */ 1747248619Sdes if (options.num_auth_methods != 0) { 1748248619Sdes if ((options.protocol & SSH_PROTO_1)) 1749248619Sdes fatal("AuthenticationMethods is not supported with " 1750248619Sdes "SSH protocol 1"); 1751248619Sdes for (n = 0; n < options.num_auth_methods; n++) { 1752248619Sdes if (auth2_methods_valid(options.auth_methods[n], 1753248619Sdes 1) == 0) 1754248619Sdes break; 1755248619Sdes } 1756248619Sdes if (n >= options.num_auth_methods) 1757248619Sdes fatal("AuthenticationMethods cannot be satisfied by " 1758248619Sdes "enabled authentication methods"); 1759248619Sdes } 1760248619Sdes 1761147005Sdes /* set default channel AF */ 1762147005Sdes channel_set_af(options.address_family); 1763147005Sdes 176457429Smarkm /* Check that there are no remaining arguments. */ 176557429Smarkm if (optind < ac) { 176657429Smarkm fprintf(stderr, "Extra argument %s.\n", av[optind]); 176757429Smarkm exit(1); 176857429Smarkm } 176957429Smarkm 1770294693Sdes debug("sshd version %s, %s", SSH_VERSION, 1771295367Sdes#ifdef WITH_OPENSSL 1772295367Sdes SSLeay_version(SSLEAY_VERSION) 1773295367Sdes#else 1774295367Sdes "without OpenSSL" 1775295367Sdes#endif 1776295367Sdes ); 177757429Smarkm 1778164149Sdes /* Store privilege separation user for later use if required. */ 1779164149Sdes if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { 1780164149Sdes if (use_privsep || options.kerberos_authentication) 1781164149Sdes fatal("Privilege separation user %s does not exist", 1782164149Sdes SSH_PRIVSEP_USER); 1783164149Sdes } else { 1784264377Sdes explicit_bzero(privsep_pw->pw_passwd, 1785264377Sdes strlen(privsep_pw->pw_passwd)); 1786164149Sdes privsep_pw = pwcopy(privsep_pw); 1787255767Sdes free(privsep_pw->pw_passwd); 1788164149Sdes privsep_pw->pw_passwd = xstrdup("*"); 1789164149Sdes } 1790162856Sdes endpwent(); 1791162856Sdes 1792255767Sdes /* load host keys */ 1793162856Sdes sensitive_data.host_keys = xcalloc(options.num_host_key_files, 1794106130Sdes sizeof(Key *)); 1795255767Sdes sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, 1796255767Sdes sizeof(Key *)); 179760576Skris 1798255767Sdes if (options.host_key_agent) { 1799255767Sdes if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) 1800255767Sdes setenv(SSH_AUTHSOCKET_ENV_NAME, 1801255767Sdes options.host_key_agent, 1); 1802295367Sdes if ((r = ssh_get_authentication_socket(NULL)) == 0) 1803295367Sdes have_agent = 1; 1804295367Sdes else 1805295367Sdes error("Could not connect to agent \"%s\": %s", 1806295367Sdes options.host_key_agent, ssh_err(r)); 1807255767Sdes } 1808255767Sdes 180992559Sdes for (i = 0; i < options.num_host_key_files; i++) { 1810295367Sdes if (options.host_key_files[i] == NULL) 1811295367Sdes continue; 181276262Sgreen key = key_load_private(options.host_key_files[i], "", NULL); 1813255767Sdes pubkey = key_load_public(options.host_key_files[i], NULL); 1814295367Sdes if (pubkey == NULL && key != NULL) 1815295367Sdes pubkey = key_demote(key); 181676262Sgreen sensitive_data.host_keys[i] = key; 1817255767Sdes sensitive_data.host_pubkeys[i] = pubkey; 1818255767Sdes 1819255767Sdes if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 && 1820255767Sdes have_agent) { 1821255767Sdes debug("will rely on agent for hostkey %s", 1822255767Sdes options.host_key_files[i]); 1823255767Sdes keytype = pubkey->type; 1824255767Sdes } else if (key != NULL) { 1825255767Sdes keytype = key->type; 1826255767Sdes } else { 182776262Sgreen error("Could not load host key: %s", 182876262Sgreen options.host_key_files[i]); 182976262Sgreen sensitive_data.host_keys[i] = NULL; 1830255767Sdes sensitive_data.host_pubkeys[i] = NULL; 183176262Sgreen continue; 183276262Sgreen } 1833255767Sdes 1834255767Sdes switch (keytype) { 183576262Sgreen case KEY_RSA1: 183676262Sgreen sensitive_data.ssh1_host_key = key; 183776262Sgreen sensitive_data.have_ssh1_key = 1; 183876262Sgreen break; 183976262Sgreen case KEY_RSA: 184076262Sgreen case KEY_DSA: 1841221420Sdes case KEY_ECDSA: 1842262566Sdes case KEY_ED25519: 1843295367Sdes if (have_agent || key != NULL) 1844295367Sdes sensitive_data.have_ssh2_key = 1; 184576262Sgreen break; 184676262Sgreen } 1847295367Sdes if ((fp = sshkey_fingerprint(pubkey, options.fingerprint_hash, 1848295367Sdes SSH_FP_DEFAULT)) == NULL) 1849295367Sdes fatal("sshkey_fingerprint failed"); 1850295367Sdes debug("%s host key #%d: %s %s", 1851295367Sdes key ? "private" : "agent", i, keytype == KEY_RSA1 ? 1852295367Sdes sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); 1853295367Sdes free(fp); 185476262Sgreen } 185576262Sgreen if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { 1856124211Sdes logit("Disabling protocol version 1. Could not load host key"); 185760576Skris options.protocol &= ~SSH_PROTO_1; 185860576Skris } 185976262Sgreen if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1860124211Sdes logit("Disabling protocol version 2. Could not load host key"); 186176262Sgreen options.protocol &= ~SSH_PROTO_2; 186260576Skris } 186376262Sgreen if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1864124211Sdes logit("sshd: no hostkeys available -- exiting."); 186557429Smarkm exit(1); 186657429Smarkm } 186757429Smarkm 1868204917Sdes /* 1869204917Sdes * Load certificates. They are stored in an array at identical 1870204917Sdes * indices to the public keys that they relate to. 1871204917Sdes */ 1872204917Sdes sensitive_data.host_certificates = xcalloc(options.num_host_key_files, 1873204917Sdes sizeof(Key *)); 1874204917Sdes for (i = 0; i < options.num_host_key_files; i++) 1875204917Sdes sensitive_data.host_certificates[i] = NULL; 1876204917Sdes 1877204917Sdes for (i = 0; i < options.num_host_cert_files; i++) { 1878295367Sdes if (options.host_cert_files[i] == NULL) 1879295367Sdes continue; 1880204917Sdes key = key_load_public(options.host_cert_files[i], NULL); 1881204917Sdes if (key == NULL) { 1882204917Sdes error("Could not load host certificate: %s", 1883204917Sdes options.host_cert_files[i]); 1884204917Sdes continue; 1885204917Sdes } 1886204917Sdes if (!key_is_cert(key)) { 1887204917Sdes error("Certificate file is not a certificate: %s", 1888204917Sdes options.host_cert_files[i]); 1889204917Sdes key_free(key); 1890204917Sdes continue; 1891204917Sdes } 1892204917Sdes /* Find matching private key */ 1893204917Sdes for (j = 0; j < options.num_host_key_files; j++) { 1894204917Sdes if (key_equal_public(key, 1895204917Sdes sensitive_data.host_keys[j])) { 1896204917Sdes sensitive_data.host_certificates[j] = key; 1897204917Sdes break; 1898204917Sdes } 1899204917Sdes } 1900204917Sdes if (j >= options.num_host_key_files) { 1901204917Sdes error("No matching private key for certificate: %s", 1902204917Sdes options.host_cert_files[i]); 1903204917Sdes key_free(key); 1904204917Sdes continue; 1905204917Sdes } 1906204917Sdes sensitive_data.host_certificates[j] = key; 1907204917Sdes debug("host certificate: #%d type %d %s", j, key->type, 1908204917Sdes key_type(key)); 1909204917Sdes } 1910295367Sdes 1911295367Sdes#ifdef WITH_SSH1 191260576Skris /* Check certain values for sanity. */ 191360576Skris if (options.protocol & SSH_PROTO_1) { 1914295367Sdes if (options.server_key_bits < SSH_RSA_MINIMUM_MODULUS_SIZE || 1915295367Sdes options.server_key_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { 191660576Skris fprintf(stderr, "Bad server key size.\n"); 191760576Skris exit(1); 191860576Skris } 191960576Skris /* 192060576Skris * Check that server and host key lengths differ sufficiently. This 192160576Skris * is necessary to make double encryption work with rsaref. Oh, I 192260576Skris * hate software patents. I dont know if this can go? Niels 192360576Skris */ 192460576Skris if (options.server_key_bits > 192599063Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - 192699063Sdes SSH_KEY_BITS_RESERVED && options.server_key_bits < 192799063Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + 192899063Sdes SSH_KEY_BITS_RESERVED) { 192960576Skris options.server_key_bits = 193099063Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + 193199063Sdes SSH_KEY_BITS_RESERVED; 193260576Skris debug("Forcing server key to %d bits to make it differ from host key.", 193360576Skris options.server_key_bits); 193460576Skris } 193560576Skris } 1936295367Sdes#endif 193760576Skris 193898684Sdes if (use_privsep) { 193998684Sdes struct stat st; 194098684Sdes 194198684Sdes if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || 194298684Sdes (S_ISDIR(st.st_mode) == 0)) 194398684Sdes fatal("Missing privilege separation directory: %s", 194498684Sdes _PATH_PRIVSEP_CHROOT_DIR); 1945106130Sdes 1946106130Sdes#ifdef HAVE_CYGWIN 1947106130Sdes if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) && 1948106130Sdes (st.st_uid != getuid () || 1949106130Sdes (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)) 1950106130Sdes#else 195199063Sdes if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) 1952106130Sdes#endif 1953113911Sdes fatal("%s must be owned by root and not group or " 1954113911Sdes "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); 195598684Sdes } 195698684Sdes 1957181111Sdes if (test_flag > 1) { 1958240075Sdes if (server_match_spec_complete(connection_info) == 1) 1959240075Sdes parse_server_match_config(&options, connection_info); 1960181111Sdes dump_config(&options); 1961181111Sdes } 1962181111Sdes 196392559Sdes /* Configuration looks good, so exit if in test mode. */ 196492559Sdes if (test_flag) 196592559Sdes exit(0); 196692559Sdes 196798941Sdes /* 196898941Sdes * Clear out any supplemental groups we may have inherited. This 196998941Sdes * prevents inadvertent creation of files with bad modes (in the 1970126277Sdes * portable version at least, it's certainly possible for PAM 1971126277Sdes * to create a file, and we can't control the code in every 197298941Sdes * module which might be used). 197398941Sdes */ 197498941Sdes if (setgroups(0, NULL) < 0) 197598941Sdes debug("setgroups() failed: %.200s", strerror(errno)); 197698941Sdes 1977137019Sdes if (rexec_flag) { 1978162856Sdes rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *)); 1979137019Sdes for (i = 0; i < rexec_argc; i++) { 1980137019Sdes debug("rexec_argv[%d]='%s'", i, saved_argv[i]); 1981137019Sdes rexec_argv[i] = saved_argv[i]; 1982137019Sdes } 1983137019Sdes rexec_argv[rexec_argc] = "-R"; 1984137019Sdes rexec_argv[rexec_argc + 1] = NULL; 1985137019Sdes } 1986137019Sdes 1987181111Sdes /* Ensure that umask disallows at least group and world write */ 1988181111Sdes new_umask = umask(0077) | 0022; 1989181111Sdes (void) umask(new_umask); 1990181111Sdes 199160576Skris /* Initialize the log (it is reinitialized below in case we forked). */ 1992147005Sdes if (debug_flag && (!inetd_flag || rexeced_flag)) 199357429Smarkm log_stderr = 1; 199476262Sgreen log_init(__progname, options.log_level, options.log_facility, log_stderr); 199557429Smarkm 199660576Skris /* 199760576Skris * If not in debugging mode, and not started from inetd, disconnect 199860576Skris * from the controlling terminal, and fork. The original process 199960576Skris * exits. 200060576Skris */ 200176262Sgreen if (!(debug_flag || inetd_flag || no_daemon_flag)) { 200257429Smarkm#ifdef TIOCNOTTY 200357429Smarkm int fd; 200457429Smarkm#endif /* TIOCNOTTY */ 200557429Smarkm if (daemon(0, 0) < 0) 200657429Smarkm fatal("daemon() failed: %.200s", strerror(errno)); 200757429Smarkm 200857429Smarkm /* Disconnect from the controlling tty. */ 200957429Smarkm#ifdef TIOCNOTTY 201076262Sgreen fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); 201157429Smarkm if (fd >= 0) { 201257429Smarkm (void) ioctl(fd, TIOCNOTTY, NULL); 201357429Smarkm close(fd); 201457429Smarkm } 201557429Smarkm#endif /* TIOCNOTTY */ 201657429Smarkm } 201757429Smarkm /* Reinitialize the log (because of the fork above). */ 201876262Sgreen log_init(__progname, options.log_level, options.log_facility, log_stderr); 201957429Smarkm 2020206397Skib /* Avoid killing the process in high-pressure swapping environments. */ 2021206397Skib if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0) 2022206397Skib debug("madvise(): %.200s", strerror(errno)); 2023206397Skib 202457429Smarkm /* Chdir to the root directory so that the current disk can be 202557429Smarkm unmounted if desired. */ 2026255767Sdes if (chdir("/") == -1) 2027255767Sdes error("chdir(\"/\"): %s", strerror(errno)); 202892559Sdes 202976262Sgreen /* ignore SIGPIPE */ 203076262Sgreen signal(SIGPIPE, SIG_IGN); 203157429Smarkm 2032162856Sdes /* Get a connection, either from inetd or a listening TCP socket */ 203357429Smarkm if (inetd_flag) { 2034162856Sdes server_accept_inetd(&sock_in, &sock_out); 203557429Smarkm } else { 2036204917Sdes platform_pre_listen(); 2037162856Sdes server_listen(); 203857429Smarkm 203992559Sdes if (options.protocol & SSH_PROTO_1) 204092559Sdes generate_ephemeral_server_key(); 204192559Sdes 204292559Sdes signal(SIGHUP, sighup_handler); 2043162856Sdes signal(SIGCHLD, main_sigchld_handler); 204492559Sdes signal(SIGTERM, sigterm_handler); 204592559Sdes signal(SIGQUIT, sigterm_handler); 204692559Sdes 2047162856Sdes /* 2048162856Sdes * Write out the pid file after the sigterm handler 2049162856Sdes * is setup and the listen sockets are bound 2050162856Sdes */ 2051295367Sdes if (options.pid_file != NULL && !debug_flag) { 2052162856Sdes FILE *f = fopen(options.pid_file, "w"); 205392559Sdes 2054124211Sdes if (f == NULL) { 2055124211Sdes error("Couldn't create pid file \"%s\": %s", 2056124211Sdes options.pid_file, strerror(errno)); 2057124211Sdes } else { 205898684Sdes fprintf(f, "%ld\n", (long) getpid()); 205957429Smarkm fclose(f); 206057429Smarkm } 206157429Smarkm } 206257429Smarkm 2063162856Sdes /* Accept a connection and return in a forked child */ 2064162856Sdes server_accept_loop(&sock_in, &sock_out, 2065162856Sdes &newsock, config_s); 206657429Smarkm } 206757429Smarkm 206857429Smarkm /* This is the child processing a new connection. */ 2069128460Sdes setproctitle("%s", "[accepted]"); 207057429Smarkm 207157429Smarkm /* 207298684Sdes * Create a new session and process group since the 4.4BSD 207398684Sdes * setlogin() affects the entire process group. We don't 207498684Sdes * want the child to be able to affect the parent. 207598684Sdes */ 2076124211Sdes#if !defined(SSHD_ACQUIRES_CTTY) 2077113911Sdes /* 2078124211Sdes * If setsid is called, on some platforms sshd will later acquire a 2079124211Sdes * controlling terminal which will result in "could not set 2080124211Sdes * controlling tty" errors. 2081113911Sdes */ 208299063Sdes if (!debug_flag && !inetd_flag && setsid() < 0) 208398684Sdes error("setsid: %.100s", strerror(errno)); 208498941Sdes#endif 208598684Sdes 2086137019Sdes if (rexec_flag) { 2087137019Sdes int fd; 2088137019Sdes 2089137019Sdes debug("rexec start in %d out %d newsock %d pipe %d sock %d", 2090137019Sdes sock_in, sock_out, newsock, startup_pipe, config_s[0]); 2091137019Sdes dup2(newsock, STDIN_FILENO); 2092137019Sdes dup2(STDIN_FILENO, STDOUT_FILENO); 2093137019Sdes if (startup_pipe == -1) 2094137019Sdes close(REEXEC_STARTUP_PIPE_FD); 2095262566Sdes else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { 2096137019Sdes dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD); 2097262566Sdes close(startup_pipe); 2098262566Sdes startup_pipe = REEXEC_STARTUP_PIPE_FD; 2099262566Sdes } 2100137019Sdes 2101137019Sdes dup2(config_s[1], REEXEC_CONFIG_PASS_FD); 2102137019Sdes close(config_s[1]); 2103137019Sdes 2104137019Sdes execv(rexec_argv[0], rexec_argv); 2105137019Sdes 2106137019Sdes /* Reexec has failed, fall back and continue */ 2107137019Sdes error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); 2108137019Sdes recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL); 2109137019Sdes log_init(__progname, options.log_level, 2110137019Sdes options.log_facility, log_stderr); 2111137019Sdes 2112137019Sdes /* Clean up fds */ 2113137019Sdes close(REEXEC_CONFIG_PASS_FD); 2114137019Sdes newsock = sock_out = sock_in = dup(STDIN_FILENO); 2115137019Sdes if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 2116137019Sdes dup2(fd, STDIN_FILENO); 2117137019Sdes dup2(fd, STDOUT_FILENO); 2118137019Sdes if (fd > STDERR_FILENO) 2119137019Sdes close(fd); 2120137019Sdes } 2121137019Sdes debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d", 2122137019Sdes sock_in, sock_out, newsock, startup_pipe, config_s[0]); 2123137019Sdes } 2124137019Sdes 2125204917Sdes /* Executed child processes don't need these. */ 2126204917Sdes fcntl(sock_out, F_SETFD, FD_CLOEXEC); 2127204917Sdes fcntl(sock_in, F_SETFD, FD_CLOEXEC); 2128204917Sdes 212998684Sdes /* 213057429Smarkm * Disable the key regeneration alarm. We will not regenerate the 213157429Smarkm * key since we are no longer in a position to give it to anyone. We 213257429Smarkm * will not restart on SIGHUP since it no longer makes sense. 213357429Smarkm */ 213457429Smarkm alarm(0); 213557429Smarkm signal(SIGALRM, SIG_DFL); 213657429Smarkm signal(SIGHUP, SIG_DFL); 213757429Smarkm signal(SIGTERM, SIG_DFL); 213857429Smarkm signal(SIGQUIT, SIG_DFL); 213957429Smarkm signal(SIGCHLD, SIG_DFL); 214098941Sdes signal(SIGINT, SIG_DFL); 214157429Smarkm 2142109683Sdes#ifdef __FreeBSD__ 214357429Smarkm /* 2144109683Sdes * Initialize the resolver. This may not happen automatically 2145231584Sed * before privsep chroot(). 2146109683Sdes */ 2147109683Sdes if ((_res.options & RES_INIT) == 0) { 2148231584Sed debug("res_init()"); 2149231584Sed res_init(); 2150109683Sdes } 2151153838Sdfr#ifdef GSSAPI 2152153838Sdfr /* 2153153838Sdfr * Force GSS-API to parse its configuration and load any 2154153838Sdfr * mechanism plugins. 2155153838Sdfr */ 2156153838Sdfr { 2157153838Sdfr gss_OID_set mechs; 2158153838Sdfr OM_uint32 minor_status; 2159153838Sdfr gss_indicate_mechs(&minor_status, &mechs); 2160153838Sdfr gss_release_oid_set(&minor_status, &mechs); 2161153838Sdfr } 2162109683Sdes#endif 2163153838Sdfr#endif 2164109683Sdes 2165109683Sdes /* 216657429Smarkm * Register our connection. This turns encryption off because we do 216757429Smarkm * not have a key. 216857429Smarkm */ 216957429Smarkm packet_set_connection(sock_in, sock_out); 2170149753Sdes packet_set_server(); 217157429Smarkm 2172149753Sdes /* Set SO_KEEPALIVE if requested. */ 2173149753Sdes if (options.tcp_keep_alive && packet_connection_is_on_socket() && 2174149753Sdes setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) 2175149753Sdes error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 2176149753Sdes 2177149753Sdes if ((remote_port = get_remote_port()) < 0) { 2178149753Sdes debug("get_remote_port failed"); 2179149753Sdes cleanup_exit(255); 2180149753Sdes } 218157429Smarkm 2182157019Sdes /* 2183157019Sdes * We use get_canonical_hostname with usedns = 0 instead of 2184157019Sdes * get_remote_ipaddr here so IP options will be checked. 2185157019Sdes */ 2186162856Sdes (void) get_canonical_hostname(0); 2187162856Sdes /* 2188162856Sdes * The rest of the code depends on the fact that 2189162856Sdes * get_remote_ipaddr() caches the remote ip, even if 2190162856Sdes * the socket goes away. 2191162856Sdes */ 2192162856Sdes remote_ip = get_remote_ipaddr(); 2193157019Sdes 2194147005Sdes#ifdef SSH_AUDIT_EVENTS 2195147005Sdes audit_connection_from(remote_ip, remote_port); 2196147005Sdes#endif 219792559Sdes#ifdef LIBWRAP 2198181111Sdes allow_severity = options.log_facility|LOG_INFO; 2199181111Sdes deny_severity = options.log_facility|LOG_WARNING; 220057429Smarkm /* Check whether logins are denied from this host. */ 2201137019Sdes if (packet_connection_is_on_socket()) { 220257429Smarkm struct request_info req; 220357429Smarkm 220492559Sdes request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); 220557429Smarkm fromhost(&req); 220657429Smarkm 220757429Smarkm if (!hosts_access(&req)) { 220892559Sdes debug("Connection refused by tcp wrapper"); 220976262Sgreen refuse(&req); 221092559Sdes /* NOTREACHED */ 221192559Sdes fatal("libwrap refuse returns"); 221257429Smarkm } 221357429Smarkm } 221457429Smarkm#endif /* LIBWRAP */ 221592559Sdes 221657429Smarkm /* Log the connection. */ 2217295367Sdes laddr = get_local_ipaddr(sock_in); 2218262566Sdes verbose("Connection from %s port %d on %s port %d", 2219295367Sdes remote_ip, remote_port, laddr, get_local_port()); 2220295367Sdes free(laddr); 222157429Smarkm 222257429Smarkm /* 2223157019Sdes * We don't want to listen forever unless the other side 222457429Smarkm * successfully authenticates itself. So we set up an alarm which is 222557429Smarkm * cleared after successful authentication. A limit of zero 2226157019Sdes * indicates no limit. Note that we don't set the alarm in debugging 222757429Smarkm * mode; it is just annoying to have the server exit just when you 222857429Smarkm * are about to discover the bug. 222957429Smarkm */ 223057429Smarkm signal(SIGALRM, grace_alarm_handler); 223157429Smarkm if (!debug_flag) 223257429Smarkm alarm(options.login_grace_time); 223357429Smarkm 223460576Skris sshd_exchange_identification(sock_in, sock_out); 223557429Smarkm 2236181111Sdes /* In inetd mode, generate ephemeral key only for proto 1 connections */ 2237181111Sdes if (!compat20 && inetd_flag && sensitive_data.server_key == NULL) 2238181111Sdes generate_ephemeral_server_key(); 2239181111Sdes 224057429Smarkm packet_set_nonblocking(); 224157429Smarkm 2242126277Sdes /* allocate authentication context */ 2243162856Sdes authctxt = xcalloc(1, sizeof(*authctxt)); 2244126277Sdes 2245147005Sdes authctxt->loginmsg = &loginmsg; 2246147005Sdes 2247126277Sdes /* XXX global for cleanup, access from other modules */ 2248126277Sdes the_authctxt = authctxt; 2249126277Sdes 2250147005Sdes /* prepare buffer to collect messages to display to user after login */ 2251147005Sdes buffer_init(&loginmsg); 2252204917Sdes auth_debug_reset(); 2253147005Sdes 2254255767Sdes if (use_privsep) { 2255126277Sdes if (privsep_preauth(authctxt) == 1) 225698684Sdes goto authenticated; 2257295367Sdes } else if (compat20 && have_agent) { 2258295367Sdes if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { 2259295367Sdes error("Unable to get agent socket: %s", ssh_err(r)); 2260295367Sdes have_agent = 0; 2261295367Sdes } 2262295367Sdes } 226398684Sdes 226457429Smarkm /* perform the key exchange */ 226557429Smarkm /* authenticate user and start session */ 226660576Skris if (compat20) { 226760576Skris do_ssh2_kex(); 2268126277Sdes do_authentication2(authctxt); 226960576Skris } else { 2270295367Sdes#ifdef WITH_SSH1 227160576Skris do_ssh1_kex(); 2272126277Sdes do_authentication(authctxt); 2273295367Sdes#else 2274295367Sdes fatal("ssh1 not supported"); 2275295367Sdes#endif 227660576Skris } 227798684Sdes /* 227898684Sdes * If we use privilege separation, the unprivileged child transfers 227998684Sdes * the current keystate and exits 228098684Sdes */ 228198684Sdes if (use_privsep) { 228298684Sdes mm_send_keystate(pmonitor); 228398684Sdes exit(0); 228498684Sdes } 228598684Sdes 228698684Sdes authenticated: 2287157019Sdes /* 2288157019Sdes * Cancel the alarm we set to limit the time taken for 2289157019Sdes * authentication. 2290157019Sdes */ 2291157019Sdes alarm(0); 2292157019Sdes signal(SIGALRM, SIG_DFL); 2293162856Sdes authctxt->authenticated = 1; 2294157019Sdes if (startup_pipe != -1) { 2295157019Sdes close(startup_pipe); 2296157019Sdes startup_pipe = -1; 2297157019Sdes } 2298157019Sdes 2299147005Sdes#ifdef SSH_AUDIT_EVENTS 2300147005Sdes audit_event(SSH_AUTH_SUCCESS); 2301147005Sdes#endif 2302147005Sdes 2303181111Sdes#ifdef GSSAPI 2304181111Sdes if (options.gss_authentication) { 2305181111Sdes temporarily_use_uid(authctxt->pw); 2306181111Sdes ssh_gssapi_storecreds(); 2307181111Sdes restore_uid(); 2308181111Sdes } 2309181111Sdes#endif 2310181111Sdes#ifdef USE_PAM 2311181111Sdes if (options.use_pam) { 2312181111Sdes do_pam_setcred(1); 2313181111Sdes do_pam_session(); 2314181111Sdes } 2315181111Sdes#endif 2316181111Sdes 231798684Sdes /* 231898684Sdes * In privilege separation, we fork another child and prepare 231998684Sdes * file descriptor passing. 232098684Sdes */ 232198684Sdes if (use_privsep) { 232298684Sdes privsep_postauth(authctxt); 232398684Sdes /* the monitor process [priv] will not return */ 232498684Sdes if (!compat20) 232598684Sdes destroy_sensitive_data(); 232698684Sdes } 232798684Sdes 2328181111Sdes packet_set_timeout(options.client_alive_interval, 2329181111Sdes options.client_alive_count_max); 2330181111Sdes 2331295367Sdes /* Try to send all our hostkeys to the client */ 2332295367Sdes if (compat20) 2333295367Sdes notify_hostkeys(active_state); 2334295367Sdes 2335126277Sdes /* Start session. */ 233698684Sdes do_authenticated(authctxt); 233798684Sdes 233857429Smarkm /* The connection has been terminated. */ 2339295367Sdes packet_get_bytes(&ibytes, &obytes); 2340221420Sdes verbose("Transferred: sent %llu, received %llu bytes", 2341221420Sdes (unsigned long long)obytes, (unsigned long long)ibytes); 234269591Sgreen 2343181111Sdes verbose("Closing connection to %.500s port %d", remote_ip, remote_port); 2344181111Sdes 234569591Sgreen#ifdef USE_PAM 2346124211Sdes if (options.use_pam) 2347124211Sdes finish_pam(); 234869591Sgreen#endif /* USE_PAM */ 234969591Sgreen 2350147005Sdes#ifdef SSH_AUDIT_EVENTS 2351147005Sdes PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); 2352147005Sdes#endif 2353147005Sdes 235457429Smarkm packet_close(); 235598684Sdes 235698684Sdes if (use_privsep) 235798684Sdes mm_terminate(); 235898684Sdes 235957429Smarkm exit(0); 236057429Smarkm} 236157429Smarkm 2362295367Sdes#ifdef WITH_SSH1 236357429Smarkm/* 236498684Sdes * Decrypt session_key_int using our private server key and private host key 236598684Sdes * (key with larger modulus first). 236698684Sdes */ 236798684Sdesint 236898684Sdesssh1_session_key(BIGNUM *session_key_int) 236998684Sdes{ 237098684Sdes int rsafail = 0; 237198684Sdes 2372162856Sdes if (BN_cmp(sensitive_data.server_key->rsa->n, 2373162856Sdes sensitive_data.ssh1_host_key->rsa->n) > 0) { 237498684Sdes /* Server key has bigger modulus. */ 237598684Sdes if (BN_num_bits(sensitive_data.server_key->rsa->n) < 2376162856Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + 2377162856Sdes SSH_KEY_BITS_RESERVED) { 2378162856Sdes fatal("do_connection: %s: " 2379162856Sdes "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", 238098684Sdes get_remote_ipaddr(), 238198684Sdes BN_num_bits(sensitive_data.server_key->rsa->n), 238298684Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), 238398684Sdes SSH_KEY_BITS_RESERVED); 238498684Sdes } 238598684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2386295367Sdes sensitive_data.server_key->rsa) != 0) 238798684Sdes rsafail++; 238898684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2389295367Sdes sensitive_data.ssh1_host_key->rsa) != 0) 239098684Sdes rsafail++; 239198684Sdes } else { 239298684Sdes /* Host key has bigger modulus (or they are equal). */ 239398684Sdes if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < 2394162856Sdes BN_num_bits(sensitive_data.server_key->rsa->n) + 2395162856Sdes SSH_KEY_BITS_RESERVED) { 2396162856Sdes fatal("do_connection: %s: " 2397162856Sdes "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", 239898684Sdes get_remote_ipaddr(), 239998684Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), 240098684Sdes BN_num_bits(sensitive_data.server_key->rsa->n), 240198684Sdes SSH_KEY_BITS_RESERVED); 240298684Sdes } 240398684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2404295367Sdes sensitive_data.ssh1_host_key->rsa) != 0) 240598684Sdes rsafail++; 240698684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2407295367Sdes sensitive_data.server_key->rsa) != 0) 240898684Sdes rsafail++; 240998684Sdes } 241098684Sdes return (rsafail); 241198684Sdes} 2412295367Sdes 241398684Sdes/* 241457429Smarkm * SSH1 key exchange 241557429Smarkm */ 241692559Sdesstatic void 241776262Sgreendo_ssh1_kex(void) 241857429Smarkm{ 241957429Smarkm int i, len; 242072397Skris int rsafail = 0; 2421295367Sdes BIGNUM *session_key_int, *fake_key_int, *real_key_int; 242276262Sgreen u_char session_key[SSH_SESSION_KEY_LENGTH]; 2423295367Sdes u_char fake_key_bytes[4096 / 8]; 2424295367Sdes size_t fake_key_len; 242576262Sgreen u_char cookie[8]; 242676262Sgreen u_int cipher_type, auth_mask, protocol_flags; 242757429Smarkm 242857429Smarkm /* 242957429Smarkm * Generate check bytes that the client must send back in the user 243057429Smarkm * packet in order for it to be accepted; this is used to defy ip 243157429Smarkm * spoofing attacks. Note that this only works against somebody 243257429Smarkm * doing IP spoofing from a remote machine; any machine on the local 243357429Smarkm * network can still see outgoing packets and catch the random 243457429Smarkm * cookie. This only affects rhosts authentication, and this is one 243557429Smarkm * of the reasons why it is inherently insecure. 243657429Smarkm */ 2437181111Sdes arc4random_buf(cookie, sizeof(cookie)); 243857429Smarkm 243957429Smarkm /* 244057429Smarkm * Send our public key. We include in the packet 64 bits of random 244157429Smarkm * data that must be matched in the reply in order to prevent IP 244257429Smarkm * spoofing. 244357429Smarkm */ 244457429Smarkm packet_start(SSH_SMSG_PUBLIC_KEY); 244557429Smarkm for (i = 0; i < 8; i++) 244657429Smarkm packet_put_char(cookie[i]); 244757429Smarkm 244857429Smarkm /* Store our public server RSA key. */ 244976262Sgreen packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); 245076262Sgreen packet_put_bignum(sensitive_data.server_key->rsa->e); 245176262Sgreen packet_put_bignum(sensitive_data.server_key->rsa->n); 245257429Smarkm 245357429Smarkm /* Store our public host RSA key. */ 245476262Sgreen packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); 245576262Sgreen packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); 245676262Sgreen packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); 245757429Smarkm 245857429Smarkm /* Put protocol flags. */ 245957429Smarkm packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); 246057429Smarkm 246157429Smarkm /* Declare which ciphers we support. */ 246269591Sgreen packet_put_int(cipher_mask_ssh1(0)); 246357429Smarkm 246457429Smarkm /* Declare supported authentication types. */ 246557429Smarkm auth_mask = 0; 246657429Smarkm if (options.rhosts_rsa_authentication) 246757429Smarkm auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; 246857429Smarkm if (options.rsa_authentication) 246957429Smarkm auth_mask |= 1 << SSH_AUTH_RSA; 247092559Sdes if (options.challenge_response_authentication == 1) 247157429Smarkm auth_mask |= 1 << SSH_AUTH_TIS; 247257429Smarkm if (options.password_authentication) 247357429Smarkm auth_mask |= 1 << SSH_AUTH_PASSWORD; 247457429Smarkm packet_put_int(auth_mask); 247557429Smarkm 247657429Smarkm /* Send the packet and wait for it to be sent. */ 247757429Smarkm packet_send(); 247857429Smarkm packet_write_wait(); 247957429Smarkm 248076262Sgreen debug("Sent %d bit server key and %d bit host key.", 248176262Sgreen BN_num_bits(sensitive_data.server_key->rsa->n), 248276262Sgreen BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); 248357429Smarkm 248457429Smarkm /* Read clients reply (cipher type and session key). */ 248592559Sdes packet_read_expect(SSH_CMSG_SESSION_KEY); 248657429Smarkm 248757429Smarkm /* Get cipher type and check whether we accept this. */ 248857429Smarkm cipher_type = packet_get_char(); 248957429Smarkm 249069591Sgreen if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) 249157429Smarkm packet_disconnect("Warning: client selects unsupported cipher."); 249257429Smarkm 249357429Smarkm /* Get check bytes from the packet. These must match those we 249457429Smarkm sent earlier with the public key packet. */ 249557429Smarkm for (i = 0; i < 8; i++) 249657429Smarkm if (cookie[i] != packet_get_char()) 249757429Smarkm packet_disconnect("IP Spoofing check bytes do not match."); 249857429Smarkm 249957429Smarkm debug("Encryption type: %.200s", cipher_name(cipher_type)); 250057429Smarkm 250157429Smarkm /* Get the encrypted integer. */ 2502295367Sdes if ((real_key_int = BN_new()) == NULL) 250392559Sdes fatal("do_ssh1_kex: BN_new failed"); 2504295367Sdes packet_get_bignum(real_key_int); 250557429Smarkm 250657429Smarkm protocol_flags = packet_get_int(); 250757429Smarkm packet_set_protocol_flags(protocol_flags); 250892559Sdes packet_check_eom(); 250957429Smarkm 2510295367Sdes /* Setup a fake key in case RSA decryption fails */ 2511295367Sdes if ((fake_key_int = BN_new()) == NULL) 2512295367Sdes fatal("do_ssh1_kex: BN_new failed"); 2513295367Sdes fake_key_len = BN_num_bytes(real_key_int); 2514295367Sdes if (fake_key_len > sizeof(fake_key_bytes)) 2515295367Sdes fake_key_len = sizeof(fake_key_bytes); 2516295367Sdes arc4random_buf(fake_key_bytes, fake_key_len); 2517295367Sdes if (BN_bin2bn(fake_key_bytes, fake_key_len, fake_key_int) == NULL) 2518295367Sdes fatal("do_ssh1_kex: BN_bin2bn failed"); 251998684Sdes 2520295367Sdes /* Decrypt real_key_int using host/server keys */ 2521295367Sdes rsafail = PRIVSEP(ssh1_session_key(real_key_int)); 2522295367Sdes /* If decryption failed, use the fake key. Else, the real key. */ 2523295367Sdes if (rsafail) 2524295367Sdes session_key_int = fake_key_int; 2525295367Sdes else 2526295367Sdes session_key_int = real_key_int; 2527295367Sdes 252857429Smarkm /* 252957429Smarkm * Extract session key from the decrypted integer. The key is in the 253057429Smarkm * least significant 256 bits of the integer; the first byte of the 253157429Smarkm * key is in the highest bits. 253257429Smarkm */ 2533295367Sdes (void) BN_mask_bits(session_key_int, sizeof(session_key) * 8); 2534295367Sdes len = BN_num_bytes(session_key_int); 2535295367Sdes if (len < 0 || (u_int)len > sizeof(session_key)) { 2536295367Sdes error("do_ssh1_kex: bad session key len from %s: " 2537295367Sdes "session_key_int %d > sizeof(session_key) %lu", 2538295367Sdes get_remote_ipaddr(), len, (u_long)sizeof(session_key)); 2539295367Sdes rsafail++; 2540295367Sdes } else { 2541295367Sdes explicit_bzero(session_key, sizeof(session_key)); 2542295367Sdes BN_bn2bin(session_key_int, 2543295367Sdes session_key + sizeof(session_key) - len); 254476262Sgreen 2545295367Sdes derive_ssh1_session_id( 2546295367Sdes sensitive_data.ssh1_host_key->rsa->n, 2547295367Sdes sensitive_data.server_key->rsa->n, 2548295367Sdes cookie, session_id); 2549295367Sdes /* 2550295367Sdes * Xor the first 16 bytes of the session key with the 2551295367Sdes * session id. 2552295367Sdes */ 2553295367Sdes for (i = 0; i < 16; i++) 2554295367Sdes session_key[i] ^= session_id[i]; 255572397Skris } 255676262Sgreen 255798684Sdes /* Destroy the private and public keys. No longer. */ 255876262Sgreen destroy_sensitive_data(); 255957429Smarkm 256098684Sdes if (use_privsep) 256198684Sdes mm_ssh1_session_id(session_id); 256298684Sdes 256357429Smarkm /* Destroy the decrypted integer. It is no longer needed. */ 2564295367Sdes BN_clear_free(real_key_int); 2565295367Sdes BN_clear_free(fake_key_int); 256657429Smarkm 256757429Smarkm /* Set the session key. From this on all communications will be encrypted. */ 256857429Smarkm packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); 256957429Smarkm 257057429Smarkm /* Destroy our copy of the session key. It is no longer needed. */ 2571264377Sdes explicit_bzero(session_key, sizeof(session_key)); 257257429Smarkm 257357429Smarkm debug("Received session key; encryption turned on."); 257457429Smarkm 257598684Sdes /* Send an acknowledgment packet. Note that this packet is sent encrypted. */ 257657429Smarkm packet_start(SSH_SMSG_SUCCESS); 257757429Smarkm packet_send(); 257857429Smarkm packet_write_wait(); 257957429Smarkm} 2580295367Sdes#endif 258157429Smarkm 2582295367Sdesint 2583295367Sdessshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, 2584296853Sdes const u_char *data, size_t dlen, const char *alg, u_int flag) 2585255767Sdes{ 2586295367Sdes int r; 2587295367Sdes u_int xxx_slen, xxx_dlen = dlen; 2588295367Sdes 2589255767Sdes if (privkey) { 2590296853Sdes if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen, 2591296853Sdes alg) < 0)) 2592255767Sdes fatal("%s: key_sign failed", __func__); 2593295367Sdes if (slen) 2594295367Sdes *slen = xxx_slen; 2595255767Sdes } else if (use_privsep) { 2596296853Sdes if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen, 2597296853Sdes alg) < 0) 2598255767Sdes fatal("%s: pubkey_sign failed", __func__); 2599295367Sdes if (slen) 2600295367Sdes *slen = xxx_slen; 2601255767Sdes } else { 2602295367Sdes if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slen, 2603296853Sdes data, dlen, alg, datafellows)) != 0) 2604295367Sdes fatal("%s: ssh_agent_sign failed: %s", 2605295367Sdes __func__, ssh_err(r)); 2606255767Sdes } 2607295367Sdes return 0; 2608255767Sdes} 2609255767Sdes 2610295367Sdes/* SSH2 key exchange */ 261192559Sdesstatic void 261276262Sgreendo_ssh2_kex(void) 261357429Smarkm{ 2614295367Sdes char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; 2615295367Sdes struct kex *kex; 2616295367Sdes int r; 261757429Smarkm 2618295367Sdes myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( 2619295367Sdes options.kex_algorithms); 2620295367Sdes myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal( 2621295367Sdes options.ciphers); 2622295367Sdes myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal( 2623295367Sdes options.ciphers); 2624295367Sdes myproposal[PROPOSAL_MAC_ALGS_CTOS] = 2625295367Sdes myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 262657429Smarkm 2627149753Sdes if (options.compression == COMP_NONE) { 262898684Sdes myproposal[PROPOSAL_COMP_ALGS_CTOS] = 262998684Sdes myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; 2630149753Sdes } else if (options.compression == COMP_DELAYED) { 2631149753Sdes myproposal[PROPOSAL_COMP_ALGS_CTOS] = 2632149753Sdes myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com"; 263398684Sdes } 2634162856Sdes 2635255767Sdes if (options.rekey_limit || options.rekey_interval) 2636296853Sdes packet_set_rekey_limits(options.rekey_limit, 2637255767Sdes (time_t)options.rekey_interval); 2638255767Sdes 2639262566Sdes myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2640262566Sdes list_hostkey_types()); 264169591Sgreen 264276262Sgreen /* start key exchange */ 2643295367Sdes if ((r = kex_setup(active_state, myproposal)) != 0) 2644295367Sdes fatal("kex_setup: %s", ssh_err(r)); 2645295367Sdes kex = active_state->kex; 2646295367Sdes#ifdef WITH_OPENSSL 2647113911Sdes kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 2648137019Sdes kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; 2649113911Sdes kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 2650162856Sdes kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 2651295367Sdes# ifdef OPENSSL_HAS_ECC 2652221420Sdes kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 2653295367Sdes# endif 2654295367Sdes#endif 2655262566Sdes kex->kex[KEX_C25519_SHA256] = kexc25519_server; 265676262Sgreen kex->server = 1; 265776262Sgreen kex->client_version_string=client_version_string; 265876262Sgreen kex->server_version_string=server_version_string; 2659204917Sdes kex->load_host_public_key=&get_hostkey_public_by_type; 2660204917Sdes kex->load_host_private_key=&get_hostkey_private_by_type; 266198684Sdes kex->host_key_index=&get_hostkey_index; 2662255767Sdes kex->sign = sshd_hostkey_sign; 266369591Sgreen 2664295367Sdes dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); 266569591Sgreen 266676262Sgreen session_id2 = kex->session_id; 266776262Sgreen session_id2_len = kex->session_id_len; 266876262Sgreen 266969591Sgreen#ifdef DEBUG_KEXDH 267069591Sgreen /* send 1st encrypted/maced/compressed message */ 267169591Sgreen packet_start(SSH2_MSG_IGNORE); 267269591Sgreen packet_put_cstring("markus"); 267369591Sgreen packet_send(); 267469591Sgreen packet_write_wait(); 267569591Sgreen#endif 267676262Sgreen debug("KEX done"); 267769591Sgreen} 2678126277Sdes 2679126277Sdes/* server specific fatal cleanup */ 2680126277Sdesvoid 2681126277Sdescleanup_exit(int i) 2682126277Sdes{ 2683240075Sdes if (the_authctxt) { 2684126277Sdes do_cleanup(the_authctxt); 2685295367Sdes if (use_privsep && privsep_is_preauth && 2686295367Sdes pmonitor != NULL && pmonitor->m_pid > 1) { 2687240075Sdes debug("Killing privsep child %d", pmonitor->m_pid); 2688240075Sdes if (kill(pmonitor->m_pid, SIGKILL) != 0 && 2689240075Sdes errno != ESRCH) 2690240075Sdes error("%s: kill(%d): %s", __func__, 2691240075Sdes pmonitor->m_pid, strerror(errno)); 2692240075Sdes } 2693240075Sdes } 2694147005Sdes#ifdef SSH_AUDIT_EVENTS 2695147005Sdes /* done after do_cleanup so it can cancel the PAM auth 'thread' */ 2696147005Sdes if (!use_privsep || mm_is_monitor()) 2697147005Sdes audit_event(SSH_CONNECTION_ABANDON); 2698147005Sdes#endif 2699126277Sdes _exit(i); 2700126277Sdes} 2701