version 1.195, 2003/09/16 21:02:40 |
version 1.195.2.1, 2004/02/28 03:51:32 |
|
|
channels = xmalloc(channels_alloc * sizeof(Channel *)); |
channels = xmalloc(channels_alloc * sizeof(Channel *)); |
for (i = 0; i < channels_alloc; i++) |
for (i = 0; i < channels_alloc; i++) |
channels[i] = NULL; |
channels[i] = NULL; |
fatal_add_cleanup((void (*) (void *)) channel_free_all, NULL); |
|
} |
} |
/* Try to find a free slot where to put the new channel. */ |
/* Try to find a free slot where to put the new channel. */ |
for (found = -1, i = 0; i < channels_alloc; i++) |
for (found = -1, i = 0; i < channels_alloc; i++) |
|
|
have = buffer_len(&c->input); |
have = buffer_len(&c->input); |
if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { |
if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { |
/* format: ver | nmethods | methods */ |
/* format: ver | nmethods | methods */ |
if (have < 2) |
if (have < 2) |
return 0; |
return 0; |
nmethods = p[1]; |
nmethods = p[1]; |
if (have < nmethods + 2) |
if (have < nmethods + 2) |
|
|
else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) |
else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) |
return -1; |
return -1; |
c->host_port = ntohs(dest_port); |
c->host_port = ntohs(dest_port); |
|
|
debug2("channel %d: dynamic request: socks5 host %s port %u command %u", |
debug2("channel %d: dynamic request: socks5 host %s port %u command %u", |
c->self, c->path, c->host_port, s5_req.command); |
c->self, c->path, c->host_port, s5_req.command); |
|
|
|
|
c->type != SSH_CHANNEL_X11_OPEN) |
c->type != SSH_CHANNEL_X11_OPEN) |
return; |
return; |
|
|
/* same for protocol 1.5 if output end is no longer open */ |
|
if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) |
|
return; |
|
|
|
/* Get the data. */ |
/* Get the data. */ |
data = packet_get_string(&data_len); |
data = packet_get_string(&data_len); |
|
|
|
/* |
|
* Ignore data for protocol > 1.3 if output end is no longer open. |
|
* For protocol 2 the sending side is reducing its window as it sends |
|
* data, so we must 'fake' consumption of the data in order to ensure |
|
* that window updates are sent back. Otherwise the connection might |
|
* deadlock. |
|
*/ |
|
if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) { |
|
if (compat20) { |
|
c->local_window -= data_len; |
|
c->local_consumed += data_len; |
|
} |
|
xfree(data); |
|
return; |
|
} |
|
|
if (compat20) { |
if (compat20) { |
if (data_len > c->local_maxpacket) { |
if (data_len > c->local_maxpacket) { |
logit("channel %d: rcvd big packet %d, maxpack %d", |
logit("channel %d: rcvd big packet %d, maxpack %d", |
|
|
continue; |
continue; |
} |
} |
/* Start listening for connections on the socket. */ |
/* Start listening for connections on the socket. */ |
if (listen(sock, 5) < 0) { |
if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { |
error("listen: %.100s", strerror(errno)); |
error("listen: %.100s", strerror(errno)); |
close(sock); |
close(sock); |
continue; |
continue; |
|
|
/* Start listening for connections on the socket. */ |
/* Start listening for connections on the socket. */ |
for (n = 0; n < num_socks; n++) { |
for (n = 0; n < num_socks; n++) { |
sock = socks[n]; |
sock = socks[n]; |
if (listen(sock, 5) < 0) { |
if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { |
error("listen: %.100s", strerror(errno)); |
error("listen: %.100s", strerror(errno)); |
close(sock); |
close(sock); |
return -1; |
return -1; |
|
|
packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); |
packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING); |
packet_send(); |
packet_send(); |
packet_write_wait(); |
packet_write_wait(); |
} |
|
|
|
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ |
|
|
|
void |
|
auth_input_open_request(int type, u_int32_t seq, void *ctxt) |
|
{ |
|
Channel *c = NULL; |
|
int remote_id, sock; |
|
|
|
/* Read the remote channel number from the message. */ |
|
remote_id = packet_get_int(); |
|
packet_check_eom(); |
|
|
|
/* |
|
* Get a connection to the local authentication agent (this may again |
|
* get forwarded). |
|
*/ |
|
sock = ssh_get_authentication_socket(); |
|
|
|
/* |
|
* If we could not connect the agent, send an error message back to |
|
* the server. This should never happen unless the agent dies, |
|
* because authentication forwarding is only enabled if we have an |
|
* agent. |
|
*/ |
|
if (sock >= 0) { |
|
c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, |
|
-1, 0, 0, 0, "authentication agent connection", 1); |
|
c->remote_id = remote_id; |
|
c->force_drain = 1; |
|
} |
|
if (c == NULL) { |
|
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
|
packet_put_int(remote_id); |
|
} else { |
|
/* Send a confirmation to the remote host. */ |
|
debug("Forwarding authentication connection."); |
|
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); |
|
packet_put_int(remote_id); |
|
packet_put_int(c->self); |
|
} |
|
packet_send(); |
|
} |
} |