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