version 1.320, 2013/04/06 16:07:00 |
version 1.321, 2013/05/17 00:13:13 |
|
|
|
|
s = channel_open_message(); |
s = channel_open_message(); |
debug3("channel %d: status: %s", c->self, s); |
debug3("channel %d: status: %s", c->self, s); |
xfree(s); |
free(s); |
|
|
if (c->sock != -1) |
if (c->sock != -1) |
shutdown(c->sock, SHUT_RDWR); |
shutdown(c->sock, SHUT_RDWR); |
|
|
buffer_free(&c->input); |
buffer_free(&c->input); |
buffer_free(&c->output); |
buffer_free(&c->output); |
buffer_free(&c->extended); |
buffer_free(&c->extended); |
if (c->remote_name) { |
free(c->remote_name); |
xfree(c->remote_name); |
c->remote_name = NULL; |
c->remote_name = NULL; |
free(c->path); |
} |
c->path = NULL; |
if (c->path) { |
free(c->listening_addr); |
xfree(c->path); |
c->listening_addr = NULL; |
c->path = NULL; |
|
} |
|
if (c->listening_addr) { |
|
xfree(c->listening_addr); |
|
c->listening_addr = NULL; |
|
} |
|
while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { |
while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { |
if (cc->abandon_cb != NULL) |
if (cc->abandon_cb != NULL) |
cc->abandon_cb(c, cc->ctx); |
cc->abandon_cb(c, cc->ctx); |
TAILQ_REMOVE(&c->status_confirms, cc, entry); |
TAILQ_REMOVE(&c->status_confirms, cc, entry); |
bzero(cc, sizeof(*cc)); |
bzero(cc, sizeof(*cc)); |
xfree(cc); |
free(cc); |
} |
} |
if (c->filter_cleanup != NULL && c->filter_ctx != NULL) |
if (c->filter_cleanup != NULL && c->filter_ctx != NULL) |
c->filter_cleanup(c->self, c->filter_ctx); |
c->filter_cleanup(c->self, c->filter_ctx); |
channels[c->self] = NULL; |
channels[c->self] = NULL; |
xfree(c); |
free(c); |
} |
} |
|
|
void |
void |
|
|
strlcpy(username, p, sizeof(username)); |
strlcpy(username, p, sizeof(username)); |
buffer_consume(&c->input, len); |
buffer_consume(&c->input, len); |
|
|
if (c->path != NULL) { |
free(c->path); |
xfree(c->path); |
c->path = NULL; |
c->path = NULL; |
|
} |
|
if (need == 1) { /* SOCKS4: one string */ |
if (need == 1) { /* SOCKS4: one string */ |
host = inet_ntoa(s4_req.dest_addr); |
host = inet_ntoa(s4_req.dest_addr); |
c->path = xstrdup(host); |
c->path = xstrdup(host); |
|
|
buffer_get(&c->input, (char *)&dest_addr, addrlen); |
buffer_get(&c->input, (char *)&dest_addr, addrlen); |
buffer_get(&c->input, (char *)&dest_port, 2); |
buffer_get(&c->input, (char *)&dest_port, 2); |
dest_addr[addrlen] = '\0'; |
dest_addr[addrlen] = '\0'; |
if (c->path != NULL) { |
free(c->path); |
xfree(c->path); |
c->path = NULL; |
c->path = NULL; |
|
} |
|
if (s5_req.atyp == SSH_SOCKS5_DOMAIN) { |
if (s5_req.atyp == SSH_SOCKS5_DOMAIN) { |
if (addrlen >= NI_MAXHOST) { |
if (addrlen >= NI_MAXHOST) { |
error("channel %d: dynamic request: socks5 hostname " |
error("channel %d: dynamic request: socks5 hostname " |
|
|
packet_put_cstring(buf); |
packet_put_cstring(buf); |
packet_send(); |
packet_send(); |
} |
} |
xfree(remote_ipaddr); |
free(remote_ipaddr); |
} |
} |
} |
} |
|
|
|
|
|
|
if (remote_port == -1) { |
if (remote_port == -1) { |
/* Fake addr/port to appease peers that validate it (Tectia) */ |
/* Fake addr/port to appease peers that validate it (Tectia) */ |
xfree(remote_ipaddr); |
free(remote_ipaddr); |
remote_ipaddr = xstrdup("127.0.0.1"); |
remote_ipaddr = xstrdup("127.0.0.1"); |
remote_port = 65535; |
remote_port = 65535; |
} |
} |
|
|
rtype, c->listening_port, c->path, c->host_port, |
rtype, c->listening_port, c->path, c->host_port, |
remote_ipaddr, remote_port); |
remote_ipaddr, remote_port); |
|
|
xfree(c->remote_name); |
free(c->remote_name); |
c->remote_name = xstrdup(buf); |
c->remote_name = xstrdup(buf); |
|
|
if (compat20) { |
if (compat20) { |
|
|
packet_put_cstring(c->remote_name); |
packet_put_cstring(c->remote_name); |
packet_send(); |
packet_send(); |
} |
} |
xfree(remote_ipaddr); |
free(remote_ipaddr); |
} |
} |
|
|
static void |
static void |
|
|
if (c->datagram) { |
if (c->datagram) { |
/* ignore truncated writes, datagrams might get lost */ |
/* ignore truncated writes, datagrams might get lost */ |
len = write(c->wfd, buf, dlen); |
len = write(c->wfd, buf, dlen); |
xfree(data); |
free(data); |
if (len < 0 && (errno == EINTR || errno == EAGAIN)) |
if (len < 0 && (errno == EINTR || errno == EAGAIN)) |
return 1; |
return 1; |
if (len <= 0) { |
if (len <= 0) { |
|
|
debug("channel %d: datagram " |
debug("channel %d: datagram " |
"too big for channel", |
"too big for channel", |
c->self); |
c->self); |
xfree(data); |
free(data); |
continue; |
continue; |
} |
} |
packet_start(SSH2_MSG_CHANNEL_DATA); |
packet_start(SSH2_MSG_CHANNEL_DATA); |
|
|
packet_put_string(data, dlen); |
packet_put_string(data, dlen); |
packet_send(); |
packet_send(); |
c->remote_window -= dlen + 4; |
c->remote_window -= dlen + 4; |
xfree(data); |
free(data); |
} |
} |
continue; |
continue; |
} |
} |
|
|
if (data_len > c->local_window) { |
if (data_len > c->local_window) { |
logit("channel %d: rcvd too much extended_data %d, win %d", |
logit("channel %d: rcvd too much extended_data %d, win %d", |
c->self, data_len, c->local_window); |
c->self, data_len, c->local_window); |
xfree(data); |
free(data); |
return; |
return; |
} |
} |
debug2("channel %d: rcvd ext data %d", c->self, data_len); |
debug2("channel %d: rcvd ext data %d", c->self, data_len); |
c->local_window -= data_len; |
c->local_window -= data_len; |
buffer_append(&c->extended, data, data_len); |
buffer_append(&c->extended, data, data_len); |
xfree(data); |
free(data); |
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
|
|
} |
} |
logit("channel %d: open failed: %s%s%s", id, |
logit("channel %d: open failed: %s%s%s", id, |
reason2txt(reason), msg ? ": ": "", msg ? msg : ""); |
reason2txt(reason), msg ? ": ": "", msg ? msg : ""); |
if (msg != NULL) |
free(msg); |
xfree(msg); |
free(lang); |
if (lang != NULL) |
|
xfree(lang); |
|
if (c->open_confirm) { |
if (c->open_confirm) { |
debug2("callback start"); |
debug2("callback start"); |
c->open_confirm(c->self, 0, c->open_confirm_ctx); |
c->open_confirm(c->self, 0, c->open_confirm_ctx); |
|
|
packet_check_eom(); |
packet_check_eom(); |
c = channel_connect_to(host, host_port, |
c = channel_connect_to(host, host_port, |
"connected socket", originator_string); |
"connected socket", originator_string); |
xfree(originator_string); |
free(originator_string); |
xfree(host); |
free(host); |
if (c == NULL) { |
if (c == NULL) { |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
packet_put_int(remote_id); |
packet_put_int(remote_id); |
|
|
cc->cb(type, c, cc->ctx); |
cc->cb(type, c, cc->ctx); |
TAILQ_REMOVE(&c->status_confirms, cc, entry); |
TAILQ_REMOVE(&c->status_confirms, cc, entry); |
bzero(cc, sizeof(*cc)); |
bzero(cc, sizeof(*cc)); |
xfree(cc); |
free(cc); |
} |
} |
|
|
/* -- tcp forwarding */ |
/* -- tcp forwarding */ |
|
|
|
|
permitted_opens[i].listen_port = 0; |
permitted_opens[i].listen_port = 0; |
permitted_opens[i].port_to_connect = 0; |
permitted_opens[i].port_to_connect = 0; |
xfree(permitted_opens[i].host_to_connect); |
free(permitted_opens[i].host_to_connect); |
permitted_opens[i].host_to_connect = NULL; |
permitted_opens[i].host_to_connect = NULL; |
|
|
return 0; |
return 0; |
|
|
host_port, gateway_ports); |
host_port, gateway_ports); |
|
|
/* Free the argument string. */ |
/* Free the argument string. */ |
xfree(hostname); |
free(hostname); |
|
|
return (success ? 0 : -1); |
return (success ? 0 : -1); |
} |
} |
|
|
} else { |
} else { |
permitted_opens[idx].listen_port = 0; |
permitted_opens[idx].listen_port = 0; |
permitted_opens[idx].port_to_connect = 0; |
permitted_opens[idx].port_to_connect = 0; |
xfree(permitted_opens[idx].host_to_connect); |
free(permitted_opens[idx].host_to_connect); |
permitted_opens[idx].host_to_connect = NULL; |
permitted_opens[idx].host_to_connect = NULL; |
} |
} |
} |
} |
|
|
int i; |
int i; |
|
|
for (i = 0; i < num_permitted_opens; i++) |
for (i = 0; i < num_permitted_opens; i++) |
if (permitted_opens[i].host_to_connect != NULL) |
free(permitted_opens[i].host_to_connect); |
xfree(permitted_opens[i].host_to_connect); |
free(permitted_opens); |
if (num_permitted_opens > 0) { |
permitted_opens = NULL; |
xfree(permitted_opens); |
|
permitted_opens = NULL; |
|
} |
|
num_permitted_opens = 0; |
num_permitted_opens = 0; |
} |
} |
|
|
|
|
int i; |
int i; |
|
|
for (i = 0; i < num_adm_permitted_opens; i++) |
for (i = 0; i < num_adm_permitted_opens; i++) |
if (permitted_adm_opens[i].host_to_connect != NULL) |
free(permitted_adm_opens[i].host_to_connect); |
xfree(permitted_adm_opens[i].host_to_connect); |
free(permitted_adm_opens); |
if (num_adm_permitted_opens > 0) { |
permitted_adm_opens = NULL; |
xfree(permitted_adm_opens); |
|
permitted_adm_opens = NULL; |
|
} |
|
num_adm_permitted_opens = 0; |
num_adm_permitted_opens = 0; |
} |
} |
|
|
|
|
static void |
static void |
channel_connect_ctx_free(struct channel_connect *cctx) |
channel_connect_ctx_free(struct channel_connect *cctx) |
{ |
{ |
xfree(cctx->host); |
free(cctx->host); |
if (cctx->aitop) |
if (cctx->aitop) |
freeaddrinfo(cctx->aitop); |
freeaddrinfo(cctx->aitop); |
bzero(cctx, sizeof(*cctx)); |
bzero(cctx, sizeof(*cctx)); |
|
|
c->remote_id = remote_id; |
c->remote_id = remote_id; |
c->force_drain = 1; |
c->force_drain = 1; |
} |
} |
xfree(remote_host); |
free(remote_host); |
if (c == NULL) { |
if (c == NULL) { |
/* Send refusal to the remote host. */ |
/* Send refusal to the remote host. */ |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
|
|
packet_put_int(screen_number); |
packet_put_int(screen_number); |
packet_send(); |
packet_send(); |
packet_write_wait(); |
packet_write_wait(); |
xfree(new_data); |
free(new_data); |
} |
} |
|
|
|
|