summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2020-04-03 02:40:33 +0000
committerDamien Miller <djm@cvs.openbsd.org>2020-04-03 02:40:33 +0000
commit6f6188894d60b8dc09c5a551292baea2ea11a30f (patch)
treecfb2c7c8f6440018983c3bf81c45174a27211b25 /usr.bin
parent1ba7cc36b66db363eb4b74ea52345c8a9742c71d (diff)
make failures when establishing "Tunnel" forwarding terminate the
connection when ExitOnForwardFailure is enabled; bz3116; ok dtucker
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/clientloop.c7
-rw-r--r--usr.bin/ssh/clientloop.h5
-rw-r--r--usr.bin/ssh/ssh.c62
3 files changed, 47 insertions, 27 deletions
diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c
index 3873ec99cdb..9e55acf6c18 100644
--- a/usr.bin/ssh/clientloop.c
+++ b/usr.bin/ssh/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.342 2020/02/26 13:40:09 jsg Exp $ */
+/* $OpenBSD: clientloop.c,v 1.343 2020/04/03 02:40:32 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1637,7 +1637,7 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
char *
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
- int local_tun, int remote_tun)
+ int local_tun, int remote_tun, channel_open_fn *cb, void *cbctx)
{
Channel *c;
int r, fd;
@@ -1659,6 +1659,9 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
c->datagram = 1;
+ if (cb != NULL)
+ channel_register_open_confirm(ssh, c->self, cb, cbctx);
+
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
(r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
diff --git a/usr.bin/ssh/clientloop.h b/usr.bin/ssh/clientloop.h
index bf79c87bf89..31630551b23 100644
--- a/usr.bin/ssh/clientloop.h
+++ b/usr.bin/ssh/clientloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.h,v 1.36 2018/07/09 21:03:30 markus Exp $ */
+/* $OpenBSD: clientloop.h,v 1.37 2020/04/03 02:40:32 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -46,7 +46,8 @@ int client_x11_get_proto(struct ssh *, const char *, const char *,
void client_global_request_reply_fwd(int, u_int32_t, void *);
void client_session2_setup(struct ssh *, int, int, int,
const char *, struct termios *, int, struct sshbuf *, char **);
-char *client_request_tun_fwd(struct ssh *, int, int, int);
+char *client_request_tun_fwd(struct ssh *, int, int, int,
+ channel_open_fn *, void *);
void client_stop_mux(void);
/* Escape filter for protocol 2 sessions */
diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c
index 3ed4cd73342..cbb0df6ee75 100644
--- a/usr.bin/ssh/ssh.c
+++ b/usr.bin/ssh/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.522 2020/04/03 02:27:12 dtucker Exp $ */
+/* $OpenBSD: ssh.c,v 1.523 2020/04/03 02:40:32 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -181,7 +181,7 @@ struct sshbuf *command;
int subsystem_flag = 0;
/* # of replies received for global requests */
-static int remote_forward_confirms_received = 0;
+static int forward_confirms_pending = -1;
/* mux.c */
extern int muxserver_sock;
@@ -1646,6 +1646,16 @@ fork_postauth(void)
fatal("daemon() failed: %.200s", strerror(errno));
}
+static void
+forwarding_success(void)
+{
+ if (forward_confirms_pending > 0 && --forward_confirms_pending == 0) {
+ debug("All forwarding requests processed");
+ if (fork_after_authentication_flag)
+ fork_postauth();
+ }
+}
+
/* Callback for remote forward global requests */
static void
ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
@@ -1705,11 +1715,7 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
"for listen port %d", rfwd->listen_port);
}
}
- if (++remote_forward_confirms_received == options.num_remote_forwards) {
- debug("All remote forwarding requests processed");
- if (fork_after_authentication_flag)
- fork_postauth();
- }
+ forwarding_success();
}
static void
@@ -1727,6 +1733,19 @@ ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
}
static void
+ssh_tun_confirm(struct ssh *ssh, int id, int success, void *arg)
+{
+ if (!success) {
+ error("Tunnel forwarding failed");
+ if (options.exit_on_forward_failure)
+ cleanup_exit(255);
+ }
+
+ debug("%s: tunnel forward established, id=%d", __func__, id);
+ forwarding_success();
+}
+
+static void
ssh_init_stdio_forwarding(struct ssh *ssh)
{
Channel *c;
@@ -1789,32 +1808,29 @@ ssh_init_forwarding(struct ssh *ssh, char **ifname)
options.remote_forwards[i].connect_path :
options.remote_forwards[i].connect_host,
options.remote_forwards[i].connect_port);
- options.remote_forwards[i].handle =
+ if ((options.remote_forwards[i].handle =
channel_request_remote_forwarding(ssh,
- &options.remote_forwards[i]);
- if (options.remote_forwards[i].handle < 0) {
- if (options.exit_on_forward_failure)
- fatal("Could not request remote forwarding.");
- else
- logit("Warning: Could not request remote "
- "forwarding.");
- } else {
+ &options.remote_forwards[i])) >= 0) {
client_register_global_confirm(
ssh_confirm_remote_forward,
&options.remote_forwards[i]);
- }
+ forward_confirms_pending++;
+ } else if (options.exit_on_forward_failure)
+ fatal("Could not request remote forwarding.");
+ else
+ logit("Warning: Could not request remote forwarding.");
}
/* Initiate tunnel forwarding. */
if (options.tun_open != SSH_TUNMODE_NO) {
if ((*ifname = client_request_tun_fwd(ssh,
options.tun_open, options.tun_local,
- options.tun_remote)) == NULL) {
- if (options.exit_on_forward_failure)
- fatal("Could not request tunnel forwarding.");
- else
- error("Could not request tunnel forwarding.");
- }
+ options.tun_remote, ssh_tun_confirm, NULL)) != NULL)
+ forward_confirms_pending++;
+ else if (options.exit_on_forward_failure)
+ fatal("Could not request tunnel forwarding.");
+ else
+ error("Could not request tunnel forwarding.");
}
}