diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-09-12 06:32:07 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-09-12 17:37:02 +1000 |
commit | dbee4119b502e3f8b6cd3282c69c537fd01d8e16 (patch) | |
tree | b8a3263a79e0920e8d08f188654f1ccb7c254406 /ssh.c | |
parent | abd59663df37a42152e37980113ccaa405b9a282 (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.c | 88 |
1 files changed, 48 insertions, 40 deletions
@@ -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 | ||
211 | static int ssh_session2(void); | 211 | static int ssh_session2(struct ssh *); |
212 | static void load_public_identity_files(void); | 212 | static void load_public_identity_files(void); |
213 | static void main_sigchld_handler(int); | 213 | static 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 */ |
1532 | static void | 1539 | static void |
1533 | ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | 1540 | ssh_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 | ||
1582 | static void | 1589 | static void |
1583 | client_cleanup_stdio_fwd(int id, void *arg) | 1590 | client_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 | ||
1589 | static void | 1596 | static void |
1590 | ssh_stdio_confirm(int id, int success, void *arg) | 1597 | ssh_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 | ||
1596 | static void | 1603 | static void |
1597 | ssh_init_stdio_forwarding(void) | 1604 | ssh_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 | ||
1618 | static void | 1625 | static void |
1619 | ssh_init_forwarding(void) | 1626 | ssh_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 | ||
1702 | static void | 1710 | static void |
1703 | ssh_session2_setup(int id, int success, void *arg) | 1711 | ssh_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 */ |
1745 | static int | 1753 | static int |
1746 | ssh_session2_open(void) | 1754 | ssh_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 | ||
1791 | static int | 1799 | static int |
1792 | ssh_session2(void) | 1800 | ssh_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 | ||