version 1.290.2.1, 2004/08/19 04:13:28 |
version 1.290.2.2, 2005/03/10 17:15:05 |
|
|
char *config_file_name = _PATH_SERVER_CONFIG_FILE; |
char *config_file_name = _PATH_SERVER_CONFIG_FILE; |
|
|
/* |
/* |
* Flag indicating whether IPv4 or IPv6. This can be set on the command line. |
|
* Default value is AF_UNSPEC means both IPv4 and IPv6. |
|
*/ |
|
int IPv4or6 = AF_UNSPEC; |
|
|
|
/* |
|
* Debug mode flag. This can be set on the command line. If debug |
* Debug mode flag. This can be set on the command line. If debug |
* mode is enabled, extra debugging output will be sent to the system |
* mode is enabled, extra debugging output will be sent to the system |
* log, the daemon will not go to background, and will exit after processing |
* log, the daemon will not go to background, and will exit after processing |
|
|
else if (pmonitor->m_pid != 0) { |
else if (pmonitor->m_pid != 0) { |
debug2("User child is on pid %ld", (long)pmonitor->m_pid); |
debug2("User child is on pid %ld", (long)pmonitor->m_pid); |
close(pmonitor->m_recvfd); |
close(pmonitor->m_recvfd); |
|
buffer_clear(&loginmsg); |
monitor_child_postauth(pmonitor); |
monitor_child_postauth(pmonitor); |
|
|
/* NEVERREACHED */ |
/* NEVERREACHED */ |
|
|
static int |
static int |
drop_connection(int startups) |
drop_connection(int startups) |
{ |
{ |
double p, r; |
int p, r; |
|
|
if (startups < options.max_startups_begin) |
if (startups < options.max_startups_begin) |
return 0; |
return 0; |
|
|
|
|
p = 100 - options.max_startups_rate; |
p = 100 - options.max_startups_rate; |
p *= startups - options.max_startups_begin; |
p *= startups - options.max_startups_begin; |
p /= (double) (options.max_startups - options.max_startups_begin); |
p /= options.max_startups - options.max_startups_begin; |
p += options.max_startups_rate; |
p += options.max_startups_rate; |
p /= 100.0; |
r = arc4random() % 100; |
r = arc4random() / (double) UINT_MAX; |
|
|
|
debug("drop_connection: p %g, r %g", p, r); |
debug("drop_connection: p %d, r %d", p, r); |
return (r < p) ? 1 : 0; |
return (r < p) ? 1 : 0; |
} |
} |
|
|
|
|
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
char *line; |
char *line; |
int listen_sock, maxfd; |
int listen_sock, maxfd; |
int startup_p[2], config_s[2]; |
int startup_p[2] = { -1 , -1 }, config_s[2] = { -1 , -1 }; |
int startups = 0; |
int startups = 0; |
Key *key; |
Key *key; |
Authctxt *authctxt; |
Authctxt *authctxt; |
|
|
while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { |
while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { |
switch (opt) { |
switch (opt) { |
case '4': |
case '4': |
IPv4or6 = AF_INET; |
options.address_family = AF_INET; |
break; |
break; |
case '6': |
case '6': |
IPv4or6 = AF_INET6; |
options.address_family = AF_INET6; |
break; |
break; |
case 'f': |
case 'f': |
config_file_name = optarg; |
config_file_name = optarg; |
|
|
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); |
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); |
|
|
SSLeay_add_all_algorithms(); |
SSLeay_add_all_algorithms(); |
channel_set_af(IPv4or6); |
|
|
|
/* |
/* |
* Force logging to stderr until we have loaded the private host |
* Force logging to stderr until we have loaded the private host |
|
|
/* Fill in default values for those options not explicitly set. */ |
/* Fill in default values for those options not explicitly set. */ |
fill_default_server_options(&options); |
fill_default_server_options(&options); |
|
|
|
/* set default channel AF */ |
|
channel_set_af(options.address_family); |
|
|
/* Check that there are no remaining arguments. */ |
/* Check that there are no remaining arguments. */ |
if (optind < ac) { |
if (optind < ac) { |
fprintf(stderr, "Extra argument %s.\n", av[optind]); |
fprintf(stderr, "Extra argument %s.\n", av[optind]); |
|
|
} |
} |
|
|
/* Initialize the log (it is reinitialized below in case we forked). */ |
/* Initialize the log (it is reinitialized below in case we forked). */ |
if (debug_flag && !inetd_flag) |
if (debug_flag && (!inetd_flag || rexeced_flag)) |
log_stderr = 1; |
log_stderr = 1; |
log_init(__progname, options.log_level, options.log_facility, log_stderr); |
log_init(__progname, options.log_level, options.log_facility, log_stderr); |
|
|
|
|
if (num_listen_socks >= MAX_LISTEN_SOCKS) |
if (num_listen_socks >= MAX_LISTEN_SOCKS) |
fatal("Too many listen sockets. " |
fatal("Too many listen sockets. " |
"Enlarge MAX_LISTEN_SOCKS"); |
"Enlarge MAX_LISTEN_SOCKS"); |
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, |
if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, |
ntop, sizeof(ntop), strport, sizeof(strport), |
ntop, sizeof(ntop), strport, sizeof(strport), |
NI_NUMERICHOST|NI_NUMERICSERV) != 0) { |
NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { |
error("getnameinfo failed"); |
error("getnameinfo failed: %.100s", |
|
(ret != EAI_SYSTEM) ? gai_strerror(ret) : |
|
strerror(errno)); |
continue; |
continue; |
} |
} |
/* Create socket for listening. */ |
/* Create socket for listening. */ |
|
|
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); |
close(config_s[0]); |
if (rexec_flag) |
|
close(config_s[0]); |
break; |
break; |
} |
} |
} |
} |
|
|
/* XXX global for cleanup, access from other modules */ |
/* XXX global for cleanup, access from other modules */ |
the_authctxt = authctxt; |
the_authctxt = authctxt; |
|
|
|
/* prepare buffer to collect messages to display to user after login */ |
|
buffer_init(&loginmsg); |
|
|
if (use_privsep) |
if (use_privsep) |
if (privsep_preauth(authctxt) == 1) |
if (privsep_preauth(authctxt) == 1) |
goto authenticated; |
goto authenticated; |
|
|
/* prepare buffer to collect messages to display to user after login */ |
|
buffer_init(&loginmsg); |
|
|
|
/* perform the key exchange */ |
/* perform the key exchange */ |
/* authenticate user and start session */ |
/* authenticate user and start session */ |