version 1.326, 2006/03/19 18:51:19 |
version 1.327, 2006/03/19 18:56:41 |
|
|
* the effect is to reread the configuration file (and to regenerate |
* the effect is to reread the configuration file (and to regenerate |
* the server key). |
* the server key). |
*/ |
*/ |
|
|
|
/*ARGSUSED*/ |
static void |
static void |
sighup_handler(int sig) |
sighup_handler(int sig) |
{ |
{ |
|
|
* Called from the main program after receiving SIGHUP. |
* Called from the main program after receiving SIGHUP. |
* Restarts the server. |
* Restarts the server. |
*/ |
*/ |
|
/*ARGSUSED*/ |
static void |
static void |
sighup_restart(void) |
sighup_restart(void) |
{ |
{ |
|
|
/* |
/* |
* Generic signal handler for terminating signals in the master daemon. |
* Generic signal handler for terminating signals in the master daemon. |
*/ |
*/ |
|
/*ARGSUSED*/ |
static void |
static void |
sigterm_handler(int sig) |
sigterm_handler(int sig) |
{ |
{ |
|
|
* SIGCHLD handler. This is called whenever a child dies. This will then |
* SIGCHLD handler. This is called whenever a child dies. This will then |
* reap any zombies left by exited children. |
* reap any zombies left by exited children. |
*/ |
*/ |
|
/*ARGSUSED*/ |
static void |
static void |
main_sigchld_handler(int sig) |
main_sigchld_handler(int sig) |
{ |
{ |
|
|
/* |
/* |
* Signal handler for the alarm after the login grace period has expired. |
* Signal handler for the alarm after the login grace period has expired. |
*/ |
*/ |
|
/*ARGSUSED*/ |
static void |
static void |
grace_alarm_handler(int sig) |
grace_alarm_handler(int sig) |
{ |
{ |
|
|
arc4random_stir(); |
arc4random_stir(); |
} |
} |
|
|
|
/*ARGSUSED*/ |
static void |
static void |
key_regeneration_alarm(int sig) |
key_regeneration_alarm(int sig) |
{ |
{ |
|
|
options.log_level = SYSLOG_LEVEL_QUIET; |
options.log_level = SYSLOG_LEVEL_QUIET; |
break; |
break; |
case 'b': |
case 'b': |
options.server_key_bits = atoi(optarg); |
options.server_key_bits = (int)strtonum(optarg, 256, |
|
32768, NULL); |
break; |
break; |
case 'p': |
case 'p': |
options.ports_from_cmdline = 1; |
options.ports_from_cmdline = 1; |
|
|
test_flag = 1; |
test_flag = 1; |
break; |
break; |
case 'u': |
case 'u': |
utmp_len = atoi(optarg); |
utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); |
if (utmp_len > MAXHOSTNAMELEN) { |
if (utmp_len > MAXHOSTNAMELEN) { |
fprintf(stderr, "Invalid utmp length.\n"); |
fprintf(stderr, "Invalid utmp length.\n"); |
exit(1); |
exit(1); |
|
|
} |
} |
|
|
if (use_privsep) { |
if (use_privsep) { |
struct passwd *pw; |
|
struct stat st; |
struct stat st; |
|
|
if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) |
if (getpwnam(SSH_PRIVSEP_USER) == NULL) |
fatal("Privilege separation user %s does not exist", |
fatal("Privilege separation user %s does not exist", |
SSH_PRIVSEP_USER); |
SSH_PRIVSEP_USER); |
if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || |
if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || |
|
|
if (!FD_ISSET(listen_socks[i], fdset)) |
if (!FD_ISSET(listen_socks[i], fdset)) |
continue; |
continue; |
fromlen = sizeof(from); |
fromlen = sizeof(from); |
newsock = accept(listen_socks[i], (struct sockaddr *)&from, |
newsock = accept(listen_socks[i], |
&fromlen); |
(struct sockaddr *)&from, &fromlen); |
if (newsock < 0) { |
if (newsock < 0) { |
if (errno != EINTR && errno != EWOULDBLOCK) |
if (errno != EINTR && errno != EWOULDBLOCK) |
error("accept: %.100s", strerror(errno)); |
error("accept: %.100s", strerror(errno)); |
|
|
*/ |
*/ |
if ((pid = fork()) == 0) { |
if ((pid = fork()) == 0) { |
/* |
/* |
* Child. Close the listening and max_startup |
* Child. Close the listening and |
* sockets. Start using the accepted socket. |
* max_startup sockets. Start using |
* Reinitialize logging (since our pid has |
* the accepted socket. Reinitialize |
* changed). We break out of the loop to handle |
* logging (since our pid has changed). |
|
* We break out of the loop to handle |
* the connection. |
* the connection. |
*/ |
*/ |
startup_pipe = startup_p[1]; |
startup_pipe = startup_p[1]; |
|
|
close_listen_socks(); |
close_listen_socks(); |
sock_in = newsock; |
sock_in = newsock; |
sock_out = newsock; |
sock_out = newsock; |
log_init(__progname, options.log_level, options.log_facility, log_stderr); |
log_init(__progname, |
|
options.log_level, |
|
options.log_facility, |
|
log_stderr); |
if (rexec_flag) |
if (rexec_flag) |
close(config_s[0]); |
close(config_s[0]); |
break; |
break; |
|
|
close(config_s[1]); |
close(config_s[1]); |
} |
} |
|
|
/* Mark that the key has been used (it was "given" to the child). */ |
/* |
|
* Mark that the key has been used (it |
|
* was "given" to the child). |
|
*/ |
if ((options.protocol & SSH_PROTO_1) && |
if ((options.protocol & SSH_PROTO_1) && |
key_used == 0) { |
key_used == 0) { |
/* Schedule server key regeneration alarm. */ |
/* Schedule server key regeneration alarm. */ |
|
|
} |
} |
|
|
arc4random_stir(); |
arc4random_stir(); |
|
|
/* Close the new socket (the child is now taking care of it). */ |
|
close(newsock); |
close(newsock); |
} |
} |
/* child process check (or debug mode) */ |
/* child process check (or debug mode) */ |
|
|
{ |
{ |
int rsafail = 0; |
int rsafail = 0; |
|
|
if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { |
if (BN_cmp(sensitive_data.server_key->rsa->n, |
|
sensitive_data.ssh1_host_key->rsa->n) > 0) { |
/* Server key has bigger modulus. */ |
/* Server key has bigger modulus. */ |
if (BN_num_bits(sensitive_data.server_key->rsa->n) < |
if (BN_num_bits(sensitive_data.server_key->rsa->n) < |
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { |
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + |
fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", |
SSH_KEY_BITS_RESERVED) { |
|
fatal("do_connection: %s: " |
|
"server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", |
get_remote_ipaddr(), |
get_remote_ipaddr(), |
BN_num_bits(sensitive_data.server_key->rsa->n), |
BN_num_bits(sensitive_data.server_key->rsa->n), |
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), |
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), |
|
|
} else { |
} else { |
/* Host key has bigger modulus (or they are equal). */ |
/* Host key has bigger modulus (or they are equal). */ |
if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < |
if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < |
BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { |
BN_num_bits(sensitive_data.server_key->rsa->n) + |
fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", |
SSH_KEY_BITS_RESERVED) { |
|
fatal("do_connection: %s: " |
|
"host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", |
get_remote_ipaddr(), |
get_remote_ipaddr(), |
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), |
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), |
BN_num_bits(sensitive_data.server_key->rsa->n), |
BN_num_bits(sensitive_data.server_key->rsa->n), |
|
|
myproposal[PROPOSAL_COMP_ALGS_CTOS] = |
myproposal[PROPOSAL_COMP_ALGS_CTOS] = |
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com"; |
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com"; |
} |
} |
|
|
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); |
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); |
|
|
/* start key exchange */ |
/* start key exchange */ |