From 2362db19c34ff0d1b04e3b2656523d93089a4a15 Mon Sep 17 00:00:00 2001 From: dtucker Date: Thu, 2 Oct 2003 06:12:36 +0000 Subject: [PATCH] - 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@ --- ChangeLog | 12 +++++++ Makefile.in | 4 +-- auth-krb5.c | 11 ++---- auth.c | 10 +----- auth.h | 11 +++--- auth1.c | 10 ++---- auth2.c | 22 ++---------- canohost.c | 8 ++--- cleanup.c | 26 ++++++++++++++ clientloop.c | 11 ++---- fatal.c | 4 +-- gss-serv.c | 8 ++--- log.c | 79 +----------------------------------------- log.h | 9 ++--- monitor.c | 17 ++++----- monitor.h | 4 +-- monitor_wrap.c | 17 ++++++--- monitor_wrap.h | 6 ++-- packet.c | 10 +++--- serverloop.c | 14 ++++---- session.c | 94 +++++++++++++++++++++++++++++--------------------- session.h | 5 +-- ssh-agent.c | 15 ++------ sshd.c | 59 +++++++++++++++++++------------ 24 files changed, 201 insertions(+), 265 deletions(-) create mode 100644 cleanup.c diff --git a/ChangeLog b/ChangeLog index dd434ebd..826e2a00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +20031002 + - OpenBSD CVS Sync + - 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@ + 20030930 - (bal) Fix issues in openbsd-compat/realpath.c diff --git a/Makefile.in b/Makefile.in index d04d5d04..fd7b2821 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,8 +62,8 @@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@ TARGETS=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) LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \ - cipher.o cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \ - compat.o compress.o crc32.o deattack.o fatal.o \ + cipher.o cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \ + cleanup.o compat.o compress.o crc32.o deattack.o fatal.o \ hostfile.o log.o match.o moduli.o mpaux.o nchan.o packet.o \ readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \ key.o dispatch.o kex.o mac.o uuencode.o misc.o \ diff --git a/auth-krb5.c b/auth-krb5.c index 0aa5195b..e31f2eb0 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -28,7 +28,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $"); +RCSID("$OpenBSD: auth-krb5.c,v 1.13 2003/09/23 20:17:11 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -50,7 +50,6 @@ krb5_init(void *context) { Authctxt *authctxt = (Authctxt *)context; krb5_error_code problem; - static int cleanup_registered = 0; if (authctxt->krb5_ctx == NULL) { problem = krb5_init_context(&authctxt->krb5_ctx); @@ -58,10 +57,6 @@ krb5_init(void *context) return (problem); krb5_init_ets(authctxt->krb5_ctx); } - if (!cleanup_registered) { - fatal_add_cleanup(krb5_cleanup_proc, authctxt); - cleanup_registered = 1; - } return (0); } @@ -205,10 +200,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) } void -krb5_cleanup_proc(void *context) +krb5_cleanup_proc(Authctxt *authctxt) { - Authctxt *authctxt = (Authctxt *)context; - debug("krb5_cleanup_proc called"); if (authctxt->krb5_fwd_ccache) { krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); diff --git a/auth.c b/auth.c index 46e495ad..02967287 100644 --- a/auth.c +++ b/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $"); +RCSID("$OpenBSD: auth.c,v 1.50 2003/09/23 20:17:11 markus Exp $"); #ifdef HAVE_LOGIN_H #include @@ -263,14 +263,6 @@ allowed_user(struct passwd * pw) return 1; } -Authctxt * -authctxt_new(void) -{ - Authctxt *authctxt = xmalloc(sizeof(*authctxt)); - memset(authctxt, 0, sizeof(*authctxt)); - return authctxt; -} - void auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) { diff --git a/auth.h b/auth.h index beaacb8b..b081bb5c 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.47 2003/09/23 20:17:11 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -118,15 +118,14 @@ int user_key_allowed(struct passwd *, Key *); int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); int auth_krb5_password(Authctxt *authctxt, const char *password); -void krb5_cleanup_proc(void *authctxt); +void krb5_cleanup_proc(Authctxt *authctxt); #endif /* KRB5 */ #include "auth-pam.h" -Authctxt *do_authentication(void); -Authctxt *do_authentication2(void); +void do_authentication(Authctxt *); +void do_authentication2(Authctxt *); -Authctxt *authctxt_new(void); void auth_log(Authctxt *, int, char *, char *); void userauth_finish(Authctxt *, int, char *); int auth_root_allowed(char *); @@ -149,8 +148,6 @@ char *get_challenge(Authctxt *); int verify_response(Authctxt *, const char *); void abandon_challenge_response(Authctxt *); -struct passwd * auth_get_user(void); - char *expand_filename(const char *, struct passwd *); char *authorized_keys_file(struct passwd *); char *authorized_keys_file2(struct passwd *); diff --git a/auth1.c b/auth1.c index dfe944dd..38c0bf93 100644 --- a/auth1.c +++ b/auth1.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.53 2003/09/23 20:17:11 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -275,10 +275,9 @@ do_authloop(Authctxt *authctxt) * Performs authentication of an incoming connection. Session key has already * been exchanged and encryption is enabled. */ -Authctxt * -do_authentication(void) +void +do_authentication(Authctxt *authctxt) { - Authctxt *authctxt; u_int ulen; char *user, *style = NULL; @@ -292,7 +291,6 @@ do_authentication(void) if ((style = strchr(user, ':')) != NULL) *style++ = '\0'; - authctxt = authctxt_new(); authctxt->user = user; authctxt->style = style; @@ -332,6 +330,4 @@ do_authentication(void) packet_start(SSH_SMSG_SUCCESS); packet_send(); packet_write_wait(); - - return (authctxt); } diff --git a/auth2.c b/auth2.c index 41e77efd..ef1173fe 100644 --- a/auth2.c +++ b/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.103 2003/09/23 20:17:11 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -45,8 +45,6 @@ extern ServerOptions options; extern u_char *session_id2; extern u_int session_id2_len; -Authctxt *x_authctxt = NULL; - /* methods */ extern Authmethod method_none; @@ -85,13 +83,9 @@ int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); * loop until authctxt->success == TRUE */ -Authctxt * -do_authentication2(void) +void +do_authentication2(Authctxt *authctxt) { - Authctxt *authctxt = authctxt_new(); - - x_authctxt = authctxt; /*XXX*/ - /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; @@ -99,8 +93,6 @@ do_authentication2(void) dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); - - return (authctxt); } static void @@ -264,14 +256,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) } } -/* get current user */ - -struct passwd* -auth_get_user(void) -{ - return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL; -} - #define DELIM "," static char * diff --git a/canohost.c b/canohost.c index 438175f7..fca7134f 100644 --- a/canohost.c +++ b/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $"); #include "packet.h" #include "xmalloc.h" @@ -40,7 +40,7 @@ get_remote_hostname(int socket, int use_dns) memset(&from, 0, sizeof(from)); if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); - fatal_cleanup(); + cleanup_exit(255); } #ifdef IPV4_IN_IPV6 if (from.ss_family == AF_INET6) { @@ -296,7 +296,7 @@ get_remote_ipaddr(void) canonical_host_ip = get_peer_ipaddr(packet_get_connection_in()); if (canonical_host_ip == NULL) - fatal_cleanup(); + cleanup_exit(255); } else { /* If not on socket, return UNKNOWN. */ canonical_host_ip = xstrdup("UNKNOWN"); @@ -336,7 +336,7 @@ get_sock_port(int sock, int local) } else { if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); - fatal_cleanup(); + cleanup_exit(255); } } diff --git a/cleanup.c b/cleanup.c new file mode 100644 index 00000000..11d1d4d9 --- /dev/null +++ b/cleanup.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2003 Markus Friedl + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "includes.h" +RCSID("$OpenBSD: cleanup.c,v 1.1 2003/09/23 20:17:11 markus Exp $"); + +#include "log.h" + +/* default implementation */ +void +cleanup_exit(int i) +{ + _exit(i); +} diff --git a/clientloop.c b/clientloop.c index bc50f0bc..d3a32a81 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.113 2003/09/19 17:43:35 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.114 2003/09/23 20:17:11 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1384,14 +1384,9 @@ client_init_dispatch(void) /* client specific fatal cleanup */ void -fatal(const char *fmt,...) +cleanup_exit(int i) { - va_list args; - - va_start(args, fmt); - do_log(SYSLOG_LEVEL_FATAL, fmt, args); - va_end(args); leave_raw_mode(); leave_non_blocking(); - _exit(255); + _exit(i); } diff --git a/fatal.c b/fatal.c index 9e7d1600..ae1aaac6 100644 --- a/fatal.c +++ b/fatal.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: fatal.c,v 1.1 2002/02/22 12:20:34 markus Exp $"); +RCSID("$OpenBSD: fatal.c,v 1.2 2003/09/23 20:17:11 markus Exp $"); #include "log.h" @@ -36,5 +36,5 @@ fatal(const char *fmt,...) va_start(args, fmt); do_log(SYSLOG_LEVEL_FATAL, fmt, args); va_end(args); - fatal_cleanup(); + cleanup_exit(255); } diff --git a/gss-serv.c b/gss-serv.c index 8fd1d63f..6574f975 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv.c,v 1.3 2003/08/31 13:31:57 markus Exp $ */ +/* $OpenBSD: gss-serv.c,v 1.4 2003/09/23 20:17:11 markus Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -232,9 +232,9 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) return (ctx->major); } -/* As user - called through fatal cleanup hook */ +/* As user - called on fatal/exit */ void -ssh_gssapi_cleanup_creds(void *ignored) +ssh_gssapi_cleanup_creds(void) { if (gssapi_client.store.filename != NULL) { /* Unlink probably isn't sufficient */ @@ -249,8 +249,6 @@ ssh_gssapi_storecreds(void) { if (gssapi_client.mech && gssapi_client.mech->storecreds) { (*gssapi_client.mech->storecreds)(&gssapi_client); - if (options.gss_cleanup_creds) - fatal_add_cleanup(ssh_gssapi_cleanup_creds, NULL); } else debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); } diff --git a/log.c b/log.c index 9bce2555..686a2a43 100644 --- a/log.c +++ b/log.c @@ -34,7 +34,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.28 2003/05/24 09:02:22 djm Exp $"); +RCSID("$OpenBSD: log.c,v 1.29 2003/09/23 20:17:11 markus Exp $"); #include "log.h" #include "xmalloc.h" @@ -183,83 +183,6 @@ debug3(const char *fmt,...) va_end(args); } -/* Fatal cleanup */ - -struct fatal_cleanup { - struct fatal_cleanup *next; - void (*proc) (void *); - void *context; -}; - -static struct fatal_cleanup *fatal_cleanups = NULL; - -/* Registers a cleanup function to be called by fatal() before exiting. */ - -void -fatal_add_cleanup(void (*proc) (void *), void *context) -{ - struct fatal_cleanup *cu; - - cu = xmalloc(sizeof(*cu)); - cu->proc = proc; - cu->context = context; - cu->next = fatal_cleanups; - fatal_cleanups = cu; -} - -/* Removes a cleanup frunction to be called at fatal(). */ - -void -fatal_remove_cleanup(void (*proc) (void *context), void *context) -{ - struct fatal_cleanup **cup, *cu; - - for (cup = &fatal_cleanups; *cup; cup = &cu->next) { - cu = *cup; - if (cu->proc == proc && cu->context == context) { - *cup = cu->next; - xfree(cu); - return; - } - } - fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx", - (u_long) proc, (u_long) context); -} - -/* Remove all cleanups, to be called after fork() */ -void -fatal_remove_all_cleanups(void) -{ - struct fatal_cleanup *cu, *next_cu; - - for (cu = fatal_cleanups; cu; cu = next_cu) { - next_cu = cu->next; - xfree(cu); - } - fatal_cleanups = NULL; -} - -/* Cleanup and exit */ -void -fatal_cleanup(void) -{ - struct fatal_cleanup *cu, *next_cu; - static int called = 0; - - if (called) - exit(255); - called = 1; - /* Call cleanup functions. */ - for (cu = fatal_cleanups; cu; cu = next_cu) { - next_cu = cu->next; - debug("Calling cleanup 0x%lx(0x%lx)", - (u_long) cu->proc, (u_long) cu->context); - (*cu->proc) (cu->context); - } - exit(255); -} - - /* * Initialize the log. */ diff --git a/log.h b/log.h index c3666818..e0263194 100644 --- a/log.h +++ b/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.9 2003/04/08 20:21:28 itojun Exp $ */ +/* $OpenBSD: log.h,v 1.10 2003/09/23 20:17:11 markus Exp $ */ /* * Author: Tatu Ylonen @@ -61,11 +61,6 @@ void debug(const char *, ...) __attribute__((format(printf, 1, 2))); void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); -void fatal_cleanup(void); -void fatal_add_cleanup(void (*) (void *), void *); -void fatal_remove_cleanup(void (*) (void *), void *); -void fatal_remove_all_cleanups(void); - void do_log(LogLevel, const char *, va_list); - +void cleanup_exit(int); #endif diff --git a/monitor.c b/monitor.c index e5656470..eaf66f7c 100644 --- a/monitor.c +++ b/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.50 2003/09/23 20:17:11 markus Exp $"); #include @@ -272,14 +272,17 @@ monitor_permit_authentications(int permit) } } -Authctxt * -monitor_child_preauth(struct monitor *pmonitor) +void +monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) { struct mon_table *ent; int authenticated = 0; debug3("preauth child monitor started"); + authctxt = _authctxt; + memset(authctxt, 0, sizeof(*authctxt)); + if (compat20) { mon_dispatch = mon_dispatch_proto20; @@ -292,8 +295,6 @@ monitor_child_preauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); } - authctxt = authctxt_new(); - /* The first few requests do not require asynchronous access */ while (!authenticated) { authenticated = monitor_read(pmonitor, mon_dispatch, &ent); @@ -333,8 +334,6 @@ monitor_child_preauth(struct monitor *pmonitor) __func__, authctxt->user); mm_get_keystate(pmonitor); - - return (authctxt); } static void @@ -1185,7 +1184,7 @@ mm_record_login(Session *s, struct passwd *pw) if (getpeername(packet_get_connection_in(), (struct sockaddr *) & from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); - fatal_cleanup(); + cleanup_exit(255); } } /* Record that there was a login on that tty from the remote host. */ @@ -1200,7 +1199,6 @@ mm_session_close(Session *s) debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); if (s->ttyfd != -1) { debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); - fatal_remove_cleanup(session_pty_cleanup2, (void *)s); session_pty_cleanup2(s); } s->used = 0; @@ -1225,7 +1223,6 @@ mm_answer_pty(int socket, Buffer *m) res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); if (res == 0) goto error; - fatal_add_cleanup(session_pty_cleanup2, (void *)s); pty_setowner(authctxt->pw, s->tty); buffer_put_int(m, 1); diff --git a/monitor.h b/monitor.h index 2461156c..a153f416 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ +/* $OpenBSD: monitor.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -76,7 +76,7 @@ void monitor_reinit(struct monitor *); void monitor_sync(struct monitor *); struct Authctxt; -struct Authctxt *monitor_child_preauth(struct monitor *); +void monitor_child_preauth(struct Authctxt *, struct monitor *); void monitor_child_postauth(struct monitor *); struct mon_table; diff --git a/monitor_wrap.c b/monitor_wrap.c index 4034d569..99dfc850 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.32 2003/09/23 20:17:11 markus Exp $"); #include #include @@ -66,6 +66,16 @@ extern struct monitor *pmonitor; extern Buffer input, output; extern ServerOptions options; +int +mm_is_monitor(void) +{ + /* + * m_pid is only set in the privileged part, and + * points to the unprivileged child. + */ + return (pmonitor->m_pid > 0); +} + void mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) { @@ -94,7 +104,7 @@ mm_request_receive(int socket, Buffer *m) res = atomicio(read, socket, buf, sizeof(buf)); if (res != sizeof(buf)) { if (res == 0) - fatal_cleanup(); + cleanup_exit(255); fatal("%s: read: %ld", __func__, (long)res); } msg_len = GET_32BIT(buf); @@ -648,9 +658,8 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) } void -mm_session_pty_cleanup2(void *session) +mm_session_pty_cleanup2(Session *s) { - Session *s = session; Buffer m; if (s->ttyfd == -1) diff --git a/monitor_wrap.h b/monitor_wrap.h index 5e033458..76c02f13 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.12 2003/09/23 20:17:11 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -40,6 +40,7 @@ struct mm_master; struct passwd; struct Authctxt; +int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); void mm_inform_authserv(char *, char *); @@ -72,9 +73,10 @@ int mm_sshpam_respond(void *, u_int, char **); void mm_sshpam_free_ctx(void *); #endif +struct Session; void mm_terminate(void); int mm_pty_allocate(int *, int *, char *, int); -void mm_session_pty_cleanup2(void *); +void mm_session_pty_cleanup2(struct Session *); /* SSHv1 interfaces */ void mm_ssh1_session_id(u_char *); diff --git a/packet.c b/packet.c index 6e7e574a..52b4f664 100644 --- a/packet.c +++ b/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.111 2003/09/19 11:33:09 markus Exp $"); +RCSID("$OpenBSD: packet.c,v 1.112 2003/09/23 20:17:11 markus Exp $"); #include "openbsd-compat/sys-queue.h" @@ -868,7 +868,7 @@ packet_read_seqnr(u_int32_t *seqnr_p) len = read(connection_in, buf, sizeof(buf)); if (len == 0) { logit("Connection closed by %.200s", get_remote_ipaddr()); - fatal_cleanup(); + cleanup_exit(255); } if (len < 0) fatal("Read from socket failed: %.100s", strerror(errno)); @@ -1134,7 +1134,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) logit("Received disconnect from %s: %u: %.400s", get_remote_ipaddr(), reason, msg); xfree(msg); - fatal_cleanup(); + cleanup_exit(255); break; case SSH2_MSG_UNIMPLEMENTED: seqnr = packet_get_int(); @@ -1159,7 +1159,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) msg = packet_get_string(NULL); logit("Received disconnect from %s: %.400s", get_remote_ipaddr(), msg); - fatal_cleanup(); + cleanup_exit(255); xfree(msg); break; default: @@ -1336,7 +1336,7 @@ packet_disconnect(const char *fmt,...) /* Close the connection. */ packet_close(); - fatal_cleanup(); + cleanup_exit(255); } /* Checks if there is any buffered output, and tries to write some of the output. */ diff --git a/serverloop.c b/serverloop.c index a9539027..21656cf8 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.110 2003/06/24 08:23:46 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.111 2003/09/23 20:17:11 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -60,7 +60,7 @@ extern ServerOptions options; /* XXX */ extern Kex *xxx_kex; -static Authctxt *xxx_authctxt; +extern Authctxt *the_authctxt; static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ @@ -355,13 +355,13 @@ process_input(fd_set * readset) connection_closed = 1; if (compat20) return; - fatal_cleanup(); + cleanup_exit(255); } else if (len < 0) { if (errno != EINTR && errno != EAGAIN) { verbose("Read error from remote host " "%.100s: %.100s", get_remote_ipaddr(), strerror(errno)); - fatal_cleanup(); + cleanup_exit(255); } } else { /* Buffer any received data. */ @@ -756,8 +756,6 @@ server_loop2(Authctxt *authctxt) max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, notify_pipe[0]); - xxx_authctxt = authctxt; - server_init_dispatch(); for (;;) { @@ -900,7 +898,7 @@ server_request_session(char *ctype) c = channel_new(ctype, SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); - if (session_open(xxx_authctxt, c->self) != 1) { + if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); return NULL; @@ -974,7 +972,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) char *listen_address; u_short listen_port; - pw = auth_get_user(); + pw = the_authctxt->pw; if (pw == NULL) fatal("server_input_global_request: no user"); listen_address = packet_get_string(NULL); diff --git a/session.c b/session.c index 2898ac51..647be401 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.165 2003/09/23 20:17:11 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -66,7 +66,7 @@ RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $"); Session *session_new(void); void session_set_fds(Session *, int, int, int); -void session_pty_cleanup(void *); +void session_pty_cleanup(Session *); void session_proctitle(Session *); int session_setup_x11fwd(Session *); void do_exec_pty(Session *, const char *); @@ -106,6 +106,8 @@ Session sessions[MAX_SESSIONS]; login_cap_t *lc; #endif +static int is_child = 0; + /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; static char *auth_sock_dir = NULL; @@ -113,10 +115,8 @@ static char *auth_sock_dir = NULL; /* removes the agent forwarding socket */ static void -auth_sock_cleanup_proc(void *_pw) +auth_sock_cleanup_proc(struct passwd *pw) { - struct passwd *pw = _pw; - if (auth_sock_name != NULL) { temporarily_use_uid(pw); unlink(auth_sock_name); @@ -160,9 +160,6 @@ auth_input_request_forwarding(struct passwd * pw) snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld", auth_sock_dir, (long) getpid()); - /* delete agent socket on fatal() */ - fatal_add_cleanup(auth_sock_cleanup_proc, pw); - /* Create the socket. */ sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) @@ -217,13 +214,7 @@ do_authenticated(Authctxt *authctxt) else do_authenticated1(authctxt); - /* remove agent socket */ - if (auth_sock_name != NULL) - auth_sock_cleanup_proc(authctxt->pw); -#ifdef KRB5 - if (options.kerberos_ticket_cleanup) - krb5_cleanup_proc(authctxt); -#endif + do_cleanup(authctxt); } /* @@ -405,7 +396,7 @@ do_exec_no_pty(Session *s, const char *command) /* Fork the child. */ if ((pid = fork()) == 0) { - fatal_remove_all_cleanups(); + is_child = 1; /* Child. Reinitialize the log since the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -531,7 +522,7 @@ do_exec_pty(Session *s, const char *command) /* Fork the child. */ if ((pid = fork()) == 0) { - fatal_remove_all_cleanups(); + is_child = 1; /* Child. Reinitialize the log because the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -627,7 +618,7 @@ do_pre_login(Session *s) if (getpeername(packet_get_connection_in(), (struct sockaddr *) & from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); - fatal_cleanup(); + cleanup_exit(255); } } @@ -687,7 +678,7 @@ do_login(Session *s, const char *command) if (getpeername(packet_get_connection_in(), (struct sockaddr *) & from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); - fatal_cleanup(); + cleanup_exit(255); } } @@ -1178,7 +1169,7 @@ do_rc_files(Session *s, const char *shell) if (debug_flag) { fprintf(stderr, "Running %.500s remove %.100s\n", - options.xauth_location, s->auth_display); + options.xauth_location, s->auth_display); fprintf(stderr, "%.500s add %.100s %.100s %.100s\n", options.xauth_location, s->auth_display, @@ -1663,11 +1654,6 @@ session_pty_req(Session *s) n_bytes = packet_remaining(); tty_parse_modes(s->ttyfd, &n_bytes); - /* - * Add a cleanup function to clear the utmp entry and record logout - * time in case we call fatal() (e.g., the connection gets closed). - */ - fatal_add_cleanup(session_pty_cleanup, (void *)s); if (!use_privsep) pty_setowner(s->pw, s->tty); @@ -1849,10 +1835,8 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr) * (e.g., due to a dropped connection). */ void -session_pty_cleanup2(void *session) +session_pty_cleanup2(Session *s) { - Session *s = session; - if (s == NULL) { error("session_pty_cleanup: no session"); return; @@ -1883,9 +1867,9 @@ session_pty_cleanup2(void *session) } void -session_pty_cleanup(void *session) +session_pty_cleanup(Session *s) { - PRIVSEP(session_pty_cleanup2(session)); + PRIVSEP(session_pty_cleanup2(s)); } static char * @@ -1958,10 +1942,8 @@ void session_close(Session *s) { debug("session_close: session %d pid %ld", s->self, (long)s->pid); - if (s->ttyfd != -1) { - fatal_remove_cleanup(session_pty_cleanup, (void *)s); + if (s->ttyfd != -1) session_pty_cleanup(s); - } if (s->term) xfree(s->term); if (s->display) @@ -2010,10 +1992,8 @@ session_close_by_channel(int id, void *arg) * delay detach of session, but release pty, since * the fd's to the child are already closed */ - if (s->ttyfd != -1) { - fatal_remove_cleanup(session_pty_cleanup, (void *)s); + if (s->ttyfd != -1) session_pty_cleanup(s); - } return; } /* detach by removing callback */ @@ -2154,8 +2134,44 @@ static void do_authenticated2(Authctxt *authctxt) { server_loop2(authctxt); -#if defined(GSSAPI) - if (options.gss_cleanup_creds) - ssh_gssapi_cleanup_creds(NULL); +} + +void +do_cleanup(Authctxt *authctxt) +{ + static int called = 0; + + debug("do_cleanup"); + + /* no cleanup if we're in the child for login shell */ + if (is_child) + return; + + /* avoid double cleanup */ + if (called) + return; + called = 1; + + if (authctxt == NULL) + return; +#ifdef KRB5 + if (options.kerberos_ticket_cleanup && + authctxt->krb5_ctx) + krb5_cleanup_proc(authctxt); #endif + +#ifdef GSSAPI + if (compat20 && options.gss_cleanup_creds) + ssh_gssapi_cleanup_creds(); +#endif + + /* remove agent socket */ + auth_sock_cleanup_proc(authctxt->pw); + + /* + * Cleanup ptys/utmp only if privsep is disabled, + * or if running in monitor. + */ + if (!use_privsep || mm_is_monitor()) + session_destroy_all(session_pty_cleanup2); } diff --git a/session.h b/session.h index 525e47f6..405b8fe8 100644 --- a/session.h +++ b/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $ */ +/* $OpenBSD: session.h,v 1.21 2003/09/23 20:17:11 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -56,13 +56,14 @@ struct Session { }; void do_authenticated(Authctxt *); +void do_cleanup(Authctxt *); int session_open(Authctxt *, int); int session_input_channel_req(Channel *, const char *); void session_close_by_pid(pid_t, int); void session_close_by_channel(int, void *); void session_destroy_all(void (*)(Session *)); -void session_pty_cleanup2(void *); +void session_pty_cleanup2(Session *); Session *session_new(void); Session *session_by_tty(char *); diff --git a/ssh-agent.c b/ssh-agent.c index 28a39a93..0fe87729 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.113 2003/09/19 11:29:40 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.114 2003/09/23 20:17:11 markus Exp $"); #include #include @@ -957,7 +957,7 @@ cleanup_socket(void) rmdir(socket_dir); } -static void +void cleanup_exit(int i) { cleanup_socket(); @@ -971,17 +971,6 @@ cleanup_handler(int sig) _exit(2); } -void -fatal(const char *fmt,...) -{ - va_list args; - va_start(args, fmt); - do_log(SYSLOG_LEVEL_FATAL, fmt, args); - va_end(args); - cleanup_socket(); - _exit(255); -} - static void check_parent_exists(int sig) { diff --git a/sshd.c b/sshd.c index 4b3ff0da..5c271129 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 #include @@ -204,6 +204,9 @@ struct monitor *pmonitor; /* 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 @@ sshd_exchange_identification(int sock_in, int sock_out) 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 @@ sshd_exchange_identification(int sock_in, int sock_out) 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 @@ sshd_exchange_identification(int sock_in, int sock_out) 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 @@ sshd_exchange_identification(int sock_in, int sock_out) 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 @@ sshd_exchange_identification(int sock_in, int sock_out) 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 @@ privsep_preauth_child(void) #endif } -static Authctxt * -privsep_preauth(void) +static int +privsep_preauth(Authctxt *authctxt) { - Authctxt *authctxt = NULL; int status; pid_t pid; @@ -590,7 +592,7 @@ privsep_preauth(void) 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 @@ privsep_preauth(void) while (waitpid(pid, &status, 0) < 0) if (errno != EINTR) break; - return (authctxt); + return (1); } else { /* child */ @@ -611,17 +613,12 @@ privsep_preauth(void) 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 @@ main(int ac, char **av) 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 @@ main(int ac, char **av) /* 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 @@ main(int ac, char **av) destroy_sensitive_data(); } - /* Perform session preparation. */ + /* Start session. */ do_authenticated(authctxt); /* The connection has been terminated. */ @@ -1787,3 +1791,12 @@ do_ssh2_kex(void) #endif debug("KEX done"); } + +/* server specific fatal cleanup */ +void +cleanup_exit(int i) +{ + if (the_authctxt) + do_cleanup(the_authctxt); + _exit(i); +} -- 2.45.1