Deleted Added
full compact
clientloop.c (294328) clientloop.c (294332)
1/* $OpenBSD: clientloop.c,v 1.261 2014/07/15 15:54:14 millert Exp $ */
1/* $OpenBSD: clientloop.c,v 1.272 2015/02/25 19:54:02 djm Exp $ */
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * The main loop for the interactive session (client side).
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this

--- 45 unchanged lines hidden (view full) ---

55 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
59 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 */
61
62#include "includes.h"
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * The main loop for the interactive session (client side).
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this

--- 45 unchanged lines hidden (view full) ---

55 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
59 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 */
61
62#include "includes.h"
63__RCSID("$FreeBSD: head/crypto/openssh/clientloop.c 294328 2016-01-19 16:18:26Z des $");
63__RCSID("$FreeBSD: head/crypto/openssh/clientloop.c 294332 2016-01-19 18:28:23Z des $");
64
64
65#include <sys/param.h> /* MIN MAX */
65#include <sys/types.h>
66#include <sys/ioctl.h>
66#include <sys/types.h>
67#include <sys/ioctl.h>
67#include <sys/param.h>
68#ifdef HAVE_SYS_STAT_H
69# include <sys/stat.h>
70#endif
71#ifdef HAVE_SYS_TIME_H
72# include <sys/time.h>
73#endif
74#include <sys/socket.h>
75

--- 5 unchanged lines hidden (view full) ---

81#include <signal.h>
82#include <stdarg.h>
83#include <stdio.h>
84#include <stdlib.h>
85#include <string.h>
86#include <termios.h>
87#include <pwd.h>
88#include <unistd.h>
68#ifdef HAVE_SYS_STAT_H
69# include <sys/stat.h>
70#endif
71#ifdef HAVE_SYS_TIME_H
72# include <sys/time.h>
73#endif
74#include <sys/socket.h>
75

--- 5 unchanged lines hidden (view full) ---

81#include <signal.h>
82#include <stdarg.h>
83#include <stdio.h>
84#include <stdlib.h>
85#include <string.h>
86#include <termios.h>
87#include <pwd.h>
88#include <unistd.h>
89#include <limits.h>
89
90#include "openbsd-compat/sys-queue.h"
91#include "xmalloc.h"
92#include "ssh.h"
93#include "ssh1.h"
94#include "ssh2.h"
95#include "packet.h"
96#include "buffer.h"

--- 9 unchanged lines hidden (view full) ---

106#include "clientloop.h"
107#include "sshconnect.h"
108#include "authfd.h"
109#include "atomicio.h"
110#include "sshpty.h"
111#include "match.h"
112#include "msg.h"
113#include "roaming.h"
90
91#include "openbsd-compat/sys-queue.h"
92#include "xmalloc.h"
93#include "ssh.h"
94#include "ssh1.h"
95#include "ssh2.h"
96#include "packet.h"
97#include "buffer.h"

--- 9 unchanged lines hidden (view full) ---

107#include "clientloop.h"
108#include "sshconnect.h"
109#include "authfd.h"
110#include "atomicio.h"
111#include "sshpty.h"
112#include "match.h"
113#include "msg.h"
114#include "roaming.h"
115#include "ssherr.h"
116#include "hostfile.h"
114
115/* import options */
116extern Options options;
117
118/* Flag indicating that stdin should be redirected from /dev/null. */
119extern int stdin_null_flag;
120
121/* Flag indicating that no shell has been requested */

--- 65 unchanged lines hidden (view full) ---

187 global_confirm_cb *cb;
188 void *ctx;
189 int ref_count;
190};
191TAILQ_HEAD(global_confirms, global_confirm);
192static struct global_confirms global_confirms =
193 TAILQ_HEAD_INITIALIZER(global_confirms);
194
117
118/* import options */
119extern Options options;
120
121/* Flag indicating that stdin should be redirected from /dev/null. */
122extern int stdin_null_flag;
123
124/* Flag indicating that no shell has been requested */

--- 65 unchanged lines hidden (view full) ---

