- markus@cvs.openbsd.org 2003/09/23 20:17:11
[Makefile.in auth1.c auth2.c auth.c auth.h auth-krb5.c canohost.c
cleanup.c clientloop.c fatal.c gss-serv.c log.c log.h monitor.c monitor.h
monitor_wrap.c monitor_wrap.h packet.c serverloop.c session.c session.h
ssh-agent.c sshd.c]
replace fatal_cleanup() and linked list of fatal callbacks with static
cleanup_exit() function. re-refine cleanup_exit() where appropriate,
allocate sshd's authctxt eary to allow simpler cleanup in sshd.
tested by many, ok deraadt@
diff --git a/sshd.c b/sshd.c
index 4b3ff0d..5c27112 100644
--- a/sshd.c
+++ b/sshd.c
@@ -42,7 +42,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.277 2003/09/19 11:33:09 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.278 2003/09/23 20:17:11 markus Exp $");
#include <openssl/dh.h>
#include <openssl/bn.h>
@@ -204,6 +204,9 @@
/* message to be displayed after login */
Buffer loginmsg;
+/* global authentication context */
+Authctxt *the_authctxt = NULL;
+
/* Prototypes for various functions defined later in this file. */
void destroy_sensitive_data(void);
void demote_sensitive_data(void);
@@ -375,7 +378,7 @@
strlen(server_version_string))
!= strlen(server_version_string)) {
logit("Could not write ident string to %s", get_remote_ipaddr());
- fatal_cleanup();
+ cleanup_exit(255);
}
/* Read other sides version identification. */
@@ -384,7 +387,7 @@
if (atomicio(read, sock_in, &buf[i], 1) != 1) {
logit("Did not receive identification string from %s",
get_remote_ipaddr());
- fatal_cleanup();
+ cleanup_exit(255);
}
if (buf[i] == '\r') {
buf[i] = 0;
@@ -414,7 +417,7 @@
close(sock_out);
logit("Bad protocol version identification '%.100s' from %s",
client_version_string, get_remote_ipaddr());
- fatal_cleanup();
+ cleanup_exit(255);
}
debug("Client protocol version %d.%d; client software version %.100s",
remote_major, remote_minor, remote_version);
@@ -424,13 +427,13 @@
if (datafellows & SSH_BUG_PROBE) {
logit("probed from %s with %s. Don't panic.",
get_remote_ipaddr(), client_version_string);
- fatal_cleanup();
+ cleanup_exit(255);
}
if (datafellows & SSH_BUG_SCANNER) {
logit("scanned from %s with %s. Don't panic.",
get_remote_ipaddr(), client_version_string);
- fatal_cleanup();
+ cleanup_exit(255);
}
mismatch = 0;
@@ -476,7 +479,7 @@
logit("Protocol major versions differ for %s: %.200s vs. %.200s",
get_remote_ipaddr(),
server_version_string, client_version_string);
- fatal_cleanup();
+ cleanup_exit(255);
}
}
@@ -571,10 +574,9 @@
#endif
}
-static Authctxt *
-privsep_preauth(void)
+static int
+privsep_preauth(Authctxt *authctxt)
{
- Authctxt *authctxt = NULL;
int status;
pid_t pid;
@@ -590,7 +592,7 @@
debug2("Network child is on pid %ld", (long)pid);
close(pmonitor->m_recvfd);
- authctxt = monitor_child_preauth(pmonitor);
+ monitor_child_preauth(authctxt, pmonitor);
close(pmonitor->m_sendfd);
/* Sync memory */
@@ -600,7 +602,7 @@
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
break;
- return (authctxt);
+ return (1);
} else {
/* child */
@@ -611,17 +613,12 @@
privsep_preauth_child();
setproctitle("%s", "[net]");
}
- return (NULL);
+ return (0);
}
static void
privsep_postauth(Authctxt *authctxt)
{
- extern Authctxt *x_authctxt;
-
- /* XXX - Remote port forwarding */
- x_authctxt = authctxt;
-
#ifdef DISABLE_FD_PASSING
if (1) {
#else
@@ -804,8 +801,8 @@
int listen_sock, maxfd;
int startup_p[2];
int startups = 0;
- Authctxt *authctxt;
Key *key;
+ Authctxt *authctxt;
int ret, key_used = 0;
#ifdef HAVE_SECUREWARE
@@ -1460,18 +1457,25 @@
/* prepare buffers to collect authentication messages */
buffer_init(&loginmsg);
+ /* allocate authentication context */
+ authctxt = xmalloc(sizeof(*authctxt));
+ memset(authctxt, 0, sizeof(*authctxt));
+
+ /* XXX global for cleanup, access from other modules */
+ the_authctxt = authctxt;
+
if (use_privsep)
- if ((authctxt = privsep_preauth()) != NULL)
+ if (privsep_preauth(authctxt) == 1)
goto authenticated;
/* perform the key exchange */
/* authenticate user and start session */
if (compat20) {
do_ssh2_kex();
- authctxt = do_authentication2();
+ do_authentication2(authctxt);
} else {
do_ssh1_kex();
- authctxt = do_authentication();
+ do_authentication(authctxt);
}
/*
* If we use privilege separation, the unprivileged child transfers
@@ -1494,7 +1498,7 @@
destroy_sensitive_data();
}
- /* Perform session preparation. */
+ /* Start session. */
do_authenticated(authctxt);
/* The connection has been terminated. */
@@ -1787,3 +1791,12 @@
#endif
debug("KEX done");
}
+
+/* server specific fatal cleanup */
+void
+cleanup_exit(int i)
+{
+ if (the_authctxt)
+ do_cleanup(the_authctxt);
+ _exit(i);
+}