summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2005-01-04 13:07:27 +0000
committerColin Watson <cjwatson@debian.org>2005-01-04 13:07:27 +0000
commitfd0f611b70a83d80fe8793af785542ee5541b7cd (patch)
treebededd22bb7eeec52e20083237ab7e4113445a16 /channels.c
parentc44fe9a5b9d3db96a7249b04d915f17e4a3a3b04 (diff)
parentebd2ce335af5861020c79fddb1ae35c03bf036cf (diff)
Merge 3.9p1 to the trunk.
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c198
1 files changed, 159 insertions, 39 deletions
diff --git a/channels.c b/channels.c
index e663c2159..1f6984aa7 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.200 2004/01/19 09:24:21 markus Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.209 2004/08/11 21:43:04 avsm Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -68,7 +68,7 @@ static Channel **channels = NULL;
68 * Size of the channel array. All slots of the array must always be 68 * Size of the channel array. All slots of the array must always be
69 * initialized (at least the type field); unused slots set to NULL 69 * initialized (at least the type field); unused slots set to NULL
70 */ 70 */
71static int channels_alloc = 0; 71static u_int channels_alloc = 0;
72 72
73/* 73/*
74 * Maximum file descriptor value used in any of the channels. This is 74 * Maximum file descriptor value used in any of the channels. This is
@@ -141,7 +141,7 @@ channel_lookup(int id)
141{ 141{
142 Channel *c; 142 Channel *c;
143 143
144 if (id < 0 || id >= channels_alloc) { 144 if (id < 0 || (u_int)id >= channels_alloc) {
145 logit("channel_lookup: %d: bad id", id); 145 logit("channel_lookup: %d: bad id", id);
146 return NULL; 146 return NULL;
147 } 147 }
@@ -172,6 +172,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
172 c->rfd = rfd; 172 c->rfd = rfd;
173 c->wfd = wfd; 173 c->wfd = wfd;
174 c->sock = (rfd == wfd) ? rfd : -1; 174 c->sock = (rfd == wfd) ? rfd : -1;
175 c->ctl_fd = -1; /* XXX: set elsewhere */
175 c->efd = efd; 176 c->efd = efd;
176 c->extended_usage = extusage; 177 c->extended_usage = extusage;
177 178
@@ -208,7 +209,8 @@ Channel *
208channel_new(char *ctype, int type, int rfd, int wfd, int efd, 209channel_new(char *ctype, int type, int rfd, int wfd, int efd,
209 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock) 210 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
210{ 211{
211 int i, found; 212 int found;
213 u_int i;
212 Channel *c; 214 Channel *c;
213 215
214 /* Do initial allocation if this is the first call. */ 216 /* Do initial allocation if this is the first call. */
@@ -222,10 +224,10 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
222 for (found = -1, i = 0; i < channels_alloc; i++) 224 for (found = -1, i = 0; i < channels_alloc; i++)
223 if (channels[i] == NULL) { 225 if (channels[i] == NULL) {
224 /* Found a free slot. */ 226 /* Found a free slot. */
225 found = i; 227 found = (int)i;
226 break; 228 break;
227 } 229 }
228 if (found == -1) { 230 if (found < 0) {
229 /* There are no free slots. Take last+1 slot and expand the array. */ 231 /* There are no free slots. Take last+1 slot and expand the array. */
230 found = channels_alloc; 232 found = channels_alloc;
231 if (channels_alloc > 10000) 233 if (channels_alloc > 10000)
@@ -263,6 +265,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
263 c->single_connection = 0; 265 c->single_connection = 0;
264 c->detach_user = NULL; 266 c->detach_user = NULL;
265 c->confirm = NULL; 267 c->confirm = NULL;
268 c->confirm_ctx = NULL;
266 c->input_filter = NULL; 269 c->input_filter = NULL;
267 debug("channel %d: new [%s]", found, remote_name); 270 debug("channel %d: new [%s]", found, remote_name);
268 return c; 271 return c;
@@ -271,7 +274,8 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
271static int 274static int
272channel_find_maxfd(void) 275channel_find_maxfd(void)
273{ 276{
274 int i, max = 0; 277 u_int i;
278 int max = 0;
275 Channel *c; 279 Channel *c;
276 280
277 for (i = 0; i < channels_alloc; i++) { 281 for (i = 0; i < channels_alloc; i++) {
@@ -304,10 +308,11 @@ channel_close_fd(int *fdp)
304static void 308static void
305channel_close_fds(Channel *c) 309channel_close_fds(Channel *c)
306{ 310{
307 debug3("channel %d: close_fds r %d w %d e %d", 311 debug3("channel %d: close_fds r %d w %d e %d c %d",
308 c->self, c->rfd, c->wfd, c->efd); 312 c->self, c->rfd, c->wfd, c->efd, c->ctl_fd);
309 313
310 channel_close_fd(&c->sock); 314 channel_close_fd(&c->sock);
315 channel_close_fd(&c->ctl_fd);
311 channel_close_fd(&c->rfd); 316 channel_close_fd(&c->rfd);
312 channel_close_fd(&c->wfd); 317 channel_close_fd(&c->wfd);
313 channel_close_fd(&c->efd); 318 channel_close_fd(&c->efd);
@@ -319,12 +324,12 @@ void
319channel_free(Channel *c) 324channel_free(Channel *c)
320{ 325{
321 char *s; 326 char *s;
322 int i, n; 327 u_int i, n;
323 328
324 for (n = 0, i = 0; i < channels_alloc; i++) 329 for (n = 0, i = 0; i < channels_alloc; i++)
325 if (channels[i]) 330 if (channels[i])
326 n++; 331 n++;
327 debug("channel %d: free: %s, nchannels %d", c->self, 332 debug("channel %d: free: %s, nchannels %u", c->self,
328 c->remote_name ? c->remote_name : "???", n); 333 c->remote_name ? c->remote_name : "???", n);
329 334
330 s = channel_open_message(); 335 s = channel_open_message();
@@ -333,6 +338,8 @@ channel_free(Channel *c)
333 338
334 if (c->sock != -1) 339 if (c->sock != -1)
335 shutdown(c->sock, SHUT_RDWR); 340 shutdown(c->sock, SHUT_RDWR);
341 if (c->ctl_fd != -1)
342 shutdown(c->ctl_fd, SHUT_RDWR);
336 channel_close_fds(c); 343 channel_close_fds(c);
337 buffer_free(&c->input); 344 buffer_free(&c->input);
338 buffer_free(&c->output); 345 buffer_free(&c->output);
@@ -348,7 +355,7 @@ channel_free(Channel *c)
348void 355void
349channel_free_all(void) 356channel_free_all(void)
350{ 357{
351 int i; 358 u_int i;
352 359
353 for (i = 0; i < channels_alloc; i++) 360 for (i = 0; i < channels_alloc; i++)
354 if (channels[i] != NULL) 361 if (channels[i] != NULL)
@@ -363,7 +370,7 @@ channel_free_all(void)
363void 370void
364channel_close_all(void) 371channel_close_all(void)
365{ 372{
366 int i; 373 u_int i;
367 374
368 for (i = 0; i < channels_alloc; i++) 375 for (i = 0; i < channels_alloc; i++)
369 if (channels[i] != NULL) 376 if (channels[i] != NULL)
@@ -377,7 +384,7 @@ channel_close_all(void)
377void 384void
378channel_stop_listening(void) 385channel_stop_listening(void)
379{ 386{
380 int i; 387 u_int i;
381 Channel *c; 388 Channel *c;
382 389
383 for (i = 0; i < channels_alloc; i++) { 390 for (i = 0; i < channels_alloc; i++) {
@@ -434,7 +441,7 @@ channel_not_very_much_buffered_data(void)
434int 441int
435channel_still_open(void) 442channel_still_open(void)
436{ 443{
437 int i; 444 u_int i;
438 Channel *c; 445 Channel *c;
439 446
440 for (i = 0; i < channels_alloc; i++) { 447 for (i = 0; i < channels_alloc; i++) {
@@ -477,12 +484,12 @@ channel_still_open(void)
477int 484int
478channel_find_open(void) 485channel_find_open(void)
479{ 486{
480 int i; 487 u_int i;
481 Channel *c; 488 Channel *c;
482 489
483 for (i = 0; i < channels_alloc; i++) { 490 for (i = 0; i < channels_alloc; i++) {
484 c = channels[i]; 491 c = channels[i];
485 if (c == NULL) 492 if (c == NULL || c->remote_id < 0)
486 continue; 493 continue;
487 switch (c->type) { 494 switch (c->type) {
488 case SSH_CHANNEL_CLOSED: 495 case SSH_CHANNEL_CLOSED:
@@ -525,7 +532,7 @@ channel_open_message(void)
525 Buffer buffer; 532 Buffer buffer;
526 Channel *c; 533 Channel *c;
527 char buf[1024], *cp; 534 char buf[1024], *cp;
528 int i; 535 u_int i;
529 536
530 buffer_init(&buffer); 537 buffer_init(&buffer);
531 snprintf(buf, sizeof buf, "The following connections are open:\r\n"); 538 snprintf(buf, sizeof buf, "The following connections are open:\r\n");
@@ -550,12 +557,13 @@ channel_open_message(void)
550 case SSH_CHANNEL_X11_OPEN: 557 case SSH_CHANNEL_X11_OPEN:
551 case SSH_CHANNEL_INPUT_DRAINING: 558 case SSH_CHANNEL_INPUT_DRAINING:
552 case SSH_CHANNEL_OUTPUT_DRAINING: 559 case SSH_CHANNEL_OUTPUT_DRAINING:
553 snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n", 560 snprintf(buf, sizeof buf,
561 " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cfd %d)\r\n",
554 c->self, c->remote_name, 562 c->self, c->remote_name,
555 c->type, c->remote_id, 563 c->type, c->remote_id,
556 c->istate, buffer_len(&c->input), 564 c->istate, buffer_len(&c->input),
557 c->ostate, buffer_len(&c->output), 565 c->ostate, buffer_len(&c->output),
558 c->rfd, c->wfd); 566 c->rfd, c->wfd, c->ctl_fd);
559 buffer_append(&buffer, buf, strlen(buf)); 567 buffer_append(&buffer, buf, strlen(buf));
560 continue; 568 continue;
561 default: 569 default:
@@ -596,14 +604,14 @@ channel_request_start(int id, char *service, int wantconfirm)
596 logit("channel_request_start: %d: unknown channel id", id); 604 logit("channel_request_start: %d: unknown channel id", id);
597 return; 605 return;
598 } 606 }
599 debug2("channel %d: request %s", id, service) ; 607 debug2("channel %d: request %s confirm %d", id, service, wantconfirm);
600 packet_start(SSH2_MSG_CHANNEL_REQUEST); 608 packet_start(SSH2_MSG_CHANNEL_REQUEST);
601 packet_put_int(c->remote_id); 609 packet_put_int(c->remote_id);
602 packet_put_cstring(service); 610 packet_put_cstring(service);
603 packet_put_char(wantconfirm); 611 packet_put_char(wantconfirm);
604} 612}
605void 613void
606channel_register_confirm(int id, channel_callback_fn *fn) 614channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
607{ 615{
608 Channel *c = channel_lookup(id); 616 Channel *c = channel_lookup(id);
609 617
@@ -612,6 +620,7 @@ channel_register_confirm(int id, channel_callback_fn *fn)
612 return; 620 return;
613 } 621 }
614 c->confirm = fn; 622 c->confirm = fn;
623 c->confirm_ctx = ctx;
615} 624}
616void 625void
617channel_register_cleanup(int id, channel_callback_fn *fn) 626channel_register_cleanup(int id, channel_callback_fn *fn)
@@ -729,6 +738,10 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
729 buffer_len(&c->extended) < c->remote_window) 738 buffer_len(&c->extended) < c->remote_window)
730 FD_SET(c->efd, readset); 739 FD_SET(c->efd, readset);
731 } 740 }
741 /* XXX: What about efd? races? */
742 if (compat20 && c->ctl_fd != -1 &&
743 c->istate == CHAN_INPUT_OPEN && c->ostate == CHAN_OUTPUT_OPEN)
744 FD_SET(c->ctl_fd, readset);
732} 745}
733 746
734static void 747static void
@@ -1031,7 +1044,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1031 buffer_get(&c->input, (char *)&dest_port, 2); 1044 buffer_get(&c->input, (char *)&dest_port, 2);
1032 dest_addr[addrlen] = '\0'; 1045 dest_addr[addrlen] = '\0';
1033 if (s5_req.atyp == SSH_SOCKS5_DOMAIN) 1046 if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
1034 strlcpy(c->path, dest_addr, sizeof(c->path)); 1047 strlcpy(c->path, (char *)dest_addr, sizeof(c->path));
1035 else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) 1048 else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
1036 return -1; 1049 return -1;
1037 c->host_port = ntohs(dest_port); 1050 c->host_port = ntohs(dest_port);
@@ -1482,6 +1495,33 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
1482 return 1; 1495 return 1;
1483} 1496}
1484static int 1497static int
1498channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset)
1499{
1500 char buf[16];
1501 int len;
1502
1503 /* Monitor control fd to detect if the slave client exits */
1504 if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) {
1505 len = read(c->ctl_fd, buf, sizeof(buf));
1506 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1507 return 1;
1508 if (len <= 0) {
1509 debug2("channel %d: ctl read<=0", c->self);
1510 if (c->type != SSH_CHANNEL_OPEN) {
1511 debug2("channel %d: not open", c->self);
1512 chan_mark_dead(c);
1513 return -1;
1514 } else {
1515 chan_read_failed(c);
1516 chan_write_failed(c);
1517 }
1518 return -1;
1519 } else
1520 fatal("%s: unexpected data on ctl fd", __func__);
1521 }
1522 return 1;
1523}
1524static int
1485channel_check_window(Channel *c) 1525channel_check_window(Channel *c)
1486{ 1526{
1487 if (c->type == SSH_CHANNEL_OPEN && 1527 if (c->type == SSH_CHANNEL_OPEN &&
@@ -1511,6 +1551,7 @@ channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
1511 if (!compat20) 1551 if (!compat20)
1512 return; 1552 return;
1513 channel_handle_efd(c, readset, writeset); 1553 channel_handle_efd(c, readset, writeset);
1554 channel_handle_ctl(c, readset, writeset);
1514 channel_check_window(c); 1555 channel_check_window(c);
1515} 1556}
1516 1557
@@ -1635,7 +1676,7 @@ static void
1635channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) 1676channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1636{ 1677{
1637 static int did_init = 0; 1678 static int did_init = 0;
1638 int i; 1679 u_int i;
1639 Channel *c; 1680 Channel *c;
1640 1681
1641 if (!did_init) { 1682 if (!did_init) {
@@ -1658,10 +1699,9 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1658 */ 1699 */
1659void 1700void
1660channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, 1701channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
1661 int *nallocp, int rekeying) 1702 u_int *nallocp, int rekeying)
1662{ 1703{
1663 int n; 1704 u_int n, sz;
1664 u_int sz;
1665 1705
1666 n = MAX(*maxfdp, channel_max_fd); 1706 n = MAX(*maxfdp, channel_max_fd);
1667 1707
@@ -1697,8 +1737,7 @@ void
1697channel_output_poll(void) 1737channel_output_poll(void)
1698{ 1738{
1699 Channel *c; 1739 Channel *c;
1700 int i; 1740 u_int i, len;
1701 u_int len;
1702 1741
1703 for (i = 0; i < channels_alloc; i++) { 1742 for (i = 0; i < channels_alloc; i++) {
1704 c = channels[i]; 1743 c = channels[i];
@@ -2011,7 +2050,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
2011 c->remote_maxpacket = packet_get_int(); 2050 c->remote_maxpacket = packet_get_int();
2012 if (c->confirm) { 2051 if (c->confirm) {
2013 debug2("callback start"); 2052 debug2("callback start");
2014 c->confirm(c->self, NULL); 2053 c->confirm(c->self, c->confirm_ctx);
2015 debug2("callback done"); 2054 debug2("callback done");
2016 } 2055 }
2017 debug2("channel %d: open confirm rwindow %u rmax %u", c->self, 2056 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
@@ -2228,6 +2267,27 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2228 return success; 2267 return success;
2229} 2268}
2230 2269
2270int
2271channel_cancel_rport_listener(const char *host, u_short port)
2272{
2273 u_int i;
2274 int found = 0;
2275
2276 for(i = 0; i < channels_alloc; i++) {
2277 Channel *c = channels[i];
2278
2279 if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
2280 strncmp(c->path, host, sizeof(c->path)) == 0 &&
2281 c->listening_port == port) {
2282 debug2("%s: close clannel %d", __func__, i);
2283 channel_free(c);
2284 found = 1;
2285 }
2286 }
2287
2288 return (found);
2289}
2290
2231/* protocol local port fwd, used by ssh (and sshd in v1) */ 2291/* protocol local port fwd, used by ssh (and sshd in v1) */
2232int 2292int
2233channel_setup_local_fwd_listener(u_short listen_port, 2293channel_setup_local_fwd_listener(u_short listen_port,
@@ -2305,6 +2365,41 @@ channel_request_remote_forwarding(u_short listen_port,
2305} 2365}
2306 2366
2307/* 2367/*
2368 * Request cancellation of remote forwarding of connection host:port from
2369 * local side.
2370 */
2371void
2372channel_request_rforward_cancel(u_short port)
2373{
2374 int i;
2375 const char *address_to_bind = "0.0.0.0";
2376
2377 if (!compat20)
2378 return;
2379
2380 for (i = 0; i < num_permitted_opens; i++) {
2381 if (permitted_opens[i].host_to_connect != NULL &&
2382 permitted_opens[i].listen_port == port)
2383 break;
2384 }
2385 if (i >= num_permitted_opens) {
2386 debug("%s: requested forward not found", __func__);
2387 return;
2388 }
2389 packet_start(SSH2_MSG_GLOBAL_REQUEST);
2390 packet_put_cstring("cancel-tcpip-forward");
2391 packet_put_char(0);
2392 packet_put_cstring(address_to_bind);
2393 packet_put_int(port);
2394 packet_send();
2395
2396 permitted_opens[i].listen_port = 0;
2397 permitted_opens[i].port_to_connect = 0;
2398 free(permitted_opens[i].host_to_connect);
2399 permitted_opens[i].host_to_connect = NULL;
2400}
2401
2402/*
2308 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates 2403 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
2309 * listening for the port, and sends back a success reply (or disconnect 2404 * listening for the port, and sends back a success reply (or disconnect
2310 * message if there was an error). This never returns if there was an error. 2405 * message if there was an error). This never returns if there was an error.
@@ -2373,7 +2468,8 @@ channel_clear_permitted_opens(void)
2373 int i; 2468 int i;
2374 2469
2375 for (i = 0; i < num_permitted_opens; i++) 2470 for (i = 0; i < num_permitted_opens; i++)
2376 xfree(permitted_opens[i].host_to_connect); 2471 if (permitted_opens[i].host_to_connect != NULL)
2472 xfree(permitted_opens[i].host_to_connect);
2377 num_permitted_opens = 0; 2473 num_permitted_opens = 0;
2378 2474
2379} 2475}
@@ -2413,8 +2509,8 @@ connect_to(const char *host, u_short port)
2413 verbose("socket: %.100s", strerror(errno)); 2509 verbose("socket: %.100s", strerror(errno));
2414 continue; 2510 continue;
2415 } 2511 }
2416 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) 2512 if (set_nonblock(sock) == -1)
2417 fatal("connect_to: F_SETFL: %s", strerror(errno)); 2513 fatal("%s: set_nonblock(%d)", __func__, sock);
2418 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && 2514 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 &&
2419 errno != EINPROGRESS) { 2515 errno != EINPROGRESS) {
2420 error("connect_to %.100s port %s: %.100s", ntop, strport, 2516 error("connect_to %.100s port %s: %.100s", ntop, strport,
@@ -2441,7 +2537,8 @@ channel_connect_by_listen_address(u_short listen_port)
2441 int i; 2537 int i;
2442 2538
2443 for (i = 0; i < num_permitted_opens; i++) 2539 for (i = 0; i < num_permitted_opens; i++)
2444 if (permitted_opens[i].listen_port == listen_port) 2540 if (permitted_opens[i].host_to_connect != NULL &&
2541 permitted_opens[i].listen_port == listen_port)
2445 return connect_to( 2542 return connect_to(
2446 permitted_opens[i].host_to_connect, 2543 permitted_opens[i].host_to_connect,
2447 permitted_opens[i].port_to_connect); 2544 permitted_opens[i].port_to_connect);
@@ -2459,7 +2556,8 @@ channel_connect_to(const char *host, u_short port)
2459 permit = all_opens_permitted; 2556 permit = all_opens_permitted;
2460 if (!permit) { 2557 if (!permit) {
2461 for (i = 0; i < num_permitted_opens; i++) 2558 for (i = 0; i < num_permitted_opens; i++)
2462 if (permitted_opens[i].port_to_connect == port && 2559 if (permitted_opens[i].host_to_connect != NULL &&
2560 permitted_opens[i].port_to_connect == port &&
2463 strcmp(permitted_opens[i].host_to_connect, host) == 0) 2561 strcmp(permitted_opens[i].host_to_connect, host) == 0)
2464 permit = 1; 2562 permit = 1;
2465 2563
@@ -2472,6 +2570,27 @@ channel_connect_to(const char *host, u_short port)
2472 return connect_to(host, port); 2570 return connect_to(host, port);
2473} 2571}
2474 2572
2573void
2574channel_send_window_changes(void)
2575{
2576 u_int i;
2577 struct winsize ws;
2578
2579 for (i = 0; i < channels_alloc; i++) {
2580 if (channels[i] == NULL ||
2581 channels[i]->type != SSH_CHANNEL_OPEN)
2582 continue;
2583 if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
2584 continue;
2585 channel_request_start(i, "window-change", 0);
2586 packet_put_int(ws.ws_col);
2587 packet_put_int(ws.ws_row);
2588 packet_put_int(ws.ws_xpixel);
2589 packet_put_int(ws.ws_ypixel);
2590 packet_send();
2591 }
2592}
2593
2475/* -- X11 forwarding */ 2594/* -- X11 forwarding */
2476 2595
2477/* 2596/*
@@ -2511,6 +2630,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2511 if (sock < 0) { 2630 if (sock < 0) {
2512 if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { 2631 if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) {
2513 error("socket: %.100s", strerror(errno)); 2632 error("socket: %.100s", strerror(errno));
2633 freeaddrinfo(aitop);
2514 return -1; 2634 return -1;
2515 } else { 2635 } else {
2516 debug("x11_create_display_inet: Socket family %d not supported", 2636 debug("x11_create_display_inet: Socket family %d not supported",
@@ -2783,7 +2903,7 @@ x11_request_forwarding_with_spoofing(int client_session_id,
2783 char *new_data; 2903 char *new_data;
2784 int screen_number; 2904 int screen_number;
2785 const char *cp; 2905 const char *cp;
2786 u_int32_t rand = 0; 2906 u_int32_t rnd = 0;
2787 2907
2788 cp = getenv("DISPLAY"); 2908 cp = getenv("DISPLAY");
2789 if (cp) 2909 if (cp)
@@ -2808,10 +2928,10 @@ x11_request_forwarding_with_spoofing(int client_session_id,
2808 if (sscanf(data + 2 * i, "%2x", &value) != 1) 2928 if (sscanf(data + 2 * i, "%2x", &value) != 1)
2809 fatal("x11_request_forwarding: bad authentication data: %.100s", data); 2929 fatal("x11_request_forwarding: bad authentication data: %.100s", data);
2810 if (i % 4 == 0) 2930 if (i % 4 == 0)
2811 rand = arc4random(); 2931 rnd = arc4random();
2812 x11_saved_data[i] = value; 2932 x11_saved_data[i] = value;
2813 x11_fake_data[i] = rand & 0xff; 2933 x11_fake_data[i] = rnd & 0xff;
2814 rand >>= 8; 2934 rnd >>= 8;
2815 } 2935 }
2816 x11_saved_data_len = data_len; 2936 x11_saved_data_len = data_len;
2817 x11_fake_data_len = data_len; 2937 x11_fake_data_len = data_len;