=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/channels.c,v retrieving revision 1.210.2.3 retrieving revision 1.211 diff -u -r1.210.2.3 -r1.211 --- src/usr.bin/ssh/channels.c 2005/09/02 03:44:59 1.210.2.3 +++ src/usr.bin/ssh/channels.c 2004/10/29 21:47:15 1.211 @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.210.2.3 2005/09/02 03:44:59 brad Exp $"); +RCSID("$OpenBSD: channels.c,v 1.211 2004/10/29 21:47:15 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -58,8 +58,6 @@ /* -- channel core */ -#define CHAN_RBUF 16*1024 - /* * Pointer to an array containing all allocated channels. The array is * dynamically extended as needed. @@ -111,9 +109,6 @@ /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 -/* Saved X11 local (client) display. */ -static char *x11_saved_display = NULL; - /* Saved X11 authentication protocol name. */ static char *x11_saved_proto = NULL; @@ -716,9 +711,6 @@ { u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); - /* check buffer limits */ - limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF)); - if (c->istate == CHAN_INPUT_OPEN && limit > 0 && buffer_len(&c->input) < limit) @@ -729,8 +721,8 @@ FD_SET(c->wfd, writeset); } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) - debug2("channel %d: obuf_empty delayed efd %d/(%d)", - c->self, c->efd, buffer_len(&c->extended)); + debug2("channel %d: obuf_empty delayed efd %d/(%d)", + c->self, c->efd, buffer_len(&c->extended)); else chan_obuf_empty(c); } @@ -896,7 +888,7 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) { char *p, *host; - u_int len, have, i, found; + int len, have, i, found; char username[256]; struct { u_int8_t version; @@ -981,7 +973,7 @@ } s5_req, s5_rsp; u_int16_t dest_port; u_char *p, dest_addr[255+1]; - u_int have, i, found, nmethods, addrlen, af; + int i, have, found, nmethods, addrlen, af; debug2("channel %d: decode socks5", c->self); p = buffer_ptr(&c->input); @@ -1025,7 +1017,7 @@ debug2("channel %d: only socks5 connect supported", c->self); return -1; } - switch (s5_req.atyp){ + switch(s5_req.atyp){ case SSH_SOCKS5_IPV4: addrlen = 4; af = AF_INET; @@ -1077,8 +1069,7 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) { u_char *p; - u_int have; - int ret; + int have, ret; have = buffer_len(&c->input); c->delayed = 0; @@ -1181,7 +1172,7 @@ int direct; char buf[1024]; char *remote_ipaddr = get_peer_ipaddr(c->sock); - int remote_port = get_peer_port(c->sock); + u_short remote_port = get_peer_port(c->sock); direct = (strcmp(rtype, "direct-tcpip") == 0); @@ -1211,7 +1202,7 @@ } /* originator host and port */ packet_put_cstring(remote_ipaddr); - packet_put_int((u_int)remote_port); + packet_put_int(remote_port); packet_send(); } else { packet_start(SSH_MSG_PORT_OPEN); @@ -1368,7 +1359,7 @@ static int channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) { - char buf[CHAN_RBUF]; + char buf[16*1024]; int len; if (c->rfd != -1 && @@ -1457,7 +1448,7 @@ static int channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) { - char buf[CHAN_RBUF]; + char buf[16*1024]; int len; /** XXX handle drain efd, too */ @@ -1807,8 +1798,8 @@ * hack for extended data: delay EOF if EFD still in use. */ if (CHANNEL_EFD_INPUT_ACTIVE(c)) - debug2("channel %d: ibuf_empty delayed efd %d/(%d)", - c->self, c->efd, buffer_len(&c->extended)); + debug2("channel %d: ibuf_empty delayed efd %d/(%d)", + c->self, c->efd, buffer_len(&c->extended)); else chan_ibuf_empty(c); } @@ -2182,77 +2173,35 @@ const char *host_to_connect, u_short port_to_connect, int gateway_ports) { Channel *c; - int sock, r, success = 0, on = 1, wildcard = 0, is_client; + int success, sock, on = 1; struct addrinfo hints, *ai, *aitop; - const char *host, *addr; + const char *host; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + success = 0; host = (type == SSH_CHANNEL_RPORT_LISTENER) ? listen_addr : host_to_connect; - is_client = (type == SSH_CHANNEL_PORT_LISTENER); if (host == NULL) { error("No forward host name."); - return 0; + return success; } if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { error("Forward host name too long."); - return 0; + return success; } /* - * Determine whether or not a port forward listens to loopback, - * specified address or wildcard. On the client, a specified bind - * address will always override gateway_ports. On the server, a - * gateway_ports of 1 (``yes'') will override the client's - * specification and force a wildcard bind, whereas a value of 2 - * (``clientspecified'') will bind to whatever address the client - * asked for. - * - * Special-case listen_addrs are: - * - * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR - * "" (empty string), "*" -> wildcard v4/v6 - * "localhost" -> loopback v4/v6 - */ - addr = NULL; - if (listen_addr == NULL) { - /* No address specified: default to gateway_ports setting */ - if (gateway_ports) - wildcard = 1; - } else if (gateway_ports || is_client) { - if (((datafellows & SSH_OLD_FORWARD_ADDR) && - strcmp(listen_addr, "0.0.0.0") == 0) || - *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || - (!is_client && gateway_ports == 1)) - wildcard = 1; - else if (strcmp(listen_addr, "localhost") != 0) - addr = listen_addr; - } - - debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", - type, wildcard, (addr == NULL) ? "NULL" : addr); - - /* * getaddrinfo returns a loopback address if the hostname is * set to NULL and hints.ai_flags is not AI_PASSIVE */ memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; - hints.ai_flags = wildcard ? AI_PASSIVE : 0; + hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%d", listen_port); - if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) { - if (addr == NULL) { - /* This really shouldn't happen */ - packet_disconnect("getaddrinfo: fatal error: %s", - gai_strerror(r)); - } else { - error("channel_setup_fwd_listener: " - "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); - } - return 0; - } + if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) + packet_disconnect("getaddrinfo: fatal error"); for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) @@ -2314,7 +2263,7 @@ u_int i; int found = 0; - for (i = 0; i < channels_alloc; i++) { + for(i = 0; i < channels_alloc; i++) { Channel *c = channels[i]; if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && @@ -2331,12 +2280,11 @@ /* protocol local port fwd, used by ssh (and sshd in v1) */ int -channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, +channel_setup_local_fwd_listener(u_short listen_port, const char *host_to_connect, u_short port_to_connect, int gateway_ports) { return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, - listen_host, listen_port, host_to_connect, port_to_connect, - gateway_ports); + NULL, listen_port, host_to_connect, port_to_connect, gateway_ports); } /* protocol v2 remote port fwd, used by sshd */ @@ -2354,7 +2302,7 @@ */ void -channel_request_remote_forwarding(const char *listen_host, u_short listen_port, +channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect, u_short port_to_connect) { int type, success = 0; @@ -2365,14 +2313,7 @@ /* Send the forward request to the remote side. */ if (compat20) { - const char *address_to_bind; - if (listen_host == NULL) - address_to_bind = "localhost"; - else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) - address_to_bind = ""; - else - address_to_bind = listen_host; - + const char *address_to_bind = "0.0.0.0"; packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("tcpip-forward"); packet_put_char(1); /* boolean: want reply */ @@ -2418,9 +2359,10 @@ * local side. */ void -channel_request_rforward_cancel(const char *host, u_short port) +channel_request_rforward_cancel(u_short port) { int i; + const char *address_to_bind = "0.0.0.0"; if (!compat20) return; @@ -2437,7 +2379,7 @@ packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("cancel-tcpip-forward"); packet_put_char(0); - packet_put_cstring(host == NULL ? "" : host); + packet_put_cstring(address_to_bind); packet_put_int(port); packet_send(); @@ -2476,8 +2418,7 @@ packet_disconnect("Dynamic forwarding denied."); /* Initiate forwarding */ - channel_setup_local_fwd_listener(NULL, port, hostname, - host_port, gateway_ports); + channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports); /* Free the argument string. */ xfree(hostname); @@ -2624,7 +2565,7 @@ struct winsize ws; for (i = 0; i < channels_alloc; i++) { - if (channels[i] == NULL || !channels[i]->client_tty || + if (channels[i] == NULL || !channels[i]->client_tty || channels[i]->type != SSH_CHANNEL_OPEN) continue; if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) @@ -2647,7 +2588,7 @@ */ int x11_create_display_inet(int x11_display_offset, int x11_use_localhost, - int single_connection, u_int *display_numberp, int **chanids) + int single_connection, u_int *display_numberp) { Channel *nc = NULL; int display_number, sock; @@ -2715,8 +2656,6 @@ } /* Allocate a channel for each socket. */ - if (chanids != NULL) - *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); for (n = 0; n < num_socks; n++) { sock = socks[n]; nc = channel_new("x11 listener", @@ -2724,11 +2663,7 @@ CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "X11 inet listener", 1); nc->single_connection = single_connection; - if (*chanids != NULL) - (*chanids)[n] = nc->self; } - if (*chanids != NULL) - (*chanids)[n] = -1; /* Return the display number for the DISPLAY environment variable. */ *display_numberp = display_number; @@ -2926,59 +2861,53 @@ * This should be called in the client only. */ void -x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, +x11_request_forwarding_with_spoofing(int client_session_id, const char *proto, const char *data) { u_int data_len = (u_int) strlen(data) / 2; - u_int i, value; + u_int i, value, len; char *new_data; int screen_number; const char *cp; u_int32_t rnd = 0; - if (x11_saved_display == NULL) - x11_saved_display = xstrdup(disp); - else if (strcmp(disp, x11_saved_display) != 0) { - error("x11_request_forwarding_with_spoofing: different " - "$DISPLAY already forwarded"); - return; - } - - cp = disp; - if (disp) - cp = strchr(disp, ':'); + cp = getenv("DISPLAY"); if (cp) + cp = strchr(cp, ':'); + if (cp) cp = strchr(cp, '.'); if (cp) screen_number = atoi(cp + 1); else screen_number = 0; - if (x11_saved_proto == NULL) { - /* Save protocol name. */ - x11_saved_proto = xstrdup(proto); - /* - * Extract real authentication data and generate fake data - * of the same length. - */ - x11_saved_data = xmalloc(data_len); - x11_fake_data = xmalloc(data_len); - for (i = 0; i < data_len; i++) { - if (sscanf(data + 2 * i, "%2x", &value) != 1) - fatal("x11_request_forwarding: bad " - "authentication data: %.100s", data); - if (i % 4 == 0) - rnd = arc4random(); - x11_saved_data[i] = value; - x11_fake_data[i] = rnd & 0xff; - rnd >>= 8; - } - x11_saved_data_len = data_len; - x11_fake_data_len = data_len; + /* Save protocol name. */ + x11_saved_proto = xstrdup(proto); + + /* + * Extract real authentication data and generate fake data of the + * same length. + */ + x11_saved_data = xmalloc(data_len); + x11_fake_data = xmalloc(data_len); + for (i = 0; i < data_len; i++) { + if (sscanf(data + 2 * i, "%2x", &value) != 1) + fatal("x11_request_forwarding: bad authentication data: %.100s", data); + if (i % 4 == 0) + rnd = arc4random(); + x11_saved_data[i] = value; + x11_fake_data[i] = rnd & 0xff; + rnd >>= 8; } + x11_saved_data_len = data_len; + x11_fake_data_len = data_len; /* Convert the fake data into hex. */ - new_data = tohex(x11_fake_data, data_len); + len = 2 * data_len + 1; + new_data = xmalloc(len); + for (i = 0; i < data_len; i++) + snprintf(new_data + 2 * i, len - 2 * i, + "%02x", (u_char) x11_fake_data[i]); /* Send the request packet. */ if (compat20) {