summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c85
1 files changed, 27 insertions, 58 deletions
diff --git a/channels.c b/channels.c
index 65a6a7f00..e663c2159 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.194 2003/08/29 10:04:36 markus Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.200 2004/01/19 09:24:21 markus Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -217,7 +217,6 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
217 channels = xmalloc(channels_alloc * sizeof(Channel *)); 217 channels = xmalloc(channels_alloc * sizeof(Channel *));
218 for (i = 0; i < channels_alloc; i++) 218 for (i = 0; i < channels_alloc; i++)
219 channels[i] = NULL; 219 channels[i] = NULL;
220 fatal_add_cleanup((void (*) (void *)) channel_free_all, NULL);
221 } 220 }
222 /* Try to find a free slot where to put the new channel. */ 221 /* Try to find a free slot where to put the new channel. */
223 for (found = -1, i = 0; i < channels_alloc; i++) 222 for (found = -1, i = 0; i < channels_alloc; i++)
@@ -229,12 +228,13 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
229 if (found == -1) { 228 if (found == -1) {
230 /* There are no free slots. Take last+1 slot and expand the array. */ 229 /* There are no free slots. Take last+1 slot and expand the array. */
231 found = channels_alloc; 230 found = channels_alloc;
232 channels_alloc += 10;
233 if (channels_alloc > 10000) 231 if (channels_alloc > 10000)
234 fatal("channel_new: internal error: channels_alloc %d " 232 fatal("channel_new: internal error: channels_alloc %d "
235 "too big.", channels_alloc); 233 "too big.", channels_alloc);
234 channels = xrealloc(channels,
235 (channels_alloc + 10) * sizeof(Channel *));
236 channels_alloc += 10;
236 debug2("channel: expanding %d", channels_alloc); 237 debug2("channel: expanding %d", channels_alloc);
237 channels = xrealloc(channels, channels_alloc * sizeof(Channel *));
238 for (i = found; i < channels_alloc; i++) 238 for (i = found; i < channels_alloc; i++)
239 channels[i] = NULL; 239 channels[i] = NULL;
240 } 240 }
@@ -970,7 +970,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
970 have = buffer_len(&c->input); 970 have = buffer_len(&c->input);
971 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { 971 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
972 /* format: ver | nmethods | methods */ 972 /* format: ver | nmethods | methods */
973 if (have < 2) 973 if (have < 2)
974 return 0; 974 return 0;
975 nmethods = p[1]; 975 nmethods = p[1];
976 if (have < nmethods + 2) 976 if (have < nmethods + 2)
@@ -1035,7 +1035,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1035 else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) 1035 else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
1036 return -1; 1036 return -1;
1037 c->host_port = ntohs(dest_port); 1037 c->host_port = ntohs(dest_port);
1038 1038
1039 debug2("channel %d: dynamic request: socks5 host %s port %u command %u", 1039 debug2("channel %d: dynamic request: socks5 host %s port %u command %u",
1040 c->self, c->path, c->host_port, s5_req.command); 1040 c->self, c->path, c->host_port, s5_req.command);
1041 1041
@@ -1397,9 +1397,9 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1397 data = buffer_ptr(&c->output); 1397 data = buffer_ptr(&c->output);
1398 dlen = buffer_len(&c->output); 1398 dlen = buffer_len(&c->output);
1399#ifdef _AIX 1399#ifdef _AIX
1400 /* XXX: Later AIX versions can't push as much data to tty */ 1400 /* XXX: Later AIX versions can't push as much data to tty */
1401 if (compat20 && c->wfd_isatty && dlen > 8*1024) 1401 if (compat20 && c->wfd_isatty)
1402 dlen = 8*1024; 1402 dlen = MIN(dlen, 8*1024);
1403#endif 1403#endif
1404 len = write(c->wfd, data, dlen); 1404 len = write(c->wfd, data, dlen);
1405 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1405 if (len < 0 && (errno == EINTR || errno == EAGAIN))
@@ -1817,13 +1817,25 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
1817 c->type != SSH_CHANNEL_X11_OPEN) 1817 c->type != SSH_CHANNEL_X11_OPEN)
1818 return; 1818 return;
1819 1819
1820 /* same for protocol 1.5 if output end is no longer open */
1821 if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN)
1822 return;
1823
1824 /* Get the data. */ 1820 /* Get the data. */
1825 data = packet_get_string(&data_len); 1821 data = packet_get_string(&data_len);
1826 1822
1823 /*
1824 * Ignore data for protocol > 1.3 if output end is no longer open.
1825 * For protocol 2 the sending side is reducing its window as it sends
1826 * data, so we must 'fake' consumption of the data in order to ensure
1827 * that window updates are sent back. Otherwise the connection might
1828 * deadlock.
1829 */
1830 if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) {
1831 if (compat20) {
1832 c->local_window -= data_len;
1833 c->local_consumed += data_len;
1834 }
1835 xfree(data);
1836 return;
1837 }
1838
1827 if (compat20) { 1839 if (compat20) {
1828 if (data_len > c->local_maxpacket) { 1840 if (data_len > c->local_maxpacket) {
1829 logit("channel %d: rcvd big packet %d, maxpack %d", 1841 logit("channel %d: rcvd big packet %d, maxpack %d",
@@ -2195,7 +2207,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2195 continue; 2207 continue;
2196 } 2208 }
2197 /* Start listening for connections on the socket. */ 2209 /* Start listening for connections on the socket. */
2198 if (listen(sock, 5) < 0) { 2210 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
2199 error("listen: %.100s", strerror(errno)); 2211 error("listen: %.100s", strerror(errno));
2200 close(sock); 2212 close(sock);
2201 continue; 2213 continue;
@@ -2550,7 +2562,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2550 /* Start listening for connections on the socket. */ 2562 /* Start listening for connections on the socket. */
2551 for (n = 0; n < num_socks; n++) { 2563 for (n = 0; n < num_socks; n++) {
2552 sock = socks[n]; 2564 sock = socks[n];
2553 if (listen(sock, 5) < 0) { 2565 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
2554 error("listen: %.100s", strerror(errno)); 2566 error("listen: %.100s", strerror(errno));
2555 close(sock); 2567 close(sock);
2556 return -1; 2568 return -1;
@@ -2838,46 +2850,3 @@ auth_request_forwarding(void)
2838 packet_send(); 2850 packet_send();
2839 packet_write_wait(); 2851 packet_write_wait();
2840} 2852}
2841
2842/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
2843
2844void
2845auth_input_open_request(int type, u_int32_t seq, void *ctxt)
2846{
2847 Channel *c = NULL;
2848 int remote_id, sock;
2849
2850 /* Read the remote channel number from the message. */
2851 remote_id = packet_get_int();
2852 packet_check_eom();
2853
2854 /*
2855 * Get a connection to the local authentication agent (this may again
2856 * get forwarded).
2857 */
2858 sock = ssh_get_authentication_socket();
2859
2860 /*
2861 * If we could not connect the agent, send an error message back to
2862 * the server. This should never happen unless the agent dies,
2863 * because authentication forwarding is only enabled if we have an
2864 * agent.
2865 */
2866 if (sock >= 0) {
2867 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
2868 -1, 0, 0, 0, "authentication agent connection", 1);
2869 c->remote_id = remote_id;
2870 c->force_drain = 1;
2871 }
2872 if (c == NULL) {
2873 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2874 packet_put_int(remote_id);
2875 } else {
2876 /* Send a confirmation to the remote host. */
2877 debug("Forwarding authentication connection.");
2878 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
2879 packet_put_int(remote_id);
2880 packet_put_int(c->self);
2881 }
2882 packet_send();
2883}