summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-09-12 06:32:07 +0000
committerDamien Miller <djm@mindrot.org>2017-09-12 17:37:02 +1000
commitdbee4119b502e3f8b6cd3282c69c537fd01d8e16 (patch)
treeb8a3263a79e0920e8d08f188654f1ccb7c254406 /ssh.c
parentabd59663df37a42152e37980113ccaa405b9a282 (diff)
upstream commit
refactor channels.c Move static state to a "struct ssh_channels" that is allocated at runtime and tracked as a member of struct ssh. Explicitly pass "struct ssh" to all channels functions. Replace use of the legacy packet APIs in channels.c. Rework sshd_config PermitOpen handling: previously the configuration parser would call directly into the channels layer. After the refactor this is not possible, as the channels structures are allocated at connection time and aren't available when the configuration is parsed. The server config parser now tracks PermitOpen itself and explicitly configures the channels code later. ok markus@ Upstream-ID: 11828f161656b965cc306576422613614bea2d8f
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c88
1 files changed, 48 insertions, 40 deletions
diff --git a/ssh.c b/ssh.c
index 019d1d31c..ecc50f37e 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.462 2017/08/12 06:46:01 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.463 2017/09/12 06:32:07 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
@@ -208,7 +208,7 @@ usage(void)
208 exit(255); 208 exit(255);
209} 209}
210 210
211static int ssh_session2(void); 211static int ssh_session2(struct ssh *);
212static void load_public_identity_files(void); 212static void load_public_identity_files(void);
213static void main_sigchld_handler(int); 213static void main_sigchld_handler(int);
214 214
@@ -596,6 +596,14 @@ main(int ac, char **av)
596 */ 596 */
597 initialize_options(&options); 597 initialize_options(&options);
598 598
599 /*
600 * Prepare main ssh transport/connection structures
601 */
602 if ((ssh = ssh_alloc_session_state()) == NULL)
603 fatal("Couldn't allocate session state");
604 channel_init_channels(ssh);
605 active_state = ssh; /* XXX legacy API compat */
606
599 /* Parse command-line arguments. */ 607 /* Parse command-line arguments. */
600 host = NULL; 608 host = NULL;
601 use_syslog = 0; 609 use_syslog = 0;
@@ -1108,7 +1116,7 @@ main(int ac, char **av)
1108 1116
1109 if (options.port == 0) 1117 if (options.port == 0)
1110 options.port = default_ssh_port(); 1118 options.port = default_ssh_port();
1111 channel_set_af(options.address_family); 1119 channel_set_af(ssh, options.address_family);
1112 1120
1113 /* Tidy and check options */ 1121 /* Tidy and check options */
1114 if (options.host_key_alias != NULL) 1122 if (options.host_key_alias != NULL)
@@ -1253,8 +1261,7 @@ main(int ac, char **av)
1253 if (options.control_path != NULL) { 1261 if (options.control_path != NULL) {
1254 int sock; 1262 int sock;
1255 if ((sock = muxclient(options.control_path)) >= 0) { 1263 if ((sock = muxclient(options.control_path)) >= 0) {
1256 packet_set_connection(sock, sock); 1264 ssh_packet_set_connection(ssh, sock, sock);
1257 ssh = active_state; /* XXX */
1258 packet_set_mux(); 1265 packet_set_mux();
1259 goto skip_connect; 1266 goto skip_connect;
1260 } 1267 }
@@ -1274,7 +1281,7 @@ main(int ac, char **av)
1274 timeout_ms = options.connection_timeout * 1000; 1281 timeout_ms = options.connection_timeout * 1000;
1275 1282
1276 /* Open a connection to the remote host. */ 1283 /* Open a connection to the remote host. */
1277 if (ssh_connect(host, addrs, &hostaddr, options.port, 1284 if (ssh_connect(ssh, host, addrs, &hostaddr, options.port,
1278 options.address_family, options.connection_attempts, 1285 options.address_family, options.connection_attempts,
1279 &timeout_ms, options.tcp_keep_alive, 1286 &timeout_ms, options.tcp_keep_alive,
1280 options.use_privileged_port) != 0) 1287 options.use_privileged_port) != 0)
@@ -1457,7 +1464,7 @@ main(int ac, char **av)
1457 } 1464 }
1458 1465
1459 skip_connect: 1466 skip_connect:
1460 exit_status = ssh_session2(); 1467 exit_status = ssh_session2(ssh);
1461 packet_close(); 1468 packet_close();
1462 1469
1463 if (options.control_path != NULL && muxserver_sock != -1) 1470 if (options.control_path != NULL && muxserver_sock != -1)
@@ -1530,7 +1537,7 @@ fork_postauth(void)
1530 1537
1531/* Callback for remote forward global requests */ 1538/* Callback for remote forward global requests */
1532static void 1539static void
1533ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 1540ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
1534{ 1541{
1535 struct Forward *rfwd = (struct Forward *)ctxt; 1542 struct Forward *rfwd = (struct Forward *)ctxt;
1536 1543
@@ -1548,10 +1555,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1548 logit("Allocated port %u for remote forward to %s:%d", 1555 logit("Allocated port %u for remote forward to %s:%d",
1549 rfwd->allocated_port, 1556 rfwd->allocated_port,
1550 rfwd->connect_host, rfwd->connect_port); 1557 rfwd->connect_host, rfwd->connect_port);
1551 channel_update_permitted_opens(rfwd->handle, 1558 channel_update_permitted_opens(ssh,
1552 rfwd->allocated_port); 1559 rfwd->handle, rfwd->allocated_port);
1553 } else { 1560 } else {
1554 channel_update_permitted_opens(rfwd->handle, -1); 1561 channel_update_permitted_opens(ssh, rfwd->handle, -1);
1555 } 1562 }
1556 } 1563 }
1557 1564
@@ -1580,21 +1587,21 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1580} 1587}
1581 1588
1582static void 1589static void
1583client_cleanup_stdio_fwd(int id, void *arg) 1590client_cleanup_stdio_fwd(struct ssh *ssh, int id, void *arg)
1584{ 1591{
1585 debug("stdio forwarding: done"); 1592 debug("stdio forwarding: done");
1586 cleanup_exit(0); 1593 cleanup_exit(0);
1587} 1594}
1588 1595
1589static void 1596static void
1590ssh_stdio_confirm(int id, int success, void *arg) 1597ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1591{ 1598{
1592 if (!success) 1599 if (!success)
1593 fatal("stdio forwarding failed"); 1600 fatal("stdio forwarding failed");
1594} 1601}
1595 1602
1596static void 1603static void
1597ssh_init_stdio_forwarding(void) 1604ssh_init_stdio_forwarding(struct ssh *ssh)
1598{ 1605{
1599 Channel *c; 1606 Channel *c;
1600 int in, out; 1607 int in, out;
@@ -1608,15 +1615,15 @@ ssh_init_stdio_forwarding(void)
1608 if ((in = dup(STDIN_FILENO)) < 0 || 1615 if ((in = dup(STDIN_FILENO)) < 0 ||
1609 (out = dup(STDOUT_FILENO)) < 0) 1616 (out = dup(STDOUT_FILENO)) < 0)
1610 fatal("channel_connect_stdio_fwd: dup() in/out failed"); 1617 fatal("channel_connect_stdio_fwd: dup() in/out failed");
1611 if ((c = channel_connect_stdio_fwd(options.stdio_forward_host, 1618 if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host,
1612 options.stdio_forward_port, in, out)) == NULL) 1619 options.stdio_forward_port, in, out)) == NULL)
1613 fatal("%s: channel_connect_stdio_fwd failed", __func__); 1620 fatal("%s: channel_connect_stdio_fwd failed", __func__);
1614 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); 1621 channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0);
1615 channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL); 1622 channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL);
1616} 1623}
1617 1624
1618static void 1625static void
1619ssh_init_forwarding(void) 1626ssh_init_forwarding(struct ssh *ssh)
1620{ 1627{
1621 int success = 0; 1628 int success = 0;
1622 int i; 1629 int i;
@@ -1635,7 +1642,7 @@ ssh_init_forwarding(void)
1635 options.local_forwards[i].connect_path : 1642 options.local_forwards[i].connect_path :
1636 options.local_forwards[i].connect_host, 1643 options.local_forwards[i].connect_host,
1637 options.local_forwards[i].connect_port); 1644 options.local_forwards[i].connect_port);
1638 success += channel_setup_local_fwd_listener( 1645 success += channel_setup_local_fwd_listener(ssh,
1639 &options.local_forwards[i], &options.fwd_opts); 1646 &options.local_forwards[i], &options.fwd_opts);
1640 } 1647 }
1641 if (i > 0 && success != i && options.exit_on_forward_failure) 1648 if (i > 0 && success != i && options.exit_on_forward_failure)
@@ -1657,7 +1664,7 @@ ssh_init_forwarding(void)
1657 options.remote_forwards[i].connect_host, 1664 options.remote_forwards[i].connect_host,
1658 options.remote_forwards[i].connect_port); 1665 options.remote_forwards[i].connect_port);
1659 options.remote_forwards[i].handle = 1666 options.remote_forwards[i].handle =
1660 channel_request_remote_forwarding( 1667 channel_request_remote_forwarding(ssh,
1661 &options.remote_forwards[i]); 1668 &options.remote_forwards[i]);
1662 if (options.remote_forwards[i].handle < 0) { 1669 if (options.remote_forwards[i].handle < 0) {
1663 if (options.exit_on_forward_failure) 1670 if (options.exit_on_forward_failure)
@@ -1666,14 +1673,15 @@ ssh_init_forwarding(void)
1666 logit("Warning: Could not request remote " 1673 logit("Warning: Could not request remote "
1667 "forwarding."); 1674 "forwarding.");
1668 } else { 1675 } else {
1669 client_register_global_confirm(ssh_confirm_remote_forward, 1676 client_register_global_confirm(
1677 ssh_confirm_remote_forward,
1670 &options.remote_forwards[i]); 1678 &options.remote_forwards[i]);
1671 } 1679 }
1672 } 1680 }
1673 1681
1674 /* Initiate tunnel forwarding. */ 1682 /* Initiate tunnel forwarding. */
1675 if (options.tun_open != SSH_TUNMODE_NO) { 1683 if (options.tun_open != SSH_TUNMODE_NO) {
1676 if (client_request_tun_fwd(options.tun_open, 1684 if (client_request_tun_fwd(ssh, options.tun_open,
1677 options.tun_local, options.tun_remote) == -1) { 1685 options.tun_local, options.tun_remote) == -1) {
1678 if (options.exit_on_forward_failure) 1686 if (options.exit_on_forward_failure)
1679 fatal("Could not request tunnel forwarding."); 1687 fatal("Could not request tunnel forwarding.");
@@ -1700,7 +1708,7 @@ check_agent_present(void)
1700} 1708}
1701 1709
1702static void 1710static void
1703ssh_session2_setup(int id, int success, void *arg) 1711ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
1704{ 1712{
1705 extern char **environ; 1713 extern char **environ;
1706 const char *display; 1714 const char *display;
@@ -1713,15 +1721,15 @@ ssh_session2_setup(int id, int success, void *arg)
1713 display = getenv("DISPLAY"); 1721 display = getenv("DISPLAY");
1714 if (display == NULL && options.forward_x11) 1722 if (display == NULL && options.forward_x11)
1715 debug("X11 forwarding requested but DISPLAY not set"); 1723 debug("X11 forwarding requested but DISPLAY not set");
1716 if (options.forward_x11 && client_x11_get_proto(display, 1724 if (options.forward_x11 && client_x11_get_proto(ssh, display,
1717 options.xauth_location, options.forward_x11_trusted, 1725 options.xauth_location, options.forward_x11_trusted,
1718 options.forward_x11_timeout, &proto, &data) == 0) { 1726 options.forward_x11_timeout, &proto, &data) == 0) {
1719 /* Request forwarding with authentication spoofing. */ 1727 /* Request forwarding with authentication spoofing. */
1720 debug("Requesting X11 forwarding with authentication " 1728 debug("Requesting X11 forwarding with authentication "
1721 "spoofing."); 1729 "spoofing.");
1722 x11_request_forwarding_with_spoofing(id, display, proto, 1730 x11_request_forwarding_with_spoofing(ssh, id, display, proto,
1723 data, 1); 1731 data, 1);
1724 client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); 1732 client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN);
1725 /* XXX exit_on_forward_failure */ 1733 /* XXX exit_on_forward_failure */
1726 interactive = 1; 1734 interactive = 1;
1727 } 1735 }
@@ -1729,7 +1737,7 @@ ssh_session2_setup(int id, int success, void *arg)
1729 check_agent_present(); 1737 check_agent_present();
1730 if (options.forward_agent) { 1738 if (options.forward_agent) {
1731 debug("Requesting authentication agent forwarding."); 1739 debug("Requesting authentication agent forwarding.");
1732 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1740 channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
1733 packet_send(); 1741 packet_send();
1734 } 1742 }
1735 1743
@@ -1737,13 +1745,13 @@ ssh_session2_setup(int id, int success, void *arg)
1737 packet_set_interactive(interactive, 1745 packet_set_interactive(interactive,
1738 options.ip_qos_interactive, options.ip_qos_bulk); 1746 options.ip_qos_interactive, options.ip_qos_bulk);
1739 1747
1740 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1748 client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"),
1741 NULL, fileno(stdin), &command, environ); 1749 NULL, fileno(stdin), &command, environ);
1742} 1750}
1743 1751
1744/* open new channel for a session */ 1752/* open new channel for a session */
1745static int 1753static int
1746ssh_session2_open(void) 1754ssh_session2_open(struct ssh *ssh)
1747{ 1755{
1748 Channel *c; 1756 Channel *c;
1749 int window, packetmax, in, out, err; 1757 int window, packetmax, in, out, err;
@@ -1773,34 +1781,34 @@ ssh_session2_open(void)
1773 window >>= 1; 1781 window >>= 1;
1774 packetmax >>= 1; 1782 packetmax >>= 1;
1775 } 1783 }
1776 c = channel_new( 1784 c = channel_new(ssh,
1777 "session", SSH_CHANNEL_OPENING, in, out, err, 1785 "session", SSH_CHANNEL_OPENING, in, out, err,
1778 window, packetmax, CHAN_EXTENDED_WRITE, 1786 window, packetmax, CHAN_EXTENDED_WRITE,
1779 "client-session", /*nonblock*/0); 1787 "client-session", /*nonblock*/0);
1780 1788
1781 debug3("ssh_session2_open: channel_new: %d", c->self); 1789 debug3("%s: channel_new: %d", __func__, c->self);
1782 1790
1783 channel_send_open(c->self); 1791 channel_send_open(ssh, c->self);
1784 if (!no_shell_flag) 1792 if (!no_shell_flag)
1785 channel_register_open_confirm(c->self, 1793 channel_register_open_confirm(ssh, c->self,
1786 ssh_session2_setup, NULL); 1794 ssh_session2_setup, NULL);
1787 1795
1788 return c->self; 1796 return c->self;
1789} 1797}
1790 1798
1791static int 1799static int
1792ssh_session2(void) 1800ssh_session2(struct ssh *ssh)
1793{ 1801{
1794 int id = -1; 1802 int id = -1;
1795 1803
1796 /* XXX should be pre-session */ 1804 /* XXX should be pre-session */
1797 if (!options.control_persist) 1805 if (!options.control_persist)
1798 ssh_init_stdio_forwarding(); 1806 ssh_init_stdio_forwarding(ssh);
1799 ssh_init_forwarding(); 1807 ssh_init_forwarding(ssh);
1800 1808
1801 /* Start listening for multiplex clients */ 1809 /* Start listening for multiplex clients */
1802 if (!packet_get_mux()) 1810 if (!packet_get_mux())
1803 muxserver_listen(); 1811 muxserver_listen(ssh);
1804 1812
1805 /* 1813 /*
1806 * If we are in control persist mode and have a working mux listen 1814 * If we are in control persist mode and have a working mux listen
@@ -1828,10 +1836,10 @@ ssh_session2(void)
1828 * stdio forward setup that we skipped earlier. 1836 * stdio forward setup that we skipped earlier.
1829 */ 1837 */
1830 if (options.control_persist && muxserver_sock == -1) 1838 if (options.control_persist && muxserver_sock == -1)
1831 ssh_init_stdio_forwarding(); 1839 ssh_init_stdio_forwarding(ssh);
1832 1840
1833 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1841 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1834 id = ssh_session2_open(); 1842 id = ssh_session2_open(ssh);
1835 else { 1843 else {
1836 packet_set_interactive( 1844 packet_set_interactive(
1837 options.control_master == SSHCTL_MASTER_NO, 1845 options.control_master == SSHCTL_MASTER_NO,
@@ -1866,7 +1874,7 @@ ssh_session2(void)
1866 fork_postauth(); 1874 fork_postauth();
1867 } 1875 }
1868 1876
1869 return client_loop(tty_flag, tty_flag ? 1877 return client_loop(ssh, tty_flag, tty_flag ?
1870 options.escape_char : SSH_ESCAPECHAR_NONE, id); 1878 options.escape_char : SSH_ESCAPECHAR_NONE, id);
1871} 1879}
1872 1880