diff options
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 | ||