diff options
-rw-r--r-- | channels.c | 43 | ||||
-rw-r--r-- | channels.h | 5 | ||||
-rw-r--r-- | clientloop.c | 14 | ||||
-rw-r--r-- | mux.c | 6 | ||||
-rw-r--r-- | session.c | 14 | ||||
-rw-r--r-- | session.h | 4 | ||||
-rw-r--r-- | ssh.c | 4 |
7 files changed, 50 insertions, 40 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.422 2023/01/06 02:38:23 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.423 2023/01/06 02:39:59 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1222,6 +1222,29 @@ x11_open_helper(struct ssh *ssh, struct sshbuf *b) return 1; } +void +channel_force_close(struct ssh *ssh, Channel *c, int abandon) +{ + debug3_f("channel %d: forcibly closing", c->self); + if (c->istate == CHAN_INPUT_OPEN) + chan_read_failed(ssh, c); + if (c->istate == CHAN_INPUT_WAIT_DRAIN) { + sshbuf_reset(c->input); + chan_ibuf_empty(ssh, c); + } + if (c->ostate == CHAN_OUTPUT_OPEN || + c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { + sshbuf_reset(c->output); + chan_write_failed(ssh, c); + } + if (c->detach_user) + c->detach_user(ssh, c->self, 1, NULL); + if (c->efd != -1) + channel_close_fd(ssh, c, &c->efd); + if (abandon) + c->type = SSH_CHANNEL_ABANDONED; +} + static void channel_pre_x11_open(struct ssh *ssh, Channel *c) { @@ -1233,15 +1256,11 @@ channel_pre_x11_open(struct ssh *ssh, Channel *c) c->type = SSH_CHANNEL_OPEN; channel_pre_open(ssh, c); } else if (ret == -1) { - logit("X11 connection rejected because of wrong authentication."); + logit("X11 connection rejected because of wrong " + "authentication."); debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); - chan_read_failed(ssh, c); - sshbuf_reset(c->input); - chan_ibuf_empty(ssh, c); - sshbuf_reset(c->output); - chan_write_failed(ssh, c); - debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); + channel_force_close(ssh, c, 0); } } @@ -1591,11 +1610,7 @@ static void rdynamic_close(struct ssh *ssh, Channel *c) { c->type = SSH_CHANNEL_OPEN; - chan_read_failed(ssh, c); - sshbuf_reset(c->input); - chan_ibuf_empty(ssh, c); - sshbuf_reset(c->output); - chan_write_failed(ssh, c); + channel_force_close(ssh, c, 0); } /* reverse dynamic port forwarding */ @@ -2395,7 +2410,7 @@ channel_garbage_collect(struct ssh *ssh, Channel *c) return; debug2("channel %d: gc: notify user", c->self); - c->detach_user(ssh, c->self, NULL); + c->detach_user(ssh, c->self, 0, NULL); /* if we still have a callback */ if (c->detach_user != NULL) return; @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.144 2023/01/06 02:38:23 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.145 2023/01/06 02:39:59 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -88,7 +88,7 @@ typedef struct Channel Channel; struct fwd_perm_list; typedef void channel_open_fn(struct ssh *, int, int, void *); -typedef void channel_callback_fn(struct ssh *, int, void *); +typedef void channel_callback_fn(struct ssh *, int, int, void *); typedef int channel_infilter_fn(struct ssh *, struct Channel *, char *, int); typedef void channel_filter_cleanup_fn(struct ssh *, int, void *); typedef u_char *channel_outfilter_fn(struct ssh *, struct Channel *, @@ -281,6 +281,7 @@ void channel_set_fds(struct ssh *, int, int, int, int, int, void channel_free(struct ssh *, Channel *); void channel_free_all(struct ssh *); void channel_stop_listening(struct ssh *); +void channel_force_close(struct ssh *, Channel *, int); void channel_send_open(struct ssh *, int); void channel_request_start(struct ssh *, int, char *, int); diff --git a/clientloop.c b/clientloop.c index d087b05b..fef9efc6 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.386 2023/01/06 02:38:23 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.387 2023/01/06 02:39:59 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1033,15 +1033,7 @@ process_escapes(struct ssh *ssh, Channel *c, efc->escape_char)) != 0) fatal_fr(r, "sshbuf_putf"); if (c && c->ctl_chan != -1) { - chan_read_failed(ssh, c); - chan_write_failed(ssh, c); - if (c->detach_user) { - c->detach_user(ssh, - c->self, NULL); - } - c->type = SSH_CHANNEL_ABANDONED; - sshbuf_reset(c->input); - chan_ibuf_empty(ssh, c); + channel_force_close(ssh, c, 1); return 0; } else quit_pending = 1; @@ -1267,7 +1259,7 @@ client_simple_escape_filter(struct ssh *ssh, Channel *c, char *buf, int len) } static void -client_channel_closed(struct ssh *ssh, int id, void *arg) +client_channel_closed(struct ssh *ssh, int id, int force, void *arg) { channel_cancel_cleanup(ssh, id); session_closed = 1; @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.94 2022/06/03 04:30:47 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.95 2023/01/06 02:39:59 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> * @@ -188,7 +188,7 @@ static const struct { /* Cleanup callback fired on closure of mux client _session_ channel */ /* ARGSUSED */ static void -mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused) +mux_master_session_cleanup_cb(struct ssh *ssh, int cid, int force, void *unused) { Channel *cc, *c = channel_by_id(ssh, cid); @@ -210,7 +210,7 @@ mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused) /* Cleanup callback fired on closure of mux client _control_ channel */ /* ARGSUSED */ static void -mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused) +mux_master_control_cleanup_cb(struct ssh *ssh, int cid, int force, void *unused) { Channel *sc, *c = channel_by_id(ssh, cid); @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.330 2022/02/08 08:59:12 dtucker Exp $ */ +/* $OpenBSD: session.c,v 1.331 2023/01/06 02:39:59 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -2335,7 +2335,7 @@ session_close_x11(struct ssh *ssh, int id) } static void -session_close_single_x11(struct ssh *ssh, int id, void *arg) +session_close_single_x11(struct ssh *ssh, int id, int force, void *arg) { Session *s; u_int i; @@ -2469,7 +2469,7 @@ session_close_by_pid(struct ssh *ssh, pid_t pid, int status) * the session 'child' itself dies */ void -session_close_by_channel(struct ssh *ssh, int id, void *arg) +session_close_by_channel(struct ssh *ssh, int id, int force, void *arg) { Session *s = session_by_channel(id); u_int i; @@ -2482,12 +2482,14 @@ session_close_by_channel(struct ssh *ssh, int id, void *arg) if (s->pid != 0) { debug_f("channel %d: has child, ttyfd %d", id, s->ttyfd); /* - * delay detach of session, but release pty, since - * the fd's to the child are already closed + * delay detach of session (unless this is a forced close), + * but release pty, since the fd's to the child are already + * closed */ if (s->ttyfd != -1) session_pty_cleanup(s); - return; + if (!force) + return; } /* detach by removing callback */ channel_cancel_cleanup(ssh, s->chanid); @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.36 2018/10/02 12:40:07 djm Exp $ */ +/* $OpenBSD: session.h,v 1.37 2023/01/06 02:39:59 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -70,7 +70,7 @@ int session_open(Authctxt *, int); void session_unused(int); int session_input_channel_req(struct ssh *, Channel *, const char *); void session_close_by_pid(struct ssh *ssh, pid_t, int); -void session_close_by_channel(struct ssh *, int, void *); +void session_close_by_channel(struct ssh *, int, int, void *); void session_destroy_all(struct ssh *, void (*)(Session *)); void session_pty_cleanup2(Session *); @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.581 2022/12/09 00:22:29 dtucker Exp $ */ +/* $OpenBSD: ssh.c,v 1.582 2023/01/06 02:39:59 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1855,7 +1855,7 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) } static void -client_cleanup_stdio_fwd(struct ssh *ssh, int id, void *arg) +client_cleanup_stdio_fwd(struct ssh *ssh, int id, int force, void *arg) { debug("stdio forwarding: done"); cleanup_exit(0); |