190 global_confirm_cb *cb;
191 void *ctx;
192 int ref_count;
193};
194TAILQ_HEAD(global_confirms, global_confirm);
195static struct global_confirms global_confirms =
196 TAILQ_HEAD_INITIALIZER(global_confirms);
197
195/*XXX*/
196extern Kex *xxx_kex;
197
198void ssh_process_session2_setup(int, int, int, Buffer *);
199
200/* Restores stdin to blocking mode. */
201
202static void
203leave_non_blocking(void)
204{
205 if (in_non_blocking_mode) {

--- 131 unchanged lines hidden (view full) ---

337 * is not perfect.
338 */
339 if (strncmp(display, "localhost:", 10) == 0) {
340 snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
341 display + 10);
342 display = xdisplay;
343 }
344 if (trusted == 0) {
198void ssh_process_session2_setup(int, int, int, Buffer *);
199
200/* Restores stdin to blocking mode. */
201
202static void
203leave_non_blocking(void)
204{
205 if (in_non_blocking_mode) {

--- 131 unchanged lines hidden (view full) ---

337 * is not perfect.
338 */
339 if (strncmp(display, "localhost:", 10) == 0) {
340 snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
341 display + 10);
342 display = xdisplay;
343 }
344 if (trusted == 0) {
345 xauthdir = xmalloc(MAXPATHLEN);
346 xauthfile = xmalloc(MAXPATHLEN);
347 mktemp_proto(xauthdir, MAXPATHLEN);
345 xauthdir = xmalloc(PATH_MAX);
346 xauthfile = xmalloc(PATH_MAX);
347 mktemp_proto(xauthdir, PATH_MAX);
348 if (mkdtemp(xauthdir) != NULL) {
349 do_unlink = 1;
348 if (mkdtemp(xauthdir) != NULL) {
349 do_unlink = 1;
350 snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
350 snprintf(xauthfile, PATH_MAX, "%s/xauthfile",
351 xauthdir);
352 snprintf(cmd, sizeof(cmd),
353 "%s -f %s generate %s " SSH_X11_PROTO
354 " untrusted timeout %u 2>" _PATH_DEVNULL,
355 xauth_path, xauthfile, display, timeout);
356 debug2("x11_get_proto: %s", cmd);
357 if (system(cmd) == 0)
358 generated = 1;

--- 175 unchanged lines hidden (view full) ---

534 packet_put_int((u_int)ws.ws_row);
535 packet_put_int((u_int)ws.ws_col);
536 packet_put_int((u_int)ws.ws_xpixel);
537 packet_put_int((u_int)ws.ws_ypixel);
538 packet_send();
539 }
540}
541
351 xauthdir);
352 snprintf(cmd, sizeof(cmd),
353 "%s -f %s generate %s " SSH_X11_PROTO
354 " untrusted timeout %u 2>" _PATH_DEVNULL,
355 xauth_path, xauthfile, display, timeout);
356 debug2("x11_get_proto: %s", cmd);
357 if (system(cmd) == 0)
358 generated = 1;

--- 175 unchanged lines hidden (view full) ---

534 packet_put_int((u_int)ws.ws_row);
535 packet_put_int((u_int)ws.ws_col);
536 packet_put_int((u_int)ws.ws_xpixel);
537 packet_put_int((u_int)ws.ws_ypixel);
538 packet_send();
539 }
540}
541
542static void
542static int
543client_global_request_reply(int type, u_int32_t seq, void *ctxt)
544{
545 struct global_confirm *gc;
546
547 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
543client_global_request_reply(int type, u_int32_t seq, void *ctxt)
544{
545 struct global_confirm *gc;
546
547 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
548 return;
548 return 0;
549 if (gc->cb != NULL)
550 gc->cb(type, seq, gc->ctx);
551 if (--gc->ref_count <= 0) {
552 TAILQ_REMOVE(&global_confirms, gc, entry);
553 explicit_bzero(gc, sizeof(*gc));
554 free(gc);
555 }
556
557 packet_set_alive_timeouts(0);
549 if (gc->cb != NULL)
550 gc->cb(type, seq, gc->ctx);
551 if (--gc->ref_count <= 0) {
552 TAILQ_REMOVE(&global_confirms, gc, entry);
553 explicit_bzero(gc, sizeof(*gc));
554 free(gc);
555 }
556
557 packet_set_alive_timeouts(0);
558 return 0;
558}
559
560static void
561server_alive_check(void)
562{
563 if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
564 logit("Timeout, server %s not responding.", host);
565 cleanup_exit(255);

--- 844 unchanged lines hidden (view full) ---

1410 * confirmations are sent. Any compatible protocol
1411 * extensions must be negotiated during the
1412 * preparatory phase.
1413 */
1414
1415static void
1416client_process_buffered_input_packets(void)
1417{
559}
560
561static void
562server_alive_check(void)
563{
564 if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
565 logit("Timeout, server %s not responding.", host);
566 cleanup_exit(255);

--- 844 unchanged lines hidden (view full) ---

1411 * confirmations are sent. Any compatible protocol
1412 * extensions must be negotiated during the
1413 * preparatory phase.
1414 */
1415
1416static void
1417client_process_buffered_input_packets(void)
1418{
1418 dispatch_run(DISPATCH_NONBLOCK, &quit_pending,
1419 compat20 ? xxx_kex : NULL);
1419 dispatch_run(DISPATCH_NONBLOCK, &quit_pending, active_state);
1420}
1421
1422/* scan buf[] for '~' before sending data to the peer */
1423
1424/* Helper: allocate a new escape_filter_ctx and fill in its escape char */
1425void *
1426client_new_escape_filter_ctx(int escape_char)
1427{

--- 37 unchanged lines hidden (view full) ---

1465 * used as an escape character for terminating or suspending the session.
1466 */
1467
1468int
1469client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1470{
1471 fd_set *readset = NULL, *writeset = NULL;
1472 double start_time, total_time;
1420}
1421
1422/* scan buf[] for '~' before sending data to the peer */
1423
1424/* Helper: allocate a new escape_filter_ctx and fill in its escape char */
1425void *
1426client_new_escape_filter_ctx(int escape_char)
1427{

--- 37 unchanged lines hidden (view full) ---

1465 * used as an escape character for terminating or suspending the session.
1466 */
1467
1468int
1469client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1470{
1471 fd_set *readset = NULL, *writeset = NULL;
1472 double start_time, total_time;
1473 int max_fd = 0, max_fd2 = 0, len, rekeying = 0;
1473 int r, max_fd = 0, max_fd2 = 0, len, rekeying = 0;
1474 u_int64_t ibytes, obytes;
1475 u_int nalloc = 0;
1476 char buf[100];
1477
1478 debug("Entering interactive session.");
1479
1480 start_time = get_current_time();
1481

--- 68 unchanged lines hidden (view full) ---

1550 while (!quit_pending) {
1551
1552 /* Process buffered packets sent by the server. */
1553 client_process_buffered_input_packets();
1554
1555 if (compat20 && session_closed && !channel_still_open())
1556 break;
1557
1474 u_int64_t ibytes, obytes;
1475 u_int nalloc = 0;
1476 char buf[100];
1477
1478 debug("Entering interactive session.");
1479
1480 start_time = get_current_time();
1481

--- 68 unchanged lines hidden (view full) ---

1550 while (!quit_pending) {
1551
1552 /* Process buffered packets sent by the server. */
1553 client_process_buffered_input_packets();
1554
1555 if (compat20 && session_closed && !channel_still_open())
1556 break;
1557
1558 rekeying = (xxx_kex != NULL && !xxx_kex->done);
1558 rekeying = (active_state->kex != NULL && !active_state->kex->done);
1559
1560 if (rekeying) {
1561 debug("rekeying in progress");
1562 } else {
1563 /*
1564 * Make packets of buffered stdin data, and buffer
1565 * them for sending to the server.
1566 */

--- 27 unchanged lines hidden (view full) ---

1594 if (quit_pending)
1595 break;
1596
1597 /* Do channel operations unless rekeying in progress. */
1598 if (!rekeying) {
1599 channel_after_select(readset, writeset);
1600 if (need_rekeying || packet_need_rekeying()) {
1601 debug("need rekeying");
1559
1560 if (rekeying) {
1561 debug("rekeying in progress");
1562 } else {
1563 /*
1564 * Make packets of buffered stdin data, and buffer
1565 * them for sending to the server.
1566 */

--- 27 unchanged lines hidden (view full) ---

1594 if (quit_pending)
1595 break;
1596
1597 /* Do channel operations unless rekeying in progress. */
1598 if (!rekeying) {
1599 channel_after_select(readset, writeset);
1600 if (need_rekeying || packet_need_rekeying()) {
1601 debug("need rekeying");
1602 xxx_kex->done = 0;
1603 kex_send_kexinit(xxx_kex);
1602 active_state->kex->done = 0;
1603 if ((r = kex_send_kexinit(active_state)) != 0)
1604 fatal("%s: kex_send_kexinit: %s",
1605 __func__, ssh_err(r));
1604 need_rekeying = 0;
1605 }
1606 }
1607
1608 /* Buffer input from the connection. */
1609 client_process_net_input(readset);
1610
1611 if (quit_pending)

--- 112 unchanged lines hidden (view full) ---

1724 /* Clear and free any buffers. */
1725 memset(buf, 0, sizeof(buf));
1726 buffer_free(&stdin_buffer);
1727 buffer_free(&stdout_buffer);
1728 buffer_free(&stderr_buffer);
1729
1730 /* Report bytes transferred, and transfer rates. */
1731 total_time = get_current_time() - start_time;
1606 need_rekeying = 0;
1607 }
1608 }
1609
1610 /* Buffer input from the connection. */
1611 client_process_net_input(readset);
1612
1613 if (quit_pending)

--- 112 unchanged lines hidden (view full) ---

1726 /* Clear and free any buffers. */
1727 memset(buf, 0, sizeof(buf));
1728 buffer_free(&stdin_buffer);
1729 buffer_free(&stdout_buffer);
1730 buffer_free(&stderr_buffer);
1731
1732 /* Report bytes transferred, and transfer rates. */
1733 total_time = get_current_time() - start_time;
1732 packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
1733 packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
1734 packet_get_bytes(&ibytes, &obytes);
1734 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
1735 (unsigned long long)obytes, (unsigned long long)ibytes, total_time);
1736 if (total_time > 0)
1737 verbose("Bytes per second: sent %.1f, received %.1f",
1738 obytes / total_time, ibytes / total_time);
1739 /* Return the exit status of the program. */
1740 debug("Exit status %d", exit_status);
1741 return exit_status;
1742}
1743
1744/*********/
1745
1735 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
1736 (unsigned long long)obytes, (unsigned long long)ibytes, total_time);
1737 if (total_time > 0)
1738 verbose("Bytes per second: sent %.1f, received %.1f",
1739 obytes / total_time, ibytes / total_time);
1740 /* Return the exit status of the program. */
1741 debug("Exit status %d", exit_status);
1742 return exit_status;
1743}
1744
1745/*********/
1746
1746static void
1747static int
1747client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
1748{
1749 u_int data_len;
1750 char *data = packet_get_string(&data_len);
1751 packet_check_eom();
1752 buffer_append(&stdout_buffer, data, data_len);
1753 explicit_bzero(data, data_len);
1754 free(data);
1748client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
1749{
1750 u_int data_len;
1751 char *data = packet_get_string(&data_len);
1752 packet_check_eom();
1753 buffer_append(&stdout_buffer, data, data_len);
1754 explicit_bzero(data, data_len);
1755 free(data);
1756 return 0;
1755}
1757}
1756static void
1758static int
1757client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
1758{
1759 u_int data_len;
1760 char *data = packet_get_string(&data_len);
1761 packet_check_eom();
1762 buffer_append(&stderr_buffer, data, data_len);
1763 explicit_bzero(data, data_len);
1764 free(data);
1759client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
1760{
1761 u_int data_len;
1762 char *data = packet_get_string(&data_len);
1763 packet_check_eom();
1764 buffer_append(&stderr_buffer, data, data_len);
1765 explicit_bzero(data, data_len);
1766 free(data);
1767 return 0;
1765}
1768}
1766static void
1769static int
1767client_input_exit_status(int type, u_int32_t seq, void *ctxt)
1768{
1769 exit_status = packet_get_int();
1770 packet_check_eom();
1771 /* Acknowledge the exit. */
1772 packet_start(SSH_CMSG_EXIT_CONFIRMATION);
1773 packet_send();
1774 /*
1775 * Must wait for packet to be sent since we are
1776 * exiting the loop.
1777 */
1778 packet_write_wait();
1779 /* Flag that we want to exit. */
1780 quit_pending = 1;
1770client_input_exit_status(int type, u_int32_t seq, void *ctxt)
1771{
1772 exit_status = packet_get_int();
1773 packet_check_eom();
1774 /* Acknowledge the exit. */
1775 packet_start(SSH_CMSG_EXIT_CONFIRMATION);
1776 packet_send();
1777 /*
1778 * Must wait for packet to be sent since we are
1779 * exiting the loop.
1780 */
1781 packet_write_wait();
1782 /* Flag that we want to exit. */
1783 quit_pending = 1;
1784 return 0;
1781}
1785}
1782static void
1786
1787static int
1783client_input_agent_open(int type, u_int32_t seq, void *ctxt)
1784{
1785 Channel *c = NULL;
1788client_input_agent_open(int type, u_int32_t seq, void *ctxt)
1789{
1790 Channel *c = NULL;
1786 int remote_id, sock;
1791 int r, remote_id, sock;
1787
1788 /* Read the remote channel number from the message. */
1789 remote_id = packet_get_int();
1790 packet_check_eom();
1791
1792 /*
1793 * Get a connection to the local authentication agent (this may again
1794 * get forwarded).
1795 */
1792
1793 /* Read the remote channel number from the message. */
1794 remote_id = packet_get_int();
1795 packet_check_eom();
1796
1797 /*
1798 * Get a connection to the local authentication agent (this may again
1799 * get forwarded).
1800 */
1796 sock = ssh_get_authentication_socket();
1801 if ((r = ssh_get_authentication_socket(&sock)) != 0 &&
1802 r != SSH_ERR_AGENT_NOT_PRESENT)
1803 debug("%s: ssh_get_authentication_socket: %s",
1804 __func__, ssh_err(r));
1797
1805
1806
1798 /*
1799 * If we could not connect the agent, send an error message back to
1800 * the server. This should never happen unless the agent dies,
1801 * because authentication forwarding is only enabled if we have an
1802 * agent.
1803 */
1804 if (sock >= 0) {
1805 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,

--- 7 unchanged lines hidden (view full) ---

1813 } else {
1814 /* Send a confirmation to the remote host. */
1815 debug("Forwarding authentication connection.");
1816 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1817 packet_put_int(remote_id);
1818 packet_put_int(c->self);
1819 }
1820 packet_send();
1807 /*
1808 * If we could not connect the agent, send an error message back to
1809 * the server. This should never happen unless the agent dies,
1810 * because authentication forwarding is only enabled if we have an
1811 * agent.
1812 */
1813 if (sock >= 0) {
1814 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,

--- 7 unchanged lines hidden (view full) ---

1822 } else {
1823 /* Send a confirmation to the remote host. */
1824 debug("Forwarding authentication connection.");
1825 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1826 packet_put_int(remote_id);
1827 packet_put_int(c->self);
1828 }
1829 packet_send();
1830 return 0;
1821}
1822
1823static Channel *
1824client_request_forwarded_tcpip(const char *request_type, int rchan)
1825{
1826 Channel *c = NULL;
1827 char *listen_address, *originator_address;
1828 u_short listen_port, originator_port;

--- 77 unchanged lines hidden (view full) ---

1906 c->force_drain = 1;
1907 return c;
1908}
1909
1910static Channel *
1911client_request_agent(const char *request_type, int rchan)
1912{
1913 Channel *c = NULL;
1831}
1832
1833static Channel *
1834client_request_forwarded_tcpip(const char *request_type, int rchan)
1835{
1836 Channel *c = NULL;
1837 char *listen_address, *originator_address;
1838 u_short listen_port, originator_port;

--- 77 unchanged lines hidden (view full) ---

1916 c->force_drain = 1;
1917 return c;
1918}
1919
1920static Channel *
1921client_request_agent(const char *request_type, int rchan)
1922{
1923 Channel *c = NULL;
1914 int sock;
1924 int r, sock;
1915
1916 if (!options.forward_agent) {
1917 error("Warning: ssh server tried agent forwarding.");
1918 error("Warning: this is probably a break-in attempt by a "
1919 "malicious server.");
1920 return NULL;
1921 }
1925
1926 if (!options.forward_agent) {
1927 error("Warning: ssh server tried agent forwarding.");
1928 error("Warning: this is probably a break-in attempt by a "
1929 "malicious server.");
1930 return NULL;
1931 }
1922 sock = ssh_get_authentication_socket();
1923 if (sock < 0)
1932 if ((r = ssh_get_authentication_socket(&sock)) != 0) {
1933 if (r != SSH_ERR_AGENT_NOT_PRESENT)
1934 debug("%s: ssh_get_authentication_socket: %s",
1935 __func__, ssh_err(r));
1924 return NULL;
1936 return NULL;
1937 }
1925 c = channel_new("authentication agent connection",
1926 SSH_CHANNEL_OPEN, sock, sock, -1,
1927 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
1928 "authentication agent connection", 1);
1929 c->force_drain = 1;
1930 return c;
1931}
1932

--- 37 unchanged lines hidden (view full) ---

1970 packet_put_int(tun_mode);
1971 packet_put_int(remote_tun);
1972 packet_send();
1973
1974 return 0;
1975}
1976
1977/* XXXX move to generic input handler */
1938 c = channel_new("authentication agent connection",
1939 SSH_CHANNEL_OPEN, sock, sock, -1,
1940 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
1941 "authentication agent connection", 1);
1942 c->force_drain = 1;
1943 return c;
1944}
1945

--- 37 unchanged lines hidden (view full) ---

1983 packet_put_int(tun_mode);
1984 packet_put_int(remote_tun);
1985 packet_send();
1986
1987 return 0;
1988}
1989
1990/* XXXX move to generic input handler */
1978static void
1991static int
1979client_input_channel_open(int type, u_int32_t seq, void *ctxt)
1980{
1981 Channel *c = NULL;
1982 char *ctype;
1983 int rchan;
1984 u_int rmaxpack, rwindow, len;
1985
1986 ctype = packet_get_string(&len);

--- 34 unchanged lines hidden (view full) ---

2021 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
2022 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
2023 packet_put_cstring("open failed");
2024 packet_put_cstring("");
2025 }
2026 packet_send();
2027 }
2028 free(ctype);
1992client_input_channel_open(int type, u_int32_t seq, void *ctxt)
1993{
1994 Channel *c = NULL;
1995 char *ctype;
1996 int rchan;
1997 u_int rmaxpack, rwindow, len;
1998
1999 ctype = packet_get_string(&len);

--- 34 unchanged lines hidden (view full) ---

2034 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
2035 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
2036 packet_put_cstring("open failed");
2037 packet_put_cstring("");
2038 }
2039 packet_send();
2040 }
2041 free(ctype);
2042 return 0;
2029}
2043}
2030static void
2044
2045static int
2031client_input_channel_req(int type, u_int32_t seq, void *ctxt)
2032{
2033 Channel *c = NULL;
2034 int exitval, id, reply, success = 0;
2035 char *rtype;
2036
2037 id = packet_get_int();
2038 rtype = packet_get_string(NULL);

--- 28 unchanged lines hidden (view full) ---

2067 }
2068 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
2069 packet_start(success ?
2070 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
2071 packet_put_int(c->remote_id);
2072 packet_send();
2073 }
2074 free(rtype);
2046client_input_channel_req(int type, u_int32_t seq, void *ctxt)
2047{
2048 Channel *c = NULL;
2049 int exitval, id, reply, success = 0;
2050 char *rtype;
2051
2052 id = packet_get_int();
2053 rtype = packet_get_string(NULL);

--- 28 unchanged lines hidden (view full) ---

2082 }
2083 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
2084 packet_start(success ?
2085 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
2086 packet_put_int(c->remote_id);
2087 packet_send();
2088 }
2089 free(rtype);
2090 return 0;
2075}
2091}
2092
2093struct hostkeys_update_ctx {
2094 /* The hostname and (optionally) IP address string for the server */
2095 char *host_str, *ip_str;
2096
2097 /*
2098 * Keys received from the server and a flag for each indicating
2099 * whether they already exist in known_hosts.
2100 * keys_seen is filled in by hostkeys_find() and later (for new
2101 * keys) by client_global_hostkeys_private_confirm().
2102 */
2103 struct sshkey **keys;
2104 int *keys_seen;
2105 size_t nkeys;
2106
2107 size_t nnew;
2108
2109 /*
2110 * Keys that are in known_hosts, but were not present in the update
2111 * from the server (i.e. scheduled to be deleted).
2112 * Filled in by hostkeys_find().
2113 */
2114 struct sshkey **old_keys;
2115 size_t nold;
2116};
2117
2076static void
2118static void
2119hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
2120{
2121 size_t i;
2122
2123 if (ctx == NULL)
2124 return;
2125 for (i = 0; i < ctx->nkeys; i++)
2126 sshkey_free(ctx->keys[i]);
2127 free(ctx->keys);
2128 free(ctx->keys_seen);
2129 for (i = 0; i < ctx->nold; i++)
2130 sshkey_free(ctx->old_keys[i]);
2131 free(ctx->old_keys);
2132 free(ctx->host_str);
2133 free(ctx->ip_str);
2134 free(ctx);
2135}
2136
2137static int
2138hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
2139{
2140 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2141 size_t i;
2142 struct sshkey **tmp;
2143
2144 if (l->status != HKF_STATUS_MATCHED || l->key == NULL ||
2145 l->key->type == KEY_RSA1)
2146 return 0;
2147
2148 /* Mark off keys we've already seen for this host */
2149 for (i = 0; i < ctx->nkeys; i++) {
2150 if (sshkey_equal(l->key, ctx->keys[i])) {
2151 debug3("%s: found %s key at %s:%ld", __func__,
2152 sshkey_ssh_name(ctx->keys[i]), l->path, l->linenum);
2153 ctx->keys_seen[i] = 1;
2154 return 0;
2155 }
2156 }
2157 /* This line contained a key that not offered by the server */
2158 debug3("%s: deprecated %s key at %s:%ld", __func__,
2159 sshkey_ssh_name(l->key), l->path, l->linenum);
2160 if ((tmp = reallocarray(ctx->old_keys, ctx->nold + 1,
2161 sizeof(*ctx->old_keys))) == NULL)
2162 fatal("%s: reallocarray failed nold = %zu",
2163 __func__, ctx->nold);
2164 ctx->old_keys = tmp;
2165 ctx->old_keys[ctx->nold++] = l->key;
2166 l->key = NULL;
2167
2168 return 0;
2169}
2170
2171static void
2172update_known_hosts(struct hostkeys_update_ctx *ctx)
2173{
2174 int r, was_raw = 0;
2175 int loglevel = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK ?
2176 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;
2177 char *fp, *response;
2178 size_t i;
2179
2180 for (i = 0; i < ctx->nkeys; i++) {
2181 if (ctx->keys_seen[i] != 2)
2182 continue;
2183 if ((fp = sshkey_fingerprint(ctx->keys[i],
2184 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
2185 fatal("%s: sshkey_fingerprint failed", __func__);
2186 do_log2(loglevel, "Learned new hostkey: %s %s",
2187 sshkey_type(ctx->keys[i]), fp);
2188 free(fp);
2189 }
2190 for (i = 0; i < ctx->nold; i++) {
2191 if ((fp = sshkey_fingerprint(ctx->old_keys[i],
2192 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
2193 fatal("%s: sshkey_fingerprint failed", __func__);
2194 do_log2(loglevel, "Deprecating obsolete hostkey: %s %s",
2195 sshkey_type(ctx->old_keys[i]), fp);
2196 free(fp);
2197 }
2198 if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
2199 if (get_saved_tio() != NULL) {
2200 leave_raw_mode(1);
2201 was_raw = 1;
2202 }
2203 response = NULL;
2204 for (i = 0; !quit_pending && i < 3; i++) {
2205 free(response);
2206 response = read_passphrase("Accept updated hostkeys? "
2207 "(yes/no): ", RP_ECHO);
2208 if (strcasecmp(response, "yes") == 0)
2209 break;
2210 else if (quit_pending || response == NULL ||
2211 strcasecmp(response, "no") == 0) {
2212 options.update_hostkeys = 0;
2213 break;
2214 } else {
2215 do_log2(loglevel, "Please enter "
2216 "\"yes\" or \"no\"");
2217 }
2218 }
2219 if (quit_pending || i >= 3 || response == NULL)
2220 options.update_hostkeys = 0;
2221 free(response);
2222 if (was_raw)
2223 enter_raw_mode(1);
2224 }
2225
2226 /*
2227 * Now that all the keys are verified, we can go ahead and replace
2228 * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't
2229 * cancel the operation).
2230 */
2231 if (options.update_hostkeys != 0 &&
2232 (r = hostfile_replace_entries(options.user_hostfiles[0],
2233 ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys,
2234 options.hash_known_hosts, 0,
2235 options.fingerprint_hash)) != 0)
2236 error("%s: hostfile_replace_entries failed: %s",
2237 __func__, ssh_err(r));
2238}
2239
2240static void
2241client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx)
2242{
2243 struct ssh *ssh = active_state; /* XXX */
2244 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2245 size_t i, ndone;
2246 struct sshbuf *signdata;
2247 int r;
2248 const u_char *sig;
2249 size_t siglen;
2250
2251 if (ctx->nnew == 0)
2252 fatal("%s: ctx->nnew == 0", __func__); /* sanity */
2253 if (type != SSH2_MSG_REQUEST_SUCCESS) {
2254 error("Server failed to confirm ownership of "
2255 "private host keys");
2256 hostkeys_update_ctx_free(ctx);
2257 return;
2258 }
2259 if ((signdata = sshbuf_new()) == NULL)
2260 fatal("%s: sshbuf_new failed", __func__);
2261 /* Don't want to accidentally accept an unbound signature */
2262 if (ssh->kex->session_id_len == 0)
2263 fatal("%s: ssh->kex->session_id_len == 0", __func__);
2264 /*
2265 * Expect a signature for each of the ctx->nnew private keys we
2266 * haven't seen before. They will be in the same order as the
2267 * ctx->keys where the corresponding ctx->keys_seen[i] == 0.
2268 */
2269 for (ndone = i = 0; i < ctx->nkeys; i++) {
2270 if (ctx->keys_seen[i])
2271 continue;
2272 /* Prepare data to be signed: session ID, unique string, key */
2273 sshbuf_reset(signdata);
2274 if ( (r = sshbuf_put_cstring(signdata,
2275 "hostkeys-prove-00@openssh.com")) != 0 ||
2276 (r = sshbuf_put_string(signdata, ssh->kex->session_id,
2277 ssh->kex->session_id_len)) != 0 ||
2278 (r = sshkey_puts(ctx->keys[i], signdata)) != 0)
2279 fatal("%s: failed to prepare signature: %s",
2280 __func__, ssh_err(r));
2281 /* Extract and verify signature */
2282 if ((r = sshpkt_get_string_direct(ssh, &sig, &siglen)) != 0) {
2283 error("%s: couldn't parse message: %s",
2284 __func__, ssh_err(r));
2285 goto out;
2286 }
2287 if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
2288 sshbuf_ptr(signdata), sshbuf_len(signdata), 0)) != 0) {
2289 error("%s: server gave bad signature for %s key %zu",
2290 __func__, sshkey_type(ctx->keys[i]), i);
2291 goto out;
2292 }
2293 /* Key is good. Mark it as 'seen' */
2294 ctx->keys_seen[i] = 2;
2295 ndone++;
2296 }
2297 if (ndone != ctx->nnew)
2298 fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__,
2299 ndone, ctx->nnew); /* Shouldn't happen */
2300 ssh_packet_check_eom(ssh);
2301
2302 /* Make the edits to known_hosts */
2303 update_known_hosts(ctx);
2304 out:
2305 hostkeys_update_ctx_free(ctx);
2306}
2307
2308/*
2309 * Handle hostkeys-00@openssh.com global request to inform the client of all
2310 * the server's hostkeys. The keys are checked against the user's
2311 * HostkeyAlgorithms preference before they are accepted.
2312 */
2313static int
2314client_input_hostkeys(void)
2315{
2316 struct ssh *ssh = active_state; /* XXX */
2317 const u_char *blob = NULL;
2318 size_t i, len = 0;
2319 struct sshbuf *buf = NULL;
2320 struct sshkey *key = NULL, **tmp;
2321 int r;
2322 char *fp;
2323 static int hostkeys_seen = 0; /* XXX use struct ssh */
2324 extern struct sockaddr_storage hostaddr; /* XXX from ssh.c */
2325 struct hostkeys_update_ctx *ctx = NULL;
2326
2327 if (hostkeys_seen)
2328 fatal("%s: server already sent hostkeys", __func__);
2329 if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK &&
2330 options.batch_mode)
2331 return 1; /* won't ask in batchmode, so don't even try */
2332 if (!options.update_hostkeys || options.num_user_hostfiles <= 0)
2333 return 1;
2334
2335 ctx = xcalloc(1, sizeof(*ctx));
2336 while (ssh_packet_remaining(ssh) > 0) {
2337 sshkey_free(key);
2338 key = NULL;
2339 if ((r = sshpkt_get_string_direct(ssh, &blob, &len)) != 0) {
2340 error("%s: couldn't parse message: %s",
2341 __func__, ssh_err(r));
2342 goto out;
2343 }
2344 if ((r = sshkey_from_blob(blob, len, &key)) != 0) {
2345 error("%s: parse key: %s", __func__, ssh_err(r));
2346 goto out;
2347 }
2348 fp = sshkey_fingerprint(key, options.fingerprint_hash,
2349 SSH_FP_DEFAULT);
2350 debug3("%s: received %s key %s", __func__,
2351 sshkey_type(key), fp);
2352 free(fp);
2353 /* Check that the key is accepted in HostkeyAlgorithms */
2354 if (options.hostkeyalgorithms != NULL &&
2355 match_pattern_list(sshkey_ssh_name(key),
2356 options.hostkeyalgorithms,
2357 strlen(options.hostkeyalgorithms), 0) != 1) {
2358 debug3("%s: %s key not permitted by HostkeyAlgorithms",
2359 __func__, sshkey_ssh_name(key));
2360 continue;
2361 }
2362 /* Skip certs */
2363 if (sshkey_is_cert(key)) {
2364 debug3("%s: %s key is a certificate; skipping",
2365 __func__, sshkey_ssh_name(key));
2366 continue;
2367 }
2368 /* Ensure keys are unique */
2369 for (i = 0; i < ctx->nkeys; i++) {
2370 if (sshkey_equal(key, ctx->keys[i])) {
2371 error("%s: received duplicated %s host key",
2372 __func__, sshkey_ssh_name(key));
2373 goto out;
2374 }
2375 }
2376 /* Key is good, record it */
2377 if ((tmp = reallocarray(ctx->keys, ctx->nkeys + 1,
2378 sizeof(*ctx->keys))) == NULL)
2379 fatal("%s: reallocarray failed nkeys = %zu",
2380 __func__, ctx->nkeys);
2381 ctx->keys = tmp;
2382 ctx->keys[ctx->nkeys++] = key;
2383 key = NULL;
2384 }
2385
2386 if (ctx->nkeys == 0) {
2387 debug("%s: server sent no hostkeys", __func__);
2388 goto out;
2389 }
2390
2391 if ((ctx->keys_seen = calloc(ctx->nkeys,
2392 sizeof(*ctx->keys_seen))) == NULL)
2393 fatal("%s: calloc failed", __func__);
2394
2395 get_hostfile_hostname_ipaddr(host,
2396 options.check_host_ip ? (struct sockaddr *)&hostaddr : NULL,
2397 options.port, &ctx->host_str,
2398 options.check_host_ip ? &ctx->ip_str : NULL);
2399
2400 /* Find which keys we already know about. */
2401 if ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find,
2402 ctx, ctx->host_str, ctx->ip_str,
2403 HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) {
2404 error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r));
2405 goto out;
2406 }
2407
2408 /* Figure out if we have any new keys to add */
2409 ctx->nnew = 0;
2410 for (i = 0; i < ctx->nkeys; i++) {
2411 if (!ctx->keys_seen[i])
2412 ctx->nnew++;
2413 }
2414
2415 debug3("%s: %zu keys from server: %zu new, %zu retained. %zu to remove",
2416 __func__, ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold);
2417
2418 if (ctx->nnew == 0 && ctx->nold != 0) {
2419 /* We have some keys to remove. Just do it. */
2420 update_known_hosts(ctx);
2421 } else if (ctx->nnew != 0) {
2422 /*
2423 * We have received hitherto-unseen keys from the server.
2424 * Ask the server to confirm ownership of the private halves.
2425 */
2426 debug3("%s: asking server to prove ownership for %zu keys",
2427 __func__, ctx->nnew);
2428 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
2429 (r = sshpkt_put_cstring(ssh,
2430 "hostkeys-prove-00@openssh.com")) != 0 ||
2431 (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */
2432 fatal("%s: cannot prepare packet: %s",
2433 __func__, ssh_err(r));
2434 if ((buf = sshbuf_new()) == NULL)
2435 fatal("%s: sshbuf_new", __func__);
2436 for (i = 0; i < ctx->nkeys; i++) {
2437 if (ctx->keys_seen[i])
2438 continue;
2439 sshbuf_reset(buf);
2440 if ((r = sshkey_putb(ctx->keys[i], buf)) != 0)
2441 fatal("%s: sshkey_putb: %s",
2442 __func__, ssh_err(r));
2443 if ((r = sshpkt_put_stringb(ssh, buf)) != 0)
2444 fatal("%s: sshpkt_put_string: %s",
2445 __func__, ssh_err(r));
2446 }
2447 if ((r = sshpkt_send(ssh)) != 0)
2448 fatal("%s: sshpkt_send: %s", __func__, ssh_err(r));
2449 client_register_global_confirm(
2450 client_global_hostkeys_private_confirm, ctx);
2451 ctx = NULL; /* will be freed in callback */
2452 }
2453
2454 /* Success */
2455 out:
2456 hostkeys_update_ctx_free(ctx);
2457 sshkey_free(key);
2458 sshbuf_free(buf);
2459 /*
2460 * NB. Return success for all cases. The server doesn't need to know
2461 * what the client does with its hosts file.
2462 */
2463 return 1;
2464}
2465
2466static int
2077client_input_global_request(int type, u_int32_t seq, void *ctxt)
2078{
2079 char *rtype;
2080 int want_reply;
2081 int success = 0;
2082
2467client_input_global_request(int type, u_int32_t seq, void *ctxt)
2468{
2469 char *rtype;
2470 int want_reply;
2471 int success = 0;
2472
2083 rtype = packet_get_string(NULL);
2473 rtype = packet_get_cstring(NULL);
2084 want_reply = packet_get_char();
2085 debug("client_input_global_request: rtype %s want_reply %d",
2086 rtype, want_reply);
2474 want_reply = packet_get_char();
2475 debug("client_input_global_request: rtype %s want_reply %d",
2476 rtype, want_reply);
2477 if (strcmp(rtype, "hostkeys-00@openssh.com") == 0)
2478 success = client_input_hostkeys();
2087 if (want_reply) {
2088 packet_start(success ?
2089 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
2090 packet_send();
2091 packet_write_wait();
2092 }
2093 free(rtype);
2479 if (want_reply) {
2480 packet_start(success ?
2481 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
2482 packet_send();
2483 packet_write_wait();
2484 }
2485 free(rtype);
2486 return 0;
2094}
2095
2096void
2097client_session2_setup(int id, int want_tty, int want_subsystem,
2098 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)
2099{
2100 int len;
2101 Channel *c = NULL;

--- 183 unchanged lines hidden ---
2487}
2488
2489void
2490client_session2_setup(int id, int want_tty, int want_subsystem,
2491 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)
2492{
2493 int len;
2494 Channel *c = NULL;

--- 183 unchanged lines hidden ---