=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sshd.c,v retrieving revision 1.195 retrieving revision 1.195.2.2 diff -u -r1.195 -r1.195.2.2 --- src/usr.bin/ssh/sshd.c 2001/04/15 16:58:03 1.195 +++ src/usr.bin/ssh/sshd.c 2001/11/15 00:15:19 1.195.2.2 @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.195 2001/04/15 16:58:03 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.195.2.2 2001/11/15 00:15:19 miod Exp $"); #include #include @@ -71,6 +71,7 @@ #include "auth.h" #include "misc.h" #include "dispatch.h" +#include "channels.h" #ifdef LIBWRAP #include @@ -105,6 +106,9 @@ */ int debug_flag = 0; +/* Flag indicating that the daemon should only test the configuration and keys. */ +int test_flag = 0; + /* Flag indicating that the daemon is being started from inetd. */ int inetd_flag = 0; @@ -158,8 +162,9 @@ */ int key_do_regen = 0; -/* This is set to true when SIGHUP is received. */ +/* This is set to true when a signal is received. */ int received_sighup = 0; +int received_sigterm = 0; /* session identifier, used by RSA-auth */ u_char session_id[16]; @@ -172,16 +177,15 @@ u_int utmp_len = MAXHOSTNAMELEN; /* Prototypes for various functions defined later in this file. */ -void do_ssh1_kex(void); -void do_ssh2_kex(void); +void destroy_sensitive_data(void); -void ssh_dh1_server(Kex *, Buffer *_kexinit, Buffer *); -void ssh_dhgex_server(Kex *, Buffer *_kexinit, Buffer *); +static void do_ssh1_kex(void); +static void do_ssh2_kex(void); /* * Close all listening sockets */ -void +static void close_listen_socks(void) { int i; @@ -195,7 +199,7 @@ * the effect is to reread the configuration file (and to regenerate * the server key). */ -void +static void sighup_handler(int sig) { received_sighup = 1; @@ -206,7 +210,7 @@ * Called from the main program after receiving SIGHUP. * Restarts the server. */ -void +static void sighup_restart(void) { log("Received SIGHUP; restarting."); @@ -218,23 +222,18 @@ /* * Generic signal handler for terminating signals in the master daemon. - * These close the listen socket; not closing it seems to cause "Address - * already in use" problems on some machines, which is inconvenient. */ -void +static void sigterm_handler(int sig) { - log("Received signal %d; terminating.", sig); - close_listen_socks(); - unlink(options.pid_file); - exit(255); + received_sigterm = sig; } /* * SIGCHLD handler. This is called whenever a child dies. This will then - * reap any zombies left by exited c. + * reap any zombies left by exited children. */ -void +static void main_sigchld_handler(int sig) { int save_errno = errno; @@ -250,9 +249,11 @@ /* * Signal handler for the alarm after the login grace period has expired. */ -void +static void grace_alarm_handler(int sig) { + /* XXX no idea how fix this signal handler */ + /* Close the connection. */ packet_close(); @@ -267,7 +268,7 @@ * Thus there should be no concurrency control/asynchronous execution * problems. */ -void +static void generate_ephemeral_server_key(void) { u_int32_t rand = 0; @@ -290,7 +291,7 @@ arc4random_stir(); } -void +static void key_regeneration_alarm(int sig) { int save_errno = errno; @@ -299,7 +300,7 @@ key_do_regen = 1; } -void +static void sshd_exchange_identification(int sock_in, int sock_out) { int i, mismatch; @@ -426,8 +427,6 @@ server_version_string, client_version_string); fatal_cleanup(); } - if (compat20) - packet_set_ssh2_format(); } @@ -451,7 +450,7 @@ memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); } -char * +static char * list_hostkey_types(void) { static char buf[1024]; @@ -476,7 +475,7 @@ return buf; } -Key * +static Key * get_hostkey_by_type(int type) { int i; @@ -494,7 +493,7 @@ * of (max_startups_rate/100). the probability increases linearly until * all connections are dropped for startups > max_startups */ -int +static int drop_connection(int startups) { double p, r; @@ -552,7 +551,7 @@ initialize_server_options(&options); /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDeiqQ46")) != -1) { + while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:dDeiqtQ46")) != -1) { switch (opt) { case '4': IPv4or6 = AF_INET; @@ -605,10 +604,16 @@ } break; case 'g': - options.login_grace_time = atoi(optarg); + if ((options.login_grace_time = convtime(optarg)) == -1) { + fprintf(stderr, "Invalid login grace time.\n"); + exit(1); + } break; case 'k': - options.key_regeneration_time = atoi(optarg); + if ((options.key_regeneration_time = convtime(optarg)) == -1) { + fprintf(stderr, "Invalid key regeneration interval.\n"); + exit(1); + } break; case 'h': if (options.num_host_key_files >= MAX_HOSTKEYS) { @@ -622,6 +627,9 @@ /* only makes sense with inetd_flag, i.e. no listen() */ inetd_flag = 1; break; + case 't': + test_flag = 1; + break; case 'u': utmp_len = atoi(optarg); break; @@ -634,6 +642,7 @@ fprintf(stderr, " -d Debugging mode (multiple -d means more debugging)\n"); fprintf(stderr, " -i Started from inetd\n"); fprintf(stderr, " -D Do not fork into daemon mode\n"); + fprintf(stderr, " -t Only test configuration file and keys\n"); fprintf(stderr, " -q Quiet (no logging)\n"); fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); @@ -648,6 +657,7 @@ } } SSLeay_add_all_algorithms(); + channel_set_af(IPv4or6); /* * Force logging to stderr until we have loaded the private host @@ -739,6 +749,10 @@ } } + /* Configuration looks good, so exit if in test mode. */ + if (test_flag) + exit(0); + /* Initialize the log (it is reinitialized below in case we forked). */ if (debug_flag && !inetd_flag) log_stderr = 1; @@ -855,6 +869,22 @@ if (!num_listen_socks) fatal("Cannot bind any address."); + if (options.protocol & SSH_PROTO_1) + generate_ephemeral_server_key(); + + /* + * Arrange to restart on SIGHUP. The handler needs + * listen_sock. + */ + signal(SIGHUP, sighup_handler); + + signal(SIGTERM, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + + /* Arrange SIGCHLD to be caught. */ + signal(SIGCHLD, main_sigchld_handler); + + /* Write out the pid file after the sigterm handler is setup */ if (!debug_flag) { /* * Record our pid in /var/run/sshd.pid to make it @@ -869,18 +899,7 @@ fclose(f); } } - if (options.protocol & SSH_PROTO_1) - generate_ephemeral_server_key(); - /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ - signal(SIGHUP, sighup_handler); - - signal(SIGTERM, sigterm_handler); - signal(SIGQUIT, sigterm_handler); - - /* Arrange SIGCHLD to be caught. */ - signal(SIGCHLD, main_sigchld_handler); - /* setup fd set for listen */ fdset = NULL; maxfd = 0; @@ -915,6 +934,13 @@ ret = select(maxfd+1, fdset, NULL, NULL, NULL); if (ret < 0 && errno != EINTR) error("select: %.100s", strerror(errno)); + if (received_sigterm) { + log("Received signal %d; terminating.", + received_sigterm); + close_listen_socks(); + unlink(options.pid_file); + exit(255); + } if (key_used && key_do_regen) { generate_ephemeral_server_key(); key_used = 0; @@ -1086,7 +1112,7 @@ { struct request_info req; - request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, NULL); + request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); fromhost(&req); if (!hosts_access(&req)) { @@ -1126,13 +1152,13 @@ "originating port not trusted."); options.rhosts_authentication = 0; } -#ifdef KRB4 +#if defined(KRB4) && !defined(KRB5) if (!packet_connection_is_ipv4() && options.kerberos_authentication) { debug("Kerberos Authentication disabled, only available for IPv4."); options.kerberos_authentication = 0; } -#endif /* KRB4 */ +#endif /* KRB4 && !KRB5 */ #ifdef AFS /* If machine has AFS, set process authentication group. */ if (k_hasafs()) { @@ -1152,13 +1178,6 @@ do_ssh1_kex(); do_authentication(); } - -#ifdef KRB4 - /* Cleanup user's ticket cache file. */ - if (options.kerberos_ticket_cleanup) - (void) dest_tkt(); -#endif /* KRB4 */ - /* The connection has been terminated. */ verbose("Closing connection to %.100s", remote_ip); packet_close(); @@ -1168,7 +1187,7 @@ /* * SSH1 key exchange */ -void +static void do_ssh1_kex(void) { int i, len; @@ -1229,17 +1248,19 @@ auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; if (options.rsa_authentication) auth_mask |= 1 << SSH_AUTH_RSA; -#ifdef KRB4 +#if defined(KRB4) || defined(KRB5) if (options.kerberos_authentication) auth_mask |= 1 << SSH_AUTH_KERBEROS; #endif -#ifdef AFS +#if defined(AFS) || defined(KRB5) if (options.kerberos_tgt_passing) auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; +#endif +#ifdef AFS if (options.afs_token_passing) auth_mask |= 1 << SSH_PASS_AFS_TOKEN; #endif - if (options.challenge_reponse_authentication == 1) + if (options.challenge_response_authentication == 1) auth_mask |= 1 << SSH_AUTH_TIS; if (options.password_authentication) auth_mask |= 1 << SSH_AUTH_PASSWORD; @@ -1389,7 +1410,7 @@ /* * SSH2 key exchange: diffie-hellman-group1-sha1 */ -void +static void do_ssh2_kex(void) { Kex *kex;