summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/sshd.c')
-rw-r--r--crypto/openssh/sshd.c95
1 files changed, 54 insertions, 41 deletions
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index fa79b63..937ad1e 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.385 2011/06/23 09:34:13 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.393 2012/07/10 02:19:15 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -251,6 +251,7 @@ int startup_pipe; /* in child */
/* variables used for privilege separation */
int use_privsep = -1;
struct monitor *pmonitor = NULL;
+int privsep_is_preauth = 1;
/* global authentication context */
Authctxt *the_authctxt = NULL;
@@ -430,9 +431,12 @@ sshd_exchange_identification(int sock_in, int sock_out)
major = PROTOCOL_MAJOR_1;
minor = PROTOCOL_MINOR_1;
}
- snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
- ssh_version_get(options.hpn_disabled), newline);
- server_version_string = xstrdup(buf);
+
+ xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s%s",
+ major, minor, SSH_VERSION,
+ options.hpn_disabled ? "" : SSH_VERSION_HPN,
+ *options.version_addendum == '\0' ? "" : " ",
+ options.version_addendum, newline);
/* Send our protocol version identification. */
if (roaming_atomicio(vwrite, sock_out, server_version_string,
@@ -644,7 +648,7 @@ privsep_preauth(Authctxt *authctxt)
/* Store a pointer to the kex for later rekeying */
pmonitor->m_pkex = &xxx_kex;
- if (use_privsep == PRIVSEP_SANDBOX)
+ if (use_privsep == PRIVSEP_ON)
box = ssh_sandbox_init();
pid = fork();
if (pid == -1) {
@@ -652,9 +656,9 @@ privsep_preauth(Authctxt *authctxt)
} else if (pid != 0) {
debug2("Network child is on pid %ld", (long)pid);
+ pmonitor->m_pid = pid;
if (box != NULL)
ssh_sandbox_parent_preauth(box, pid);
- pmonitor->m_pid = pid;
monitor_child_preauth(authctxt, pmonitor);
/* Sync memory */
@@ -662,10 +666,13 @@ privsep_preauth(Authctxt *authctxt)
/* Wait for the child's exit status */
while (waitpid(pid, &status, 0) < 0) {
- if (errno != EINTR)
- fatal("%s: waitpid: %s", __func__,
- strerror(errno));
+ if (errno == EINTR)
+ continue;
+ pmonitor->m_pid = -1;
+ fatal("%s: waitpid: %s", __func__, strerror(errno));
}
+ privsep_is_preauth = 0;
+ pmonitor->m_pid = -1;
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0)
fatal("%s: preauth child exited with status %d",
@@ -893,8 +900,14 @@ drop_connection(int startups)
static void
usage(void)
{
- fprintf(stderr, "%s, %s\n",
- ssh_version_get(0), SSLeay_version(SSLEAY_VERSION));
+ if (options.version_addendum && *options.version_addendum != '\0')
+ fprintf(stderr, "%s%s %s, %s\n",
+ SSH_RELEASE, options.hpn_disabled ? "" : SSH_VERSION_HPN,
+ options.version_addendum, SSLeay_version(SSLEAY_VERSION));
+ else
+ fprintf(stderr, "%s%s, %s\n",
+ SSH_RELEASE, options.hpn_disabled ? "" : SSH_VERSION_HPN,
+ SSLeay_version(SSLEAY_VERSION));
fprintf(stderr,
"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n"
" [-f config_file] [-g login_grace_time] [-h host_key_file]\n"
@@ -1189,7 +1202,10 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
if (*newsock < 0) {
if (errno != EINTR && errno != EAGAIN &&
errno != EWOULDBLOCK)
- error("accept: %.100s", strerror(errno));
+ error("accept: %.100s",
+ strerror(errno));
+ if (errno == EMFILE || errno == ENFILE)
+ usleep(100 * 1000);
continue;
}
if (unset_nonblock(*newsock) == -1) {
@@ -1335,14 +1351,14 @@ main(int ac, char **av)
int opt, i, j, on = 1;
int sock_in = -1, sock_out = -1, newsock = -1;
const char *remote_ip;
- char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
int remote_port;
- char *line, *p, *cp;
+ char *line;
int config_s[2] = { -1 , -1 };
u_int64_t ibytes, obytes;
mode_t new_umask;
Key *key;
Authctxt *authctxt;
+ struct connection_info *connection_info = get_connection_info(0, 0);
#ifdef HAVE_SECUREWARE
(void)set_auth_parameters(ac, av);
@@ -1464,20 +1480,9 @@ main(int ac, char **av)
test_flag = 2;
break;
case 'C':
- cp = optarg;
- while ((p = strsep(&cp, ",")) && *p != '\0') {
- if (strncmp(p, "addr=", 5) == 0)
- test_addr = xstrdup(p + 5);
- else if (strncmp(p, "host=", 5) == 0)
- test_host = xstrdup(p + 5);
- else if (strncmp(p, "user=", 5) == 0)
- test_user = xstrdup(p + 5);
- else {
- fprintf(stderr, "Invalid test "
- "mode specification %s\n", p);
- exit(1);
- }
- }
+ if (parse_server_match_testspec(connection_info,
+ optarg) == -1)
+ exit(1);
break;
case 'u':
utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL);
@@ -1489,7 +1494,7 @@ main(int ac, char **av)
case 'o':
line = xstrdup(optarg);
if (process_server_config_line(&options, line,
- "command-line", 0, NULL, NULL, NULL, NULL) != 0)
+ "command-line", 0, NULL, NULL) != 0)
exit(1);
xfree(line);
break;
@@ -1526,7 +1531,7 @@ main(int ac, char **av)
* root's environment
*/
if (getenv("KRB5CCNAME") != NULL)
- unsetenv("KRB5CCNAME");
+ (void) unsetenv("KRB5CCNAME");
#ifdef _UNICOS
/* Cray can define user privs drop all privs now!
@@ -1545,13 +1550,10 @@ main(int ac, char **av)
* the parameters we need. If we're not doing an extended test,
* do not silently ignore connection test params.
*/
- if (test_flag >= 2 &&
- (test_user != NULL || test_host != NULL || test_addr != NULL)
- && (test_user == NULL || test_host == NULL || test_addr == NULL))
+ if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0)
fatal("user, host and addr are all required when testing "
"Match configs");
- if (test_flag < 2 && (test_user != NULL || test_host != NULL ||
- test_addr != NULL))
+ if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0)
fatal("Config test connection parameter (-C) provided without "
"test mode (-T)");
@@ -1563,7 +1565,7 @@ main(int ac, char **av)
load_server_config(config_file_name, &cfg);
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
- &cfg, NULL, NULL, NULL);
+ &cfg, NULL);
seed_rng();
@@ -1583,7 +1585,11 @@ main(int ac, char **av)
exit(1);
}
- debug("sshd version %.100s", ssh_version_get(options.hpn_disabled));
+ debug("sshd version %.100s%.100s%s%.100s",
+ SSH_RELEASE,
+ options.hpn_disabled ? "" : SSH_VERSION_HPN,
+ *options.version_addendum == '\0' ? "" : " ",
+ options.version_addendum);
/* Store privilege separation user for later use if required. */
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
@@ -1725,9 +1731,8 @@ main(int ac, char **av)
}
if (test_flag > 1) {
- if (test_user != NULL && test_addr != NULL && test_host != NULL)
- parse_server_match_config(&options, test_user,
- test_host, test_addr);
+ if (server_match_spec_complete(connection_info) == 1)
+ parse_server_match_config(&options, connection_info);
dump_config(&options);
}
@@ -2415,8 +2420,16 @@ do_ssh2_kex(void)
void
cleanup_exit(int i)
{
- if (the_authctxt)
+ if (the_authctxt) {
do_cleanup(the_authctxt);
+ if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) {
+ debug("Killing privsep child %d", pmonitor->m_pid);
+ if (kill(pmonitor->m_pid, SIGKILL) != 0 &&
+ errno != ESRCH)
+ error("%s: kill(%d): %s", __func__,
+ pmonitor->m_pid, strerror(errno));
+ }
+ }
#ifdef SSH_AUDIT_EVENTS
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
if (!use_privsep || mm_is_monitor())
OpenPOWER on IntegriCloud