=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sshd.c,v retrieving revision 1.150 retrieving revision 1.151 diff -u -r1.150 -r1.151 --- src/usr.bin/ssh/sshd.c 2001/01/13 18:32:51 1.150 +++ src/usr.bin/ssh/sshd.c 2001/01/18 15:54:49 1.151 @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.150 2001/01/13 18:32:51 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.151 2001/01/18 15:54:49 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -144,10 +144,10 @@ } sensitive_data; /* - * Flag indicating whether the current session key has been used. This flag - * is set whenever the key is used, and cleared when the key is regenerated. + * Flag indicating whether the RSA server key needs to be regenerated. + * Is set in the SIGALRM handler and cleared when the key is regenerated. */ -int key_used = 0; +int key_do_regen = 0; /* This is set to true when SIGHUP is received. */ int received_sighup = 0; @@ -257,7 +257,6 @@ * do anything with the private key or random state before forking. * Thus there should be no concurrency control/asynchronous execution * problems. - * XXX calling log() is not safe from races. */ void generate_empheral_server_key(void) @@ -275,17 +274,9 @@ key_regeneration_alarm(int sig) { int save_errno = errno; - - /* Check if we should generate a new key. */ - if (key_used) { - /* This should really be done in the background. */ - generate_empheral_server_key(); - key_used = 0; - } - /* Reschedule the alarm. */ - signal(SIGALRM, key_regeneration_alarm); - alarm(options.key_regeneration_time); + signal(SIGALRM, SIG_DFL); errno = save_errno; + key_do_regen = 1; } void @@ -559,6 +550,7 @@ int listen_sock, maxfd; int startup_p[2]; int startups = 0; + int ret, key_used = 0; /* Save argv. */ saved_argv = av; @@ -872,14 +864,9 @@ fclose(f); } } - if (options.protocol & SSH_PROTO_1) { + if (options.protocol & SSH_PROTO_1) generate_empheral_server_key(); - /* Schedule server key regeneration alarm. */ - signal(SIGALRM, key_regeneration_alarm); - alarm(options.key_regeneration_time); - } - /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ signal(SIGHUP, sighup_handler); @@ -920,11 +907,17 @@ FD_SET(startup_pipes[i], fdset); /* Wait in select until there is a connection. */ - if (select(maxfd+1, fdset, NULL, NULL, NULL) < 0) { - if (errno != EINTR) - error("select: %.100s", strerror(errno)); - continue; + ret = select(maxfd+1, fdset, NULL, NULL, NULL); + if (ret < 0 && errno != EINTR) + error("select: %.100s", strerror(errno)); + if (key_used && key_do_regen) { + generate_empheral_server_key(); + key_used = 0; + key_do_regen = 0; } + if (ret < 0) + continue; + for (i = 0; i < options.max_startups; i++) if (startup_pipes[i] != -1 && FD_ISSET(startup_pipes[i], fdset)) { @@ -1024,7 +1017,13 @@ close(startup_p[1]); /* Mark that the key has been used (it was "given" to the child). */ - key_used = 1; + if ((options.protocol & SSH_PROTO_1) && + key_used == 0) { + /* Schedule server key regeneration alarm. */ + signal(SIGALRM, key_regeneration_alarm); + alarm(options.key_regeneration_time); + key_used = 1; + } arc4random_stir();