summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-11-05 14:52:50 +1100
committerDamien Miller <djm@mindrot.org>2005-11-05 14:52:50 +1100
commit39eda6eb6a8364e8df6779e71e0b434eaae3edd5 (patch)
tree2e7a8fda98f3a3d9b4e14f2b36787fc2168b691a
parent3f54a9f5b7978e8e7085f86722bc2704f7fab2e2 (diff)
- 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@
-rw-r--r--ChangeLog7
-rw-r--r--channels.c9
-rw-r--r--channels.h7
-rw-r--r--clientloop.c4
-rw-r--r--serverloop.c4
-rw-r--r--session.c37
6 files changed, 43 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 10c031042..221301eb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,11 @@
7 in order to improve the security of DSA you need to change more 7 in order to improve the security of DSA you need to change more
8 components of DSA key generation (e.g. the internal SHA1 hash); 8 components of DSA key generation (e.g. the internal SHA1 hash);
9 ok deraadt 9 ok deraadt
10 - djm@cvs.openbsd.org 2005/10/10 10:23:08
11 [channels.c channels.h clientloop.c serverloop.c session.c]
12 fix regression I introduced in 4.2: X11 forwardings initiated after
13 a session has exited (e.g. "(sleep 5; xterm) &") would not start.
14 bz #1086 reported by t8m AT centrum.cz; ok markus@ dtucker@
10 15
1120051102 1620051102
12 - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup(). 17 - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup().
@@ -3140,4 +3145,4 @@
3140 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 3145 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
3141 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 3146 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
3142 3147
3143$Id: ChangeLog,v 1.3927 2005/11/05 03:52:18 djm Exp $ 3148$Id: ChangeLog,v 1.3928 2005/11/05 03:52:50 djm Exp $
diff --git a/channels.c b/channels.c
index af858b4a5..b0bc77901 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.224 2005/09/07 08:53:53 markus Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.225 2005/10/10 10:23:08 djm Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -269,6 +269,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
269 c->force_drain = 0; 269 c->force_drain = 0;
270 c->single_connection = 0; 270 c->single_connection = 0;
271 c->detach_user = NULL; 271 c->detach_user = NULL;
272 c->detach_close = 0;
272 c->confirm = NULL; 273 c->confirm = NULL;
273 c->confirm_ctx = NULL; 274 c->confirm_ctx = NULL;
274 c->input_filter = NULL; 275 c->input_filter = NULL;
@@ -628,7 +629,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
628 c->confirm_ctx = ctx; 629 c->confirm_ctx = ctx;
629} 630}
630void 631void
631channel_register_cleanup(int id, channel_callback_fn *fn) 632channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
632{ 633{
633 Channel *c = channel_lookup(id); 634 Channel *c = channel_lookup(id);
634 635
@@ -637,6 +638,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn)
637 return; 638 return;
638 } 639 }
639 c->detach_user = fn; 640 c->detach_user = fn;
641 c->detach_close = do_close;
640} 642}
641void 643void
642channel_cancel_cleanup(int id) 644channel_cancel_cleanup(int id)
@@ -648,6 +650,7 @@ channel_cancel_cleanup(int id)
648 return; 650 return;
649 } 651 }
650 c->detach_user = NULL; 652 c->detach_user = NULL;
653 c->detach_close = 0;
651} 654}
652void 655void
653channel_register_filter(int id, channel_filter_fn *fn) 656channel_register_filter(int id, channel_filter_fn *fn)
@@ -1666,7 +1669,7 @@ channel_garbage_collect(Channel *c)
1666 if (c == NULL) 1669 if (c == NULL)
1667 return; 1670 return;
1668 if (c->detach_user != NULL) { 1671 if (c->detach_user != NULL) {
1669 if (!chan_is_dead(c, 0)) 1672 if (!chan_is_dead(c, c->detach_close))
1670 return; 1673 return;
1671 debug2("channel %d: gc: notify user", c->self); 1674 debug2("channel %d: gc: notify user", c->self);
1672 c->detach_user(c->self, NULL); 1675 c->detach_user(c->self, NULL);
diff --git a/channels.h b/channels.h
index 1cb2c3a34..7e1cc7c5a 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.79 2005/07/17 06:49:04 djm Exp $ */ 1/* $OpenBSD: channels.h,v 1.80 2005/10/10 10:23:08 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -106,8 +106,9 @@ struct Channel {
106 106
107 /* callback */ 107 /* callback */
108 channel_callback_fn *confirm; 108 channel_callback_fn *confirm;
109 channel_callback_fn *detach_user;
110 void *confirm_ctx; 109 void *confirm_ctx;
110 channel_callback_fn *detach_user;
111 int detach_close;
111 112
112 /* filter */ 113 /* filter */
113 channel_filter_fn *input_filter; 114 channel_filter_fn *input_filter;
@@ -163,7 +164,7 @@ void channel_stop_listening(void);
163 164
164void channel_send_open(int); 165void channel_send_open(int);
165void channel_request_start(int, char *, int); 166void channel_request_start(int, char *, int);
166void channel_register_cleanup(int, channel_callback_fn *); 167void channel_register_cleanup(int, channel_callback_fn *, int);
167void channel_register_confirm(int, channel_callback_fn *, void *); 168void channel_register_confirm(int, channel_callback_fn *, void *);
168void channel_register_filter(int, channel_filter_fn *); 169void channel_register_filter(int, channel_filter_fn *);
169void channel_cancel_cleanup(int); 170void channel_cancel_cleanup(int);
diff --git a/clientloop.c b/clientloop.c
index da5bfd7bd..fed684956 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.142 2005/09/09 19:18:05 markus Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.143 2005/10/10 10:23:08 djm Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -1379,7 +1379,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1379 simple_escape_filter); 1379 simple_escape_filter);
1380 if (session_ident != -1) 1380 if (session_ident != -1)
1381 channel_register_cleanup(session_ident, 1381 channel_register_cleanup(session_ident,
1382 client_channel_closed); 1382 client_channel_closed, 0);
1383 } else { 1383 } else {
1384 /* Check if we should immediately send eof on stdin. */ 1384 /* Check if we should immediately send eof on stdin. */
1385 client_check_initial_eof_on_stdin(); 1385 client_check_initial_eof_on_stdin();
diff --git a/serverloop.c b/serverloop.c
index d2eff170a..17608c238 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.118 2005/07/17 07:17:55 djm Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.119 2005/10/10 10:23:08 djm Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -900,7 +900,7 @@ server_request_session(void)
900 channel_free(c); 900 channel_free(c);
901 return NULL; 901 return NULL;
902 } 902 }
903 channel_register_cleanup(c->self, session_close_by_channel); 903 channel_register_cleanup(c->self, session_close_by_channel, 0);
904 return c; 904 return c;
905} 905}
906 906
diff --git a/session.c b/session.c
index 2a1a25ac4..5e6627cb0 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.186 2005/07/25 11:59:40 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.187 2005/10/10 10:23:08 djm Exp $");
37 37
38#include "ssh.h" 38#include "ssh.h"
39#include "ssh1.h" 39#include "ssh1.h"
@@ -2156,7 +2156,6 @@ static void
2156session_exit_message(Session *s, int status) 2156session_exit_message(Session *s, int status)
2157{ 2157{
2158 Channel *c; 2158 Channel *c;
2159 u_int i;
2160 2159
2161 if ((c = channel_lookup(s->chanid)) == NULL) 2160 if ((c = channel_lookup(s->chanid)) == NULL)
2162 fatal("session_exit_message: session %d: no channel %d", 2161 fatal("session_exit_message: session %d: no channel %d",
@@ -2186,7 +2185,15 @@ session_exit_message(Session *s, int status)
2186 2185
2187 /* disconnect channel */ 2186 /* disconnect channel */
2188 debug("session_exit_message: release channel %d", s->chanid); 2187 debug("session_exit_message: release channel %d", s->chanid);
2189 channel_cancel_cleanup(s->chanid); 2188 s->pid = 0;
2189
2190 /*
2191 * Adjust cleanup callback attachment to send close messages when
2192 * the channel gets EOF. The session will be then be closed
2193 * by session_close_by_channel when the childs close their fds.
2194 */
2195 channel_register_cleanup(c->self, session_close_by_channel, 1);
2196
2190 /* 2197 /*
2191 * emulate a write failure with 'chan_write_failed', nobody will be 2198 * emulate a write failure with 'chan_write_failed', nobody will be
2192 * interested in data we write. 2199 * interested in data we write.
@@ -2195,15 +2202,6 @@ session_exit_message(Session *s, int status)
2195 */ 2202 */
2196 if (c->ostate != CHAN_OUTPUT_CLOSED) 2203 if (c->ostate != CHAN_OUTPUT_CLOSED)
2197 chan_write_failed(c); 2204 chan_write_failed(c);
2198 s->chanid = -1;
2199
2200 /* Close any X11 listeners associated with this session */
2201 if (s->x11_chanids != NULL) {
2202 for (i = 0; s->x11_chanids[i] != -1; i++) {
2203 session_close_x11(s->x11_chanids[i]);
2204 s->x11_chanids[i] = -1;
2205 }
2206 }
2207} 2205}
2208 2206
2209void 2207void
@@ -2247,7 +2245,8 @@ session_close_by_pid(pid_t pid, int status)
2247 } 2245 }
2248 if (s->chanid != -1) 2246 if (s->chanid != -1)
2249 session_exit_message(s, status); 2247 session_exit_message(s, status);
2250 session_close(s); 2248 if (s->ttyfd != -1)
2249 session_pty_cleanup(s);
2251} 2250}
2252 2251
2253/* 2252/*
@@ -2258,6 +2257,7 @@ void
2258session_close_by_channel(int id, void *arg) 2257session_close_by_channel(int id, void *arg)
2259{ 2258{
2260 Session *s = session_by_channel(id); 2259 Session *s = session_by_channel(id);
2260 u_int i;
2261 2261
2262 if (s == NULL) { 2262 if (s == NULL) {
2263 debug("session_close_by_channel: no session for id %d", id); 2263 debug("session_close_by_channel: no session for id %d", id);
@@ -2277,6 +2277,15 @@ session_close_by_channel(int id, void *arg)
2277 } 2277 }
2278 /* detach by removing callback */ 2278 /* detach by removing callback */
2279 channel_cancel_cleanup(s->chanid); 2279 channel_cancel_cleanup(s->chanid);
2280
2281 /* Close any X11 listeners associated with this session */
2282 if (s->x11_chanids != NULL) {
2283 for (i = 0; s->x11_chanids[i] != -1; i++) {
2284 session_close_x11(s->x11_chanids[i]);
2285 s->x11_chanids[i] = -1;
2286 }
2287 }
2288
2280 s->chanid = -1; 2289 s->chanid = -1;
2281 session_close(s); 2290 session_close(s);
2282} 2291}
@@ -2371,7 +2380,7 @@ session_setup_x11fwd(Session *s)
2371 } 2380 }
2372 for (i = 0; s->x11_chanids[i] != -1; i++) { 2381 for (i = 0; s->x11_chanids[i] != -1; i++) {
2373 channel_register_cleanup(s->x11_chanids[i], 2382 channel_register_cleanup(s->x11_chanids[i],
2374 session_close_single_x11); 2383 session_close_single_x11, 0);
2375 } 2384 }
2376 2385
2377 /* Set up a suitable value for the DISPLAY variable. */ 2386 /* Set up a suitable value for the DISPLAY variable. */