version 1.214, 2005/03/14 11:46:56 |
version 1.214.2.1, 2005/09/04 18:40:01 |
|
|
/* Maximum number of fake X11 displays to try. */ |
/* Maximum number of fake X11 displays to try. */ |
#define MAX_DISPLAYS 1000 |
#define MAX_DISPLAYS 1000 |
|
|
|
/* Saved X11 local (client) display. */ |
|
static char *x11_saved_display = NULL; |
|
|
/* Saved X11 authentication protocol name. */ |
/* Saved X11 authentication protocol name. */ |
static char *x11_saved_proto = NULL; |
static char *x11_saved_proto = NULL; |
|
|
|
|
FD_SET(c->wfd, writeset); |
FD_SET(c->wfd, writeset); |
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { |
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { |
if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) |
if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) |
debug2("channel %d: obuf_empty delayed efd %d/(%d)", |
debug2("channel %d: obuf_empty delayed efd %d/(%d)", |
c->self, c->efd, buffer_len(&c->extended)); |
c->self, c->efd, buffer_len(&c->extended)); |
else |
else |
chan_obuf_empty(c); |
chan_obuf_empty(c); |
} |
} |
|
|
channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) |
channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) |
{ |
{ |
char *p, *host; |
char *p, *host; |
int len, have, i, found; |
u_int len, have, i, found; |
char username[256]; |
char username[256]; |
struct { |
struct { |
u_int8_t version; |
u_int8_t version; |
|
|
} s5_req, s5_rsp; |
} s5_req, s5_rsp; |
u_int16_t dest_port; |
u_int16_t dest_port; |
u_char *p, dest_addr[255+1]; |
u_char *p, dest_addr[255+1]; |
int i, have, found, nmethods, addrlen, af; |
u_int have, i, found, nmethods, addrlen, af; |
|
|
debug2("channel %d: decode socks5", c->self); |
debug2("channel %d: decode socks5", c->self); |
p = buffer_ptr(&c->input); |
p = buffer_ptr(&c->input); |
|
|
channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) |
channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) |
{ |
{ |
u_char *p; |
u_char *p; |
int have, ret; |
u_int have; |
|
int ret; |
|
|
have = buffer_len(&c->input); |
have = buffer_len(&c->input); |
c->delayed = 0; |
c->delayed = 0; |
|
|
int direct; |
int direct; |
char buf[1024]; |
char buf[1024]; |
char *remote_ipaddr = get_peer_ipaddr(c->sock); |
char *remote_ipaddr = get_peer_ipaddr(c->sock); |
u_short remote_port = get_peer_port(c->sock); |
int remote_port = get_peer_port(c->sock); |
|
|
direct = (strcmp(rtype, "direct-tcpip") == 0); |
direct = (strcmp(rtype, "direct-tcpip") == 0); |
|
|
|
|
} |
} |
/* originator host and port */ |
/* originator host and port */ |
packet_put_cstring(remote_ipaddr); |
packet_put_cstring(remote_ipaddr); |
packet_put_int(remote_port); |
packet_put_int((u_int)remote_port); |
packet_send(); |
packet_send(); |
} else { |
} else { |
packet_start(SSH_MSG_PORT_OPEN); |
packet_start(SSH_MSG_PORT_OPEN); |
|
|
* hack for extended data: delay EOF if EFD still in use. |
* hack for extended data: delay EOF if EFD still in use. |
*/ |
*/ |
if (CHANNEL_EFD_INPUT_ACTIVE(c)) |
if (CHANNEL_EFD_INPUT_ACTIVE(c)) |
debug2("channel %d: ibuf_empty delayed efd %d/(%d)", |
debug2("channel %d: ibuf_empty delayed efd %d/(%d)", |
c->self, c->efd, buffer_len(&c->extended)); |
c->self, c->efd, buffer_len(&c->extended)); |
else |
else |
chan_ibuf_empty(c); |
chan_ibuf_empty(c); |
} |
} |
|
|
|
|
if (host == NULL) { |
if (host == NULL) { |
error("No forward host name."); |
error("No forward host name."); |
return success; |
return 0; |
} |
} |
if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { |
if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { |
error("Forward host name too long."); |
error("Forward host name too long."); |
return success; |
return 0; |
} |
} |
|
|
/* |
/* |
|
|
packet_disconnect("getaddrinfo: fatal error: %s", |
packet_disconnect("getaddrinfo: fatal error: %s", |
gai_strerror(r)); |
gai_strerror(r)); |
} else { |
} else { |
verbose("channel_setup_fwd_listener: " |
error("channel_setup_fwd_listener: " |
"getaddrinfo(%.64s): %s", addr, gai_strerror(r)); |
"getaddrinfo(%.64s): %s", addr, gai_strerror(r)); |
packet_send_debug("channel_setup_fwd_listener: " |
|
"getaddrinfo(%.64s): %s", addr, gai_strerror(r)); |
|
} |
} |
aitop = NULL; |
return 0; |
} |
} |
|
|
for (ai = aitop; ai; ai = ai->ai_next) { |
for (ai = aitop; ai; ai = ai->ai_next) { |
|
|
*/ |
*/ |
int |
int |
x11_create_display_inet(int x11_display_offset, int x11_use_localhost, |
x11_create_display_inet(int x11_display_offset, int x11_use_localhost, |
int single_connection, u_int *display_numberp) |
int single_connection, u_int *display_numberp, int **chanids) |
{ |
{ |
Channel *nc = NULL; |
Channel *nc = NULL; |
int display_number, sock; |
int display_number, sock; |
|
|
} |
} |
|
|
/* Allocate a channel for each socket. */ |
/* Allocate a channel for each socket. */ |
|
if (chanids != NULL) |
|
*chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); |
for (n = 0; n < num_socks; n++) { |
for (n = 0; n < num_socks; n++) { |
sock = socks[n]; |
sock = socks[n]; |
nc = channel_new("x11 listener", |
nc = channel_new("x11 listener", |
|
|
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, |
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, |
0, "X11 inet listener", 1); |
0, "X11 inet listener", 1); |
nc->single_connection = single_connection; |
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. */ |
/* Return the display number for the DISPLAY environment variable. */ |
*display_numberp = display_number; |
*display_numberp = display_number; |
|
|
* This should be called in the client only. |
* This should be called in the client only. |
*/ |
*/ |
void |
void |
x11_request_forwarding_with_spoofing(int client_session_id, |
x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, |
const char *proto, const char *data) |
const char *proto, const char *data) |
{ |
{ |
u_int data_len = (u_int) strlen(data) / 2; |
u_int data_len = (u_int) strlen(data) / 2; |
u_int i, value, len; |
u_int i, value; |
char *new_data; |
char *new_data; |
int screen_number; |
int screen_number; |
const char *cp; |
const char *cp; |
u_int32_t rnd = 0; |
u_int32_t rnd = 0; |
|
|
cp = getenv("DISPLAY"); |
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, ':'); |
if (cp) |
if (cp) |
cp = strchr(cp, ':'); |
|
if (cp) |
|
cp = strchr(cp, '.'); |
cp = strchr(cp, '.'); |
if (cp) |
if (cp) |
screen_number = atoi(cp + 1); |
screen_number = atoi(cp + 1); |
else |
else |
screen_number = 0; |
screen_number = 0; |
|
|
/* Save protocol name. */ |
if (x11_saved_proto == NULL) { |
x11_saved_proto = xstrdup(proto); |
/* Save protocol name. */ |
|
x11_saved_proto = xstrdup(proto); |
/* |
/* |
* Extract real authentication data and generate fake data of the |
* Extract real authentication data and generate fake data |
* same length. |
* of the same length. |
*/ |
*/ |
x11_saved_data = xmalloc(data_len); |
x11_saved_data = xmalloc(data_len); |
x11_fake_data = xmalloc(data_len); |
x11_fake_data = xmalloc(data_len); |
for (i = 0; i < data_len; i++) { |
for (i = 0; i < data_len; i++) { |
if (sscanf(data + 2 * i, "%2x", &value) != 1) |
if (sscanf(data + 2 * i, "%2x", &value) != 1) |
fatal("x11_request_forwarding: bad authentication data: %.100s", data); |
fatal("x11_request_forwarding: bad " |
if (i % 4 == 0) |
"authentication data: %.100s", data); |
rnd = arc4random(); |
if (i % 4 == 0) |
x11_saved_data[i] = value; |
rnd = arc4random(); |
x11_fake_data[i] = rnd & 0xff; |
x11_saved_data[i] = value; |
rnd >>= 8; |
x11_fake_data[i] = rnd & 0xff; |
|
rnd >>= 8; |
|
} |
|
x11_saved_data_len = data_len; |
|
x11_fake_data_len = data_len; |
} |
} |
x11_saved_data_len = data_len; |
|
x11_fake_data_len = data_len; |
|
|
|
/* Convert the fake data into hex. */ |
/* Convert the fake data into hex. */ |
len = 2 * data_len + 1; |
new_data = tohex(x11_fake_data, data_len); |
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. */ |
/* Send the request packet. */ |
if (compat20) { |
if (compat20) { |