1323124Sdes/* $OpenBSD: sshd.c,v 1.470 2016/05/24 04:43:45 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: stable/10/crypto/openssh/sshd.c 323124 2017-09-01 22:52:18Z 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. */ 392323124Sdes sigdie("Timeout before authentication for %s port %d", 393323124Sdes ssh_remote_ipaddr(active_state), ssh_remote_port(active_state)); 39457429Smarkm} 39557429Smarkm 39657429Smarkm/* 39757429Smarkm * Signal handler for the key regeneration alarm. Note that this 39857429Smarkm * alarm only occurs in the daemon waiting for connections, and it does not 39957429Smarkm * do anything with the private key or random state before forking. 40057429Smarkm * Thus there should be no concurrency control/asynchronous execution 40157429Smarkm * problems. 40257429Smarkm */ 40392559Sdesstatic void 40476262Sgreengenerate_ephemeral_server_key(void) 40557429Smarkm{ 40676262Sgreen verbose("Generating %s%d bit RSA key.", 40776262Sgreen sensitive_data.server_key ? "new " : "", options.server_key_bits); 40876262Sgreen if (sensitive_data.server_key != NULL) 40976262Sgreen key_free(sensitive_data.server_key); 41076262Sgreen sensitive_data.server_key = key_generate(KEY_RSA1, 41176262Sgreen options.server_key_bits); 41276262Sgreen verbose("RSA key generation complete."); 41357429Smarkm 414181111Sdes arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); 41576262Sgreen} 41657429Smarkm 417162856Sdes/*ARGSUSED*/ 41892559Sdesstatic void 41976262Sgreenkey_regeneration_alarm(int sig) 42076262Sgreen{ 42176262Sgreen int save_errno = errno; 42299063Sdes 42376262Sgreen signal(SIGALRM, SIG_DFL); 42457429Smarkm errno = save_errno; 42576262Sgreen key_do_regen = 1; 42657429Smarkm} 42757429Smarkm 42892559Sdesstatic void 429323124Sdessshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) 43060576Skris{ 431149753Sdes u_int i; 432149753Sdes int mismatch; 43360576Skris int remote_major, remote_minor; 43460576Skris int major, minor; 435181111Sdes char *s, *newline = "\n"; 43660576Skris char buf[256]; /* Must not be larger than remote_version. */ 43760576Skris char remote_version[256]; /* Must be at least as big as buf. */ 43860576Skris 43960576Skris if ((options.protocol & SSH_PROTO_1) && 44060576Skris (options.protocol & SSH_PROTO_2)) { 44160576Skris major = PROTOCOL_MAJOR_1; 44260576Skris minor = 99; 44360576Skris } else if (options.protocol & SSH_PROTO_2) { 44460576Skris major = PROTOCOL_MAJOR_2; 44560576Skris minor = PROTOCOL_MINOR_2; 446181111Sdes newline = "\r\n"; 44760576Skris } else { 44860576Skris major = PROTOCOL_MAJOR_1; 44960576Skris minor = PROTOCOL_MINOR_1; 45060576Skris } 45160576Skris 452294693Sdes xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", 453240075Sdes major, minor, SSH_VERSION, 454240075Sdes *options.version_addendum == '\0' ? "" : " ", 455240075Sdes options.version_addendum, newline); 456240075Sdes 457124211Sdes /* Send our protocol version identification. */ 458296781Sdes if (atomicio(vwrite, sock_out, server_version_string, 459124211Sdes strlen(server_version_string)) 460124211Sdes != strlen(server_version_string)) { 461323124Sdes logit("Could not write ident string to %s port %d", 462323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 463126277Sdes cleanup_exit(255); 464124211Sdes } 465124211Sdes 466124211Sdes /* Read other sides version identification. */ 467124211Sdes memset(buf, 0, sizeof(buf)); 468124211Sdes for (i = 0; i < sizeof(buf) - 1; i++) { 469296781Sdes if (atomicio(read, sock_in, &buf[i], 1) != 1) { 470323124Sdes logit("Did not receive identification string " 471323124Sdes "from %s port %d", 472323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 473126277Sdes cleanup_exit(255); 47460576Skris } 475124211Sdes if (buf[i] == '\r') { 476124211Sdes buf[i] = 0; 477124211Sdes /* Kludge for F-Secure Macintosh < 1.0.2 */ 478124211Sdes if (i == 12 && 479124211Sdes strncmp(buf, "SSH-1.5-W1.0", 12) == 0) 48060576Skris break; 481124211Sdes continue; 48260576Skris } 483124211Sdes if (buf[i] == '\n') { 484124211Sdes buf[i] = 0; 485124211Sdes break; 486124211Sdes } 48760576Skris } 488124211Sdes buf[sizeof(buf) - 1] = 0; 489124211Sdes client_version_string = xstrdup(buf); 49060576Skris 49160576Skris /* 49260576Skris * Check that the versions match. In future this might accept 49360576Skris * several versions and set appropriate flags to handle them. 49460576Skris */ 49560576Skris if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", 49660576Skris &remote_major, &remote_minor, remote_version) != 3) { 49760576Skris s = "Protocol mismatch.\n"; 498124211Sdes (void) atomicio(vwrite, sock_out, s, strlen(s)); 499262566Sdes logit("Bad protocol version identification '%.100s' " 500262566Sdes "from %s port %d", client_version_string, 501323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 50260576Skris close(sock_in); 50360576Skris close(sock_out); 504126277Sdes cleanup_exit(255); 50560576Skris } 50660576Skris debug("Client protocol version %d.%d; client software version %.100s", 50792559Sdes remote_major, remote_minor, remote_version); 50860576Skris 509323124Sdes ssh->compat = compat_datafellows(remote_version); 51060576Skris 511323124Sdes if ((ssh->compat & SSH_BUG_PROBE) != 0) { 512323124Sdes logit("probed from %s port %d with %s. Don't panic.", 513323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 514323124Sdes client_version_string); 515126277Sdes cleanup_exit(255); 516106130Sdes } 517323124Sdes if ((ssh->compat & SSH_BUG_SCANNER) != 0) { 518323124Sdes logit("scanned from %s port %d with %s. Don't panic.", 519323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 520323124Sdes client_version_string); 521126277Sdes cleanup_exit(255); 52276262Sgreen } 523323124Sdes if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) { 524262566Sdes logit("Client version \"%.100s\" uses unsafe RSA signature " 525262566Sdes "scheme; disabling use of RSA keys", remote_version); 526262566Sdes } 527323124Sdes if ((ssh->compat & SSH_BUG_DERIVEKEY) != 0) { 528262566Sdes fatal("Client version \"%.100s\" uses unsafe key agreement; " 529262566Sdes "refusing connection", remote_version); 530262566Sdes } 53176262Sgreen 53260576Skris mismatch = 0; 53392559Sdes switch (remote_major) { 53460576Skris case 1: 53560576Skris if (remote_minor == 99) { 53660576Skris if (options.protocol & SSH_PROTO_2) 53760576Skris enable_compat20(); 53860576Skris else 53960576Skris mismatch = 1; 54060576Skris break; 54160576Skris } 54260576Skris if (!(options.protocol & SSH_PROTO_1)) { 54360576Skris mismatch = 1; 54460576Skris break; 54560576Skris } 54660576Skris if (remote_minor < 3) { 54765674Skris packet_disconnect("Your ssh version is too old and " 54860576Skris "is no longer supported. Please install a newer version."); 54960576Skris } else if (remote_minor == 3) { 55060576Skris /* note that this disables agent-forwarding */ 55160576Skris enable_compat13(); 55260576Skris } 55360576Skris break; 55460576Skris case 2: 55560576Skris if (options.protocol & SSH_PROTO_2) { 55660576Skris enable_compat20(); 55760576Skris break; 55860576Skris } 55960576Skris /* FALLTHROUGH */ 56060576Skris default: 56160576Skris mismatch = 1; 56260576Skris break; 56360576Skris } 56460576Skris chop(server_version_string); 56560576Skris debug("Local version string %.200s", server_version_string); 56660576Skris 56760576Skris if (mismatch) { 56860576Skris s = "Protocol major versions differ.\n"; 569124211Sdes (void) atomicio(vwrite, sock_out, s, strlen(s)); 57060576Skris close(sock_in); 57160576Skris close(sock_out); 572323124Sdes logit("Protocol major versions differ for %s port %d: " 573323124Sdes "%.200s vs. %.200s", 574323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 57560576Skris server_version_string, client_version_string); 576126277Sdes cleanup_exit(255); 57760576Skris } 57860576Skris} 57960576Skris 58076262Sgreen/* Destroy the host and server keys. They will no longer be needed. */ 58160576Skrisvoid 58260576Skrisdestroy_sensitive_data(void) 58360576Skris{ 58476262Sgreen int i; 58576262Sgreen 58676262Sgreen if (sensitive_data.server_key) { 58776262Sgreen key_free(sensitive_data.server_key); 58876262Sgreen sensitive_data.server_key = NULL; 58976262Sgreen } 59092559Sdes for (i = 0; i < options.num_host_key_files; i++) { 59176262Sgreen if (sensitive_data.host_keys[i]) { 59276262Sgreen key_free(sensitive_data.host_keys[i]); 59376262Sgreen sensitive_data.host_keys[i] = NULL; 59476262Sgreen } 595204917Sdes if (sensitive_data.host_certificates[i]) { 596204917Sdes key_free(sensitive_data.host_certificates[i]); 597204917Sdes sensitive_data.host_certificates[i] = NULL; 598204917Sdes } 59976262Sgreen } 60076262Sgreen sensitive_data.ssh1_host_key = NULL; 601264377Sdes explicit_bzero(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); 60260576Skris} 60360576Skris 60498684Sdes/* Demote private to public keys for network child */ 60598684Sdesvoid 60698684Sdesdemote_sensitive_data(void) 60798684Sdes{ 60898684Sdes Key *tmp; 60998684Sdes int i; 61098684Sdes 61198684Sdes if (sensitive_data.server_key) { 61298684Sdes tmp = key_demote(sensitive_data.server_key); 61398684Sdes key_free(sensitive_data.server_key); 61498684Sdes sensitive_data.server_key = tmp; 61598684Sdes } 61698684Sdes 61798684Sdes for (i = 0; i < options.num_host_key_files; i++) { 61898684Sdes if (sensitive_data.host_keys[i]) { 61998684Sdes tmp = key_demote(sensitive_data.host_keys[i]); 62098684Sdes key_free(sensitive_data.host_keys[i]); 62198684Sdes sensitive_data.host_keys[i] = tmp; 62298684Sdes if (tmp->type == KEY_RSA1) 62398684Sdes sensitive_data.ssh1_host_key = tmp; 62498684Sdes } 625204917Sdes /* Certs do not need demotion */ 62698684Sdes } 62798684Sdes 62898684Sdes /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ 62998684Sdes} 63098684Sdes 63198684Sdesstatic void 63298684Sdesprivsep_preauth_child(void) 63398684Sdes{ 634197679Sdes u_int32_t rnd[256]; 635106130Sdes gid_t gidset[1]; 63698684Sdes 63798684Sdes /* Enable challenge-response authentication for privilege separation */ 63898684Sdes privsep_challenge_enable(); 63998684Sdes 640264377Sdes#ifdef GSSAPI 641264377Sdes /* Cache supported mechanism OIDs for later use */ 642264377Sdes if (options.gss_authentication) 643264377Sdes ssh_gssapi_prepare_supported_oids(); 644264377Sdes#endif 645264377Sdes 646181111Sdes arc4random_stir(); 647181111Sdes arc4random_buf(rnd, sizeof(rnd)); 648295367Sdes#ifdef WITH_OPENSSL 649106130Sdes RAND_seed(rnd, sizeof(rnd)); 650295367Sdes if ((RAND_bytes((u_char *)rnd, 1)) != 1) 651295367Sdes fatal("%s: RAND_bytes failed", __func__); 652295367Sdes#endif 653264377Sdes explicit_bzero(rnd, sizeof(rnd)); 65498684Sdes 65598684Sdes /* Demote the private keys to public keys. */ 65698684Sdes demote_sensitive_data(); 65798684Sdes 658296781Sdes /* Demote the child */ 659296781Sdes if (getuid() == 0 || geteuid() == 0) { 660296781Sdes /* Change our root directory */ 661296781Sdes if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) 662296781Sdes fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, 663296781Sdes strerror(errno)); 664296781Sdes if (chdir("/") == -1) 665296781Sdes fatal("chdir(\"/\"): %s", strerror(errno)); 66698684Sdes 667296781Sdes /* Drop our privileges */ 668296781Sdes debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, 669296781Sdes (u_int)privsep_pw->pw_gid); 670296781Sdes gidset[0] = privsep_pw->pw_gid; 671296781Sdes if (setgroups(1, gidset) < 0) 672296781Sdes fatal("setgroups: %.100s", strerror(errno)); 673296781Sdes permanently_set_uid(privsep_pw); 674296781Sdes } 67598684Sdes} 67698684Sdes 677126277Sdesstatic int 678126277Sdesprivsep_preauth(Authctxt *authctxt) 67998684Sdes{ 680295367Sdes int status, r; 68198684Sdes pid_t pid; 682226046Sdes struct ssh_sandbox *box = NULL; 68398684Sdes 68498684Sdes /* Set up unprivileged child process to deal with network data */ 68598684Sdes pmonitor = monitor_init(); 68698684Sdes /* Store a pointer to the kex for later rekeying */ 687295367Sdes pmonitor->m_pkex = &active_state->kex; 68898684Sdes 689240075Sdes if (use_privsep == PRIVSEP_ON) 690262566Sdes box = ssh_sandbox_init(pmonitor); 69198684Sdes pid = fork(); 69298684Sdes if (pid == -1) { 69398684Sdes fatal("fork of unprivileged child failed"); 69498684Sdes } else if (pid != 0) { 69598684Sdes debug2("Network child is on pid %ld", (long)pid); 69698684Sdes 697240075Sdes pmonitor->m_pid = pid; 698295367Sdes if (have_agent) { 699295367Sdes r = ssh_get_authentication_socket(&auth_sock); 700295367Sdes if (r != 0) { 701295367Sdes error("Could not get agent socket: %s", 702295367Sdes ssh_err(r)); 703295367Sdes have_agent = 0; 704295367Sdes } 705295367Sdes } 706226046Sdes if (box != NULL) 707226046Sdes ssh_sandbox_parent_preauth(box, pid); 708126277Sdes monitor_child_preauth(authctxt, pmonitor); 70998684Sdes 71098684Sdes /* Sync memory */ 71198684Sdes monitor_sync(pmonitor); 71298684Sdes 71398684Sdes /* Wait for the child's exit status */ 714226046Sdes while (waitpid(pid, &status, 0) < 0) { 715240075Sdes if (errno == EINTR) 716240075Sdes continue; 717240075Sdes pmonitor->m_pid = -1; 718240075Sdes fatal("%s: waitpid: %s", __func__, strerror(errno)); 719226046Sdes } 720240075Sdes privsep_is_preauth = 0; 721240075Sdes pmonitor->m_pid = -1; 722226046Sdes if (WIFEXITED(status)) { 723226046Sdes if (WEXITSTATUS(status) != 0) 724226046Sdes fatal("%s: preauth child exited with status %d", 725226046Sdes __func__, WEXITSTATUS(status)); 726226046Sdes } else if (WIFSIGNALED(status)) 727226046Sdes fatal("%s: preauth child terminated by signal %d", 728226046Sdes __func__, WTERMSIG(status)); 729226046Sdes if (box != NULL) 730226046Sdes ssh_sandbox_parent_finish(box); 731226046Sdes return 1; 73298684Sdes } else { 73398684Sdes /* child */ 73498684Sdes close(pmonitor->m_sendfd); 735226046Sdes close(pmonitor->m_log_recvfd); 73698684Sdes 737226046Sdes /* Arrange for logging to be sent to the monitor */ 738226046Sdes set_log_handler(mm_log_handler, pmonitor); 739226046Sdes 740296781Sdes privsep_preauth_child(); 74198684Sdes setproctitle("%s", "[net]"); 742226046Sdes if (box != NULL) 743226046Sdes ssh_sandbox_child(box); 744226046Sdes 745226046Sdes return 0; 74698684Sdes } 74798684Sdes} 74898684Sdes 74998684Sdesstatic void 75098684Sdesprivsep_postauth(Authctxt *authctxt) 75198684Sdes{ 752181111Sdes u_int32_t rnd[256]; 753181111Sdes 754106130Sdes#ifdef DISABLE_FD_PASSING 75599063Sdes if (1) { 75699063Sdes#else 75798684Sdes if (authctxt->pw->pw_uid == 0 || options.use_login) { 75899063Sdes#endif 75998684Sdes /* File descriptor passing is broken or root login */ 76098684Sdes use_privsep = 0; 761157019Sdes goto skip; 76298684Sdes } 76398684Sdes 76498684Sdes /* New socket pair */ 76598684Sdes monitor_reinit(pmonitor); 76698684Sdes 76798684Sdes pmonitor->m_pid = fork(); 76898684Sdes if (pmonitor->m_pid == -1) 76998684Sdes fatal("fork of unprivileged child failed"); 77098684Sdes else if (pmonitor->m_pid != 0) { 771181111Sdes verbose("User child is on pid %ld", (long)pmonitor->m_pid); 772137019Sdes buffer_clear(&loginmsg); 77398684Sdes monitor_child_postauth(pmonitor); 77498684Sdes 77598684Sdes /* NEVERREACHED */ 77698684Sdes exit(0); 77798684Sdes } 77898684Sdes 779226046Sdes /* child */ 780226046Sdes 78198684Sdes close(pmonitor->m_sendfd); 782226046Sdes pmonitor->m_sendfd = -1; 78398684Sdes 78498684Sdes /* Demote the private keys to public keys. */ 78598684Sdes demote_sensitive_data(); 78698684Sdes 787181111Sdes arc4random_stir(); 788181111Sdes arc4random_buf(rnd, sizeof(rnd)); 789295367Sdes#ifdef WITH_OPENSSL 790181111Sdes RAND_seed(rnd, sizeof(rnd)); 791295367Sdes if ((RAND_bytes((u_char *)rnd, 1)) != 1) 792295367Sdes fatal("%s: RAND_bytes failed", __func__); 793295367Sdes#endif 794264377Sdes explicit_bzero(rnd, sizeof(rnd)); 795181111Sdes 79698684Sdes /* Drop privileges */ 79798684Sdes do_setusercontext(authctxt->pw); 79898684Sdes 799157019Sdes skip: 80098684Sdes /* It is safe now to apply the key state */ 80198684Sdes monitor_apply_keystate(pmonitor); 802149753Sdes 803149753Sdes /* 804149753Sdes * Tell the packet layer that authentication was successful, since 805149753Sdes * this information is not part of the key state. 806149753Sdes */ 807149753Sdes packet_set_authenticated(); 80898684Sdes} 80998684Sdes 81092559Sdesstatic char * 81176262Sgreenlist_hostkey_types(void) 81276262Sgreen{ 81392559Sdes Buffer b; 814126277Sdes const char *p; 815126277Sdes char *ret; 81676262Sgreen int i; 817204917Sdes Key *key; 81892559Sdes 81992559Sdes buffer_init(&b); 82092559Sdes for (i = 0; i < options.num_host_key_files; i++) { 821204917Sdes key = sensitive_data.host_keys[i]; 82276262Sgreen if (key == NULL) 823255767Sdes key = sensitive_data.host_pubkeys[i]; 824295367Sdes if (key == NULL || key->type == KEY_RSA1) 82576262Sgreen continue; 826295367Sdes /* Check that the key is accepted in HostkeyAlgorithms */ 827295367Sdes if (match_pattern_list(sshkey_ssh_name(key), 828295367Sdes options.hostkeyalgorithms, 0) != 1) { 829295367Sdes debug3("%s: %s key not permitted by HostkeyAlgorithms", 830295367Sdes __func__, sshkey_ssh_name(key)); 831295367Sdes continue; 832295367Sdes } 83392559Sdes switch (key->type) { 83476262Sgreen case KEY_RSA: 83576262Sgreen case KEY_DSA: 836221420Sdes case KEY_ECDSA: 837262566Sdes case KEY_ED25519: 83892559Sdes if (buffer_len(&b) > 0) 83992559Sdes buffer_append(&b, ",", 1); 84092559Sdes p = key_ssh_name(key); 84192559Sdes buffer_append(&b, p, strlen(p)); 842296781Sdes 843296781Sdes /* for RSA we also support SHA2 signatures */ 844296781Sdes if (key->type == KEY_RSA) { 845296781Sdes p = ",rsa-sha2-512,rsa-sha2-256"; 846296781Sdes buffer_append(&b, p, strlen(p)); 847296781Sdes } 84876262Sgreen break; 84976262Sgreen } 850204917Sdes /* If the private key has a cert peer, then list that too */ 851204917Sdes key = sensitive_data.host_certificates[i]; 852204917Sdes if (key == NULL) 853204917Sdes continue; 854204917Sdes switch (key->type) { 855204917Sdes case KEY_RSA_CERT: 856204917Sdes case KEY_DSA_CERT: 857221420Sdes case KEY_ECDSA_CERT: 858262566Sdes case KEY_ED25519_CERT: 859204917Sdes if (buffer_len(&b) > 0) 860204917Sdes buffer_append(&b, ",", 1); 861204917Sdes p = key_ssh_name(key); 862204917Sdes buffer_append(&b, p, strlen(p)); 863204917Sdes break; 864204917Sdes } 86576262Sgreen } 866323124Sdes if ((ret = sshbuf_dup_string(&b)) == NULL) 867323124Sdes fatal("%s: sshbuf_dup_string failed", __func__); 86892559Sdes buffer_free(&b); 869126277Sdes debug("list_hostkey_types: %s", ret); 870126277Sdes return ret; 87176262Sgreen} 87276262Sgreen 873204917Sdesstatic Key * 874295367Sdesget_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) 87576262Sgreen{ 87676262Sgreen int i; 877204917Sdes Key *key; 87899063Sdes 87992559Sdes for (i = 0; i < options.num_host_key_files; i++) { 880215116Sdes switch (type) { 881215116Sdes case KEY_RSA_CERT: 882215116Sdes case KEY_DSA_CERT: 883221420Sdes case KEY_ECDSA_CERT: 884262566Sdes case KEY_ED25519_CERT: 885204917Sdes key = sensitive_data.host_certificates[i]; 886215116Sdes break; 887215116Sdes default: 888204917Sdes key = sensitive_data.host_keys[i]; 889255767Sdes if (key == NULL && !need_private) 890255767Sdes key = sensitive_data.host_pubkeys[i]; 891215116Sdes break; 892215116Sdes } 893295367Sdes if (key != NULL && key->type == type && 894295367Sdes (key->type != KEY_ECDSA || key->ecdsa_nid == nid)) 895204917Sdes return need_private ? 896204917Sdes sensitive_data.host_keys[i] : key; 89776262Sgreen } 89876262Sgreen return NULL; 89976262Sgreen} 90076262Sgreen 90198684SdesKey * 902295367Sdesget_hostkey_public_by_type(int type, int nid, struct ssh *ssh) 903204917Sdes{ 904295367Sdes return get_hostkey_by_type(type, nid, 0, ssh); 905204917Sdes} 906204917Sdes 907204917SdesKey * 908295367Sdesget_hostkey_private_by_type(int type, int nid, struct ssh *ssh) 909204917Sdes{ 910295367Sdes return get_hostkey_by_type(type, nid, 1, ssh); 911204917Sdes} 912204917Sdes 913204917SdesKey * 91498684Sdesget_hostkey_by_index(int ind) 91598684Sdes{ 91698684Sdes if (ind < 0 || ind >= options.num_host_key_files) 91798684Sdes return (NULL); 91898684Sdes return (sensitive_data.host_keys[ind]); 91998684Sdes} 92098684Sdes 921255767SdesKey * 922295367Sdesget_hostkey_public_by_index(int ind, struct ssh *ssh) 923255767Sdes{ 924255767Sdes if (ind < 0 || ind >= options.num_host_key_files) 925255767Sdes return (NULL); 926255767Sdes return (sensitive_data.host_pubkeys[ind]); 927255767Sdes} 928255767Sdes 92998684Sdesint 930295367Sdesget_hostkey_index(Key *key, int compare, struct ssh *ssh) 93198684Sdes{ 93298684Sdes int i; 93399063Sdes 93498684Sdes for (i = 0; i < options.num_host_key_files; i++) { 935204917Sdes if (key_is_cert(key)) { 936295367Sdes if (key == sensitive_data.host_certificates[i] || 937295367Sdes (compare && sensitive_data.host_certificates[i] && 938295367Sdes sshkey_equal(key, 939295367Sdes sensitive_data.host_certificates[i]))) 940204917Sdes return (i); 941204917Sdes } else { 942295367Sdes if (key == sensitive_data.host_keys[i] || 943295367Sdes (compare && sensitive_data.host_keys[i] && 944295367Sdes sshkey_equal(key, sensitive_data.host_keys[i]))) 945204917Sdes return (i); 946295367Sdes if (key == sensitive_data.host_pubkeys[i] || 947295367Sdes (compare && sensitive_data.host_pubkeys[i] && 948295367Sdes sshkey_equal(key, sensitive_data.host_pubkeys[i]))) 949255767Sdes return (i); 950204917Sdes } 95198684Sdes } 95298684Sdes return (-1); 95398684Sdes} 95498684Sdes 955295367Sdes/* Inform the client of all hostkeys */ 956295367Sdesstatic void 957295367Sdesnotify_hostkeys(struct ssh *ssh) 958295367Sdes{ 959295367Sdes struct sshbuf *buf; 960295367Sdes struct sshkey *key; 961295367Sdes int i, nkeys, r; 962295367Sdes char *fp; 963295367Sdes 964295367Sdes /* Some clients cannot cope with the hostkeys message, skip those. */ 965295367Sdes if (datafellows & SSH_BUG_HOSTKEYS) 966295367Sdes return; 967295367Sdes 968295367Sdes if ((buf = sshbuf_new()) == NULL) 969295367Sdes fatal("%s: sshbuf_new", __func__); 970295367Sdes for (i = nkeys = 0; i < options.num_host_key_files; i++) { 971295367Sdes key = get_hostkey_public_by_index(i, ssh); 972295367Sdes if (key == NULL || key->type == KEY_UNSPEC || 973295367Sdes key->type == KEY_RSA1 || sshkey_is_cert(key)) 974295367Sdes continue; 975295367Sdes fp = sshkey_fingerprint(key, options.fingerprint_hash, 976295367Sdes SSH_FP_DEFAULT); 977295367Sdes debug3("%s: key %d: %s %s", __func__, i, 978295367Sdes sshkey_ssh_name(key), fp); 979295367Sdes free(fp); 980295367Sdes if (nkeys == 0) { 981295367Sdes packet_start(SSH2_MSG_GLOBAL_REQUEST); 982295367Sdes packet_put_cstring("hostkeys-00@openssh.com"); 983295367Sdes packet_put_char(0); /* want-reply */ 984295367Sdes } 985295367Sdes sshbuf_reset(buf); 986295367Sdes if ((r = sshkey_putb(key, buf)) != 0) 987295367Sdes fatal("%s: couldn't put hostkey %d: %s", 988295367Sdes __func__, i, ssh_err(r)); 989295367Sdes packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); 990295367Sdes nkeys++; 991295367Sdes } 992295367Sdes debug3("%s: sent %d hostkeys", __func__, nkeys); 993295367Sdes if (nkeys == 0) 994295367Sdes fatal("%s: no hostkeys", __func__); 995295367Sdes packet_send(); 996295367Sdes sshbuf_free(buf); 997295367Sdes} 998295367Sdes 99957429Smarkm/* 100065674Skris * returns 1 if connection should be dropped, 0 otherwise. 100165674Skris * dropping starts at connection #max_startups_begin with a probability 100265674Skris * of (max_startups_rate/100). the probability increases linearly until 100365674Skris * all connections are dropped for startups > max_startups 100465674Skris */ 100592559Sdesstatic int 100665674Skrisdrop_connection(int startups) 100765674Skris{ 1008147005Sdes int p, r; 100965674Skris 101065674Skris if (startups < options.max_startups_begin) 101165674Skris return 0; 101265674Skris if (startups >= options.max_startups) 101365674Skris return 1; 101465674Skris if (options.max_startups_rate == 100) 101565674Skris return 1; 101665674Skris 101765674Skris p = 100 - options.max_startups_rate; 101865674Skris p *= startups - options.max_startups_begin; 1019147005Sdes p /= options.max_startups - options.max_startups_begin; 102065674Skris p += options.max_startups_rate; 1021181111Sdes r = arc4random_uniform(100); 102265674Skris 1023147005Sdes debug("drop_connection: p %d, r %d", p, r); 102465674Skris return (r < p) ? 1 : 0; 102565674Skris} 102665674Skris 102792559Sdesstatic void 102892559Sdesusage(void) 102992559Sdes{ 1030240075Sdes if (options.version_addendum && *options.version_addendum != '\0') 1031294693Sdes fprintf(stderr, "%s %s, %s\n", 1032294693Sdes SSH_RELEASE, 1033295367Sdes options.version_addendum, OPENSSL_VERSION); 1034240075Sdes else 1035294693Sdes fprintf(stderr, "%s, %s\n", 1036295367Sdes SSH_RELEASE, OPENSSL_VERSION); 1037128460Sdes fprintf(stderr, 1038204917Sdes"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" 1039255767Sdes" [-E log_file] [-f config_file] [-g login_grace_time]\n" 1040255767Sdes" [-h host_key_file] [-k key_gen_time] [-o option] [-p port]\n" 1041255767Sdes" [-u len]\n" 1042128460Sdes ); 104392559Sdes exit(1); 104492559Sdes} 104565674Skris 1046137019Sdesstatic void 1047323124Sdessend_rexec_state(int fd, struct sshbuf *conf) 1048137019Sdes{ 1049323124Sdes struct sshbuf *m; 1050323124Sdes int r; 1051137019Sdes 1052323124Sdes debug3("%s: entering fd = %d config len %zu", __func__, fd, 1053323124Sdes sshbuf_len(conf)); 1054137019Sdes 1055137019Sdes /* 1056137019Sdes * Protocol from reexec master to child: 1057137019Sdes * string configuration 1058137019Sdes * u_int ephemeral_key_follows 1059137019Sdes * bignum e (only if ephemeral_key_follows == 1) 1060137019Sdes * bignum n " 1061137019Sdes * bignum d " 1062137019Sdes * bignum iqmp " 1063137019Sdes * bignum p " 1064137019Sdes * bignum q " 1065157019Sdes * string rngseed (only if OpenSSL is not self-seeded) 1066137019Sdes */ 1067323124Sdes if ((m = sshbuf_new()) == NULL) 1068323124Sdes fatal("%s: sshbuf_new failed", __func__); 1069323124Sdes if ((r = sshbuf_put_stringb(m, conf)) != 0) 1070323124Sdes fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1071137019Sdes 1072295367Sdes#ifdef WITH_SSH1 1073137019Sdes if (sensitive_data.server_key != NULL && 1074137019Sdes sensitive_data.server_key->type == KEY_RSA1) { 1075323124Sdes if ((r = sshbuf_put_u32(m, 1)) != 0 || 1076323124Sdes (r = sshbuf_put_bignum1(m, 1077323124Sdes sensitive_data.server_key->rsa->e)) != 0 || 1078323124Sdes (r = sshbuf_put_bignum1(m, 1079323124Sdes sensitive_data.server_key->rsa->n)) != 0 || 1080323124Sdes (r = sshbuf_put_bignum1(m, 1081323124Sdes sensitive_data.server_key->rsa->d)) != 0 || 1082323124Sdes (r = sshbuf_put_bignum1(m, 1083323124Sdes sensitive_data.server_key->rsa->iqmp)) != 0 || 1084323124Sdes (r = sshbuf_put_bignum1(m, 1085323124Sdes sensitive_data.server_key->rsa->p)) != 0 || 1086323124Sdes (r = sshbuf_put_bignum1(m, 1087323124Sdes sensitive_data.server_key->rsa->q)) != 0) 1088323124Sdes fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1089137019Sdes } else 1090295367Sdes#endif 1091323124Sdes if ((r = sshbuf_put_u32(m, 0)) != 0) 1092323124Sdes fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1093137019Sdes 1094295367Sdes#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) 1095323124Sdes rexec_send_rng_seed(m); 1096157019Sdes#endif 1097157019Sdes 1098323124Sdes if (ssh_msg_send(fd, 0, m) == -1) 1099137019Sdes fatal("%s: ssh_msg_send failed", __func__); 1100137019Sdes 1101323124Sdes sshbuf_free(m); 1102137019Sdes 1103137019Sdes debug3("%s: done", __func__); 1104137019Sdes} 1105137019Sdes 1106137019Sdesstatic void 1107137019Sdesrecv_rexec_state(int fd, Buffer *conf) 1108137019Sdes{ 1109137019Sdes Buffer m; 1110137019Sdes char *cp; 1111137019Sdes u_int len; 1112137019Sdes 1113137019Sdes debug3("%s: entering fd = %d", __func__, fd); 1114137019Sdes 1115137019Sdes buffer_init(&m); 1116137019Sdes 1117137019Sdes if (ssh_msg_recv(fd, &m) == -1) 1118137019Sdes fatal("%s: ssh_msg_recv failed", __func__); 1119137019Sdes if (buffer_get_char(&m) != 0) 1120137019Sdes fatal("%s: rexec version mismatch", __func__); 1121137019Sdes 1122137019Sdes cp = buffer_get_string(&m, &len); 1123137019Sdes if (conf != NULL) 1124323124Sdes buffer_append(conf, cp, len); 1125255767Sdes free(cp); 1126137019Sdes 1127137019Sdes if (buffer_get_int(&m)) { 1128295367Sdes#ifdef WITH_SSH1 1129137019Sdes if (sensitive_data.server_key != NULL) 1130137019Sdes key_free(sensitive_data.server_key); 1131137019Sdes sensitive_data.server_key = key_new_private(KEY_RSA1); 1132137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->e); 1133137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->n); 1134137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->d); 1135137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); 1136137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); 1137137019Sdes buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); 1138295367Sdes if (rsa_generate_additional_parameters( 1139295367Sdes sensitive_data.server_key->rsa) != 0) 1140295367Sdes fatal("%s: rsa_generate_additional_parameters " 1141295367Sdes "error", __func__); 1142295367Sdes#endif 1143137019Sdes } 1144157019Sdes 1145295367Sdes#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) 1146157019Sdes rexec_recv_rng_seed(&m); 1147157019Sdes#endif 1148157019Sdes 1149137019Sdes buffer_free(&m); 1150137019Sdes 1151137019Sdes debug3("%s: done", __func__); 1152137019Sdes} 1153137019Sdes 1154162856Sdes/* Accept a connection from inetd */ 1155162856Sdesstatic void 1156162856Sdesserver_accept_inetd(int *sock_in, int *sock_out) 1157162856Sdes{ 1158162856Sdes int fd; 1159162856Sdes 1160162856Sdes startup_pipe = -1; 1161162856Sdes if (rexeced_flag) { 1162162856Sdes close(REEXEC_CONFIG_PASS_FD); 1163162856Sdes *sock_in = *sock_out = dup(STDIN_FILENO); 1164162856Sdes if (!debug_flag) { 1165162856Sdes startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); 1166162856Sdes close(REEXEC_STARTUP_PIPE_FD); 1167162856Sdes } 1168162856Sdes } else { 1169162856Sdes *sock_in = dup(STDIN_FILENO); 1170162856Sdes *sock_out = dup(STDOUT_FILENO); 1171162856Sdes } 1172162856Sdes /* 1173162856Sdes * We intentionally do not close the descriptors 0, 1, and 2 1174162856Sdes * as our code for setting the descriptors won't work if 1175162856Sdes * ttyfd happens to be one of those. 1176162856Sdes */ 1177162856Sdes if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 1178162856Sdes dup2(fd, STDIN_FILENO); 1179162856Sdes dup2(fd, STDOUT_FILENO); 1180255767Sdes if (!log_stderr) 1181255767Sdes dup2(fd, STDERR_FILENO); 1182255767Sdes if (fd > (log_stderr ? STDERR_FILENO : STDOUT_FILENO)) 1183162856Sdes close(fd); 1184162856Sdes } 1185162856Sdes debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out); 1186162856Sdes} 1187162856Sdes 118865674Skris/* 1189162856Sdes * Listen for TCP connections 1190162856Sdes */ 1191162856Sdesstatic void 1192162856Sdesserver_listen(void) 1193162856Sdes{ 1194162856Sdes int ret, listen_sock, on = 1; 1195162856Sdes struct addrinfo *ai; 1196162856Sdes char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 1197224638Sbrooks int socksize; 1198224638Sbrooks socklen_t len; 1199162856Sdes 1200162856Sdes for (ai = options.listen_addrs; ai; ai = ai->ai_next) { 1201162856Sdes if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 1202162856Sdes continue; 1203162856Sdes if (num_listen_socks >= MAX_LISTEN_SOCKS) 1204162856Sdes fatal("Too many listen sockets. " 1205162856Sdes "Enlarge MAX_LISTEN_SOCKS"); 1206162856Sdes if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, 1207162856Sdes ntop, sizeof(ntop), strport, sizeof(strport), 1208162856Sdes NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 1209162856Sdes error("getnameinfo failed: %.100s", 1210181111Sdes ssh_gai_strerror(ret)); 1211162856Sdes continue; 1212162856Sdes } 1213162856Sdes /* Create socket for listening. */ 1214162856Sdes listen_sock = socket(ai->ai_family, ai->ai_socktype, 1215162856Sdes ai->ai_protocol); 1216162856Sdes if (listen_sock < 0) { 1217162856Sdes /* kernel may not support ipv6 */ 1218162856Sdes verbose("socket: %.100s", strerror(errno)); 1219162856Sdes continue; 1220162856Sdes } 1221162856Sdes if (set_nonblock(listen_sock) == -1) { 1222162856Sdes close(listen_sock); 1223162856Sdes continue; 1224162856Sdes } 1225162856Sdes /* 1226162856Sdes * Set socket options. 1227162856Sdes * Allow local port reuse in TIME_WAIT. 1228162856Sdes */ 1229162856Sdes if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, 1230162856Sdes &on, sizeof(on)) == -1) 1231162856Sdes error("setsockopt SO_REUSEADDR: %s", strerror(errno)); 1232162856Sdes 1233181111Sdes /* Only communicate in IPv6 over AF_INET6 sockets. */ 1234204917Sdes if (ai->ai_family == AF_INET6) 1235204917Sdes sock_set_v6only(listen_sock); 1236181111Sdes 1237162856Sdes debug("Bind to port %s on %s.", strport, ntop); 1238162856Sdes 1239224638Sbrooks len = sizeof(socksize); 1240224638Sbrooks getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &socksize, &len); 1241224638Sbrooks debug("Server TCP RWIN socket size: %d", socksize); 1242224638Sbrooks 1243162856Sdes /* Bind the socket to the desired port. */ 1244162856Sdes if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { 1245162856Sdes error("Bind to port %s on %s failed: %.200s.", 1246162856Sdes strport, ntop, strerror(errno)); 1247162856Sdes close(listen_sock); 1248162856Sdes continue; 1249162856Sdes } 1250162856Sdes listen_socks[num_listen_socks] = listen_sock; 1251162856Sdes num_listen_socks++; 1252162856Sdes 1253162856Sdes /* Start listening on the port. */ 1254162856Sdes if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0) 1255162856Sdes fatal("listen on [%s]:%s: %.100s", 1256162856Sdes ntop, strport, strerror(errno)); 1257162856Sdes logit("Server listening on %s port %s.", ntop, strport); 1258162856Sdes } 1259162856Sdes freeaddrinfo(options.listen_addrs); 1260162856Sdes 1261162856Sdes if (!num_listen_socks) 1262162856Sdes fatal("Cannot bind any address."); 1263162856Sdes} 1264162856Sdes 1265162856Sdes/* 1266162856Sdes * The main TCP accept loop. Note that, for the non-debug case, returns 1267162856Sdes * from this function are in a forked subprocess. 1268162856Sdes */ 1269162856Sdesstatic void 1270162856Sdesserver_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) 1271162856Sdes{ 1272162856Sdes fd_set *fdset; 1273162856Sdes int i, j, ret, maxfd; 1274162856Sdes int key_used = 0, startups = 0; 1275162856Sdes int startup_p[2] = { -1 , -1 }; 1276162856Sdes struct sockaddr_storage from; 1277162856Sdes socklen_t fromlen; 1278162856Sdes pid_t pid; 1279262566Sdes u_char rnd[256]; 1280162856Sdes 1281162856Sdes /* setup fd set for accept */ 1282162856Sdes fdset = NULL; 1283162856Sdes maxfd = 0; 1284162856Sdes for (i = 0; i < num_listen_socks; i++) 1285162856Sdes if (listen_socks[i] > maxfd) 1286162856Sdes maxfd = listen_socks[i]; 1287162856Sdes /* pipes connected to unauthenticated childs */ 1288162856Sdes startup_pipes = xcalloc(options.max_startups, sizeof(int)); 1289162856Sdes for (i = 0; i < options.max_startups; i++) 1290162856Sdes startup_pipes[i] = -1; 1291162856Sdes 1292162856Sdes /* 1293162856Sdes * Stay listening for connections until the system crashes or 1294162856Sdes * the daemon is killed with a signal. 1295162856Sdes */ 1296162856Sdes for (;;) { 1297162856Sdes if (received_sighup) 1298162856Sdes sighup_restart(); 1299296781Sdes free(fdset); 1300295367Sdes fdset = xcalloc(howmany(maxfd + 1, NFDBITS), 1301162856Sdes sizeof(fd_mask)); 1302162856Sdes 1303162856Sdes for (i = 0; i < num_listen_socks; i++) 1304162856Sdes FD_SET(listen_socks[i], fdset); 1305162856Sdes for (i = 0; i < options.max_startups; i++) 1306162856Sdes if (startup_pipes[i] != -1) 1307162856Sdes FD_SET(startup_pipes[i], fdset); 1308162856Sdes 1309162856Sdes /* Wait in select until there is a connection. */ 1310162856Sdes ret = select(maxfd+1, fdset, NULL, NULL, NULL); 1311162856Sdes if (ret < 0 && errno != EINTR) 1312162856Sdes error("select: %.100s", strerror(errno)); 1313162856Sdes if (received_sigterm) { 1314162856Sdes logit("Received signal %d; terminating.", 1315162856Sdes (int) received_sigterm); 1316162856Sdes close_listen_socks(); 1317295367Sdes if (options.pid_file != NULL) 1318295367Sdes unlink(options.pid_file); 1319226046Sdes exit(received_sigterm == SIGTERM ? 0 : 255); 1320162856Sdes } 1321162856Sdes if (key_used && key_do_regen) { 1322162856Sdes generate_ephemeral_server_key(); 1323162856Sdes key_used = 0; 1324162856Sdes key_do_regen = 0; 1325162856Sdes } 1326162856Sdes if (ret < 0) 1327162856Sdes continue; 1328162856Sdes 1329162856Sdes for (i = 0; i < options.max_startups; i++) 1330162856Sdes if (startup_pipes[i] != -1 && 1331162856Sdes FD_ISSET(startup_pipes[i], fdset)) { 1332162856Sdes /* 1333162856Sdes * the read end of the pipe is ready 1334162856Sdes * if the child has closed the pipe 1335162856Sdes * after successful authentication 1336162856Sdes * or if the child has died 1337162856Sdes */ 1338162856Sdes close(startup_pipes[i]); 1339162856Sdes startup_pipes[i] = -1; 1340162856Sdes startups--; 1341162856Sdes } 1342162856Sdes for (i = 0; i < num_listen_socks; i++) { 1343162856Sdes if (!FD_ISSET(listen_socks[i], fdset)) 1344162856Sdes continue; 1345162856Sdes fromlen = sizeof(from); 1346162856Sdes *newsock = accept(listen_socks[i], 1347162856Sdes (struct sockaddr *)&from, &fromlen); 1348162856Sdes if (*newsock < 0) { 1349255767Sdes if (errno != EINTR && errno != EWOULDBLOCK && 1350255767Sdes errno != ECONNABORTED && errno != EAGAIN) 1351240075Sdes error("accept: %.100s", 1352240075Sdes strerror(errno)); 1353240075Sdes if (errno == EMFILE || errno == ENFILE) 1354240075Sdes usleep(100 * 1000); 1355162856Sdes continue; 1356162856Sdes } 1357162856Sdes if (unset_nonblock(*newsock) == -1) { 1358162856Sdes close(*newsock); 1359162856Sdes continue; 1360162856Sdes } 1361162856Sdes if (drop_connection(startups) == 1) { 1362162856Sdes debug("drop connection #%d", startups); 1363162856Sdes close(*newsock); 1364162856Sdes continue; 1365162856Sdes } 1366162856Sdes if (pipe(startup_p) == -1) { 1367162856Sdes close(*newsock); 1368162856Sdes continue; 1369162856Sdes } 1370162856Sdes 1371162856Sdes if (rexec_flag && socketpair(AF_UNIX, 1372162856Sdes SOCK_STREAM, 0, config_s) == -1) { 1373162856Sdes error("reexec socketpair: %s", 1374162856Sdes strerror(errno)); 1375162856Sdes close(*newsock); 1376162856Sdes close(startup_p[0]); 1377162856Sdes close(startup_p[1]); 1378162856Sdes continue; 1379162856Sdes } 1380162856Sdes 1381162856Sdes for (j = 0; j < options.max_startups; j++) 1382162856Sdes if (startup_pipes[j] == -1) { 1383162856Sdes startup_pipes[j] = startup_p[0]; 1384162856Sdes if (maxfd < startup_p[0]) 1385162856Sdes maxfd = startup_p[0]; 1386162856Sdes startups++; 1387162856Sdes break; 1388162856Sdes } 1389162856Sdes 1390162856Sdes /* 1391162856Sdes * Got connection. Fork a child to handle it, unless 1392162856Sdes * we are in debugging mode. 1393162856Sdes */ 1394162856Sdes if (debug_flag) { 1395162856Sdes /* 1396162856Sdes * In debugging mode. Close the listening 1397162856Sdes * socket, and start processing the 1398162856Sdes * connection without forking. 1399162856Sdes */ 1400162856Sdes debug("Server will not fork when running in debugging mode."); 1401162856Sdes close_listen_socks(); 1402162856Sdes *sock_in = *newsock; 1403162856Sdes *sock_out = *newsock; 1404162856Sdes close(startup_p[0]); 1405162856Sdes close(startup_p[1]); 1406162856Sdes startup_pipe = -1; 1407162856Sdes pid = getpid(); 1408162856Sdes if (rexec_flag) { 1409162856Sdes send_rexec_state(config_s[0], 1410162856Sdes &cfg); 1411162856Sdes close(config_s[0]); 1412162856Sdes } 1413162856Sdes break; 1414162856Sdes } 1415162856Sdes 1416162856Sdes /* 1417162856Sdes * Normal production daemon. Fork, and have 1418162856Sdes * the child process the connection. The 1419162856Sdes * parent continues listening. 1420162856Sdes */ 1421162856Sdes platform_pre_fork(); 1422162856Sdes if ((pid = fork()) == 0) { 1423162856Sdes /* 1424162856Sdes * Child. Close the listening and 1425162856Sdes * max_startup sockets. Start using 1426162856Sdes * the accepted socket. Reinitialize 1427162856Sdes * logging (since our pid has changed). 1428162856Sdes * We break out of the loop to handle 1429162856Sdes * the connection. 1430162856Sdes */ 1431162856Sdes platform_post_fork_child(); 1432162856Sdes startup_pipe = startup_p[1]; 1433162856Sdes close_startup_pipes(); 1434162856Sdes close_listen_socks(); 1435162856Sdes *sock_in = *newsock; 1436162856Sdes *sock_out = *newsock; 1437162856Sdes log_init(__progname, 1438162856Sdes options.log_level, 1439162856Sdes options.log_facility, 1440162856Sdes log_stderr); 1441162856Sdes if (rexec_flag) 1442162856Sdes close(config_s[0]); 1443162856Sdes break; 1444162856Sdes } 1445162856Sdes 1446162856Sdes /* Parent. Stay in the loop. */ 1447162856Sdes platform_post_fork_parent(pid); 1448162856Sdes if (pid < 0) 1449162856Sdes error("fork: %.100s", strerror(errno)); 1450162856Sdes else 1451162856Sdes debug("Forked child %ld.", (long)pid); 1452162856Sdes 1453162856Sdes close(startup_p[1]); 1454162856Sdes 1455162856Sdes if (rexec_flag) { 1456162856Sdes send_rexec_state(config_s[0], &cfg); 1457162856Sdes close(config_s[0]); 1458162856Sdes close(config_s[1]); 1459162856Sdes } 1460162856Sdes 1461162856Sdes /* 1462162856Sdes * Mark that the key has been used (it 1463162856Sdes * was "given" to the child). 1464162856Sdes */ 1465162856Sdes if ((options.protocol & SSH_PROTO_1) && 1466162856Sdes key_used == 0) { 1467162856Sdes /* Schedule server key regeneration alarm. */ 1468162856Sdes signal(SIGALRM, key_regeneration_alarm); 1469162856Sdes alarm(options.key_regeneration_time); 1470162856Sdes key_used = 1; 1471162856Sdes } 1472162856Sdes 1473162856Sdes close(*newsock); 1474162856Sdes 1475162856Sdes /* 1476162856Sdes * Ensure that our random state differs 1477162856Sdes * from that of the child 1478162856Sdes */ 1479162856Sdes arc4random_stir(); 1480262566Sdes arc4random_buf(rnd, sizeof(rnd)); 1481295367Sdes#ifdef WITH_OPENSSL 1482262566Sdes RAND_seed(rnd, sizeof(rnd)); 1483295367Sdes if ((RAND_bytes((u_char *)rnd, 1)) != 1) 1484295367Sdes fatal("%s: RAND_bytes failed", __func__); 1485295367Sdes#endif 1486264377Sdes explicit_bzero(rnd, sizeof(rnd)); 1487162856Sdes } 1488162856Sdes 1489162856Sdes /* child process check (or debug mode) */ 1490162856Sdes if (num_listen_socks < 0) 1491162856Sdes break; 1492162856Sdes } 1493162856Sdes} 1494162856Sdes 1495323124Sdes/* 1496323124Sdes * If IP options are supported, make sure there are none (log and 1497323124Sdes * return an error if any are found). Basically we are worried about 1498323124Sdes * source routing; it can be used to pretend you are somebody 1499323124Sdes * (ip-address) you are not. That itself may be "almost acceptable" 1500323124Sdes * under certain circumstances, but rhosts autentication is useless 1501323124Sdes * if source routing is accepted. Notice also that if we just dropped 1502323124Sdes * source routing here, the other side could use IP spoofing to do 1503323124Sdes * rest of the interaction and could still bypass security. So we 1504323124Sdes * exit here if we detect any IP options. 1505323124Sdes */ 1506323124Sdesstatic void 1507323124Sdescheck_ip_options(struct ssh *ssh) 1508323124Sdes{ 1509323124Sdes#ifdef IP_OPTIONS 1510323124Sdes int sock_in = ssh_packet_get_connection_in(ssh); 1511323124Sdes struct sockaddr_storage from; 1512323124Sdes socklen_t option_size, i, fromlen = sizeof(from); 1513323124Sdes u_char opts[200]; 1514323124Sdes char text[sizeof(opts) * 3 + 1]; 1515162856Sdes 1516323124Sdes memset(&from, 0, sizeof(from)); 1517323124Sdes if (getpeername(sock_in, (struct sockaddr *)&from, 1518323124Sdes &fromlen) < 0) 1519323124Sdes return; 1520323124Sdes if (from.ss_family != AF_INET) 1521323124Sdes return; 1522323124Sdes /* XXX IPv6 options? */ 1523323124Sdes 1524323124Sdes if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, 1525323124Sdes &option_size) >= 0 && option_size != 0) { 1526323124Sdes text[0] = '\0'; 1527323124Sdes for (i = 0; i < option_size; i++) 1528323124Sdes snprintf(text + i*3, sizeof(text) - i*3, 1529323124Sdes " %2.2x", opts[i]); 1530323124Sdes fatal("Connection from %.100s port %d with IP opts: %.800s", 1531323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); 1532323124Sdes } 1533323124Sdes return; 1534323124Sdes#endif /* IP_OPTIONS */ 1535323124Sdes} 1536323124Sdes 1537162856Sdes/* 153857429Smarkm * Main program for the daemon. 153957429Smarkm */ 154057429Smarkmint 154157429Smarkmmain(int ac, char **av) 154257429Smarkm{ 1543323124Sdes struct ssh *ssh = NULL; 154457429Smarkm extern char *optarg; 154557429Smarkm extern int optind; 1546295367Sdes int r, opt, i, j, on = 1; 1547137019Sdes int sock_in = -1, sock_out = -1, newsock = -1; 154857429Smarkm const char *remote_ip; 154957429Smarkm int remote_port; 1550295367Sdes char *fp, *line, *laddr, *logfile = NULL; 1551162856Sdes int config_s[2] = { -1 , -1 }; 1552248619Sdes u_int n; 1553181111Sdes u_int64_t ibytes, obytes; 1554181111Sdes mode_t new_umask; 1555126277Sdes Key *key; 1556255767Sdes Key *pubkey; 1557255767Sdes int keytype; 155898684Sdes Authctxt *authctxt; 1559240075Sdes struct connection_info *connection_info = get_connection_info(0, 0); 156057429Smarkm 1561296781Sdes ssh_malloc_init(); /* must be called before any mallocs */ 1562296781Sdes 156398941Sdes#ifdef HAVE_SECUREWARE 156498941Sdes (void)set_auth_parameters(ac, av); 156598941Sdes#endif 1566124211Sdes __progname = ssh_get_progname(av[0]); 156798941Sdes 1568113911Sdes /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ 156998941Sdes saved_argc = ac; 1570137019Sdes rexec_argc = ac; 1571162856Sdes saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); 1572113911Sdes for (i = 0; i < ac; i++) 1573113911Sdes saved_argv[i] = xstrdup(av[i]); 1574124211Sdes saved_argv[i] = NULL; 157557429Smarkm 1576113911Sdes#ifndef HAVE_SETPROCTITLE 1577113911Sdes /* Prepare for later setproctitle emulation */ 1578113911Sdes compat_init_setproctitle(ac, av); 1579124211Sdes av = saved_argv; 1580113911Sdes#endif 1581113911Sdes 1582128460Sdes if (geteuid() == 0 && setgroups(0, NULL) == -1) 1583128460Sdes debug("setgroups(): %.200s", strerror(errno)); 1584128460Sdes 1585157019Sdes /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1586157019Sdes sanitise_stdfd(); 1587157019Sdes 158857429Smarkm /* Initialize configuration options to their default values. */ 158957429Smarkm initialize_server_options(&options); 159057429Smarkm 159157429Smarkm /* Parse command-line arguments. */ 1592295367Sdes while ((opt = getopt(ac, av, 1593295367Sdes "C:E:b:c:f:g:h:k:o:p:u:46DQRTdeiqrt")) != -1) { 159457429Smarkm switch (opt) { 159557429Smarkm case '4': 1596147005Sdes options.address_family = AF_INET; 159757429Smarkm break; 159857429Smarkm case '6': 1599147005Sdes options.address_family = AF_INET6; 160057429Smarkm break; 160157429Smarkm case 'f': 160257429Smarkm config_file_name = optarg; 160357429Smarkm break; 1604204917Sdes case 'c': 1605204917Sdes if (options.num_host_cert_files >= MAX_HOSTCERTS) { 1606204917Sdes fprintf(stderr, "too many host certificates.\n"); 1607204917Sdes exit(1); 1608204917Sdes } 1609204917Sdes options.host_cert_files[options.num_host_cert_files++] = 1610204917Sdes derelativise_path(optarg); 1611204917Sdes break; 161257429Smarkm case 'd': 1613124211Sdes if (debug_flag == 0) { 161469591Sgreen debug_flag = 1; 161569591Sgreen options.log_level = SYSLOG_LEVEL_DEBUG1; 1616124211Sdes } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) 161769591Sgreen options.log_level++; 161857429Smarkm break; 161976262Sgreen case 'D': 162076262Sgreen no_daemon_flag = 1; 162176262Sgreen break; 1622255767Sdes case 'E': 1623296781Sdes logfile = optarg; 1624255767Sdes /* FALLTHROUGH */ 162576262Sgreen case 'e': 162676262Sgreen log_stderr = 1; 162776262Sgreen break; 162857429Smarkm case 'i': 162957429Smarkm inetd_flag = 1; 163057429Smarkm break; 1631137019Sdes case 'r': 1632137019Sdes rexec_flag = 0; 1633137019Sdes break; 1634137019Sdes case 'R': 1635137019Sdes rexeced_flag = 1; 1636137019Sdes inetd_flag = 1; 1637137019Sdes break; 163857429Smarkm case 'Q': 163976262Sgreen /* ignored */ 164057429Smarkm break; 164157429Smarkm case 'q': 164257429Smarkm options.log_level = SYSLOG_LEVEL_QUIET; 164357429Smarkm break; 164457429Smarkm case 'b': 1645162856Sdes options.server_key_bits = (int)strtonum(optarg, 256, 1646162856Sdes 32768, NULL); 164757429Smarkm break; 164857429Smarkm case 'p': 164957429Smarkm options.ports_from_cmdline = 1; 165069591Sgreen if (options.num_ports >= MAX_PORTS) { 165169591Sgreen fprintf(stderr, "too many ports.\n"); 165269591Sgreen exit(1); 165369591Sgreen } 165476262Sgreen options.ports[options.num_ports++] = a2port(optarg); 1655192595Sdes if (options.ports[options.num_ports-1] <= 0) { 165676262Sgreen fprintf(stderr, "Bad port number.\n"); 165776262Sgreen exit(1); 165876262Sgreen } 165957429Smarkm break; 166057429Smarkm case 'g': 166192559Sdes if ((options.login_grace_time = convtime(optarg)) == -1) { 166292559Sdes fprintf(stderr, "Invalid login grace time.\n"); 166392559Sdes exit(1); 166492559Sdes } 166557429Smarkm break; 166657429Smarkm case 'k': 166792559Sdes if ((options.key_regeneration_time = convtime(optarg)) == -1) { 166892559Sdes fprintf(stderr, "Invalid key regeneration interval.\n"); 166992559Sdes exit(1); 167092559Sdes } 167157429Smarkm break; 167257429Smarkm case 'h': 167376262Sgreen if (options.num_host_key_files >= MAX_HOSTKEYS) { 167476262Sgreen fprintf(stderr, "too many host keys.\n"); 167576262Sgreen exit(1); 167676262Sgreen } 1677204917Sdes options.host_key_files[options.num_host_key_files++] = 1678204917Sdes derelativise_path(optarg); 167957429Smarkm break; 168092559Sdes case 't': 168192559Sdes test_flag = 1; 168292559Sdes break; 1683181111Sdes case 'T': 1684181111Sdes test_flag = 2; 1685181111Sdes break; 1686181111Sdes case 'C': 1687240075Sdes if (parse_server_match_testspec(connection_info, 1688240075Sdes optarg) == -1) 1689240075Sdes exit(1); 1690181111Sdes break; 169165674Skris case 'u': 1692295367Sdes utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); 1693295367Sdes if (utmp_len > HOST_NAME_MAX+1) { 1694106130Sdes fprintf(stderr, "Invalid utmp length.\n"); 1695106130Sdes exit(1); 1696106130Sdes } 169765674Skris break; 169892559Sdes case 'o': 1699126277Sdes line = xstrdup(optarg); 1700126277Sdes if (process_server_config_line(&options, line, 1701240075Sdes "command-line", 0, NULL, NULL) != 0) 170292559Sdes exit(1); 1703255767Sdes free(line); 170492559Sdes break; 170557429Smarkm case '?': 170657429Smarkm default: 170792559Sdes usage(); 170892559Sdes break; 170957429Smarkm } 171057429Smarkm } 1711137019Sdes if (rexeced_flag || inetd_flag) 1712137019Sdes rexec_flag = 0; 1713181111Sdes if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/'))) 1714137019Sdes fatal("sshd re-exec requires execution with an absolute path"); 1715137019Sdes if (rexeced_flag) 1716137019Sdes closefrom(REEXEC_MIN_FREE_FD); 1717137019Sdes else 1718137019Sdes closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); 1719137019Sdes 1720295367Sdes#ifdef WITH_OPENSSL 1721221420Sdes OpenSSL_add_all_algorithms(); 1722295367Sdes#endif 172357429Smarkm 1724255767Sdes /* If requested, redirect the logs to the specified logfile. */ 1725296781Sdes if (logfile != NULL) 1726255767Sdes log_redirect_stderr_to(logfile); 172757429Smarkm /* 172857429Smarkm * Force logging to stderr until we have loaded the private host 172957429Smarkm * key (unless started from inetd) 173057429Smarkm */ 173176262Sgreen log_init(__progname, 173292559Sdes options.log_level == SYSLOG_LEVEL_NOT_SET ? 173392559Sdes SYSLOG_LEVEL_INFO : options.log_level, 173492559Sdes options.log_facility == SYSLOG_FACILITY_NOT_SET ? 173592559Sdes SYSLOG_FACILITY_AUTH : options.log_facility, 1736113911Sdes log_stderr || !inetd_flag); 173757429Smarkm 1738128460Sdes /* 1739128460Sdes * Unset KRB5CCNAME, otherwise the user's session may inherit it from 1740128460Sdes * root's environment 1741149753Sdes */ 1742147005Sdes if (getenv("KRB5CCNAME") != NULL) 1743240075Sdes (void) unsetenv("KRB5CCNAME"); 1744147005Sdes 1745106130Sdes#ifdef _UNICOS 1746137019Sdes /* Cray can define user privs drop all privs now! 174798941Sdes * Not needed on PRIV_SU systems! 174898941Sdes */ 174998941Sdes drop_cray_privs(); 175098941Sdes#endif 175198941Sdes 1752137019Sdes sensitive_data.server_key = NULL; 1753137019Sdes sensitive_data.ssh1_host_key = NULL; 1754137019Sdes sensitive_data.have_ssh1_key = 0; 1755137019Sdes sensitive_data.have_ssh2_key = 0; 175657429Smarkm 1757181111Sdes /* 1758181111Sdes * If we're doing an extended config test, make sure we have all of 1759181111Sdes * the parameters we need. If we're not doing an extended test, 1760181111Sdes * do not silently ignore connection test params. 1761181111Sdes */ 1762240075Sdes if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0) 1763181111Sdes fatal("user, host and addr are all required when testing " 1764181111Sdes "Match configs"); 1765240075Sdes if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0) 1766181111Sdes fatal("Config test connection parameter (-C) provided without " 1767181111Sdes "test mode (-T)"); 1768181111Sdes 1769137019Sdes /* Fetch our configuration */ 1770137019Sdes buffer_init(&cfg); 1771137019Sdes if (rexeced_flag) 1772137019Sdes recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg); 1773295367Sdes else if (strcasecmp(config_file_name, "none") != 0) 1774137019Sdes load_server_config(config_file_name, &cfg); 1775137019Sdes 1776162856Sdes parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, 1777240075Sdes &cfg, NULL); 1778137019Sdes 1779157019Sdes seed_rng(); 1780157019Sdes 178157429Smarkm /* Fill in default values for those options not explicitly set. */ 178257429Smarkm fill_default_server_options(&options); 178357429Smarkm 1784181111Sdes /* challenge-response is implemented via keyboard interactive */ 1785181111Sdes if (options.challenge_response_authentication) 1786181111Sdes options.kbd_interactive_authentication = 1; 1787181111Sdes 1788248619Sdes /* Check that options are sensible */ 1789248619Sdes if (options.authorized_keys_command_user == NULL && 1790248619Sdes (options.authorized_keys_command != NULL && 1791248619Sdes strcasecmp(options.authorized_keys_command, "none") != 0)) 1792248619Sdes fatal("AuthorizedKeysCommand set without " 1793248619Sdes "AuthorizedKeysCommandUser"); 1794295367Sdes if (options.authorized_principals_command_user == NULL && 1795295367Sdes (options.authorized_principals_command != NULL && 1796295367Sdes strcasecmp(options.authorized_principals_command, "none") != 0)) 1797295367Sdes fatal("AuthorizedPrincipalsCommand set without " 1798295367Sdes "AuthorizedPrincipalsCommandUser"); 1799248619Sdes 1800248619Sdes /* 1801248619Sdes * Check whether there is any path through configured auth methods. 1802248619Sdes * Unfortunately it is not possible to verify this generally before 1803248619Sdes * daemonisation in the presence of Match block, but this catches 1804248619Sdes * and warns for trivial misconfigurations that could break login. 1805248619Sdes */ 1806248619Sdes if (options.num_auth_methods != 0) { 1807248619Sdes if ((options.protocol & SSH_PROTO_1)) 1808248619Sdes fatal("AuthenticationMethods is not supported with " 1809248619Sdes "SSH protocol 1"); 1810248619Sdes for (n = 0; n < options.num_auth_methods; n++) { 1811248619Sdes if (auth2_methods_valid(options.auth_methods[n], 1812248619Sdes 1) == 0) 1813248619Sdes break; 1814248619Sdes } 1815248619Sdes if (n >= options.num_auth_methods) 1816248619Sdes fatal("AuthenticationMethods cannot be satisfied by " 1817248619Sdes "enabled authentication methods"); 1818248619Sdes } 1819248619Sdes 1820147005Sdes /* set default channel AF */ 1821147005Sdes channel_set_af(options.address_family); 1822147005Sdes 182357429Smarkm /* Check that there are no remaining arguments. */ 182457429Smarkm if (optind < ac) { 182557429Smarkm fprintf(stderr, "Extra argument %s.\n", av[optind]); 182657429Smarkm exit(1); 182757429Smarkm } 182857429Smarkm 1829294693Sdes debug("sshd version %s, %s", SSH_VERSION, 1830295367Sdes#ifdef WITH_OPENSSL 1831295367Sdes SSLeay_version(SSLEAY_VERSION) 1832295367Sdes#else 1833295367Sdes "without OpenSSL" 1834295367Sdes#endif 1835295367Sdes ); 183657429Smarkm 1837164149Sdes /* Store privilege separation user for later use if required. */ 1838164149Sdes if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { 1839164149Sdes if (use_privsep || options.kerberos_authentication) 1840164149Sdes fatal("Privilege separation user %s does not exist", 1841164149Sdes SSH_PRIVSEP_USER); 1842164149Sdes } else { 1843264377Sdes explicit_bzero(privsep_pw->pw_passwd, 1844264377Sdes strlen(privsep_pw->pw_passwd)); 1845164149Sdes privsep_pw = pwcopy(privsep_pw); 1846255767Sdes free(privsep_pw->pw_passwd); 1847164149Sdes privsep_pw->pw_passwd = xstrdup("*"); 1848164149Sdes } 1849162856Sdes endpwent(); 1850162856Sdes 1851255767Sdes /* load host keys */ 1852162856Sdes sensitive_data.host_keys = xcalloc(options.num_host_key_files, 1853106130Sdes sizeof(Key *)); 1854255767Sdes sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, 1855255767Sdes sizeof(Key *)); 185660576Skris 1857255767Sdes if (options.host_key_agent) { 1858255767Sdes if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) 1859255767Sdes setenv(SSH_AUTHSOCKET_ENV_NAME, 1860255767Sdes options.host_key_agent, 1); 1861295367Sdes if ((r = ssh_get_authentication_socket(NULL)) == 0) 1862295367Sdes have_agent = 1; 1863295367Sdes else 1864295367Sdes error("Could not connect to agent \"%s\": %s", 1865295367Sdes options.host_key_agent, ssh_err(r)); 1866255767Sdes } 1867255767Sdes 186892559Sdes for (i = 0; i < options.num_host_key_files; i++) { 1869295367Sdes if (options.host_key_files[i] == NULL) 1870295367Sdes continue; 187176262Sgreen key = key_load_private(options.host_key_files[i], "", NULL); 1872255767Sdes pubkey = key_load_public(options.host_key_files[i], NULL); 1873295367Sdes if (pubkey == NULL && key != NULL) 1874295367Sdes pubkey = key_demote(key); 187576262Sgreen sensitive_data.host_keys[i] = key; 1876255767Sdes sensitive_data.host_pubkeys[i] = pubkey; 1877255767Sdes 1878255767Sdes if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 && 1879255767Sdes have_agent) { 1880255767Sdes debug("will rely on agent for hostkey %s", 1881255767Sdes options.host_key_files[i]); 1882255767Sdes keytype = pubkey->type; 1883255767Sdes } else if (key != NULL) { 1884255767Sdes keytype = key->type; 1885255767Sdes } else { 188676262Sgreen error("Could not load host key: %s", 188776262Sgreen options.host_key_files[i]); 188876262Sgreen sensitive_data.host_keys[i] = NULL; 1889255767Sdes sensitive_data.host_pubkeys[i] = NULL; 189076262Sgreen continue; 189176262Sgreen } 1892255767Sdes 1893255767Sdes switch (keytype) { 189476262Sgreen case KEY_RSA1: 189576262Sgreen sensitive_data.ssh1_host_key = key; 189676262Sgreen sensitive_data.have_ssh1_key = 1; 189776262Sgreen break; 189876262Sgreen case KEY_RSA: 189976262Sgreen case KEY_DSA: 1900221420Sdes case KEY_ECDSA: 1901262566Sdes case KEY_ED25519: 1902295367Sdes if (have_agent || key != NULL) 1903295367Sdes sensitive_data.have_ssh2_key = 1; 190476262Sgreen break; 190576262Sgreen } 1906295367Sdes if ((fp = sshkey_fingerprint(pubkey, options.fingerprint_hash, 1907295367Sdes SSH_FP_DEFAULT)) == NULL) 1908295367Sdes fatal("sshkey_fingerprint failed"); 1909295367Sdes debug("%s host key #%d: %s %s", 1910295367Sdes key ? "private" : "agent", i, keytype == KEY_RSA1 ? 1911295367Sdes sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); 1912295367Sdes free(fp); 191376262Sgreen } 191476262Sgreen if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { 1915124211Sdes logit("Disabling protocol version 1. Could not load host key"); 191660576Skris options.protocol &= ~SSH_PROTO_1; 191760576Skris } 191876262Sgreen if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1919124211Sdes logit("Disabling protocol version 2. Could not load host key"); 192076262Sgreen options.protocol &= ~SSH_PROTO_2; 192160576Skris } 192276262Sgreen if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1923124211Sdes logit("sshd: no hostkeys available -- exiting."); 192457429Smarkm exit(1); 192557429Smarkm } 192657429Smarkm 1927204917Sdes /* 1928204917Sdes * Load certificates. They are stored in an array at identical 1929204917Sdes * indices to the public keys that they relate to. 1930204917Sdes */ 1931204917Sdes sensitive_data.host_certificates = xcalloc(options.num_host_key_files, 1932204917Sdes sizeof(Key *)); 1933204917Sdes for (i = 0; i < options.num_host_key_files; i++) 1934204917Sdes sensitive_data.host_certificates[i] = NULL; 1935204917Sdes 1936204917Sdes for (i = 0; i < options.num_host_cert_files; i++) { 1937295367Sdes if (options.host_cert_files[i] == NULL) 1938295367Sdes continue; 1939204917Sdes key = key_load_public(options.host_cert_files[i], NULL); 1940204917Sdes if (key == NULL) { 1941204917Sdes error("Could not load host certificate: %s", 1942204917Sdes options.host_cert_files[i]); 1943204917Sdes continue; 1944204917Sdes } 1945204917Sdes if (!key_is_cert(key)) { 1946204917Sdes error("Certificate file is not a certificate: %s", 1947204917Sdes options.host_cert_files[i]); 1948204917Sdes key_free(key); 1949204917Sdes continue; 1950204917Sdes } 1951204917Sdes /* Find matching private key */ 1952204917Sdes for (j = 0; j < options.num_host_key_files; j++) { 1953204917Sdes if (key_equal_public(key, 1954204917Sdes sensitive_data.host_keys[j])) { 1955204917Sdes sensitive_data.host_certificates[j] = key; 1956204917Sdes break; 1957204917Sdes } 1958204917Sdes } 1959204917Sdes if (j >= options.num_host_key_files) { 1960204917Sdes error("No matching private key for certificate: %s", 1961204917Sdes options.host_cert_files[i]); 1962204917Sdes key_free(key); 1963204917Sdes continue; 1964204917Sdes } 1965204917Sdes sensitive_data.host_certificates[j] = key; 1966204917Sdes debug("host certificate: #%d type %d %s", j, key->type, 1967204917Sdes key_type(key)); 1968204917Sdes } 1969295367Sdes 1970295367Sdes#ifdef WITH_SSH1 197160576Skris /* Check certain values for sanity. */ 197260576Skris if (options.protocol & SSH_PROTO_1) { 1973295367Sdes if (options.server_key_bits < SSH_RSA_MINIMUM_MODULUS_SIZE || 1974295367Sdes options.server_key_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { 197560576Skris fprintf(stderr, "Bad server key size.\n"); 197660576Skris exit(1); 197760576Skris } 197860576Skris /* 197960576Skris * Check that server and host key lengths differ sufficiently. This 198060576Skris * is necessary to make double encryption work with rsaref. Oh, I 198160576Skris * hate software patents. I dont know if this can go? Niels 198260576Skris */ 198360576Skris if (options.server_key_bits > 198499063Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - 198599063Sdes SSH_KEY_BITS_RESERVED && options.server_key_bits < 198699063Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + 198799063Sdes SSH_KEY_BITS_RESERVED) { 198860576Skris options.server_key_bits = 198999063Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + 199099063Sdes SSH_KEY_BITS_RESERVED; 199160576Skris debug("Forcing server key to %d bits to make it differ from host key.", 199260576Skris options.server_key_bits); 199360576Skris } 199460576Skris } 1995295367Sdes#endif 199660576Skris 199798684Sdes if (use_privsep) { 199898684Sdes struct stat st; 199998684Sdes 200098684Sdes if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || 200198684Sdes (S_ISDIR(st.st_mode) == 0)) 200298684Sdes fatal("Missing privilege separation directory: %s", 200398684Sdes _PATH_PRIVSEP_CHROOT_DIR); 2004106130Sdes 2005106130Sdes#ifdef HAVE_CYGWIN 2006106130Sdes if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) && 2007106130Sdes (st.st_uid != getuid () || 2008106130Sdes (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)) 2009106130Sdes#else 201099063Sdes if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) 2011106130Sdes#endif 2012113911Sdes fatal("%s must be owned by root and not group or " 2013113911Sdes "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); 201498684Sdes } 201598684Sdes 2016181111Sdes if (test_flag > 1) { 2017240075Sdes if (server_match_spec_complete(connection_info) == 1) 2018240075Sdes parse_server_match_config(&options, connection_info); 2019181111Sdes dump_config(&options); 2020181111Sdes } 2021181111Sdes 202292559Sdes /* Configuration looks good, so exit if in test mode. */ 202392559Sdes if (test_flag) 202492559Sdes exit(0); 202592559Sdes 202698941Sdes /* 202798941Sdes * Clear out any supplemental groups we may have inherited. This 202898941Sdes * prevents inadvertent creation of files with bad modes (in the 2029126277Sdes * portable version at least, it's certainly possible for PAM 2030126277Sdes * to create a file, and we can't control the code in every 203198941Sdes * module which might be used). 203298941Sdes */ 203398941Sdes if (setgroups(0, NULL) < 0) 203498941Sdes debug("setgroups() failed: %.200s", strerror(errno)); 203598941Sdes 2036137019Sdes if (rexec_flag) { 2037162856Sdes rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *)); 2038137019Sdes for (i = 0; i < rexec_argc; i++) { 2039137019Sdes debug("rexec_argv[%d]='%s'", i, saved_argv[i]); 2040137019Sdes rexec_argv[i] = saved_argv[i]; 2041137019Sdes } 2042137019Sdes rexec_argv[rexec_argc] = "-R"; 2043137019Sdes rexec_argv[rexec_argc + 1] = NULL; 2044137019Sdes } 2045137019Sdes 2046181111Sdes /* Ensure that umask disallows at least group and world write */ 2047181111Sdes new_umask = umask(0077) | 0022; 2048181111Sdes (void) umask(new_umask); 2049181111Sdes 205060576Skris /* Initialize the log (it is reinitialized below in case we forked). */ 2051147005Sdes if (debug_flag && (!inetd_flag || rexeced_flag)) 205257429Smarkm log_stderr = 1; 205376262Sgreen log_init(__progname, options.log_level, options.log_facility, log_stderr); 205457429Smarkm 205560576Skris /* 205660576Skris * If not in debugging mode, and not started from inetd, disconnect 205760576Skris * from the controlling terminal, and fork. The original process 205860576Skris * exits. 205960576Skris */ 206076262Sgreen if (!(debug_flag || inetd_flag || no_daemon_flag)) { 206157429Smarkm#ifdef TIOCNOTTY 206257429Smarkm int fd; 206357429Smarkm#endif /* TIOCNOTTY */ 206457429Smarkm if (daemon(0, 0) < 0) 206557429Smarkm fatal("daemon() failed: %.200s", strerror(errno)); 206657429Smarkm 206757429Smarkm /* Disconnect from the controlling tty. */ 206857429Smarkm#ifdef TIOCNOTTY 206976262Sgreen fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); 207057429Smarkm if (fd >= 0) { 207157429Smarkm (void) ioctl(fd, TIOCNOTTY, NULL); 207257429Smarkm close(fd); 207357429Smarkm } 207457429Smarkm#endif /* TIOCNOTTY */ 207557429Smarkm } 207657429Smarkm /* Reinitialize the log (because of the fork above). */ 207776262Sgreen log_init(__progname, options.log_level, options.log_facility, log_stderr); 207857429Smarkm 2079206397Skib /* Avoid killing the process in high-pressure swapping environments. */ 2080206397Skib if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0) 2081206397Skib debug("madvise(): %.200s", strerror(errno)); 2082206397Skib 208357429Smarkm /* Chdir to the root directory so that the current disk can be 208457429Smarkm unmounted if desired. */ 2085255767Sdes if (chdir("/") == -1) 2086255767Sdes error("chdir(\"/\"): %s", strerror(errno)); 208792559Sdes 208876262Sgreen /* ignore SIGPIPE */ 208976262Sgreen signal(SIGPIPE, SIG_IGN); 209057429Smarkm 2091162856Sdes /* Get a connection, either from inetd or a listening TCP socket */ 209257429Smarkm if (inetd_flag) { 2093162856Sdes server_accept_inetd(&sock_in, &sock_out); 209457429Smarkm } else { 2095204917Sdes platform_pre_listen(); 2096162856Sdes server_listen(); 209757429Smarkm 209892559Sdes if (options.protocol & SSH_PROTO_1) 209992559Sdes generate_ephemeral_server_key(); 210092559Sdes 210192559Sdes signal(SIGHUP, sighup_handler); 2102162856Sdes signal(SIGCHLD, main_sigchld_handler); 210392559Sdes signal(SIGTERM, sigterm_handler); 210492559Sdes signal(SIGQUIT, sigterm_handler); 210592559Sdes 2106162856Sdes /* 2107162856Sdes * Write out the pid file after the sigterm handler 2108162856Sdes * is setup and the listen sockets are bound 2109162856Sdes */ 2110295367Sdes if (options.pid_file != NULL && !debug_flag) { 2111162856Sdes FILE *f = fopen(options.pid_file, "w"); 211292559Sdes 2113124211Sdes if (f == NULL) { 2114124211Sdes error("Couldn't create pid file \"%s\": %s", 2115124211Sdes options.pid_file, strerror(errno)); 2116124211Sdes } else { 211798684Sdes fprintf(f, "%ld\n", (long) getpid()); 211857429Smarkm fclose(f); 211957429Smarkm } 212057429Smarkm } 212157429Smarkm 2122162856Sdes /* Accept a connection and return in a forked child */ 2123162856Sdes server_accept_loop(&sock_in, &sock_out, 2124162856Sdes &newsock, config_s); 212557429Smarkm } 212657429Smarkm 212757429Smarkm /* This is the child processing a new connection. */ 2128128460Sdes setproctitle("%s", "[accepted]"); 212957429Smarkm 213057429Smarkm /* 213198684Sdes * Create a new session and process group since the 4.4BSD 213298684Sdes * setlogin() affects the entire process group. We don't 213398684Sdes * want the child to be able to affect the parent. 213498684Sdes */ 2135124211Sdes#if !defined(SSHD_ACQUIRES_CTTY) 2136113911Sdes /* 2137124211Sdes * If setsid is called, on some platforms sshd will later acquire a 2138124211Sdes * controlling terminal which will result in "could not set 2139124211Sdes * controlling tty" errors. 2140113911Sdes */ 214199063Sdes if (!debug_flag && !inetd_flag && setsid() < 0) 214298684Sdes error("setsid: %.100s", strerror(errno)); 214398941Sdes#endif 214498684Sdes 2145137019Sdes if (rexec_flag) { 2146137019Sdes int fd; 2147137019Sdes 2148137019Sdes debug("rexec start in %d out %d newsock %d pipe %d sock %d", 2149137019Sdes sock_in, sock_out, newsock, startup_pipe, config_s[0]); 2150137019Sdes dup2(newsock, STDIN_FILENO); 2151137019Sdes dup2(STDIN_FILENO, STDOUT_FILENO); 2152137019Sdes if (startup_pipe == -1) 2153137019Sdes close(REEXEC_STARTUP_PIPE_FD); 2154262566Sdes else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { 2155137019Sdes dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD); 2156262566Sdes close(startup_pipe); 2157262566Sdes startup_pipe = REEXEC_STARTUP_PIPE_FD; 2158262566Sdes } 2159137019Sdes 2160137019Sdes dup2(config_s[1], REEXEC_CONFIG_PASS_FD); 2161137019Sdes close(config_s[1]); 2162137019Sdes 2163137019Sdes execv(rexec_argv[0], rexec_argv); 2164137019Sdes 2165137019Sdes /* Reexec has failed, fall back and continue */ 2166137019Sdes error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); 2167137019Sdes recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL); 2168137019Sdes log_init(__progname, options.log_level, 2169137019Sdes options.log_facility, log_stderr); 2170137019Sdes 2171137019Sdes /* Clean up fds */ 2172137019Sdes close(REEXEC_CONFIG_PASS_FD); 2173137019Sdes newsock = sock_out = sock_in = dup(STDIN_FILENO); 2174137019Sdes if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 2175137019Sdes dup2(fd, STDIN_FILENO); 2176137019Sdes dup2(fd, STDOUT_FILENO); 2177137019Sdes if (fd > STDERR_FILENO) 2178137019Sdes close(fd); 2179137019Sdes } 2180137019Sdes debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d", 2181137019Sdes sock_in, sock_out, newsock, startup_pipe, config_s[0]); 2182137019Sdes } 2183137019Sdes 2184204917Sdes /* Executed child processes don't need these. */ 2185204917Sdes fcntl(sock_out, F_SETFD, FD_CLOEXEC); 2186204917Sdes fcntl(sock_in, F_SETFD, FD_CLOEXEC); 2187204917Sdes 218898684Sdes /* 218957429Smarkm * Disable the key regeneration alarm. We will not regenerate the 219057429Smarkm * key since we are no longer in a position to give it to anyone. We 219157429Smarkm * will not restart on SIGHUP since it no longer makes sense. 219257429Smarkm */ 219357429Smarkm alarm(0); 219457429Smarkm signal(SIGALRM, SIG_DFL); 219557429Smarkm signal(SIGHUP, SIG_DFL); 219657429Smarkm signal(SIGTERM, SIG_DFL); 219757429Smarkm signal(SIGQUIT, SIG_DFL); 219857429Smarkm signal(SIGCHLD, SIG_DFL); 219998941Sdes signal(SIGINT, SIG_DFL); 220057429Smarkm 2201109683Sdes#ifdef __FreeBSD__ 220257429Smarkm /* 2203109683Sdes * Initialize the resolver. This may not happen automatically 2204231584Sed * before privsep chroot(). 2205109683Sdes */ 2206109683Sdes if ((_res.options & RES_INIT) == 0) { 2207231584Sed debug("res_init()"); 2208231584Sed res_init(); 2209109683Sdes } 2210153838Sdfr#ifdef GSSAPI 2211153838Sdfr /* 2212153838Sdfr * Force GSS-API to parse its configuration and load any 2213153838Sdfr * mechanism plugins. 2214153838Sdfr */ 2215153838Sdfr { 2216153838Sdfr gss_OID_set mechs; 2217153838Sdfr OM_uint32 minor_status; 2218153838Sdfr gss_indicate_mechs(&minor_status, &mechs); 2219153838Sdfr gss_release_oid_set(&minor_status, &mechs); 2220153838Sdfr } 2221109683Sdes#endif 2222153838Sdfr#endif 2223109683Sdes 2224109683Sdes /* 222557429Smarkm * Register our connection. This turns encryption off because we do 222657429Smarkm * not have a key. 222757429Smarkm */ 222857429Smarkm packet_set_connection(sock_in, sock_out); 2229149753Sdes packet_set_server(); 2230323124Sdes ssh = active_state; /* XXX */ 2231323124Sdes check_ip_options(ssh); 223257429Smarkm 2233149753Sdes /* Set SO_KEEPALIVE if requested. */ 2234149753Sdes if (options.tcp_keep_alive && packet_connection_is_on_socket() && 2235149753Sdes setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) 2236149753Sdes error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 2237149753Sdes 2238323124Sdes if ((remote_port = ssh_remote_port(ssh)) < 0) { 2239323124Sdes debug("ssh_remote_port failed"); 2240149753Sdes cleanup_exit(255); 2241149753Sdes } 224257429Smarkm 2243157019Sdes /* 2244162856Sdes * The rest of the code depends on the fact that 2245323124Sdes * ssh_remote_ipaddr() caches the remote ip, even if 2246162856Sdes * the socket goes away. 2247162856Sdes */ 2248323124Sdes remote_ip = ssh_remote_ipaddr(ssh); 2249157019Sdes 2250147005Sdes#ifdef SSH_AUDIT_EVENTS 2251147005Sdes audit_connection_from(remote_ip, remote_port); 2252147005Sdes#endif 225392559Sdes#ifdef LIBWRAP 2254181111Sdes allow_severity = options.log_facility|LOG_INFO; 2255181111Sdes deny_severity = options.log_facility|LOG_WARNING; 225657429Smarkm /* Check whether logins are denied from this host. */ 2257137019Sdes if (packet_connection_is_on_socket()) { 225857429Smarkm struct request_info req; 225957429Smarkm 226092559Sdes request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); 226157429Smarkm fromhost(&req); 226257429Smarkm 226357429Smarkm if (!hosts_access(&req)) { 226492559Sdes debug("Connection refused by tcp wrapper"); 226576262Sgreen refuse(&req); 226692559Sdes /* NOTREACHED */ 226792559Sdes fatal("libwrap refuse returns"); 226857429Smarkm } 226957429Smarkm } 227057429Smarkm#endif /* LIBWRAP */ 227192559Sdes 227257429Smarkm /* Log the connection. */ 2273295367Sdes laddr = get_local_ipaddr(sock_in); 2274262566Sdes verbose("Connection from %s port %d on %s port %d", 2275323124Sdes remote_ip, remote_port, laddr, ssh_local_port(ssh)); 2276295367Sdes free(laddr); 227757429Smarkm 227857429Smarkm /* 2279157019Sdes * We don't want to listen forever unless the other side 228057429Smarkm * successfully authenticates itself. So we set up an alarm which is 228157429Smarkm * cleared after successful authentication. A limit of zero 2282157019Sdes * indicates no limit. Note that we don't set the alarm in debugging 228357429Smarkm * mode; it is just annoying to have the server exit just when you 228457429Smarkm * are about to discover the bug. 228557429Smarkm */ 228657429Smarkm signal(SIGALRM, grace_alarm_handler); 228757429Smarkm if (!debug_flag) 228857429Smarkm alarm(options.login_grace_time); 228957429Smarkm 2290323124Sdes sshd_exchange_identification(ssh, sock_in, sock_out); 229157429Smarkm 2292181111Sdes /* In inetd mode, generate ephemeral key only for proto 1 connections */ 2293181111Sdes if (!compat20 && inetd_flag && sensitive_data.server_key == NULL) 2294181111Sdes generate_ephemeral_server_key(); 2295181111Sdes 229657429Smarkm packet_set_nonblocking(); 229757429Smarkm 2298126277Sdes /* allocate authentication context */ 2299162856Sdes authctxt = xcalloc(1, sizeof(*authctxt)); 2300126277Sdes 2301147005Sdes authctxt->loginmsg = &loginmsg; 2302147005Sdes 2303126277Sdes /* XXX global for cleanup, access from other modules */ 2304126277Sdes the_authctxt = authctxt; 2305126277Sdes 2306147005Sdes /* prepare buffer to collect messages to display to user after login */ 2307147005Sdes buffer_init(&loginmsg); 2308204917Sdes auth_debug_reset(); 2309147005Sdes 2310255767Sdes if (use_privsep) { 2311126277Sdes if (privsep_preauth(authctxt) == 1) 231298684Sdes goto authenticated; 2313295367Sdes } else if (compat20 && have_agent) { 2314295367Sdes if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { 2315295367Sdes error("Unable to get agent socket: %s", ssh_err(r)); 2316295367Sdes have_agent = 0; 2317295367Sdes } 2318295367Sdes } 231998684Sdes 232057429Smarkm /* perform the key exchange */ 232157429Smarkm /* authenticate user and start session */ 232260576Skris if (compat20) { 232360576Skris do_ssh2_kex(); 2324126277Sdes do_authentication2(authctxt); 232560576Skris } else { 2326295367Sdes#ifdef WITH_SSH1 232760576Skris do_ssh1_kex(); 2328126277Sdes do_authentication(authctxt); 2329295367Sdes#else 2330295367Sdes fatal("ssh1 not supported"); 2331295367Sdes#endif 233260576Skris } 233398684Sdes /* 233498684Sdes * If we use privilege separation, the unprivileged child transfers 233598684Sdes * the current keystate and exits 233698684Sdes */ 233798684Sdes if (use_privsep) { 233898684Sdes mm_send_keystate(pmonitor); 233998684Sdes exit(0); 234098684Sdes } 234198684Sdes 234298684Sdes authenticated: 2343157019Sdes /* 2344157019Sdes * Cancel the alarm we set to limit the time taken for 2345157019Sdes * authentication. 2346157019Sdes */ 2347157019Sdes alarm(0); 2348157019Sdes signal(SIGALRM, SIG_DFL); 2349162856Sdes authctxt->authenticated = 1; 2350157019Sdes if (startup_pipe != -1) { 2351157019Sdes close(startup_pipe); 2352157019Sdes startup_pipe = -1; 2353157019Sdes } 2354157019Sdes 2355147005Sdes#ifdef SSH_AUDIT_EVENTS 2356147005Sdes audit_event(SSH_AUTH_SUCCESS); 2357147005Sdes#endif 2358147005Sdes 2359181111Sdes#ifdef GSSAPI 2360181111Sdes if (options.gss_authentication) { 2361181111Sdes temporarily_use_uid(authctxt->pw); 2362181111Sdes ssh_gssapi_storecreds(); 2363181111Sdes restore_uid(); 2364181111Sdes } 2365181111Sdes#endif 2366181111Sdes#ifdef USE_PAM 2367181111Sdes if (options.use_pam) { 2368181111Sdes do_pam_setcred(1); 2369181111Sdes do_pam_session(); 2370181111Sdes } 2371181111Sdes#endif 2372181111Sdes 237398684Sdes /* 237498684Sdes * In privilege separation, we fork another child and prepare 237598684Sdes * file descriptor passing. 237698684Sdes */ 237798684Sdes if (use_privsep) { 237898684Sdes privsep_postauth(authctxt); 237998684Sdes /* the monitor process [priv] will not return */ 238098684Sdes if (!compat20) 238198684Sdes destroy_sensitive_data(); 238298684Sdes } 238398684Sdes 2384181111Sdes packet_set_timeout(options.client_alive_interval, 2385181111Sdes options.client_alive_count_max); 2386181111Sdes 2387295367Sdes /* Try to send all our hostkeys to the client */ 2388295367Sdes if (compat20) 2389295367Sdes notify_hostkeys(active_state); 2390295367Sdes 2391126277Sdes /* Start session. */ 239298684Sdes do_authenticated(authctxt); 239398684Sdes 239457429Smarkm /* The connection has been terminated. */ 2395295367Sdes packet_get_bytes(&ibytes, &obytes); 2396221420Sdes verbose("Transferred: sent %llu, received %llu bytes", 2397221420Sdes (unsigned long long)obytes, (unsigned long long)ibytes); 239869591Sgreen 2399181111Sdes verbose("Closing connection to %.500s port %d", remote_ip, remote_port); 2400181111Sdes 240169591Sgreen#ifdef USE_PAM 2402124211Sdes if (options.use_pam) 2403124211Sdes finish_pam(); 240469591Sgreen#endif /* USE_PAM */ 240569591Sgreen 2406147005Sdes#ifdef SSH_AUDIT_EVENTS 2407147005Sdes PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); 2408147005Sdes#endif 2409147005Sdes 241057429Smarkm packet_close(); 241198684Sdes 241298684Sdes if (use_privsep) 241398684Sdes mm_terminate(); 241498684Sdes 241557429Smarkm exit(0); 241657429Smarkm} 241757429Smarkm 2418295367Sdes#ifdef WITH_SSH1 241957429Smarkm/* 242098684Sdes * Decrypt session_key_int using our private server key and private host key 242198684Sdes * (key with larger modulus first). 242298684Sdes */ 242398684Sdesint 242498684Sdesssh1_session_key(BIGNUM *session_key_int) 242598684Sdes{ 2426323124Sdes struct ssh *ssh = active_state; /* XXX */ 242798684Sdes int rsafail = 0; 242898684Sdes 2429162856Sdes if (BN_cmp(sensitive_data.server_key->rsa->n, 2430162856Sdes sensitive_data.ssh1_host_key->rsa->n) > 0) { 243198684Sdes /* Server key has bigger modulus. */ 243298684Sdes if (BN_num_bits(sensitive_data.server_key->rsa->n) < 2433162856Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + 2434162856Sdes SSH_KEY_BITS_RESERVED) { 2435323124Sdes fatal("do_connection: %s port %d: " 2436162856Sdes "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", 2437323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 243898684Sdes BN_num_bits(sensitive_data.server_key->rsa->n), 243998684Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), 244098684Sdes SSH_KEY_BITS_RESERVED); 244198684Sdes } 244298684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2443295367Sdes sensitive_data.server_key->rsa) != 0) 244498684Sdes rsafail++; 244598684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2446295367Sdes sensitive_data.ssh1_host_key->rsa) != 0) 244798684Sdes rsafail++; 244898684Sdes } else { 244998684Sdes /* Host key has bigger modulus (or they are equal). */ 245098684Sdes if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < 2451162856Sdes BN_num_bits(sensitive_data.server_key->rsa->n) + 2452162856Sdes SSH_KEY_BITS_RESERVED) { 2453323124Sdes fatal("do_connection: %s port %d: " 2454162856Sdes "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", 2455323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 245698684Sdes BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), 245798684Sdes BN_num_bits(sensitive_data.server_key->rsa->n), 245898684Sdes SSH_KEY_BITS_RESERVED); 245998684Sdes } 246098684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2461295367Sdes sensitive_data.ssh1_host_key->rsa) != 0) 246298684Sdes rsafail++; 246398684Sdes if (rsa_private_decrypt(session_key_int, session_key_int, 2464295367Sdes sensitive_data.server_key->rsa) != 0) 246598684Sdes rsafail++; 246698684Sdes } 246798684Sdes return (rsafail); 246898684Sdes} 2469295367Sdes 247098684Sdes/* 247157429Smarkm * SSH1 key exchange 247257429Smarkm */ 247392559Sdesstatic void 247476262Sgreendo_ssh1_kex(void) 247557429Smarkm{ 2476323124Sdes struct ssh *ssh = active_state; /* XXX */ 247757429Smarkm int i, len; 247872397Skris int rsafail = 0; 2479295367Sdes BIGNUM *session_key_int, *fake_key_int, *real_key_int; 248076262Sgreen u_char session_key[SSH_SESSION_KEY_LENGTH]; 2481295367Sdes u_char fake_key_bytes[4096 / 8]; 2482295367Sdes size_t fake_key_len; 248376262Sgreen u_char cookie[8]; 248476262Sgreen u_int cipher_type, auth_mask, protocol_flags; 248557429Smarkm 248657429Smarkm /* 248757429Smarkm * Generate check bytes that the client must send back in the user 248857429Smarkm * packet in order for it to be accepted; this is used to defy ip 248957429Smarkm * spoofing attacks. Note that this only works against somebody 249057429Smarkm * doing IP spoofing from a remote machine; any machine on the local 249157429Smarkm * network can still see outgoing packets and catch the random 249257429Smarkm * cookie. This only affects rhosts authentication, and this is one 249357429Smarkm * of the reasons why it is inherently insecure. 249457429Smarkm */ 2495181111Sdes arc4random_buf(cookie, sizeof(cookie)); 249657429Smarkm 249757429Smarkm /* 249857429Smarkm * Send our public key. We include in the packet 64 bits of random 249957429Smarkm * data that must be matched in the reply in order to prevent IP 250057429Smarkm * spoofing. 250157429Smarkm */ 250257429Smarkm packet_start(SSH_SMSG_PUBLIC_KEY); 250357429Smarkm for (i = 0; i < 8; i++) 250457429Smarkm packet_put_char(cookie[i]); 250557429Smarkm 250657429Smarkm /* Store our public server RSA key. */ 250776262Sgreen packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); 250876262Sgreen packet_put_bignum(sensitive_data.server_key->rsa->e); 250976262Sgreen packet_put_bignum(sensitive_data.server_key->rsa->n); 251057429Smarkm 251157429Smarkm /* Store our public host RSA key. */ 251276262Sgreen packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); 251376262Sgreen packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); 251476262Sgreen packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); 251557429Smarkm 251657429Smarkm /* Put protocol flags. */ 251757429Smarkm packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); 251857429Smarkm 251957429Smarkm /* Declare which ciphers we support. */ 252069591Sgreen packet_put_int(cipher_mask_ssh1(0)); 252157429Smarkm 252257429Smarkm /* Declare supported authentication types. */ 252357429Smarkm auth_mask = 0; 252457429Smarkm if (options.rhosts_rsa_authentication) 252557429Smarkm auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; 252657429Smarkm if (options.rsa_authentication) 252757429Smarkm auth_mask |= 1 << SSH_AUTH_RSA; 252892559Sdes if (options.challenge_response_authentication == 1) 252957429Smarkm auth_mask |= 1 << SSH_AUTH_TIS; 253057429Smarkm if (options.password_authentication) 253157429Smarkm auth_mask |= 1 << SSH_AUTH_PASSWORD; 253257429Smarkm packet_put_int(auth_mask); 253357429Smarkm 253457429Smarkm /* Send the packet and wait for it to be sent. */ 253557429Smarkm packet_send(); 253657429Smarkm packet_write_wait(); 253757429Smarkm 253876262Sgreen debug("Sent %d bit server key and %d bit host key.", 253976262Sgreen BN_num_bits(sensitive_data.server_key->rsa->n), 254076262Sgreen BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); 254157429Smarkm 254257429Smarkm /* Read clients reply (cipher type and session key). */ 254392559Sdes packet_read_expect(SSH_CMSG_SESSION_KEY); 254457429Smarkm 254557429Smarkm /* Get cipher type and check whether we accept this. */ 254657429Smarkm cipher_type = packet_get_char(); 254757429Smarkm 254869591Sgreen if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) 254957429Smarkm packet_disconnect("Warning: client selects unsupported cipher."); 255057429Smarkm 255157429Smarkm /* Get check bytes from the packet. These must match those we 255257429Smarkm sent earlier with the public key packet. */ 255357429Smarkm for (i = 0; i < 8; i++) 255457429Smarkm if (cookie[i] != packet_get_char()) 255557429Smarkm packet_disconnect("IP Spoofing check bytes do not match."); 255657429Smarkm 255757429Smarkm debug("Encryption type: %.200s", cipher_name(cipher_type)); 255857429Smarkm 255957429Smarkm /* Get the encrypted integer. */ 2560295367Sdes if ((real_key_int = BN_new()) == NULL) 256192559Sdes fatal("do_ssh1_kex: BN_new failed"); 2562295367Sdes packet_get_bignum(real_key_int); 256357429Smarkm 256457429Smarkm protocol_flags = packet_get_int(); 256557429Smarkm packet_set_protocol_flags(protocol_flags); 256692559Sdes packet_check_eom(); 256757429Smarkm 2568295367Sdes /* Setup a fake key in case RSA decryption fails */ 2569295367Sdes if ((fake_key_int = BN_new()) == NULL) 2570295367Sdes fatal("do_ssh1_kex: BN_new failed"); 2571295367Sdes fake_key_len = BN_num_bytes(real_key_int); 2572295367Sdes if (fake_key_len > sizeof(fake_key_bytes)) 2573295367Sdes fake_key_len = sizeof(fake_key_bytes); 2574295367Sdes arc4random_buf(fake_key_bytes, fake_key_len); 2575295367Sdes if (BN_bin2bn(fake_key_bytes, fake_key_len, fake_key_int) == NULL) 2576295367Sdes fatal("do_ssh1_kex: BN_bin2bn failed"); 257798684Sdes 2578295367Sdes /* Decrypt real_key_int using host/server keys */ 2579295367Sdes rsafail = PRIVSEP(ssh1_session_key(real_key_int)); 2580295367Sdes /* If decryption failed, use the fake key. Else, the real key. */ 2581295367Sdes if (rsafail) 2582295367Sdes session_key_int = fake_key_int; 2583295367Sdes else 2584295367Sdes session_key_int = real_key_int; 2585295367Sdes 258657429Smarkm /* 258757429Smarkm * Extract session key from the decrypted integer. The key is in the 258857429Smarkm * least significant 256 bits of the integer; the first byte of the 258957429Smarkm * key is in the highest bits. 259057429Smarkm */ 2591295367Sdes (void) BN_mask_bits(session_key_int, sizeof(session_key) * 8); 2592295367Sdes len = BN_num_bytes(session_key_int); 2593295367Sdes if (len < 0 || (u_int)len > sizeof(session_key)) { 2594323124Sdes error("%s: bad session key len from %s port %d: " 2595323124Sdes "session_key_int %d > sizeof(session_key) %lu", __func__, 2596323124Sdes ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 2597323124Sdes len, (u_long)sizeof(session_key)); 2598295367Sdes rsafail++; 2599295367Sdes } else { 2600295367Sdes explicit_bzero(session_key, sizeof(session_key)); 2601295367Sdes BN_bn2bin(session_key_int, 2602295367Sdes session_key + sizeof(session_key) - len); 260376262Sgreen 2604295367Sdes derive_ssh1_session_id( 2605295367Sdes sensitive_data.ssh1_host_key->rsa->n, 2606295367Sdes sensitive_data.server_key->rsa->n, 2607295367Sdes cookie, session_id); 2608295367Sdes /* 2609295367Sdes * Xor the first 16 bytes of the session key with the 2610295367Sdes * session id. 2611295367Sdes */ 2612295367Sdes for (i = 0; i < 16; i++) 2613295367Sdes session_key[i] ^= session_id[i]; 261472397Skris } 261576262Sgreen 261698684Sdes /* Destroy the private and public keys. No longer. */ 261776262Sgreen destroy_sensitive_data(); 261857429Smarkm 261998684Sdes if (use_privsep) 262098684Sdes mm_ssh1_session_id(session_id); 262198684Sdes 262257429Smarkm /* Destroy the decrypted integer. It is no longer needed. */ 2623295367Sdes BN_clear_free(real_key_int); 2624295367Sdes BN_clear_free(fake_key_int); 262557429Smarkm 262657429Smarkm /* Set the session key. From this on all communications will be encrypted. */ 262757429Smarkm packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); 262857429Smarkm 262957429Smarkm /* Destroy our copy of the session key. It is no longer needed. */ 2630264377Sdes explicit_bzero(session_key, sizeof(session_key)); 263157429Smarkm 263257429Smarkm debug("Received session key; encryption turned on."); 263357429Smarkm 263498684Sdes /* Send an acknowledgment packet. Note that this packet is sent encrypted. */ 263557429Smarkm packet_start(SSH_SMSG_SUCCESS); 263657429Smarkm packet_send(); 263757429Smarkm packet_write_wait(); 263857429Smarkm} 2639295367Sdes#endif 264057429Smarkm 2641295367Sdesint 2642295367Sdessshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, 2643296781Sdes const u_char *data, size_t dlen, const char *alg, u_int flag) 2644255767Sdes{ 2645295367Sdes int r; 2646295367Sdes u_int xxx_slen, xxx_dlen = dlen; 2647295367Sdes 2648255767Sdes if (privkey) { 2649296781Sdes if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen, 2650296781Sdes alg) < 0)) 2651255767Sdes fatal("%s: key_sign failed", __func__); 2652295367Sdes if (slen) 2653295367Sdes *slen = xxx_slen; 2654255767Sdes } else if (use_privsep) { 2655296781Sdes if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen, 2656296781Sdes alg) < 0) 2657255767Sdes fatal("%s: pubkey_sign failed", __func__); 2658295367Sdes if (slen) 2659295367Sdes *slen = xxx_slen; 2660255767Sdes } else { 2661295367Sdes if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slen, 2662296781Sdes data, dlen, alg, datafellows)) != 0) 2663295367Sdes fatal("%s: ssh_agent_sign failed: %s", 2664295367Sdes __func__, ssh_err(r)); 2665255767Sdes } 2666295367Sdes return 0; 2667255767Sdes} 2668255767Sdes 2669295367Sdes/* SSH2 key exchange */ 267092559Sdesstatic void 267176262Sgreendo_ssh2_kex(void) 267257429Smarkm{ 2673295367Sdes char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; 2674295367Sdes struct kex *kex; 2675295367Sdes int r; 267657429Smarkm 2677295367Sdes myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( 2678295367Sdes options.kex_algorithms); 2679295367Sdes myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal( 2680295367Sdes options.ciphers); 2681295367Sdes myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal( 2682295367Sdes options.ciphers); 2683295367Sdes myproposal[PROPOSAL_MAC_ALGS_CTOS] = 2684295367Sdes myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 268557429Smarkm 2686149753Sdes if (options.compression == COMP_NONE) { 268798684Sdes myproposal[PROPOSAL_COMP_ALGS_CTOS] = 2688323124Sdes myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; 2689149753Sdes } else if (options.compression == COMP_DELAYED) { 2690149753Sdes myproposal[PROPOSAL_COMP_ALGS_CTOS] = 2691323124Sdes myproposal[PROPOSAL_COMP_ALGS_STOC] = 2692323124Sdes "none,zlib@openssh.com"; 269398684Sdes } 2694162856Sdes 2695255767Sdes if (options.rekey_limit || options.rekey_interval) 2696296781Sdes packet_set_rekey_limits(options.rekey_limit, 2697255767Sdes (time_t)options.rekey_interval); 2698255767Sdes 2699262566Sdes myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2700262566Sdes list_hostkey_types()); 270169591Sgreen 270276262Sgreen /* start key exchange */ 2703295367Sdes if ((r = kex_setup(active_state, myproposal)) != 0) 2704295367Sdes fatal("kex_setup: %s", ssh_err(r)); 2705295367Sdes kex = active_state->kex; 2706295367Sdes#ifdef WITH_OPENSSL 2707113911Sdes kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 2708137019Sdes kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; 2709323124Sdes kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; 2710323124Sdes kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; 2711323124Sdes kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server; 2712113911Sdes kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 2713162856Sdes kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 2714295367Sdes# ifdef OPENSSL_HAS_ECC 2715221420Sdes kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 2716295367Sdes# endif 2717295367Sdes#endif 2718262566Sdes kex->kex[KEX_C25519_SHA256] = kexc25519_server; 271976262Sgreen kex->server = 1; 272076262Sgreen kex->client_version_string=client_version_string; 272176262Sgreen kex->server_version_string=server_version_string; 2722204917Sdes kex->load_host_public_key=&get_hostkey_public_by_type; 2723204917Sdes kex->load_host_private_key=&get_hostkey_private_by_type; 272498684Sdes kex->host_key_index=&get_hostkey_index; 2725255767Sdes kex->sign = sshd_hostkey_sign; 272669591Sgreen 2727295367Sdes dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); 272869591Sgreen 272976262Sgreen session_id2 = kex->session_id; 273076262Sgreen session_id2_len = kex->session_id_len; 273176262Sgreen 273269591Sgreen#ifdef DEBUG_KEXDH 273369591Sgreen /* send 1st encrypted/maced/compressed message */ 273469591Sgreen packet_start(SSH2_MSG_IGNORE); 273569591Sgreen packet_put_cstring("markus"); 273669591Sgreen packet_send(); 273769591Sgreen packet_write_wait(); 273869591Sgreen#endif 273976262Sgreen debug("KEX done"); 274069591Sgreen} 2741126277Sdes 2742126277Sdes/* server specific fatal cleanup */ 2743126277Sdesvoid 2744126277Sdescleanup_exit(int i) 2745126277Sdes{ 2746240075Sdes if (the_authctxt) { 2747126277Sdes do_cleanup(the_authctxt); 2748295367Sdes if (use_privsep && privsep_is_preauth && 2749295367Sdes pmonitor != NULL && pmonitor->m_pid > 1) { 2750240075Sdes debug("Killing privsep child %d", pmonitor->m_pid); 2751240075Sdes if (kill(pmonitor->m_pid, SIGKILL) != 0 && 2752240075Sdes errno != ESRCH) 2753240075Sdes error("%s: kill(%d): %s", __func__, 2754240075Sdes pmonitor->m_pid, strerror(errno)); 2755240075Sdes } 2756240075Sdes } 2757147005Sdes#ifdef SSH_AUDIT_EVENTS 2758147005Sdes /* done after do_cleanup so it can cancel the PAM auth 'thread' */ 2759147005Sdes if (!use_privsep || mm_is_monitor()) 2760147005Sdes audit_event(SSH_CONNECTION_ABANDON); 2761147005Sdes#endif 2762126277Sdes _exit(i); 2763126277Sdes} 2764