summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-04-03 02:40:32 +0000
committerDamien Miller <djm@mindrot.org>2020-04-03 13:42:33 +1100
commit663e84bb53de2a60e56a44d538d25b8152b5c1cc (patch)
tree2b8a180730e1bd4e130f1af40800b0393beb818e
parented833da176611a39d3376d62154eb88eb440d31c (diff)
upstream: make failures when establishing "Tunnel" forwarding terminate
the connection when ExitOnForwardFailure is enabled; bz3116; ok dtucker OpenBSD-Commit-ID: ef4b4808de0a419c17579b1081da768625c1d735
-rw-r--r--clientloop.c7
-rw-r--r--clientloop.h5
-rw-r--r--ssh.c62
3 files changed, 47 insertions, 27 deletions
diff --git a/clientloop.c b/clientloop.c
index 5bfccdd35..8950f444b 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.342 2020/02/26 13:40:09 jsg Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.343 2020/04/03 02:40:32 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1645,7 +1645,7 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
1645 1645
1646char * 1646char *
1647client_request_tun_fwd(struct ssh *ssh, int tun_mode, 1647client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1648 int local_tun, int remote_tun) 1648 int local_tun, int remote_tun, channel_open_fn *cb, void *cbctx)
1649{ 1649{
1650 Channel *c; 1650 Channel *c;
1651 int r, fd; 1651 int r, fd;
@@ -1673,6 +1673,9 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1673 sys_tun_outfilter, NULL, NULL); 1673 sys_tun_outfilter, NULL, NULL);
1674#endif 1674#endif
1675 1675
1676 if (cb != NULL)
1677 channel_register_open_confirm(ssh, c->self, cb, cbctx);
1678
1676 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 || 1679 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
1677 (r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 || 1680 (r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 ||
1678 (r = sshpkt_put_u32(ssh, c->self)) != 0 || 1681 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
diff --git a/clientloop.h b/clientloop.h
index bf79c87bf..31630551b 100644
--- a/clientloop.h
+++ b/clientloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.h,v 1.36 2018/07/09 21:03:30 markus Exp $ */ 1/* $OpenBSD: clientloop.h,v 1.37 2020/04/03 02:40:32 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -46,7 +46,8 @@ int client_x11_get_proto(struct ssh *, const char *, const char *,
46void client_global_request_reply_fwd(int, u_int32_t, void *); 46void client_global_request_reply_fwd(int, u_int32_t, void *);
47void client_session2_setup(struct ssh *, int, int, int, 47void client_session2_setup(struct ssh *, int, int, int,
48 const char *, struct termios *, int, struct sshbuf *, char **); 48 const char *, struct termios *, int, struct sshbuf *, char **);
49char *client_request_tun_fwd(struct ssh *, int, int, int); 49char *client_request_tun_fwd(struct ssh *, int, int, int,
50 channel_open_fn *, void *);
50void client_stop_mux(void); 51void client_stop_mux(void);
51 52
52/* Escape filter for protocol 2 sessions */ 53/* Escape filter for protocol 2 sessions */
diff --git a/ssh.c b/ssh.c
index 470d9b7e6..d99a245a4 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.522 2020/04/03 02:27:12 dtucker Exp $ */ 1/* $OpenBSD: ssh.c,v 1.523 2020/04/03 02:40:32 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -197,7 +197,7 @@ struct sshbuf *command;
197int subsystem_flag = 0; 197int subsystem_flag = 0;
198 198
199/* # of replies received for global requests */ 199/* # of replies received for global requests */
200static int remote_forward_confirms_received = 0; 200static int forward_confirms_pending = -1;
201 201
202/* mux.c */ 202/* mux.c */
203extern int muxserver_sock; 203extern int muxserver_sock;
@@ -1673,6 +1673,16 @@ fork_postauth(void)
1673 fatal("daemon() failed: %.200s", strerror(errno)); 1673 fatal("daemon() failed: %.200s", strerror(errno));
1674} 1674}
1675 1675
1676static void
1677forwarding_success(void)
1678{
1679 if (forward_confirms_pending > 0 && --forward_confirms_pending == 0) {
1680 debug("All forwarding requests processed");
1681 if (fork_after_authentication_flag)
1682 fork_postauth();
1683 }
1684}
1685
1676/* Callback for remote forward global requests */ 1686/* Callback for remote forward global requests */
1677static void 1687static void
1678ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) 1688ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
@@ -1732,11 +1742,7 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
1732 "for listen port %d", rfwd->listen_port); 1742 "for listen port %d", rfwd->listen_port);
1733 } 1743 }
1734 } 1744 }
1735 if (++remote_forward_confirms_received == options.num_remote_forwards) { 1745 forwarding_success();
1736 debug("All remote forwarding requests processed");
1737 if (fork_after_authentication_flag)
1738 fork_postauth();
1739 }
1740} 1746}
1741 1747
1742static void 1748static void
@@ -1754,6 +1760,19 @@ ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1754} 1760}
1755 1761
1756static void 1762static void
1763ssh_tun_confirm(struct ssh *ssh, int id, int success, void *arg)
1764{
1765 if (!success) {
1766 error("Tunnel forwarding failed");
1767 if (options.exit_on_forward_failure)
1768 cleanup_exit(255);
1769 }
1770
1771 debug("%s: tunnel forward established, id=%d", __func__, id);
1772 forwarding_success();
1773}
1774
1775static void
1757ssh_init_stdio_forwarding(struct ssh *ssh) 1776ssh_init_stdio_forwarding(struct ssh *ssh)
1758{ 1777{
1759 Channel *c; 1778 Channel *c;
@@ -1816,32 +1835,29 @@ ssh_init_forwarding(struct ssh *ssh, char **ifname)
1816 options.remote_forwards[i].connect_path : 1835 options.remote_forwards[i].connect_path :
1817 options.remote_forwards[i].connect_host, 1836 options.remote_forwards[i].connect_host,
1818 options.remote_forwards[i].connect_port); 1837 options.remote_forwards[i].connect_port);
1819 options.remote_forwards[i].handle = 1838 if ((options.remote_forwards[i].handle =
1820 channel_request_remote_forwarding(ssh, 1839 channel_request_remote_forwarding(ssh,
1821 &options.remote_forwards[i]); 1840 &options.remote_forwards[i])) >= 0) {
1822 if (options.remote_forwards[i].handle < 0) {
1823 if (options.exit_on_forward_failure)
1824 fatal("Could not request remote forwarding.");
1825 else
1826 logit("Warning: Could not request remote "
1827 "forwarding.");
1828 } else {
1829 client_register_global_confirm( 1841 client_register_global_confirm(
1830 ssh_confirm_remote_forward, 1842 ssh_confirm_remote_forward,
1831 &options.remote_forwards[i]); 1843 &options.remote_forwards[i]);
1832 } 1844 forward_confirms_pending++;
1845 } else if (options.exit_on_forward_failure)
1846 fatal("Could not request remote forwarding.");
1847 else
1848 logit("Warning: Could not request remote forwarding.");
1833 } 1849 }
1834 1850
1835 /* Initiate tunnel forwarding. */ 1851 /* Initiate tunnel forwarding. */
1836 if (options.tun_open != SSH_TUNMODE_NO) { 1852 if (options.tun_open != SSH_TUNMODE_NO) {
1837 if ((*ifname = client_request_tun_fwd(ssh, 1853 if ((*ifname = client_request_tun_fwd(ssh,
1838 options.tun_open, options.tun_local, 1854 options.tun_open, options.tun_local,
1839 options.tun_remote)) == NULL) { 1855 options.tun_remote, ssh_tun_confirm, NULL)) != NULL)
1840 if (options.exit_on_forward_failure) 1856 forward_confirms_pending++;
1841 fatal("Could not request tunnel forwarding."); 1857 else if (options.exit_on_forward_failure)
1842 else 1858 fatal("Could not request tunnel forwarding.");
1843 error("Could not request tunnel forwarding."); 1859 else
1844 } 1860 error("Could not request tunnel forwarding.");
1845 } 1861 }
1846} 1862}
1847 1863