summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c133
1 files changed, 76 insertions, 57 deletions
diff --git a/channels.c b/channels.c
index 1be213bce..8c7b2b369 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.212 2005/03/01 10:09:52 djm Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.223 2005/07/17 07:17:54 djm Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -58,6 +58,8 @@ RCSID("$OpenBSD: channels.c,v 1.212 2005/03/01 10:09:52 djm Exp $");
58 58
59/* -- channel core */ 59/* -- channel core */
60 60
61#define CHAN_RBUF 16*1024
62
61/* 63/*
62 * Pointer to an array containing all allocated channels. The array is 64 * Pointer to an array containing all allocated channels. The array is
63 * dynamically extended as needed. 65 * dynamically extended as needed.
@@ -109,6 +111,9 @@ static int all_opens_permitted = 0;
109/* Maximum number of fake X11 displays to try. */ 111/* Maximum number of fake X11 displays to try. */
110#define MAX_DISPLAYS 1000 112#define MAX_DISPLAYS 1000
111 113
114/* Saved X11 local (client) display. */
115static char *x11_saved_display = NULL;
116
112/* Saved X11 authentication protocol name. */ 117/* Saved X11 authentication protocol name. */
113static char *x11_saved_proto = NULL; 118static char *x11_saved_proto = NULL;
114 119
@@ -712,6 +717,9 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
712{ 717{
713 u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); 718 u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
714 719
720 /* check buffer limits */
721 limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
722
715 if (c->istate == CHAN_INPUT_OPEN && 723 if (c->istate == CHAN_INPUT_OPEN &&
716 limit > 0 && 724 limit > 0 &&
717 buffer_len(&c->input) < limit) 725 buffer_len(&c->input) < limit)
@@ -722,8 +730,8 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
722 FD_SET(c->wfd, writeset); 730 FD_SET(c->wfd, writeset);
723 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 731 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
724 if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) 732 if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
725 debug2("channel %d: obuf_empty delayed efd %d/(%d)", 733 debug2("channel %d: obuf_empty delayed efd %d/(%d)",
726 c->self, c->efd, buffer_len(&c->extended)); 734 c->self, c->efd, buffer_len(&c->extended));
727 else 735 else
728 chan_obuf_empty(c); 736 chan_obuf_empty(c);
729 } 737 }
@@ -889,7 +897,7 @@ static int
889channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) 897channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
890{ 898{
891 char *p, *host; 899 char *p, *host;
892 int len, have, i, found; 900 u_int len, have, i, found;
893 char username[256]; 901 char username[256];
894 struct { 902 struct {
895 u_int8_t version; 903 u_int8_t version;
@@ -974,7 +982,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
974 } s5_req, s5_rsp; 982 } s5_req, s5_rsp;
975 u_int16_t dest_port; 983 u_int16_t dest_port;
976 u_char *p, dest_addr[255+1]; 984 u_char *p, dest_addr[255+1];
977 int i, have, found, nmethods, addrlen, af; 985 u_int have, i, found, nmethods, addrlen, af;
978 986
979 debug2("channel %d: decode socks5", c->self); 987 debug2("channel %d: decode socks5", c->self);
980 p = buffer_ptr(&c->input); 988 p = buffer_ptr(&c->input);
@@ -1018,7 +1026,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1018 debug2("channel %d: only socks5 connect supported", c->self); 1026 debug2("channel %d: only socks5 connect supported", c->self);
1019 return -1; 1027 return -1;
1020 } 1028 }
1021 switch(s5_req.atyp){ 1029 switch (s5_req.atyp){
1022 case SSH_SOCKS5_IPV4: 1030 case SSH_SOCKS5_IPV4:
1023 addrlen = 4; 1031 addrlen = 4;
1024 af = AF_INET; 1032 af = AF_INET;
@@ -1070,7 +1078,8 @@ static void
1070channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) 1078channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
1071{ 1079{
1072 u_char *p; 1080 u_char *p;
1073 int have, ret; 1081 u_int have;
1082 int ret;
1074 1083
1075 have = buffer_len(&c->input); 1084 have = buffer_len(&c->input);
1076 c->delayed = 0; 1085 c->delayed = 0;
@@ -1173,7 +1182,7 @@ port_open_helper(Channel *c, char *rtype)
1173 int direct; 1182 int direct;
1174 char buf[1024]; 1183 char buf[1024];
1175 char *remote_ipaddr = get_peer_ipaddr(c->sock); 1184 char *remote_ipaddr = get_peer_ipaddr(c->sock);
1176 u_short remote_port = get_peer_port(c->sock); 1185 int remote_port = get_peer_port(c->sock);
1177 1186
1178 direct = (strcmp(rtype, "direct-tcpip") == 0); 1187 direct = (strcmp(rtype, "direct-tcpip") == 0);
1179 1188
@@ -1203,7 +1212,7 @@ port_open_helper(Channel *c, char *rtype)
1203 } 1212 }
1204 /* originator host and port */ 1213 /* originator host and port */
1205 packet_put_cstring(remote_ipaddr); 1214 packet_put_cstring(remote_ipaddr);
1206 packet_put_int(remote_port); 1215 packet_put_int((u_int)remote_port);
1207 packet_send(); 1216 packet_send();
1208 } else { 1217 } else {
1209 packet_start(SSH_MSG_PORT_OPEN); 1218 packet_start(SSH_MSG_PORT_OPEN);
@@ -1360,7 +1369,7 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
1360static int 1369static int
1361channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) 1370channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
1362{ 1371{
1363 char buf[16*1024]; 1372 char buf[CHAN_RBUF];
1364 int len; 1373 int len;
1365 1374
1366 if (c->rfd != -1 && 1375 if (c->rfd != -1 &&
@@ -1454,7 +1463,7 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1454static int 1463static int
1455channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) 1464channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
1456{ 1465{
1457 char buf[16*1024]; 1466 char buf[CHAN_RBUF];
1458 int len; 1467 int len;
1459 1468
1460/** XXX handle drain efd, too */ 1469/** XXX handle drain efd, too */
@@ -1804,8 +1813,8 @@ channel_output_poll(void)
1804 * hack for extended data: delay EOF if EFD still in use. 1813 * hack for extended data: delay EOF if EFD still in use.
1805 */ 1814 */
1806 if (CHANNEL_EFD_INPUT_ACTIVE(c)) 1815 if (CHANNEL_EFD_INPUT_ACTIVE(c))
1807 debug2("channel %d: ibuf_empty delayed efd %d/(%d)", 1816 debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
1808 c->self, c->efd, buffer_len(&c->extended)); 1817 c->self, c->efd, buffer_len(&c->extended));
1809 else 1818 else
1810 chan_ibuf_empty(c); 1819 chan_ibuf_empty(c);
1811 } 1820 }
@@ -2190,20 +2199,20 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2190 2199
2191 if (host == NULL) { 2200 if (host == NULL) {
2192 error("No forward host name."); 2201 error("No forward host name.");
2193 return success; 2202 return 0;
2194 } 2203 }
2195 if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { 2204 if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
2196 error("Forward host name too long."); 2205 error("Forward host name too long.");
2197 return success; 2206 return 0;
2198 } 2207 }
2199 2208
2200 /* 2209 /*
2201 * Determine whether or not a port forward listens to loopback, 2210 * Determine whether or not a port forward listens to loopback,
2202 * specified address or wildcard. On the client, a specified bind 2211 * specified address or wildcard. On the client, a specified bind
2203 * address will always override gateway_ports. On the server, a 2212 * address will always override gateway_ports. On the server, a
2204 * gateway_ports of 1 (``yes'') will override the client's 2213 * gateway_ports of 1 (``yes'') will override the client's
2205 * specification and force a wildcard bind, whereas a value of 2 2214 * specification and force a wildcard bind, whereas a value of 2
2206 * (``clientspecified'') will bind to whatever address the client 2215 * (``clientspecified'') will bind to whatever address the client
2207 * asked for. 2216 * asked for.
2208 * 2217 *
2209 * Special-case listen_addrs are: 2218 * Special-case listen_addrs are:
@@ -2245,12 +2254,10 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2245 packet_disconnect("getaddrinfo: fatal error: %s", 2254 packet_disconnect("getaddrinfo: fatal error: %s",
2246 gai_strerror(r)); 2255 gai_strerror(r));
2247 } else { 2256 } else {
2248 verbose("channel_setup_fwd_listener: " 2257 error("channel_setup_fwd_listener: "
2249 "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
2250 packet_send_debug("channel_setup_fwd_listener: "
2251 "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); 2258 "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
2252 } 2259 }
2253 aitop = NULL; 2260 return 0;
2254 } 2261 }
2255 2262
2256 for (ai = aitop; ai; ai = ai->ai_next) { 2263 for (ai = aitop; ai; ai = ai->ai_next) {
@@ -2317,7 +2324,7 @@ channel_cancel_rport_listener(const char *host, u_short port)
2317 u_int i; 2324 u_int i;
2318 int found = 0; 2325 int found = 0;
2319 2326
2320 for(i = 0; i < channels_alloc; i++) { 2327 for (i = 0; i < channels_alloc; i++) {
2321 Channel *c = channels[i]; 2328 Channel *c = channels[i];
2322 2329
2323 if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && 2330 if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
@@ -2629,7 +2636,7 @@ channel_send_window_changes(void)
2629 struct winsize ws; 2636 struct winsize ws;
2630 2637
2631 for (i = 0; i < channels_alloc; i++) { 2638 for (i = 0; i < channels_alloc; i++) {
2632 if (channels[i] == NULL || !channels[i]->client_tty || 2639 if (channels[i] == NULL || !channels[i]->client_tty ||
2633 channels[i]->type != SSH_CHANNEL_OPEN) 2640 channels[i]->type != SSH_CHANNEL_OPEN)
2634 continue; 2641 continue;
2635 if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) 2642 if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
@@ -2652,7 +2659,7 @@ channel_send_window_changes(void)
2652 */ 2659 */
2653int 2660int
2654x11_create_display_inet(int x11_display_offset, int x11_use_localhost, 2661x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2655 int single_connection, u_int *display_numberp) 2662 int single_connection, u_int *display_numberp, int **chanids)
2656{ 2663{
2657 Channel *nc = NULL; 2664 Channel *nc = NULL;
2658 int display_number, sock; 2665 int display_number, sock;
@@ -2742,6 +2749,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2742 } 2749 }
2743 2750
2744 /* Allocate a channel for each socket. */ 2751 /* Allocate a channel for each socket. */
2752 if (chanids != NULL)
2753 *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1));
2745 for (n = 0; n < num_socks; n++) { 2754 for (n = 0; n < num_socks; n++) {
2746 sock = socks[n]; 2755 sock = socks[n];
2747 nc = channel_new("x11 listener", 2756 nc = channel_new("x11 listener",
@@ -2749,7 +2758,11 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2749 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 2758 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
2750 0, "X11 inet listener", 1); 2759 0, "X11 inet listener", 1);
2751 nc->single_connection = single_connection; 2760 nc->single_connection = single_connection;
2761 if (*chanids != NULL)
2762 (*chanids)[n] = nc->self;
2752 } 2763 }
2764 if (*chanids != NULL)
2765 (*chanids)[n] = -1;
2753 2766
2754 /* Return the display number for the DISPLAY environment variable. */ 2767 /* Return the display number for the DISPLAY environment variable. */
2755 *display_numberp = display_number; 2768 *display_numberp = display_number;
@@ -2947,19 +2960,27 @@ deny_input_open(int type, u_int32_t seq, void *ctxt)
2947 * This should be called in the client only. 2960 * This should be called in the client only.
2948 */ 2961 */
2949void 2962void
2950x11_request_forwarding_with_spoofing(int client_session_id, 2963x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
2951 const char *proto, const char *data) 2964 const char *proto, const char *data)
2952{ 2965{
2953 u_int data_len = (u_int) strlen(data) / 2; 2966 u_int data_len = (u_int) strlen(data) / 2;
2954 u_int i, value, len; 2967 u_int i, value;
2955 char *new_data; 2968 char *new_data;
2956 int screen_number; 2969 int screen_number;
2957 const char *cp; 2970 const char *cp;
2958 u_int32_t rnd = 0; 2971 u_int32_t rnd = 0;
2959 2972
2960 cp = getenv("DISPLAY"); 2973 if (x11_saved_display == NULL)
2961 if (cp) 2974 x11_saved_display = xstrdup(disp);
2962 cp = strchr(cp, ':'); 2975 else if (strcmp(disp, x11_saved_display) != 0) {
2976 error("x11_request_forwarding_with_spoofing: different "
2977 "$DISPLAY already forwarded");
2978 return;
2979 }
2980
2981 cp = disp;
2982 if (disp)
2983 cp = strchr(disp, ':');
2963 if (cp) 2984 if (cp)
2964 cp = strchr(cp, '.'); 2985 cp = strchr(cp, '.');
2965 if (cp) 2986 if (cp)
@@ -2967,33 +2988,31 @@ x11_request_forwarding_with_spoofing(int client_session_id,
2967 else 2988 else
2968 screen_number = 0; 2989 screen_number = 0;
2969 2990
2970 /* Save protocol name. */ 2991 if (x11_saved_proto == NULL) {
2971 x11_saved_proto = xstrdup(proto); 2992 /* Save protocol name. */
2972 2993 x11_saved_proto = xstrdup(proto);
2973 /* 2994 /*
2974 * Extract real authentication data and generate fake data of the 2995 * Extract real authentication data and generate fake data
2975 * same length. 2996 * of the same length.
2976 */ 2997 */
2977 x11_saved_data = xmalloc(data_len); 2998 x11_saved_data = xmalloc(data_len);
2978 x11_fake_data = xmalloc(data_len); 2999 x11_fake_data = xmalloc(data_len);
2979 for (i = 0; i < data_len; i++) { 3000 for (i = 0; i < data_len; i++) {
2980 if (sscanf(data + 2 * i, "%2x", &value) != 1) 3001 if (sscanf(data + 2 * i, "%2x", &value) != 1)
2981 fatal("x11_request_forwarding: bad authentication data: %.100s", data); 3002 fatal("x11_request_forwarding: bad "
2982 if (i % 4 == 0) 3003 "authentication data: %.100s", data);
2983 rnd = arc4random(); 3004 if (i % 4 == 0)
2984 x11_saved_data[i] = value; 3005 rnd = arc4random();
2985 x11_fake_data[i] = rnd & 0xff; 3006 x11_saved_data[i] = value;
2986 rnd >>= 8; 3007 x11_fake_data[i] = rnd & 0xff;
2987 } 3008 rnd >>= 8;
2988 x11_saved_data_len = data_len; 3009 }
2989 x11_fake_data_len = data_len; 3010 x11_saved_data_len = data_len;
3011 x11_fake_data_len = data_len;
3012 }
2990 3013
2991 /* Convert the fake data into hex. */ 3014 /* Convert the fake data into hex. */
2992 len = 2 * data_len + 1; 3015 new_data = tohex(x11_fake_data, data_len);
2993 new_data = xmalloc(len);
2994 for (i = 0; i < data_len; i++)
2995 snprintf(new_data + 2 * i, len - 2 * i,
2996 "%02x", (u_char) x11_fake_data[i]);
2997 3016
2998 /* Send the request packet. */ 3017 /* Send the request packet. */
2999 if (compat20) { 3018 if (compat20) {