- djm@cvs.openbsd.org 2005/10/10 10:23:08

[channels.c channels.h clientloop.c serverloop.c session.c]
     fix regression I introduced in 4.2: X11 forwardings initiated after
     a session has exited (e.g. "(sleep 5; xterm) &") would not start.
     bz #1086 reported by t8m AT centrum.cz; ok markus@ dtucker@
This commit is contained in:
Damien Miller 2005-11-05 14:52:50 +11:00
parent 3f54a9f5b7
commit 39eda6eb6a
6 changed files with 43 additions and 25 deletions

View File

@ -7,6 +7,11 @@
in order to improve the security of DSA you need to change more in order to improve the security of DSA you need to change more
components of DSA key generation (e.g. the internal SHA1 hash); components of DSA key generation (e.g. the internal SHA1 hash);
ok deraadt ok deraadt
- djm@cvs.openbsd.org 2005/10/10 10:23:08
[channels.c channels.h clientloop.c serverloop.c session.c]
fix regression I introduced in 4.2: X11 forwardings initiated after
a session has exited (e.g. "(sleep 5; xterm) &") would not start.
bz #1086 reported by t8m AT centrum.cz; ok markus@ dtucker@
20051102 20051102
- (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup(). - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup().
@ -3140,4 +3145,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
$Id: ChangeLog,v 1.3927 2005/11/05 03:52:18 djm Exp $ $Id: ChangeLog,v 1.3928 2005/11/05 03:52:50 djm Exp $

View File

@ -39,7 +39,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: channels.c,v 1.224 2005/09/07 08:53:53 markus Exp $"); RCSID("$OpenBSD: channels.c,v 1.225 2005/10/10 10:23:08 djm Exp $");
#include "ssh.h" #include "ssh.h"
#include "ssh1.h" #include "ssh1.h"
@ -269,6 +269,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
c->force_drain = 0; c->force_drain = 0;
c->single_connection = 0; c->single_connection = 0;
c->detach_user = NULL; c->detach_user = NULL;
c->detach_close = 0;
c->confirm = NULL; c->confirm = NULL;
c->confirm_ctx = NULL; c->confirm_ctx = NULL;
c->input_filter = NULL; c->input_filter = NULL;
@ -628,7 +629,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
c->confirm_ctx = ctx; c->confirm_ctx = ctx;
} }
void void
channel_register_cleanup(int id, channel_callback_fn *fn) channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
{ {
Channel *c = channel_lookup(id); Channel *c = channel_lookup(id);
@ -637,6 +638,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn)
return; return;
} }
c->detach_user = fn; c->detach_user = fn;
c->detach_close = do_close;
} }
void void
channel_cancel_cleanup(int id) channel_cancel_cleanup(int id)
@ -648,6 +650,7 @@ channel_cancel_cleanup(int id)
return; return;
} }
c->detach_user = NULL; c->detach_user = NULL;
c->detach_close = 0;
} }
void void
channel_register_filter(int id, channel_filter_fn *fn) channel_register_filter(int id, channel_filter_fn *fn)
@ -1666,7 +1669,7 @@ channel_garbage_collect(Channel *c)
if (c == NULL) if (c == NULL)
return; return;
if (c->detach_user != NULL) { if (c->detach_user != NULL) {
if (!chan_is_dead(c, 0)) if (!chan_is_dead(c, c->detach_close))
return; return;
debug2("channel %d: gc: notify user", c->self); debug2("channel %d: gc: notify user", c->self);
c->detach_user(c->self, NULL); c->detach_user(c->self, NULL);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.79 2005/07/17 06:49:04 djm Exp $ */ /* $OpenBSD: channels.h,v 1.80 2005/10/10 10:23:08 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -106,8 +106,9 @@ struct Channel {
/* callback */ /* callback */
channel_callback_fn *confirm; channel_callback_fn *confirm;
channel_callback_fn *detach_user;
void *confirm_ctx; void *confirm_ctx;
channel_callback_fn *detach_user;
int detach_close;
/* filter */ /* filter */
channel_filter_fn *input_filter; channel_filter_fn *input_filter;
@ -163,7 +164,7 @@ void channel_stop_listening(void);
void channel_send_open(int); void channel_send_open(int);
void channel_request_start(int, char *, int); void channel_request_start(int, char *, int);
void channel_register_cleanup(int, channel_callback_fn *); void channel_register_cleanup(int, channel_callback_fn *, int);
void channel_register_confirm(int, channel_callback_fn *, void *); void channel_register_confirm(int, channel_callback_fn *, void *);
void channel_register_filter(int, channel_filter_fn *); void channel_register_filter(int, channel_filter_fn *);
void channel_cancel_cleanup(int); void channel_cancel_cleanup(int);

View File

@ -59,7 +59,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: clientloop.c,v 1.142 2005/09/09 19:18:05 markus Exp $"); RCSID("$OpenBSD: clientloop.c,v 1.143 2005/10/10 10:23:08 djm Exp $");
#include "ssh.h" #include "ssh.h"
#include "ssh1.h" #include "ssh1.h"
@ -1379,7 +1379,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
simple_escape_filter); simple_escape_filter);
if (session_ident != -1) if (session_ident != -1)
channel_register_cleanup(session_ident, channel_register_cleanup(session_ident,
client_channel_closed); client_channel_closed, 0);
} else { } else {
/* Check if we should immediately send eof on stdin. */ /* Check if we should immediately send eof on stdin. */
client_check_initial_eof_on_stdin(); client_check_initial_eof_on_stdin();

View File

@ -35,7 +35,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: serverloop.c,v 1.118 2005/07/17 07:17:55 djm Exp $"); RCSID("$OpenBSD: serverloop.c,v 1.119 2005/10/10 10:23:08 djm Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "packet.h" #include "packet.h"
@ -900,7 +900,7 @@ server_request_session(void)
channel_free(c); channel_free(c);
return NULL; return NULL;
} }
channel_register_cleanup(c->self, session_close_by_channel); channel_register_cleanup(c->self, session_close_by_channel, 0);
return c; return c;
} }

