diff options
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/channels.c b/channels.c index b8507ca13..707b57d86 100644 --- a/channels.c +++ b/channels.c | |||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: channels.c,v 1.214 2005/03/14 11:46:56 markus Exp $"); | 42 | RCSID("$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" |
@@ -111,6 +111,9 @@ static int all_opens_permitted = 0; | |||
111 | /* Maximum number of fake X11 displays to try. */ | 111 | /* Maximum number of fake X11 displays to try. */ |
112 | #define MAX_DISPLAYS 1000 | 112 | #define MAX_DISPLAYS 1000 |
113 | 113 | ||
114 | /* Saved X11 local (client) display. */ | ||
115 | static char *x11_saved_display = NULL; | ||
116 | |||
114 | /* Saved X11 authentication protocol name. */ | 117 | /* Saved X11 authentication protocol name. */ |
115 | static char *x11_saved_proto = NULL; | 118 | static char *x11_saved_proto = NULL; |
116 | 119 | ||
@@ -727,8 +730,8 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset) | |||
727 | FD_SET(c->wfd, writeset); | 730 | FD_SET(c->wfd, writeset); |
728 | } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { | 731 | } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { |
729 | if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) | 732 | if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) |
730 | debug2("channel %d: obuf_empty delayed efd %d/(%d)", | 733 | debug2("channel %d: obuf_empty delayed efd %d/(%d)", |
731 | c->self, c->efd, buffer_len(&c->extended)); | 734 | c->self, c->efd, buffer_len(&c->extended)); |
732 | else | 735 | else |
733 | chan_obuf_empty(c); | 736 | chan_obuf_empty(c); |
734 | } | 737 | } |
@@ -894,7 +897,7 @@ static int | |||
894 | channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) | 897 | channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) |
895 | { | 898 | { |
896 | char *p, *host; | 899 | char *p, *host; |
897 | int len, have, i, found; | 900 | u_int len, have, i, found; |
898 | char username[256]; | 901 | char username[256]; |
899 | struct { | 902 | struct { |
900 | u_int8_t version; | 903 | u_int8_t version; |
@@ -979,7 +982,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset) | |||
979 | } s5_req, s5_rsp; | 982 | } s5_req, s5_rsp; |
980 | u_int16_t dest_port; | 983 | u_int16_t dest_port; |
981 | u_char *p, dest_addr[255+1]; | 984 | u_char *p, dest_addr[255+1]; |
982 | int i, have, found, nmethods, addrlen, af; | 985 | u_int have, i, found, nmethods, addrlen, af; |
983 | 986 | ||
984 | debug2("channel %d: decode socks5", c->self); | 987 | debug2("channel %d: decode socks5", c->self); |
985 | p = buffer_ptr(&c->input); | 988 | p = buffer_ptr(&c->input); |
@@ -1075,7 +1078,8 @@ static void | |||
1075 | channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) | 1078 | channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) |
1076 | { | 1079 | { |
1077 | u_char *p; | 1080 | u_char *p; |
1078 | int have, ret; | 1081 | u_int have; |
1082 | int ret; | ||
1079 | 1083 | ||
1080 | have = buffer_len(&c->input); | 1084 | have = buffer_len(&c->input); |
1081 | c->delayed = 0; | 1085 | c->delayed = 0; |
@@ -1178,7 +1182,7 @@ port_open_helper(Channel *c, char *rtype) | |||
1178 | int direct; | 1182 | int direct; |
1179 | char buf[1024]; | 1183 | char buf[1024]; |
1180 | char *remote_ipaddr = get_peer_ipaddr(c->sock); | 1184 | char *remote_ipaddr = get_peer_ipaddr(c->sock); |
1181 | u_short remote_port = get_peer_port(c->sock); | 1185 | int remote_port = get_peer_port(c->sock); |
1182 | 1186 | ||
1183 | direct = (strcmp(rtype, "direct-tcpip") == 0); | 1187 | direct = (strcmp(rtype, "direct-tcpip") == 0); |
1184 | 1188 | ||
@@ -1208,7 +1212,7 @@ port_open_helper(Channel *c, char *rtype) | |||
1208 | } | 1212 | } |
1209 | /* originator host and port */ | 1213 | /* originator host and port */ |
1210 | packet_put_cstring(remote_ipaddr); | 1214 | packet_put_cstring(remote_ipaddr); |
1211 | packet_put_int(remote_port); | 1215 | packet_put_int((u_int)remote_port); |
1212 | packet_send(); | 1216 | packet_send(); |
1213 | } else { | 1217 | } else { |
1214 | packet_start(SSH_MSG_PORT_OPEN); | 1218 | packet_start(SSH_MSG_PORT_OPEN); |
@@ -1809,8 +1813,8 @@ channel_output_poll(void) | |||
1809 | * hack for extended data: delay EOF if EFD still in use. | 1813 | * hack for extended data: delay EOF if EFD still in use. |
1810 | */ | 1814 | */ |
1811 | if (CHANNEL_EFD_INPUT_ACTIVE(c)) | 1815 | if (CHANNEL_EFD_INPUT_ACTIVE(c)) |
1812 | debug2("channel %d: ibuf_empty delayed efd %d/(%d)", | 1816 | debug2("channel %d: ibuf_empty delayed efd %d/(%d)", |
1813 | c->self, c->efd, buffer_len(&c->extended)); | 1817 | c->self, c->efd, buffer_len(&c->extended)); |
1814 | else | 1818 | else |
1815 | chan_ibuf_empty(c); | 1819 | chan_ibuf_empty(c); |
1816 | } | 1820 | } |
@@ -2195,11 +2199,11 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por | |||
2195 | 2199 | ||
2196 | if (host == NULL) { | 2200 | if (host == NULL) { |
2197 | error("No forward host name."); | 2201 | error("No forward host name."); |
2198 | return success; | 2202 | return 0; |
2199 | } | 2203 | } |
2200 | if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { | 2204 | if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { |
2201 | error("Forward host name too long."); | 2205 | error("Forward host name too long."); |
2202 | return success; | 2206 | return 0; |
2203 | } | 2207 | } |
2204 | 2208 | ||
2205 | /* | 2209 | /* |
@@ -2250,12 +2254,10 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por | |||
2250 | packet_disconnect("getaddrinfo: fatal error: %s", | 2254 | packet_disconnect("getaddrinfo: fatal error: %s", |
2251 | gai_strerror(r)); | 2255 | gai_strerror(r)); |
2252 | } else { | 2256 | } else { |
2253 | verbose("channel_setup_fwd_listener: " | 2257 | error("channel_setup_fwd_listener: " |
2254 | "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); | ||
2255 | packet_send_debug("channel_setup_fwd_listener: " | ||
2256 | "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); | 2258 | "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); |
2257 | } | 2259 | } |
2258 | aitop = NULL; | 2260 | return 0; |
2259 | } | 2261 | } |
2260 | 2262 | ||
2261 | for (ai = aitop; ai; ai = ai->ai_next) { | 2263 | for (ai = aitop; ai; ai = ai->ai_next) { |
@@ -2657,7 +2659,7 @@ channel_send_window_changes(void) | |||
2657 | */ | 2659 | */ |
2658 | int | 2660 | int |
2659 | x11_create_display_inet(int x11_display_offset, int x11_use_localhost, | 2661 | x11_create_display_inet(int x11_display_offset, int x11_use_localhost, |
2660 | int single_connection, u_int *display_numberp) | 2662 | int single_connection, u_int *display_numberp, int **chanids) |
2661 | { | 2663 | { |
2662 | Channel *nc = NULL; | 2664 | Channel *nc = NULL; |
2663 | int display_number, sock; | 2665 | int display_number, sock; |
@@ -2751,6 +2753,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, | |||
2751 | } | 2753 | } |
2752 | 2754 | ||
2753 | /* Allocate a channel for each socket. */ | 2755 | /* Allocate a channel for each socket. */ |
2756 | if (chanids != NULL) | ||
2757 | *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); | ||
2754 | for (n = 0; n < num_socks; n++) { | 2758 | for (n = 0; n < num_socks; n++) { |
2755 | sock = socks[n]; | 2759 | sock = socks[n]; |
2756 | nc = channel_new("x11 listener", | 2760 | nc = channel_new("x11 listener", |
@@ -2758,7 +2762,11 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, | |||
2758 | CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, | 2762 | CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, |
2759 | 0, "X11 inet listener", 1); | 2763 | 0, "X11 inet listener", 1); |
2760 | nc->single_connection = single_connection; | 2764 | nc->single_connection = single_connection; |
2765 | if (*chanids != NULL) | ||
2766 | (*chanids)[n] = nc->self; | ||
2761 | } | 2767 | } |
2768 | if (*chanids != NULL) | ||
2769 | (*chanids)[n] = -1; | ||
2762 | 2770 | ||
2763 | /* Return the display number for the DISPLAY environment variable. */ | 2771 | /* Return the display number for the DISPLAY environment variable. */ |
2764 | *display_numberp = display_number; | 2772 | *display_numberp = display_number; |
@@ -2956,19 +2964,27 @@ deny_input_open(int type, u_int32_t seq, void *ctxt) | |||
2956 | * This should be called in the client only. | 2964 | * This should be called in the client only. |
2957 | */ | 2965 | */ |
2958 | void | 2966 | void |
2959 | x11_request_forwarding_with_spoofing(int client_session_id, | 2967 | x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, |
2960 | const char *proto, const char *data) | 2968 | const char *proto, const char *data) |
2961 | { | 2969 | { |
2962 | u_int data_len = (u_int) strlen(data) / 2; | 2970 | u_int data_len = (u_int) strlen(data) / 2; |
2963 | u_int i, value, len; | 2971 | u_int i, value; |
2964 | char *new_data; | 2972 | char *new_data; |
2965 | int screen_number; | 2973 | int screen_number; |
2966 | const char *cp; | 2974 | const char *cp; |
2967 | u_int32_t rnd = 0; | 2975 | u_int32_t rnd = 0; |
2968 | 2976 | ||
2969 | cp = getenv("DISPLAY"); | 2977 | if (x11_saved_display == NULL) |
2970 | if (cp) | 2978 | x11_saved_display = xstrdup(disp); |
2971 | cp = strchr(cp, ':'); | 2979 | else if (strcmp(disp, x11_saved_display) != 0) { |
2980 | error("x11_request_forwarding_with_spoofing: different " | ||
2981 | "$DISPLAY already forwarded"); | ||
2982 | return; | ||
2983 | } | ||
2984 | |||
2985 | cp = disp; | ||
2986 | if (disp) | ||
2987 | cp = strchr(disp, ':'); | ||
2972 | if (cp) | 2988 | if (cp) |
2973 | cp = strchr(cp, '.'); | 2989 | cp = strchr(cp, '.'); |
2974 | if (cp) | 2990 | if (cp) |
@@ -2976,33 +2992,31 @@ x11_request_forwarding_with_spoofing(int client_session_id, | |||
2976 | else | 2992 | else |
2977 | screen_number = 0; | 2993 | screen_number = 0; |
2978 | 2994 | ||
2979 | /* Save protocol name. */ | 2995 | if (x11_saved_proto == NULL) { |
2980 | x11_saved_proto = xstrdup(proto); | 2996 | /* Save protocol name. */ |
2981 | 2997 | x11_saved_proto = xstrdup(proto); | |
2982 | /* | 2998 | /* |
2983 | * Extract real authentication data and generate fake data of the | 2999 | * Extract real authentication data and generate fake data |
2984 | * same length. | 3000 | * of the same length. |
2985 | */ | 3001 | */ |
2986 | x11_saved_data = xmalloc(data_len); | 3002 | x11_saved_data = xmalloc(data_len); |
2987 | x11_fake_data = xmalloc(data_len); | 3003 | x11_fake_data = xmalloc(data_len); |
2988 | for (i = 0; i < data_len; i++) { | 3004 | for (i = 0; i < data_len; i++) { |
2989 | if (sscanf(data + 2 * i, "%2x", &value) != 1) | 3005 | if (sscanf(data + 2 * i, "%2x", &value) != 1) |
2990 | fatal("x11_request_forwarding: bad authentication data: %.100s", data); | 3006 | fatal("x11_request_forwarding: bad " |
2991 | if (i % 4 == 0) | 3007 | "authentication data: %.100s", data); |
2992 | rnd = arc4random(); | 3008 | if (i % 4 == 0) |
2993 | x11_saved_data[i] = value; | 3009 | rnd = arc4random(); |
2994 | x11_fake_data[i] = rnd & 0xff; | 3010 | x11_saved_data[i] = value; |
2995 | rnd >>= 8; | 3011 | x11_fake_data[i] = rnd & 0xff; |
2996 | } | 3012 | rnd >>= 8; |
2997 | x11_saved_data_len = data_len; | 3013 | } |
2998 | x11_fake_data_len = data_len; | 3014 | x11_saved_data_len = data_len; |
3015 | x11_fake_data_len = data_len; | ||
3016 | } | ||
2999 | 3017 | ||
3000 | /* Convert the fake data into hex. */ | 3018 | /* Convert the fake data into hex. */ |
3001 | len = 2 * data_len + 1; | 3019 | new_data = tohex(x11_fake_data, data_len); |
3002 | new_data = xmalloc(len); | ||
3003 | for (i = 0; i < data_len; i++) | ||
3004 | snprintf(new_data + 2 * i, len - 2 * i, | ||
3005 | "%02x", (u_char) x11_fake_data[i]); | ||
3006 | 3020 | ||
3007 | /* Send the request packet. */ | 3021 | /* Send the request packet. */ |
3008 | if (compat20) { | 3022 | if (compat20) { |