diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 73 |
1 files changed, 52 insertions, 21 deletions
diff --git a/clientloop.c b/clientloop.c index e5cc3f8cb..5876cc9af 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.286 2016/07/23 02:54:08 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.289 2016/09/30 09:19:13 markus 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 |
@@ -61,7 +61,6 @@ | |||
61 | 61 | ||
62 | #include "includes.h" | 62 | #include "includes.h" |
63 | 63 | ||
64 | #include <sys/param.h> /* MIN MAX */ | ||
65 | #include <sys/types.h> | 64 | #include <sys/types.h> |
66 | #include <sys/ioctl.h> | 65 | #include <sys/ioctl.h> |
67 | #ifdef HAVE_SYS_STAT_H | 66 | #ifdef HAVE_SYS_STAT_H |
@@ -316,7 +315,7 @@ client_x11_get_proto(const char *display, const char *xauth_path, | |||
316 | char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; | 315 | char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; |
317 | static char proto[512], data[512]; | 316 | static char proto[512], data[512]; |
318 | FILE *f; | 317 | FILE *f; |
319 | int got_data = 0, generated = 0, do_unlink = 0, i, r; | 318 | int got_data = 0, generated = 0, do_unlink = 0, r; |
320 | struct stat st; | 319 | struct stat st; |
321 | u_int now, x11_timeout_real; | 320 | u_int now, x11_timeout_real; |
322 | 321 | ||
@@ -443,17 +442,16 @@ client_x11_get_proto(const char *display, const char *xauth_path, | |||
443 | * for the local connection. | 442 | * for the local connection. |
444 | */ | 443 | */ |
445 | if (!got_data) { | 444 | if (!got_data) { |
446 | u_int32_t rnd = 0; | 445 | u_int8_t rnd[16]; |
446 | u_int i; | ||
447 | 447 | ||
448 | logit("Warning: No xauth data; " | 448 | logit("Warning: No xauth data; " |
449 | "using fake authentication data for X11 forwarding."); | 449 | "using fake authentication data for X11 forwarding."); |
450 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); | 450 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); |
451 | for (i = 0; i < 16; i++) { | 451 | arc4random_buf(rnd, sizeof(rnd)); |
452 | if (i % 4 == 0) | 452 | for (i = 0; i < sizeof(rnd); i++) { |
453 | rnd = arc4random(); | ||
454 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", | 453 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", |
455 | rnd & 0xff); | 454 | rnd[i]); |
456 | rnd >>= 8; | ||
457 | } | 455 | } |
458 | } | 456 | } |
459 | 457 | ||
@@ -676,16 +674,16 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | |||
676 | server_alive_time = now + options.server_alive_interval; | 674 | server_alive_time = now + options.server_alive_interval; |
677 | } | 675 | } |
678 | if (options.rekey_interval > 0 && compat20 && !rekeying) | 676 | if (options.rekey_interval > 0 && compat20 && !rekeying) |
679 | timeout_secs = MIN(timeout_secs, packet_get_rekey_timeout()); | 677 | timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); |
680 | set_control_persist_exit_time(); | 678 | set_control_persist_exit_time(); |
681 | if (control_persist_exit_time > 0) { | 679 | if (control_persist_exit_time > 0) { |
682 | timeout_secs = MIN(timeout_secs, | 680 | timeout_secs = MINIMUM(timeout_secs, |
683 | control_persist_exit_time - now); | 681 | control_persist_exit_time - now); |
684 | if (timeout_secs < 0) | 682 | if (timeout_secs < 0) |
685 | timeout_secs = 0; | 683 | timeout_secs = 0; |
686 | } | 684 | } |
687 | if (minwait_secs != 0) | 685 | if (minwait_secs != 0) |
688 | timeout_secs = MIN(timeout_secs, (int)minwait_secs); | 686 | timeout_secs = MINIMUM(timeout_secs, (int)minwait_secs); |
689 | if (timeout_secs == INT_MAX) | 687 | if (timeout_secs == INT_MAX) |
690 | tvp = NULL; | 688 | tvp = NULL; |
691 | else { | 689 | else { |
@@ -1557,7 +1555,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1557 | buffer_high = 64 * 1024; | 1555 | buffer_high = 64 * 1024; |
1558 | connection_in = packet_get_connection_in(); | 1556 | connection_in = packet_get_connection_in(); |
1559 | connection_out = packet_get_connection_out(); | 1557 | connection_out = packet_get_connection_out(); |
1560 | max_fd = MAX(connection_in, connection_out); | 1558 | max_fd = MAXIMUM(connection_in, connection_out); |
1561 | 1559 | ||
1562 | if (!compat20) { | 1560 | if (!compat20) { |
1563 | /* enable nonblocking unless tty */ | 1561 | /* enable nonblocking unless tty */ |
@@ -1567,9 +1565,9 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1567 | set_nonblock(fileno(stdout)); | 1565 | set_nonblock(fileno(stdout)); |
1568 | if (!isatty(fileno(stderr))) | 1566 | if (!isatty(fileno(stderr))) |
1569 | set_nonblock(fileno(stderr)); | 1567 | set_nonblock(fileno(stderr)); |
1570 | max_fd = MAX(max_fd, fileno(stdin)); | 1568 | max_fd = MAXIMUM(max_fd, fileno(stdin)); |
1571 | max_fd = MAX(max_fd, fileno(stdout)); | 1569 | max_fd = MAXIMUM(max_fd, fileno(stdout)); |
1572 | max_fd = MAX(max_fd, fileno(stderr)); | 1570 | max_fd = MAXIMUM(max_fd, fileno(stderr)); |
1573 | } | 1571 | } |
1574 | quit_pending = 0; | 1572 | quit_pending = 0; |
1575 | escape_char1 = escape_char_arg; | 1573 | escape_char1 = escape_char_arg; |
@@ -1900,11 +1898,14 @@ client_input_agent_open(int type, u_int32_t seq, void *ctxt) | |||
1900 | } | 1898 | } |
1901 | 1899 | ||
1902 | static Channel * | 1900 | static Channel * |
1903 | client_request_forwarded_tcpip(const char *request_type, int rchan) | 1901 | client_request_forwarded_tcpip(const char *request_type, int rchan, |
1902 | u_int rwindow, u_int rmaxpack) | ||
1904 | { | 1903 | { |
1905 | Channel *c = NULL; | 1904 | Channel *c = NULL; |
1905 | struct sshbuf *b = NULL; | ||
1906 | char *listen_address, *originator_address; | 1906 | char *listen_address, *originator_address; |
1907 | u_short listen_port, originator_port; | 1907 | u_short listen_port, originator_port; |
1908 | int r; | ||
1908 | 1909 | ||
1909 | /* Get rest of the packet */ | 1910 | /* Get rest of the packet */ |
1910 | listen_address = packet_get_string(NULL); | 1911 | listen_address = packet_get_string(NULL); |
@@ -1919,6 +1920,31 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) | |||
1919 | c = channel_connect_by_listen_address(listen_address, listen_port, | 1920 | c = channel_connect_by_listen_address(listen_address, listen_port, |
1920 | "forwarded-tcpip", originator_address); | 1921 | "forwarded-tcpip", originator_address); |
1921 | 1922 | ||
1923 | if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { | ||
1924 | if ((b = sshbuf_new()) == NULL) { | ||
1925 | error("%s: alloc reply", __func__); | ||
1926 | goto out; | ||
1927 | } | ||
1928 | /* reconstruct and send to muxclient */ | ||
1929 | if ((r = sshbuf_put_u8(b, 0)) != 0 || /* padlen */ | ||
1930 | (r = sshbuf_put_u8(b, SSH2_MSG_CHANNEL_OPEN)) != 0 || | ||
1931 | (r = sshbuf_put_cstring(b, request_type)) != 0 || | ||
1932 | (r = sshbuf_put_u32(b, rchan)) != 0 || | ||
1933 | (r = sshbuf_put_u32(b, rwindow)) != 0 || | ||
1934 | (r = sshbuf_put_u32(b, rmaxpack)) != 0 || | ||
1935 | (r = sshbuf_put_cstring(b, listen_address)) != 0 || | ||
1936 | (r = sshbuf_put_u32(b, listen_port)) != 0 || | ||
1937 | (r = sshbuf_put_cstring(b, originator_address)) != 0 || | ||
1938 | (r = sshbuf_put_u32(b, originator_port)) != 0 || | ||
1939 | (r = sshbuf_put_stringb(&c->output, b)) != 0) { | ||
1940 | error("%s: compose for muxclient %s", __func__, | ||
1941 | ssh_err(r)); | ||
1942 | goto out; | ||
1943 | } | ||
1944 | } | ||
1945 | |||
1946 | out: | ||
1947 | sshbuf_free(b); | ||
1922 | free(originator_address); | 1948 | free(originator_address); |
1923 | free(listen_address); | 1949 | free(listen_address); |
1924 | return c; | 1950 | return c; |
@@ -2074,7 +2100,8 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt) | |||
2074 | ctype, rchan, rwindow, rmaxpack); | 2100 | ctype, rchan, rwindow, rmaxpack); |
2075 | 2101 | ||
2076 | if (strcmp(ctype, "forwarded-tcpip") == 0) { | 2102 | if (strcmp(ctype, "forwarded-tcpip") == 0) { |
2077 | c = client_request_forwarded_tcpip(ctype, rchan); | 2103 | c = client_request_forwarded_tcpip(ctype, rchan, rwindow, |
2104 | rmaxpack); | ||
2078 | } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { | 2105 | } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { |
2079 | c = client_request_forwarded_streamlocal(ctype, rchan); | 2106 | c = client_request_forwarded_streamlocal(ctype, rchan); |
2080 | } else if (strcmp(ctype, "x11") == 0) { | 2107 | } else if (strcmp(ctype, "x11") == 0) { |
@@ -2082,8 +2109,9 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt) | |||
2082 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { | 2109 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { |
2083 | c = client_request_agent(ctype, rchan); | 2110 | c = client_request_agent(ctype, rchan); |
2084 | } | 2111 | } |
2085 | /* XXX duplicate : */ | 2112 | if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { |
2086 | if (c != NULL) { | 2113 | debug3("proxied to downstream: %s", ctype); |
2114 | } else if (c != NULL) { | ||
2087 | debug("confirm %s", ctype); | 2115 | debug("confirm %s", ctype); |
2088 | c->remote_id = rchan; | 2116 | c->remote_id = rchan; |
2089 | c->remote_window = rwindow; | 2117 | c->remote_window = rwindow; |
@@ -2119,6 +2147,9 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) | |||
2119 | char *rtype; | 2147 | char *rtype; |
2120 | 2148 | ||
2121 | id = packet_get_int(); | 2149 | id = packet_get_int(); |
2150 | c = channel_lookup(id); | ||
2151 | if (channel_proxy_upstream(c, type, seq, ctxt)) | ||
2152 | return 0; | ||
2122 | rtype = packet_get_string(NULL); | 2153 | rtype = packet_get_string(NULL); |
2123 | reply = packet_get_char(); | 2154 | reply = packet_get_char(); |
2124 | 2155 | ||
@@ -2127,7 +2158,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) | |||
2127 | 2158 | ||
2128 | if (id == -1) { | 2159 | if (id == -1) { |
2129 | error("client_input_channel_req: request for channel -1"); | 2160 | error("client_input_channel_req: request for channel -1"); |
2130 | } else if ((c = channel_lookup(id)) == NULL) { | 2161 | } else if (c == NULL) { |
2131 | error("client_input_channel_req: channel %d: " | 2162 | error("client_input_channel_req: channel %d: " |
2132 | "unknown channel", id); | 2163 | "unknown channel", id); |
2133 | } else if (strcmp(rtype, "eow@openssh.com") == 0) { | 2164 | } else if (strcmp(rtype, "eow@openssh.com") == 0) { |