View File

@ -33,7 +33,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: session.c,v 1.186 2005/07/25 11:59:40 markus Exp $"); RCSID("$OpenBSD: session.c,v 1.187 2005/10/10 10:23:08 djm Exp $");
#include "ssh.h" #include "ssh.h"
#include "ssh1.h" #include "ssh1.h"
@ -2156,7 +2156,6 @@ static void
session_exit_message(Session *s, int status) session_exit_message(Session *s, int status)
{ {
Channel *c; Channel *c;
u_int i;
if ((c = channel_lookup(s->chanid)) == NULL) if ((c = channel_lookup(s->chanid)) == NULL)
fatal("session_exit_message: session %d: no channel %d", fatal("session_exit_message: session %d: no channel %d",
@ -2186,7 +2185,15 @@ session_exit_message(Session *s, int status)
/* disconnect channel */ /* disconnect channel */
debug("session_exit_message: release channel %d", s->chanid); debug("session_exit_message: release channel %d", s->chanid);
channel_cancel_cleanup(s->chanid); s->pid = 0;
/*
* Adjust cleanup callback attachment to send close messages when
* the channel gets EOF. The session will be then be closed
* by session_close_by_channel when the childs close their fds.
*/
channel_register_cleanup(c->self, session_close_by_channel, 1);
/* /*
* emulate a write failure with 'chan_write_failed', nobody will be * emulate a write failure with 'chan_write_failed', nobody will be
* interested in data we write. * interested in data we write.
@ -2195,15 +2202,6 @@ session_exit_message(Session *s, int status)
*/ */
if (c->ostate != CHAN_OUTPUT_CLOSED) if (c->ostate != CHAN_OUTPUT_CLOSED)
chan_write_failed(c); chan_write_failed(c);
s->chanid = -1;
/* Close any X11 listeners associated with this session */
if (s->x11_chanids != NULL) {
for (i = 0; s->x11_chanids[i] != -1; i++) {
session_close_x11(s->x11_chanids[i]);
s->x11_chanids[i] = -1;
}
}
} }
void void
@ -2247,7 +2245,8 @@ session_close_by_pid(pid_t pid, int status)
} }
if (s->chanid != -1) if (s->chanid != -1)
session_exit_message(s, status); session_exit_message(s, status);
session_close(s); if (s->ttyfd != -1)
session_pty_cleanup(s);
} }
/* /*
@ -2258,6 +2257,7 @@ void
session_close_by_channel(int id, void *arg) session_close_by_channel(int id, void *arg)
{ {
Session *s = session_by_channel(id); Session *s = session_by_channel(id);
u_int i;
if (s == NULL) { if (s == NULL) {
debug("session_close_by_channel: no session for id %d", id); debug("session_close_by_channel: no session for id %d", id);
@ -2277,6 +2277,15 @@ session_close_by_channel(int id, void *arg)
} }
/* detach by removing callback */ /* detach by removing callback */
channel_cancel_cleanup(s->chanid); channel_cancel_cleanup(s->chanid);
/* Close any X11 listeners associated with this session */
if (s->x11_chanids != NULL) {
for (i = 0; s->x11_chanids[i] != -1; i++) {
session_close_x11(s->x11_chanids[i]);
s->x11_chanids[i] = -1;
}
}
s->chanid = -1; s->chanid = -1;
session_close(s); session_close(s);
} }
@ -2371,7 +2380,7 @@ session_setup_x11fwd(Session *s)
} }
for (i = 0; s->x11_chanids[i] != -1; i++) { for (i = 0; s->x11_chanids[i] != -1; i++) {
channel_register_cleanup(s->x11_chanids[i], channel_register_cleanup(s->x11_chanids[i],
session_close_single_x11); session_close_single_x11, 0);
} }
/* Set up a suitable value for the DISPLAY variable. */ /* Set up a suitable value for the DISPLAY variable. */