]> andersk Git - openssh.git/blame - channels.c
- deraadt@cvs.openbsd.org 2002/07/04 04:15:33
[openssh.git] / channels.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5260325f 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5260325f 5 * This file contains functions for generic socket connection forwarding.
6 * There is also code for initiating connection forwarding for X11 connections,
7 * arbitrary tcp/ip connections, and the authentication agent connection.
6ae2364d 8 *
bcbf86ec 9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 *
7e7327a1 15 * SSH2 support added by Markus Friedl.
8341f420 16 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
bcbf86ec 17 * Copyright (c) 1999 Dug Song. All rights reserved.
18 * Copyright (c) 1999 Theo de Raadt. All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
34 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5260325f 39 */
8efc0c15 40
41#include "includes.h"
5df8c731 42RCSID("$OpenBSD: channels.c,v 1.179 2002/06/26 08:55:02 markus Exp $");
8efc0c15 43
44#include "ssh.h"
42f11eb2 45#include "ssh1.h"
46#include "ssh2.h"
8efc0c15 47#include "packet.h"
48#include "xmalloc.h"
42f11eb2 49#include "log.h"
50#include "misc.h"
8efc0c15 51#include "channels.h"
8efc0c15 52#include "compat.h"
42f11eb2 53#include "canohost.h"
4c8722d9 54#include "key.h"
55#include "authfd.h"
805e659f 56#include "pathnames.h"
7e7327a1 57
8efc0c15 58
8e7895b8 59/* -- channel core */
8efc0c15 60
aa3378df 61/*
62 * Pointer to an array containing all allocated channels. The array is
63 * dynamically extended as needed.
64 */
719fc62f 65static Channel **channels = NULL;
8efc0c15 66
aa3378df 67/*
68 * Size of the channel array. All slots of the array must always be
719fc62f 69 * initialized (at least the type field); unused slots set to NULL
aa3378df 70 */
8efc0c15 71static int channels_alloc = 0;
72
aa3378df 73/*
74 * Maximum file descriptor value used in any of the channels. This is
719fc62f 75 * updated in channel_new.
aa3378df 76 */
39929cdb 77static int channel_max_fd = 0;
8efc0c15 78
8efc0c15 79
8e7895b8 80/* -- tcp forwarding */
8efc0c15 81
aa3378df 82/*
83 * Data structure for storing which hosts are permitted for forward requests.
84 * The local sides of any remote forwards are stored in this array to prevent
85 * a corrupt remote server from accessing arbitrary TCP/IP ports on our local
86 * network (which might be behind a firewall).
87 */
5260325f 88typedef struct {
7368a6c8 89 char *host_to_connect; /* Connect to 'host'. */
90 u_short port_to_connect; /* Connect to 'port'. */
91 u_short listen_port; /* Remote side should listen port number. */
8efc0c15 92} ForwardPermission;
93
94/* List of all permitted host/port pairs to connect. */
95static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
8e7895b8 96
8efc0c15 97/* Number of permitted host/port pairs in the array. */
98static int num_permitted_opens = 0;
aa3378df 99/*
100 * If this is true, all opens are permitted. This is the case on the server
101 * on which we have to trust the client anyway, and the user could do
102 * anything after logging in anyway.
103 */
8efc0c15 104static int all_opens_permitted = 0;
105
8efc0c15 106
8e7895b8 107/* -- X11 forwarding */
42f11eb2 108
8e7895b8 109/* Maximum number of fake X11 displays to try. */
110#define MAX_DISPLAYS 1000
0490e609 111
8e7895b8 112/* Saved X11 authentication protocol name. */
113static char *x11_saved_proto = NULL;
8efc0c15 114
8e7895b8 115/* Saved X11 authentication data. This is the real data. */
116static char *x11_saved_data = NULL;
117static u_int x11_saved_data_len = 0;
118
119/*
120 * Fake X11 authentication data. This is what the server will be sending us;
121 * we should replace any occurrences of this by the real data.
122 */
123static char *x11_fake_data = NULL;
124static u_int x11_fake_data_len;
125
126
127/* -- agent forwarding */
8efc0c15 128
8e7895b8 129#define NUM_SOCKS 10
130
8e7895b8 131/* AF_UNSPEC or AF_INET or AF_INET6 */
5e4a7219 132static int IPv4or6 = AF_UNSPEC;
8e7895b8 133
134/* helper */
396c147e 135static void port_open_helper(Channel *c, char *rtype);
8e7895b8 136
137/* -- channel core */
7368a6c8 138
139Channel *
140channel_lookup(int id)
141{
142 Channel *c;
719fc62f 143
c77d2e56 144 if (id < 0 || id >= channels_alloc) {
7368a6c8 145 log("channel_lookup: %d: bad id", id);
146 return NULL;
147 }
719fc62f 148 c = channels[id];
149 if (c == NULL) {
7368a6c8 150 log("channel_lookup: %d: bad id: channel free", id);
151 return NULL;
152 }
153 return c;
154}
155
aa3378df 156/*
1d1ffb87 157 * Register filedescriptors for a channel, used when allocating a channel or
0fbe8c74 158 * when the channel consumer/producer is ready, e.g. shell exec'd
aa3378df 159 */
8efc0c15 160
396c147e 161static void
a22aff1f 162channel_register_fds(Channel *c, int rfd, int wfd, int efd,
163 int extusage, int nonblock)
8efc0c15 164{
5260325f 165 /* Update the maximum file descriptor value. */
39929cdb 166 channel_max_fd = MAX(channel_max_fd, rfd);
167 channel_max_fd = MAX(channel_max_fd, wfd);
168 channel_max_fd = MAX(channel_max_fd, efd);
169
aa3378df 170 /* XXX set close-on-exec -markus */
1d1ffb87 171
0fbe8c74 172 c->rfd = rfd;
173 c->wfd = wfd;
174 c->sock = (rfd == wfd) ? rfd : -1;
175 c->efd = efd;
176 c->extended_usage = extusage;
a22aff1f 177
0ae4fe1d 178 /* XXX ugly hack: nonblock is only set by the server */
179 if (nonblock && isatty(c->rfd)) {
94dfb550 180 debug("channel %d: rfd %d isatty", c->self, c->rfd);
0ae4fe1d 181 c->isatty = 1;
182 if (!isatty(c->wfd)) {
94dfb550 183 error("channel %d: wfd %d is not a tty?",
0ae4fe1d 184 c->self, c->wfd);
185 }
186 } else {
187 c->isatty = 0;
188 }
189
a22aff1f 190 /* enable nonblocking mode */
191 if (nonblock) {
192 if (rfd != -1)
193 set_nonblock(rfd);
194 if (wfd != -1)
195 set_nonblock(wfd);
196 if (efd != -1)
197 set_nonblock(efd);
198 }
0fbe8c74 199}
200
201/*
202 * Allocate a new channel object and set its type and socket. This will cause
203 * remote_name to be freed.
204 */
205
719fc62f 206Channel *
0fbe8c74 207channel_new(char *ctype, int type, int rfd, int wfd, int efd,
f91d9a89 208 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
0fbe8c74 209{
210 int i, found;
211 Channel *c;
5260325f 212
213 /* Do initial allocation if this is the first call. */
214 if (channels_alloc == 0) {
215 channels_alloc = 10;
719fc62f 216 channels = xmalloc(channels_alloc * sizeof(Channel *));
5260325f 217 for (i = 0; i < channels_alloc; i++)
719fc62f 218 channels[i] = NULL;
d6746a0b 219 fatal_add_cleanup((void (*) (void *)) channel_free_all, NULL);
5260325f 220 }
221 /* Try to find a free slot where to put the new channel. */
222 for (found = -1, i = 0; i < channels_alloc; i++)
719fc62f 223 if (channels[i] == NULL) {
5260325f 224 /* Found a free slot. */
225 found = i;
226 break;
227 }
228 if (found == -1) {
aa3378df 229 /* There are no free slots. Take last+1 slot and expand the array. */
5260325f 230 found = channels_alloc;
231 channels_alloc += 10;
5df8c731 232 if (channels_alloc > 10000)
233 fatal("channel_new: internal error: channels_alloc %d "
234 "too big.", channels_alloc);
de273eef 235 debug2("channel: expanding %d", channels_alloc);
719fc62f 236 channels = xrealloc(channels, channels_alloc * sizeof(Channel *));
5260325f 237 for (i = found; i < channels_alloc; i++)
719fc62f 238 channels[i] = NULL;
5260325f 239 }
719fc62f 240 /* Initialize and return new channel. */
241 c = channels[found] = xmalloc(sizeof(Channel));
639cb8ab 242 memset(c, 0, sizeof(Channel));
5260325f 243 buffer_init(&c->input);
244 buffer_init(&c->output);
7368a6c8 245 buffer_init(&c->extended);
70bef40e 246 c->ostate = CHAN_OUTPUT_OPEN;
247 c->istate = CHAN_INPUT_OPEN;
248 c->flags = 0;
a22aff1f 249 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
5260325f 250 c->self = found;
251 c->type = type;
7368a6c8 252 c->ctype = ctype;
0b242b12 253 c->local_window = window;
254 c->local_window_max = window;
255 c->local_consumed = 0;
256 c->local_maxpacket = maxpack;
5260325f 257 c->remote_id = -1;
258 c->remote_name = remote_name;
7368a6c8 259 c->remote_window = 0;
260 c->remote_maxpacket = 0;
a5f82435 261 c->force_drain = 0;
ac151b18 262 c->single_connection = 0;
3cf2be58 263 c->detach_user = NULL;
05ca0898 264 c->confirm = NULL;
2e73a022 265 c->input_filter = NULL;
5260325f 266 debug("channel %d: new [%s]", found, remote_name);
719fc62f 267 return c;
7368a6c8 268}
8efc0c15 269
489aa2e9 270static int
271channel_find_maxfd(void)
272{
273 int i, max = 0;
274 Channel *c;
275
276 for (i = 0; i < channels_alloc; i++) {
277 c = channels[i];
278 if (c != NULL) {
279 max = MAX(max, c->rfd);
280 max = MAX(max, c->wfd);
281 max = MAX(max, c->efd);
282 }
283 }
284 return max;
285}
286
287int
288channel_close_fd(int *fdp)
289{
290 int ret = 0, fd = *fdp;
291
292 if (fd != -1) {
293 ret = close(fd);
294 *fdp = -1;
295 if (fd == channel_max_fd)
296 channel_max_fd = channel_find_maxfd();
297 }
298 return ret;
299}
300
0fbe8c74 301/* Close all channel fd/socket. */
302
396c147e 303static void
0fbe8c74 304channel_close_fds(Channel *c)
305{
6fd8622b 306 debug3("channel_close_fds: channel %d: r %d w %d e %d",
307 c->self, c->rfd, c->wfd, c->efd);
308
489aa2e9 309 channel_close_fd(&c->sock);
310 channel_close_fd(&c->rfd);
311 channel_close_fd(&c->wfd);
312 channel_close_fd(&c->efd);
0fbe8c74 313}
314
8e7895b8 315/* Free the channel and close its fd/socket. */
316
317void
318channel_free(Channel *c)
319{
320 char *s;
321 int i, n;
322
323 for (n = 0, i = 0; i < channels_alloc; i++)
324 if (channels[i])
325 n++;
326 debug("channel_free: channel %d: %s, nchannels %d", c->self,
327 c->remote_name ? c->remote_name : "???", n);
328
329 s = channel_open_message();
330 debug3("channel_free: status: %s", s);
331 xfree(s);
332
8e7895b8 333 if (c->sock != -1)
334 shutdown(c->sock, SHUT_RDWR);
335 channel_close_fds(c);
336 buffer_free(&c->input);
337 buffer_free(&c->output);
338 buffer_free(&c->extended);
339 if (c->remote_name) {
340 xfree(c->remote_name);
341 c->remote_name = NULL;
342 }
343 channels[c->self] = NULL;
344 xfree(c);
345}
346
8e7895b8 347void
d6746a0b 348channel_free_all(void)
8e7895b8 349{
350 int i;
8e7895b8 351
d6746a0b 352 for (i = 0; i < channels_alloc; i++)
353 if (channels[i] != NULL)
354 channel_free(channels[i]);
8e7895b8 355}
356
357/*
358 * Closes the sockets/fds of all channels. This is used to close extra file
359 * descriptors after a fork.
360 */
361
362void
d5bb9418 363channel_close_all(void)
8e7895b8 364{
365 int i;
366
367 for (i = 0; i < channels_alloc; i++)
368 if (channels[i] != NULL)
369 channel_close_fds(channels[i]);
370}
371
3cf2be58 372/*
373 * Stop listening to channels.
374 */
375
376void
377channel_stop_listening(void)
378{
379 int i;
380 Channel *c;
381
382 for (i = 0; i < channels_alloc; i++) {
383 c = channels[i];
384 if (c != NULL) {
385 switch (c->type) {
386 case SSH_CHANNEL_AUTH_SOCKET:
387 case SSH_CHANNEL_PORT_LISTENER:
388 case SSH_CHANNEL_RPORT_LISTENER:
389 case SSH_CHANNEL_X11_LISTENER:
489aa2e9 390 channel_close_fd(&c->sock);
3cf2be58 391 channel_free(c);
392 break;
393 }
394 }
395 }
396}
397
8e7895b8 398/*
399 * Returns true if no channel has too much buffered data, and false if one or
400 * more channel is overfull.
401 */
402
403int
d5bb9418 404channel_not_very_much_buffered_data(void)
8e7895b8 405{
406 u_int i;
407 Channel *c;
408
409 for (i = 0; i < channels_alloc; i++) {
410 c = channels[i];
411 if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
0c139bd1 412#if 0
413 if (!compat20 &&
414 buffer_len(&c->input) > packet_get_maxsize()) {
8e7895b8 415 debug("channel %d: big input buffer %d",
416 c->self, buffer_len(&c->input));
417 return 0;
418 }
0c139bd1 419#endif
8e7895b8 420 if (buffer_len(&c->output) > packet_get_maxsize()) {
0c139bd1 421 debug("channel %d: big output buffer %d > %d",
422 c->self, buffer_len(&c->output),
423 packet_get_maxsize());
8e7895b8 424 return 0;
425 }
426 }
427 }
428 return 1;
429}
430
431/* Returns true if any channel is still open. */
432
433int
d5bb9418 434channel_still_open(void)
8e7895b8 435{
436 int i;
437 Channel *c;
438
439 for (i = 0; i < channels_alloc; i++) {
440 c = channels[i];
441 if (c == NULL)
442 continue;
443 switch (c->type) {
444 case SSH_CHANNEL_X11_LISTENER:
445 case SSH_CHANNEL_PORT_LISTENER:
446 case SSH_CHANNEL_RPORT_LISTENER:
447 case SSH_CHANNEL_CLOSED:
448 case SSH_CHANNEL_AUTH_SOCKET:
449 case SSH_CHANNEL_DYNAMIC:
450 case SSH_CHANNEL_CONNECTING:
451 case SSH_CHANNEL_ZOMBIE:
452 continue;
453 case SSH_CHANNEL_LARVAL:
454 if (!compat20)
455 fatal("cannot happen: SSH_CHANNEL_LARVAL");
456 continue;
457 case SSH_CHANNEL_OPENING:
458 case SSH_CHANNEL_OPEN:
459 case SSH_CHANNEL_X11_OPEN:
460 return 1;
461 case SSH_CHANNEL_INPUT_DRAINING:
462 case SSH_CHANNEL_OUTPUT_DRAINING:
463 if (!compat13)
464 fatal("cannot happen: OUT_DRAIN");
465 return 1;
466 default:
467 fatal("channel_still_open: bad channel type %d", c->type);
468 /* NOTREACHED */
469 }
470 }
471 return 0;
472}
473
474/* Returns the id of an open channel suitable for keepaliving */
475
476int
d5bb9418 477channel_find_open(void)
8e7895b8 478{
479 int i;
480 Channel *c;
481
482 for (i = 0; i < channels_alloc; i++) {
483 c = channels[i];
484 if (c == NULL)
485 continue;
486 switch (c->type) {
487 case SSH_CHANNEL_CLOSED:
488 case SSH_CHANNEL_DYNAMIC:
489 case SSH_CHANNEL_X11_LISTENER:
490 case SSH_CHANNEL_PORT_LISTENER:
491 case SSH_CHANNEL_RPORT_LISTENER:
492 case SSH_CHANNEL_OPENING:
493 case SSH_CHANNEL_CONNECTING:
494 case SSH_CHANNEL_ZOMBIE:
495 continue;
496 case SSH_CHANNEL_LARVAL:
497 case SSH_CHANNEL_AUTH_SOCKET:
498 case SSH_CHANNEL_OPEN:
499 case SSH_CHANNEL_X11_OPEN:
500 return i;
501 case SSH_CHANNEL_INPUT_DRAINING:
502 case SSH_CHANNEL_OUTPUT_DRAINING:
503 if (!compat13)
504 fatal("cannot happen: OUT_DRAIN");
505 return i;
506 default:
507 fatal("channel_find_open: bad channel type %d", c->type);
508 /* NOTREACHED */
509 }
510 }
511 return -1;
512}
513
514
515/*
516 * Returns a message describing the currently open forwarded connections,
517 * suitable for sending to the client. The message contains crlf pairs for
518 * newlines.
519 */
520
521char *
d5bb9418 522channel_open_message(void)
8e7895b8 523{
524 Buffer buffer;
525 Channel *c;
526 char buf[1024], *cp;
527 int i;
528
529 buffer_init(&buffer);
530 snprintf(buf, sizeof buf, "The following connections are open:\r\n");
531 buffer_append(&buffer, buf, strlen(buf));
532 for (i = 0; i < channels_alloc; i++) {
533 c = channels[i];
534 if (c == NULL)
535 continue;
536 switch (c->type) {
537 case SSH_CHANNEL_X11_LISTENER:
538 case SSH_CHANNEL_PORT_LISTENER:
539 case SSH_CHANNEL_RPORT_LISTENER:
540 case SSH_CHANNEL_CLOSED:
541 case SSH_CHANNEL_AUTH_SOCKET:
542 case SSH_CHANNEL_ZOMBIE:
543 continue;
544 case SSH_CHANNEL_LARVAL:
545 case SSH_CHANNEL_OPENING:
546 case SSH_CHANNEL_CONNECTING:
547 case SSH_CHANNEL_DYNAMIC:
548 case SSH_CHANNEL_OPEN:
549 case SSH_CHANNEL_X11_OPEN:
550 case SSH_CHANNEL_INPUT_DRAINING:
551 case SSH_CHANNEL_OUTPUT_DRAINING:
552 snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n",
553 c->self, c->remote_name,
554 c->type, c->remote_id,
555 c->istate, buffer_len(&c->input),
556 c->ostate, buffer_len(&c->output),
557 c->rfd, c->wfd);
558 buffer_append(&buffer, buf, strlen(buf));
559 continue;
560 default:
561 fatal("channel_open_message: bad channel type %d", c->type);
562 /* NOTREACHED */
563 }
564 }
565 buffer_append(&buffer, "\0", 1);
566 cp = xstrdup(buffer_ptr(&buffer));
567 buffer_free(&buffer);
568 return cp;
569}
570
571void
572channel_send_open(int id)
573{
574 Channel *c = channel_lookup(id);
575 if (c == NULL) {
576 log("channel_send_open: %d: bad id", id);
577 return;
578 }
579 debug("send channel open %d", id);
580 packet_start(SSH2_MSG_CHANNEL_OPEN);
581 packet_put_cstring(c->ctype);
582 packet_put_int(c->self);
583 packet_put_int(c->local_window);
584 packet_put_int(c->local_maxpacket);
585 packet_send();
586}
587
588void
06ee33fb 589channel_request_start(int local_id, char *service, int wantconfirm)
8e7895b8 590{
06ee33fb 591 Channel *c = channel_lookup(local_id);
8e7895b8 592 if (c == NULL) {
06ee33fb 593 log("channel_request_start: %d: unknown channel id", local_id);
8e7895b8 594 return;
595 }
06ee33fb 596 debug("channel request %d: %s", local_id, service) ;
8e7895b8 597 packet_start(SSH2_MSG_CHANNEL_REQUEST);
598 packet_put_int(c->remote_id);
599 packet_put_cstring(service);
600 packet_put_char(wantconfirm);
601}
602void
05ca0898 603channel_register_confirm(int id, channel_callback_fn *fn)
8e7895b8 604{
605 Channel *c = channel_lookup(id);
606 if (c == NULL) {
05ca0898 607 log("channel_register_comfirm: %d: bad id", id);
8e7895b8 608 return;
609 }
05ca0898 610 c->confirm = fn;
8e7895b8 611}
612void
613channel_register_cleanup(int id, channel_callback_fn *fn)
614{
615 Channel *c = channel_lookup(id);
616 if (c == NULL) {
617 log("channel_register_cleanup: %d: bad id", id);
618 return;
619 }
3cf2be58 620 c->detach_user = fn;
8e7895b8 621}
622void
623channel_cancel_cleanup(int id)
624{
625 Channel *c = channel_lookup(id);
626 if (c == NULL) {
627 log("channel_cancel_cleanup: %d: bad id", id);
628 return;
629 }
3cf2be58 630 c->detach_user = NULL;
8e7895b8 631}
632void
633channel_register_filter(int id, channel_filter_fn *fn)
634{
635 Channel *c = channel_lookup(id);
636 if (c == NULL) {
637 log("channel_register_filter: %d: bad id", id);
638 return;
639 }
640 c->input_filter = fn;
641}
642
6ae2364d 643void
8e7895b8 644channel_set_fds(int id, int rfd, int wfd, int efd,
399d1ea6 645 int extusage, int nonblock, u_int window_max)
8efc0c15 646{
8e7895b8 647 Channel *c = channel_lookup(id);
648 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
649 fatal("channel_activate for non-larval channel %d.", id);
650 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
651 c->type = SSH_CHANNEL_OPEN;
399d1ea6 652 c->local_window = c->local_window_max = window_max;
8e7895b8 653 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
654 packet_put_int(c->remote_id);
655 packet_put_int(c->local_window);
656 packet_send();
8efc0c15 657}
658
aa3378df 659/*
7368a6c8 660 * 'channel_pre*' are called just before select() to add any bits relevant to
661 * channels in the select bitmasks.
aa3378df 662 */
7368a6c8 663/*
664 * 'channel_post*': perform any appropriate operations for channels which
665 * have events pending.
666 */
667typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset);
668chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];
669chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];
8efc0c15 670
396c147e 671static void
7368a6c8 672channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset)
8efc0c15 673{
7368a6c8 674 FD_SET(c->sock, readset);
675}
5260325f 676
396c147e 677static void
97fb6912 678channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset)
679{
680 debug3("channel %d: waiting for connection", c->self);
681 FD_SET(c->sock, writeset);
682}
683
396c147e 684static void
7368a6c8 685channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
686{
687 if (buffer_len(&c->input) < packet_get_maxsize())
688 FD_SET(c->sock, readset);
689 if (buffer_len(&c->output) > 0)
690 FD_SET(c->sock, writeset);
691}
5260325f 692
396c147e 693static void
0c0738d5 694channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
7368a6c8 695{
0c0738d5 696 u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
5260325f 697
7e7327a1 698 if (c->istate == CHAN_INPUT_OPEN &&
0c0738d5 699 limit > 0 &&
700 buffer_len(&c->input) < limit)
7e7327a1 701 FD_SET(c->rfd, readset);
702 if (c->ostate == CHAN_OUTPUT_OPEN ||
703 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
704 if (buffer_len(&c->output) > 0) {
705 FD_SET(c->wfd, writeset);
706 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
d2296ed7 707 if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
875ec275 708 debug2("channel %d: obuf_empty delayed efd %d/(%d)",
709 c->self, c->efd, buffer_len(&c->extended));
d2296ed7 710 else
711 chan_obuf_empty(c);
7e7327a1 712 }
713 }
714 /** XXX check close conditions, too */
0c0738d5 715 if (compat20 && c->efd != -1) {
7e7327a1 716 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
717 buffer_len(&c->extended) > 0)
718 FD_SET(c->efd, writeset);
d2296ed7 719 else if (!(c->flags & CHAN_EOF_SENT) &&
720 c->extended_usage == CHAN_EXTENDED_READ &&
7e7327a1 721 buffer_len(&c->extended) < c->remote_window)
722 FD_SET(c->efd, readset);
723 }
724}
725
396c147e 726static void
7368a6c8 727channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
728{
729 if (buffer_len(&c->input) == 0) {
730 packet_start(SSH_MSG_CHANNEL_CLOSE);
731 packet_put_int(c->remote_id);
732 packet_send();
733 c->type = SSH_CHANNEL_CLOSED;
070adba2 734 debug("channel %d: closing after input drain.", c->self);
7368a6c8 735 }
736}
5260325f 737
396c147e 738static void
7368a6c8 739channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
740{
741 if (buffer_len(&c->output) == 0)
719fc62f 742 chan_mark_dead(c);
6ae2364d 743 else
7368a6c8 744 FD_SET(c->sock, writeset);
745}
5260325f 746
7368a6c8 747/*
748 * This is a special state for X11 authentication spoofing. An opened X11
749 * connection (when authentication spoofing is being done) remains in this
750 * state until the first packet has been completely read. The authentication
751 * data in that packet is then substituted by the real data if it matches the
752 * fake data, and the channel is put into normal mode.
0b242b12 753 * XXX All this happens at the client side.
8e7895b8 754 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
7368a6c8 755 */
396c147e 756static int
8e7895b8 757x11_open_helper(Buffer *b)
7368a6c8 758{
1e3b8b07 759 u_char *ucp;
760 u_int proto_len, data_len;
5260325f 761
7368a6c8 762 /* Check if the fixed size part of the packet is in buffer. */
8e7895b8 763 if (buffer_len(b) < 12)
7368a6c8 764 return 0;
765
766 /* Parse the lengths of variable-length fields. */
20905a8e 767 ucp = buffer_ptr(b);
7368a6c8 768 if (ucp[0] == 0x42) { /* Byte order MSB first. */
769 proto_len = 256 * ucp[6] + ucp[7];
770 data_len = 256 * ucp[8] + ucp[9];
771 } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */
772 proto_len = ucp[6] + 256 * ucp[7];
773 data_len = ucp[8] + 256 * ucp[9];
774 } else {
775 debug("Initial X11 packet contains bad byte order byte: 0x%x",
184eed6a 776 ucp[0]);
7368a6c8 777 return -1;
778 }
5260325f 779
7368a6c8 780 /* Check if the whole packet is in buffer. */
8e7895b8 781 if (buffer_len(b) <
7368a6c8 782 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
783 return 0;
5260325f 784
7368a6c8 785 /* Check if authentication protocol matches. */
786 if (proto_len != strlen(x11_saved_proto) ||
787 memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {
788 debug("X11 connection uses different authentication protocol.");
789 return -1;
790 }
791 /* Check if authentication data matches our fake data. */
792 if (data_len != x11_fake_data_len ||
793 memcmp(ucp + 12 + ((proto_len + 3) & ~3),
794 x11_fake_data, x11_fake_data_len) != 0) {
795 debug("X11 auth data does not match fake data.");
796 return -1;
797 }
798 /* Check fake data length */
799 if (x11_fake_data_len != x11_saved_data_len) {
800 error("X11 fake_data_len %d != saved_data_len %d",
801 x11_fake_data_len, x11_saved_data_len);
802 return -1;
803 }
804 /*
805 * Received authentication protocol and data match
806 * our fake data. Substitute the fake data with real
807 * data.
808 */
809 memcpy(ucp + 12 + ((proto_len + 3) & ~3),
810 x11_saved_data, x11_saved_data_len);
811 return 1;
812}
5260325f 813
396c147e 814static void
7368a6c8 815channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
816{
8e7895b8 817 int ret = x11_open_helper(&c->output);
7368a6c8 818 if (ret == 1) {
819 /* Start normal processing for the channel. */
820 c->type = SSH_CHANNEL_OPEN;
a8be9f80 821 channel_pre_open_13(c, readset, writeset);
7368a6c8 822 } else if (ret == -1) {
823 /*
824 * We have received an X11 connection that has bad
825 * authentication information.
826 */
54b974dc 827 log("X11 connection rejected because of wrong authentication.");
7368a6c8 828 buffer_clear(&c->input);
829 buffer_clear(&c->output);
489aa2e9 830 channel_close_fd(&c->sock);
7368a6c8 831 c->sock = -1;
832 c->type = SSH_CHANNEL_CLOSED;
833 packet_start(SSH_MSG_CHANNEL_CLOSE);
834 packet_put_int(c->remote_id);
835 packet_send();
836 }
837}
5260325f 838
396c147e 839static void
0b242b12 840channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
7368a6c8 841{
8e7895b8 842 int ret = x11_open_helper(&c->output);
a5f82435 843
844 /* c->force_drain = 1; */
845
7368a6c8 846 if (ret == 1) {
847 c->type = SSH_CHANNEL_OPEN;
0c0738d5 848 channel_pre_open(c, readset, writeset);
7368a6c8 849 } else if (ret == -1) {
8341f420 850 log("X11 connection rejected because of wrong authentication.");
7368a6c8 851 debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
8341f420 852 chan_read_failed(c);
853 buffer_clear(&c->input);
854 chan_ibuf_empty(c);
855 buffer_clear(&c->output);
856 /* for proto v1, the peer will send an IEOF */
857 if (compat20)
858 chan_write_failed(c);
859 else
860 c->type = SSH_CHANNEL_OPEN;
7368a6c8 861 debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
862 }
863}
5260325f 864
28b9cb4d 865/* try to decode a socks4 header */
396c147e 866static int
28b9cb4d 867channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
0490e609 868{
869 u_char *p, *host;
53b8fe68 870 int len, have, i, found;
184eed6a 871 char username[256];
0490e609 872 struct {
873 u_int8_t version;
874 u_int8_t command;
875 u_int16_t dest_port;
28b9cb4d 876 struct in_addr dest_addr;
0490e609 877 } s4_req, s4_rsp;
878
28b9cb4d 879 debug2("channel %d: decode socks4", c->self);
53b8fe68 880
881 have = buffer_len(&c->input);
882 len = sizeof(s4_req);
883 if (have < len)
884 return 0;
885 p = buffer_ptr(&c->input);
886 for (found = 0, i = len; i < have; i++) {
887 if (p[i] == '\0') {
888 found = 1;
889 break;
890 }
891 if (i > 1024) {
892 /* the peer is probably sending garbage */
893 debug("channel %d: decode socks4: too long",
894 c->self);
895 return -1;
896 }
897 }
898 if (!found)
899 return 0;
0490e609 900 buffer_get(&c->input, (char *)&s4_req.version, 1);
901 buffer_get(&c->input, (char *)&s4_req.command, 1);
902 buffer_get(&c->input, (char *)&s4_req.dest_port, 2);
28b9cb4d 903 buffer_get(&c->input, (char *)&s4_req.dest_addr, 4);
53b8fe68 904 have = buffer_len(&c->input);
0490e609 905 p = buffer_ptr(&c->input);
906 len = strlen(p);
6683b40f 907 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
0490e609 908 if (len > have)
28b9cb4d 909 fatal("channel %d: decode socks4: len %d > have %d",
0490e609 910 c->self, len, have);
911 strlcpy(username, p, sizeof(username));
912 buffer_consume(&c->input, len);
913 buffer_consume(&c->input, 1); /* trailing '\0' */
914
28b9cb4d 915 host = inet_ntoa(s4_req.dest_addr);
0490e609 916 strlcpy(c->path, host, sizeof(c->path));
917 c->host_port = ntohs(s4_req.dest_port);
184eed6a 918
6683b40f 919 debug("channel %d: dynamic request: socks4 host %s port %u command %u",
920 c->self, host, c->host_port, s4_req.command);
0490e609 921
28b9cb4d 922 if (s4_req.command != 1) {
923 debug("channel %d: cannot handle: socks4 cn %d",
924 c->self, s4_req.command);
925 return -1;
0490e609 926 }
28b9cb4d 927 s4_rsp.version = 0; /* vn: 0 for reply */
928 s4_rsp.command = 90; /* cd: req granted */
0490e609 929 s4_rsp.dest_port = 0; /* ignored */
28b9cb4d 930 s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */
0490e609 931 buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp));
28b9cb4d 932 return 1;
0490e609 933}
934
28b9cb4d 935/* dynamic port forwarding */
396c147e 936static void
28b9cb4d 937channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
938{
939 u_char *p;
940 int have, ret;
941
942 have = buffer_len(&c->input);
639cb8ab 943 c->delayed = 0;
28b9cb4d 944 debug2("channel %d: pre_dynamic: have %d", c->self, have);
070adba2 945 /* buffer_dump(&c->input); */
28b9cb4d 946 /* check if the fixed size part of the packet is in buffer. */
947 if (have < 4) {
948 /* need more */
949 FD_SET(c->sock, readset);
950 return;
951 }
952 /* try to guess the protocol */
953 p = buffer_ptr(&c->input);
954 switch (p[0]) {
6683b40f 955 case 0x04:
956 ret = channel_decode_socks4(c, readset, writeset);
957 break;
28b9cb4d 958 default:
959 ret = -1;
960 break;
961 }
962 if (ret < 0) {
719fc62f 963 chan_mark_dead(c);
28b9cb4d 964 } else if (ret == 0) {
965 debug2("channel %d: pre_dynamic: need more", c->self);
966 /* need more */
967 FD_SET(c->sock, readset);
968 } else {
969 /* switch to the next state */
970 c->type = SSH_CHANNEL_OPENING;
971 port_open_helper(c, "direct-tcpip");
972 }
973}
0490e609 974
7368a6c8 975/* This is our fake X11 server socket. */
396c147e 976static void
7368a6c8 977channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
978{
719fc62f 979 Channel *nc;
7368a6c8 980 struct sockaddr addr;
bcc0381e 981 int newsock;
7368a6c8 982 socklen_t addrlen;
865ac82e 983 char buf[16384], *remote_ipaddr;
0b242b12 984 int remote_port;
7368a6c8 985
986 if (FD_ISSET(c->sock, readset)) {
987 debug("X11 connection requested.");
988 addrlen = sizeof(addr);
989 newsock = accept(c->sock, &addr, &addrlen);
ac151b18 990 if (c->single_connection) {
991 debug("single_connection: closing X11 listener.");
992 channel_close_fd(&c->sock);
993 chan_mark_dead(c);
994 }
7368a6c8 995 if (newsock < 0) {
996 error("accept: %.100s", strerror(errno));
997 return;
5260325f 998 }
bcc0381e 999 set_nodelay(newsock);
865ac82e 1000 remote_ipaddr = get_peer_ipaddr(newsock);
0b242b12 1001 remote_port = get_peer_port(newsock);
7368a6c8 1002 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
865ac82e 1003 remote_ipaddr, remote_port);
0b242b12 1004
719fc62f 1005 nc = channel_new("accepted x11 socket",
0b242b12 1006 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1007 c->local_window_max, c->local_maxpacket,
a22aff1f 1008 0, xstrdup(buf), 1);
0b242b12 1009 if (compat20) {
1010 packet_start(SSH2_MSG_CHANNEL_OPEN);
1011 packet_put_cstring("x11");
719fc62f 1012 packet_put_int(nc->self);
ac151b18 1013 packet_put_int(nc->local_window_max);
1014 packet_put_int(nc->local_maxpacket);
865ac82e 1015 /* originator ipaddr and port */
1016 packet_put_cstring(remote_ipaddr);
d0c832f3 1017 if (datafellows & SSH_BUG_X11FWD) {
1018 debug("ssh2 x11 bug compat mode");
1019 } else {
1020 packet_put_int(remote_port);
1021 }
0b242b12 1022 packet_send();
1023 } else {
1024 packet_start(SSH_SMSG_X11_OPEN);
719fc62f 1025 packet_put_int(nc->self);
8e7895b8 1026 if (packet_get_protocol_flags() &
1027 SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
449c5ba5 1028 packet_put_cstring(buf);
0b242b12 1029 packet_send();
1030 }
865ac82e 1031 xfree(remote_ipaddr);
8efc0c15 1032 }
8efc0c15 1033}
1034
396c147e 1035static void
0490e609 1036port_open_helper(Channel *c, char *rtype)
1037{
1038 int direct;
1039 char buf[1024];
1040 char *remote_ipaddr = get_peer_ipaddr(c->sock);
1041 u_short remote_port = get_peer_port(c->sock);
1042
1043 direct = (strcmp(rtype, "direct-tcpip") == 0);
1044
1045 snprintf(buf, sizeof buf,
1046 "%s: listening port %d for %.100s port %d, "
1047 "connect from %.200s port %d",
1048 rtype, c->listening_port, c->path, c->host_port,
1049 remote_ipaddr, remote_port);
1050
1051 xfree(c->remote_name);
1052 c->remote_name = xstrdup(buf);
1053
1054 if (compat20) {
1055 packet_start(SSH2_MSG_CHANNEL_OPEN);
1056 packet_put_cstring(rtype);
1057 packet_put_int(c->self);
1058 packet_put_int(c->local_window_max);
1059 packet_put_int(c->local_maxpacket);
1060 if (direct) {
1061 /* target host, port */
1062 packet_put_cstring(c->path);
1063 packet_put_int(c->host_port);
1064 } else {
1065 /* listen address, port */
1066 packet_put_cstring(c->path);
1067 packet_put_int(c->listening_port);
1068 }
1069 /* originator host and port */
1070 packet_put_cstring(remote_ipaddr);
1071 packet_put_int(remote_port);
1072 packet_send();
1073 } else {
1074 packet_start(SSH_MSG_PORT_OPEN);
1075 packet_put_int(c->self);
1076 packet_put_cstring(c->path);
1077 packet_put_int(c->host_port);
8e7895b8 1078 if (packet_get_protocol_flags() &
1079 SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
0490e609 1080 packet_put_cstring(c->remote_name);
1081 packet_send();
1082 }
1083 xfree(remote_ipaddr);
1084}
1085
aa3378df 1086/*
7368a6c8 1087 * This socket is listening for connections to a forwarded TCP/IP port.
aa3378df 1088 */
396c147e 1089static void
7368a6c8 1090channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
1091{
0490e609 1092 Channel *nc;
7368a6c8 1093 struct sockaddr addr;
719fc62f 1094 int newsock, nextstate;
7368a6c8 1095 socklen_t addrlen;
0490e609 1096 char *rtype;
fa08c86b 1097
7368a6c8 1098 if (FD_ISSET(c->sock, readset)) {
1099 debug("Connection to port %d forwarding "
1100 "to %.100s port %d requested.",
1101 c->listening_port, c->path, c->host_port);
0490e609 1102
639cb8ab 1103 if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
1104 nextstate = SSH_CHANNEL_OPENING;
1105 rtype = "forwarded-tcpip";
1106 } else {
1107 if (c->host_port == 0) {
1108 nextstate = SSH_CHANNEL_DYNAMIC;
f3964cb9 1109 rtype = "dynamic-tcpip";
639cb8ab 1110 } else {
1111 nextstate = SSH_CHANNEL_OPENING;
1112 rtype = "direct-tcpip";
1113 }
1114 }
0490e609 1115
7368a6c8 1116 addrlen = sizeof(addr);
1117 newsock = accept(c->sock, &addr, &addrlen);
1118 if (newsock < 0) {
1119 error("accept: %.100s", strerror(errno));
1120 return;
1121 }
811a6342 1122 set_nodelay(newsock);
719fc62f 1123 nc = channel_new(rtype,
0490e609 1124 nextstate, newsock, newsock, -1,
7368a6c8 1125 c->local_window_max, c->local_maxpacket,
0490e609 1126 0, xstrdup(rtype), 1);
0490e609 1127 nc->listening_port = c->listening_port;
1128 nc->host_port = c->host_port;
1129 strlcpy(nc->path, c->path, sizeof(nc->path));
1130
639cb8ab 1131 if (nextstate == SSH_CHANNEL_DYNAMIC) {
1132 /*
1133 * do not call the channel_post handler until
1134 * this flag has been reset by a pre-handler.
1135 * otherwise the FD_ISSET calls might overflow
1136 */
1137 nc->delayed = 1;
1138 } else {
0490e609 1139 port_open_helper(nc, rtype);
639cb8ab 1140 }
7368a6c8 1141 }
1142}
8efc0c15 1143
7368a6c8 1144/*
1145 * This is the authentication agent socket listening for connections from
1146 * clients.
1147 */
396c147e 1148static void
7368a6c8 1149channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
8efc0c15 1150{
719fc62f 1151 Channel *nc;
8e7895b8 1152 char *name;
719fc62f 1153 int newsock;
5260325f 1154 struct sockaddr addr;
48e671d5 1155 socklen_t addrlen;
5260325f 1156
7368a6c8 1157 if (FD_ISSET(c->sock, readset)) {
1158 addrlen = sizeof(addr);
1159 newsock = accept(c->sock, &addr, &addrlen);
1160 if (newsock < 0) {
1161 error("accept from auth socket: %.100s", strerror(errno));
1162 return;
1163 }
8e7895b8 1164 name = xstrdup("accepted auth socket");
719fc62f 1165 nc = channel_new("accepted auth socket",
fa08c86b 1166 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1167 c->local_window_max, c->local_maxpacket,
8e7895b8 1168 0, name, 1);
fa08c86b 1169 if (compat20) {
1170 packet_start(SSH2_MSG_CHANNEL_OPEN);
1171 packet_put_cstring("auth-agent@openssh.com");
719fc62f 1172 packet_put_int(nc->self);
fa08c86b 1173 packet_put_int(c->local_window_max);
1174 packet_put_int(c->local_maxpacket);
1175 } else {
1176 packet_start(SSH_SMSG_AGENT_OPEN);
719fc62f 1177 packet_put_int(nc->self);
fa08c86b 1178 }
7368a6c8 1179 packet_send();
1180 }
1181}
5260325f 1182
396c147e 1183static void
97fb6912 1184channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
1185{
d18e0850 1186 int err = 0;
8ab2cb35 1187 socklen_t sz = sizeof(err);
d18e0850 1188
97fb6912 1189 if (FD_ISSET(c->sock, writeset)) {
db518d9b 1190 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
d18e0850 1191 err = errno;
1192 error("getsockopt SO_ERROR failed");
1193 }
1194 if (err == 0) {
1195 debug("channel %d: connected", c->self);
1196 c->type = SSH_CHANNEL_OPEN;
1197 if (compat20) {
1198 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1199 packet_put_int(c->remote_id);
1200 packet_put_int(c->self);
1201 packet_put_int(c->local_window);
1202 packet_put_int(c->local_maxpacket);
1203 } else {
1204 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1205 packet_put_int(c->remote_id);
1206 packet_put_int(c->self);
1207 }
97fb6912 1208 } else {
d18e0850 1209 debug("channel %d: not connected: %s",
1210 c->self, strerror(err));
1211 if (compat20) {
1212 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1213 packet_put_int(c->remote_id);
1214 packet_put_int(SSH2_OPEN_CONNECT_FAILED);
1215 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1216 packet_put_cstring(strerror(err));
1217 packet_put_cstring("");
1218 }
97fb6912 1219 } else {
d18e0850 1220 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1221 packet_put_int(c->remote_id);
97fb6912 1222 }
d18e0850 1223 chan_mark_dead(c);
97fb6912 1224 }
d18e0850 1225 packet_send();
97fb6912 1226 }
1227}
1228
396c147e 1229static int
7368a6c8 1230channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
1231{
1232 char buf[16*1024];
1233 int len;
1234
6fd8622b 1235 if (c->rfd != -1 &&
7368a6c8 1236 FD_ISSET(c->rfd, readset)) {
1237 len = read(c->rfd, buf, sizeof(buf));
0fbe8c74 1238 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1239 return 1;
7368a6c8 1240 if (len <= 0) {
0b242b12 1241 debug("channel %d: read<=0 rfd %d len %d",
7368a6c8 1242 c->self, c->rfd, len);
28b9cb4d 1243 if (c->type != SSH_CHANNEL_OPEN) {
1244 debug("channel %d: not open", c->self);
719fc62f 1245 chan_mark_dead(c);
0490e609 1246 return -1;
28b9cb4d 1247 } else if (compat13) {
9c50edcf 1248 buffer_clear(&c->output);
7368a6c8 1249 c->type = SSH_CHANNEL_INPUT_DRAINING;
8e7895b8 1250 debug("channel %d: input draining.", c->self);
7368a6c8 1251 } else {
1252 chan_read_failed(c);
5260325f 1253 }
7368a6c8 1254 return -1;
1255 }
6aacefa7 1256 if (c->input_filter != NULL) {
2e73a022 1257 if (c->input_filter(c, buf, len) == -1) {
070adba2 1258 debug("channel %d: filter stops", c->self);
2e73a022 1259 chan_read_failed(c);
1260 }
1261 } else {
1262 buffer_append(&c->input, buf, len);
1263 }
7368a6c8 1264 }
1265 return 1;
1266}
396c147e 1267static int
7368a6c8 1268channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1269{
95ce5599 1270 struct termios tio;
780a9951 1271 u_char *data;
1272 u_int dlen;
7368a6c8 1273 int len;
1274
1275 /* Send buffered output data to the socket. */
6fd8622b 1276 if (c->wfd != -1 &&
7368a6c8 1277 FD_ISSET(c->wfd, writeset) &&
1278 buffer_len(&c->output) > 0) {
780a9951 1279 data = buffer_ptr(&c->output);
1280 dlen = buffer_len(&c->output);
1281 len = write(c->wfd, data, dlen);
64c0ce80 1282#ifdef _AIX
1283 /* XXX: Later AIX versions can't push as much data to tty */
1284 if (compat20 && c->isatty && dlen >= 8*1024)
1285 dlen = 8*1024;
1286#endif
0fbe8c74 1287 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1288 return 1;
7368a6c8 1289 if (len <= 0) {
28b9cb4d 1290 if (c->type != SSH_CHANNEL_OPEN) {
1291 debug("channel %d: not open", c->self);
719fc62f 1292 chan_mark_dead(c);
28b9cb4d 1293 return -1;
1294 } else if (compat13) {
9c50edcf 1295 buffer_clear(&c->output);
8e7895b8 1296 debug("channel %d: input draining.", c->self);
7368a6c8 1297 c->type = SSH_CHANNEL_INPUT_DRAINING;
1298 } else {
1299 chan_write_failed(c);
5260325f 1300 }
7368a6c8 1301 return -1;
1302 }
780a9951 1303 if (compat20 && c->isatty && dlen >= 1 && data[0] != '\r') {
0ae4fe1d 1304 if (tcgetattr(c->wfd, &tio) == 0 &&
1305 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
1306 /*
1307 * Simulate echo to reduce the impact of
355724fc 1308 * traffic analysis. We need to match the
95ce5599 1309 * size of a SSH2_MSG_CHANNEL_DATA message
1310 * (4 byte channel id + data)
0ae4fe1d 1311 */
95ce5599 1312 packet_send_ignore(4 + len);
0ae4fe1d 1313 packet_send();
0ae4fe1d 1314 }
1315 }
7368a6c8 1316 buffer_consume(&c->output, len);
7e7327a1 1317 if (compat20 && len > 0) {
1318 c->local_consumed += len;
1319 }
1320 }
1321 return 1;
1322}
396c147e 1323static int
7e7327a1 1324channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
1325{
1326 char buf[16*1024];
1327 int len;
1328
8ce64345 1329/** XXX handle drain efd, too */
7e7327a1 1330 if (c->efd != -1) {
1331 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
1332 FD_ISSET(c->efd, writeset) &&
1333 buffer_len(&c->extended) > 0) {
1334 len = write(c->efd, buffer_ptr(&c->extended),
1335 buffer_len(&c->extended));
de273eef 1336 debug2("channel %d: written %d to efd %d",
7e7327a1 1337 c->self, len, c->efd);
ee55dacf 1338 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1339 return 1;
1340 if (len <= 0) {
1341 debug2("channel %d: closing write-efd %d",
1342 c->self, c->efd);
489aa2e9 1343 channel_close_fd(&c->efd);
ee55dacf 1344 } else {
7e7327a1 1345 buffer_consume(&c->extended, len);
1346 c->local_consumed += len;
1347 }
1348 } else if (c->extended_usage == CHAN_EXTENDED_READ &&
1349 FD_ISSET(c->efd, readset)) {
1350 len = read(c->efd, buf, sizeof(buf));
de273eef 1351 debug2("channel %d: read %d from efd %d",
184eed6a 1352 c->self, len, c->efd);
ee55dacf 1353 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1354 return 1;
1355 if (len <= 0) {
1356 debug2("channel %d: closing read-efd %d",
8ce64345 1357 c->self, c->efd);
489aa2e9 1358 channel_close_fd(&c->efd);
ee55dacf 1359 } else {
7e7327a1 1360 buffer_append(&c->extended, buf, len);
ee55dacf 1361 }
7e7327a1 1362 }
1363 }
1364 return 1;
1365}
396c147e 1366static int
ee55dacf 1367channel_check_window(Channel *c)
7e7327a1 1368{
28b9cb4d 1369 if (c->type == SSH_CHANNEL_OPEN &&
1370 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
7e7327a1 1371 c->local_window < c->local_window_max/2 &&
1372 c->local_consumed > 0) {
1373 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
1374 packet_put_int(c->remote_id);
1375 packet_put_int(c->local_consumed);
1376 packet_send();
de273eef 1377 debug2("channel %d: window %d sent adjust %d",
7e7327a1 1378 c->self, c->local_window,
1379 c->local_consumed);
1380 c->local_window += c->local_consumed;
1381 c->local_consumed = 0;
7368a6c8 1382 }
1383 return 1;
1384}
5260325f 1385
396c147e 1386static void
0c0738d5 1387channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
7368a6c8 1388{
639cb8ab 1389 if (c->delayed)
1390 return;
7368a6c8 1391 channel_handle_rfd(c, readset, writeset);
1392 channel_handle_wfd(c, readset, writeset);
0c0738d5 1393 if (!compat20)
639cb8ab 1394 return;
7e7327a1 1395 channel_handle_efd(c, readset, writeset);
ee55dacf 1396 channel_check_window(c);
7e7327a1 1397}
1398
396c147e 1399static void
7368a6c8 1400channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
1401{
1402 int len;
1403 /* Send buffered output data to the socket. */
1404 if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {
1405 len = write(c->sock, buffer_ptr(&c->output),
1406 buffer_len(&c->output));
1407 if (len <= 0)
9c50edcf 1408 buffer_clear(&c->output);
7368a6c8 1409 else
1410 buffer_consume(&c->output, len);
1411 }
1412}
5260325f 1413
396c147e 1414static void
7e7327a1 1415channel_handler_init_20(void)
1416{
0c0738d5 1417 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
0b242b12 1418 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
7e7327a1 1419 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
fa08c86b 1420 channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener;
0b242b12 1421 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
fa08c86b 1422 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
97fb6912 1423 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
0490e609 1424 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
7e7327a1 1425
0c0738d5 1426 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
7e7327a1 1427 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
fa08c86b 1428 channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener;
0b242b12 1429 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
fa08c86b 1430 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
97fb6912 1431 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
0c0738d5 1432 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
7e7327a1 1433}
1434
396c147e 1435static void
7368a6c8 1436channel_handler_init_13(void)
1437{
1438 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13;
1439 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13;
1440 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
1441 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
1442 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
1443 channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining;
1444 channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining;
97fb6912 1445 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
0490e609 1446 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
7368a6c8 1447
0c0738d5 1448 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
7368a6c8 1449 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
1450 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
1451 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
1452 channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13;
97fb6912 1453 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
0c0738d5 1454 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
7368a6c8 1455}
5260325f 1456
396c147e 1457static void
7368a6c8 1458channel_handler_init_15(void)
1459{
0c0738d5 1460 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
0b242b12 1461 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
7368a6c8 1462 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
1463 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
1464 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
97fb6912 1465 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
0490e609 1466 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
7368a6c8 1467
1468 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
1469 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
1470 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
0c0738d5 1471 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
97fb6912 1472 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
0c0738d5 1473 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
7368a6c8 1474}
1475
396c147e 1476static void
7368a6c8 1477channel_handler_init(void)
1478{
1479 int i;
184eed6a 1480 for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
7368a6c8 1481 channel_pre[i] = NULL;
1482 channel_post[i] = NULL;
1483 }
7e7327a1 1484 if (compat20)
1485 channel_handler_init_20();
1486 else if (compat13)
7368a6c8 1487 channel_handler_init_13();
1488 else
1489 channel_handler_init_15();
1490}
1491
418e724c 1492/* gc dead channels */
1493static void
1494channel_garbage_collect(Channel *c)
1495{
1496 if (c == NULL)
1497 return;
1498 if (c->detach_user != NULL) {
1499 if (!chan_is_dead(c, 0))
1500 return;
1501 debug("channel %d: gc: notify user", c->self);
1502 c->detach_user(c->self, NULL);
1503 /* if we still have a callback */
1504 if (c->detach_user != NULL)
1505 return;
1506 debug("channel %d: gc: user detached", c->self);
1507 }
1508 if (!chan_is_dead(c, 1))
1509 return;
1510 debug("channel %d: garbage collecting", c->self);
1511 channel_free(c);
1512}
1513
396c147e 1514static void
7368a6c8 1515channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1516{
1517 static int did_init = 0;
1518 int i;
1519 Channel *c;
1520
1521 if (!did_init) {
1522 channel_handler_init();
1523 did_init = 1;
1524 }
1525 for (i = 0; i < channels_alloc; i++) {
719fc62f 1526 c = channels[i];
1527 if (c == NULL)
5260325f 1528 continue;
6fd8622b 1529 if (ftab[c->type] != NULL)
1530 (*ftab[c->type])(c, readset, writeset);
418e724c 1531 channel_garbage_collect(c);
8efc0c15 1532 }
8efc0c15 1533}
1534
8e7895b8 1535/*
1536 * Allocate/update select bitmasks and add any bits relevant to channels in
1537 * select bitmasks.
1538 */
6ae2364d 1539void
c422989b 1540channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
489aa2e9 1541 int *nallocp, int rekeying)
7368a6c8 1542{
39929cdb 1543 int n;
1544 u_int sz;
1545
1546 n = MAX(*maxfdp, channel_max_fd);
1547
1548 sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
489aa2e9 1549 /* perhaps check sz < nalloc/2 and shrink? */
1550 if (*readsetp == NULL || sz > *nallocp) {
1551 *readsetp = xrealloc(*readsetp, sz);
1552 *writesetp = xrealloc(*writesetp, sz);
1553 *nallocp = sz;
39929cdb 1554 }
489aa2e9 1555 *maxfdp = n;
39929cdb 1556 memset(*readsetp, 0, sz);
1557 memset(*writesetp, 0, sz);
1558
c422989b 1559 if (!rekeying)
1560 channel_handler(channel_pre, *readsetp, *writesetp);
7368a6c8 1561}
1562
8e7895b8 1563/*
1564 * After select, perform any appropriate operations for channels which have
1565 * events pending.
1566 */
6ae2364d 1567void
7368a6c8 1568channel_after_select(fd_set * readset, fd_set * writeset)
1569{
1570 channel_handler(channel_post, readset, writeset);
1571}
1572
8e7895b8 1573
39929cdb 1574/* If there is data to send to the connection, enqueue some of it now. */
8efc0c15 1575
6ae2364d 1576void
d5bb9418 1577channel_output_poll(void)
8efc0c15 1578{
7368a6c8 1579 Channel *c;
f91d9a89 1580 int i;
1581 u_int len;
5260325f 1582
1583 for (i = 0; i < channels_alloc; i++) {
719fc62f 1584 c = channels[i];
1585 if (c == NULL)
1586 continue;
48e671d5 1587
8e7895b8 1588 /*
1589 * We are only interested in channels that can have buffered
1590 * incoming data.
1591 */
48e671d5 1592 if (compat13) {
7368a6c8 1593 if (c->type != SSH_CHANNEL_OPEN &&
1594 c->type != SSH_CHANNEL_INPUT_DRAINING)
48e671d5 1595 continue;
1596 } else {
7368a6c8 1597 if (c->type != SSH_CHANNEL_OPEN)
48e671d5 1598 continue;
48e671d5 1599 }
e78a59f5 1600 if (compat20 &&
1601 (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
ee55dacf 1602 /* XXX is this true? */
418e724c 1603 debug3("channel %d: will not send data after close", c->self);
7e7327a1 1604 continue;
1605 }
5260325f 1606
1607 /* Get the amount of buffered data for this channel. */
ee55dacf 1608 if ((c->istate == CHAN_INPUT_OPEN ||
1609 c->istate == CHAN_INPUT_WAIT_DRAIN) &&
1610 (len = buffer_len(&c->input)) > 0) {
8e7895b8 1611 /*
1612 * Send some data for the other side over the secure
1613 * connection.
1614 */
7e7327a1 1615 if (compat20) {
1616 if (len > c->remote_window)
1617 len = c->remote_window;
1618 if (len > c->remote_maxpacket)
1619 len = c->remote_maxpacket;
5260325f 1620 } else {
7e7327a1 1621 if (packet_is_interactive()) {
1622 if (len > 1024)
1623 len = 512;
1624 } else {
1625 /* Keep the packets at reasonable size. */
1626 if (len > packet_get_maxsize()/2)
1627 len = packet_get_maxsize()/2;
1628 }
5260325f 1629 }
7368a6c8 1630 if (len > 0) {
7e7327a1 1631 packet_start(compat20 ?
1632 SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
7368a6c8 1633 packet_put_int(c->remote_id);
1634 packet_put_string(buffer_ptr(&c->input), len);
1635 packet_send();
1636 buffer_consume(&c->input, len);
1637 c->remote_window -= len;
7368a6c8 1638 }
1639 } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
5260325f 1640 if (compat13)
1641 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
aa3378df 1642 /*
1643 * input-buffer is empty and read-socket shutdown:
d2296ed7 1644 * tell peer, that we will not send more data: send IEOF.
1645 * hack for extended data: delay EOF if EFD still in use.
aa3378df 1646 */
d2296ed7 1647 if (CHANNEL_EFD_INPUT_ACTIVE(c))
875ec275 1648 debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
1649 c->self, c->efd, buffer_len(&c->extended));
d2296ed7 1650 else
1651 chan_ibuf_empty(c);
5260325f 1652 }
7e7327a1 1653 /* Send extended data, i.e. stderr */
1654 if (compat20 &&
d2296ed7 1655 !(c->flags & CHAN_EOF_SENT) &&
7e7327a1 1656 c->remote_window > 0 &&
1657 (len = buffer_len(&c->extended)) > 0 &&
1658 c->extended_usage == CHAN_EXTENDED_READ) {
f91d9a89 1659 debug2("channel %d: rwin %u elen %u euse %d",
ee55dacf 1660 c->self, c->remote_window, buffer_len(&c->extended),
1661 c->extended_usage);
7e7327a1 1662 if (len > c->remote_window)
1663 len = c->remote_window;
1664 if (len > c->remote_maxpacket)
1665 len = c->remote_maxpacket;
1666 packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA);
1667 packet_put_int(c->remote_id);
1668 packet_put_int(SSH2_EXTENDED_DATA_STDERR);
1669 packet_put_string(buffer_ptr(&c->extended), len);
1670 packet_send();
1671 buffer_consume(&c->extended, len);
1672 c->remote_window -= len;
ee55dacf 1673 debug2("channel %d: sent ext data %d", c->self, len);
7e7327a1 1674 }
8efc0c15 1675 }
8efc0c15 1676}
1677
8e7895b8 1678
1679/* -- protocol input */
8efc0c15 1680
6ae2364d 1681void
7819b5c3 1682channel_input_data(int type, u_int32_t seq, void *ctxt)
8efc0c15 1683{
48e671d5 1684 int id;
5260325f 1685 char *data;
1e3b8b07 1686 u_int data_len;
7368a6c8 1687 Channel *c;
5260325f 1688
1689 /* Get the channel number and verify it. */
48e671d5 1690 id = packet_get_int();
7368a6c8 1691 c = channel_lookup(id);
1692 if (c == NULL)
48e671d5 1693 packet_disconnect("Received data for nonexistent channel %d.", id);
5260325f 1694
1695 /* Ignore any data for non-open channels (might happen on close) */
7368a6c8 1696 if (c->type != SSH_CHANNEL_OPEN &&
1697 c->type != SSH_CHANNEL_X11_OPEN)
48e671d5 1698 return;
1699
1700 /* same for protocol 1.5 if output end is no longer open */
7368a6c8 1701 if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN)
5260325f 1702 return;
1703
1704 /* Get the data. */
1705 data = packet_get_string(&data_len);
7368a6c8 1706
6aacefa7 1707 if (compat20) {
7e7327a1 1708 if (data_len > c->local_maxpacket) {
1709 log("channel %d: rcvd big packet %d, maxpack %d",
1710 c->self, data_len, c->local_maxpacket);
1711 }
1712 if (data_len > c->local_window) {
1713 log("channel %d: rcvd too much data %d, win %d",
1714 c->self, data_len, c->local_window);
1715 xfree(data);
1716 return;
1717 }
1718 c->local_window -= data_len;
7e7327a1 1719 }
95500969 1720 packet_check_eom();
7368a6c8 1721 buffer_append(&c->output, data, data_len);
5260325f 1722 xfree(data);
8efc0c15 1723}
8e7895b8 1724
6ae2364d 1725void
7819b5c3 1726channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
7e7327a1 1727{
1728 int id;
7e7327a1 1729 char *data;
a594fa74 1730 u_int data_len, tcode;
7e7327a1 1731 Channel *c;
1732
1733 /* Get the channel number and verify it. */
1734 id = packet_get_int();
1735 c = channel_lookup(id);
1736
1737 if (c == NULL)
1738 packet_disconnect("Received extended_data for bad channel %d.", id);
1739 if (c->type != SSH_CHANNEL_OPEN) {
1740 log("channel %d: ext data for non open", id);
1741 return;
1742 }
d2296ed7 1743 if (c->flags & CHAN_EOF_RCVD) {
1744 if (datafellows & SSH_BUG_EXTEOF)
1745 debug("channel %d: accepting ext data after eof", id);
1746 else
1747 packet_disconnect("Received extended_data after EOF "
1748 "on channel %d.", id);
1749 }
7e7327a1 1750 tcode = packet_get_int();
1751 if (c->efd == -1 ||
1752 c->extended_usage != CHAN_EXTENDED_WRITE ||
1753 tcode != SSH2_EXTENDED_DATA_STDERR) {
1754 log("channel %d: bad ext data", c->self);
1755 return;
1756 }
1757 data = packet_get_string(&data_len);
95500969 1758 packet_check_eom();
7e7327a1 1759 if (data_len > c->local_window) {
1760 log("channel %d: rcvd too much extended_data %d, win %d",
1761 c->self, data_len, c->local_window);
1762 xfree(data);
1763 return;
1764 }
de273eef 1765 debug2("channel %d: rcvd ext data %d", c->self, data_len);
7e7327a1 1766 c->local_window -= data_len;
1767 buffer_append(&c->extended, data, data_len);
1768 xfree(data);
1769}
1770
6ae2364d 1771void
7819b5c3 1772channel_input_ieof(int type, u_int32_t seq, void *ctxt)
7368a6c8 1773{
1774 int id;
1775 Channel *c;
1776
7368a6c8 1777 id = packet_get_int();
95500969 1778 packet_check_eom();
7368a6c8 1779 c = channel_lookup(id);
1780 if (c == NULL)
1781 packet_disconnect("Received ieof for nonexistent channel %d.", id);
1782 chan_rcvd_ieof(c);
a5f82435 1783
1784 /* XXX force input close */
8341f420 1785 if (c->force_drain && c->istate == CHAN_INPUT_OPEN) {
a5f82435 1786 debug("channel %d: FORCE input drain", c->self);
1787 c->istate = CHAN_INPUT_WAIT_DRAIN;
32e7d71f 1788 if (buffer_len(&c->input) == 0)
1789 chan_ibuf_empty(c);
a5f82435 1790 }
1791
7368a6c8 1792}
8efc0c15 1793
6ae2364d 1794void
7819b5c3 1795channel_input_close(int type, u_int32_t seq, void *ctxt)
8efc0c15 1796{
7368a6c8 1797 int id;
1798 Channel *c;
5260325f 1799
7368a6c8 1800 id = packet_get_int();
95500969 1801 packet_check_eom();
7368a6c8 1802 c = channel_lookup(id);
1803 if (c == NULL)
1804 packet_disconnect("Received close for nonexistent channel %d.", id);
aa3378df 1805
1806 /*
1807 * Send a confirmation that we have closed the channel and no more
1808 * data is coming for it.
1809 */
5260325f 1810 packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
7368a6c8 1811 packet_put_int(c->remote_id);
5260325f 1812 packet_send();
1813
aa3378df 1814 /*
1815 * If the channel is in closed state, we have sent a close request,
1816 * and the other side will eventually respond with a confirmation.
1817 * Thus, we cannot free the channel here, because then there would be
1818 * no-one to receive the confirmation. The channel gets freed when
1819 * the confirmation arrives.
1820 */
7368a6c8 1821 if (c->type != SSH_CHANNEL_CLOSED) {
aa3378df 1822 /*
1823 * Not a closed channel - mark it as draining, which will
1824 * cause it to be freed later.
1825 */
9c50edcf 1826 buffer_clear(&c->input);
7368a6c8 1827 c->type = SSH_CHANNEL_OUTPUT_DRAINING;
5260325f 1828 }
8efc0c15 1829}
1830
7368a6c8 1831/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
6ae2364d 1832void
7819b5c3 1833channel_input_oclose(int type, u_int32_t seq, void *ctxt)
8efc0c15 1834{
7368a6c8 1835 int id = packet_get_int();
1836 Channel *c = channel_lookup(id);
a8a21a53 1837
95500969 1838 packet_check_eom();
7368a6c8 1839 if (c == NULL)
1840 packet_disconnect("Received oclose for nonexistent channel %d.", id);
1841 chan_rcvd_oclose(c);
8efc0c15 1842}
1843
6ae2364d 1844void
7819b5c3 1845channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
7368a6c8 1846{
1847 int id = packet_get_int();
1848 Channel *c = channel_lookup(id);
1849
95500969 1850 packet_check_eom();
7368a6c8 1851 if (c == NULL)
1852 packet_disconnect("Received close confirmation for "
1853 "out-of-range channel %d.", id);
1854 if (c->type != SSH_CHANNEL_CLOSED)
1855 packet_disconnect("Received close confirmation for "
1856 "non-closed channel %d (type %d).", id, c->type);
719fc62f 1857 channel_free(c);
7368a6c8 1858}
8efc0c15 1859
6ae2364d 1860void
7819b5c3 1861channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
8efc0c15 1862{
7368a6c8 1863 int id, remote_id;
1864 Channel *c;
5260325f 1865
7368a6c8 1866 id = packet_get_int();
1867 c = channel_lookup(id);
5260325f 1868
7368a6c8 1869 if (c==NULL || c->type != SSH_CHANNEL_OPENING)
1870 packet_disconnect("Received open confirmation for "
1871 "non-opening channel %d.", id);
1872 remote_id = packet_get_int();
aa3378df 1873 /* Record the remote channel number and mark that the channel is now open. */
7368a6c8 1874 c->remote_id = remote_id;
1875 c->type = SSH_CHANNEL_OPEN;
7e7327a1 1876
1877 if (compat20) {
1878 c->remote_window = packet_get_int();
1879 c->remote_maxpacket = packet_get_int();
05ca0898 1880 if (c->confirm) {
de273eef 1881 debug2("callback start");
05ca0898 1882 c->confirm(c->self, NULL);
de273eef 1883 debug2("callback done");
7e7327a1 1884 }
f91d9a89 1885 debug("channel %d: open confirm rwindow %u rmax %u", c->self,
7e7327a1 1886 c->remote_window, c->remote_maxpacket);
1887 }
95500969 1888 packet_check_eom();
8efc0c15 1889}
1890
396c147e 1891static char *
d18e0850 1892reason2txt(int reason)
1893{
6aacefa7 1894 switch (reason) {
d18e0850 1895 case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED:
1896 return "administratively prohibited";
1897 case SSH2_OPEN_CONNECT_FAILED:
1898 return "connect failed";
1899 case SSH2_OPEN_UNKNOWN_CHANNEL_TYPE:
1900 return "unknown channel type";
1901 case SSH2_OPEN_RESOURCE_SHORTAGE:
1902 return "resource shortage";
1903 }
7e8c18e9 1904 return "unknown reason";
d18e0850 1905}
1906
6ae2364d 1907void
7819b5c3 1908channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
8efc0c15 1909{
02a024dd 1910 int id, reason;
1911 char *msg = NULL, *lang = NULL;
7368a6c8 1912 Channel *c;
5260325f 1913
7368a6c8 1914 id = packet_get_int();
1915 c = channel_lookup(id);
1916
1917 if (c==NULL || c->type != SSH_CHANNEL_OPENING)
1918 packet_disconnect("Received open failure for "
1919 "non-opening channel %d.", id);
7e7327a1 1920 if (compat20) {
02a024dd 1921 reason = packet_get_int();
fbe90f7b 1922 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
02a024dd 1923 msg = packet_get_string(NULL);
1924 lang = packet_get_string(NULL);
1925 }
d18e0850 1926 log("channel %d: open failed: %s%s%s", id,
1927 reason2txt(reason), msg ? ": ": "", msg ? msg : "");
02a024dd 1928 if (msg != NULL)
1929 xfree(msg);
1930 if (lang != NULL)
1931 xfree(lang);
7e7327a1 1932 }
95500969 1933 packet_check_eom();
5260325f 1934 /* Free the channel. This will also close the socket. */
719fc62f 1935 channel_free(c);
8efc0c15 1936}
1937
8e7895b8 1938void
7819b5c3 1939channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
8e7895b8 1940{
1941 Channel *c;
f91d9a89 1942 int id;
1943 u_int adjust;
3ffc6336 1944
8e7895b8 1945 if (!compat20)
1946 return;
8efc0c15 1947
8e7895b8 1948 /* Get the channel number and verify it. */
1949 id = packet_get_int();
1950 c = channel_lookup(id);
1951
1952 if (c == NULL || c->type != SSH_CHANNEL_OPEN) {
1953 log("Received window adjust for "
1954 "non-open channel %d.", id);
1955 return;
1956 }
1957 adjust = packet_get_int();
95500969 1958 packet_check_eom();
f91d9a89 1959 debug2("channel %d: rcvd adjust %u", id, adjust);
8e7895b8 1960 c->remote_window += adjust;
1961}
1962
1963void
7819b5c3 1964channel_input_port_open(int type, u_int32_t seq, void *ctxt)
8efc0c15 1965{
8e7895b8 1966 Channel *c = NULL;
1967 u_short host_port;
1968 char *host, *originator_string;
1969 int remote_id, sock = -1;
5260325f 1970
8e7895b8 1971 remote_id = packet_get_int();
1972 host = packet_get_string(NULL);
1973 host_port = packet_get_int();
1974
1975 if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
1976 originator_string = packet_get_string(NULL);
1977 } else {
1978 originator_string = xstrdup("unknown (remote did not supply name)");
1979 }
95500969 1980 packet_check_eom();
8e7895b8 1981 sock = channel_connect_to(host, host_port);
1982 if (sock != -1) {
1983 c = channel_new("connected socket",
1984 SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
1985 originator_string, 1);
3a0d3d54 1986 c->remote_id = remote_id;
5260325f 1987 }
8e7895b8 1988 if (c == NULL) {
1989 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1990 packet_put_int(remote_id);
1991 packet_send();
1992 }
1993 xfree(host);
8efc0c15 1994}
1995
8e7895b8 1996
1997/* -- tcp forwarding */
1998
5e4a7219 1999void
2000channel_set_af(int af)
2001{
2002 IPv4or6 = af;
2003}
2004
5641aefa 2005static int
2006channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
2007 const char *host_to_connect, u_short port_to_connect, int gateway_ports)
8efc0c15 2008{
719fc62f 2009 Channel *c;
5641aefa 2010 int success, sock, on = 1;
48e671d5 2011 struct addrinfo hints, *ai, *aitop;
fa08c86b 2012 const char *host;
5641aefa 2013 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
aa3378df 2014 struct linger linger;
5260325f 2015
02a024dd 2016 success = 0;
5641aefa 2017 host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
2018 listen_addr : host_to_connect;
02a024dd 2019
5641aefa 2020 if (host == NULL) {
2021 error("No forward host name.");
2022 return success;
fa08c86b 2023 }
719fc62f 2024 if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
02a024dd 2025 error("Forward host name too long.");
2026 return success;
2027 }
5260325f 2028
aa3378df 2029 /*
48e671d5 2030 * getaddrinfo returns a loopback address if the hostname is
2031 * set to NULL and hints.ai_flags is not AI_PASSIVE
aa3378df 2032 */
48e671d5 2033 memset(&hints, 0, sizeof(hints));
2034 hints.ai_family = IPv4or6;
2035 hints.ai_flags = gateway_ports ? AI_PASSIVE : 0;
2036 hints.ai_socktype = SOCK_STREAM;
fa08c86b 2037 snprintf(strport, sizeof strport, "%d", listen_port);
48e671d5 2038 if (getaddrinfo(NULL, strport, &hints, &aitop) != 0)
2039 packet_disconnect("getaddrinfo: fatal error");
2040
48e671d5 2041 for (ai = aitop; ai; ai = ai->ai_next) {
2042 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2043 continue;
2044 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
2045 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
5641aefa 2046 error("channel_setup_fwd_listener: getnameinfo failed");
48e671d5 2047 continue;
2048 }
2049 /* Create a port to listen for the host. */
2050 sock = socket(ai->ai_family, SOCK_STREAM, 0);
2051 if (sock < 0) {
2052 /* this is no error since kernel may not support ipv6 */
2053 verbose("socket: %.100s", strerror(errno));
2054 continue;
2055 }
2056 /*
2057 * Set socket options. We would like the socket to disappear
2058 * as soon as it has been closed for whatever reason.
2059 */
db518d9b 2060 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
48e671d5 2061 linger.l_onoff = 1;
2062 linger.l_linger = 5;
db518d9b 2063 setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
48e671d5 2064 debug("Local forwarding listening on %s port %s.", ntop, strport);
2065
2066 /* Bind the socket to the address. */
2067 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2068 /* address can be in use ipv6 address is already bound */
16218745 2069 if (!ai->ai_next)
2070 error("bind: %.100s", strerror(errno));
2071 else
2072 verbose("bind: %.100s", strerror(errno));
2b87da3b 2073
48e671d5 2074 close(sock);
2075 continue;
2076 }
2077 /* Start listening for connections on the socket. */
2078 if (listen(sock, 5) < 0) {
2079 error("listen: %.100s", strerror(errno));
2080 close(sock);
2081 continue;
2082 }
2083 /* Allocate a channel number for the socket. */
8e7895b8 2084 c = channel_new("port listener", type, sock, sock, -1,
0b242b12 2085 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
a22aff1f 2086 0, xstrdup("port listener"), 1);
719fc62f 2087 strlcpy(c->path, host, sizeof(c->path));
2088 c->host_port = port_to_connect;
2089 c->listening_port = listen_port;
48e671d5 2090 success = 1;
2091 }
2092 if (success == 0)
5641aefa 2093 error("channel_setup_fwd_listener: cannot listen to port: %d",
02a024dd 2094 listen_port);
48e671d5 2095 freeaddrinfo(aitop);
02a024dd 2096 return success;
5260325f 2097}
8efc0c15 2098
5641aefa 2099/* protocol local port fwd, used by ssh (and sshd in v1) */
2100int
2101channel_setup_local_fwd_listener(u_short listen_port,
2102 const char *host_to_connect, u_short port_to_connect, int gateway_ports)
2103{
2104 return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
2105 NULL, listen_port, host_to_connect, port_to_connect, gateway_ports);
2106}
2107
2108/* protocol v2 remote port fwd, used by sshd */
2109int
2110channel_setup_remote_fwd_listener(const char *listen_address,
2111 u_short listen_port, int gateway_ports)
2112{
2113 return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
2114 listen_address, listen_port, NULL, 0, gateway_ports);
2115}
2116
aa3378df 2117/*
2118 * Initiate forwarding of connections to port "port" on remote host through
2119 * the secure channel to host:port from local side.
2120 */
8efc0c15 2121
6ae2364d 2122void
fa08c86b 2123channel_request_remote_forwarding(u_short listen_port,
2124 const char *host_to_connect, u_short port_to_connect)
8efc0c15 2125{
54a5250f 2126 int type, success = 0;
fa08c86b 2127
5260325f 2128 /* Record locally that connection to this host/port is permitted. */
2129 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
2130 fatal("channel_request_remote_forwarding: too many forwards");
2131
5260325f 2132 /* Send the forward request to the remote side. */
7e7327a1 2133 if (compat20) {
2134 const char *address_to_bind = "0.0.0.0";
2135 packet_start(SSH2_MSG_GLOBAL_REQUEST);
2136 packet_put_cstring("tcpip-forward");
e0ae8728 2137 packet_put_char(1); /* boolean: want reply */
7e7327a1 2138 packet_put_cstring(address_to_bind);
2139 packet_put_int(listen_port);
fa08c86b 2140 packet_send();
2141 packet_write_wait();
2142 /* Assume that server accepts the request */
2143 success = 1;
7e7327a1 2144 } else {
2145 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
7e7327a1 2146 packet_put_int(listen_port);
d6f24e45 2147 packet_put_cstring(host_to_connect);
2148 packet_put_int(port_to_connect);
7e7327a1 2149 packet_send();
2150 packet_write_wait();
fa08c86b 2151
2152 /* Wait for response from the remote side. */
54a5250f 2153 type = packet_read();
fa08c86b 2154 switch (type) {
2155 case SSH_SMSG_SUCCESS:
2156 success = 1;
2157 break;
2158 case SSH_SMSG_FAILURE:
2159 log("Warning: Server denied remote port forwarding.");
2160 break;
2161 default:
2162 /* Unknown packet */
2163 packet_disconnect("Protocol error for port forward request:"
2164 "received packet type %d.", type);
2165 }
2166 }
2167 if (success) {
2168 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
2169 permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
2170 permitted_opens[num_permitted_opens].listen_port = listen_port;
2171 num_permitted_opens++;
7e7327a1 2172 }
8efc0c15 2173}
2174
aa3378df 2175/*
2176 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
2177 * listening for the port, and sends back a success reply (or disconnect
2178 * message if there was an error). This never returns if there was an error.
2179 */
8efc0c15 2180
6ae2364d 2181void
1d1ffb87 2182channel_input_port_forward_request(int is_root, int gateway_ports)
8efc0c15 2183{
57112b5a 2184 u_short port, host_port;
5260325f 2185 char *hostname;
2186
2187 /* Get arguments from the packet. */
2188 port = packet_get_int();
2189 hostname = packet_get_string(NULL);
2190 host_port = packet_get_int();
2191
3c62e7eb 2192#ifndef HAVE_CYGWIN
aa3378df 2193 /*
2194 * Check that an unprivileged user is not trying to forward a
2195 * privileged port.
2196 */
5260325f 2197 if (port < IPPORT_RESERVED && !is_root)
2198 packet_disconnect("Requested forwarding of port %d but user is not root.",
2199 port);
3c62e7eb 2200#endif
fa08c86b 2201 /* Initiate forwarding */
5641aefa 2202 channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);
5260325f 2203
2204 /* Free the argument string. */
2205 xfree(hostname);
8efc0c15 2206}
2207
01794848 2208/*
2209 * Permits opening to any host/port if permitted_opens[] is empty. This is
2210 * usually called by the server, because the user could connect to any port
2211 * anyway, and the server has no way to know but to trust the client anyway.
2212 */
2213void
d5bb9418 2214channel_permit_all_opens(void)
01794848 2215{
2216 if (num_permitted_opens == 0)
2217 all_opens_permitted = 1;
2218}
2219
cd332296 2220void
01794848 2221channel_add_permitted_opens(char *host, int port)
2222{
2223 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
2224 fatal("channel_request_remote_forwarding: too many forwards");
2225 debug("allow port forwarding to host %s port %d", host, port);
2226
2227 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
2228 permitted_opens[num_permitted_opens].port_to_connect = port;
2229 num_permitted_opens++;
2230
2231 all_opens_permitted = 0;
2232}
2233
cd332296 2234void
01794848 2235channel_clear_permitted_opens(void)
2236{
2237 int i;
2238
2239 for (i = 0; i < num_permitted_opens; i++)
2240 xfree(permitted_opens[i].host_to_connect);
2241 num_permitted_opens = 0;
2242
2243}
2244
2245
2246/* return socket to remote host, port */
396c147e 2247static int
01794848 2248connect_to(const char *host, u_short port)
8efc0c15 2249{
48e671d5 2250 struct addrinfo hints, *ai, *aitop;
2251 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2252 int gaierr;
7368a6c8 2253 int sock = -1;
48e671d5 2254
2255 memset(&hints, 0, sizeof(hints));
2256 hints.ai_family = IPv4or6;
2257 hints.ai_socktype = SOCK_STREAM;
01794848 2258 snprintf(strport, sizeof strport, "%d", port);
48e671d5 2259 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
01794848 2260 error("connect_to %.100s: unknown host (%s)", host,
2261 gai_strerror(gaierr));
7368a6c8 2262 return -1;
48e671d5 2263 }
48e671d5 2264 for (ai = aitop; ai; ai = ai->ai_next) {
2265 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2266 continue;
2267 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
2268 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
01794848 2269 error("connect_to: getnameinfo failed");
48e671d5 2270 continue;
5260325f 2271 }
48e671d5 2272 sock = socket(ai->ai_family, SOCK_STREAM, 0);
2273 if (sock < 0) {
2274 error("socket: %.100s", strerror(errno));
2275 continue;
5260325f 2276 }
eea39c02 2277 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
97fb6912 2278 fatal("connect_to: F_SETFL: %s", strerror(errno));
97fb6912 2279 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 &&
2280 errno != EINPROGRESS) {
01794848 2281 error("connect_to %.100s port %s: %.100s", ntop, strport,
48e671d5 2282 strerror(errno));
2283 close(sock);
2b87da3b 2284 continue; /* fail -- try next */
48e671d5 2285 }
2286 break; /* success */
5260325f 2287
5260325f 2288 }
48e671d5 2289 freeaddrinfo(aitop);
48e671d5 2290 if (!ai) {
01794848 2291 error("connect_to %.100s port %d: failed.", host, port);
7368a6c8 2292 return -1;
8efc0c15 2293 }
7368a6c8 2294 /* success */
811a6342 2295 set_nodelay(sock);
7368a6c8 2296 return sock;
2297}
01794848 2298
fa08c86b 2299int
b3f8a79c 2300channel_connect_by_listen_address(u_short listen_port)
fa08c86b 2301{
2302 int i;
01794848 2303
fa08c86b 2304 for (i = 0; i < num_permitted_opens; i++)
2305 if (permitted_opens[i].listen_port == listen_port)
01794848 2306 return connect_to(
fa08c86b 2307 permitted_opens[i].host_to_connect,
2308 permitted_opens[i].port_to_connect);
0b6fbf03 2309 error("WARNING: Server requests forwarding for unknown listen_port %d",
2310 listen_port);
fa08c86b 2311 return -1;
2312}
48e671d5 2313
01794848 2314/* Check if connecting to that port is permitted and connect. */
2315int
2316channel_connect_to(const char *host, u_short port)
2317{
2318 int i, permit;
2319
2320 permit = all_opens_permitted;
2321 if (!permit) {
2322 for (i = 0; i < num_permitted_opens; i++)
2323 if (permitted_opens[i].port_to_connect == port &&
2324 strcmp(permitted_opens[i].host_to_connect, host) == 0)
2325 permit = 1;
2326
2327 }
2328 if (!permit) {
2329 log("Received request to connect to host %.100s port %d, "
2330 "but the request was denied.", host, port);
2331 return -1;
2332 }
2333 return connect_to(host, port);
2334}
2335
8e7895b8 2336/* -- X11 forwarding */
8efc0c15 2337
aa3378df 2338/*
2339 * Creates an internet domain socket for listening for X11 connections.
57f228e8 2340 * Returns 0 and a suitable display number for the DISPLAY variable
2341 * stored in display_numberp , or -1 if an error occurs.
aa3378df 2342 */
c9d0ad9b 2343int
e6e573bd 2344x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
57f228e8 2345 int single_connection, u_int *display_numberp)
8efc0c15 2346{
ac151b18 2347 Channel *nc = NULL;
57112b5a 2348 int display_number, sock;
2349 u_short port;
48e671d5 2350 struct addrinfo hints, *ai, *aitop;
2351 char strport[NI_MAXSERV];
2352 int gaierr, n, num_socks = 0, socks[NUM_SOCKS];
5260325f 2353
95f1eccc 2354 for (display_number = x11_display_offset;
184eed6a 2355 display_number < MAX_DISPLAYS;
2356 display_number++) {
5260325f 2357 port = 6000 + display_number;
48e671d5 2358 memset(&hints, 0, sizeof(hints));
2359 hints.ai_family = IPv4or6;
e6e573bd 2360 hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
48e671d5 2361 hints.ai_socktype = SOCK_STREAM;
2362 snprintf(strport, sizeof strport, "%d", port);
2363 if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
2364 error("getaddrinfo: %.100s", gai_strerror(gaierr));
c9d0ad9b 2365 return -1;
5260325f 2366 }
48e671d5 2367 for (ai = aitop; ai; ai = ai->ai_next) {
2368 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2369 continue;
2370 sock = socket(ai->ai_family, SOCK_STREAM, 0);
2371 if (sock < 0) {
4ee81249 2372 if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) {
80a44451 2373 error("socket: %.100s", strerror(errno));
c9d0ad9b 2374 return -1;
80a44451 2375 } else {
22d89d24 2376 debug("x11_create_display_inet: Socket family %d not supported",
2377 ai->ai_family);
80a44451 2378 continue;
2379 }
48e671d5 2380 }
688aaeda 2381#ifdef IPV6_V6ONLY
2382 if (ai->ai_family == AF_INET6) {
2383 int on = 1;
2384 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
2385 error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno));
2386 }
2387#endif
48e671d5 2388 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2389 debug("bind port %d: %.100s", port, strerror(errno));
48e671d5 2390 close(sock);
16218745 2391
2392 if (ai->ai_next)
2393 continue;
2394
48e671d5 2395 for (n = 0; n < num_socks; n++) {
48e671d5 2396 close(socks[n]);
2397 }
2398 num_socks = 0;
2399 break;
2400 }
2401 socks[num_socks++] = sock;
80faa19f 2402#ifndef DONT_TRY_OTHER_AF
48e671d5 2403 if (num_socks == NUM_SOCKS)
2404 break;
80faa19f 2405#else
688aaeda 2406 if (x11_use_localhost) {
2407 if (num_socks == NUM_SOCKS)
2408 break;
2409 } else {
2410 break;
2411 }
80faa19f 2412#endif
5260325f 2413 }
4ccb01d6 2414 freeaddrinfo(aitop);
48e671d5 2415 if (num_socks > 0)
2416 break;
5260325f 2417 }
2418 if (display_number >= MAX_DISPLAYS) {
2419 error("Failed to allocate internet-domain X11 display socket.");
c9d0ad9b 2420 return -1;
8efc0c15 2421 }
5260325f 2422 /* Start listening for connections on the socket. */
48e671d5 2423 for (n = 0; n < num_socks; n++) {
2424 sock = socks[n];
2425 if (listen(sock, 5) < 0) {
2426 error("listen: %.100s", strerror(errno));
48e671d5 2427 close(sock);
c9d0ad9b 2428 return -1;
a7effaac 2429 }
a7effaac 2430 }
5260325f 2431
48e671d5 2432 /* Allocate a channel for each socket. */
2433 for (n = 0; n < num_socks; n++) {
2434 sock = socks[n];
ac151b18 2435 nc = channel_new("x11 listener",
0b242b12 2436 SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
2437 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
a22aff1f 2438 0, xstrdup("X11 inet listener"), 1);
3a0d3d54 2439 nc->single_connection = single_connection;
48e671d5 2440 }
5260325f 2441
c9d0ad9b 2442 /* Return the display number for the DISPLAY environment variable. */
57f228e8 2443 *display_numberp = display_number;
2444 return (0);
8efc0c15 2445}
2446
396c147e 2447static int
1e3b8b07 2448connect_local_xsocket(u_int dnr)
8efc0c15 2449{
5260325f 2450 int sock;
2451 struct sockaddr_un addr;
5260325f 2452
805e659f 2453 sock = socket(AF_UNIX, SOCK_STREAM, 0);
2454 if (sock < 0)
2455 error("socket: %.100s", strerror(errno));
2456 memset(&addr, 0, sizeof(addr));
2457 addr.sun_family = AF_UNIX;
2458 snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
2459 if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0)
2460 return sock;
2461 close(sock);
5260325f 2462 error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
2463 return -1;
8efc0c15 2464}
2465
0b242b12 2466int
2467x11_connect_display(void)
8efc0c15 2468{
bcc0381e 2469 int display_number, sock = 0;
5260325f 2470 const char *display;
0b242b12 2471 char buf[1024], *cp;
48e671d5 2472 struct addrinfo hints, *ai, *aitop;
2473 char strport[NI_MAXSERV];
2474 int gaierr;
5260325f 2475
5260325f 2476 /* Try to open a socket for the local X server. */
2477 display = getenv("DISPLAY");
2478 if (!display) {
2479 error("DISPLAY not set.");
0b242b12 2480 return -1;
5260325f 2481 }
aa3378df 2482 /*
2483 * Now we decode the value of the DISPLAY variable and make a
2484 * connection to the real X server.
2485 */
2486
2487 /*
2488 * Check if it is a unix domain socket. Unix domain displays are in
2489 * one of the following formats: unix:d[.s], :d[.s], ::d[.s]
2490 */
5260325f 2491 if (strncmp(display, "unix:", 5) == 0 ||
2492 display[0] == ':') {
2493 /* Connect to the unix domain socket. */
2494 if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
2495 error("Could not parse display number from DISPLAY: %.100s",
184eed6a 2496 display);
0b242b12 2497 return -1;
5260325f 2498 }
2499 /* Create a socket. */
2500 sock = connect_local_xsocket(display_number);
2501 if (sock < 0)
0b242b12 2502 return -1;
5260325f 2503
2504 /* OK, we now have a connection to the display. */
0b242b12 2505 return sock;
5260325f 2506 }
aa3378df 2507 /*
2508 * Connect to an inet socket. The DISPLAY value is supposedly
2509 * hostname:d[.s], where hostname may also be numeric IP address.
2510 */
74860245 2511 strlcpy(buf, display, sizeof(buf));
5260325f 2512 cp = strchr(buf, ':');
2513 if (!cp) {
2514 error("Could not find ':' in DISPLAY: %.100s", display);
0b242b12 2515 return -1;
5260325f 2516 }
2517 *cp = 0;
aa3378df 2518 /* buf now contains the host name. But first we parse the display number. */
5260325f 2519 if (sscanf(cp + 1, "%d", &display_number) != 1) {
2520 error("Could not parse display number from DISPLAY: %.100s",
184eed6a 2521 display);
0b242b12 2522 return -1;
5260325f 2523 }
5260325f 2524
48e671d5 2525 /* Look up the host address */
2526 memset(&hints, 0, sizeof(hints));
2527 hints.ai_family = IPv4or6;
2528 hints.ai_socktype = SOCK_STREAM;
2529 snprintf(strport, sizeof strport, "%d", 6000 + display_number);
2530 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
2531 error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
0b242b12 2532 return -1;
8efc0c15 2533 }
48e671d5 2534 for (ai = aitop; ai; ai = ai->ai_next) {
2535 /* Create a socket. */
2536 sock = socket(ai->ai_family, SOCK_STREAM, 0);
2537 if (sock < 0) {
2538 debug("socket: %.100s", strerror(errno));
7368a6c8 2539 continue;
2540 }
2541 /* Connect it to the display. */
2542 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2543 debug("connect %.100s port %d: %.100s", buf,
2544 6000 + display_number, strerror(errno));
2545 close(sock);
2546 continue;
2547 }
2548 /* Success */
2549 break;
48e671d5 2550 }
48e671d5 2551 freeaddrinfo(aitop);
2552 if (!ai) {
6ae2364d 2553 error("connect %.100s port %d: %.100s", buf, 6000 + display_number,
48e671d5 2554 strerror(errno));
0b242b12 2555 return -1;
8efc0c15 2556 }
bcc0381e 2557 set_nodelay(sock);
0b242b12 2558 return sock;
2559}
5260325f 2560
0b242b12 2561/*
2562 * This is called when SSH_SMSG_X11_OPEN is received. The packet contains
2563 * the remote channel number. We should do whatever we want, and respond
2564 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
2565 */
5260325f 2566
0b242b12 2567void
7819b5c3 2568x11_input_open(int type, u_int32_t seq, void *ctxt)
0b242b12 2569{
719fc62f 2570 Channel *c = NULL;
2571 int remote_id, sock = 0;
0b242b12 2572 char *remote_host;
5260325f 2573
719fc62f 2574 debug("Received X11 open request.");
5260325f 2575
719fc62f 2576 remote_id = packet_get_int();
8e7895b8 2577
2578 if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
719fc62f 2579 remote_host = packet_get_string(NULL);
0b242b12 2580 } else {
2581 remote_host = xstrdup("unknown (remote did not supply name)");
0b242b12 2582 }
95500969 2583 packet_check_eom();
0b242b12 2584
2585 /* Obtain a connection to the real X display. */
2586 sock = x11_connect_display();
719fc62f 2587 if (sock != -1) {
2588 /* Allocate a channel for this connection. */
2589 c = channel_new("connected x11 socket",
2590 SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,
2591 remote_host, 1);
3a0d3d54 2592 c->remote_id = remote_id;
2593 c->force_drain = 1;
719fc62f 2594 }
2595 if (c == NULL) {
0b242b12 2596 /* Send refusal to the remote host. */
2597 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
719fc62f 2598 packet_put_int(remote_id);
0b242b12 2599 } else {
0b242b12 2600 /* Send a confirmation to the remote host. */
2601 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
719fc62f 2602 packet_put_int(remote_id);
2603 packet_put_int(c->self);
0b242b12 2604 }
719fc62f 2605 packet_send();
8efc0c15 2606}
2607
a22aff1f 2608/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
2609void
7819b5c3 2610deny_input_open(int type, u_int32_t seq, void *ctxt)
a22aff1f 2611{
2612 int rchan = packet_get_int();
6aacefa7 2613 switch (type) {
a22aff1f 2614 case SSH_SMSG_AGENT_OPEN:
2615 error("Warning: ssh server tried agent forwarding.");
2616 break;
2617 case SSH_SMSG_X11_OPEN:
2618 error("Warning: ssh server tried X11 forwarding.");
2619 break;
2620 default:
7819b5c3 2621 error("deny_input_open: type %d", type);
a22aff1f 2622 break;
2623 }
2624 error("Warning: this is probably a break in attempt by a malicious server.");
2625 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2626 packet_put_int(rchan);
2627 packet_send();
2628}
2629
aa3378df 2630/*
2631 * Requests forwarding of X11 connections, generates fake authentication
2632 * data, and enables authentication spoofing.
8e7895b8 2633 * This should be called in the client only.
aa3378df 2634 */
6ae2364d 2635void
0b242b12 2636x11_request_forwarding_with_spoofing(int client_session_id,
2637 const char *proto, const char *data)
8efc0c15 2638{
1e3b8b07 2639 u_int data_len = (u_int) strlen(data) / 2;
ca910e13 2640 u_int i, value, len;
5260325f 2641 char *new_data;
2642 int screen_number;
2643 const char *cp;
2644 u_int32_t rand = 0;
2645
2646 cp = getenv("DISPLAY");
2647 if (cp)
2648 cp = strchr(cp, ':');
2649 if (cp)
2650 cp = strchr(cp, '.');
2651 if (cp)
2652 screen_number = atoi(cp + 1);
2653 else
2654 screen_number = 0;
2655
2656 /* Save protocol name. */
2657 x11_saved_proto = xstrdup(proto);
2658
aa3378df 2659 /*
2660 * Extract real authentication data and generate fake data of the
2661 * same length.
2662 */
5260325f 2663 x11_saved_data = xmalloc(data_len);
2664 x11_fake_data = xmalloc(data_len);
2665 for (i = 0; i < data_len; i++) {
2666 if (sscanf(data + 2 * i, "%2x", &value) != 1)
2667 fatal("x11_request_forwarding: bad authentication data: %.100s", data);
2668 if (i % 4 == 0)
2669 rand = arc4random();
2670 x11_saved_data[i] = value;
2671 x11_fake_data[i] = rand & 0xff;
2672 rand >>= 8;
2673 }
2674 x11_saved_data_len = data_len;
2675 x11_fake_data_len = data_len;
2676
2677 /* Convert the fake data into hex. */
ca910e13 2678 len = 2 * data_len + 1;
2679 new_data = xmalloc(len);
5260325f 2680 for (i = 0; i < data_len; i++)
ca910e13 2681 snprintf(new_data + 2 * i, len - 2 * i,
2682 "%02x", (u_char) x11_fake_data[i]);
5260325f 2683
2684 /* Send the request packet. */
0b242b12 2685 if (compat20) {
2686 channel_request_start(client_session_id, "x11-req", 0);
2687 packet_put_char(0); /* XXX bool single connection */
2688 } else {
2689 packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
2690 }
2691 packet_put_cstring(proto);
2692 packet_put_cstring(new_data);
5260325f 2693 packet_put_int(screen_number);
2694 packet_send();
2695 packet_write_wait();
2696 xfree(new_data);
8efc0c15 2697}
2698
8e7895b8 2699
2700/* -- agent forwarding */
2701
8efc0c15 2702/* Sends a message to the server to request authentication fd forwarding. */
2703
6ae2364d 2704void
d5bb9418 2705auth_request_forwarding(void)
8efc0c15 2706{
5260325f 2707 packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
2708 packet_send();
2709 packet_write_wait();
8efc0c15 2710}
2711
8efc0c15 2712/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
2713
6ae2364d 2714void
7819b5c3 2715auth_input_open_request(int type, u_int32_t seq, void *ctxt)
8efc0c15 2716{
719fc62f 2717 Channel *c = NULL;
2718 int remote_id, sock;
8e7895b8 2719 char *name;
5260325f 2720
2721 /* Read the remote channel number from the message. */
719fc62f 2722 remote_id = packet_get_int();
95500969 2723 packet_check_eom();
5260325f 2724
aa3378df 2725 /*
2726 * Get a connection to the local authentication agent (this may again
2727 * get forwarded).
2728 */
5260325f 2729 sock = ssh_get_authentication_socket();
2730
aa3378df 2731 /*
2732 * If we could not connect the agent, send an error message back to
2733 * the server. This should never happen unless the agent dies,
2734 * because authentication forwarding is only enabled if we have an
2735 * agent.
2736 */
719fc62f 2737 if (sock >= 0) {
8e7895b8 2738 name = xstrdup("authentication agent connection");
2739 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
2740 -1, 0, 0, 0, name, 1);
3a0d3d54 2741 c->remote_id = remote_id;
2742 c->force_drain = 1;
719fc62f 2743 }
2744 if (c == NULL) {
5260325f 2745 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
719fc62f 2746 packet_put_int(remote_id);
2747 } else {
2748 /* Send a confirmation to the remote host. */
2749 debug("Forwarding authentication connection.");
2750 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
2751 packet_put_int(remote_id);
2752 packet_put_int(c->self);
5260325f 2753 }
5260325f 2754 packet_send();
8efc0c15 2755}
This page took 0.656234 seconds and 5 git commands to generate.