]> andersk Git - openssh.git/blob - channels.c
- More OpenBSD updates:
[openssh.git] / channels.c
1 /*
2  *
3  * channels.c
4  *
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  *
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  *
10  * Created: Fri Mar 24 16:35:24 1995 ylo
11  *
12  * This file contains functions for generic socket connection forwarding.
13  * There is also code for initiating connection forwarding for X11 connections,
14  * arbitrary tcp/ip connections, and the authentication agent connection.
15  *
16  * SSH2 support added by Markus Friedl.
17  */
18
19 #include "includes.h"
20 RCSID("$Id$");
21
22 #include "ssh.h"
23 #include "packet.h"
24 #include "xmalloc.h"
25 #include "buffer.h"
26 #include "authfd.h"
27 #include "uidswap.h"
28 #include "readconf.h"
29 #include "servconf.h"
30
31 #include "channels.h"
32 #include "nchan.h"
33 #include "compat.h"
34
35 #include "ssh2.h"
36
37 /* Maximum number of fake X11 displays to try. */
38 #define MAX_DISPLAYS  1000
39
40 /* Max len of agent socket */
41 #define MAX_SOCKET_NAME 100
42
43 /* default window/packet sizes for tcp/x11-fwd-channel */
44 #define CHAN_TCP_WINDOW_DEFAULT (8*1024)
45 #define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2)
46 #define CHAN_X11_WINDOW_DEFAULT (4*1024)
47 #define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2)
48
49 /*
50  * Pointer to an array containing all allocated channels.  The array is
51  * dynamically extended as needed.
52  */
53 static Channel *channels = NULL;
54
55 /*
56  * Size of the channel array.  All slots of the array must always be
57  * initialized (at least the type field); unused slots are marked with type
58  * SSH_CHANNEL_FREE.
59  */
60 static int channels_alloc = 0;
61
62 /*
63  * Maximum file descriptor value used in any of the channels.  This is
64  * updated in channel_allocate.
65  */
66 static int channel_max_fd_value = 0;
67
68 /* Name and directory of socket for authentication agent forwarding. */
69 static char *channel_forwarded_auth_socket_name = NULL;
70 static char *channel_forwarded_auth_socket_dir = NULL;
71
72 /* Saved X11 authentication protocol name. */
73 char *x11_saved_proto = NULL;
74
75 /* Saved X11 authentication data.  This is the real data. */
76 char *x11_saved_data = NULL;
77 unsigned int x11_saved_data_len = 0;
78
79 /*
80  * Fake X11 authentication data.  This is what the server will be sending us;
81  * we should replace any occurrences of this by the real data.
82  */
83 char *x11_fake_data = NULL;
84 unsigned int x11_fake_data_len;
85
86 /*
87  * Data structure for storing which hosts are permitted for forward requests.
88  * The local sides of any remote forwards are stored in this array to prevent
89  * a corrupt remote server from accessing arbitrary TCP/IP ports on our local
90  * network (which might be behind a firewall).
91  */
92 typedef struct {
93         char *host_to_connect;          /* Connect to 'host'. */
94         u_short port_to_connect;        /* Connect to 'port'. */
95         u_short listen_port;            /* Remote side should listen port number. */
96 } ForwardPermission;
97
98 /* List of all permitted host/port pairs to connect. */
99 static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
100 /* Number of permitted host/port pairs in the array. */
101 static int num_permitted_opens = 0;
102 /*
103  * If this is true, all opens are permitted.  This is the case on the server
104  * on which we have to trust the client anyway, and the user could do
105  * anything after logging in anyway.
106  */
107 static int all_opens_permitted = 0;
108
109 /* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */
110 static int have_hostname_in_open = 0;
111
112 /* Sets specific protocol options. */
113
114 void
115 channel_set_options(int hostname_in_open)
116 {
117         have_hostname_in_open = hostname_in_open;
118 }
119
120 /*
121  * Permits opening to any host/port in SSH_MSG_PORT_OPEN.  This is usually
122  * called by the server, because the user could connect to any port anyway,
123  * and the server has no way to know but to trust the client anyway.
124  */
125
126 void
127 channel_permit_all_opens()
128 {
129         all_opens_permitted = 1;
130 }
131
132 /* lookup channel by id */
133
134 Channel *
135 channel_lookup(int id)
136 {
137         Channel *c;
138         if (id < 0 && id > channels_alloc) {
139                 log("channel_lookup: %d: bad id", id);
140                 return NULL;
141         }
142         c = &channels[id];
143         if (c->type == SSH_CHANNEL_FREE) {
144                 log("channel_lookup: %d: bad id: channel free", id);
145                 return NULL;
146         }
147         return c;
148 }
149
150 /*
151  * Allocate a new channel object and set its type and socket. This will cause
152  * remote_name to be freed.
153  */
154
155 int
156 channel_new(char *ctype, int type, int rfd, int wfd, int efd,
157     int window, int maxpack, int extended_usage, char *remote_name)
158 {
159         int i, found;
160         Channel *c;
161
162         /* Update the maximum file descriptor value. */
163         if (rfd > channel_max_fd_value)
164                 channel_max_fd_value = rfd;
165         if (wfd > channel_max_fd_value)
166                 channel_max_fd_value = wfd;
167         if (efd > channel_max_fd_value)
168                 channel_max_fd_value = efd;
169         /* XXX set close-on-exec -markus */
170
171         /* Do initial allocation if this is the first call. */
172         if (channels_alloc == 0) {
173                 chan_init();
174                 channels_alloc = 10;
175                 channels = xmalloc(channels_alloc * sizeof(Channel));
176                 for (i = 0; i < channels_alloc; i++)
177                         channels[i].type = SSH_CHANNEL_FREE;
178                 /*
179                  * Kludge: arrange a call to channel_stop_listening if we
180                  * terminate with fatal().
181                  */
182                 fatal_add_cleanup((void (*) (void *)) channel_stop_listening, NULL);
183         }
184         /* Try to find a free slot where to put the new channel. */
185         for (found = -1, i = 0; i < channels_alloc; i++)
186                 if (channels[i].type == SSH_CHANNEL_FREE) {
187                         /* Found a free slot. */
188                         found = i;
189                         break;
190                 }
191         if (found == -1) {
192                 /* There are no free slots.  Take last+1 slot and expand the array.  */
193                 found = channels_alloc;
194                 channels_alloc += 10;
195                 debug("channel: expanding %d", channels_alloc);
196                 channels = xrealloc(channels, channels_alloc * sizeof(Channel));
197                 for (i = found; i < channels_alloc; i++)
198                         channels[i].type = SSH_CHANNEL_FREE;
199         }
200         /* Initialize and return new channel number. */
201         c = &channels[found];
202         buffer_init(&c->input);
203         buffer_init(&c->output);
204         buffer_init(&c->extended);
205         chan_init_iostates(c);
206         c->self = found;
207         c->type = type;
208         c->ctype = ctype;
209         c->rfd = rfd;
210         c->wfd = wfd;
211         c->sock = (rfd == wfd) ? rfd : -1;
212         c->efd = efd;
213         c->extended_usage = extended_usage;
214         c->local_window = window;
215         c->local_window_max = window;
216         c->local_consumed = 0;
217         c->local_maxpacket = maxpack;
218         c->remote_id = -1;
219         c->remote_name = remote_name;
220         c->remote_window = 0;
221         c->remote_maxpacket = 0;
222         c->cb_fn = NULL;
223         c->cb_arg = NULL;
224         c->cb_event = 0;
225         c->dettach_user = NULL;
226         debug("channel %d: new [%s]", found, remote_name);
227         return found;
228 }
229 int
230 channel_allocate(int type, int sock, char *remote_name)
231 {
232         return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name);
233 }
234
235 /* Free the channel and close its socket. */
236
237 void
238 channel_free(int id)
239 {
240         Channel *c = channel_lookup(id);
241         if (c == NULL)
242                 packet_disconnect("channel free: bad local channel %d", id);
243         debug("channel_free: channel %d: status: %s", id, channel_open_message());
244         if (c->dettach_user != NULL) {
245                 debug("channel_free: channel %d: dettaching channel user", id);
246                 c->dettach_user(c->self, NULL);
247         }
248         if (c->sock != -1) {
249                 shutdown(c->sock, SHUT_RDWR);
250                 close(c->sock);
251                 c->sock = -1;
252         }
253         if (compat20) {
254                 if (c->rfd != -1) {
255                         close(c->rfd);
256                         c->rfd = -1;
257                 }
258                 if (c->wfd != -1) {
259                         close(c->wfd);
260                         c->wfd = -1;
261                 }
262                 if (c->efd != -1) {
263                         close(c->efd);
264                         c->efd = -1;
265                 }
266         }
267         buffer_free(&c->input);
268         buffer_free(&c->output);
269         buffer_free(&c->extended);
270         c->type = SSH_CHANNEL_FREE;
271         if (c->remote_name) {
272                 xfree(c->remote_name);
273                 c->remote_name = NULL;
274         }
275 }
276
277 /*
278  * 'channel_pre*' are called just before select() to add any bits relevant to
279  * channels in the select bitmasks.
280  */
281 /*
282  * 'channel_post*': perform any appropriate operations for channels which
283  * have events pending.
284  */
285 typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset);
286 chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];
287 chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];
288
289 void
290 channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset)
291 {
292         FD_SET(c->sock, readset);
293 }
294
295 void
296 channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
297 {
298         if (buffer_len(&c->input) < packet_get_maxsize())
299                 FD_SET(c->sock, readset);
300         if (buffer_len(&c->output) > 0)
301                 FD_SET(c->sock, writeset);
302 }
303
304 void
305 channel_pre_open_15(Channel *c, fd_set * readset, fd_set * writeset)
306 {
307         /* test whether sockets are 'alive' for read/write */
308         if (c->istate == CHAN_INPUT_OPEN)
309                 if (buffer_len(&c->input) < packet_get_maxsize())
310                         FD_SET(c->sock, readset);
311         if (c->ostate == CHAN_OUTPUT_OPEN ||
312             c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
313                 if (buffer_len(&c->output) > 0) {
314                         FD_SET(c->sock, writeset);
315                 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
316                         chan_obuf_empty(c);
317                 }
318         }
319 }
320
321 void
322 channel_pre_open_20(Channel *c, fd_set * readset, fd_set * writeset)
323 {
324         if (c->istate == CHAN_INPUT_OPEN &&
325             c->remote_window > 0 &&
326             buffer_len(&c->input) < c->remote_window)
327                 FD_SET(c->rfd, readset);
328         if (c->ostate == CHAN_OUTPUT_OPEN ||
329             c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
330                 if (buffer_len(&c->output) > 0) {
331                         FD_SET(c->wfd, writeset);
332                 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
333                         chan_obuf_empty(c);
334                 }
335         }
336         /** XXX check close conditions, too */
337         if (c->efd != -1) {
338                 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
339                     buffer_len(&c->extended) > 0)
340                         FD_SET(c->efd, writeset);
341                 else if (c->extended_usage == CHAN_EXTENDED_READ &&
342                     buffer_len(&c->extended) < c->remote_window)
343                         FD_SET(c->efd, readset);
344         }
345 }
346
347 void
348 channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
349 {
350         if (buffer_len(&c->input) == 0) {
351                 packet_start(SSH_MSG_CHANNEL_CLOSE);
352                 packet_put_int(c->remote_id);
353                 packet_send();
354                 c->type = SSH_CHANNEL_CLOSED;
355                 debug("Closing channel %d after input drain.", c->self);
356         }
357 }
358
359 void
360 channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
361 {
362         if (buffer_len(&c->output) == 0)
363                 channel_free(c->self);
364         else
365                 FD_SET(c->sock, writeset);
366 }
367
368 /*
369  * This is a special state for X11 authentication spoofing.  An opened X11
370  * connection (when authentication spoofing is being done) remains in this
371  * state until the first packet has been completely read.  The authentication
372  * data in that packet is then substituted by the real data if it matches the
373  * fake data, and the channel is put into normal mode.
374  * XXX All this happens at the client side.
375  */
376 int
377 x11_open_helper(Channel *c)
378 {
379         unsigned char *ucp;
380         unsigned int proto_len, data_len;
381
382         /* Check if the fixed size part of the packet is in buffer. */
383         if (buffer_len(&c->output) < 12)
384                 return 0;
385
386         /* Parse the lengths of variable-length fields. */
387         ucp = (unsigned char *) buffer_ptr(&c->output);
388         if (ucp[0] == 0x42) {   /* Byte order MSB first. */
389                 proto_len = 256 * ucp[6] + ucp[7];
390                 data_len = 256 * ucp[8] + ucp[9];
391         } else if (ucp[0] == 0x6c) {    /* Byte order LSB first. */
392                 proto_len = ucp[6] + 256 * ucp[7];
393                 data_len = ucp[8] + 256 * ucp[9];
394         } else {
395                 debug("Initial X11 packet contains bad byte order byte: 0x%x",
396                       ucp[0]);
397                 return -1;
398         }
399
400         /* Check if the whole packet is in buffer. */
401         if (buffer_len(&c->output) <
402             12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
403                 return 0;
404
405         /* Check if authentication protocol matches. */
406         if (proto_len != strlen(x11_saved_proto) ||
407             memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {
408                 debug("X11 connection uses different authentication protocol.");
409                 return -1;
410         }
411         /* Check if authentication data matches our fake data. */
412         if (data_len != x11_fake_data_len ||
413             memcmp(ucp + 12 + ((proto_len + 3) & ~3),
414                 x11_fake_data, x11_fake_data_len) != 0) {
415                 debug("X11 auth data does not match fake data.");
416                 return -1;
417         }
418         /* Check fake data length */
419         if (x11_fake_data_len != x11_saved_data_len) {
420                 error("X11 fake_data_len %d != saved_data_len %d",
421                     x11_fake_data_len, x11_saved_data_len);
422                 return -1;
423         }
424         /*
425          * Received authentication protocol and data match
426          * our fake data. Substitute the fake data with real
427          * data.
428          */
429         memcpy(ucp + 12 + ((proto_len + 3) & ~3),
430             x11_saved_data, x11_saved_data_len);
431         return 1;
432 }
433
434 void
435 channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
436 {
437         int ret = x11_open_helper(c);
438         if (ret == 1) {
439                 /* Start normal processing for the channel. */
440                 c->type = SSH_CHANNEL_OPEN;
441                 channel_pre_open_13(c, readset, writeset);
442         } else if (ret == -1) {
443                 /*
444                  * We have received an X11 connection that has bad
445                  * authentication information.
446                  */
447                 log("X11 connection rejected because of wrong authentication.\r\n");
448                 buffer_clear(&c->input);
449                 buffer_clear(&c->output);
450                 close(c->sock);
451                 c->sock = -1;
452                 c->type = SSH_CHANNEL_CLOSED;
453                 packet_start(SSH_MSG_CHANNEL_CLOSE);
454                 packet_put_int(c->remote_id);
455                 packet_send();
456         }
457 }
458
459 void
460 channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
461 {
462         int ret = x11_open_helper(c);
463         if (ret == 1) {
464                 c->type = SSH_CHANNEL_OPEN;
465                 channel_pre_open_15(c, readset, writeset);
466         } else if (ret == -1) {
467                 debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
468                 chan_read_failed(c);    /** force close? */
469                 chan_write_failed(c);
470                 debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
471         }
472 }
473
474 /* This is our fake X11 server socket. */
475 void
476 channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
477 {
478         struct sockaddr addr;
479         int newsock, newch;
480         socklen_t addrlen;
481         char buf[16384], *remote_hostname;
482         int remote_port;
483
484         if (FD_ISSET(c->sock, readset)) {
485                 debug("X11 connection requested.");
486                 addrlen = sizeof(addr);
487                 newsock = accept(c->sock, &addr, &addrlen);
488                 if (newsock < 0) {
489                         error("accept: %.100s", strerror(errno));
490                         return;
491                 }
492                 remote_hostname = get_remote_hostname(newsock);
493                 remote_port = get_peer_port(newsock);
494                 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
495                     remote_hostname, remote_port);
496
497                 newch = channel_new("x11",
498                     SSH_CHANNEL_OPENING, newsock, newsock, -1,
499                     c->local_window_max, c->local_maxpacket,
500                     0, xstrdup(buf));
501                 if (compat20) {
502                         packet_start(SSH2_MSG_CHANNEL_OPEN);
503                         packet_put_cstring("x11");
504                         packet_put_int(newch);
505                         packet_put_int(c->local_window_max);
506                         packet_put_int(c->local_maxpacket);
507                         /* originator host and port */
508                         packet_put_cstring(remote_hostname);
509                         packet_put_int(remote_port);
510                         packet_send();
511                 } else {
512                         packet_start(SSH_SMSG_X11_OPEN);
513                         packet_put_int(newch);
514                         if (have_hostname_in_open)
515                                 packet_put_string(buf, strlen(buf));
516                         packet_send();
517                 }
518                 xfree(remote_hostname);
519         }
520 }
521
522 /*
523  * This socket is listening for connections to a forwarded TCP/IP port.
524  */
525 void
526 channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
527 {
528         struct sockaddr addr;
529         int newsock, newch;
530         socklen_t addrlen;
531         char buf[1024], *remote_hostname;
532         int remote_port;
533
534         if (FD_ISSET(c->sock, readset)) {
535                 debug("Connection to port %d forwarding "
536                     "to %.100s port %d requested.",
537                     c->listening_port, c->path, c->host_port);
538                 addrlen = sizeof(addr);
539                 newsock = accept(c->sock, &addr, &addrlen);
540                 if (newsock < 0) {
541                         error("accept: %.100s", strerror(errno));
542                         return;
543                 }
544                 remote_hostname = get_remote_hostname(newsock);
545                 remote_port = get_peer_port(newsock);
546                 snprintf(buf, sizeof buf,
547                     "listen port %d for %.100s port %d, "
548                     "connect from %.200s port %d",
549                     c->listening_port, c->path, c->host_port,
550                     remote_hostname, remote_port);
551                 newch = channel_new("direct-tcpip",
552                     SSH_CHANNEL_OPENING, newsock, newsock, -1,
553                     c->local_window_max, c->local_maxpacket,
554                     0, xstrdup(buf));
555                 if (compat20) {
556                         packet_start(SSH2_MSG_CHANNEL_OPEN);
557                         packet_put_cstring("direct-tcpip");
558                         packet_put_int(newch);
559                         packet_put_int(c->local_window_max);
560                         packet_put_int(c->local_maxpacket);
561                         /* target host and port */
562                         packet_put_string(c->path, strlen(c->path));
563                         packet_put_int(c->host_port);
564                         /* originator host and port */
565                         packet_put_cstring(remote_hostname);
566                         packet_put_int(remote_port);
567                         packet_send();
568                 } else {
569                         packet_start(SSH_MSG_PORT_OPEN);
570                         packet_put_int(newch);
571                         packet_put_string(c->path, strlen(c->path));
572                         packet_put_int(c->host_port);
573                         if (have_hostname_in_open) {
574                                 packet_put_string(buf, strlen(buf));
575                         }
576                         packet_send();
577                 }
578                 xfree(remote_hostname);
579         }
580 }
581
582 /*
583  * This is the authentication agent socket listening for connections from
584  * clients.
585  */
586 void
587 channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
588 {
589         struct sockaddr addr;
590         int newsock, newch;
591         socklen_t addrlen;
592
593         if (FD_ISSET(c->sock, readset)) {
594                 addrlen = sizeof(addr);
595                 newsock = accept(c->sock, &addr, &addrlen);
596                 if (newsock < 0) {
597                         error("accept from auth socket: %.100s", strerror(errno));
598                         return;
599                 }
600                 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
601                     xstrdup("accepted auth socket"));
602                 packet_start(SSH_SMSG_AGENT_OPEN);
603                 packet_put_int(newch);
604                 packet_send();
605         }
606 }
607
608 int
609 channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
610 {
611         char buf[16*1024];
612         int len;
613
614         if (c->rfd != -1 &&
615             FD_ISSET(c->rfd, readset)) {
616                 len = read(c->rfd, buf, sizeof(buf));
617                 if (len <= 0) {
618                         debug("channel %d: read<=0 rfd %d len %d",
619                             c->self, c->rfd, len);
620                         if (compat13) {
621                                 buffer_consume(&c->output, buffer_len(&c->output));
622                                 c->type = SSH_CHANNEL_INPUT_DRAINING;
623                                 debug("Channel %d status set to input draining.", c->self);
624                         } else {
625                                 chan_read_failed(c);
626                         }
627                         return -1;
628                 }
629                 buffer_append(&c->input, buf, len);
630         }
631         return 1;
632 }
633 int
634 channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
635 {
636         int len;
637
638         /* Send buffered output data to the socket. */
639         if (c->wfd != -1 &&
640             FD_ISSET(c->wfd, writeset) &&
641             buffer_len(&c->output) > 0) {
642                 len = write(c->wfd, buffer_ptr(&c->output),
643                             buffer_len(&c->output));
644                 if (len <= 0) {
645                         if (compat13) {
646                                 buffer_consume(&c->output, buffer_len(&c->output));
647                                 debug("Channel %d status set to input draining.", c->self);
648                                 c->type = SSH_CHANNEL_INPUT_DRAINING;
649                         } else {
650                                 chan_write_failed(c);
651                         }
652                         return -1;
653                 }
654                 buffer_consume(&c->output, len);
655                 if (compat20 && len > 0) {
656                         c->local_consumed += len;
657                 }
658         }
659         return 1;
660 }
661 int
662 channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
663 {
664         char buf[16*1024];
665         int len;
666
667 /** XXX handle drain efd, too */
668         if (c->efd != -1) {
669                 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
670                     FD_ISSET(c->efd, writeset) &&
671                     buffer_len(&c->extended) > 0) {
672                         len = write(c->efd, buffer_ptr(&c->extended),
673                             buffer_len(&c->extended));
674                         debug("channel %d: written %d to efd %d",
675                             c->self, len, c->efd);
676                         if (len > 0) {
677                                 buffer_consume(&c->extended, len);
678                                 c->local_consumed += len;
679                         }
680                 } else if (c->extended_usage == CHAN_EXTENDED_READ &&
681                     FD_ISSET(c->efd, readset)) {
682                         len = read(c->efd, buf, sizeof(buf));
683                         debug("channel %d: read %d from efd %d",
684                              c->self, len, c->efd);
685                         if (len == 0) {
686                                 debug("channel %d: closing efd %d",
687                                     c->self, c->efd);
688                                 close(c->efd);
689                                 c->efd = -1;
690                         } else if (len > 0)
691                                 buffer_append(&c->extended, buf, len);
692                 }
693         }
694         return 1;
695 }
696 int
697 channel_check_window(Channel *c, fd_set * readset, fd_set * writeset)
698 {
699         if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
700             c->local_window < c->local_window_max/2 &&
701             c->local_consumed > 0) {
702                 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
703                 packet_put_int(c->remote_id);
704                 packet_put_int(c->local_consumed);
705                 packet_send();
706                 debug("channel %d: window %d sent adjust %d",
707                     c->self, c->local_window,
708                     c->local_consumed);
709                 c->local_window += c->local_consumed;
710                 c->local_consumed = 0;
711         }
712         return 1;
713 }
714
715 void
716 channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset)
717 {
718         channel_handle_rfd(c, readset, writeset);
719         channel_handle_wfd(c, readset, writeset);
720 }
721
722 void
723 channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset)
724 {
725         channel_handle_rfd(c, readset, writeset);
726         channel_handle_wfd(c, readset, writeset);
727         channel_handle_efd(c, readset, writeset);
728         channel_check_window(c, readset, writeset);
729 }
730
731 void
732 channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
733 {
734         int len;
735         /* Send buffered output data to the socket. */
736         if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {
737                 len = write(c->sock, buffer_ptr(&c->output),
738                             buffer_len(&c->output));
739                 if (len <= 0)
740                         buffer_consume(&c->output, buffer_len(&c->output));
741                 else
742                         buffer_consume(&c->output, len);
743         }
744 }
745
746 void
747 channel_handler_init_20(void)
748 {
749         channel_pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open_20;
750         channel_pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open;
751         channel_pre[SSH_CHANNEL_PORT_LISTENER] =        &channel_pre_listener;
752         channel_pre[SSH_CHANNEL_X11_LISTENER] =         &channel_pre_listener;
753
754         channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open_2;
755         channel_post[SSH_CHANNEL_PORT_LISTENER] =       &channel_post_port_listener;
756         channel_post[SSH_CHANNEL_X11_LISTENER] =        &channel_post_x11_listener;
757 }
758
759 void
760 channel_handler_init_13(void)
761 {
762         channel_pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open_13;
763         channel_pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open_13;
764         channel_pre[SSH_CHANNEL_X11_LISTENER] =         &channel_pre_listener;
765         channel_pre[SSH_CHANNEL_PORT_LISTENER] =        &channel_pre_listener;
766         channel_pre[SSH_CHANNEL_AUTH_SOCKET] =          &channel_pre_listener;
767         channel_pre[SSH_CHANNEL_INPUT_DRAINING] =       &channel_pre_input_draining;
768         channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] =      &channel_pre_output_draining;
769
770         channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open_1;
771         channel_post[SSH_CHANNEL_X11_LISTENER] =        &channel_post_x11_listener;
772         channel_post[SSH_CHANNEL_PORT_LISTENER] =       &channel_post_port_listener;
773         channel_post[SSH_CHANNEL_AUTH_SOCKET] =         &channel_post_auth_listener;
774         channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =     &channel_post_output_drain_13;
775 }
776
777 void
778 channel_handler_init_15(void)
779 {
780         channel_pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open_15;
781         channel_pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open;
782         channel_pre[SSH_CHANNEL_X11_LISTENER] =         &channel_pre_listener;
783         channel_pre[SSH_CHANNEL_PORT_LISTENER] =        &channel_pre_listener;
784         channel_pre[SSH_CHANNEL_AUTH_SOCKET] =          &channel_pre_listener;
785
786         channel_post[SSH_CHANNEL_X11_LISTENER] =        &channel_post_x11_listener;
787         channel_post[SSH_CHANNEL_PORT_LISTENER] =       &channel_post_port_listener;
788         channel_post[SSH_CHANNEL_AUTH_SOCKET] =         &channel_post_auth_listener;
789         channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open_1;
790 }
791
792 void
793 channel_handler_init(void)
794 {
795         int i;
796         for(i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
797                 channel_pre[i] = NULL;
798                 channel_post[i] = NULL;
799         }
800         if (compat20)
801                 channel_handler_init_20();
802         else if (compat13)
803                 channel_handler_init_13();
804         else
805                 channel_handler_init_15();
806 }
807
808 void
809 channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
810 {
811         static int did_init = 0;
812         int i;
813         Channel *c;
814
815         if (!did_init) {
816                 channel_handler_init();
817                 did_init = 1;
818         }
819         for (i = 0; i < channels_alloc; i++) {
820                 c = &channels[i];
821                 if (c->type == SSH_CHANNEL_FREE)
822                         continue;
823                 if (ftab[c->type] == NULL)
824                         continue;
825                 (*ftab[c->type])(c, readset, writeset);
826                 chan_delete_if_full_closed(c);
827         }
828 }
829
830 void
831 channel_prepare_select(fd_set * readset, fd_set * writeset)
832 {
833         channel_handler(channel_pre, readset, writeset);
834 }
835
836 void
837 channel_after_select(fd_set * readset, fd_set * writeset)
838 {
839         channel_handler(channel_post, readset, writeset);
840 }
841
842 /* If there is data to send to the connection, send some of it now. */
843
844 void
845 channel_output_poll()
846 {
847         int len, i;
848         Channel *c;
849
850         for (i = 0; i < channels_alloc; i++) {
851                 c = &channels[i];
852
853                 /* We are only interested in channels that can have buffered incoming data. */
854                 if (compat13) {
855                         if (c->type != SSH_CHANNEL_OPEN &&
856                             c->type != SSH_CHANNEL_INPUT_DRAINING)
857                                 continue;
858                 } else {
859                         if (c->type != SSH_CHANNEL_OPEN)
860                                 continue;
861                         if (c->istate != CHAN_INPUT_OPEN &&
862                             c->istate != CHAN_INPUT_WAIT_DRAIN)
863                                 continue;
864                 }
865                 if (compat20 &&
866                     (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
867                         debug("channel: %d: no data after CLOSE", c->self);
868                         continue;
869                 }
870
871                 /* Get the amount of buffered data for this channel. */
872                 len = buffer_len(&c->input);
873                 if (len > 0) {
874                         /* Send some data for the other side over the secure connection. */
875                         if (compat20) {
876                                 if (len > c->remote_window)
877                                         len = c->remote_window;
878                                 if (len > c->remote_maxpacket)
879                                         len = c->remote_maxpacket;
880                         } else {
881                                 if (packet_is_interactive()) {
882                                         if (len > 1024)
883                                                 len = 512;
884                                 } else {
885                                         /* Keep the packets at reasonable size. */
886                                         if (len > packet_get_maxsize()/2)
887                                                 len = packet_get_maxsize()/2;
888                                 }
889                         }
890                         if (len > 0) {
891                                 packet_start(compat20 ?
892                                     SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
893                                 packet_put_int(c->remote_id);
894                                 packet_put_string(buffer_ptr(&c->input), len);
895                                 packet_send();
896                                 buffer_consume(&c->input, len);
897                                 c->remote_window -= len;
898                                 debug("channel %d: send data len %d", c->self, len);
899                         }
900                 } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
901                         if (compat13)
902                                 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
903                         /*
904                          * input-buffer is empty and read-socket shutdown:
905                          * tell peer, that we will not send more data: send IEOF
906                          */
907                         chan_ibuf_empty(c);
908                 }
909                 /* Send extended data, i.e. stderr */
910                 if (compat20 &&
911                     c->remote_window > 0 &&
912                     (len = buffer_len(&c->extended)) > 0 &&
913                     c->extended_usage == CHAN_EXTENDED_READ) {
914                         if (len > c->remote_window)
915                                 len = c->remote_window;
916                         if (len > c->remote_maxpacket)
917                                 len = c->remote_maxpacket;
918                         packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA);
919                         packet_put_int(c->remote_id);
920                         packet_put_int(SSH2_EXTENDED_DATA_STDERR);
921                         packet_put_string(buffer_ptr(&c->extended), len);
922                         packet_send();
923                         buffer_consume(&c->extended, len);
924                         c->remote_window -= len;
925                 }
926         }
927 }
928
929 /*
930  * This is called when a packet of type CHANNEL_DATA has just been received.
931  * The message type has already been consumed, but channel number and data is
932  * still there.
933  */
934
935 void
936 channel_input_data(int type, int plen)
937 {
938         int id;
939         char *data;
940         unsigned int data_len;
941         Channel *c;
942
943         /* Get the channel number and verify it. */
944         id = packet_get_int();
945         c = channel_lookup(id);
946         if (c == NULL)
947                 packet_disconnect("Received data for nonexistent channel %d.", id);
948
949         /* Ignore any data for non-open channels (might happen on close) */
950         if (c->type != SSH_CHANNEL_OPEN &&
951             c->type != SSH_CHANNEL_X11_OPEN)
952                 return;
953
954         /* same for protocol 1.5 if output end is no longer open */
955         if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN)
956                 return;
957
958         /* Get the data. */
959         data = packet_get_string(&data_len);
960         packet_done();
961
962         if (compat20){
963                 if (data_len > c->local_maxpacket) {
964                         log("channel %d: rcvd big packet %d, maxpack %d",
965                             c->self, data_len, c->local_maxpacket);
966                 }
967                 if (data_len > c->local_window) {
968                         log("channel %d: rcvd too much data %d, win %d",
969                             c->self, data_len, c->local_window);
970                         xfree(data);
971                         return;
972                 }
973                 c->local_window -= data_len;
974         }else{
975                 packet_integrity_check(plen, 4 + 4 + data_len, type);
976         }
977         buffer_append(&c->output, data, data_len);
978         xfree(data);
979 }
980 void
981 channel_input_extended_data(int type, int plen)
982 {
983         int id;
984         int tcode;
985         char *data;
986         unsigned int data_len;
987         Channel *c;
988
989         /* Get the channel number and verify it. */
990         id = packet_get_int();
991         c = channel_lookup(id);
992
993         if (c == NULL)
994                 packet_disconnect("Received extended_data for bad channel %d.", id);
995         if (c->type != SSH_CHANNEL_OPEN) {
996                 log("channel %d: ext data for non open", id);
997                 return;
998         }
999         tcode = packet_get_int();
1000         if (c->efd == -1 ||
1001             c->extended_usage != CHAN_EXTENDED_WRITE ||
1002             tcode != SSH2_EXTENDED_DATA_STDERR) {
1003                 log("channel %d: bad ext data", c->self);
1004                 return;
1005         }
1006         data = packet_get_string(&data_len);
1007         packet_done();
1008         if (data_len > c->local_window) {
1009                 log("channel %d: rcvd too much extended_data %d, win %d",
1010                     c->self, data_len, c->local_window);
1011                 xfree(data);
1012                 return;
1013         }
1014         debug("channel %d: rcvd ext data %d", c->self, data_len);
1015         c->local_window -= data_len;
1016         buffer_append(&c->extended, data, data_len);
1017         xfree(data);
1018 }
1019
1020
1021 /*
1022  * Returns true if no channel has too much buffered data, and false if one or
1023  * more channel is overfull.
1024  */
1025
1026 int
1027 channel_not_very_much_buffered_data()
1028 {
1029         unsigned int i;
1030         Channel *c;
1031
1032         for (i = 0; i < channels_alloc; i++) {
1033                 c = &channels[i];
1034                 if (c->type == SSH_CHANNEL_OPEN) {
1035                         if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) {
1036                                 debug("channel %d: big input buffer %d",
1037                                     c->self, buffer_len(&c->input));
1038                                 return 0;
1039                         }
1040                         if (buffer_len(&c->output) > packet_get_maxsize()) {
1041                                 debug("channel %d: big output buffer %d",
1042                                     c->self, buffer_len(&c->output));
1043                                 return 0;
1044                         }
1045                 }
1046         }
1047         return 1;
1048 }
1049
1050 void
1051 channel_input_ieof(int type, int plen)
1052 {
1053         int id;
1054         Channel *c;
1055
1056         packet_integrity_check(plen, 4, type);
1057
1058         id = packet_get_int();
1059         c = channel_lookup(id);
1060         if (c == NULL)
1061                 packet_disconnect("Received ieof for nonexistent channel %d.", id);
1062         chan_rcvd_ieof(c);
1063 }
1064
1065 void
1066 channel_input_close(int type, int plen)
1067 {
1068         int id;
1069         Channel *c;
1070
1071         packet_integrity_check(plen, 4, type);
1072
1073         id = packet_get_int();
1074         c = channel_lookup(id);
1075         if (c == NULL)
1076                 packet_disconnect("Received close for nonexistent channel %d.", id);
1077
1078         /*
1079          * Send a confirmation that we have closed the channel and no more
1080          * data is coming for it.
1081          */
1082         packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
1083         packet_put_int(c->remote_id);
1084         packet_send();
1085
1086         /*
1087          * If the channel is in closed state, we have sent a close request,
1088          * and the other side will eventually respond with a confirmation.
1089          * Thus, we cannot free the channel here, because then there would be
1090          * no-one to receive the confirmation.  The channel gets freed when
1091          * the confirmation arrives.
1092          */
1093         if (c->type != SSH_CHANNEL_CLOSED) {
1094                 /*
1095                  * Not a closed channel - mark it as draining, which will
1096                  * cause it to be freed later.
1097                  */
1098                 buffer_consume(&c->input, buffer_len(&c->input));
1099                 c->type = SSH_CHANNEL_OUTPUT_DRAINING;
1100         }
1101 }
1102
1103 /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
1104 void
1105 channel_input_oclose(int type, int plen)
1106 {
1107         int id = packet_get_int();
1108         Channel *c = channel_lookup(id);
1109         packet_integrity_check(plen, 4, type);
1110         if (c == NULL)
1111                 packet_disconnect("Received oclose for nonexistent channel %d.", id);
1112         chan_rcvd_oclose(c);
1113 }
1114
1115 void
1116 channel_input_close_confirmation(int type, int plen)
1117 {
1118         int id = packet_get_int();
1119         Channel *c = channel_lookup(id);
1120
1121         packet_done();
1122         if (c == NULL)
1123                 packet_disconnect("Received close confirmation for "
1124                     "out-of-range channel %d.", id);
1125         if (c->type != SSH_CHANNEL_CLOSED)
1126                 packet_disconnect("Received close confirmation for "
1127                     "non-closed channel %d (type %d).", id, c->type);
1128         channel_free(c->self);
1129 }
1130
1131 void
1132 channel_input_open_confirmation(int type, int plen)
1133 {
1134         int id, remote_id;
1135         Channel *c;
1136
1137         if (!compat20)
1138                 packet_integrity_check(plen, 4 + 4, type);
1139
1140         id = packet_get_int();
1141         c = channel_lookup(id);
1142
1143         if (c==NULL || c->type != SSH_CHANNEL_OPENING)
1144                 packet_disconnect("Received open confirmation for "
1145                     "non-opening channel %d.", id);
1146         remote_id = packet_get_int();
1147         /* Record the remote channel number and mark that the channel is now open. */
1148         c->remote_id = remote_id;
1149         c->type = SSH_CHANNEL_OPEN;
1150
1151         if (compat20) {
1152                 c->remote_window = packet_get_int();
1153                 c->remote_maxpacket = packet_get_int();
1154                 packet_done();
1155                 if (c->cb_fn != NULL && c->cb_event == type) {
1156                         debug("callback start");
1157                         c->cb_fn(c->self, c->cb_arg);
1158                         debug("callback done");
1159                 }
1160                 debug("channel %d: open confirm rwindow %d rmax %d", c->self,
1161                     c->remote_window, c->remote_maxpacket);
1162         }
1163 }
1164
1165 void
1166 channel_input_open_failure(int type, int plen)
1167 {
1168         int id;
1169         Channel *c;
1170
1171         if (!compat20)
1172                 packet_integrity_check(plen, 4, type);
1173
1174         id = packet_get_int();
1175         c = channel_lookup(id);
1176
1177         if (c==NULL || c->type != SSH_CHANNEL_OPENING)
1178                 packet_disconnect("Received open failure for "
1179                     "non-opening channel %d.", id);
1180         if (compat20) {
1181                 int reason = packet_get_int();
1182                 char *msg  = packet_get_string(NULL);
1183                 char *lang  = packet_get_string(NULL);
1184                 log("channel_open_failure: %d: reason %d: %s", id, reason, msg);
1185                 packet_done();
1186                 xfree(msg);
1187                 xfree(lang);
1188         }
1189         /* Free the channel.  This will also close the socket. */
1190         channel_free(id);
1191 }
1192
1193 void
1194 channel_input_channel_request(int type, int plen)
1195 {
1196         int id;
1197         Channel *c;
1198
1199         id = packet_get_int();
1200         c = channel_lookup(id);
1201
1202         if (c == NULL ||
1203             (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_LARVAL))
1204                 packet_disconnect("Received request for "
1205                     "non-open channel %d.", id);
1206         if (c->cb_fn != NULL && c->cb_event == type) {
1207                 debug("callback start");
1208                 c->cb_fn(c->self, c->cb_arg);
1209                 debug("callback done");
1210         } else {
1211                 char *service = packet_get_string(NULL);
1212                 debug("channel: %d rcvd request for %s", c->self, service);
1213 debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event);
1214                 xfree(service);
1215         }
1216 }
1217
1218 void
1219 channel_input_window_adjust(int type, int plen)
1220 {
1221         Channel *c;
1222         int id, adjust;
1223
1224         if (!compat20)
1225                 return;
1226
1227         /* Get the channel number and verify it. */
1228         id = packet_get_int();
1229         c = channel_lookup(id);
1230
1231         if (c == NULL || c->type != SSH_CHANNEL_OPEN) {
1232                 log("Received window adjust for "
1233                     "non-open channel %d.", id);
1234                 return;
1235         }
1236         adjust = packet_get_int();
1237         packet_done();
1238         debug("channel %d: rcvd adjust %d", id, adjust);
1239         c->remote_window += adjust;
1240 }
1241
1242 /*
1243  * Stops listening for channels, and removes any unix domain sockets that we
1244  * might have.
1245  */
1246
1247 void
1248 channel_stop_listening()
1249 {
1250         int i;
1251         for (i = 0; i < channels_alloc; i++) {
1252                 switch (channels[i].type) {
1253                 case SSH_CHANNEL_AUTH_SOCKET:
1254                         close(channels[i].sock);
1255                         remove(channels[i].path);
1256                         channel_free(i);
1257                         break;
1258                 case SSH_CHANNEL_PORT_LISTENER:
1259                 case SSH_CHANNEL_X11_LISTENER:
1260                         close(channels[i].sock);
1261                         channel_free(i);
1262                         break;
1263                 default:
1264                         break;
1265                 }
1266         }
1267 }
1268
1269 /*
1270  * Closes the sockets of all channels.  This is used to close extra file
1271  * descriptors after a fork.
1272  */
1273
1274 void
1275 channel_close_all()
1276 {
1277         int i;
1278         for (i = 0; i < channels_alloc; i++) {
1279                 if (channels[i].type != SSH_CHANNEL_FREE)
1280                         close(channels[i].sock);
1281         }
1282 }
1283
1284 /* Returns the maximum file descriptor number used by the channels. */
1285
1286 int
1287 channel_max_fd()
1288 {
1289         return channel_max_fd_value;
1290 }
1291
1292 /* Returns true if any channel is still open. */
1293
1294 int
1295 channel_still_open()
1296 {
1297         unsigned int i;
1298         for (i = 0; i < channels_alloc; i++)
1299                 switch (channels[i].type) {
1300                 case SSH_CHANNEL_FREE:
1301                 case SSH_CHANNEL_X11_LISTENER:
1302                 case SSH_CHANNEL_PORT_LISTENER:
1303                 case SSH_CHANNEL_CLOSED:
1304                 case SSH_CHANNEL_AUTH_SOCKET:
1305                         continue;
1306                 case SSH_CHANNEL_LARVAL:
1307                         if (!compat20)
1308                                 fatal("cannot happen: SSH_CHANNEL_LARVAL");
1309                         continue;
1310                 case SSH_CHANNEL_OPENING:
1311                 case SSH_CHANNEL_OPEN:
1312                 case SSH_CHANNEL_X11_OPEN:
1313                         return 1;
1314                 case SSH_CHANNEL_INPUT_DRAINING:
1315                 case SSH_CHANNEL_OUTPUT_DRAINING:
1316                         if (!compat13)
1317                                 fatal("cannot happen: OUT_DRAIN");
1318                         return 1;
1319                 default:
1320                         fatal("channel_still_open: bad channel type %d", channels[i].type);
1321                         /* NOTREACHED */
1322                 }
1323         return 0;
1324 }
1325
1326 /*
1327  * Returns a message describing the currently open forwarded connections,
1328  * suitable for sending to the client.  The message contains crlf pairs for
1329  * newlines.
1330  */
1331
1332 char *
1333 channel_open_message()
1334 {
1335         Buffer buffer;
1336         int i;
1337         char buf[512], *cp;
1338
1339         buffer_init(&buffer);
1340         snprintf(buf, sizeof buf, "The following connections are open:\r\n");
1341         buffer_append(&buffer, buf, strlen(buf));
1342         for (i = 0; i < channels_alloc; i++) {
1343                 Channel *c = &channels[i];
1344                 switch (c->type) {
1345                 case SSH_CHANNEL_FREE:
1346                 case SSH_CHANNEL_X11_LISTENER:
1347                 case SSH_CHANNEL_PORT_LISTENER:
1348                 case SSH_CHANNEL_CLOSED:
1349                 case SSH_CHANNEL_AUTH_SOCKET:
1350                         continue;
1351                 case SSH_CHANNEL_LARVAL:
1352                 case SSH_CHANNEL_OPENING:
1353                 case SSH_CHANNEL_OPEN:
1354                 case SSH_CHANNEL_X11_OPEN:
1355                 case SSH_CHANNEL_INPUT_DRAINING:
1356                 case SSH_CHANNEL_OUTPUT_DRAINING:
1357                         snprintf(buf, sizeof buf, "  #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n",
1358                             c->self, c->remote_name,
1359                             c->type, c->remote_id,
1360                             c->istate, buffer_len(&c->input),
1361                             c->ostate, buffer_len(&c->output),
1362                             c->rfd, c->wfd);
1363                         buffer_append(&buffer, buf, strlen(buf));
1364                         continue;
1365                 default:
1366                         fatal("channel_open_message: bad channel type %d", c->type);
1367                         /* NOTREACHED */
1368                 }
1369         }
1370         buffer_append(&buffer, "\0", 1);
1371         cp = xstrdup(buffer_ptr(&buffer));
1372         buffer_free(&buffer);
1373         return cp;
1374 }
1375
1376 /*
1377  * Initiate forwarding of connections to local port "port" through the secure
1378  * channel to host:port from remote side.
1379  */
1380
1381 void
1382 channel_request_local_forwarding(u_short port, const char *host,
1383                                  u_short host_port, int gateway_ports)
1384 {
1385         int success, ch, sock, on = 1;
1386         struct addrinfo hints, *ai, *aitop;
1387         char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1388         struct linger linger;
1389
1390         if (strlen(host) > sizeof(channels[0].path) - 1)
1391                 packet_disconnect("Forward host name too long.");
1392
1393         /*
1394          * getaddrinfo returns a loopback address if the hostname is
1395          * set to NULL and hints.ai_flags is not AI_PASSIVE
1396          */
1397         memset(&hints, 0, sizeof(hints));
1398         hints.ai_family = IPv4or6;
1399         hints.ai_flags = gateway_ports ? AI_PASSIVE : 0;
1400         hints.ai_socktype = SOCK_STREAM;
1401         snprintf(strport, sizeof strport, "%d", port);
1402         if (getaddrinfo(NULL, strport, &hints, &aitop) != 0)
1403                 packet_disconnect("getaddrinfo: fatal error");
1404
1405         success = 0;
1406         for (ai = aitop; ai; ai = ai->ai_next) {
1407                 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1408                         continue;
1409                 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
1410                     strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
1411                         error("channel_request_local_forwarding: getnameinfo failed");
1412                         continue;
1413                 }
1414                 /* Create a port to listen for the host. */
1415                 sock = socket(ai->ai_family, SOCK_STREAM, 0);
1416                 if (sock < 0) {
1417                         /* this is no error since kernel may not support ipv6 */
1418                         verbose("socket: %.100s", strerror(errno));
1419                         continue;
1420                 }
1421                 /*
1422                  * Set socket options.  We would like the socket to disappear
1423                  * as soon as it has been closed for whatever reason.
1424                  */
1425                 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
1426                 linger.l_onoff = 1;
1427                 linger.l_linger = 5;
1428                 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
1429                 debug("Local forwarding listening on %s port %s.", ntop, strport);
1430
1431                 /* Bind the socket to the address. */
1432                 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1433                         /* address can be in use ipv6 address is already bound */
1434                         if (!ai->ai_next)
1435                                 error("bind: %.100s", strerror(errno));
1436                         else
1437                                 verbose("bind: %.100s", strerror(errno));
1438                                 
1439                         close(sock);
1440                         continue;
1441                 }
1442                 /* Start listening for connections on the socket. */
1443                 if (listen(sock, 5) < 0) {
1444                         error("listen: %.100s", strerror(errno));
1445                         close(sock);
1446                         continue;
1447                 }
1448                 /* Allocate a channel number for the socket. */
1449                 ch = channel_new(
1450                     "port listener", SSH_CHANNEL_PORT_LISTENER,
1451                     sock, sock, -1,
1452                     CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1453                     0, xstrdup("port listener"));
1454                 strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
1455                 channels[ch].host_port = host_port;
1456                 channels[ch].listening_port = port;
1457                 success = 1;
1458         }
1459         if (success == 0)
1460                 packet_disconnect("cannot listen port: %d", port);
1461         freeaddrinfo(aitop);
1462 }
1463
1464 /*
1465  * Initiate forwarding of connections to port "port" on remote host through
1466  * the secure channel to host:port from local side.
1467  */
1468
1469 void
1470 channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect,
1471                                   u_short port_to_connect)
1472 {
1473         int payload_len;
1474         /* Record locally that connection to this host/port is permitted. */
1475         if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
1476                 fatal("channel_request_remote_forwarding: too many forwards");
1477
1478         permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
1479         permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
1480         permitted_opens[num_permitted_opens].listen_port = listen_port;
1481         num_permitted_opens++;
1482
1483         /* Send the forward request to the remote side. */
1484         if (compat20) {
1485                 const char *address_to_bind = "0.0.0.0";
1486                 packet_start(SSH2_MSG_GLOBAL_REQUEST);
1487                 packet_put_cstring("tcpip-forward");
1488                 packet_put_char(0);                     /* boolean: want reply */
1489                 packet_put_cstring(address_to_bind);
1490                 packet_put_int(listen_port);
1491         } else {
1492                 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
1493                 packet_put_int(listen_port);
1494                 packet_put_cstring(host_to_connect);
1495                 packet_put_int(port_to_connect);
1496                 packet_send();
1497                 packet_write_wait();
1498                 /*
1499                  * Wait for response from the remote side.  It will send a disconnect
1500                  * message on failure, and we will never see it here.
1501                  */
1502                 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
1503         }
1504 }
1505
1506 /*
1507  * This is called after receiving CHANNEL_FORWARDING_REQUEST.  This initates
1508  * listening for the port, and sends back a success reply (or disconnect
1509  * message if there was an error).  This never returns if there was an error.
1510  */
1511
1512 void
1513 channel_input_port_forward_request(int is_root)
1514 {
1515         u_short port, host_port;
1516         char *hostname;
1517
1518         /* Get arguments from the packet. */
1519         port = packet_get_int();
1520         hostname = packet_get_string(NULL);
1521         host_port = packet_get_int();
1522
1523         /*
1524          * Check that an unprivileged user is not trying to forward a
1525          * privileged port.
1526          */
1527         if (port < IPPORT_RESERVED && !is_root)
1528                 packet_disconnect("Requested forwarding of port %d but user is not root.",
1529                                   port);
1530         /*
1531          * Initiate forwarding,
1532          * bind port to localhost only (gateway ports == 0).
1533          */
1534         channel_request_local_forwarding(port, hostname, host_port, 0);
1535
1536         /* Free the argument string. */
1537         xfree(hostname);
1538 }
1539
1540 /* XXX move to aux.c */
1541 int
1542 channel_connect_to(const char *host, u_short host_port)
1543 {
1544         struct addrinfo hints, *ai, *aitop;
1545         char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1546         int gaierr;
1547         int sock = -1;
1548
1549         memset(&hints, 0, sizeof(hints));
1550         hints.ai_family = IPv4or6;
1551         hints.ai_socktype = SOCK_STREAM;
1552         snprintf(strport, sizeof strport, "%d", host_port);
1553         if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
1554                 error("%.100s: unknown host (%s)", host, gai_strerror(gaierr));
1555                 return -1;
1556         }
1557         for (ai = aitop; ai; ai = ai->ai_next) {
1558                 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1559                         continue;
1560                 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
1561                     strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
1562                         error("channel_connect_to: getnameinfo failed");
1563                         continue;
1564                 }
1565                 /* Create the socket. */
1566                 sock = socket(ai->ai_family, SOCK_STREAM, 0);
1567                 if (sock < 0) {
1568                         error("socket: %.100s", strerror(errno));
1569                         continue;
1570                 }
1571                 /* Connect to the host/port. */
1572                 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1573                         error("connect %.100s port %s: %.100s", ntop, strport,
1574                             strerror(errno));
1575                         close(sock);
1576                         continue;       /* fail -- try next */  
1577                 }
1578                 break; /* success */
1579
1580         }
1581         freeaddrinfo(aitop);
1582         if (!ai) {
1583                 error("connect %.100s port %d: failed.", host, host_port);      
1584                 return -1;
1585         }
1586         /* success */
1587         return sock;
1588 }
1589
1590 /*
1591  * This is called after receiving PORT_OPEN message.  This attempts to
1592  * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION
1593  * or CHANNEL_OPEN_FAILURE.
1594  */
1595
1596 void
1597 channel_input_port_open(int type, int plen)
1598 {
1599         u_short host_port;
1600         char *host, *originator_string;
1601         int remote_channel, sock = -1, newch, i, denied;
1602         unsigned int host_len, originator_len;
1603
1604         /* Get remote channel number. */
1605         remote_channel = packet_get_int();
1606
1607         /* Get host name to connect to. */
1608         host = packet_get_string(&host_len);
1609
1610         /* Get port to connect to. */
1611         host_port = packet_get_int();
1612
1613         /* Get remote originator name. */
1614         if (have_hostname_in_open) {
1615                 originator_string = packet_get_string(&originator_len);
1616                 originator_len += 4;    /* size of packet_int */
1617         } else {
1618                 originator_string = xstrdup("unknown (remote did not supply name)");
1619                 originator_len = 0;     /* no originator supplied */
1620         }
1621
1622         packet_integrity_check(plen,
1623             4 + 4 + host_len + 4 + originator_len, SSH_MSG_PORT_OPEN);
1624
1625         /* Check if opening that port is permitted. */
1626         denied = 0;
1627         if (!all_opens_permitted) {
1628                 /* Go trough all permitted ports. */
1629                 for (i = 0; i < num_permitted_opens; i++)
1630                         if (permitted_opens[i].port_to_connect == host_port &&
1631                             strcmp(permitted_opens[i].host_to_connect, host) == 0)
1632                                 break;
1633
1634                 /* Check if we found the requested port among those permitted. */
1635                 if (i >= num_permitted_opens) {
1636                         /* The port is not permitted. */
1637                         log("Received request to connect to %.100s:%d, but the request was denied.",
1638                             host, host_port);
1639                         denied = 1;
1640                 }
1641         }
1642         sock = denied ? -1 : channel_connect_to(host, host_port);
1643         if (sock > 0) {
1644                 /* Allocate a channel for this connection. */
1645                 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string);
1646                 channels[newch].remote_id = remote_channel;
1647
1648                 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1649                 packet_put_int(remote_channel);
1650                 packet_put_int(newch);
1651                 packet_send();
1652         } else {
1653                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1654                 packet_put_int(remote_channel);
1655                 packet_send();
1656         }
1657         xfree(host);
1658 }
1659
1660 /*
1661  * Creates an internet domain socket for listening for X11 connections.
1662  * Returns a suitable value for the DISPLAY variable, or NULL if an error
1663  * occurs.
1664  */
1665
1666 #define NUM_SOCKS       10
1667
1668 char *
1669 x11_create_display_inet(int screen_number, int x11_display_offset)
1670 {
1671         int display_number, sock;
1672         u_short port;
1673         struct addrinfo hints, *ai, *aitop;
1674         char strport[NI_MAXSERV];
1675         int gaierr, n, num_socks = 0, socks[NUM_SOCKS];
1676         char display[512];
1677         char hostname[MAXHOSTNAMELEN];
1678
1679         for (display_number = x11_display_offset;
1680              display_number < MAX_DISPLAYS;
1681              display_number++) {
1682                 port = 6000 + display_number;
1683                 memset(&hints, 0, sizeof(hints));
1684                 hints.ai_family = IPv4or6;
1685                 hints.ai_flags = AI_PASSIVE;            /* XXX loopback only ? */
1686                 hints.ai_socktype = SOCK_STREAM;
1687                 snprintf(strport, sizeof strport, "%d", port);
1688                 if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
1689                         error("getaddrinfo: %.100s", gai_strerror(gaierr));
1690                         return NULL;
1691                 }
1692                 for (ai = aitop; ai; ai = ai->ai_next) {
1693                         if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1694                                 continue;
1695                         sock = socket(ai->ai_family, SOCK_STREAM, 0);
1696                         if (sock < 0) {
1697                                 if (errno != EINVAL) {
1698                                         error("socket: %.100s", strerror(errno));
1699                                         return NULL;
1700                                 } else {
1701                                         debug("Socket family %d not supported [X11 disp create]", ai->ai_family);
1702                                         continue;
1703                                 }
1704                         }
1705                         if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1706                                 debug("bind port %d: %.100s", port, strerror(errno));
1707                                 shutdown(sock, SHUT_RDWR);
1708                                 close(sock);
1709
1710                                 if (ai->ai_next)
1711                                         continue;
1712
1713                                 for (n = 0; n < num_socks; n++) {
1714                                         shutdown(socks[n], SHUT_RDWR);
1715                                         close(socks[n]);
1716                                 }
1717                                 num_socks = 0;
1718                                 break;
1719                         }
1720                         socks[num_socks++] = sock;
1721 #ifndef DONT_TRY_OTHER_AF
1722                         if (num_socks == NUM_SOCKS)
1723                                 break;
1724 #else
1725                         break;
1726 #endif
1727                 }
1728                 if (num_socks > 0)
1729                         break;
1730         }
1731         if (display_number >= MAX_DISPLAYS) {
1732                 error("Failed to allocate internet-domain X11 display socket.");
1733                 return NULL;
1734         }
1735         /* Start listening for connections on the socket. */
1736         for (n = 0; n < num_socks; n++) {
1737                 sock = socks[n];
1738                 if (listen(sock, 5) < 0) {
1739                         error("listen: %.100s", strerror(errno));
1740                         shutdown(sock, SHUT_RDWR);
1741                         close(sock);
1742                         return NULL;
1743                 }
1744         }
1745
1746         /* Set up a suitable value for the DISPLAY variable. */
1747
1748         if (gethostname(hostname, sizeof(hostname)) < 0)
1749                 fatal("gethostname: %.100s", strerror(errno));
1750
1751 #ifdef IPADDR_IN_DISPLAY
1752         /* 
1753          * HPUX detects the local hostname in the DISPLAY variable and tries
1754          * to set up a shared memory connection to the server, which it
1755          * incorrectly supposes to be local.
1756          *
1757          * The workaround - as used in later $$H and other programs - is
1758          * is to set display to the host's IP address.
1759          */
1760         {
1761                 struct hostent *he;
1762                 struct in_addr my_addr;
1763
1764                 he = gethostbyname(hostname);
1765                 if (he == NULL) {
1766                         error("[X11-broken-fwd-hostname-workaround] Could not get "
1767                                 "IP address for hostname %s.", hostname);
1768
1769                         packet_send_debug("[X11-broken-fwd-hostname-workaround]"
1770                                 "Could not get IP address for hostname %s.", hostname);
1771
1772                         shutdown(sock, SHUT_RDWR);
1773                         close(sock);
1774
1775                         return NULL;
1776                 }
1777
1778                 memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
1779
1780                 /* Set DISPLAY to <ip address>:screen.display */
1781                 snprintf(display, sizeof(display), "%.50s:%d.%d", inet_ntoa(my_addr), 
1782                         display_number, screen_number);
1783         }
1784 #else /* IPADDR_IN_DISPLAY */
1785         /* Just set DISPLAY to hostname:screen.display */
1786         snprintf(display, sizeof display, "%.400s:%d.%d", hostname,
1787                 display_number, screen_number);
1788 #endif /* IPADDR_IN_DISPLAY */
1789
1790         /* Allocate a channel for each socket. */
1791         for (n = 0; n < num_socks; n++) {
1792                 sock = socks[n];
1793                 (void) channel_new("x11 listener",
1794                     SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
1795                     CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
1796                     0, xstrdup("X11 inet listener"));
1797         }
1798
1799         /* Return a suitable value for the DISPLAY environment variable. */
1800         return xstrdup(display);
1801 }
1802
1803 #ifndef X_UNIX_PATH
1804 #define X_UNIX_PATH "/tmp/.X11-unix/X"
1805 #endif
1806
1807 static
1808 int
1809 connect_local_xsocket(unsigned int dnr)
1810 {
1811         static const char *const x_sockets[] = {
1812                 X_UNIX_PATH "%u",
1813                 "/var/X/.X11-unix/X" "%u",
1814                 "/usr/spool/sockets/X11/" "%u",
1815                 NULL
1816         };
1817         int sock;
1818         struct sockaddr_un addr;
1819         const char *const * path;
1820
1821         for (path = x_sockets; *path; ++path) {
1822                 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1823                 if (sock < 0)
1824                         error("socket: %.100s", strerror(errno));
1825                 memset(&addr, 0, sizeof(addr));
1826                 addr.sun_family = AF_UNIX;
1827                 snprintf(addr.sun_path, sizeof addr.sun_path, *path, dnr);
1828                 if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0)
1829                         return sock;
1830                 close(sock);
1831         }
1832         error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
1833         return -1;
1834 }
1835
1836 int
1837 x11_connect_display(void)
1838 {
1839         int display_number, sock = 0;
1840         const char *display;
1841         char buf[1024], *cp;
1842         struct addrinfo hints, *ai, *aitop;
1843         char strport[NI_MAXSERV];
1844         int gaierr;
1845
1846         /* Try to open a socket for the local X server. */
1847         display = getenv("DISPLAY");
1848         if (!display) {
1849                 error("DISPLAY not set.");
1850                 return -1;
1851         }
1852         /*
1853          * Now we decode the value of the DISPLAY variable and make a
1854          * connection to the real X server.
1855          */
1856
1857         /*
1858          * Check if it is a unix domain socket.  Unix domain displays are in
1859          * one of the following formats: unix:d[.s], :d[.s], ::d[.s]
1860          */
1861         if (strncmp(display, "unix:", 5) == 0 ||
1862             display[0] == ':') {
1863                 /* Connect to the unix domain socket. */
1864                 if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
1865                         error("Could not parse display number from DISPLAY: %.100s",
1866                               display);
1867                         return -1;
1868                 }
1869                 /* Create a socket. */
1870                 sock = connect_local_xsocket(display_number);
1871                 if (sock < 0)
1872                         return -1;
1873
1874                 /* OK, we now have a connection to the display. */
1875                 return sock;
1876         }
1877         /*
1878          * Connect to an inet socket.  The DISPLAY value is supposedly
1879          * hostname:d[.s], where hostname may also be numeric IP address.
1880          */
1881         strncpy(buf, display, sizeof(buf));
1882         buf[sizeof(buf) - 1] = 0;
1883         cp = strchr(buf, ':');
1884         if (!cp) {
1885                 error("Could not find ':' in DISPLAY: %.100s", display);
1886                 return -1;
1887         }
1888         *cp = 0;
1889         /* buf now contains the host name.  But first we parse the display number. */
1890         if (sscanf(cp + 1, "%d", &display_number) != 1) {
1891                 error("Could not parse display number from DISPLAY: %.100s",
1892                       display);
1893                 return -1;
1894         }
1895
1896         /* Look up the host address */
1897         memset(&hints, 0, sizeof(hints));
1898         hints.ai_family = IPv4or6;
1899         hints.ai_socktype = SOCK_STREAM;
1900         snprintf(strport, sizeof strport, "%d", 6000 + display_number);
1901         if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
1902                 error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
1903                 return -1;
1904         }
1905         for (ai = aitop; ai; ai = ai->ai_next) {
1906                 /* Create a socket. */
1907                 sock = socket(ai->ai_family, SOCK_STREAM, 0);
1908                 if (sock < 0) {
1909                         debug("socket: %.100s", strerror(errno));
1910                         continue;
1911                 }
1912                 /* Connect it to the display. */
1913                 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1914                         debug("connect %.100s port %d: %.100s", buf,
1915                             6000 + display_number, strerror(errno));
1916                         close(sock);
1917                         continue;
1918                 }
1919                 /* Success */
1920                 break;
1921         }
1922         freeaddrinfo(aitop);
1923         if (!ai) {
1924                 error("connect %.100s port %d: %.100s", buf, 6000 + display_number,
1925                     strerror(errno));
1926                 return -1;
1927         }
1928         return sock;
1929 }
1930
1931 /*
1932  * This is called when SSH_SMSG_X11_OPEN is received.  The packet contains
1933  * the remote channel number.  We should do whatever we want, and respond
1934  * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
1935  */
1936
1937 void
1938 x11_input_open(int type, int plen)
1939 {
1940         int remote_channel, sock = 0, newch;
1941         char *remote_host;
1942         unsigned int remote_len;
1943
1944         /* Get remote channel number. */
1945         remote_channel = packet_get_int();
1946
1947         /* Get remote originator name. */
1948         if (have_hostname_in_open) {
1949                 remote_host = packet_get_string(&remote_len);
1950                 remote_len += 4;
1951         } else {
1952                 remote_host = xstrdup("unknown (remote did not supply name)");
1953                 remote_len = 0;
1954         }
1955
1956         debug("Received X11 open request.");
1957         packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN);
1958
1959         /* Obtain a connection to the real X display. */
1960         sock = x11_connect_display();
1961         if (sock == -1) {
1962                 /* Send refusal to the remote host. */
1963                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1964                 packet_put_int(remote_channel);
1965                 packet_send();
1966         } else {
1967                 /* Allocate a channel for this connection. */
1968                 newch = channel_allocate(
1969                      (x11_saved_proto == NULL) ?
1970                      SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN,
1971                      sock, remote_host);
1972                 channels[newch].remote_id = remote_channel;
1973
1974                 /* Send a confirmation to the remote host. */
1975                 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1976                 packet_put_int(remote_channel);
1977                 packet_put_int(newch);
1978                 packet_send();
1979         }
1980 }
1981
1982 /*
1983  * Requests forwarding of X11 connections, generates fake authentication
1984  * data, and enables authentication spoofing.
1985  */
1986
1987 void
1988 x11_request_forwarding_with_spoofing(int client_session_id,
1989     const char *proto, const char *data)
1990 {
1991         unsigned int data_len = (unsigned int) strlen(data) / 2;
1992         unsigned int i, value;
1993         char *new_data;
1994         int screen_number;
1995         const char *cp;
1996         u_int32_t rand = 0;
1997
1998         cp = getenv("DISPLAY");
1999         if (cp)
2000                 cp = strchr(cp, ':');
2001         if (cp)
2002                 cp = strchr(cp, '.');
2003         if (cp)
2004                 screen_number = atoi(cp + 1);
2005         else
2006                 screen_number = 0;
2007
2008         /* Save protocol name. */
2009         x11_saved_proto = xstrdup(proto);
2010
2011         /*
2012          * Extract real authentication data and generate fake data of the
2013          * same length.
2014          */
2015         x11_saved_data = xmalloc(data_len);
2016         x11_fake_data = xmalloc(data_len);
2017         for (i = 0; i < data_len; i++) {
2018                 if (sscanf(data + 2 * i, "%2x", &value) != 1)
2019                         fatal("x11_request_forwarding: bad authentication data: %.100s", data);
2020                 if (i % 4 == 0)
2021                         rand = arc4random();
2022                 x11_saved_data[i] = value;
2023                 x11_fake_data[i] = rand & 0xff;
2024                 rand >>= 8;
2025         }
2026         x11_saved_data_len = data_len;
2027         x11_fake_data_len = data_len;
2028
2029         /* Convert the fake data into hex. */
2030         new_data = xmalloc(2 * data_len + 1);
2031         for (i = 0; i < data_len; i++)
2032                 sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]);
2033
2034         /* Send the request packet. */
2035         if (compat20) {
2036                 channel_request_start(client_session_id, "x11-req", 0);
2037                 packet_put_char(0);     /* XXX bool single connection */
2038         } else {
2039                 packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
2040         }
2041         packet_put_cstring(proto);
2042         packet_put_cstring(new_data);
2043         packet_put_int(screen_number);
2044         packet_send();
2045         packet_write_wait();
2046         xfree(new_data);
2047 }
2048
2049 /* Sends a message to the server to request authentication fd forwarding. */
2050
2051 void
2052 auth_request_forwarding()
2053 {
2054         packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
2055         packet_send();
2056         packet_write_wait();
2057 }
2058
2059 /*
2060  * Returns the name of the forwarded authentication socket.  Returns NULL if
2061  * there is no forwarded authentication socket.  The returned value points to
2062  * a static buffer.
2063  */
2064
2065 char *
2066 auth_get_socket_name()
2067 {
2068         return channel_forwarded_auth_socket_name;
2069 }
2070
2071 /* removes the agent forwarding socket */
2072
2073 void
2074 cleanup_socket(void)
2075 {
2076         remove(channel_forwarded_auth_socket_name);
2077         rmdir(channel_forwarded_auth_socket_dir);
2078 }
2079
2080 /*
2081  * This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
2082  * This starts forwarding authentication requests.
2083  */
2084
2085 void
2086 auth_input_request_forwarding(struct passwd * pw)
2087 {
2088         int sock, newch;
2089         struct sockaddr_un sunaddr;
2090
2091         if (auth_get_socket_name() != NULL)
2092                 fatal("Protocol error: authentication forwarding requested twice.");
2093
2094         /* Temporarily drop privileged uid for mkdir/bind. */
2095         temporarily_use_uid(pw->pw_uid);
2096
2097         /* Allocate a buffer for the socket name, and format the name. */
2098         channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME);
2099         channel_forwarded_auth_socket_dir = xmalloc(MAX_SOCKET_NAME);
2100         strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME);
2101
2102         /* Create private directory for socket */
2103         if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL)
2104                 packet_disconnect("mkdtemp: %.100s", strerror(errno));
2105         snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME, "%s/agent.%d",
2106                  channel_forwarded_auth_socket_dir, (int) getpid());
2107
2108         if (atexit(cleanup_socket) < 0) {
2109                 int saved = errno;
2110                 cleanup_socket();
2111                 packet_disconnect("socket: %.100s", strerror(saved));
2112         }
2113         /* Create the socket. */
2114         sock = socket(AF_UNIX, SOCK_STREAM, 0);
2115         if (sock < 0)
2116                 packet_disconnect("socket: %.100s", strerror(errno));
2117
2118         /* Bind it to the name. */
2119         memset(&sunaddr, 0, sizeof(sunaddr));
2120         sunaddr.sun_family = AF_UNIX;
2121         strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_name,
2122                 sizeof(sunaddr.sun_path));
2123
2124         if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
2125                 packet_disconnect("bind: %.100s", strerror(errno));
2126
2127         /* Restore the privileged uid. */
2128         restore_uid();
2129
2130         /* Start listening on the socket. */
2131         if (listen(sock, 5) < 0)
2132                 packet_disconnect("listen: %.100s", strerror(errno));
2133
2134         /* Allocate a channel for the authentication agent socket. */
2135         newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock,
2136                                  xstrdup("auth socket"));
2137         strlcpy(channels[newch].path, channel_forwarded_auth_socket_name,
2138             sizeof(channels[newch].path));
2139 }
2140
2141 /* This is called to process an SSH_SMSG_AGENT_OPEN message. */
2142
2143 void
2144 auth_input_open_request(int type, int plen)
2145 {
2146         int remch, sock, newch;
2147         char *dummyname;
2148
2149         packet_integrity_check(plen, 4, type);
2150
2151         /* Read the remote channel number from the message. */
2152         remch = packet_get_int();
2153
2154         /*
2155          * Get a connection to the local authentication agent (this may again
2156          * get forwarded).
2157          */
2158         sock = ssh_get_authentication_socket();
2159
2160         /*
2161          * If we could not connect the agent, send an error message back to
2162          * the server. This should never happen unless the agent dies,
2163          * because authentication forwarding is only enabled if we have an
2164          * agent.
2165          */
2166         if (sock < 0) {
2167                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2168                 packet_put_int(remch);
2169                 packet_send();
2170                 return;
2171         }
2172         debug("Forwarding authentication connection.");
2173
2174         /*
2175          * Dummy host name.  This will be freed when the channel is freed; it
2176          * will still be valid in the packet_put_string below since the
2177          * channel cannot yet be freed at that point.
2178          */
2179         dummyname = xstrdup("authentication agent connection");
2180
2181         newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname);
2182         channels[newch].remote_id = remch;
2183
2184         /* Send a confirmation to the remote host. */
2185         packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
2186         packet_put_int(remch);
2187         packet_put_int(newch);
2188         packet_send();
2189 }
2190
2191 void
2192 channel_start_open(int id)
2193 {
2194         Channel *c = channel_lookup(id);
2195         if (c == NULL) {
2196                 log("channel_open: %d: bad id", id);
2197                 return;
2198         }
2199         debug("send channel open %d", id);
2200         packet_start(SSH2_MSG_CHANNEL_OPEN);
2201         packet_put_cstring(c->ctype);
2202         packet_put_int(c->self);
2203         packet_put_int(c->local_window);
2204         packet_put_int(c->local_maxpacket);
2205 }
2206 void
2207 channel_open(int id)
2208 {
2209         /* XXX REMOVE ME */
2210         channel_start_open(id);
2211         packet_send();
2212 }
2213 void
2214 channel_request(int id, char *service, int wantconfirm)
2215 {
2216         channel_request_start(id, service, wantconfirm);
2217         packet_send();
2218         debug("channel request %d: %s", id, service) ;
2219 }
2220 void
2221 channel_request_start(int id, char *service, int wantconfirm)
2222 {
2223         Channel *c = channel_lookup(id);
2224         if (c == NULL) {
2225                 log("channel_request: %d: bad id", id);
2226                 return;
2227         }
2228         packet_start(SSH2_MSG_CHANNEL_REQUEST);
2229         packet_put_int(c->remote_id);
2230         packet_put_cstring(service);
2231         packet_put_char(wantconfirm);
2232 }
2233 void
2234 channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg)
2235 {
2236         Channel *c = channel_lookup(id);
2237         if (c == NULL) {
2238                 log("channel_register_callback: %d: bad id", id);
2239                 return;
2240         }
2241         c->cb_event = mtype;
2242         c->cb_fn = fn;
2243         c->cb_arg = arg;
2244 }
2245 void
2246 channel_register_cleanup(int id, channel_callback_fn *fn)
2247 {
2248         Channel *c = channel_lookup(id);
2249         if (c == NULL) {
2250                 log("channel_register_cleanup: %d: bad id", id);
2251                 return;
2252         }
2253         c->dettach_user = fn;
2254 }
2255 void
2256 channel_cancel_cleanup(int id)
2257 {
2258         Channel *c = channel_lookup(id);
2259         if (c == NULL) {
2260                 log("channel_cancel_cleanup: %d: bad id", id);
2261                 return;
2262         }
2263         c->dettach_user = NULL;
2264 }
2265
2266 void
2267 channel_set_fds(int id, int rfd, int wfd, int efd, int extusage)
2268 {
2269         Channel *c = channel_lookup(id);
2270         if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
2271                 fatal("channel_activate for non-larval channel %d.", id);
2272         if (rfd > channel_max_fd_value)
2273                 channel_max_fd_value = rfd;
2274         if (wfd > channel_max_fd_value)
2275                 channel_max_fd_value = wfd;
2276         if (efd > channel_max_fd_value)
2277                 channel_max_fd_value = efd;
2278         c->type = SSH_CHANNEL_OPEN;
2279         c->rfd = rfd;
2280         c->wfd = wfd;
2281         c->efd = efd;
2282         c->extended_usage = extusage;
2283         /* XXX window size? */
2284         c->local_window = c->local_window_max = c->local_maxpacket/2;
2285         packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
2286         packet_put_int(c->remote_id);
2287         packet_put_int(c->local_window);
2288         packet_send();
2289 }
This page took 0.21908 seconds and 5 git commands to generate.