summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.in6
-rw-r--r--auth-krb5.c11
-rw-r--r--auth.c10
-rw-r--r--auth.h11
-rw-r--r--auth1.c10
-rw-r--r--auth2.c22
-rw-r--r--canohost.c8
-rw-r--r--cleanup.c26
-rw-r--r--clientloop.c11
-rw-r--r--fatal.c4
-rw-r--r--gss-serv.c8
-rw-r--r--log.c79
-rw-r--r--log.h9
-rw-r--r--monitor.c17
-rw-r--r--monitor.h4
-rw-r--r--monitor_wrap.c17
-rw-r--r--monitor_wrap.h6
-rw-r--r--packet.c10
-rw-r--r--serverloop.c14
-rw-r--r--session.c94
-rw-r--r--session.h5
-rw-r--r--ssh-agent.c15
-rw-r--r--sshd.c59
24 files changed, 203 insertions, 267 deletions
diff --git a/ChangeLog b/ChangeLog
index c782c10d5..a25c731b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
120031002
2 - OpenBSD CVS Sync
3 - markus@cvs.openbsd.org 2003/09/23 20:17:11
4 [Makefile.in auth1.c auth2.c auth.c auth.h auth-krb5.c canohost.c
5 cleanup.c clientloop.c fatal.c gss-serv.c log.c log.h monitor.c monitor.h
6 monitor_wrap.c monitor_wrap.h packet.c serverloop.c session.c session.h
7 ssh-agent.c sshd.c]
8 replace fatal_cleanup() and linked list of fatal callbacks with static
9 cleanup_exit() function. re-refine cleanup_exit() where appropriate,
10 allocate sshd's authctxt eary to allow simpler cleanup in sshd.
11 tested by many, ok deraadt@
12
120030930 1320030930
2 - (bal) Fix issues in openbsd-compat/realpath.c 14 - (bal) Fix issues in openbsd-compat/realpath.c
3 15
@@ -1232,4 +1244,4 @@
1232 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. 1244 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
1233 Report from murple@murple.net, diagnosis from dtucker@zip.com.au 1245 Report from murple@murple.net, diagnosis from dtucker@zip.com.au
1234 1246
1235$Id: ChangeLog,v 1.3044 2003/09/30 23:49:06 mouring Exp $ 1247$Id: ChangeLog,v 1.3045 2003/10/02 06:12:36 dtucker Exp $
diff --git a/Makefile.in b/Makefile.in
index 4368132e5..dce12c4d1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.250 2003/09/22 00:58:56 dtucker Exp $ 1# $Id: Makefile.in,v 1.251 2003/10/02 06:12:36 dtucker Exp $
2 2
3# uncomment if you run a non bourne compatable shell. Ie. csh 3# uncomment if you run a non bourne compatable shell. Ie. csh
4#SHELL = @SH@ 4#SHELL = @SH@
@@ -62,8 +62,8 @@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
62TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) 62TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
63 63
64LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \ 64LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \
65 cipher.o cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \ 65 cipher.o cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \
66 compat.o compress.o crc32.o deattack.o fatal.o \ 66 cleanup.o compat.o compress.o crc32.o deattack.o fatal.o \
67 hostfile.o log.o match.o moduli.o mpaux.o nchan.o packet.o \ 67 hostfile.o log.o match.o moduli.o mpaux.o nchan.o packet.o \
68 readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \ 68 readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \
69 key.o dispatch.o kex.o mac.o uuencode.o misc.o \ 69 key.o dispatch.o kex.o mac.o uuencode.o misc.o \
diff --git a/auth-krb5.c b/auth-krb5.c
index 0aa5195b8..e31f2eb0e 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $"); 31RCSID("$OpenBSD: auth-krb5.c,v 1.13 2003/09/23 20:17:11 markus Exp $");
32 32
33#include "ssh.h" 33#include "ssh.h"
34#include "ssh1.h" 34#include "ssh1.h"
@@ -50,7 +50,6 @@ krb5_init(void *context)
50{ 50{
51 Authctxt *authctxt = (Authctxt *)context; 51 Authctxt *authctxt = (Authctxt *)context;
52 krb5_error_code problem; 52 krb5_error_code problem;
53 static int cleanup_registered = 0;
54 53
55 if (authctxt->krb5_ctx == NULL) { 54 if (authctxt->krb5_ctx == NULL) {
56 problem = krb5_init_context(&authctxt->krb5_ctx); 55 problem = krb5_init_context(&authctxt->krb5_ctx);
@@ -58,10 +57,6 @@ krb5_init(void *context)
58 return (problem); 57 return (problem);
59 krb5_init_ets(authctxt->krb5_ctx); 58 krb5_init_ets(authctxt->krb5_ctx);
60 } 59 }
61 if (!cleanup_registered) {
62 fatal_add_cleanup(krb5_cleanup_proc, authctxt);
63 cleanup_registered = 1;
64 }
65 return (0); 60 return (0);
66} 61}
67 62
@@ -205,10 +200,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
205} 200}
206 201
207void 202void
208krb5_cleanup_proc(void *context) 203krb5_cleanup_proc(Authctxt *authctxt)
209{ 204{
210 Authctxt *authctxt = (Authctxt *)context;
211
212 debug("krb5_cleanup_proc called"); 205 debug("krb5_cleanup_proc called");
213 if (authctxt->krb5_fwd_ccache) { 206 if (authctxt->krb5_fwd_ccache) {
214 krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); 207 krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
diff --git a/auth.c b/auth.c
index 46e495adf..029672877 100644
--- a/auth.c
+++ b/auth.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $"); 26RCSID("$OpenBSD: auth.c,v 1.50 2003/09/23 20:17:11 markus Exp $");
27 27
28#ifdef HAVE_LOGIN_H 28#ifdef HAVE_LOGIN_H
29#include <login.h> 29#include <login.h>
@@ -263,14 +263,6 @@ allowed_user(struct passwd * pw)
263 return 1; 263 return 1;
264} 264}
265 265
266Authctxt *
267authctxt_new(void)
268{
269 Authctxt *authctxt = xmalloc(sizeof(*authctxt));
270 memset(authctxt, 0, sizeof(*authctxt));
271 return authctxt;
272}
273
274void 266void
275auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) 267auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
276{ 268{
diff --git a/auth.h b/auth.h
index beaacb8bc..b081bb5cb 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $ */ 1/* $OpenBSD: auth.h,v 1.47 2003/09/23 20:17:11 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -118,15 +118,14 @@ int user_key_allowed(struct passwd *, Key *);
118int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); 118int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
119int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); 119int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
120int auth_krb5_password(Authctxt *authctxt, const char *password); 120int auth_krb5_password(Authctxt *authctxt, const char *password);
121void krb5_cleanup_proc(void *authctxt); 121void krb5_cleanup_proc(Authctxt *authctxt);
122#endif /* KRB5 */ 122#endif /* KRB5 */
123 123
124#include "auth-pam.h" 124#include "auth-pam.h"
125 125
126Authctxt *do_authentication(void); 126void do_authentication(Authctxt *);
127Authctxt *do_authentication2(void); 127void do_authentication2(Authctxt *);
128 128
129Authctxt *authctxt_new(void);
130void auth_log(Authctxt *, int, char *, char *); 129void auth_log(Authctxt *, int, char *, char *);
131void userauth_finish(Authctxt *, int, char *); 130void userauth_finish(Authctxt *, int, char *);
132int auth_root_allowed(char *); 131int auth_root_allowed(char *);
@@ -149,8 +148,6 @@ char *get_challenge(Authctxt *);
149int verify_response(Authctxt *, const char *); 148int verify_response(Authctxt *, const char *);
150void abandon_challenge_response(Authctxt *); 149void abandon_challenge_response(Authctxt *);
151 150
152struct passwd * auth_get_user(void);
153
154char *expand_filename(const char *, struct passwd *); 151char *expand_filename(const char *, struct passwd *);
155char *authorized_keys_file(struct passwd *); 152char *authorized_keys_file(struct passwd *);
156char *authorized_keys_file2(struct passwd *); 153char *authorized_keys_file2(struct passwd *);
diff --git a/auth1.c b/auth1.c
index dfe944dd1..38c0bf93c 100644
--- a/auth1.c
+++ b/auth1.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $"); 13RCSID("$OpenBSD: auth1.c,v 1.53 2003/09/23 20:17:11 markus Exp $");
14 14
15#include "xmalloc.h" 15#include "xmalloc.h"
16#include "rsa.h" 16#include "rsa.h"
@@ -275,10 +275,9 @@ do_authloop(Authctxt *authctxt)
275 * Performs authentication of an incoming connection. Session key has already 275 * Performs authentication of an incoming connection. Session key has already
276 * been exchanged and encryption is enabled. 276 * been exchanged and encryption is enabled.
277 */ 277 */
278Authctxt * 278void
279do_authentication(void) 279do_authentication(Authctxt *authctxt)
280{ 280{
281 Authctxt *authctxt;
282 u_int ulen; 281 u_int ulen;
283 char *user, *style = NULL; 282 char *user, *style = NULL;
284 283
@@ -292,7 +291,6 @@ do_authentication(void)
292 if ((style = strchr(user, ':')) != NULL) 291 if ((style = strchr(user, ':')) != NULL)
293 *style++ = '\0'; 292 *style++ = '\0';
294 293
295 authctxt = authctxt_new();
296 authctxt->user = user; 294 authctxt->user = user;
297 authctxt->style = style; 295 authctxt->style = style;
298 296
@@ -332,6 +330,4 @@ do_authentication(void)
332 packet_start(SSH_SMSG_SUCCESS); 330 packet_start(SSH_SMSG_SUCCESS);
333 packet_send(); 331 packet_send();
334 packet_write_wait(); 332 packet_write_wait();
335
336 return (authctxt);
337} 333}
diff --git a/auth2.c b/auth2.c
index 41e77efdc..ef1173fe6 100644
--- a/auth2.c
+++ b/auth2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $"); 26RCSID("$OpenBSD: auth2.c,v 1.103 2003/09/23 20:17:11 markus Exp $");
27 27
28#include "ssh2.h" 28#include "ssh2.h"
29#include "xmalloc.h" 29#include "xmalloc.h"
@@ -45,8 +45,6 @@ extern ServerOptions options;
45extern u_char *session_id2; 45extern u_char *session_id2;
46extern u_int session_id2_len; 46extern u_int session_id2_len;
47 47
48Authctxt *x_authctxt = NULL;
49
50/* methods */ 48/* methods */
51 49
52extern Authmethod method_none; 50extern Authmethod method_none;
@@ -85,13 +83,9 @@ int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
85 * loop until authctxt->success == TRUE 83 * loop until authctxt->success == TRUE
86 */ 84 */
87 85
88Authctxt * 86void
89do_authentication2(void) 87do_authentication2(Authctxt *authctxt)
90{ 88{
91 Authctxt *authctxt = authctxt_new();
92
93 x_authctxt = authctxt; /*XXX*/
94
95 /* challenge-response is implemented via keyboard interactive */ 89 /* challenge-response is implemented via keyboard interactive */
96 if (options.challenge_response_authentication) 90 if (options.challenge_response_authentication)
97 options.kbd_interactive_authentication = 1; 91 options.kbd_interactive_authentication = 1;
@@ -99,8 +93,6 @@ do_authentication2(void)
99 dispatch_init(&dispatch_protocol_error); 93 dispatch_init(&dispatch_protocol_error);
100 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 94 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
101 dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); 95 dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
102
103 return (authctxt);
104} 96}
105 97
106static void 98static void
@@ -264,14 +256,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
264 } 256 }
265} 257}
266 258
267/* get current user */
268
269struct passwd*
270auth_get_user(void)
271{
272 return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL;
273}
274
275#define DELIM "," 259#define DELIM ","
276 260
277static char * 261static char *
diff --git a/canohost.c b/canohost.c
index 438175f76..fca7134f9 100644
--- a/canohost.c
+++ b/canohost.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $"); 15RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $");
16 16
17#include "packet.h" 17#include "packet.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -40,7 +40,7 @@ get_remote_hostname(int socket, int use_dns)
40 memset(&from, 0, sizeof(from)); 40 memset(&from, 0, sizeof(from));
41 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) { 41 if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) {
42 debug("getpeername failed: %.100s", strerror(errno)); 42 debug("getpeername failed: %.100s", strerror(errno));
43 fatal_cleanup(); 43 cleanup_exit(255);
44 } 44 }
45#ifdef IPV4_IN_IPV6 45#ifdef IPV4_IN_IPV6
46 if (from.ss_family == AF_INET6) { 46 if (from.ss_family == AF_INET6) {
@@ -296,7 +296,7 @@ get_remote_ipaddr(void)
296 canonical_host_ip = 296 canonical_host_ip =
297 get_peer_ipaddr(packet_get_connection_in()); 297 get_peer_ipaddr(packet_get_connection_in());
298 if (canonical_host_ip == NULL) 298 if (canonical_host_ip == NULL)
299 fatal_cleanup(); 299 cleanup_exit(255);
300 } else { 300 } else {
301 /* If not on socket, return UNKNOWN. */ 301 /* If not on socket, return UNKNOWN. */
302 canonical_host_ip = xstrdup("UNKNOWN"); 302 canonical_host_ip = xstrdup("UNKNOWN");
@@ -336,7 +336,7 @@ get_sock_port(int sock, int local)
336 } else { 336 } else {
337 if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { 337 if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
338 debug("getpeername failed: %.100s", strerror(errno)); 338 debug("getpeername failed: %.100s", strerror(errno));
339 fatal_cleanup(); 339 cleanup_exit(255);
340 } 340 }
341 } 341 }
342 342
diff --git a/cleanup.c b/cleanup.c
new file mode 100644
index 000000000..11d1d4d9a
--- /dev/null
+++ b/cleanup.c
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include "includes.h"
17RCSID("$OpenBSD: cleanup.c,v 1.1 2003/09/23 20:17:11 markus Exp $");
18
19#include "log.h"
20
21/* default implementation */
22void
23cleanup_exit(int i)
24{
25 _exit(i);
26}
diff --git a/clientloop.c b/clientloop.c
index bc50f0bca..d3a32a81a 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.113 2003/09/19 17:43:35 markus Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.114 2003/09/23 20:17:11 markus Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -1384,14 +1384,9 @@ client_init_dispatch(void)
1384 1384
1385/* client specific fatal cleanup */ 1385/* client specific fatal cleanup */
1386void 1386void
1387fatal(const char *fmt,...) 1387cleanup_exit(int i)
1388{ 1388{
1389 va_list args;
1390
1391 va_start(args, fmt);
1392 do_log(SYSLOG_LEVEL_FATAL, fmt, args);
1393 va_end(args);
1394 leave_raw_mode(); 1389 leave_raw_mode();
1395 leave_non_blocking(); 1390 leave_non_blocking();
1396 _exit(255); 1391 _exit(i);
1397} 1392}
diff --git a/fatal.c b/fatal.c
index 9e7d16000..ae1aaac6e 100644
--- a/fatal.c
+++ b/fatal.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: fatal.c,v 1.1 2002/02/22 12:20:34 markus Exp $"); 26RCSID("$OpenBSD: fatal.c,v 1.2 2003/09/23 20:17:11 markus Exp $");
27 27
28#include "log.h" 28#include "log.h"
29 29
@@ -36,5 +36,5 @@ fatal(const char *fmt,...)
36 va_start(args, fmt); 36 va_start(args, fmt);
37 do_log(SYSLOG_LEVEL_FATAL, fmt, args); 37 do_log(SYSLOG_LEVEL_FATAL, fmt, args);
38 va_end(args); 38 va_end(args);
39 fatal_cleanup(); 39 cleanup_exit(255);
40} 40}
diff --git a/gss-serv.c b/gss-serv.c
index 8fd1d63f0..6574f9750 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gss-serv.c,v 1.3 2003/08/31 13:31:57 markus Exp $ */ 1/* $OpenBSD: gss-serv.c,v 1.4 2003/09/23 20:17:11 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -232,9 +232,9 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
232 return (ctx->major); 232 return (ctx->major);
233} 233}
234 234
235/* As user - called through fatal cleanup hook */ 235/* As user - called on fatal/exit */
236void 236void
237ssh_gssapi_cleanup_creds(void *ignored) 237ssh_gssapi_cleanup_creds(void)
238{ 238{
239 if (gssapi_client.store.filename != NULL) { 239 if (gssapi_client.store.filename != NULL) {
240 /* Unlink probably isn't sufficient */ 240 /* Unlink probably isn't sufficient */
@@ -249,8 +249,6 @@ ssh_gssapi_storecreds(void)
249{ 249{
250 if (gssapi_client.mech && gssapi_client.mech->storecreds) { 250 if (gssapi_client.mech && gssapi_client.mech->storecreds) {
251 (*gssapi_client.mech->storecreds)(&gssapi_client); 251 (*gssapi_client.mech->storecreds)(&gssapi_client);
252 if (options.gss_cleanup_creds)
253 fatal_add_cleanup(ssh_gssapi_cleanup_creds, NULL);
254 } else 252 } else
255 debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); 253 debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
256} 254}
diff --git a/log.c b/log.c
index 9bce2555b..686a2a43c 100644
--- a/log.c
+++ b/log.c
@@ -34,7 +34,7 @@
34 */ 34 */
35 35
36#include "includes.h" 36#include "includes.h"
37RCSID("$OpenBSD: log.c,v 1.28 2003/05/24 09:02:22 djm Exp $"); 37RCSID("$OpenBSD: log.c,v 1.29 2003/09/23 20:17:11 markus Exp $");
38 38
39#include "log.h" 39#include "log.h"
40#include "xmalloc.h" 40#include "xmalloc.h"
@@ -183,83 +183,6 @@ debug3(const char *fmt,...)
183 va_end(args); 183 va_end(args);
184} 184}
185 185
186/* Fatal cleanup */
187
188struct fatal_cleanup {
189 struct fatal_cleanup *next;
190 void (*proc) (void *);
191 void *context;
192};
193
194static struct fatal_cleanup *fatal_cleanups = NULL;
195
196/* Registers a cleanup function to be called by fatal() before exiting. */
197
198void
199fatal_add_cleanup(void (*proc) (void *), void *context)
200{
201 struct fatal_cleanup *cu;
202
203 cu = xmalloc(sizeof(*cu));
204 cu->proc = proc;
205 cu->context = context;
206 cu->next = fatal_cleanups;
207 fatal_cleanups = cu;
208}
209
210/* Removes a cleanup frunction to be called at fatal(). */
211
212void
213fatal_remove_cleanup(void (*proc) (void *context), void *context)
214{
215 struct fatal_cleanup **cup, *cu;
216
217 for (cup = &fatal_cleanups; *cup; cup = &cu->next) {
218 cu = *cup;
219 if (cu->proc == proc && cu->context == context) {
220 *cup = cu->next;
221 xfree(cu);
222 return;
223 }
224 }
225 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx",
226 (u_long) proc, (u_long) context);
227}
228
229/* Remove all cleanups, to be called after fork() */
230void
231fatal_remove_all_cleanups(void)
232{
233 struct fatal_cleanup *cu, *next_cu;
234
235 for (cu = fatal_cleanups; cu; cu = next_cu) {
236 next_cu = cu->next;
237 xfree(cu);
238 }
239 fatal_cleanups = NULL;
240}
241
242/* Cleanup and exit */
243void
244fatal_cleanup(void)
245{
246 struct fatal_cleanup *cu, *next_cu;
247 static int called = 0;
248
249 if (called)
250 exit(255);
251 called = 1;
252 /* Call cleanup functions. */
253 for (cu = fatal_cleanups; cu; cu = next_cu) {
254 next_cu = cu->next;
255 debug("Calling cleanup 0x%lx(0x%lx)",
256 (u_long) cu->proc, (u_long) cu->context);
257 (*cu->proc) (cu->context);
258 }
259 exit(255);
260}
261
262
263/* 186/*
264 * Initialize the log. 187 * Initialize the log.
265 */ 188 */
diff --git a/log.h b/log.h
index c3666818f..e0263194f 100644
--- a/log.h
+++ b/log.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: log.h,v 1.9 2003/04/08 20:21:28 itojun Exp $ */ 1/* $OpenBSD: log.h,v 1.10 2003/09/23 20:17:11 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -61,11 +61,6 @@ void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
61void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); 61void debug2(const char *, ...) __attribute__((format(printf, 1, 2)));
62void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); 62void debug3(const char *, ...) __attribute__((format(printf, 1, 2)));
63 63
64void fatal_cleanup(void);
65void fatal_add_cleanup(void (*) (void *), void *);
66void fatal_remove_cleanup(void (*) (void *), void *);
67void fatal_remove_all_cleanups(void);
68
69void do_log(LogLevel, const char *, va_list); 64void do_log(LogLevel, const char *, va_list);
70 65void cleanup_exit(int);
71#endif 66#endif
diff --git a/monitor.c b/monitor.c
index e5656470d..eaf66f7c8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $"); 28RCSID("$OpenBSD: monitor.c,v 1.50 2003/09/23 20:17:11 markus Exp $");
29 29
30#include <openssl/dh.h> 30#include <openssl/dh.h>
31 31
@@ -272,14 +272,17 @@ monitor_permit_authentications(int permit)
272 } 272 }
273} 273}
274 274
275Authctxt * 275void
276monitor_child_preauth(struct monitor *pmonitor) 276monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
277{ 277{
278 struct mon_table *ent; 278 struct mon_table *ent;
279 int authenticated = 0; 279 int authenticated = 0;
280 280
281 debug3("preauth child monitor started"); 281 debug3("preauth child monitor started");
282 282
283 authctxt = _authctxt;
284 memset(authctxt, 0, sizeof(*authctxt));
285
283 if (compat20) { 286 if (compat20) {
284 mon_dispatch = mon_dispatch_proto20; 287 mon_dispatch = mon_dispatch_proto20;
285 288
@@ -292,8 +295,6 @@ monitor_child_preauth(struct monitor *pmonitor)
292 monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); 295 monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
293 } 296 }
294 297
295 authctxt = authctxt_new();
296
297 /* The first few requests do not require asynchronous access */ 298 /* The first few requests do not require asynchronous access */
298 while (!authenticated) { 299 while (!authenticated) {
299 authenticated = monitor_read(pmonitor, mon_dispatch, &ent); 300 authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
@@ -333,8 +334,6 @@ monitor_child_preauth(struct monitor *pmonitor)
333 __func__, authctxt->user); 334 __func__, authctxt->user);
334 335
335 mm_get_keystate(pmonitor); 336 mm_get_keystate(pmonitor);
336
337 return (authctxt);
338} 337}
339 338
340static void 339static void
@@ -1185,7 +1184,7 @@ mm_record_login(Session *s, struct passwd *pw)
1185 if (getpeername(packet_get_connection_in(), 1184 if (getpeername(packet_get_connection_in(),
1186 (struct sockaddr *) & from, &fromlen) < 0) { 1185 (struct sockaddr *) & from, &fromlen) < 0) {
1187 debug("getpeername: %.100s", strerror(errno)); 1186 debug("getpeername: %.100s", strerror(errno));
1188 fatal_cleanup(); 1187 cleanup_exit(255);
1189 } 1188 }
1190 } 1189 }
1191 /* Record that there was a login on that tty from the remote host. */ 1190 /* Record that there was a login on that tty from the remote host. */
@@ -1200,7 +1199,6 @@ mm_session_close(Session *s)
1200 debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); 1199 debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
1201 if (s->ttyfd != -1) { 1200 if (s->ttyfd != -1) {
1202 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); 1201 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
1203 fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
1204 session_pty_cleanup2(s); 1202 session_pty_cleanup2(s);
1205 } 1203 }
1206 s->used = 0; 1204 s->used = 0;
@@ -1225,7 +1223,6 @@ mm_answer_pty(int socket, Buffer *m)
1225 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1223 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
1226 if (res == 0) 1224 if (res == 0)
1227 goto error; 1225 goto error;
1228 fatal_add_cleanup(session_pty_cleanup2, (void *)s);
1229 pty_setowner(authctxt->pw, s->tty); 1226 pty_setowner(authctxt->pw, s->tty);
1230 1227
1231 buffer_put_int(m, 1); 1228 buffer_put_int(m, 1);
diff --git a/monitor.h b/monitor.h
index 2461156c7..a153f4168 100644
--- a/monitor.h
+++ b/monitor.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ 1/* $OpenBSD: monitor.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -76,7 +76,7 @@ void monitor_reinit(struct monitor *);
76void monitor_sync(struct monitor *); 76void monitor_sync(struct monitor *);
77 77
78struct Authctxt; 78struct Authctxt;
79struct Authctxt *monitor_child_preauth(struct monitor *); 79void monitor_child_preauth(struct Authctxt *, struct monitor *);
80void monitor_child_postauth(struct monitor *); 80void monitor_child_postauth(struct monitor *);
81 81
82struct mon_table; 82struct mon_table;
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 4034d569c..99dfc8508 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $"); 28RCSID("$OpenBSD: monitor_wrap.c,v 1.32 2003/09/23 20:17:11 markus Exp $");
29 29
30#include <openssl/bn.h> 30#include <openssl/bn.h>
31#include <openssl/dh.h> 31#include <openssl/dh.h>
@@ -66,6 +66,16 @@ extern struct monitor *pmonitor;
66extern Buffer input, output; 66extern Buffer input, output;
67extern ServerOptions options; 67extern ServerOptions options;
68 68
69int
70mm_is_monitor(void)
71{
72 /*
73 * m_pid is only set in the privileged part, and
74 * points to the unprivileged child.
75 */
76 return (pmonitor->m_pid > 0);
77}
78
69void 79void
70mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) 80mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
71{ 81{
@@ -94,7 +104,7 @@ mm_request_receive(int socket, Buffer *m)
94 res = atomicio(read, socket, buf, sizeof(buf)); 104 res = atomicio(read, socket, buf, sizeof(buf));
95 if (res != sizeof(buf)) { 105 if (res != sizeof(buf)) {
96 if (res == 0) 106 if (res == 0)
97 fatal_cleanup(); 107 cleanup_exit(255);
98 fatal("%s: read: %ld", __func__, (long)res); 108 fatal("%s: read: %ld", __func__, (long)res);
99 } 109 }
100 msg_len = GET_32BIT(buf); 110 msg_len = GET_32BIT(buf);
@@ -648,9 +658,8 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
648} 658}
649 659
650void 660void
651mm_session_pty_cleanup2(void *session) 661mm_session_pty_cleanup2(Session *s)
652{ 662{
653 Session *s = session;
654 Buffer m; 663 Buffer m;
655 664
656 if (s->ttyfd == -1) 665 if (s->ttyfd == -1)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 5e0334588..76c02f13a 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -40,6 +40,7 @@ struct mm_master;
40struct passwd; 40struct passwd;
41struct Authctxt; 41struct Authctxt;
42 42
43int mm_is_monitor(void);
43DH *mm_choose_dh(int, int, int); 44DH *mm_choose_dh(int, int, int);
44int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); 45int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
45void mm_inform_authserv(char *, char *); 46void mm_inform_authserv(char *, char *);
@@ -72,9 +73,10 @@ int mm_sshpam_respond(void *, u_int, char **);
72void mm_sshpam_free_ctx(void *); 73void mm_sshpam_free_ctx(void *);
73#endif 74#endif
74 75
76struct Session;
75void mm_terminate(void); 77void mm_terminate(void);
76int mm_pty_allocate(int *, int *, char *, int); 78int mm_pty_allocate(int *, int *, char *, int);
77void mm_session_pty_cleanup2(void *); 79void mm_session_pty_cleanup2(struct Session *);
78 80
79/* SSHv1 interfaces */ 81/* SSHv1 interfaces */
80void mm_ssh1_session_id(u_char *); 82void mm_ssh1_session_id(u_char *);
diff --git a/packet.c b/packet.c
index 6e7e574ab..52b4f664c 100644
--- a/packet.c
+++ b/packet.c
@@ -37,7 +37,7 @@
37 */ 37 */
38 38
39#include "includes.h" 39#include "includes.h"
40RCSID("$OpenBSD: packet.c,v 1.111 2003/09/19 11:33:09 markus Exp $"); 40RCSID("$OpenBSD: packet.c,v 1.112 2003/09/23 20:17:11 markus Exp $");
41 41
42#include "openbsd-compat/sys-queue.h" 42#include "openbsd-compat/sys-queue.h"
43 43
@@ -868,7 +868,7 @@ packet_read_seqnr(u_int32_t *seqnr_p)
868 len = read(connection_in, buf, sizeof(buf)); 868 len = read(connection_in, buf, sizeof(buf));
869 if (len == 0) { 869 if (len == 0) {
870 logit("Connection closed by %.200s", get_remote_ipaddr()); 870 logit("Connection closed by %.200s", get_remote_ipaddr());
871 fatal_cleanup(); 871 cleanup_exit(255);
872 } 872 }
873 if (len < 0) 873 if (len < 0)
874 fatal("Read from socket failed: %.100s", strerror(errno)); 874 fatal("Read from socket failed: %.100s", strerror(errno));
@@ -1134,7 +1134,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
1134 logit("Received disconnect from %s: %u: %.400s", 1134 logit("Received disconnect from %s: %u: %.400s",
1135 get_remote_ipaddr(), reason, msg); 1135 get_remote_ipaddr(), reason, msg);
1136 xfree(msg); 1136 xfree(msg);
1137 fatal_cleanup(); 1137 cleanup_exit(255);
1138 break; 1138 break;
1139 case SSH2_MSG_UNIMPLEMENTED: 1139 case SSH2_MSG_UNIMPLEMENTED:
1140 seqnr = packet_get_int(); 1140 seqnr = packet_get_int();
@@ -1159,7 +1159,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
1159 msg = packet_get_string(NULL); 1159 msg = packet_get_string(NULL);
1160 logit("Received disconnect from %s: %.400s", 1160 logit("Received disconnect from %s: %.400s",
1161 get_remote_ipaddr(), msg); 1161 get_remote_ipaddr(), msg);
1162 fatal_cleanup(); 1162 cleanup_exit(255);
1163 xfree(msg); 1163 xfree(msg);
1164 break; 1164 break;
1165 default: 1165 default:
@@ -1336,7 +1336,7 @@ packet_disconnect(const char *fmt,...)
1336 1336
1337 /* Close the connection. */ 1337 /* Close the connection. */
1338 packet_close(); 1338 packet_close();
1339 fatal_cleanup(); 1339 cleanup_exit(255);
1340} 1340}
1341 1341
1342/* Checks if there is any buffered output, and tries to write some of the output. */ 1342/* Checks if there is any buffered output, and tries to write some of the output. */
diff --git a/serverloop.c b/serverloop.c
index a95390273..21656cf87 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.110 2003/06/24 08:23:46 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.111 2003/09/23 20:17:11 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -60,7 +60,7 @@ extern ServerOptions options;
60 60
61/* XXX */ 61/* XXX */
62extern Kex *xxx_kex; 62extern Kex *xxx_kex;
63static Authctxt *xxx_authctxt; 63extern Authctxt *the_authctxt;
64 64
65static Buffer stdin_buffer; /* Buffer for stdin data. */ 65static Buffer stdin_buffer; /* Buffer for stdin data. */
66static Buffer stdout_buffer; /* Buffer for stdout data. */ 66static Buffer stdout_buffer; /* Buffer for stdout data. */
@@ -355,13 +355,13 @@ process_input(fd_set * readset)
355 connection_closed = 1; 355 connection_closed = 1;
356 if (compat20) 356 if (compat20)
357 return; 357 return;
358 fatal_cleanup(); 358 cleanup_exit(255);
359 } else if (len < 0) { 359 } else if (len < 0) {
360 if (errno != EINTR && errno != EAGAIN) { 360 if (errno != EINTR && errno != EAGAIN) {
361 verbose("Read error from remote host " 361 verbose("Read error from remote host "
362 "%.100s: %.100s", 362 "%.100s: %.100s",
363 get_remote_ipaddr(), strerror(errno)); 363 get_remote_ipaddr(), strerror(errno));
364 fatal_cleanup(); 364 cleanup_exit(255);
365 } 365 }
366 } else { 366 } else {
367 /* Buffer any received data. */ 367 /* Buffer any received data. */
@@ -756,8 +756,6 @@ server_loop2(Authctxt *authctxt)
756 max_fd = MAX(connection_in, connection_out); 756 max_fd = MAX(connection_in, connection_out);
757 max_fd = MAX(max_fd, notify_pipe[0]); 757 max_fd = MAX(max_fd, notify_pipe[0]);
758 758
759 xxx_authctxt = authctxt;
760
761 server_init_dispatch(); 759 server_init_dispatch();
762 760
763 for (;;) { 761 for (;;) {
@@ -900,7 +898,7 @@ server_request_session(char *ctype)
900 c = channel_new(ctype, SSH_CHANNEL_LARVAL, 898 c = channel_new(ctype, SSH_CHANNEL_LARVAL,
901 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 899 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
902 0, "server-session", 1); 900 0, "server-session", 1);
903 if (session_open(xxx_authctxt, c->self) != 1) { 901 if (session_open(the_authctxt, c->self) != 1) {
904 debug("session open failed, free channel %d", c->self); 902 debug("session open failed, free channel %d", c->self);
905 channel_free(c); 903 channel_free(c);
906 return NULL; 904 return NULL;
@@ -974,7 +972,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
974 char *listen_address; 972 char *listen_address;
975 u_short listen_port; 973 u_short listen_port;
976 974
977 pw = auth_get_user(); 975 pw = the_authctxt->pw;
978 if (pw == NULL) 976 if (pw == NULL)
979 fatal("server_input_global_request: no user"); 977 fatal("server_input_global_request: no user");
980 listen_address = packet_get_string(NULL); 978 listen_address = packet_get_string(NULL);
diff --git a/session.c b/session.c
index 2898ac518..647be401e 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.165 2003/09/23 20:17:11 markus Exp $");
37 37
38#include "ssh.h" 38#include "ssh.h"
39#include "ssh1.h" 39#include "ssh1.h"
@@ -66,7 +66,7 @@ RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $");
66 66
67Session *session_new(void); 67Session *session_new(void);
68void session_set_fds(Session *, int, int, int); 68void session_set_fds(Session *, int, int, int);
69void session_pty_cleanup(void *); 69void session_pty_cleanup(Session *);
70void session_proctitle(Session *); 70void session_proctitle(Session *);
71int session_setup_x11fwd(Session *); 71int session_setup_x11fwd(Session *);
72void do_exec_pty(Session *, const char *); 72void do_exec_pty(Session *, const char *);
@@ -106,6 +106,8 @@ Session sessions[MAX_SESSIONS];
106login_cap_t *lc; 106login_cap_t *lc;
107#endif 107#endif
108 108
109static int is_child = 0;
110
109/* Name and directory of socket for authentication agent forwarding. */ 111/* Name and directory of socket for authentication agent forwarding. */
110static char *auth_sock_name = NULL; 112static char *auth_sock_name = NULL;
111static char *auth_sock_dir = NULL; 113static char *auth_sock_dir = NULL;
@@ -113,10 +115,8 @@ static char *auth_sock_dir = NULL;
113/* removes the agent forwarding socket */ 115/* removes the agent forwarding socket */
114 116
115static void 117static void
116auth_sock_cleanup_proc(void *_pw) 118auth_sock_cleanup_proc(struct passwd *pw)
117{ 119{
118 struct passwd *pw = _pw;
119
120 if (auth_sock_name != NULL) { 120 if (auth_sock_name != NULL) {
121 temporarily_use_uid(pw); 121 temporarily_use_uid(pw);
122 unlink(auth_sock_name); 122 unlink(auth_sock_name);
@@ -160,9 +160,6 @@ auth_input_request_forwarding(struct passwd * pw)
160 snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld", 160 snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
161 auth_sock_dir, (long) getpid()); 161 auth_sock_dir, (long) getpid());
162 162
163 /* delete agent socket on fatal() */
164 fatal_add_cleanup(auth_sock_cleanup_proc, pw);
165
166 /* Create the socket. */ 163 /* Create the socket. */
167 sock = socket(AF_UNIX, SOCK_STREAM, 0); 164 sock = socket(AF_UNIX, SOCK_STREAM, 0);
168 if (sock < 0) 165 if (sock < 0)
@@ -217,13 +214,7 @@ do_authenticated(Authctxt *authctxt)
217 else 214 else
218 do_authenticated1(authctxt); 215 do_authenticated1(authctxt);
219 216
220 /* remove agent socket */ 217 do_cleanup(authctxt);
221 if (auth_sock_name != NULL)
222 auth_sock_cleanup_proc(authctxt->pw);
223#ifdef KRB5
224 if (options.kerberos_ticket_cleanup)
225 krb5_cleanup_proc(authctxt);
226#endif
227} 218}
228 219
229/* 220/*
@@ -405,7 +396,7 @@ do_exec_no_pty(Session *s, const char *command)
405 396
406 /* Fork the child. */ 397 /* Fork the child. */
407 if ((pid = fork()) == 0) { 398 if ((pid = fork()) == 0) {
408 fatal_remove_all_cleanups(); 399 is_child = 1;
409 400
410 /* Child. Reinitialize the log since the pid has changed. */ 401 /* Child. Reinitialize the log since the pid has changed. */
411 log_init(__progname, options.log_level, options.log_facility, log_stderr); 402 log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -531,7 +522,7 @@ do_exec_pty(Session *s, const char *command)
531 522
532 /* Fork the child. */ 523 /* Fork the child. */
533 if ((pid = fork()) == 0) { 524 if ((pid = fork()) == 0) {
534 fatal_remove_all_cleanups(); 525 is_child = 1;
535 526
536 /* Child. Reinitialize the log because the pid has changed. */ 527 /* Child. Reinitialize the log because the pid has changed. */
537 log_init(__progname, options.log_level, options.log_facility, log_stderr); 528 log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -627,7 +618,7 @@ do_pre_login(Session *s)
627 if (getpeername(packet_get_connection_in(), 618 if (getpeername(packet_get_connection_in(),
628 (struct sockaddr *) & from, &fromlen) < 0) { 619 (struct sockaddr *) & from, &fromlen) < 0) {
629 debug("getpeername: %.100s", strerror(errno)); 620 debug("getpeername: %.100s", strerror(errno));
630 fatal_cleanup(); 621 cleanup_exit(255);
631 } 622 }
632 } 623 }
633 624
@@ -687,7 +678,7 @@ do_login(Session *s, const char *command)
687 if (getpeername(packet_get_connection_in(), 678 if (getpeername(packet_get_connection_in(),
688 (struct sockaddr *) & from, &fromlen) < 0) { 679 (struct sockaddr *) & from, &fromlen) < 0) {
689 debug("getpeername: %.100s", strerror(errno)); 680 debug("getpeername: %.100s", strerror(errno));
690 fatal_cleanup(); 681 cleanup_exit(255);
691 } 682 }
692 } 683 }
693 684
@@ -1178,7 +1169,7 @@ do_rc_files(Session *s, const char *shell)
1178 if (debug_flag) { 1169 if (debug_flag) {
1179 fprintf(stderr, 1170 fprintf(stderr,
1180 "Running %.500s remove %.100s\n", 1171 "Running %.500s remove %.100s\n",
1181 options.xauth_location, s->auth_display); 1172 options.xauth_location, s->auth_display);
1182 fprintf(stderr, 1173 fprintf(stderr,
1183 "%.500s add %.100s %.100s %.100s\n", 1174 "%.500s add %.100s %.100s %.100s\n",
1184 options.xauth_location, s->auth_display, 1175 options.xauth_location, s->auth_display,
@@ -1663,11 +1654,6 @@ session_pty_req(Session *s)
1663 n_bytes = packet_remaining(); 1654 n_bytes = packet_remaining();
1664 tty_parse_modes(s->ttyfd, &n_bytes); 1655 tty_parse_modes(s->ttyfd, &n_bytes);
1665 1656
1666 /*
1667 * Add a cleanup function to clear the utmp entry and record logout
1668 * time in case we call fatal() (e.g., the connection gets closed).
1669 */
1670 fatal_add_cleanup(session_pty_cleanup, (void *)s);
1671 if (!use_privsep) 1657 if (!use_privsep)
1672 pty_setowner(s->pw, s->tty); 1658 pty_setowner(s->pw, s->tty);
1673 1659
@@ -1849,10 +1835,8 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
1849 * (e.g., due to a dropped connection). 1835 * (e.g., due to a dropped connection).
1850 */ 1836 */
1851void 1837void
1852session_pty_cleanup2(void *session) 1838session_pty_cleanup2(Session *s)
1853{ 1839{
1854 Session *s = session;
1855
1856 if (s == NULL) { 1840 if (s == NULL) {
1857 error("session_pty_cleanup: no session"); 1841 error("session_pty_cleanup: no session");
1858 return; 1842 return;
@@ -1883,9 +1867,9 @@ session_pty_cleanup2(void *session)
1883} 1867}
1884 1868
1885void 1869void
1886session_pty_cleanup(void *session) 1870session_pty_cleanup(Session *s)
1887{ 1871{
1888 PRIVSEP(session_pty_cleanup2(session)); 1872 PRIVSEP(session_pty_cleanup2(s));
1889} 1873}
1890 1874
1891static char * 1875static char *
@@ -1958,10 +1942,8 @@ void
1958session_close(Session *s) 1942session_close(Session *s)
1959{ 1943{
1960 debug("session_close: session %d pid %ld", s->self, (long)s->pid); 1944 debug("session_close: session %d pid %ld", s->self, (long)s->pid);
1961 if (s->ttyfd != -1) { 1945 if (s->ttyfd != -1)
1962 fatal_remove_cleanup(session_pty_cleanup, (void *)s);
1963 session_pty_cleanup(s); 1946 session_pty_cleanup(s);
1964 }
1965 if (s->term) 1947 if (s->term)
1966 xfree(s->term); 1948 xfree(s->term);
1967 if (s->display) 1949 if (s->display)
@@ -2010,10 +1992,8 @@ session_close_by_channel(int id, void *arg)
2010 * delay detach of session, but release pty, since 1992 * delay detach of session, but release pty, since
2011 * the fd's to the child are already closed 1993 * the fd's to the child are already closed
2012 */ 1994 */
2013 if (s->ttyfd != -1) { 1995 if (s->ttyfd != -1)
2014 fatal_remove_cleanup(session_pty_cleanup, (void *)s);
2015 session_pty_cleanup(s); 1996 session_pty_cleanup(s);
2016 }
2017 return; 1997 return;
2018 } 1998 }
2019 /* detach by removing callback */ 1999 /* detach by removing callback */
@@ -2154,8 +2134,44 @@ static void
2154do_authenticated2(Authctxt *authctxt) 2134do_authenticated2(Authctxt *authctxt)
2155{ 2135{
2156 server_loop2(authctxt); 2136 server_loop2(authctxt);
2157#if defined(GSSAPI) 2137}
2158 if (options.gss_cleanup_creds) 2138
2159 ssh_gssapi_cleanup_creds(NULL); 2139void
2140do_cleanup(Authctxt *authctxt)
2141{
2142 static int called = 0;
2143
2144 debug("do_cleanup");
2145
2146 /* no cleanup if we're in the child for login shell */
2147 if (is_child)
2148 return;
2149
2150 /* avoid double cleanup */
2151 if (called)
2152 return;
2153 called = 1;
2154
2155 if (authctxt == NULL)
2156 return;
2157#ifdef KRB5
2158 if (options.kerberos_ticket_cleanup &&
2159 authctxt->krb5_ctx)
2160 krb5_cleanup_proc(authctxt);
2160#endif 2161#endif
2162
2163#ifdef GSSAPI
2164 if (compat20 && options.gss_cleanup_creds)
2165 ssh_gssapi_cleanup_creds();
2166#endif
2167
2168 /* remove agent socket */
2169 auth_sock_cleanup_proc(authctxt->pw);
2170
2171 /*
2172 * Cleanup ptys/utmp only if privsep is disabled,
2173 * or if running in monitor.
2174 */
2175 if (!use_privsep || mm_is_monitor())
2176 session_destroy_all(session_pty_cleanup2);
2161} 2177}
diff --git a/session.h b/session.h
index 525e47f64..405b8fe8a 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $ */ 1/* $OpenBSD: session.h,v 1.21 2003/09/23 20:17:11 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -56,13 +56,14 @@ struct Session {
56}; 56};
57 57
58void do_authenticated(Authctxt *); 58void do_authenticated(Authctxt *);
59void do_cleanup(Authctxt *);
59 60
60int session_open(Authctxt *, int); 61int session_open(Authctxt *, int);
61int session_input_channel_req(Channel *, const char *); 62int session_input_channel_req(Channel *, const char *);
62void session_close_by_pid(pid_t, int); 63void session_close_by_pid(pid_t, int);
63void session_close_by_channel(int, void *); 64void session_close_by_channel(int, void *);
64void session_destroy_all(void (*)(Session *)); 65void session_destroy_all(void (*)(Session *));
65void session_pty_cleanup2(void *); 66void session_pty_cleanup2(Session *);
66 67
67Session *session_new(void); 68Session *session_new(void);
68Session *session_by_tty(char *); 69Session *session_by_tty(char *);
diff --git a/ssh-agent.c b/ssh-agent.c
index 28a39a934..0fe877299 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -35,7 +35,7 @@
35 35
36#include "includes.h" 36#include "includes.h"
37#include "openbsd-compat/sys-queue.h" 37#include "openbsd-compat/sys-queue.h"
38RCSID("$OpenBSD: ssh-agent.c,v 1.113 2003/09/19 11:29:40 markus Exp $"); 38RCSID("$OpenBSD: ssh-agent.c,v 1.114 2003/09/23 20:17:11 markus Exp $");
39 39
40#include <openssl/evp.h> 40#include <openssl/evp.h>
41#include <openssl/md5.h> 41#include <openssl/md5.h>
@@ -957,7 +957,7 @@ cleanup_socket(void)
957 rmdir(socket_dir); 957 rmdir(socket_dir);
958} 958}
959 959
960static void 960void
961cleanup_exit(int i) 961cleanup_exit(int i)
962{ 962{
963 cleanup_socket(); 963 cleanup_socket();
@@ -971,17 +971,6 @@ cleanup_handler(int sig)
971 _exit(2); 971 _exit(2);
972} 972}
973 973
974void
975fatal(const char *fmt,...)
976{
977 va_list args;
978 va_start(args, fmt);
979 do_log(SYSLOG_LEVEL_FATAL, fmt, args);
980 va_end(args);
981 cleanup_socket();
982 _exit(255);
983}
984
985static void 974static void
986check_parent_exists(int sig) 975check_parent_exists(int sig)
987{ 976{
diff --git a/sshd.c b/sshd.c
index 4b3ff0da3..5c2711295 100644
--- a/sshd.c
+++ b/sshd.c
@@ -42,7 +42,7 @@
42 */ 42 */
43 43
44#include "includes.h" 44#include "includes.h"
45RCSID("$OpenBSD: sshd.c,v 1.277 2003/09/19 11:33:09 markus Exp $"); 45RCSID("$OpenBSD: sshd.c,v 1.278 2003/09/23 20:17:11 markus Exp $");
46 46
47#include <openssl/dh.h> 47#include <openssl/dh.h>
48#include <openssl/bn.h> 48#include <openssl/bn.h>
@@ -204,6 +204,9 @@ struct monitor *pmonitor;
204/* message to be displayed after login */ 204/* message to be displayed after login */
205Buffer loginmsg; 205Buffer loginmsg;
206 206
207/* global authentication context */
208Authctxt *the_authctxt = NULL;
209
207/* Prototypes for various functions defined later in this file. */ 210/* Prototypes for various functions defined later in this file. */
208void destroy_sensitive_data(void); 211void destroy_sensitive_data(void);
209void demote_sensitive_data(void); 212void demote_sensitive_data(void);
@@ -375,7 +378,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
375 strlen(server_version_string)) 378 strlen(server_version_string))
376 != strlen(server_version_string)) { 379 != strlen(server_version_string)) {
377 logit("Could not write ident string to %s", get_remote_ipaddr()); 380 logit("Could not write ident string to %s", get_remote_ipaddr());
378 fatal_cleanup(); 381 cleanup_exit(255);
379 } 382 }
380 383
381 /* Read other sides version identification. */ 384 /* Read other sides version identification. */
@@ -384,7 +387,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
384 if (atomicio(read, sock_in, &buf[i], 1) != 1) { 387 if (atomicio(read, sock_in, &buf[i], 1) != 1) {
385 logit("Did not receive identification string from %s", 388 logit("Did not receive identification string from %s",
386 get_remote_ipaddr()); 389 get_remote_ipaddr());
387 fatal_cleanup(); 390 cleanup_exit(255);
388 } 391 }
389 if (buf[i] == '\r') { 392 if (buf[i] == '\r') {
390 buf[i] = 0; 393 buf[i] = 0;
@@ -414,7 +417,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
414 close(sock_out); 417 close(sock_out);
415 logit("Bad protocol version identification '%.100s' from %s", 418 logit("Bad protocol version identification '%.100s' from %s",
416 client_version_string, get_remote_ipaddr()); 419 client_version_string, get_remote_ipaddr());
417 fatal_cleanup(); 420 cleanup_exit(255);
418 } 421 }
419 debug("Client protocol version %d.%d; client software version %.100s", 422 debug("Client protocol version %d.%d; client software version %.100s",
420 remote_major, remote_minor, remote_version); 423 remote_major, remote_minor, remote_version);
@@ -424,13 +427,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
424 if (datafellows & SSH_BUG_PROBE) { 427 if (datafellows & SSH_BUG_PROBE) {
425 logit("probed from %s with %s. Don't panic.", 428 logit("probed from %s with %s. Don't panic.",
426 get_remote_ipaddr(), client_version_string); 429 get_remote_ipaddr(), client_version_string);
427 fatal_cleanup(); 430 cleanup_exit(255);
428 } 431 }
429 432
430 if (datafellows & SSH_BUG_SCANNER) { 433 if (datafellows & SSH_BUG_SCANNER) {
431 logit("scanned from %s with %s. Don't panic.", 434 logit("scanned from %s with %s. Don't panic.",
432 get_remote_ipaddr(), client_version_string); 435 get_remote_ipaddr(), client_version_string);
433 fatal_cleanup(); 436 cleanup_exit(255);
434 } 437 }
435 438
436 mismatch = 0; 439 mismatch = 0;
@@ -476,7 +479,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
476 logit("Protocol major versions differ for %s: %.200s vs. %.200s", 479 logit("Protocol major versions differ for %s: %.200s vs. %.200s",
477 get_remote_ipaddr(), 480 get_remote_ipaddr(),
478 server_version_string, client_version_string); 481 server_version_string, client_version_string);
479 fatal_cleanup(); 482 cleanup_exit(255);
480 } 483 }
481} 484}
482 485
@@ -571,10 +574,9 @@ privsep_preauth_child(void)
571#endif 574#endif
572} 575}
573 576
574static Authctxt * 577static int
575privsep_preauth(void) 578privsep_preauth(Authctxt *authctxt)
576{ 579{
577 Authctxt *authctxt = NULL;
578 int status; 580 int status;
579 pid_t pid; 581 pid_t pid;
580 582
@@ -590,7 +592,7 @@ privsep_preauth(void)
590 debug2("Network child is on pid %ld", (long)pid); 592 debug2("Network child is on pid %ld", (long)pid);
591 593
592 close(pmonitor->m_recvfd); 594 close(pmonitor->m_recvfd);
593 authctxt = monitor_child_preauth(pmonitor); 595 monitor_child_preauth(authctxt, pmonitor);
594 close(pmonitor->m_sendfd); 596 close(pmonitor->m_sendfd);
595 597
596 /* Sync memory */ 598 /* Sync memory */
@@ -600,7 +602,7 @@ privsep_preauth(void)
600 while (waitpid(pid, &status, 0) < 0) 602 while (waitpid(pid, &status, 0) < 0)
601 if (errno != EINTR) 603 if (errno != EINTR)
602 break; 604 break;
603 return (authctxt); 605 return (1);
604 } else { 606 } else {
605 /* child */ 607 /* child */
606 608
@@ -611,17 +613,12 @@ privsep_preauth(void)
611 privsep_preauth_child(); 613 privsep_preauth_child();
612 setproctitle("%s", "[net]"); 614 setproctitle("%s", "[net]");
613 } 615 }
614 return (NULL); 616 return (0);
615} 617}
616 618
617static void 619static void
618privsep_postauth(Authctxt *authctxt) 620privsep_postauth(Authctxt *authctxt)
619{ 621{
620 extern Authctxt *x_authctxt;
621
622 /* XXX - Remote port forwarding */
623 x_authctxt = authctxt;
624
625#ifdef DISABLE_FD_PASSING 622#ifdef DISABLE_FD_PASSING
626 if (1) { 623 if (1) {
627#else 624#else
@@ -804,8 +801,8 @@ main(int ac, char **av)
804 int listen_sock, maxfd; 801 int listen_sock, maxfd;
805 int startup_p[2]; 802 int startup_p[2];
806 int startups = 0; 803 int startups = 0;
807 Authctxt *authctxt;
808 Key *key; 804 Key *key;
805 Authctxt *authctxt;
809 int ret, key_used = 0; 806 int ret, key_used = 0;
810 807
811#ifdef HAVE_SECUREWARE 808#ifdef HAVE_SECUREWARE
@@ -1460,18 +1457,25 @@ main(int ac, char **av)
1460 /* prepare buffers to collect authentication messages */ 1457 /* prepare buffers to collect authentication messages */
1461 buffer_init(&loginmsg); 1458 buffer_init(&loginmsg);
1462 1459
1460 /* allocate authentication context */
1461 authctxt = xmalloc(sizeof(*authctxt));
1462 memset(authctxt, 0, sizeof(*authctxt));
1463
1464 /* XXX global for cleanup, access from other modules */
1465 the_authctxt = authctxt;
1466
1463 if (use_privsep) 1467 if (use_privsep)
1464 if ((authctxt = privsep_preauth()) != NULL) 1468 if (privsep_preauth(authctxt) == 1)
1465 goto authenticated; 1469 goto authenticated;
1466 1470
1467 /* perform the key exchange */ 1471 /* perform the key exchange */
1468 /* authenticate user and start session */ 1472 /* authenticate user and start session */
1469 if (compat20) { 1473 if (compat20) {
1470 do_ssh2_kex(); 1474 do_ssh2_kex();
1471 authctxt = do_authentication2(); 1475 do_authentication2(authctxt);
1472 } else { 1476 } else {
1473 do_ssh1_kex(); 1477 do_ssh1_kex();
1474 authctxt = do_authentication(); 1478 do_authentication(authctxt);
1475 } 1479 }
1476 /* 1480 /*
1477 * If we use privilege separation, the unprivileged child transfers 1481 * If we use privilege separation, the unprivileged child transfers
@@ -1494,7 +1498,7 @@ main(int ac, char **av)
1494 destroy_sensitive_data(); 1498 destroy_sensitive_data();
1495 } 1499 }
1496 1500
1497 /* Perform session preparation. */ 1501 /* Start session. */
1498 do_authenticated(authctxt); 1502 do_authenticated(authctxt);
1499 1503
1500 /* The connection has been terminated. */ 1504 /* The connection has been terminated. */
@@ -1787,3 +1791,12 @@ do_ssh2_kex(void)
1787#endif 1791#endif
1788 debug("KEX done"); 1792 debug("KEX done");
1789} 1793}
1794
1795/* server specific fatal cleanup */
1796void
1797cleanup_exit(int i)
1798{
1799 if (the_authctxt)
1800 do_cleanup(the_authctxt);
1801 _exit(i);
1802}