summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels.c43
-rw-r--r--channels.h5
-rw-r--r--clientloop.c14
-rw-r--r--mux.c6
-rw-r--r--session.c14
-rw-r--r--session.h4
-rw-r--r--ssh.c4
7 files changed, 50 insertions, 40 deletions
diff --git a/channels.c b/channels.c
index 5541e904..84d902bd 100644
--- a/channels.c
+++ b/channels.c
@@ -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;
diff --git a/channels.h b/channels.h
index 51a02b22..bcffa6cf 100644
--- a/channels.h
+++ b/channels.h
@@ -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;
diff --git a/mux.c b/mux.c
index 3cb38761..e7580ac7 100644
--- a/mux.c
+++ b/mux.c
@@ -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);
diff --git a/session.c b/session.c
index e67d24d2..a40ee2c0 100644
--- a/session.c
+++ b/session.c
@@ -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);
diff --git a/session.h b/session.h
index ce59dabd..344a1ddf 100644
--- a/session.h
+++ b/session.h
@@ -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 *);
diff --git a/ssh.c b/ssh.c
index ba27674f..f20848e6 100644
--- a/ssh.c
+++ b/ssh.c
@@ -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);