1 /*        $NetBSD: channels.c,v 1.46 2025/04/09 15:49:32 christos Exp $         */
2 /* $OpenBSD: channels.c,v 1.442 2024/12/05 06:49:26 dtucker Exp $ */
3 
4 /*
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
7  *                    All rights reserved
8  * This file contains functions for generic socket connection forwarding.
9  * There is also code for initiating connection forwarding for X11 connections,
10  * arbitrary tcp/ip connections, and the authentication agent connection.
11  *
12  * As far as I am concerned, the code I have written for this software
13  * can be used freely for any purpose.  Any derived versions of this
14  * software must be clearly marked as such, and if the derived work is
15  * incompatible with the protocol description in the RFC file, it must be
16  * called by a name other than "ssh" or "Secure Shell".
17  *
18  * SSH2 support added by Markus Friedl.
19  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
20  * Copyright (c) 1999 Dug Song.  All rights reserved.
21  * Copyright (c) 1999 Theo de Raadt.  All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
33  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
35  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
36  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
41  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  */
43 
44 #include "includes.h"
45 __RCSID("$NetBSD: channels.c,v 1.46 2025/04/09 15:49:32 christos Exp $");
46 #include <sys/param.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <sys/ioctl.h>
50 #include <sys/un.h>
51 #include <sys/socket.h>
52 #include <sys/time.h>
53 #include <sys/queue.h>
54 
55 #include <netinet/in.h>
56 #include <arpa/inet.h>
57 
58 #include <errno.h>
59 #include <fcntl.h>
60 #include <limits.h>
61 #include <netdb.h>
62 #include <poll.h>
63 #include <stdarg.h>
64 #include <stdint.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <termios.h>
69 #include <unistd.h>
70 
71 #include "xmalloc.h"
72 #include "ssh.h"
73 #include "ssh2.h"
74 #include "ssherr.h"
75 #include "sshbuf.h"
76 #include "packet.h"
77 #include "log.h"
78 #include "misc.h"
79 #include "channels.h"
80 #include "compat.h"
81 #include "canohost.h"
82 #include "sshkey.h"
83 #include "authfd.h"
84 #include "pathnames.h"
85 #include "match.h"
86 
87 
88 static int hpn_disabled = 0;
89 static int hpn_buffer_size = 2 * 1024 * 1024;
90 
91 /* XXX remove once we're satisfied there's no lurking bugs */
92 /* #define DEBUG_CHANNEL_POLL 1 */
93 
94 /* -- agent forwarding */
95 #define   NUM_SOCKS 10
96 
97 /* -- X11 forwarding */
98 /* X11 port for display :0 */
99 #define X11_BASE_PORT         6000
100 /* Maximum number of fake X11 displays to try. */
101 #define MAX_DISPLAYS  1000
102 
103 /* Per-channel callback for pre/post IO actions */
104 typedef void chan_fn(struct ssh *, Channel *c);
105 
106 /*
107  * Data structure for storing which hosts are permitted for forward requests.
108  * The local sides of any remote forwards are stored in this array to prevent
109  * a corrupt remote server from accessing arbitrary TCP/IP ports on our local
110  * network (which might be behind a firewall).
111  */
112 /* XXX: streamlocal wants a path instead of host:port */
113 /*      Overload host_to_connect; we could just make this match Forward */
114 /*        XXX - can we use listen_host instead of listen_path? */
115 struct permission {
116           char *host_to_connect;                  /* Connect to 'host'. */
117           int port_to_connect;                    /* Connect to 'port'. */
118           char *listen_host;            /* Remote side should listen address. */
119           char *listen_path;            /* Remote side should listen path. */
120           int listen_port;              /* Remote side should listen port. */
121           Channel *downstream;                    /* Downstream mux*/
122 };
123 
124 /*
125  * Stores the forwarding permission state for a single direction (local or
126  * remote).
127  */
128 struct permission_set {
129           /*
130            * List of all local permitted host/port pairs to allow for the
131            * user.
132            */
133           u_int num_permitted_user;
134           struct permission *permitted_user;
135 
136           /*
137            * List of all permitted host/port pairs to allow for the admin.
138            */
139           u_int num_permitted_admin;
140           struct permission *permitted_admin;
141 
142           /*
143            * If this is true, all opens/listens are permitted.  This is the
144            * case on the server on which we have to trust the client anyway,
145            * and the user could do anything after logging in.
146            */
147           int all_permitted;
148 };
149 
150 /* Used to record timeouts per channel type */
151 struct ssh_channel_timeout {
152           char *type_pattern;
153           int timeout_secs;
154 };
155 
156 /* Master structure for channels state */
157 struct ssh_channels {
158           /*
159            * Pointer to an array containing all allocated channels.  The array
160            * is dynamically extended as needed.
161            */
162           Channel **channels;
163 
164           /*
165            * Size of the channel array.  All slots of the array must always be
166            * initialized (at least the type field); unused slots set to NULL
167            */
168           u_int channels_alloc;
169 
170           /*
171            * 'channel_pre*' are called just before IO to add any bits
172            * relevant to channels in the c->io_want bitmasks.
173            *
174            * 'channel_post*': perform any appropriate operations for
175            * channels which have c->io_ready events pending.
176            */
177           chan_fn **channel_pre;
178           chan_fn **channel_post;
179 
180           /* -- tcp forwarding */
181           struct permission_set local_perms;
182           struct permission_set remote_perms;
183 
184           /* -- X11 forwarding */
185 
186           /* Saved X11 local (client) display. */
187           char *x11_saved_display;
188 
189           /* Saved X11 authentication protocol name. */
190           char *x11_saved_proto;
191 
192           /* Saved X11 authentication data.  This is the real data. */
193           char *x11_saved_data;
194           u_int x11_saved_data_len;
195 
196           /* Deadline after which all X11 connections are refused */
197           time_t x11_refuse_time;
198 
199           /*
200            * Fake X11 authentication data.  This is what the server will be
201            * sending us; we should replace any occurrences of this by the
202            * real data.
203            */
204           u_char *x11_fake_data;
205           u_int x11_fake_data_len;
206 
207           /* AF_UNSPEC or AF_INET or AF_INET6 */
208           int IPv4or6;
209 
210           /* Channel timeouts by type */
211           struct ssh_channel_timeout *timeouts;
212           size_t ntimeouts;
213           /* Global timeout for all OPEN channels */
214           int global_deadline;
215           time_t lastused;
216 };
217 
218 /* helper */
219 static void port_open_helper(struct ssh *ssh, Channel *c, const char *rtype);
220 static const char *channel_rfwd_bind_host(const char *listen_host);
221 
222 /* non-blocking connect helpers */
223 static int connect_next(struct channel_connect *);
224 static void channel_connect_ctx_free(struct channel_connect *);
225 static Channel *rdynamic_connect_prepare(struct ssh *, const char *,
226     const char *);
227 static int rdynamic_connect_finish(struct ssh *, Channel *);
228 
229 /* Setup helper */
230 static void channel_handler_init(struct ssh_channels *sc);
231 
232 /* -- channel core */
233 
234 void
channel_init_channels(struct ssh * ssh)235 channel_init_channels(struct ssh *ssh)
236 {
237           struct ssh_channels *sc;
238 
239           if ((sc = calloc(1, sizeof(*sc))) == NULL)
240                     fatal_f("allocation failed");
241           sc->channels_alloc = 10;
242           sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));
243           sc->IPv4or6 = AF_UNSPEC;
244           channel_handler_init(sc);
245 
246           ssh->chanctxt = sc;
247 }
248 
249 Channel *
channel_by_id(struct ssh * ssh,int id)250 channel_by_id(struct ssh *ssh, int id)
251 {
252           Channel *c;
253 
254           if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) {
255                     logit_f("%d: bad id", id);
256                     return NULL;
257           }
258           c = ssh->chanctxt->channels[id];
259           if (c == NULL) {
260                     logit_f("%d: bad id: channel free", id);
261                     return NULL;
262           }
263           return c;
264 }
265 
266 Channel *
channel_by_remote_id(struct ssh * ssh,u_int remote_id)267 channel_by_remote_id(struct ssh *ssh, u_int remote_id)
268 {
269           Channel *c;
270           u_int i;
271 
272           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
273                     c = ssh->chanctxt->channels[i];
274                     if (c != NULL && c->have_remote_id && c->remote_id == remote_id)
275                               return c;
276           }
277           return NULL;
278 }
279 
280 /*
281  * Returns the channel if it is allowed to receive protocol messages.
282  * Private channels, like listening sockets, may not receive messages.
283  */
284 Channel *
channel_lookup(struct ssh * ssh,int id)285 channel_lookup(struct ssh *ssh, int id)
286 {
287           Channel *c;
288 
289           if ((c = channel_by_id(ssh, id)) == NULL)
290                     return NULL;
291 
292           switch (c->type) {
293           case SSH_CHANNEL_X11_OPEN:
294           case SSH_CHANNEL_LARVAL:
295           case SSH_CHANNEL_CONNECTING:
296           case SSH_CHANNEL_DYNAMIC:
297           case SSH_CHANNEL_RDYNAMIC_OPEN:
298           case SSH_CHANNEL_RDYNAMIC_FINISH:
299           case SSH_CHANNEL_OPENING:
300           case SSH_CHANNEL_OPEN:
301           case SSH_CHANNEL_ABANDONED:
302           case SSH_CHANNEL_MUX_PROXY:
303                     return c;
304           }
305           logit("Non-public channel %d, type %d.", id, c->type);
306           return NULL;
307 }
308 
309 /*
310  * Add a timeout for open channels whose c->ctype (or c->xctype if it is set)
311  * match type_pattern.
312  */
313 void
channel_add_timeout(struct ssh * ssh,const char * type_pattern,int timeout_secs)314 channel_add_timeout(struct ssh *ssh, const char *type_pattern,
315     int timeout_secs)
316 {
317           struct ssh_channels *sc = ssh->chanctxt;
318 
319           if (strcmp(type_pattern, "global") == 0) {
320                     debug2_f("global channel timeout %d seconds", timeout_secs);
321                     sc->global_deadline = timeout_secs;
322                     return;
323           }
324           debug2_f("channel type \"%s\" timeout %d seconds",
325               type_pattern, timeout_secs);
326           sc->timeouts = xrecallocarray(sc->timeouts, sc->ntimeouts,
327               sc->ntimeouts + 1, sizeof(*sc->timeouts));
328           sc->timeouts[sc->ntimeouts].type_pattern = xstrdup(type_pattern);
329           sc->timeouts[sc->ntimeouts].timeout_secs = timeout_secs;
330           sc->ntimeouts++;
331 }
332 
333 /* Clears all previously-added channel timeouts */
334 void
channel_clear_timeouts(struct ssh * ssh)335 channel_clear_timeouts(struct ssh *ssh)
336 {
337           struct ssh_channels *sc = ssh->chanctxt;
338           size_t i;
339 
340           debug3_f("clearing");
341           for (i = 0; i < sc->ntimeouts; i++)
342                     free(sc->timeouts[i].type_pattern);
343           free(sc->timeouts);
344           sc->timeouts = NULL;
345           sc->ntimeouts = 0;
346 }
347 
348 static int
lookup_timeout(struct ssh * ssh,const char * type)349 lookup_timeout(struct ssh *ssh, const char *type)
350 {
351           struct ssh_channels *sc = ssh->chanctxt;
352           size_t i;
353 
354           for (i = 0; i < sc->ntimeouts; i++) {
355                     if (match_pattern(type, sc->timeouts[i].type_pattern))
356                               return sc->timeouts[i].timeout_secs;
357           }
358 
359           return 0;
360 }
361 
362 /*
363  * Sets "extended type" of a channel; used by session layer to add additional
364  * information about channel types (e.g. shell, login, subsystem) that can then
365  * be used to select timeouts.
366  * Will reset c->inactive_deadline as a side-effect.
367  */
368 void
channel_set_xtype(struct ssh * ssh,int id,const char * xctype)369 channel_set_xtype(struct ssh *ssh, int id, const char *xctype)
370 {
371           Channel *c;
372 
373           if ((c = channel_by_id(ssh, id)) == NULL)
374                     fatal_f("missing channel %d", id);
375           if (c->xctype != NULL)
376                     free(c->xctype);
377           c->xctype = xstrdup(xctype);
378           /* Type has changed, so look up inactivity deadline again */
379           c->inactive_deadline = lookup_timeout(ssh, c->xctype);
380           debug2_f("labeled channel %d as %s (inactive timeout %u)", id, xctype,
381               c->inactive_deadline);
382 }
383 
384 /*
385  * update "last used" time on a channel.
386  * NB. nothing else should update lastused except to clear it.
387  */
388 static void
channel_set_used_time(struct ssh * ssh,Channel * c)389 channel_set_used_time(struct ssh *ssh, Channel *c)
390 {
391           ssh->chanctxt->lastused = monotime();
392           if (c != NULL)
393                     c->lastused = ssh->chanctxt->lastused;
394 }
395 
396 /*
397  * Get the time at which a channel is due to time out for inactivity.
398  * Returns 0 if the channel is not due to time out ever.
399  */
400 static time_t
channel_get_expiry(struct ssh * ssh,Channel * c)401 channel_get_expiry(struct ssh *ssh, Channel *c)
402 {
403           struct ssh_channels *sc = ssh->chanctxt;
404           time_t expiry = 0, channel_expiry;
405 
406           if (sc->lastused != 0 && sc->global_deadline != 0)
407                     expiry = sc->lastused + sc->global_deadline;
408           if (c->lastused != 0 && c->inactive_deadline != 0) {
409                     channel_expiry = c->lastused + c->inactive_deadline;
410                     if (expiry == 0 || channel_expiry < expiry)
411                               expiry = channel_expiry;
412           }
413           return expiry;
414 }
415 
416 /*
417  * Register filedescriptors for a channel, used when allocating a channel or
418  * when the channel consumer/producer is ready, e.g. shell exec'd
419  */
420 static void
channel_register_fds(struct ssh * ssh,Channel * c,int rfd,int wfd,int efd,int extusage,int nonblock,int is_tty)421 channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
422     int extusage, int nonblock, int is_tty)
423 {
424           int val;
425 
426           if (rfd != -1)
427                     (void)fcntl(rfd, F_SETFD, FD_CLOEXEC);
428           if (wfd != -1 && wfd != rfd)
429                     (void)fcntl(wfd, F_SETFD, FD_CLOEXEC);
430           if (efd != -1 && efd != rfd && efd != wfd)
431                     (void)fcntl(efd, F_SETFD, FD_CLOEXEC);
432 
433           c->rfd = rfd;
434           c->wfd = wfd;
435           c->sock = (rfd == wfd) ? rfd : -1;
436           c->efd = efd;
437           c->extended_usage = extusage;
438 
439           if ((c->isatty = is_tty) != 0)
440                     debug2("channel %d: rfd %d isatty", c->self, c->rfd);
441 
442           /* enable nonblocking mode */
443           c->restore_block = 0;
444           if (nonblock == CHANNEL_NONBLOCK_STDIO) {
445                     /*
446                      * Special handling for stdio file descriptors: do not set
447                      * non-blocking mode if they are TTYs. Otherwise prepare to
448                      * restore their blocking state on exit to avoid interfering
449                      * with other programs that follow.
450                      */
451                     if (rfd != -1 && !isatty(rfd) &&
452                         (val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
453                               c->restore_flags[0] = val;
454                               c->restore_block |= CHANNEL_RESTORE_RFD;
455                               set_nonblock(rfd);
456                     }
457                     if (wfd != -1 && !isatty(wfd) &&
458                         (val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
459                               c->restore_flags[1] = val;
460                               c->restore_block |= CHANNEL_RESTORE_WFD;
461                               set_nonblock(wfd);
462                     }
463                     if (efd != -1 && !isatty(efd) &&
464                         (val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
465                               c->restore_flags[2] = val;
466                               c->restore_block |= CHANNEL_RESTORE_EFD;
467                               set_nonblock(efd);
468                     }
469           } else if (nonblock) {
470                     if (rfd != -1)
471                               set_nonblock(rfd);
472                     if (wfd != -1)
473                               set_nonblock(wfd);
474                     if (efd != -1)
475                               set_nonblock(efd);
476           }
477           /* channel might be entering a larval state, so reset global timeout */
478           channel_set_used_time(ssh, NULL);
479 }
480 
481 /*
482  * Allocate a new channel object and set its type and socket.
483  */
484 Channel *
channel_new(struct ssh * ssh,const char * ctype,int type,int rfd,int wfd,int efd,u_int window,u_int maxpack,int extusage,const char * remote_name,int nonblock)485 channel_new(struct ssh *ssh, const char *ctype, int type, int rfd, int wfd,
486     int efd, u_int window, u_int maxpack, int extusage, const char *remote_name,
487     int nonblock)
488 {
489           struct ssh_channels *sc = ssh->chanctxt;
490           u_int i, found = 0 /* XXXGCC12 */;
491           Channel *c;
492           int r;
493 
494           /* Try to find a free slot where to put the new channel. */
495           for (i = 0; i < sc->channels_alloc; i++) {
496                     if (sc->channels[i] == NULL) {
497                               /* Found a free slot. */
498                               found = i;
499                               break;
500                     }
501           }
502           if (i >= sc->channels_alloc) {
503                     /*
504                      * There are no free slots. Take last+1 slot and expand
505                      * the array.
506                      */
507                     found = sc->channels_alloc;
508                     if (sc->channels_alloc > CHANNELS_MAX_CHANNELS)
509                               fatal_f("internal error: channels_alloc %d too big",
510                                   sc->channels_alloc);
511                     sc->channels = xrecallocarray(sc->channels, sc->channels_alloc,
512                         sc->channels_alloc + 10, sizeof(*sc->channels));
513                     sc->channels_alloc += 10;
514                     debug2("channel: expanding %d", sc->channels_alloc);
515           }
516           /* Initialize and return new channel. */
517           c = sc->channels[found] = xcalloc(1, sizeof(Channel));
518           if ((c->input = sshbuf_new()) == NULL ||
519               (c->output = sshbuf_new()) == NULL ||
520               (c->extended = sshbuf_new()) == NULL)
521                     fatal_f("sshbuf_new failed");
522           if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)
523                     fatal_fr(r, "sshbuf_set_max_size");
524           c->ostate = CHAN_OUTPUT_OPEN;
525           c->istate = CHAN_INPUT_OPEN;
526           channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);
527           c->self = found;
528           c->type = type;
529           c->ctype = __UNCONST(ctype);
530           c->local_window = window;
531           c->local_window_max = window;
532           c->local_maxpacket = maxpack;
533           c->dynamic_window = 0;
534           c->remote_id = -1;
535           c->remote_name = xstrdup(remote_name);
536           c->ctl_chan = -1;
537           c->delayed = 1;               /* prevent call to channel_post handler */
538           c->inactive_deadline = lookup_timeout(ssh, c->ctype);
539           TAILQ_INIT(&c->status_confirms);
540           debug("channel %d: new %s [%s] (inactive timeout: %u)",
541               found, c->ctype, remote_name, c->inactive_deadline);
542           return c;
543 }
544 
545 int
channel_close_fd(struct ssh * ssh,Channel * c,int * fdp)546 channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
547 {
548           int ret, fd = *fdp;
549 
550           if (fd == -1)
551                     return 0;
552 
553           /* restore blocking */
554           if (*fdp == c->rfd &&
555               (c->restore_block & CHANNEL_RESTORE_RFD) != 0)
556                     (void)fcntl(*fdp, F_SETFL, c->restore_flags[0]);
557           else if (*fdp == c->wfd &&
558               (c->restore_block & CHANNEL_RESTORE_WFD) != 0)
559                     (void)fcntl(*fdp, F_SETFL, c->restore_flags[1]);
560           else if (*fdp == c->efd &&
561               (c->restore_block & CHANNEL_RESTORE_EFD) != 0)
562                     (void)fcntl(*fdp, F_SETFL, c->restore_flags[2]);
563 
564           if (*fdp == c->rfd) {
565                     c->io_want &= ~SSH_CHAN_IO_RFD;
566                     c->io_ready &= ~SSH_CHAN_IO_RFD;
567                     c->rfd = -1;
568                     c->pfds[0] = -1;
569           }
570           if (*fdp == c->wfd) {
571                     c->io_want &= ~SSH_CHAN_IO_WFD;
572                     c->io_ready &= ~SSH_CHAN_IO_WFD;
573                     c->wfd = -1;
574                     c->pfds[1] = -1;
575           }
576           if (*fdp == c->efd) {
577                     c->io_want &= ~SSH_CHAN_IO_EFD;
578                     c->io_ready &= ~SSH_CHAN_IO_EFD;
579                     c->efd = -1;
580                     c->pfds[2] = -1;
581           }
582           if (*fdp == c->sock) {
583                     c->io_want &= ~SSH_CHAN_IO_SOCK;
584                     c->io_ready &= ~SSH_CHAN_IO_SOCK;
585                     c->sock = -1;
586                     c->pfds[3] = -1;
587           }
588 
589           ret = close(fd);
590           *fdp = -1; /* probably redundant */
591           return ret;
592 }
593 
594 /* Close all channel fd/socket. */
595 static void
channel_close_fds(struct ssh * ssh,Channel * c)596 channel_close_fds(struct ssh *ssh, Channel *c)
597 {
598           int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd;
599 
600           channel_close_fd(ssh, c, &c->sock);
601           if (rfd != sock)
602                     channel_close_fd(ssh, c, &c->rfd);
603           if (wfd != sock && wfd != rfd)
604                     channel_close_fd(ssh, c, &c->wfd);
605           if (efd != sock && efd != rfd && efd != wfd)
606                     channel_close_fd(ssh, c, &c->efd);
607 }
608 
609 static void
fwd_perm_clear(struct permission * perm)610 fwd_perm_clear(struct permission *perm)
611 {
612           free(perm->host_to_connect);
613           free(perm->listen_host);
614           free(perm->listen_path);
615           memset(perm, 0, sizeof(*perm));
616 }
617 
618 /* Returns an printable name for the specified forwarding permission list */
619 static const char *
fwd_ident(int who,int where)620 fwd_ident(int who, int where)
621 {
622           if (who == FORWARD_ADM) {
623                     if (where == FORWARD_LOCAL)
624                               return "admin local";
625                     else if (where == FORWARD_REMOTE)
626                               return "admin remote";
627           } else if (who == FORWARD_USER) {
628                     if (where == FORWARD_LOCAL)
629                               return "user local";
630                     else if (where == FORWARD_REMOTE)
631                               return "user remote";
632           }
633           fatal("Unknown forward permission list %d/%d", who, where);
634 }
635 
636 /* Returns the forwarding permission list for the specified direction */
637 static struct permission_set *
permission_set_get(struct ssh * ssh,int where)638 permission_set_get(struct ssh *ssh, int where)
639 {
640           struct ssh_channels *sc = ssh->chanctxt;
641 
642           switch (where) {
643           case FORWARD_LOCAL:
644                     return &sc->local_perms;
645                     break;
646           case FORWARD_REMOTE:
647                     return &sc->remote_perms;
648                     break;
649           default:
650                     fatal_f("invalid forwarding direction %d", where);
651           }
652 }
653 
654 /* Returns pointers to the specified forwarding list and its element count */
655 static void
permission_set_get_array(struct ssh * ssh,int who,int where,struct permission *** permpp,u_int ** npermpp)656 permission_set_get_array(struct ssh *ssh, int who, int where,
657     struct permission ***permpp, u_int **npermpp)
658 {
659           struct permission_set *pset = permission_set_get(ssh, where);
660 
661           switch (who) {
662           case FORWARD_USER:
663                     *permpp = &pset->permitted_user;
664                     *npermpp = &pset->num_permitted_user;
665                     break;
666           case FORWARD_ADM:
667                     *permpp = &pset->permitted_admin;
668                     *npermpp = &pset->num_permitted_admin;
669                     break;
670           default:
671                     fatal_f("invalid forwarding client %d", who);
672           }
673 }
674 
675 /* Adds an entry to the specified forwarding list */
676 static int
permission_set_add(struct ssh * ssh,int who,int where,const char * host_to_connect,int port_to_connect,const char * listen_host,const char * listen_path,int listen_port,Channel * downstream)677 permission_set_add(struct ssh *ssh, int who, int where,
678     const char *host_to_connect, int port_to_connect,
679     const char *listen_host, const char *listen_path, int listen_port,
680     Channel *downstream)
681 {
682           struct permission **permp;
683           u_int n, *npermp;
684 
685           permission_set_get_array(ssh, who, where, &permp, &npermp);
686 
687           if (*npermp >= INT_MAX)
688                     fatal_f("%s overflow", fwd_ident(who, where));
689 
690           *permp = xrecallocarray(*permp, *npermp, *npermp + 1, sizeof(**permp));
691           n = (*npermp)++;
692 #define MAYBE_DUP(s) ((s == NULL) ? NULL : xstrdup(s))
693           (*permp)[n].host_to_connect = MAYBE_DUP(host_to_connect);
694           (*permp)[n].port_to_connect = port_to_connect;
695           (*permp)[n].listen_host = MAYBE_DUP(listen_host);
696           (*permp)[n].listen_path = MAYBE_DUP(listen_path);
697           (*permp)[n].listen_port = listen_port;
698           (*permp)[n].downstream = downstream;
699 #undef MAYBE_DUP
700           return (int)n;
701 }
702 
703 static void
mux_remove_remote_forwardings(struct ssh * ssh,Channel * c)704 mux_remove_remote_forwardings(struct ssh *ssh, Channel *c)
705 {
706           struct ssh_channels *sc = ssh->chanctxt;
707           struct permission_set *pset = &sc->local_perms;
708           struct permission *perm;
709           int r;
710           u_int i;
711 
712           for (i = 0; i < pset->num_permitted_user; i++) {
713                     perm = &pset->permitted_user[i];
714                     if (perm->downstream != c)
715                               continue;
716 
717                     /* cancel on the server, since mux client is gone */
718                     debug("channel %d: cleanup remote forward for %s:%u",
719                         c->self, perm->listen_host, perm->listen_port);
720                     if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
721                         (r = sshpkt_put_cstring(ssh,
722                         "cancel-tcpip-forward")) != 0 ||
723                         (r = sshpkt_put_u8(ssh, 0)) != 0 ||
724                         (r = sshpkt_put_cstring(ssh,
725                         channel_rfwd_bind_host(perm->listen_host))) != 0 ||
726                         (r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 ||
727                         (r = sshpkt_send(ssh)) != 0) {
728                               fatal_fr(r, "channel %i", c->self);
729                     }
730                     fwd_perm_clear(perm); /* unregister */
731           }
732 }
733 
734 /* Free the channel and close its fd/socket. */
735 void
channel_free(struct ssh * ssh,Channel * c)736 channel_free(struct ssh *ssh, Channel *c)
737 {
738           struct ssh_channels *sc = ssh->chanctxt;
739           char *s;
740           u_int i, n;
741           Channel *other;
742           struct channel_confirm *cc;
743 
744           for (n = 0, i = 0; i < sc->channels_alloc; i++) {
745                     if ((other = sc->channels[i]) == NULL)
746                               continue;
747                     n++;
748                     /* detach from mux client and prepare for closing */
749                     if (c->type == SSH_CHANNEL_MUX_CLIENT &&
750                         other->type == SSH_CHANNEL_MUX_PROXY &&
751                         other->mux_ctx == c) {
752                               other->mux_ctx = NULL;
753                               other->type = SSH_CHANNEL_OPEN;
754                               other->istate = CHAN_INPUT_CLOSED;
755                               other->ostate = CHAN_OUTPUT_CLOSED;
756                     }
757           }
758           debug("channel %d: free: %s, nchannels %u", c->self,
759               c->remote_name ? c->remote_name : "???", n);
760 
761           if (c->type == SSH_CHANNEL_MUX_CLIENT) {
762                     mux_remove_remote_forwardings(ssh, c);
763                     free(c->mux_ctx);
764                     c->mux_ctx = NULL;
765           } else if (c->type == SSH_CHANNEL_MUX_LISTENER) {
766                     free(c->mux_ctx);
767                     c->mux_ctx = NULL;
768           }
769 
770           if (log_level_get() >= SYSLOG_LEVEL_DEBUG3) {
771                     s = channel_open_message(ssh);
772                     debug3("channel %d: status: %s", c->self, s);
773                     free(s);
774           }
775 
776           channel_close_fds(ssh, c);
777           sshbuf_free(c->input);
778           sshbuf_free(c->output);
779           sshbuf_free(c->extended);
780           c->input = c->output = c->extended = NULL;
781           free(c->remote_name);
782           c->remote_name = NULL;
783           free(c->path);
784           c->path = NULL;
785           free(c->listening_addr);
786           c->listening_addr = NULL;
787           free(c->xctype);
788           c->xctype = NULL;
789           while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
790                     if (cc->abandon_cb != NULL)
791                               cc->abandon_cb(ssh, c, cc->ctx);
792                     TAILQ_REMOVE(&c->status_confirms, cc, entry);
793                     freezero(cc, sizeof(*cc));
794           }
795           if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
796                     c->filter_cleanup(ssh, c->self, c->filter_ctx);
797           sc->channels[c->self] = NULL;
798           freezero(c, sizeof(*c));
799 }
800 
801 void
channel_free_all(struct ssh * ssh)802 channel_free_all(struct ssh *ssh)
803 {
804           u_int i;
805           struct ssh_channels *sc = ssh->chanctxt;
806 
807           for (i = 0; i < sc->channels_alloc; i++)
808                     if (sc->channels[i] != NULL)
809                               channel_free(ssh, sc->channels[i]);
810 
811           free(sc->channels);
812           sc->channels = NULL;
813           sc->channels_alloc = 0;
814 
815           free(sc->x11_saved_display);
816           sc->x11_saved_display = NULL;
817 
818           free(sc->x11_saved_proto);
819           sc->x11_saved_proto = NULL;
820 
821           free(sc->x11_saved_data);
822           sc->x11_saved_data = NULL;
823           sc->x11_saved_data_len = 0;
824 
825           free(sc->x11_fake_data);
826           sc->x11_fake_data = NULL;
827           sc->x11_fake_data_len = 0;
828 }
829 
830 /*
831  * Closes the sockets/fds of all channels.  This is used to close extra file
832  * descriptors after a fork.
833  */
834 void
channel_close_all(struct ssh * ssh)835 channel_close_all(struct ssh *ssh)
836 {
837           u_int i;
838 
839           for (i = 0; i < ssh->chanctxt->channels_alloc; i++)
840                     if (ssh->chanctxt->channels[i] != NULL)
841                               channel_close_fds(ssh, ssh->chanctxt->channels[i]);
842 }
843 
844 /*
845  * Stop listening to channels.
846  */
847 void
channel_stop_listening(struct ssh * ssh)848 channel_stop_listening(struct ssh *ssh)
849 {
850           u_int i;
851           Channel *c;
852 
853           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
854                     c = ssh->chanctxt->channels[i];
855                     if (c != NULL) {
856                               switch (c->type) {
857                               case SSH_CHANNEL_AUTH_SOCKET:
858                               case SSH_CHANNEL_PORT_LISTENER:
859                               case SSH_CHANNEL_RPORT_LISTENER:
860                               case SSH_CHANNEL_X11_LISTENER:
861                               case SSH_CHANNEL_UNIX_LISTENER:
862                               case SSH_CHANNEL_RUNIX_LISTENER:
863                                         channel_close_fd(ssh, c, &c->sock);
864                                         channel_free(ssh, c);
865                                         break;
866                               }
867                     }
868           }
869 }
870 
871 /*
872  * Returns true if no channel has too much buffered data, and false if one or
873  * more channel is overfull.
874  */
875 int
channel_not_very_much_buffered_data(struct ssh * ssh)876 channel_not_very_much_buffered_data(struct ssh *ssh)
877 {
878           u_int i;
879           u_int maxsize = ssh_packet_get_maxsize(ssh);
880           Channel *c;
881 
882           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
883                     c = ssh->chanctxt->channels[i];
884                     if (c == NULL || c->type != SSH_CHANNEL_OPEN)
885                               continue;
886                     if (sshbuf_len(c->output) > maxsize) {
887                               debug2("channel %d: big output buffer %zu > %u",
888                                   c->self, sshbuf_len(c->output), maxsize);
889                               return 0;
890                     }
891           }
892           return 1;
893 }
894 
895 /* Returns true if any channel is still open. */
896 int
channel_still_open(struct ssh * ssh)897 channel_still_open(struct ssh *ssh)
898 {
899           u_int i;
900           Channel *c;
901 
902           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
903                     c = ssh->chanctxt->channels[i];
904                     if (c == NULL)
905                               continue;
906                     switch (c->type) {
907                     case SSH_CHANNEL_X11_LISTENER:
908                     case SSH_CHANNEL_PORT_LISTENER:
909                     case SSH_CHANNEL_RPORT_LISTENER:
910                     case SSH_CHANNEL_MUX_LISTENER:
911                     case SSH_CHANNEL_CLOSED:
912                     case SSH_CHANNEL_AUTH_SOCKET:
913                     case SSH_CHANNEL_DYNAMIC:
914                     case SSH_CHANNEL_RDYNAMIC_OPEN:
915                     case SSH_CHANNEL_CONNECTING:
916                     case SSH_CHANNEL_ZOMBIE:
917                     case SSH_CHANNEL_ABANDONED:
918                     case SSH_CHANNEL_UNIX_LISTENER:
919                     case SSH_CHANNEL_RUNIX_LISTENER:
920                               continue;
921                     case SSH_CHANNEL_LARVAL:
922                               continue;
923                     case SSH_CHANNEL_OPENING:
924                     case SSH_CHANNEL_OPEN:
925                     case SSH_CHANNEL_RDYNAMIC_FINISH:
926                     case SSH_CHANNEL_X11_OPEN:
927                     case SSH_CHANNEL_MUX_CLIENT:
928                     case SSH_CHANNEL_MUX_PROXY:
929                               return 1;
930                     default:
931                               fatal_f("bad channel type %d", c->type);
932                               /* NOTREACHED */
933                     }
934           }
935           return 0;
936 }
937 
938 /* Returns true if a channel with a TTY is open. */
939 int
channel_tty_open(struct ssh * ssh)940 channel_tty_open(struct ssh *ssh)
941 {
942           u_int i;
943           Channel *c;
944 
945           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
946                     c = ssh->chanctxt->channels[i];
947                     if (c == NULL || c->type != SSH_CHANNEL_OPEN)
948                               continue;
949                     if (c->client_tty)
950                               return 1;
951           }
952           return 0;
953 }
954 
955 /* Returns the id of an open channel suitable for keepaliving */
956 int
channel_find_open(struct ssh * ssh)957 channel_find_open(struct ssh *ssh)
958 {
959           u_int i;
960           Channel *c;
961 
962           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
963                     c = ssh->chanctxt->channels[i];
964                     if (c == NULL || !c->have_remote_id)
965                               continue;
966                     switch (c->type) {
967                     case SSH_CHANNEL_CLOSED:
968                     case SSH_CHANNEL_DYNAMIC:
969                     case SSH_CHANNEL_RDYNAMIC_OPEN:
970                     case SSH_CHANNEL_RDYNAMIC_FINISH:
971                     case SSH_CHANNEL_X11_LISTENER:
972                     case SSH_CHANNEL_PORT_LISTENER:
973                     case SSH_CHANNEL_RPORT_LISTENER:
974                     case SSH_CHANNEL_MUX_LISTENER:
975                     case SSH_CHANNEL_MUX_CLIENT:
976                     case SSH_CHANNEL_MUX_PROXY:
977                     case SSH_CHANNEL_OPENING:
978                     case SSH_CHANNEL_CONNECTING:
979                     case SSH_CHANNEL_ZOMBIE:
980                     case SSH_CHANNEL_ABANDONED:
981                     case SSH_CHANNEL_UNIX_LISTENER:
982                     case SSH_CHANNEL_RUNIX_LISTENER:
983                               continue;
984                     case SSH_CHANNEL_LARVAL:
985                     case SSH_CHANNEL_AUTH_SOCKET:
986                     case SSH_CHANNEL_OPEN:
987                     case SSH_CHANNEL_X11_OPEN:
988                               return i;
989                     default:
990                               fatal_f("bad channel type %d", c->type);
991                               /* NOTREACHED */
992                     }
993           }
994           return -1;
995 }
996 
997 /* Returns the state of the channel's extended usage flag */
998 const char *
channel_format_extended_usage(const Channel * c)999 channel_format_extended_usage(const Channel *c)
1000 {
1001           if (c->efd == -1)
1002                     return "closed";
1003 
1004           switch (c->extended_usage) {
1005           case CHAN_EXTENDED_WRITE:
1006                     return "write";
1007           case CHAN_EXTENDED_READ:
1008                     return "read";
1009           case CHAN_EXTENDED_IGNORE:
1010                     return "ignore";
1011           default:
1012                     return "UNKNOWN";
1013           }
1014 }
1015 
1016 static char *
channel_format_status(const Channel * c)1017 channel_format_status(const Channel *c)
1018 {
1019           char *ret = NULL;
1020 
1021           xasprintf(&ret, "t%d [%s] %s%u %s%u i%u/%zu o%u/%zu e[%s]/%zu "
1022               "fd %d/%d/%d sock %d cc %d %s%u io 0x%02x/0x%02x",
1023               c->type, c->xctype != NULL ? c->xctype : c->ctype,
1024               c->have_remote_id ? "r" : "nr", c->remote_id,
1025               c->mux_ctx != NULL ? "m" : "nm", c->mux_downstream_id,
1026               c->istate, sshbuf_len(c->input),
1027               c->ostate, sshbuf_len(c->output),
1028               channel_format_extended_usage(c), sshbuf_len(c->extended),
1029               c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan,
1030               c->have_ctl_child_id ? "c" : "nc", c->ctl_child_id,
1031               c->io_want, c->io_ready);
1032           return ret;
1033 }
1034 
1035 /*
1036  * Returns a message describing the currently open forwarded connections,
1037  * suitable for sending to the client.  The message contains crlf pairs for
1038  * newlines.
1039  */
1040 char *
channel_open_message(struct ssh * ssh)1041 channel_open_message(struct ssh *ssh)
1042 {
1043           struct sshbuf *buf;
1044           Channel *c;
1045           u_int i;
1046           int r;
1047           char *cp, *ret;
1048 
1049           if ((buf = sshbuf_new()) == NULL)
1050                     fatal_f("sshbuf_new");
1051           if ((r = sshbuf_putf(buf,
1052               "The following connections are open:\r\n")) != 0)
1053                     fatal_fr(r, "sshbuf_putf");
1054           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
1055                     c = ssh->chanctxt->channels[i];
1056                     if (c == NULL)
1057                               continue;
1058                     switch (c->type) {
1059                     case SSH_CHANNEL_X11_LISTENER:
1060                     case SSH_CHANNEL_PORT_LISTENER:
1061                     case SSH_CHANNEL_RPORT_LISTENER:
1062                     case SSH_CHANNEL_CLOSED:
1063                     case SSH_CHANNEL_AUTH_SOCKET:
1064                     case SSH_CHANNEL_ZOMBIE:
1065                     case SSH_CHANNEL_ABANDONED:
1066                     case SSH_CHANNEL_MUX_LISTENER:
1067                     case SSH_CHANNEL_UNIX_LISTENER:
1068                     case SSH_CHANNEL_RUNIX_LISTENER:
1069                               continue;
1070                     case SSH_CHANNEL_LARVAL:
1071                     case SSH_CHANNEL_OPENING:
1072                     case SSH_CHANNEL_CONNECTING:
1073                     case SSH_CHANNEL_DYNAMIC:
1074                     case SSH_CHANNEL_RDYNAMIC_OPEN:
1075                     case SSH_CHANNEL_RDYNAMIC_FINISH:
1076                     case SSH_CHANNEL_OPEN:
1077                     case SSH_CHANNEL_X11_OPEN:
1078                     case SSH_CHANNEL_MUX_PROXY:
1079                     case SSH_CHANNEL_MUX_CLIENT:
1080                               cp = channel_format_status(c);
1081                               if ((r = sshbuf_putf(buf, "  #%d %.300s (%s)\r\n",
1082                                   c->self, c->remote_name, cp)) != 0) {
1083                                         free(cp);
1084                                         fatal_fr(r, "sshbuf_putf");
1085                               }
1086                               free(cp);
1087                               continue;
1088                     default:
1089                               fatal_f("bad channel type %d", c->type);
1090                               /* NOTREACHED */
1091                     }
1092           }
1093           if ((ret = sshbuf_dup_string(buf)) == NULL)
1094                     fatal_f("sshbuf_dup_string");
1095           sshbuf_free(buf);
1096           return ret;
1097 }
1098 
1099 static void
open_preamble(struct ssh * ssh,const char * where,Channel * c,const char * type)1100 open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type)
1101 {
1102           int r;
1103 
1104           if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
1105               (r = sshpkt_put_cstring(ssh, type)) != 0 ||
1106               (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
1107               (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
1108               (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
1109                     fatal_r(r, "%s: channel %i: open", where, c->self);
1110           }
1111 }
1112 
1113 void
channel_send_open(struct ssh * ssh,int id)1114 channel_send_open(struct ssh *ssh, int id)
1115 {
1116           Channel *c = channel_lookup(ssh, id);
1117           int r;
1118 
1119           if (c == NULL) {
1120                     logit("channel_send_open: %d: bad id", id);
1121                     return;
1122           }
1123           debug2("channel %d: send open", id);
1124           open_preamble(ssh, __func__, c, c->ctype);
1125           if ((r = sshpkt_send(ssh)) != 0)
1126                     fatal_fr(r, "channel %i", c->self);
1127 }
1128 
1129 void
channel_request_start(struct ssh * ssh,int id,const char * service,int wantconfirm)1130 channel_request_start(struct ssh *ssh, int id, const char *service,
1131     int wantconfirm)
1132 {
1133           Channel *c = channel_lookup(ssh, id);
1134           int r;
1135 
1136           if (c == NULL) {
1137                     logit_f("%d: unknown channel id", id);
1138                     return;
1139           }
1140           if (!c->have_remote_id)
1141                     fatal_f("channel %d: no remote id", c->self);
1142 
1143           debug2("channel %d: request %s confirm %d", id, service, wantconfirm);
1144           if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
1145               (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1146               (r = sshpkt_put_cstring(ssh, service)) != 0 ||
1147               (r = sshpkt_put_u8(ssh, wantconfirm)) != 0) {
1148                     fatal_fr(r, "channel %i", c->self);
1149           }
1150 }
1151 
1152 void
channel_register_status_confirm(struct ssh * ssh,int id,channel_confirm_cb * cb,channel_confirm_abandon_cb * abandon_cb,void * ctx)1153 channel_register_status_confirm(struct ssh *ssh, int id,
1154     channel_confirm_cb *cb, channel_confirm_abandon_cb *abandon_cb, void *ctx)
1155 {
1156           struct channel_confirm *cc;
1157           Channel *c;
1158 
1159           if ((c = channel_lookup(ssh, id)) == NULL)
1160                     fatal_f("%d: bad id", id);
1161 
1162           cc = xcalloc(1, sizeof(*cc));
1163           cc->cb = cb;
1164           cc->abandon_cb = abandon_cb;
1165           cc->ctx = ctx;
1166           TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry);
1167 }
1168 
1169 void
channel_register_open_confirm(struct ssh * ssh,int id,channel_open_fn * fn,void * ctx)1170 channel_register_open_confirm(struct ssh *ssh, int id,
1171     channel_open_fn *fn, void *ctx)
1172 {
1173           Channel *c = channel_lookup(ssh, id);
1174 
1175           if (c == NULL) {
1176                     logit_f("%d: bad id", id);
1177                     return;
1178           }
1179           c->open_confirm = fn;
1180           c->open_confirm_ctx = ctx;
1181 }
1182 
1183 void
channel_register_cleanup(struct ssh * ssh,int id,channel_callback_fn * fn,int do_close)1184 channel_register_cleanup(struct ssh *ssh, int id,
1185     channel_callback_fn *fn, int do_close)
1186 {
1187           Channel *c = channel_by_id(ssh, id);
1188 
1189           if (c == NULL) {
1190                     logit_f("%d: bad id", id);
1191                     return;
1192           }
1193           c->detach_user = fn;
1194           c->detach_close = do_close;
1195 }
1196 
1197 void
channel_cancel_cleanup(struct ssh * ssh,int id)1198 channel_cancel_cleanup(struct ssh *ssh, int id)
1199 {
1200           Channel *c = channel_by_id(ssh, id);
1201 
1202           if (c == NULL) {
1203                     logit_f("%d: bad id", id);
1204                     return;
1205           }
1206           c->detach_user = NULL;
1207           c->detach_close = 0;
1208 }
1209 
1210 void
channel_register_filter(struct ssh * ssh,int id,channel_infilter_fn * ifn,channel_outfilter_fn * ofn,channel_filter_cleanup_fn * cfn,void * ctx)1211 channel_register_filter(struct ssh *ssh, int id, channel_infilter_fn *ifn,
1212     channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx)
1213 {
1214           Channel *c = channel_lookup(ssh, id);
1215 
1216           if (c == NULL) {
1217                     logit_f("%d: bad id", id);
1218                     return;
1219           }
1220           c->input_filter = ifn;
1221           c->output_filter = ofn;
1222           c->filter_ctx = ctx;
1223           c->filter_cleanup = cfn;
1224 }
1225 
1226 void
channel_set_fds(struct ssh * ssh,int id,int rfd,int wfd,int efd,int extusage,int nonblock,int is_tty,u_int window_max)1227 channel_set_fds(struct ssh *ssh, int id, int rfd, int wfd, int efd,
1228     int extusage, int nonblock, int is_tty, u_int window_max)
1229 {
1230           Channel *c = channel_lookup(ssh, id);
1231           int r;
1232 
1233           if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
1234                     fatal("channel_activate for non-larval channel %d.", id);
1235           if (!c->have_remote_id)
1236                     fatal_f("channel %d: no remote id", c->self);
1237 
1238           channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);
1239           c->type = SSH_CHANNEL_OPEN;
1240           channel_set_used_time(ssh, c);
1241           c->local_window = c->local_window_max = window_max;
1242 
1243           if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
1244               (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1245               (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
1246               (r = sshpkt_send(ssh)) != 0)
1247                     fatal_fr(r, "channel %i", c->self);
1248 }
1249 
1250 static void
channel_pre_listener(struct ssh * ssh,Channel * c)1251 channel_pre_listener(struct ssh *ssh, Channel *c)
1252 {
1253           c->io_want = SSH_CHAN_IO_SOCK_R;
1254 }
1255 
1256 static void
channel_pre_connecting(struct ssh * ssh,Channel * c)1257 channel_pre_connecting(struct ssh *ssh, Channel *c)
1258 {
1259           debug3("channel %d: waiting for connection", c->self);
1260           c->io_want = SSH_CHAN_IO_SOCK_W;
1261 }
1262 
1263 static int
channel_tcpwinsz(struct ssh * ssh)1264 channel_tcpwinsz(struct ssh *ssh)
1265 {
1266           u_int32_t tcpwinsz = 0;
1267           socklen_t optsz = sizeof(tcpwinsz);
1268           int ret = -1;
1269 
1270           /* if we aren't on a socket return 128KB*/
1271           if(!ssh_packet_connection_is_on_socket(ssh))
1272               return(128*1024);
1273           ret = getsockopt(ssh_packet_get_connection_in(ssh),
1274                                SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
1275           /* return no more than SSHBUF_SIZE_MAX (currently 256MB) */
1276           if ((ret == 0) && tcpwinsz > SSHBUF_SIZE_MAX)
1277               tcpwinsz = SSHBUF_SIZE_MAX;
1278           debug2("tcpwinsz: %d for connection: %d", tcpwinsz,
1279                  ssh_packet_get_connection_in(ssh));
1280           return(tcpwinsz);
1281 }
1282 
1283 static void
channel_pre_open(struct ssh * ssh,Channel * c)1284 channel_pre_open(struct ssh *ssh, Channel *c)
1285 {
1286           c->io_want = 0;
1287           if (c->istate == CHAN_INPUT_OPEN &&
1288               c->remote_window > 0 &&
1289               sshbuf_len(c->input) < c->remote_window &&
1290               sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
1291                     c->io_want |= SSH_CHAN_IO_RFD;
1292           if (c->ostate == CHAN_OUTPUT_OPEN ||
1293               c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
1294                     if (sshbuf_len(c->output) > 0) {
1295                               c->io_want |= SSH_CHAN_IO_WFD;
1296                     } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
1297                               if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
1298                                         debug2("channel %d: "
1299                                             "obuf_empty delayed efd %d/(%zu)", c->self,
1300                                             c->efd, sshbuf_len(c->extended));
1301                               else
1302                                         chan_obuf_empty(ssh, c);
1303                     }
1304           }
1305           /** XXX check close conditions, too */
1306           if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED &&
1307               c->ostate == CHAN_OUTPUT_CLOSED)) {
1308                     if (c->extended_usage == CHAN_EXTENDED_WRITE &&
1309                         sshbuf_len(c->extended) > 0)
1310                               c->io_want |= SSH_CHAN_IO_EFD_W;
1311                     else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) &&
1312                         (c->extended_usage == CHAN_EXTENDED_READ ||
1313                         c->extended_usage == CHAN_EXTENDED_IGNORE) &&
1314                         sshbuf_len(c->extended) < c->remote_window)
1315                               c->io_want |= SSH_CHAN_IO_EFD_R;
1316           }
1317           /* XXX: What about efd? races? */
1318 }
1319 
1320 /*
1321  * This is a special state for X11 authentication spoofing.  An opened X11
1322  * connection (when authentication spoofing is being done) remains in this
1323  * state until the first packet has been completely read.  The authentication
1324  * data in that packet is then substituted by the real data if it matches the
1325  * fake data, and the channel is put into normal mode.
1326  * XXX All this happens at the client side.
1327  * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
1328  */
1329 static int
x11_open_helper(struct ssh * ssh,struct sshbuf * b)1330 x11_open_helper(struct ssh *ssh, struct sshbuf *b)
1331 {
1332           struct ssh_channels *sc = ssh->chanctxt;
1333           u_char *ucp;
1334           u_int proto_len, data_len;
1335 
1336           /* Is this being called after the refusal deadline? */
1337           if (sc->x11_refuse_time != 0 &&
1338               monotime() >= sc->x11_refuse_time) {
1339                     verbose("Rejected X11 connection after ForwardX11Timeout "
1340                         "expired");
1341                     return -1;
1342           }
1343 
1344           /* Check if the fixed size part of the packet is in buffer. */
1345           if (sshbuf_len(b) < 12)
1346                     return 0;
1347 
1348           /* Parse the lengths of variable-length fields. */
1349           ucp = sshbuf_mutable_ptr(b);
1350           if (ucp[0] == 0x42) {         /* Byte order MSB first. */
1351                     proto_len = 256 * ucp[6] + ucp[7];
1352                     data_len = 256 * ucp[8] + ucp[9];
1353           } else if (ucp[0] == 0x6c) {  /* Byte order LSB first. */
1354                     proto_len = ucp[6] + 256 * ucp[7];
1355                     data_len = ucp[8] + 256 * ucp[9];
1356           } else {
1357                     debug2("Initial X11 packet contains bad byte order byte: 0x%x",
1358                         ucp[0]);
1359                     return -1;
1360           }
1361 
1362           /* Check if the whole packet is in buffer. */
1363           if (sshbuf_len(b) <
1364               12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
1365                     return 0;
1366 
1367           /* Check if authentication protocol matches. */
1368           if (proto_len != strlen(sc->x11_saved_proto) ||
1369               memcmp(ucp + 12, sc->x11_saved_proto, proto_len) != 0) {
1370                     debug2("X11 connection uses different authentication protocol.");
1371                     return -1;
1372           }
1373           /* Check if authentication data matches our fake data. */
1374           if (data_len != sc->x11_fake_data_len ||
1375               timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3),
1376                     sc->x11_fake_data, sc->x11_fake_data_len) != 0) {
1377                     debug2("X11 auth data does not match fake data.");
1378                     return -1;
1379           }
1380           /* Check fake data length */
1381           if (sc->x11_fake_data_len != sc->x11_saved_data_len) {
1382                     error("X11 fake_data_len %d != saved_data_len %d",
1383                         sc->x11_fake_data_len, sc->x11_saved_data_len);
1384                     return -1;
1385           }
1386           /*
1387            * Received authentication protocol and data match
1388            * our fake data. Substitute the fake data with real
1389            * data.
1390            */
1391           memcpy(ucp + 12 + ((proto_len + 3) & ~3),
1392               sc->x11_saved_data, sc->x11_saved_data_len);
1393           return 1;
1394 }
1395 
1396 void
channel_force_close(struct ssh * ssh,Channel * c,int abandon)1397 channel_force_close(struct ssh *ssh, Channel *c, int abandon)
1398 {
1399           debug3_f("channel %d: forcibly closing", c->self);
1400           if (c->istate == CHAN_INPUT_OPEN)
1401                     chan_read_failed(ssh, c);
1402           if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
1403                     sshbuf_reset(c->input);
1404                     chan_ibuf_empty(ssh, c);
1405           }
1406           if (c->ostate == CHAN_OUTPUT_OPEN ||
1407               c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
1408                     sshbuf_reset(c->output);
1409                     chan_write_failed(ssh, c);
1410           }
1411           if (c->detach_user)
1412                     c->detach_user(ssh, c->self, 1, NULL);
1413           if (c->efd != -1)
1414                     channel_close_fd(ssh, c, &c->efd);
1415           if (abandon)
1416                     c->type = SSH_CHANNEL_ABANDONED;
1417           /* exempt from inactivity timeouts */
1418           c->inactive_deadline = 0;
1419           c->lastused = 0;
1420 }
1421 
1422 static void
channel_pre_x11_open(struct ssh * ssh,Channel * c)1423 channel_pre_x11_open(struct ssh *ssh, Channel *c)
1424 {
1425           int ret = x11_open_helper(ssh, c->output);
1426 
1427           /* c->force_drain = 1; */
1428 
1429           if (ret == 1) {
1430                     c->type = SSH_CHANNEL_OPEN;
1431                     channel_set_used_time(ssh, c);
1432                     channel_pre_open(ssh, c);
1433           } else if (ret == -1) {
1434                     logit("X11 connection rejected because of wrong "
1435                         "authentication.");
1436                     debug2("X11 rejected %d i%d/o%d",
1437                         c->self, c->istate, c->ostate);
1438                     channel_force_close(ssh, c, 0);
1439           }
1440 }
1441 
1442 static void
channel_pre_mux_client(struct ssh * ssh,Channel * c)1443 channel_pre_mux_client(struct ssh *ssh, Channel *c)
1444 {
1445           c->io_want = 0;
1446           if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause &&
1447               sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
1448                     c->io_want |= SSH_CHAN_IO_RFD;
1449           if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
1450                     /* clear buffer immediately (discard any partial packet) */
1451                     sshbuf_reset(c->input);
1452                     chan_ibuf_empty(ssh, c);
1453                     /* Start output drain. XXX just kill chan? */
1454                     chan_rcvd_oclose(ssh, c);
1455           }
1456           if (c->ostate == CHAN_OUTPUT_OPEN ||
1457               c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
1458                     if (sshbuf_len(c->output) > 0)
1459                               c->io_want |= SSH_CHAN_IO_WFD;
1460                     else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN)
1461                               chan_obuf_empty(ssh, c);
1462           }
1463 }
1464 
1465 /* try to decode a socks4 header */
1466 static int
channel_decode_socks4(Channel * c,struct sshbuf * input,struct sshbuf * output)1467 channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output)
1468 {
1469           const char *p;
1470           char *host;
1471           u_int len, have, i, found, need;
1472           char username[256];
1473           struct {
1474                     u_int8_t version;
1475                     u_int8_t command;
1476                     u_int16_t dest_port;
1477                     struct in_addr dest_addr;
1478           } s4_req, s4_rsp;
1479           int r;
1480 
1481           debug2("channel %d: decode socks4", c->self);
1482 
1483           have = sshbuf_len(input);
1484           len = sizeof(s4_req);
1485           if (have < len)
1486                     return 0;
1487           p = (const char *)sshbuf_ptr(input);
1488 
1489           need = 1;
1490           /* SOCKS4A uses an invalid IP address 0.0.0.x */
1491           if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) {
1492                     debug2("channel %d: socks4a request", c->self);
1493                     /* ... and needs an extra string (the hostname) */
1494                     need = 2;
1495           }
1496           /* Check for terminating NUL on the string(s) */
1497           for (found = 0, i = len; i < have; i++) {
1498                     if (p[i] == '\0') {
1499                               found++;
1500                               if (found == need)
1501                                         break;
1502                     }
1503                     if (i > 1024) {
1504                               /* the peer is probably sending garbage */
1505                               debug("channel %d: decode socks4: too long",
1506                                   c->self);
1507                               return -1;
1508                     }
1509           }
1510           if (found < need)
1511                     return 0;
1512           if ((r = sshbuf_get(input, &s4_req.version, 1)) != 0 ||
1513               (r = sshbuf_get(input, &s4_req.command, 1)) != 0 ||
1514               (r = sshbuf_get(input, &s4_req.dest_port, 2)) != 0 ||
1515               (r = sshbuf_get(input, &s4_req.dest_addr, 4)) != 0) {
1516                     debug_r(r, "channels %d: decode socks4", c->self);
1517                     return -1;
1518           }
1519           have = sshbuf_len(input);
1520           p = (const char *)sshbuf_ptr(input);
1521           if (memchr(p, '\0', have) == NULL) {
1522                     error("channel %d: decode socks4: unterminated user", c->self);
1523                     return -1;
1524           }
1525           len = strlen(p);
1526           debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
1527           len++; /* trailing '\0' */
1528           strlcpy(username, p, sizeof(username));
1529           if ((r = sshbuf_consume(input, len)) != 0)
1530                     fatal_fr(r, "channel %d: consume", c->self);
1531           free(c->path);
1532           c->path = NULL;
1533           if (need == 1) {                        /* SOCKS4: one string */
1534                     host = inet_ntoa(s4_req.dest_addr);
1535                     c->path = xstrdup(host);
1536           } else {                                /* SOCKS4A: two strings */
1537                     have = sshbuf_len(input);
1538                     p = (const char *)sshbuf_ptr(input);
1539                     if (memchr(p, '\0', have) == NULL) {
1540                               error("channel %d: decode socks4a: host not nul "
1541                                   "terminated", c->self);
1542                               return -1;
1543                     }
1544                     len = strlen(p);
1545                     debug2("channel %d: decode socks4a: host %s/%d",
1546                         c->self, p, len);
1547                     len++;                                  /* trailing '\0' */
1548                     if (len > NI_MAXHOST) {
1549                               error("channel %d: hostname \"%.100s\" too long",
1550                                   c->self, p);
1551                               return -1;
1552                     }
1553                     c->path = xstrdup(p);
1554                     if ((r = sshbuf_consume(input, len)) != 0)
1555                               fatal_fr(r, "channel %d: consume", c->self);
1556           }
1557           c->host_port = ntohs(s4_req.dest_port);
1558 
1559           debug2("channel %d: dynamic request: socks4 host %s port %u command %u",
1560               c->self, c->path, c->host_port, s4_req.command);
1561 
1562           if (s4_req.command != 1) {
1563                     debug("channel %d: cannot handle: %s cn %d",
1564                         c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command);
1565                     return -1;
1566           }
1567           s4_rsp.version = 0;                     /* vn: 0 for reply */
1568           s4_rsp.command = 90;                              /* cd: req granted */
1569           s4_rsp.dest_port = 0;                             /* ignored */
1570           s4_rsp.dest_addr.s_addr = INADDR_ANY;   /* ignored */
1571           if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0)
1572                     fatal_fr(r, "channel %d: append reply", c->self);
1573           return 1;
1574 }
1575 
1576 /* try to decode a socks5 header */
1577 #define SSH_SOCKS5_AUTHDONE   0x1000
1578 #define SSH_SOCKS5_NOAUTH     0x00
1579 #define SSH_SOCKS5_IPV4                 0x01
1580 #define SSH_SOCKS5_DOMAIN     0x03
1581 #define SSH_SOCKS5_IPV6                 0x04
1582 #define SSH_SOCKS5_CONNECT    0x01
1583 #define SSH_SOCKS5_SUCCESS    0x00
1584 
1585 static int
channel_decode_socks5(Channel * c,struct sshbuf * input,struct sshbuf * output)1586 channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
1587 {
1588           /* XXX use get/put_u8 instead of trusting struct padding */
1589           struct {
1590                     u_int8_t version;
1591                     u_int8_t command;
1592                     u_int8_t reserved;
1593                     u_int8_t atyp;
1594           } s5_req, s5_rsp;
1595           u_int16_t dest_port;
1596           char dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
1597           const u_char *p;
1598           u_int have, need, i, found, nmethods, addrlen, af;
1599           int r;
1600 
1601           debug2("channel %d: decode socks5", c->self);
1602           p = sshbuf_ptr(input);
1603           if (p[0] != 0x05)
1604                     return -1;
1605           have = sshbuf_len(input);
1606           if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
1607                     /* format: ver | nmethods | methods */
1608                     if (have < 2)
1609                               return 0;
1610                     nmethods = p[1];
1611                     if (have < nmethods + 2)
1612                               return 0;
1613                     /* look for method: "NO AUTHENTICATION REQUIRED" */
1614                     for (found = 0, i = 2; i < nmethods + 2; i++) {
1615                               if (p[i] == SSH_SOCKS5_NOAUTH) {
1616                                         found = 1;
1617                                         break;
1618                               }
1619                     }
1620                     if (!found) {
1621                               debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
1622                                   c->self);
1623                               return -1;
1624                     }
1625                     if ((r = sshbuf_consume(input, nmethods + 2)) != 0)
1626                               fatal_fr(r, "channel %d: consume", c->self);
1627                     /* version, method */
1628                     if ((r = sshbuf_put_u8(output, 0x05)) != 0 ||
1629                         (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0)
1630                               fatal_fr(r, "channel %d: append reply", c->self);
1631                     c->flags |= SSH_SOCKS5_AUTHDONE;
1632                     debug2("channel %d: socks5 auth done", c->self);
1633                     return 0;                               /* need more */
1634           }
1635           debug2("channel %d: socks5 post auth", c->self);
1636           if (have < sizeof(s5_req)+1)
1637                     return 0;                     /* need more */
1638           memcpy(&s5_req, p, sizeof(s5_req));
1639           if (s5_req.version != 0x05 ||
1640               s5_req.command != SSH_SOCKS5_CONNECT ||
1641               s5_req.reserved != 0x00) {
1642                     debug2("channel %d: only socks5 connect supported", c->self);
1643                     return -1;
1644           }
1645           switch (s5_req.atyp){
1646           case SSH_SOCKS5_IPV4:
1647                     addrlen = 4;
1648                     af = AF_INET;
1649                     break;
1650           case SSH_SOCKS5_DOMAIN:
1651                     addrlen = p[sizeof(s5_req)];
1652                     af = -1;
1653                     break;
1654           case SSH_SOCKS5_IPV6:
1655                     addrlen = 16;
1656                     af = AF_INET6;
1657                     break;
1658           default:
1659                     debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
1660                     return -1;
1661           }
1662           need = sizeof(s5_req) + addrlen + 2;
1663           if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
1664                     need++;
1665           if (have < need)
1666                     return 0;
1667           if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0)
1668                     fatal_fr(r, "channel %d: consume", c->self);
1669           if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
1670                     /* host string length */
1671                     if ((r = sshbuf_consume(input, 1)) != 0)
1672                               fatal_fr(r, "channel %d: consume", c->self);
1673           }
1674           if ((r = sshbuf_get(input, &dest_addr, addrlen)) != 0 ||
1675               (r = sshbuf_get(input, &dest_port, 2)) != 0) {
1676                     debug_r(r, "channel %d: parse addr/port", c->self);
1677                     return -1;
1678           }
1679           dest_addr[addrlen] = '\0';
1680           free(c->path);
1681           c->path = NULL;
1682           if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
1683                     if (addrlen >= NI_MAXHOST) {
1684                               error("channel %d: dynamic request: socks5 hostname "
1685                                   "\"%.100s\" too long", c->self, dest_addr);
1686                               return -1;
1687                     }
1688                     c->path = xstrdup(dest_addr);
1689           } else {
1690                     if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL)
1691                               return -1;
1692                     c->path = xstrdup(ntop);
1693           }
1694           c->host_port = ntohs(dest_port);
1695 
1696           debug2("channel %d: dynamic request: socks5 host %s port %u command %u",
1697               c->self, c->path, c->host_port, s5_req.command);
1698 
1699           s5_rsp.version = 0x05;
1700           s5_rsp.command = SSH_SOCKS5_SUCCESS;
1701           s5_rsp.reserved = 0;                              /* ignored */
1702           s5_rsp.atyp = SSH_SOCKS5_IPV4;
1703           dest_port = 0;                                    /* ignored */
1704 
1705           if ((r = sshbuf_put(output, &s5_rsp, sizeof(s5_rsp))) != 0 ||
1706               (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 ||
1707               (r = sshbuf_put(output, &dest_port, sizeof(dest_port))) != 0)
1708                     fatal_fr(r, "channel %d: append reply", c->self);
1709           return 1;
1710 }
1711 
1712 Channel *
channel_connect_stdio_fwd(struct ssh * ssh,const char * host_to_connect,int port_to_connect,int in,int out,int nonblock)1713 channel_connect_stdio_fwd(struct ssh *ssh,
1714     const char *host_to_connect, int port_to_connect,
1715     int in, int out, int nonblock)
1716 {
1717           Channel *c;
1718 
1719           debug_f("%s:%d", host_to_connect, port_to_connect);
1720 
1721           c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out,
1722               -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1723               0, "stdio-forward", nonblock);
1724 
1725           c->path = xstrdup(host_to_connect);
1726           c->host_port = port_to_connect;
1727           c->listening_port = 0;
1728           c->force_drain = 1;
1729 
1730           channel_register_fds(ssh, c, in, out, -1, 0, 1, 0);
1731           port_open_helper(ssh, c, port_to_connect == PORT_STREAMLOCAL ?
1732               "direct-streamlocal@openssh.com" : "direct-tcpip");
1733 
1734           return c;
1735 }
1736 
1737 /* dynamic port forwarding */
1738 static void
channel_pre_dynamic(struct ssh * ssh,Channel * c)1739 channel_pre_dynamic(struct ssh *ssh, Channel *c)
1740 {
1741           const u_char *p;
1742           u_int have;
1743           int ret;
1744 
1745           c->io_want = 0;
1746           have = sshbuf_len(c->input);
1747           debug2("channel %d: pre_dynamic: have %d", c->self, have);
1748           /* sshbuf_dump(c->input, stderr); */
1749           /* check if the fixed size part of the packet is in buffer. */
1750           if (have < 3) {
1751                     /* need more */
1752                     c->io_want |= SSH_CHAN_IO_RFD;
1753                     return;
1754           }
1755           /* try to guess the protocol */
1756           p = sshbuf_ptr(c->input);
1757           /* XXX sshbuf_peek_u8? */
1758           switch (p[0]) {
1759           case 0x04:
1760                     ret = channel_decode_socks4(c, c->input, c->output);
1761                     break;
1762           case 0x05:
1763                     ret = channel_decode_socks5(c, c->input, c->output);
1764                     break;
1765           default:
1766                     ret = -1;
1767                     break;
1768           }
1769           if (ret < 0) {
1770                     chan_mark_dead(ssh, c);
1771           } else if (ret == 0) {
1772                     debug2("channel %d: pre_dynamic: need more", c->self);
1773                     /* need more */
1774                     c->io_want |= SSH_CHAN_IO_RFD;
1775                     if (sshbuf_len(c->output))
1776                               c->io_want |= SSH_CHAN_IO_WFD;
1777           } else {
1778                     /* switch to the next state */
1779                     c->type = SSH_CHANNEL_OPENING;
1780                     port_open_helper(ssh, c, "direct-tcpip");
1781           }
1782 }
1783 
1784 /* simulate read-error */
1785 static void
rdynamic_close(struct ssh * ssh,Channel * c)1786 rdynamic_close(struct ssh *ssh, Channel *c)
1787 {
1788           c->type = SSH_CHANNEL_OPEN;
1789           channel_force_close(ssh, c, 0);
1790 }
1791 
1792 /* reverse dynamic port forwarding */
1793 static void
channel_before_prepare_io_rdynamic(struct ssh * ssh,Channel * c)1794 channel_before_prepare_io_rdynamic(struct ssh *ssh, Channel *c)
1795 {
1796           const u_char *p;
1797           u_int have, len;
1798           int r, ret;
1799 
1800           have = sshbuf_len(c->output);
1801           debug2("channel %d: pre_rdynamic: have %d", c->self, have);
1802           /* sshbuf_dump(c->output, stderr); */
1803           /* EOF received */
1804           if (c->flags & CHAN_EOF_RCVD) {
1805                     if ((r = sshbuf_consume(c->output, have)) != 0)
1806                               fatal_fr(r, "channel %d: consume", c->self);
1807                     rdynamic_close(ssh, c);
1808                     return;
1809           }
1810           /* check if the fixed size part of the packet is in buffer. */
1811           if (have < 3)
1812                     return;
1813           /* try to guess the protocol */
1814           p = sshbuf_ptr(c->output);
1815           switch (p[0]) {
1816           case 0x04:
1817                     /* switch input/output for reverse forwarding */
1818                     ret = channel_decode_socks4(c, c->output, c->input);
1819                     break;
1820           case 0x05:
1821                     ret = channel_decode_socks5(c, c->output, c->input);
1822                     break;
1823           default:
1824                     ret = -1;
1825                     break;
1826           }
1827           if (ret < 0) {
1828                     rdynamic_close(ssh, c);
1829           } else if (ret == 0) {
1830                     debug2("channel %d: pre_rdynamic: need more", c->self);
1831                     /* send socks request to peer */
1832                     len = sshbuf_len(c->input);
1833                     if (len > 0 && len < c->remote_window) {
1834                               if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
1835                                   (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1836                                   (r = sshpkt_put_stringb(ssh, c->input)) != 0 ||
1837                                   (r = sshpkt_send(ssh)) != 0) {
1838                                         fatal_fr(r, "channel %i: rdynamic", c->self);
1839                               }
1840                               if ((r = sshbuf_consume(c->input, len)) != 0)
1841                                         fatal_fr(r, "channel %d: consume", c->self);
1842                               c->remote_window -= len;
1843                     }
1844           } else if (rdynamic_connect_finish(ssh, c) < 0) {
1845                     /* the connect failed */
1846                     rdynamic_close(ssh, c);
1847           }
1848 }
1849 
1850 /* This is our fake X11 server socket. */
1851 static void
channel_post_x11_listener(struct ssh * ssh,Channel * c)1852 channel_post_x11_listener(struct ssh *ssh, Channel *c)
1853 {
1854           Channel *nc;
1855           struct sockaddr_storage addr;
1856           int r, newsock, oerrno, remote_port;
1857           socklen_t addrlen;
1858           char buf[16384], *remote_ipaddr;
1859 
1860           if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
1861                     return;
1862 
1863           debug("X11 connection requested.");
1864           addrlen = sizeof(addr);
1865           newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1866           if (c->single_connection) {
1867                     oerrno = errno;
1868                     debug2("single_connection: closing X11 listener.");
1869                     channel_close_fd(ssh, c, &c->sock);
1870                     chan_mark_dead(ssh, c);
1871                     errno = oerrno;
1872           }
1873           if (newsock == -1) {
1874                     if (errno != EINTR && errno != EWOULDBLOCK &&
1875                         errno != ECONNABORTED)
1876                               error("accept: %.100s", strerror(errno));
1877                     if (errno == EMFILE || errno == ENFILE)
1878                               c->notbefore = monotime() + 1;
1879                     return;
1880           }
1881           set_nodelay(newsock);
1882           remote_ipaddr = get_peer_ipaddr(newsock);
1883           remote_port = get_peer_port(newsock);
1884           snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
1885               remote_ipaddr, remote_port);
1886 
1887           nc = channel_new(ssh, "x11-connection",
1888               SSH_CHANNEL_OPENING, newsock, newsock, -1,
1889               c->local_window_max, c->local_maxpacket, 0, buf, 1);
1890           open_preamble(ssh, __func__, nc, "x11");
1891           if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
1892               (r = sshpkt_put_u32(ssh, remote_port)) != 0) {
1893                     fatal_fr(r, "channel %i: reply", c->self);
1894           }
1895           if ((r = sshpkt_send(ssh)) != 0)
1896                     fatal_fr(r, "channel %i: send", c->self);
1897           free(remote_ipaddr);
1898 }
1899 
1900 static void
port_open_helper(struct ssh * ssh,Channel * c,const char * rtype)1901 port_open_helper(struct ssh *ssh, Channel *c, const char *rtype)
1902 {
1903           char *local_ipaddr = get_local_ipaddr(c->sock);
1904           int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock);
1905           char *remote_ipaddr = get_peer_ipaddr(c->sock);
1906           int remote_port = get_peer_port(c->sock);
1907           int r;
1908 
1909           if (remote_port == -1) {
1910                     /* Fake addr/port to appease peers that validate it (Tectia) */
1911                     free(remote_ipaddr);
1912                     remote_ipaddr = xstrdup("127.0.0.1");
1913                     remote_port = 65535;
1914           }
1915 
1916           free(c->remote_name);
1917           xasprintf(&c->remote_name,
1918               "%s: listening port %d for %.100s port %d, "
1919               "connect from %.200s port %d to %.100s port %d",
1920               rtype, c->listening_port, c->path, c->host_port,
1921               remote_ipaddr, remote_port, local_ipaddr, local_port);
1922 
1923           open_preamble(ssh, __func__, c, rtype);
1924           if (strcmp(rtype, "direct-tcpip") == 0) {
1925                     /* target host, port */
1926                     if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
1927                         (r = sshpkt_put_u32(ssh, c->host_port)) != 0)
1928                               fatal_fr(r, "channel %i: reply", c->self);
1929           } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
1930                     /* target path */
1931                     if ((r = sshpkt_put_cstring(ssh, c->path)) != 0)
1932                               fatal_fr(r, "channel %i: reply", c->self);
1933           } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1934                     /* listen path */
1935                     if ((r = sshpkt_put_cstring(ssh, c->path)) != 0)
1936                               fatal_fr(r, "channel %i: reply", c->self);
1937           } else {
1938                     /* listen address, port */
1939                     if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
1940                         (r = sshpkt_put_u32(ssh, local_port)) != 0)
1941                               fatal_fr(r, "channel %i: reply", c->self);
1942           }
1943           if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1944                     /* reserved for future owner/mode info */
1945                     if ((r = sshpkt_put_cstring(ssh, "")) != 0)
1946                               fatal_fr(r, "channel %i: reply", c->self);
1947           } else {
1948                     /* originator host and port */
1949                     if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
1950                         (r = sshpkt_put_u32(ssh, (u_int)remote_port)) != 0)
1951                               fatal_fr(r, "channel %i: reply", c->self);
1952           }
1953           if ((r = sshpkt_send(ssh)) != 0)
1954                     fatal_fr(r, "channel %i: send", c->self);
1955           free(remote_ipaddr);
1956           free(local_ipaddr);
1957 }
1958 
1959 void
channel_set_x11_refuse_time(struct ssh * ssh,time_t refuse_time)1960 channel_set_x11_refuse_time(struct ssh *ssh, time_t refuse_time)
1961 {
1962           ssh->chanctxt->x11_refuse_time = refuse_time;
1963 }
1964 
1965 /*
1966  * This socket is listening for connections to a forwarded TCP/IP port.
1967  */
1968 static void
channel_post_port_listener(struct ssh * ssh,Channel * c)1969 channel_post_port_listener(struct ssh *ssh, Channel *c)
1970 {
1971           Channel *nc;
1972           struct sockaddr_storage addr;
1973           int newsock, nextstate;
1974           socklen_t addrlen;
1975           const char *rtype;
1976 
1977           if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
1978                     return;
1979 
1980           debug("Connection to port %d forwarding to %.100s port %d requested.",
1981               c->listening_port, c->path, c->host_port);
1982 
1983           if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
1984                     nextstate = SSH_CHANNEL_OPENING;
1985                     rtype = "forwarded-tcpip";
1986           } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) {
1987                     nextstate = SSH_CHANNEL_OPENING;
1988                     rtype = "forwarded-streamlocal@openssh.com";
1989           } else if (c->host_port == PORT_STREAMLOCAL) {
1990                     nextstate = SSH_CHANNEL_OPENING;
1991                     rtype = "direct-streamlocal@openssh.com";
1992           } else if (c->host_port == 0) {
1993                     nextstate = SSH_CHANNEL_DYNAMIC;
1994                     rtype = "dynamic-tcpip";
1995           } else {
1996                     nextstate = SSH_CHANNEL_OPENING;
1997                     rtype = "direct-tcpip";
1998           }
1999 
2000           addrlen = sizeof(addr);
2001           newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
2002           if (newsock == -1) {
2003                     if (errno != EINTR && errno != EWOULDBLOCK &&
2004                         errno != ECONNABORTED)
2005                               error("accept: %.100s", strerror(errno));
2006                     if (errno == EMFILE || errno == ENFILE)
2007                               c->notbefore = monotime() + 1;
2008                     return;
2009           }
2010           if (c->host_port != PORT_STREAMLOCAL)
2011                     set_nodelay(newsock);
2012           nc = channel_new(ssh, rtype, nextstate, newsock, newsock, -1,
2013               c->local_window_max, c->local_maxpacket, 0, rtype, 1);
2014           nc->listening_port = c->listening_port;
2015           nc->host_port = c->host_port;
2016           if (c->path != NULL)
2017                     nc->path = xstrdup(c->path);
2018 
2019           if (nextstate != SSH_CHANNEL_DYNAMIC)
2020                     port_open_helper(ssh, nc, rtype);
2021 }
2022 
2023 /*
2024  * This is the authentication agent socket listening for connections from
2025  * clients.
2026  */
2027 static void
channel_post_auth_listener(struct ssh * ssh,Channel * c)2028 channel_post_auth_listener(struct ssh *ssh, Channel *c)
2029 {
2030           Channel *nc;
2031           int r, newsock;
2032           struct sockaddr_storage addr;
2033           socklen_t addrlen;
2034 
2035           if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
2036                     return;
2037 
2038           addrlen = sizeof(addr);
2039           newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
2040           if (newsock == -1) {
2041                     error("accept from auth socket: %.100s", strerror(errno));
2042                     if (errno == EMFILE || errno == ENFILE)
2043                               c->notbefore = monotime() + 1;
2044                     return;
2045           }
2046           nc = channel_new(ssh, "agent-connection",
2047               SSH_CHANNEL_OPENING, newsock, newsock, -1,
2048               c->local_window_max, c->local_maxpacket,
2049               0, "accepted auth socket", 1);
2050           open_preamble(ssh, __func__, nc, "auth-agent@openssh.com");
2051           if ((r = sshpkt_send(ssh)) != 0)
2052                     fatal_fr(r, "channel %i", c->self);
2053 }
2054 
2055 static void
channel_post_connecting(struct ssh * ssh,Channel * c)2056 channel_post_connecting(struct ssh *ssh, Channel *c)
2057 {
2058           int err = 0, sock, isopen, r;
2059           socklen_t sz = sizeof(err);
2060 
2061           if ((c->io_ready & SSH_CHAN_IO_SOCK_W) == 0)
2062                     return;
2063           if (!c->have_remote_id)
2064                     fatal_f("channel %d: no remote id", c->self);
2065           /* for rdynamic the OPEN_CONFIRMATION has been sent already */
2066           isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH);
2067 
2068           if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) == -1) {
2069                     err = errno;
2070                     error("getsockopt SO_ERROR failed");
2071           }
2072 
2073           if (err == 0) {
2074                     /* Non-blocking connection completed */
2075                     debug("channel %d: connected to %s port %d",
2076                         c->self, c->connect_ctx.host, c->connect_ctx.port);
2077                     channel_connect_ctx_free(&c->connect_ctx);
2078                     c->type = SSH_CHANNEL_OPEN;
2079                     channel_set_used_time(ssh, c);
2080                     if (isopen) {
2081                               /* no message necessary */
2082                     } else {
2083                               if ((r = sshpkt_start(ssh,
2084                                   SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
2085                                   (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2086                                   (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
2087                                   (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
2088                                   (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
2089                                   (r = sshpkt_send(ssh)) != 0)
2090                                         fatal_fr(r, "channel %i open confirm", c->self);
2091                     }
2092                     return;
2093           }
2094           if (err == EINTR || err == EAGAIN || err == EINPROGRESS)
2095                     return;
2096 
2097           /* Non-blocking connection failed */
2098           debug("channel %d: connection failed: %s", c->self, strerror(err));
2099 
2100           /* Try next address, if any */
2101           if ((sock = connect_next(&c->connect_ctx)) == -1) {
2102                     /* Exhausted all addresses for this destination */
2103                     error("connect_to %.100s port %d: failed.",
2104                         c->connect_ctx.host, c->connect_ctx.port);
2105                     channel_connect_ctx_free(&c->connect_ctx);
2106                     if (isopen) {
2107                               rdynamic_close(ssh, c);
2108                     } else {
2109                               if ((r = sshpkt_start(ssh,
2110                                   SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
2111                                   (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2112                                   (r = sshpkt_put_u32(ssh,
2113                                   SSH2_OPEN_CONNECT_FAILED)) != 0 ||
2114                                   (r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
2115                                   (r = sshpkt_put_cstring(ssh, "")) != 0 ||
2116                                   (r = sshpkt_send(ssh)) != 0)
2117                                         fatal_fr(r, "channel %i: failure", c->self);
2118                               chan_mark_dead(ssh, c);
2119                     }
2120           }
2121 
2122           /* New non-blocking connection in progress */
2123           close(c->sock);
2124           c->sock = c->rfd = c->wfd = sock;
2125 }
2126 
2127 static int
channel_handle_rfd(struct ssh * ssh,Channel * c)2128 channel_handle_rfd(struct ssh *ssh, Channel *c)
2129 {
2130           char buf[CHAN_RBUF];
2131           ssize_t len;
2132           int r;
2133           size_t nr = 0, have, avail, maxlen = CHANNEL_MAX_READ;
2134 
2135           if ((c->io_ready & SSH_CHAN_IO_RFD) == 0)
2136                     return 1; /* Shouldn't happen */
2137           if ((avail = sshbuf_avail(c->input)) == 0)
2138                     return 1; /* Shouldn't happen */
2139 
2140           /*
2141            * For "simple" channels (i.e. not datagram or filtered), we can
2142            * read directly to the channel buffer.
2143            */
2144           if (c->input_filter == NULL && !c->datagram) {
2145                     /* Only OPEN channels have valid rwin */
2146                     if (c->type == SSH_CHANNEL_OPEN) {
2147                               if ((have = sshbuf_len(c->input)) >= c->remote_window)
2148                                         return 1; /* shouldn't happen */
2149                               if (maxlen > c->remote_window - have)
2150                                         maxlen = c->remote_window - have;
2151                     }
2152                     if (maxlen > avail)
2153                               maxlen = avail;
2154                     if ((r = sshbuf_read(c->rfd, c->input, maxlen, &nr)) != 0) {
2155                               if (errno == EINTR || errno == EAGAIN)
2156                                         return 1;
2157                               debug2("channel %d: read failed rfd %d maxlen %zu: %s",
2158                                   c->self, c->rfd, maxlen, ssh_err(r));
2159                               goto rfail;
2160                     }
2161                     if (nr != 0)
2162                               channel_set_used_time(ssh, c);
2163                     return 1;
2164           }
2165 
2166           len = read(c->rfd, buf, sizeof(buf));
2167           if (len == -1 && (errno == EINTR || errno == EAGAIN))
2168                     return 1;
2169           if (len <= 0) {
2170                     debug2("channel %d: read<=0 rfd %d len %zd: %s",
2171                         c->self, c->rfd, len,
2172                         len == 0 ? "closed" : strerror(errno));
2173  rfail:
2174                     if (c->type != SSH_CHANNEL_OPEN) {
2175                               debug2("channel %d: not open", c->self);
2176                               chan_mark_dead(ssh, c);
2177                               return -1;
2178                     } else {
2179                               chan_read_failed(ssh, c);
2180                     }
2181                     return -1;
2182           }
2183           channel_set_used_time(ssh, c);
2184           if (c->input_filter != NULL) {
2185                     if (c->input_filter(ssh, c, buf, len) == -1) {
2186                               debug2("channel %d: filter stops", c->self);
2187                               chan_read_failed(ssh, c);
2188                     }
2189           } else if (c->datagram) {
2190                     if ((r = sshbuf_put_string(c->input, buf, len)) != 0)
2191                               fatal_fr(r, "channel %i: put datagram", c->self);
2192           }
2193           return 1;
2194 }
2195 
2196 static int
channel_handle_wfd(struct ssh * ssh,Channel * c)2197 channel_handle_wfd(struct ssh *ssh, Channel *c)
2198 {
2199           struct termios tio;
2200           u_char *data = NULL, *buf; /* XXX const; need filter API change */
2201           size_t dlen, olen = 0;
2202           int r, len;
2203 
2204           if ((c->io_ready & SSH_CHAN_IO_WFD) == 0)
2205                     return 1;
2206           if (sshbuf_len(c->output) == 0)
2207                     return 1;
2208 
2209           /* Send buffered output data to the socket. */
2210           olen = sshbuf_len(c->output);
2211           if (c->output_filter != NULL) {
2212                     if ((buf = c->output_filter(ssh, c, &data, &dlen)) == NULL) {
2213                               debug2("channel %d: filter stops", c->self);
2214                               if (c->type != SSH_CHANNEL_OPEN)
2215                                         chan_mark_dead(ssh, c);
2216                               else
2217                                         chan_write_failed(ssh, c);
2218                               return -1;
2219                     }
2220           } else if (c->datagram) {
2221                     if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0)
2222                               fatal_fr(r, "channel %i: get datagram", c->self);
2223                     buf = data;
2224           } else {
2225                     buf = data = sshbuf_mutable_ptr(c->output);
2226                     dlen = sshbuf_len(c->output);
2227           }
2228 
2229           if (c->datagram) {
2230                     /* ignore truncated writes, datagrams might get lost */
2231                     len = write(c->wfd, buf, dlen);
2232                     free(data);
2233                     if (len == -1 && (errno == EINTR || errno == EAGAIN))
2234                               return 1;
2235                     if (len <= 0)
2236                               goto write_fail;
2237                     goto out;
2238           }
2239 
2240           len = write(c->wfd, buf, dlen);
2241           if (len == -1 && (errno == EINTR || errno == EAGAIN))
2242                     return 1;
2243           if (len <= 0) {
2244  write_fail:
2245                     if (c->type != SSH_CHANNEL_OPEN) {
2246                               debug2("channel %d: not open", c->self);
2247                               chan_mark_dead(ssh, c);
2248                               return -1;
2249                     } else {
2250                               chan_write_failed(ssh, c);
2251                     }
2252                     return -1;
2253           }
2254           channel_set_used_time(ssh, c);
2255           if (c->isatty && dlen >= 1 && buf[0] != '\r') {
2256                     if (tcgetattr(c->wfd, &tio) == 0 &&
2257                         !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
2258                               /*
2259                                * Simulate echo to reduce the impact of
2260                                * traffic analysis. We need to match the
2261                                * size of a SSH2_MSG_CHANNEL_DATA message
2262                                * (4 byte channel id + buf)
2263                                */
2264                               if ((r = sshpkt_msg_ignore(ssh, 4+len)) != 0 ||
2265                                   (r = sshpkt_send(ssh)) != 0)
2266                                         fatal_fr(r, "channel %i: ignore", c->self);
2267                     }
2268           }
2269           if ((r = sshbuf_consume(c->output, len)) != 0)
2270                     fatal_fr(r, "channel %i: consume", c->self);
2271  out:
2272           c->local_consumed += olen - sshbuf_len(c->output);
2273 
2274           return 1;
2275 }
2276 
2277 static int
channel_handle_efd_write(struct ssh * ssh,Channel * c)2278 channel_handle_efd_write(struct ssh *ssh, Channel *c)
2279 {
2280           int r;
2281           ssize_t len;
2282 
2283           if ((c->io_ready & SSH_CHAN_IO_EFD_W) == 0)
2284                     return 1;
2285           if (sshbuf_len(c->extended) == 0)
2286                     return 1;
2287 
2288           len = write(c->efd, sshbuf_ptr(c->extended),
2289               sshbuf_len(c->extended));
2290           debug2("channel %d: written %zd to efd %d", c->self, len, c->efd);
2291           if (len == -1 && (errno == EINTR || errno == EAGAIN))
2292                     return 1;
2293           if (len <= 0) {
2294                     debug2("channel %d: closing write-efd %d", c->self, c->efd);
2295                     channel_close_fd(ssh, c, &c->efd);
2296           } else {
2297                     if ((r = sshbuf_consume(c->extended, len)) != 0)
2298                               fatal_fr(r, "channel %i: consume", c->self);
2299                     c->local_consumed += len;
2300                     channel_set_used_time(ssh, c);
2301           }
2302           return 1;
2303 }
2304 
2305 static int
channel_handle_efd_read(struct ssh * ssh,Channel * c)2306 channel_handle_efd_read(struct ssh *ssh, Channel *c)
2307 {
2308           char buf[CHAN_RBUF];
2309           int r;
2310           ssize_t len;
2311 
2312           if ((c->io_ready & SSH_CHAN_IO_EFD_R) == 0)
2313                     return 1;
2314 
2315           len = read(c->efd, buf, sizeof(buf));
2316           debug2("channel %d: read %zd from efd %d", c->self, len, c->efd);
2317           if (len == -1 && (errno == EINTR || errno == EAGAIN))
2318                     return 1;
2319           if (len <= 0) {
2320                     debug2("channel %d: closing read-efd %d", c->self, c->efd);
2321                     channel_close_fd(ssh, c, &c->efd);
2322                     return 1;
2323           }
2324           channel_set_used_time(ssh, c);
2325           if (c->extended_usage == CHAN_EXTENDED_IGNORE)
2326                     debug3("channel %d: discard efd", c->self);
2327           else if ((r = sshbuf_put(c->extended, buf, len)) != 0)
2328                     fatal_fr(r, "channel %i: append", c->self);
2329           return 1;
2330 }
2331 
2332 static int
channel_handle_efd(struct ssh * ssh,Channel * c)2333 channel_handle_efd(struct ssh *ssh, Channel *c)
2334 {
2335           if (c->efd == -1)
2336                     return 1;
2337 
2338           /** XXX handle drain efd, too */
2339 
2340           if (c->extended_usage == CHAN_EXTENDED_WRITE)
2341                     return channel_handle_efd_write(ssh, c);
2342           else if (c->extended_usage == CHAN_EXTENDED_READ ||
2343               c->extended_usage == CHAN_EXTENDED_IGNORE)
2344                     return channel_handle_efd_read(ssh, c);
2345 
2346           return 1;
2347 }
2348 
2349 static int
channel_check_window(struct ssh * ssh,Channel * c)2350 channel_check_window(struct ssh *ssh, Channel *c)
2351 {
2352           int r;
2353 
2354           if (c->type == SSH_CHANNEL_OPEN &&
2355               !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
2356               ((c->local_window_max - c->local_window >
2357               c->local_maxpacket*3) ||
2358               c->local_window < c->local_window_max/2) &&
2359               c->local_consumed > 0) {
2360                     u_int addition = 0;
2361                     u_int32_t tcpwinsz = channel_tcpwinsz(ssh);
2362                     /* adjust max window size if we are in a dynamic environment */
2363                     if (c->dynamic_window && (tcpwinsz > c->local_window_max)) {
2364                               /* grow the window somewhat aggressively to maintain
2365                                * pressure */
2366                               addition = 1.5*(tcpwinsz - c->local_window_max);
2367                               c->local_window_max += addition;
2368                               debug("Channel: Window growth to %d by %d bytes", c->local_window_max, addition);
2369                     }
2370                     if (!c->have_remote_id)
2371                               fatal_f("channel %d: no remote id", c->self);
2372                     if ((r = sshpkt_start(ssh,
2373                         SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
2374                         (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2375                         (r = sshpkt_put_u32(ssh, c->local_consumed + addition)) != 0 ||
2376                         (r = sshpkt_send(ssh)) != 0) {
2377                               fatal_fr(r, "channel %i", c->self);
2378                     }
2379                     debug2("channel %d: window %d sent adjust %d", c->self,
2380                         c->local_window,
2381                         c->local_consumed + addition);
2382                     c->local_window += c->local_consumed + addition;
2383                     c->local_consumed = 0;
2384           }
2385           return 1;
2386 }
2387 
2388 static void
channel_post_open(struct ssh * ssh,Channel * c)2389 channel_post_open(struct ssh *ssh, Channel *c)
2390 {
2391           channel_handle_rfd(ssh, c);
2392           channel_handle_wfd(ssh, c);
2393           channel_handle_efd(ssh, c);
2394           channel_check_window(ssh, c);
2395 }
2396 
2397 static u_int
read_mux(struct ssh * ssh,Channel * c,u_int need)2398 read_mux(struct ssh *ssh, Channel *c, u_int need)
2399 {
2400           char buf[CHAN_RBUF];
2401           ssize_t len;
2402           u_int rlen;
2403           int r;
2404 
2405           if (sshbuf_len(c->input) < need) {
2406                     rlen = need - sshbuf_len(c->input);
2407                     len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF));
2408                     if (len == -1 && (errno == EINTR || errno == EAGAIN))
2409                               return sshbuf_len(c->input);
2410                     if (len <= 0) {
2411                               debug2("channel %d: ctl read<=0 rfd %d len %zd",
2412                                   c->self, c->rfd, len);
2413                               chan_read_failed(ssh, c);
2414                               return 0;
2415                     } else if ((r = sshbuf_put(c->input, buf, len)) != 0)
2416                               fatal_fr(r, "channel %i: append", c->self);
2417           }
2418           return sshbuf_len(c->input);
2419 }
2420 
2421 static void
channel_post_mux_client_read(struct ssh * ssh,Channel * c)2422 channel_post_mux_client_read(struct ssh *ssh, Channel *c)
2423 {
2424           u_int need;
2425 
2426           if ((c->io_ready & SSH_CHAN_IO_RFD) == 0)
2427                     return;
2428           if (c->istate != CHAN_INPUT_OPEN && c->istate != CHAN_INPUT_WAIT_DRAIN)
2429                     return;
2430           if (c->mux_pause)
2431                     return;
2432 
2433           /*
2434            * Don't not read past the precise end of packets to
2435            * avoid disrupting fd passing.
2436            */
2437           if (read_mux(ssh, c, 4) < 4) /* read header */
2438                     return;
2439           /* XXX sshbuf_peek_u32 */
2440           need = PEEK_U32(sshbuf_ptr(c->input));
2441 #define CHANNEL_MUX_MAX_PACKET          (256 * 1024)
2442           if (need > CHANNEL_MUX_MAX_PACKET) {
2443                     debug2("channel %d: packet too big %u > %u",
2444                         c->self, CHANNEL_MUX_MAX_PACKET, need);
2445                     chan_rcvd_oclose(ssh, c);
2446                     return;
2447           }
2448           if (read_mux(ssh, c, need + 4) < need + 4) /* read body */
2449                     return;
2450           if (c->mux_rcb(ssh, c) != 0) {
2451                     debug("channel %d: mux_rcb failed", c->self);
2452                     chan_mark_dead(ssh, c);
2453                     return;
2454           }
2455 }
2456 
2457 static void
channel_post_mux_client_write(struct ssh * ssh,Channel * c)2458 channel_post_mux_client_write(struct ssh *ssh, Channel *c)
2459 {
2460           ssize_t len;
2461           int r;
2462 
2463           if ((c->io_ready & SSH_CHAN_IO_WFD) == 0)
2464                     return;
2465           if (sshbuf_len(c->output) == 0)
2466                     return;
2467 
2468           len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output));
2469           if (len == -1 && (errno == EINTR || errno == EAGAIN))
2470                     return;
2471           if (len <= 0) {
2472                     chan_mark_dead(ssh, c);
2473                     return;
2474           }
2475           if ((r = sshbuf_consume(c->output, len)) != 0)
2476                     fatal_fr(r, "channel %i: consume", c->self);
2477 }
2478 
2479 static void
channel_post_mux_client(struct ssh * ssh,Channel * c)2480 channel_post_mux_client(struct ssh *ssh, Channel *c)
2481 {
2482           channel_post_mux_client_read(ssh, c);
2483           channel_post_mux_client_write(ssh, c);
2484 }
2485 
2486 static void
channel_post_mux_listener(struct ssh * ssh,Channel * c)2487 channel_post_mux_listener(struct ssh *ssh, Channel *c)
2488 {
2489           Channel *nc;
2490           struct sockaddr_storage addr;
2491           socklen_t addrlen;
2492           int newsock;
2493           uid_t euid;
2494           gid_t egid;
2495 
2496           if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
2497                     return;
2498 
2499           debug("multiplexing control connection");
2500 
2501           /*
2502            * Accept connection on control socket
2503            */
2504           memset(&addr, 0, sizeof(addr));
2505           addrlen = sizeof(addr);
2506           if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
2507               &addrlen)) == -1) {
2508                     error_f("accept: %s", strerror(errno));
2509                     if (errno == EMFILE || errno == ENFILE)
2510                               c->notbefore = monotime() + 1;
2511                     return;
2512           }
2513 
2514           if (getpeereid(newsock, &euid, &egid) == -1) {
2515                     error_f("getpeereid failed: %s", strerror(errno));
2516                     close(newsock);
2517                     return;
2518           }
2519           if ((euid != 0) && (getuid() != euid)) {
2520                     error("multiplex uid mismatch: peer euid %u != uid %u",
2521                         (u_int)euid, (u_int)getuid());
2522                     close(newsock);
2523                     return;
2524           }
2525           nc = channel_new(ssh, "mux-control", SSH_CHANNEL_MUX_CLIENT,
2526               newsock, newsock, -1, c->local_window_max,
2527               c->local_maxpacket, 0, "mux-control", 1);
2528           nc->mux_rcb = c->mux_rcb;
2529           debug3_f("new mux channel %d fd %d", nc->self, nc->sock);
2530           /* establish state */
2531           nc->mux_rcb(ssh, nc);
2532           /* mux state transitions must not elicit protocol messages */
2533           nc->flags |= CHAN_LOCAL;
2534 }
2535 
2536 static void
channel_handler_init(struct ssh_channels * sc)2537 channel_handler_init(struct ssh_channels *sc)
2538 {
2539           chan_fn **pre, **post;
2540 
2541           if ((pre = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*pre))) == NULL ||
2542               (post = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*post))) == NULL)
2543                     fatal_f("allocation failed");
2544 
2545           pre[SSH_CHANNEL_OPEN] =                           &channel_pre_open;
2546           pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open;
2547           pre[SSH_CHANNEL_PORT_LISTENER] =        &channel_pre_listener;
2548           pre[SSH_CHANNEL_RPORT_LISTENER] =       &channel_pre_listener;
2549           pre[SSH_CHANNEL_UNIX_LISTENER] =        &channel_pre_listener;
2550           pre[SSH_CHANNEL_RUNIX_LISTENER] =       &channel_pre_listener;
2551           pre[SSH_CHANNEL_X11_LISTENER] =                   &channel_pre_listener;
2552           pre[SSH_CHANNEL_AUTH_SOCKET] =                    &channel_pre_listener;
2553           pre[SSH_CHANNEL_CONNECTING] =           &channel_pre_connecting;
2554           pre[SSH_CHANNEL_DYNAMIC] =              &channel_pre_dynamic;
2555           pre[SSH_CHANNEL_RDYNAMIC_FINISH] =      &channel_pre_connecting;
2556           pre[SSH_CHANNEL_MUX_LISTENER] =                   &channel_pre_listener;
2557           pre[SSH_CHANNEL_MUX_CLIENT] =           &channel_pre_mux_client;
2558 
2559           post[SSH_CHANNEL_OPEN] =                &channel_post_open;
2560           post[SSH_CHANNEL_PORT_LISTENER] =       &channel_post_port_listener;
2561           post[SSH_CHANNEL_RPORT_LISTENER] =      &channel_post_port_listener;
2562           post[SSH_CHANNEL_UNIX_LISTENER] =       &channel_post_port_listener;
2563           post[SSH_CHANNEL_RUNIX_LISTENER] =      &channel_post_port_listener;
2564           post[SSH_CHANNEL_X11_LISTENER] =        &channel_post_x11_listener;
2565           post[SSH_CHANNEL_AUTH_SOCKET] =                   &channel_post_auth_listener;
2566           post[SSH_CHANNEL_CONNECTING] =                    &channel_post_connecting;
2567           post[SSH_CHANNEL_DYNAMIC] =             &channel_post_open;
2568           post[SSH_CHANNEL_RDYNAMIC_FINISH] =     &channel_post_connecting;
2569           post[SSH_CHANNEL_MUX_LISTENER] =        &channel_post_mux_listener;
2570           post[SSH_CHANNEL_MUX_CLIENT] =                    &channel_post_mux_client;
2571 
2572           sc->channel_pre = pre;
2573           sc->channel_post = post;
2574 }
2575 
2576 /* gc dead channels */
2577 static void
channel_garbage_collect(struct ssh * ssh,Channel * c)2578 channel_garbage_collect(struct ssh *ssh, Channel *c)
2579 {
2580           if (c == NULL)
2581                     return;
2582           if (c->detach_user != NULL) {
2583                     if (!chan_is_dead(ssh, c, c->detach_close))
2584                               return;
2585 
2586                     debug2("channel %d: gc: notify user", c->self);
2587                     c->detach_user(ssh, c->self, 0, NULL);
2588                     /* if we still have a callback */
2589                     if (c->detach_user != NULL)
2590                               return;
2591                     debug2("channel %d: gc: user detached", c->self);
2592           }
2593           if (!chan_is_dead(ssh, c, 1))
2594                     return;
2595           debug2("channel %d: garbage collecting", c->self);
2596           channel_free(ssh, c);
2597 }
2598 
2599 enum channel_table { CHAN_PRE, CHAN_POST };
2600 
2601 static void
channel_handler(struct ssh * ssh,int table,struct timespec * timeout)2602 channel_handler(struct ssh *ssh, int table, struct timespec *timeout)
2603 {
2604           struct ssh_channels *sc = ssh->chanctxt;
2605           chan_fn **ftab = table == CHAN_PRE ? sc->channel_pre : sc->channel_post;
2606           u_int i, oalloc;
2607           Channel *c;
2608           time_t now;
2609 
2610           now = monotime();
2611           for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
2612                     c = sc->channels[i];
2613                     if (c == NULL)
2614                               continue;
2615                     /* Try to keep IO going while rekeying */
2616                     if (ssh_packet_is_rekeying(ssh) && c->type != SSH_CHANNEL_OPEN)
2617                               continue;
2618                     if (c->delayed) {
2619                               if (table == CHAN_PRE)
2620                                         c->delayed = 0;
2621                               else
2622                                         continue;
2623                     }
2624                     if (ftab[c->type] != NULL) {
2625                               if (table == CHAN_PRE && c->type == SSH_CHANNEL_OPEN &&
2626                                   channel_get_expiry(ssh, c) != 0 &&
2627                                   now >= channel_get_expiry(ssh, c)) {
2628                                         /* channel closed for inactivity */
2629                                         verbose("channel %d: closing after %u seconds "
2630                                             "of inactivity", c->self,
2631                                             c->inactive_deadline);
2632                                         channel_force_close(ssh, c, 1);
2633                               } else if (c->notbefore <= now) {
2634                                         /* Run handlers that are not paused. */
2635                                         (*ftab[c->type])(ssh, c);
2636                                         /* inactivity timeouts must interrupt poll() */
2637                                         if (timeout != NULL &&
2638                                             c->type == SSH_CHANNEL_OPEN &&
2639                                             channel_get_expiry(ssh, c) != 0) {
2640                                                   ptimeout_deadline_monotime(timeout,
2641                                                       channel_get_expiry(ssh, c));
2642                                         }
2643                               } else if (timeout != NULL) {
2644                                         /*
2645                                          * Arrange for poll() wakeup when channel pause
2646                                          * timer expires.
2647                                          */
2648                                         ptimeout_deadline_monotime(timeout,
2649                                             c->notbefore);
2650                               }
2651                     }
2652                     channel_garbage_collect(ssh, c);
2653           }
2654 }
2655 
2656 /*
2657  * Create sockets before preparing IO.
2658  * This is necessary for things that need to happen after reading
2659  * the network-input but need to be completed before IO event setup, e.g.
2660  * because they may create new channels.
2661  */
2662 static void
channel_before_prepare_io(struct ssh * ssh)2663 channel_before_prepare_io(struct ssh *ssh)
2664 {
2665           struct ssh_channels *sc = ssh->chanctxt;
2666           Channel *c;
2667           u_int i, oalloc;
2668 
2669           for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
2670                     c = sc->channels[i];
2671                     if (c == NULL)
2672                               continue;
2673                     if (c->type == SSH_CHANNEL_RDYNAMIC_OPEN)
2674                               channel_before_prepare_io_rdynamic(ssh, c);
2675           }
2676 }
2677 
2678 static void
dump_channel_poll(const char * func,const char * what,Channel * c,u_int pollfd_offset,struct pollfd * pfd)2679 dump_channel_poll(const char *func, const char *what, Channel *c,
2680     u_int pollfd_offset, struct pollfd *pfd)
2681 {
2682 #ifdef DEBUG_CHANNEL_POLL
2683           debug3("%s: channel %d: %s r%d w%d e%d s%d c->pfds [ %d %d %d %d ] "
2684               "io_want 0x%02x io_ready 0x%02x pfd[%u].fd=%d "
2685               "pfd.ev 0x%02x pfd.rev 0x%02x", func, c->self, what,
2686               c->rfd, c->wfd, c->efd, c->sock,
2687               c->pfds[0], c->pfds[1], c->pfds[2], c->pfds[3],
2688               c->io_want, c->io_ready,
2689               pollfd_offset, pfd->fd, pfd->events, pfd->revents);
2690 #endif
2691 }
2692 
2693 /* Prepare pollfd entries for a single channel */
2694 static void
channel_prepare_pollfd(Channel * c,u_int * next_pollfd,struct pollfd * pfd,u_int npfd)2695 channel_prepare_pollfd(Channel *c, u_int *next_pollfd,
2696     struct pollfd *pfd, u_int npfd)
2697 {
2698           u_int ev, p = *next_pollfd;
2699 
2700           if (c == NULL)
2701                     return;
2702           if (p + 4 > npfd) {
2703                     /* Shouldn't happen */
2704                     fatal_f("channel %d: bad pfd offset %u (max %u)",
2705                         c->self, p, npfd);
2706           }
2707           c->pfds[0] = c->pfds[1] = c->pfds[2] = c->pfds[3] = -1;
2708           /*
2709            * prepare c->rfd
2710            *
2711            * This is a special case, since c->rfd might be the same as
2712            * c->wfd, c->efd and/or c->sock. Handle those here if they want
2713            * IO too.
2714            */
2715           if (c->rfd != -1) {
2716                     ev = 0;
2717                     if ((c->io_want & SSH_CHAN_IO_RFD) != 0)
2718                               ev |= POLLIN;
2719                     /* rfd == wfd */
2720                     if (c->wfd == c->rfd) {
2721                               if ((c->io_want & SSH_CHAN_IO_WFD) != 0)
2722                                         ev |= POLLOUT;
2723                     }
2724                     /* rfd == efd */
2725                     if (c->efd == c->rfd) {
2726                               if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0)
2727                                         ev |= POLLIN;
2728                               if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0)
2729                                         ev |= POLLOUT;
2730                     }
2731                     /* rfd == sock */
2732                     if (c->sock == c->rfd) {
2733                               if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0)
2734                                         ev |= POLLIN;
2735                               if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0)
2736                                         ev |= POLLOUT;
2737                     }
2738                     /* Pack a pfd entry if any event armed for this fd */
2739                     if (ev != 0) {
2740                               c->pfds[0] = p;
2741                               pfd[p].fd = c->rfd;
2742                               pfd[p].events = ev;
2743                               dump_channel_poll(__func__, "rfd", c, p, &pfd[p]);
2744                               p++;
2745                     }
2746           }
2747           /* prepare c->wfd if wanting IO and not already handled above */
2748           if (c->wfd != -1 && c->rfd != c->wfd) {
2749                     ev = 0;
2750                     if ((c->io_want & SSH_CHAN_IO_WFD))
2751                               ev |= POLLOUT;
2752                     /* Pack a pfd entry if any event armed for this fd */
2753                     if (ev != 0) {
2754                               c->pfds[1] = p;
2755                               pfd[p].fd = c->wfd;
2756                               pfd[p].events = ev;
2757                               dump_channel_poll(__func__, "wfd", c, p, &pfd[p]);
2758                               p++;
2759                     }
2760           }
2761           /* prepare c->efd if wanting IO and not already handled above */
2762           if (c->efd != -1 && c->rfd != c->efd) {
2763                     ev = 0;
2764                     if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0)
2765                               ev |= POLLIN;
2766                     if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0)
2767                               ev |= POLLOUT;
2768                     /* Pack a pfd entry if any event armed for this fd */
2769                     if (ev != 0) {
2770                               c->pfds[2] = p;
2771                               pfd[p].fd = c->efd;
2772                               pfd[p].events = ev;
2773                               dump_channel_poll(__func__, "efd", c, p, &pfd[p]);
2774                               p++;
2775                     }
2776           }
2777           /* prepare c->sock if wanting IO and not already handled above */
2778           if (c->sock != -1 && c->rfd != c->sock) {
2779                     ev = 0;
2780                     if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0)
2781                               ev |= POLLIN;
2782                     if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0)
2783                               ev |= POLLOUT;
2784                     /* Pack a pfd entry if any event armed for this fd */
2785                     if (ev != 0) {
2786                               c->pfds[3] = p;
2787                               pfd[p].fd = c->sock;
2788                               pfd[p].events = 0;
2789                               dump_channel_poll(__func__, "sock", c, p, &pfd[p]);
2790                               p++;
2791                     }
2792           }
2793           *next_pollfd = p;
2794 }
2795 
2796 /* * Allocate/prepare poll structure */
2797 void
channel_prepare_poll(struct ssh * ssh,struct pollfd ** pfdp,u_int * npfd_allocp,u_int * npfd_activep,u_int npfd_reserved,struct timespec * timeout)2798 channel_prepare_poll(struct ssh *ssh, struct pollfd **pfdp, u_int *npfd_allocp,
2799     u_int *npfd_activep, u_int npfd_reserved, struct timespec *timeout)
2800 {
2801           struct ssh_channels *sc = ssh->chanctxt;
2802           u_int i, oalloc, p, npfd = npfd_reserved;
2803 
2804           channel_before_prepare_io(ssh); /* might create a new channel */
2805           /* clear out I/O flags from last poll */
2806           for (i = 0; i < sc->channels_alloc; i++) {
2807                     if (sc->channels[i] == NULL)
2808                               continue;
2809                     sc->channels[i]->io_want = sc->channels[i]->io_ready = 0;
2810           }
2811           /* Allocate 4x pollfd for each channel (rfd, wfd, efd, sock) */
2812           if (sc->channels_alloc >= (INT_MAX / 4) - npfd_reserved)
2813                     fatal_f("too many channels"); /* shouldn't happen */
2814           npfd += sc->channels_alloc * 4;
2815           if (npfd > *npfd_allocp) {
2816                     *pfdp = xrecallocarray(*pfdp, *npfd_allocp,
2817                         npfd, sizeof(**pfdp));
2818                     *npfd_allocp = npfd;
2819           }
2820           *npfd_activep = npfd_reserved;
2821           oalloc = sc->channels_alloc;
2822 
2823           channel_handler(ssh, CHAN_PRE, timeout);
2824 
2825           if (oalloc != sc->channels_alloc) {
2826                     /* shouldn't happen */
2827                     fatal_f("channels_alloc changed during CHAN_PRE "
2828                         "(was %u, now %u)", oalloc, sc->channels_alloc);
2829           }
2830 
2831           /* Prepare pollfd */
2832           p = npfd_reserved;
2833           for (i = 0; i < sc->channels_alloc; i++)
2834                     channel_prepare_pollfd(sc->channels[i], &p, *pfdp, npfd);
2835           *npfd_activep = p;
2836 }
2837 
2838 static void
fd_ready(Channel * c,int p,struct pollfd * pfds,u_int npfd,int fd,const char * what,u_int revents_mask,u_int ready)2839 fd_ready(Channel *c, int p, struct pollfd *pfds, u_int npfd, int fd,
2840     const char *what, u_int revents_mask, u_int ready)
2841 {
2842           struct pollfd *pfd = &pfds[p];
2843 
2844           if (fd == -1)
2845                     return;
2846           if (p == -1 || (u_int)p >= npfd)
2847                     fatal_f("channel %d: bad pfd %d (max %u)", c->self, p, npfd);
2848           dump_channel_poll(__func__, what, c, p, pfd);
2849           if (pfd->fd != fd) {
2850                     fatal("channel %d: inconsistent %s fd=%d pollfd[%u].fd %d "
2851                         "r%d w%d e%d s%d", c->self, what, fd, p, pfd->fd,
2852                         c->rfd, c->wfd, c->efd, c->sock);
2853           }
2854           if ((pfd->revents & POLLNVAL) != 0) {
2855                     fatal("channel %d: invalid %s pollfd[%u].fd %d r%d w%d e%d s%d",
2856                         c->self, what, p, pfd->fd, c->rfd, c->wfd, c->efd, c->sock);
2857           }
2858           if ((pfd->revents & (revents_mask|POLLHUP|POLLERR)) != 0)
2859                     c->io_ready |= ready & c->io_want;
2860 }
2861 
2862 /*
2863  * After poll, perform any appropriate operations for channels which have
2864  * events pending.
2865  */
2866 void
channel_after_poll(struct ssh * ssh,struct pollfd * pfd,u_int npfd)2867 channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd)
2868 {
2869           struct ssh_channels *sc = ssh->chanctxt;
2870           u_int i;
2871           int p;
2872           Channel *c;
2873 
2874 #ifdef DEBUG_CHANNEL_POLL
2875           for (p = 0; p < (int)npfd; p++) {
2876                     if (pfd[p].revents == 0)
2877                               continue;
2878                     debug_f("pfd[%u].fd %d rev 0x%04x",
2879                         p, pfd[p].fd, pfd[p].revents);
2880           }
2881 #endif
2882 
2883           /* Convert pollfd into c->io_ready */
2884           for (i = 0; i < sc->channels_alloc; i++) {
2885                     c = sc->channels[i];
2886                     if (c == NULL)
2887                               continue;
2888                     /* if rfd is shared with efd/sock then wfd should be too */
2889                     if (c->rfd != -1 && c->wfd != -1 && c->rfd != c->wfd &&
2890                         (c->rfd == c->efd || c->rfd == c->sock)) {
2891                               /* Shouldn't happen */
2892                               fatal_f("channel %d: unexpected fds r%d w%d e%d s%d",
2893                                   c->self, c->rfd, c->wfd, c->efd, c->sock);
2894                     }
2895                     c->io_ready = 0;
2896                     /* rfd, potentially shared with wfd, efd and sock */
2897                     if (c->rfd != -1 && (p = c->pfds[0]) != -1) {
2898                               fd_ready(c, p, pfd, npfd, c->rfd,
2899                                   "rfd", POLLIN, SSH_CHAN_IO_RFD);
2900                               if (c->rfd == c->wfd) {
2901                                         fd_ready(c, p, pfd, npfd, c->wfd,
2902                                             "wfd/r", POLLOUT, SSH_CHAN_IO_WFD);
2903                               }
2904                               if (c->rfd == c->efd) {
2905                                         fd_ready(c, p, pfd, npfd, c->efd,
2906                                             "efdr/r", POLLIN, SSH_CHAN_IO_EFD_R);
2907                                         fd_ready(c, p, pfd, npfd, c->efd,
2908                                             "efdw/r", POLLOUT, SSH_CHAN_IO_EFD_W);
2909                               }
2910                               if (c->rfd == c->sock) {
2911                                         fd_ready(c, p, pfd, npfd, c->sock,
2912                                             "sockr/r", POLLIN, SSH_CHAN_IO_SOCK_R);
2913                                         fd_ready(c, p, pfd, npfd, c->sock,
2914                                             "sockw/r", POLLOUT, SSH_CHAN_IO_SOCK_W);
2915                               }
2916                               dump_channel_poll(__func__, "rfd", c, p, pfd);
2917                     }
2918                     /* wfd */
2919                     if (c->wfd != -1 && c->wfd != c->rfd &&
2920                         (p = c->pfds[1]) != -1) {
2921                               fd_ready(c, p, pfd, npfd, c->wfd,
2922                                   "wfd", POLLOUT, SSH_CHAN_IO_WFD);
2923                               dump_channel_poll(__func__, "wfd", c, p, pfd);
2924                     }
2925                     /* efd */
2926                     if (c->efd != -1 && c->efd != c->rfd &&
2927                         (p = c->pfds[2]) != -1) {
2928                               fd_ready(c, p, pfd, npfd, c->efd,
2929                                   "efdr", POLLIN, SSH_CHAN_IO_EFD_R);
2930                               fd_ready(c, p, pfd, npfd, c->efd,
2931                                   "efdw", POLLOUT, SSH_CHAN_IO_EFD_W);
2932                               dump_channel_poll(__func__, "efd", c, p, pfd);
2933                     }
2934                     /* sock */
2935                     if (c->sock != -1 && c->sock != c->rfd &&
2936                         (p = c->pfds[3]) != -1) {
2937                               fd_ready(c, p, pfd, npfd, c->sock,
2938                                   "sockr", POLLIN, SSH_CHAN_IO_SOCK_R);
2939                               fd_ready(c, p, pfd, npfd, c->sock,
2940                                   "sockw", POLLOUT, SSH_CHAN_IO_SOCK_W);
2941                               dump_channel_poll(__func__, "sock", c, p, pfd);
2942                     }
2943           }
2944           channel_handler(ssh, CHAN_POST, NULL);
2945 }
2946 
2947 /*
2948  * Enqueue data for channels with open or draining c->input.
2949  * Returns non-zero if a packet was enqueued.
2950  */
2951 static int
channel_output_poll_input_open(struct ssh * ssh,Channel * c)2952 channel_output_poll_input_open(struct ssh *ssh, Channel *c)
2953 {
2954           size_t len, plen;
2955           const u_char *pkt;
2956           int r;
2957 
2958           if ((len = sshbuf_len(c->input)) == 0) {
2959                     if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
2960                               /*
2961                                * input-buffer is empty and read-socket shutdown:
2962                                * tell peer, that we will not send more data:
2963                                * send IEOF.
2964                                * hack for extended data: delay EOF if EFD still
2965                                * in use.
2966                                */
2967                               if (CHANNEL_EFD_INPUT_ACTIVE(c))
2968                                         debug2("channel %d: "
2969                                             "ibuf_empty delayed efd %d/(%zu)",
2970                                             c->self, c->efd, sshbuf_len(c->extended));
2971                               else
2972                                         chan_ibuf_empty(ssh, c);
2973                     }
2974                     return 0;
2975           }
2976 
2977           if (!c->have_remote_id)
2978                     fatal_f("channel %d: no remote id", c->self);
2979 
2980           if (c->datagram) {
2981                     /* Check datagram will fit; drop if not */
2982                     if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0)
2983                               fatal_fr(r, "channel %i: get datagram", c->self);
2984                     /*
2985                      * XXX this does tail-drop on the datagram queue which is
2986                      * usually suboptimal compared to head-drop. Better to have
2987                      * backpressure at read time? (i.e. read + discard)
2988                      */
2989                     if (plen > c->remote_window || plen > c->remote_maxpacket) {
2990                               debug("channel %d: datagram too big", c->self);
2991                               return 0;
2992                     }
2993                     /* Enqueue it */
2994                     if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
2995                         (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2996                         (r = sshpkt_put_string(ssh, pkt, plen)) != 0 ||
2997                         (r = sshpkt_send(ssh)) != 0)
2998                               fatal_fr(r, "channel %i: send datagram", c->self);
2999                     c->remote_window -= plen;
3000                     return 1;
3001           }
3002 
3003           /* Enqueue packet for buffered data. */
3004           if (len > c->remote_window)
3005                     len = c->remote_window;
3006           if (len > c->remote_maxpacket)
3007                     len = c->remote_maxpacket;
3008           if (len == 0)
3009                     return 0;
3010           if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
3011               (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
3012               (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||
3013               (r = sshpkt_send(ssh)) != 0)
3014                     fatal_fr(r, "channel %i: send data", c->self);
3015           if ((r = sshbuf_consume(c->input, len)) != 0)
3016                     fatal_fr(r, "channel %i: consume", c->self);
3017           c->remote_window -= len;
3018           return 1;
3019 }
3020 
3021 /*
3022  * Enqueue data for channels with open c->extended in read mode.
3023  * Returns non-zero if a packet was enqueued.
3024  */
3025 static int
channel_output_poll_extended_read(struct ssh * ssh,Channel * c)3026 channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
3027 {
3028           size_t len;
3029           int r;
3030 
3031           if ((len = sshbuf_len(c->extended)) == 0)
3032                     return 0;
3033 
3034           debug2("channel %d: rwin %u elen %zu euse %d", c->self,
3035               c->remote_window, sshbuf_len(c->extended), c->extended_usage);
3036           if (len > c->remote_window)
3037                     len = c->remote_window;
3038           if (len > c->remote_maxpacket)
3039                     len = c->remote_maxpacket;
3040           if (len == 0)
3041                     return 0;
3042           if (!c->have_remote_id)
3043                     fatal_f("channel %d: no remote id", c->self);
3044           if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
3045               (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
3046               (r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 ||
3047               (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 ||
3048               (r = sshpkt_send(ssh)) != 0)
3049                     fatal_fr(r, "channel %i: data", c->self);
3050           if ((r = sshbuf_consume(c->extended, len)) != 0)
3051                     fatal_fr(r, "channel %i: consume", c->self);
3052           c->remote_window -= len;
3053           debug2("channel %d: sent ext data %zu", c->self, len);
3054           return 1;
3055 }
3056 
3057 /*
3058  * If there is data to send to the connection, enqueue some of it now.
3059  * Returns non-zero if data was enqueued.
3060  */
3061 int
channel_output_poll(struct ssh * ssh)3062 channel_output_poll(struct ssh *ssh)
3063 {
3064           struct ssh_channels *sc = ssh->chanctxt;
3065           Channel *c;
3066           u_int i;
3067           int ret = 0;
3068 
3069           for (i = 0; i < sc->channels_alloc; i++) {
3070                     c = sc->channels[i];
3071                     if (c == NULL)
3072                               continue;
3073 
3074                     /*
3075                      * We are only interested in channels that can have buffered
3076                      * incoming data.
3077                      */
3078                     if (c->type != SSH_CHANNEL_OPEN)
3079                               continue;
3080                     if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
3081                               /* XXX is this true? */
3082                               debug3("channel %d: will not send data after close",
3083                                   c->self);
3084                               continue;
3085                     }
3086 
3087                     /* Get the amount of buffered data for this channel. */
3088                     if (c->istate == CHAN_INPUT_OPEN ||
3089                         c->istate == CHAN_INPUT_WAIT_DRAIN)
3090                               ret |= channel_output_poll_input_open(ssh, c);
3091                     /* Send extended data, i.e. stderr */
3092                     if (!(c->flags & CHAN_EOF_SENT) &&
3093                         c->extended_usage == CHAN_EXTENDED_READ)
3094                               ret |= channel_output_poll_extended_read(ssh, c);
3095           }
3096           return ret;
3097 }
3098 
3099 /* -- mux proxy support  */
3100 
3101 /*
3102  * When multiplexing channel messages for mux clients we have to deal
3103  * with downstream messages from the mux client and upstream messages
3104  * from the ssh server:
3105  * 1) Handling downstream messages is straightforward and happens
3106  *    in channel_proxy_downstream():
3107  *    - We forward all messages (mostly) unmodified to the server.
3108  *    - However, in order to route messages from upstream to the correct
3109  *      downstream client, we have to replace the channel IDs used by the
3110  *      mux clients with a unique channel ID because the mux clients might
3111  *      use conflicting channel IDs.
3112  *    - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and
3113  *      SSH2_MSG_CHANNEL_OPEN_CONFIRMATION messages, create a local
3114  *      SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID
3115  *      with the newly allocated channel ID.
3116  * 2) Upstream messages are received by matching SSH_CHANNEL_MUX_PROXY
3117  *    channels and processed by channel_proxy_upstream(). The local channel ID
3118  *    is then translated back to the original mux client ID.
3119  * 3) In both cases we need to keep track of matching SSH2_MSG_CHANNEL_CLOSE
3120  *    messages so we can clean up SSH_CHANNEL_MUX_PROXY channels.
3121  * 4) The SSH_CHANNEL_MUX_PROXY channels also need to closed when the
3122  *    downstream mux client are removed.
3123  * 5) Handling SSH2_MSG_CHANNEL_OPEN messages from the upstream server
3124  *    requires more work, because they are not addressed to a specific
3125  *    channel. E.g. client_request_forwarded_tcpip() needs to figure
3126  *    out whether the request is addressed to the local client or a
3127  *    specific downstream client based on the listen-address/port.
3128  * 6) Agent and X11-Forwarding have a similar problem and are currently
3129  *    not supported as the matching session/channel cannot be identified
3130  *    easily.
3131  */
3132 
3133 /*
3134  * receive packets from downstream mux clients:
3135  * channel callback fired on read from mux client, creates
3136  * SSH_CHANNEL_MUX_PROXY channels and translates channel IDs
3137  * on channel creation.
3138  */
3139 int
channel_proxy_downstream(struct ssh * ssh,Channel * downstream)3140 channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
3141 {
3142           Channel *c = NULL;
3143           struct sshbuf *original = NULL, *modified = NULL;
3144           const u_char *cp;
3145           char *ctype = NULL, *listen_host = NULL;
3146           u_char type;
3147           size_t have;
3148           int ret = -1, r;
3149           u_int id, remote_id, listen_port;
3150 
3151           /* sshbuf_dump(downstream->input, stderr); */
3152           if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have))
3153               != 0) {
3154                     error_fr(r, "parse");
3155                     return -1;
3156           }
3157           if (have < 2) {
3158                     error_f("short message");
3159                     return -1;
3160           }
3161           type = cp[1];
3162           /* skip padlen + type */
3163           cp += 2;
3164           have -= 2;
3165           if (ssh_packet_log_type(type))
3166                     debug3_f("channel %u: down->up: type %u",
3167                         downstream->self, type);
3168 
3169           switch (type) {
3170           case SSH2_MSG_CHANNEL_OPEN:
3171                     if ((original = sshbuf_from(cp, have)) == NULL ||
3172                         (modified = sshbuf_new()) == NULL) {
3173                               error_f("alloc");
3174                               goto out;
3175                     }
3176                     if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||
3177                         (r = sshbuf_get_u32(original, &id)) != 0) {
3178                               error_fr(r, "parse");
3179                               goto out;
3180                     }
3181                     c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY,
3182                         -1, -1, -1, 0, 0, 0, ctype, 1);
3183                     c->mux_ctx = downstream;      /* point to mux client */
3184                     c->mux_downstream_id = id;    /* original downstream id */
3185                     if ((r = sshbuf_put_cstring(modified, ctype)) != 0 ||
3186                         (r = sshbuf_put_u32(modified, c->self)) != 0 ||
3187                         (r = sshbuf_putb(modified, original)) != 0) {
3188                               error_fr(r, "compose");
3189                               channel_free(ssh, c);
3190                               goto out;
3191                     }
3192                     break;
3193           case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
3194                     /*
3195                      * Almost the same as SSH2_MSG_CHANNEL_OPEN, except then we
3196                      * need to parse 'remote_id' instead of 'ctype'.
3197                      */
3198                     if ((original = sshbuf_from(cp, have)) == NULL ||
3199                         (modified = sshbuf_new()) == NULL) {
3200                               error_f("alloc");
3201                               goto out;
3202                     }
3203                     if ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||
3204                         (r = sshbuf_get_u32(original, &id)) != 0) {
3205                               error_fr(r, "parse");
3206                               goto out;
3207                     }
3208                     c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY,
3209                         -1, -1, -1, 0, 0, 0, "mux-down-connect", 1);
3210                     c->mux_ctx = downstream;      /* point to mux client */
3211                     c->mux_downstream_id = id;
3212                     c->remote_id = remote_id;
3213                     c->have_remote_id = 1;
3214                     if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
3215                         (r = sshbuf_put_u32(modified, c->self)) != 0 ||
3216                         (r = sshbuf_putb(modified, original)) != 0) {
3217                               error_fr(r, "compose");
3218                               channel_free(ssh, c);
3219                               goto out;
3220                     }
3221                     break;
3222           case SSH2_MSG_GLOBAL_REQUEST:
3223                     if ((original = sshbuf_from(cp, have)) == NULL) {
3224                               error_f("alloc");
3225                               goto out;
3226                     }
3227                     if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {
3228                               error_fr(r, "parse");
3229                               goto out;
3230                     }
3231                     if (strcmp(ctype, "tcpip-forward") != 0) {
3232                               error_f("unsupported request %s", ctype);
3233                               goto out;
3234                     }
3235                     if ((r = sshbuf_get_u8(original, NULL)) != 0 ||
3236                         (r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 ||
3237                         (r = sshbuf_get_u32(original, &listen_port)) != 0) {
3238                               error_fr(r, "parse");
3239                               goto out;
3240                     }
3241                     if (listen_port > 65535) {
3242                               error_f("tcpip-forward for %s: bad port %u",
3243                                   listen_host, listen_port);
3244                               goto out;
3245                     }
3246                     /* Record that connection to this host/port is permitted. */
3247                     permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL, "<mux>",
3248                         -1, listen_host, NULL, (int)listen_port, downstream);
3249                     break;
3250           case SSH2_MSG_CHANNEL_CLOSE:
3251                     if (have < 4)
3252                               break;
3253                     remote_id = PEEK_U32(cp);
3254                     if ((c = channel_by_remote_id(ssh, remote_id)) != NULL) {
3255                               if (c->flags & CHAN_CLOSE_RCVD)
3256                                         channel_free(ssh, c);
3257                               else
3258                                         c->flags |= CHAN_CLOSE_SENT;
3259                     }
3260                     break;
3261           }
3262           if (modified) {
3263                     if ((r = sshpkt_start(ssh, type)) != 0 ||
3264                         (r = sshpkt_putb(ssh, modified)) != 0 ||
3265                         (r = sshpkt_send(ssh)) != 0) {
3266                               error_fr(r, "send");
3267                               goto out;
3268                     }
3269           } else {
3270                     if ((r = sshpkt_start(ssh, type)) != 0 ||
3271                         (r = sshpkt_put(ssh, cp, have)) != 0 ||
3272                         (r = sshpkt_send(ssh)) != 0) {
3273                               error_fr(r, "send");
3274                               goto out;
3275                     }
3276           }
3277           ret = 0;
3278  out:
3279           free(ctype);
3280           free(listen_host);
3281           sshbuf_free(original);
3282           sshbuf_free(modified);
3283           return ret;
3284 }
3285 
3286 /*
3287  * receive packets from upstream server and de-multiplex packets
3288  * to correct downstream:
3289  * implemented as a helper for channel input handlers,
3290  * replaces local (proxy) channel ID with downstream channel ID.
3291  */
3292 int
channel_proxy_upstream(Channel * c,int type,u_int32_t seq,struct ssh * ssh)3293 channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)
3294 {
3295           struct sshbuf *b = NULL;
3296           Channel *downstream;
3297           const u_char *cp = NULL;
3298           size_t len;
3299           int r;
3300 
3301           /*
3302            * When receiving packets from the peer we need to check whether we
3303            * need to forward the packets to the mux client. In this case we
3304            * restore the original channel id and keep track of CLOSE messages,
3305            * so we can cleanup the channel.
3306            */
3307           if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY)
3308                     return 0;
3309           if ((downstream = c->mux_ctx) == NULL)
3310                     return 0;
3311           switch (type) {
3312           case SSH2_MSG_CHANNEL_CLOSE:
3313           case SSH2_MSG_CHANNEL_DATA:
3314           case SSH2_MSG_CHANNEL_EOF:
3315           case SSH2_MSG_CHANNEL_EXTENDED_DATA:
3316           case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
3317           case SSH2_MSG_CHANNEL_OPEN_FAILURE:
3318           case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
3319           case SSH2_MSG_CHANNEL_SUCCESS:
3320           case SSH2_MSG_CHANNEL_FAILURE:
3321           case SSH2_MSG_CHANNEL_REQUEST:
3322                     break;
3323           default:
3324                     debug2_f("channel %u: unsupported type %u", c->self, type);
3325                     return 0;
3326           }
3327           if ((b = sshbuf_new()) == NULL) {
3328                     error_f("alloc reply");
3329                     goto out;
3330           }
3331           /* get remaining payload (after id) */
3332           cp = sshpkt_ptr(ssh, &len);
3333           if (cp == NULL) {
3334                     error_f("no packet");
3335                     goto out;
3336           }
3337           /* translate id and send to muxclient */
3338           if ((r = sshbuf_put_u8(b, 0)) != 0 ||   /* padlen */
3339               (r = sshbuf_put_u8(b, type)) != 0 ||
3340               (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||
3341               (r = sshbuf_put(b, cp, len)) != 0 ||
3342               (r = sshbuf_put_stringb(downstream->output, b)) != 0) {
3343                     error_fr(r, "compose muxclient");
3344                     goto out;
3345           }
3346           /* sshbuf_dump(b, stderr); */
3347           if (ssh_packet_log_type(type))
3348                     debug3_f("channel %u: up->down: type %u", c->self, type);
3349  out:
3350           /* update state */
3351           switch (type) {
3352           case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
3353                     /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */
3354                     if (cp && len > 4) {
3355                               c->remote_id = PEEK_U32(cp);
3356                               c->have_remote_id = 1;
3357                     }
3358                     break;
3359           case SSH2_MSG_CHANNEL_CLOSE:
3360                     if (c->flags & CHAN_CLOSE_SENT)
3361                               channel_free(ssh, c);
3362                     else
3363                               c->flags |= CHAN_CLOSE_RCVD;
3364                     break;
3365           }
3366           sshbuf_free(b);
3367           return 1;
3368 }
3369 
3370 /* -- protocol input */
3371 
3372 /* Parse a channel ID from the current packet */
3373 static int
channel_parse_id(struct ssh * ssh,const char * where,const char * what)3374 channel_parse_id(struct ssh *ssh, const char *where, const char *what)
3375 {
3376           u_int32_t id;
3377           int r;
3378 
3379           if ((r = sshpkt_get_u32(ssh, &id)) != 0) {
3380                     error_r(r, "%s: parse id", where);
3381                     ssh_packet_disconnect(ssh, "Invalid %s message", what);
3382           }
3383           if (id > INT_MAX) {
3384                     error_r(r, "%s: bad channel id %u", where, id);
3385                     ssh_packet_disconnect(ssh, "Invalid %s channel id", what);
3386           }
3387           return (int)id;
3388 }
3389 
3390 /* Lookup a channel from an ID in the current packet */
3391 static Channel *
channel_from_packet_id(struct ssh * ssh,const char * where,const char * what)3392 channel_from_packet_id(struct ssh *ssh, const char *where, const char *what)
3393 {
3394           int id = channel_parse_id(ssh, where, what);
3395           Channel *c;
3396 
3397           if ((c = channel_lookup(ssh, id)) == NULL) {
3398                     ssh_packet_disconnect(ssh,
3399                         "%s packet referred to nonexistent channel %d", what, id);
3400           }
3401           return c;
3402 }
3403 
3404 int
channel_input_data(int type,u_int32_t seq,struct ssh * ssh)3405 channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
3406 {
3407           const u_char *data;
3408           size_t data_len, win_len;
3409           Channel *c = channel_from_packet_id(ssh, __func__, "data");
3410           int r;
3411 
3412           if (channel_proxy_upstream(c, type, seq, ssh))
3413                     return 0;
3414 
3415           /* Ignore any data for non-open channels (might happen on close) */
3416           if (c->type != SSH_CHANNEL_OPEN &&
3417               c->type != SSH_CHANNEL_RDYNAMIC_OPEN &&
3418               c->type != SSH_CHANNEL_RDYNAMIC_FINISH &&
3419               c->type != SSH_CHANNEL_X11_OPEN)
3420                     return 0;
3421 
3422           /* Get the data. */
3423           if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
3424             (r = sshpkt_get_end(ssh)) != 0)
3425                     fatal_fr(r, "channel %i: get data", c->self);
3426 
3427           win_len = data_len;
3428           if (c->datagram)
3429                     win_len += 4;  /* string length header */
3430 
3431           /*
3432            * The sending side reduces its window as it sends data, so we
3433            * must 'fake' consumption of the data in order to ensure that window
3434            * updates are sent back. Otherwise the connection might deadlock.
3435            */
3436           if (c->ostate != CHAN_OUTPUT_OPEN) {
3437                     c->local_window -= win_len;
3438                     c->local_consumed += win_len;
3439                     return 0;
3440           }
3441 
3442           if (win_len > c->local_maxpacket) {
3443                     logit("channel %d: rcvd big packet %zu, maxpack %u",
3444                         c->self, win_len, c->local_maxpacket);
3445                     return 0;
3446           }
3447           if (win_len > c->local_window) {
3448                     c->local_window_exceeded += win_len - c->local_window;
3449                     logit("channel %d: rcvd too much data %zu, win %u/%u "
3450                         "(excess %u)", c->self, win_len, c->local_window,
3451                         c->local_window_max, c->local_window_exceeded);
3452                     c->local_window = 0;
3453                     /* Allow 10% grace before bringing the hammer down */
3454                     if (c->local_window_exceeded > (c->local_window_max / 10)) {
3455                               ssh_packet_disconnect(ssh, "channel %d: peer ignored "
3456                                   "channel window", c->self);
3457                     }
3458           } else {
3459                     c->local_window -= win_len;
3460                     c->local_window_exceeded = 0;
3461           }
3462 
3463           if (c->datagram) {
3464                     if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)
3465                               fatal_fr(r, "channel %i: append datagram", c->self);
3466           } else if ((r = sshbuf_put(c->output, data, data_len)) != 0)
3467                     fatal_fr(r, "channel %i: append data", c->self);
3468 
3469           return 0;
3470 }
3471 
3472 int
channel_input_extended_data(int type,u_int32_t seq,struct ssh * ssh)3473 channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
3474 {
3475           const u_char *data;
3476           size_t data_len;
3477           u_int32_t tcode;
3478           Channel *c = channel_from_packet_id(ssh, __func__, "extended data");
3479           int r;
3480 
3481           if (channel_proxy_upstream(c, type, seq, ssh))
3482                     return 0;
3483           if (c->type != SSH_CHANNEL_OPEN) {
3484                     logit("channel %d: ext data for non open", c->self);
3485                     return 0;
3486           }
3487           if (c->flags & CHAN_EOF_RCVD) {
3488                     if (ssh->compat & SSH_BUG_EXTEOF)
3489                               debug("channel %d: accepting ext data after eof",
3490                                   c->self);
3491                     else
3492                               ssh_packet_disconnect(ssh, "Received extended_data "
3493                                   "after EOF on channel %d.", c->self);
3494           }
3495 
3496           if ((r = sshpkt_get_u32(ssh, &tcode)) != 0) {
3497                     error_fr(r, "parse tcode");
3498                     ssh_packet_disconnect(ssh, "Invalid extended_data message");
3499           }
3500           if (c->efd == -1 ||
3501               c->extended_usage != CHAN_EXTENDED_WRITE ||
3502               tcode != SSH2_EXTENDED_DATA_STDERR) {
3503                     logit("channel %d: bad ext data", c->self);
3504                     return 0;
3505           }
3506           if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
3507             (r = sshpkt_get_end(ssh)) != 0) {
3508                     error_fr(r, "parse data");
3509                     ssh_packet_disconnect(ssh, "Invalid extended_data message");
3510           }
3511 
3512           if (data_len > c->local_window) {
3513                     logit("channel %d: rcvd too much extended_data %zu, win %u",
3514                         c->self, data_len, c->local_window);
3515                     return 0;
3516           }
3517           debug2("channel %d: rcvd ext data %zu", c->self, data_len);
3518           /* XXX sshpkt_getb? */
3519           if ((r = sshbuf_put(c->extended, data, data_len)) != 0)
3520                     error_fr(r, "append");
3521           c->local_window -= data_len;
3522           return 0;
3523 }
3524 
3525 int
channel_input_ieof(int type,u_int32_t seq,struct ssh * ssh)3526 channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)
3527 {
3528           Channel *c = channel_from_packet_id(ssh, __func__, "ieof");
3529           int r;
3530 
3531         if ((r = sshpkt_get_end(ssh)) != 0) {
3532                     error_fr(r, "parse data");
3533                     ssh_packet_disconnect(ssh, "Invalid ieof message");
3534           }
3535 
3536           if (channel_proxy_upstream(c, type, seq, ssh))
3537                     return 0;
3538           chan_rcvd_ieof(ssh, c);
3539 
3540           /* XXX force input close */
3541           if (c->force_drain && c->istate == CHAN_INPUT_OPEN) {
3542                     debug("channel %d: FORCE input drain", c->self);
3543                     c->istate = CHAN_INPUT_WAIT_DRAIN;
3544                     if (sshbuf_len(c->input) == 0)
3545                               chan_ibuf_empty(ssh, c);
3546           }
3547           return 0;
3548 }
3549 
3550 int
channel_input_oclose(int type,u_int32_t seq,struct ssh * ssh)3551 channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)
3552 {
3553           Channel *c = channel_from_packet_id(ssh, __func__, "oclose");
3554           int r;
3555 
3556           if (channel_proxy_upstream(c, type, seq, ssh))
3557                     return 0;
3558         if ((r = sshpkt_get_end(ssh)) != 0) {
3559                     error_fr(r, "parse data");
3560                     ssh_packet_disconnect(ssh, "Invalid oclose message");
3561           }
3562           chan_rcvd_oclose(ssh, c);
3563           return 0;
3564 }
3565 
3566 int
channel_input_open_confirmation(int type,u_int32_t seq,struct ssh * ssh)3567 channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
3568 {
3569           Channel *c = channel_from_packet_id(ssh, __func__, "open confirmation");
3570           u_int32_t remote_window, remote_maxpacket;
3571           int r;
3572 
3573           if (channel_proxy_upstream(c, type, seq, ssh))
3574                     return 0;
3575           if (c->type != SSH_CHANNEL_OPENING)
3576                     ssh_packet_disconnect(ssh, "Received open confirmation for "
3577                         "non-opening channel %d.", c->self);
3578           /*
3579            * Record the remote channel number and mark that the channel
3580            * is now open.
3581            */
3582           if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 ||
3583               (r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
3584               (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0 ||
3585             (r = sshpkt_get_end(ssh)) != 0) {
3586                     error_fr(r, "window/maxpacket");
3587                     ssh_packet_disconnect(ssh, "Invalid open confirmation message");
3588           }
3589 
3590           c->have_remote_id = 1;
3591           c->remote_window = remote_window;
3592           c->remote_maxpacket = remote_maxpacket;
3593           c->type = SSH_CHANNEL_OPEN;
3594           if (c->open_confirm) {
3595                     debug2_f("channel %d: callback start", c->self);
3596                     c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);
3597                     debug2_f("channel %d: callback done", c->self);
3598           }
3599           channel_set_used_time(ssh, c);
3600           debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
3601               c->remote_window, c->remote_maxpacket);
3602           return 0;
3603 }
3604 
3605 static const char *
reason2txt(int reason)3606 reason2txt(int reason)
3607 {
3608           switch (reason) {
3609           case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED:
3610                     return "administratively prohibited";
3611           case SSH2_OPEN_CONNECT_FAILED:
3612                     return "connect failed";
3613           case SSH2_OPEN_UNKNOWN_CHANNEL_TYPE:
3614                     return "unknown channel type";
3615           case SSH2_OPEN_RESOURCE_SHORTAGE:
3616                     return "resource shortage";
3617           }
3618           return "unknown reason";
3619 }
3620 
3621 int
channel_input_open_failure(int type,u_int32_t seq,struct ssh * ssh)3622 channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)
3623 {
3624           Channel *c = channel_from_packet_id(ssh, __func__, "open failure");
3625           u_int32_t reason;
3626           char *msg = NULL;
3627           int r;
3628 
3629           if (channel_proxy_upstream(c, type, seq, ssh))
3630                     return 0;
3631           if (c->type != SSH_CHANNEL_OPENING)
3632                     ssh_packet_disconnect(ssh, "Received open failure for "
3633                         "non-opening channel %d.", c->self);
3634           if ((r = sshpkt_get_u32(ssh, &reason)) != 0) {
3635                     error_fr(r, "parse reason");
3636                     ssh_packet_disconnect(ssh, "Invalid open failure message");
3637           }
3638           /* skip language */
3639           if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||
3640               (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0 ||
3641             (r = sshpkt_get_end(ssh)) != 0) {
3642                     error_fr(r, "parse msg/lang");
3643                     ssh_packet_disconnect(ssh, "Invalid open failure message");
3644           }
3645           logit("channel %d: open failed: %s%s%s", c->self,
3646               reason2txt(reason), msg ? ": ": "", msg ? msg : "");
3647           free(msg);
3648           if (c->open_confirm) {
3649                     debug2_f("channel %d: callback start", c->self);
3650                     c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx);
3651                     debug2_f("channel %d: callback done", c->self);
3652           }
3653           /* Schedule the channel for cleanup/deletion. */
3654           chan_mark_dead(ssh, c);
3655           return 0;
3656 }
3657 
3658 int
channel_input_window_adjust(int type,u_int32_t seq,struct ssh * ssh)3659 channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh)
3660 {
3661           int id = channel_parse_id(ssh, __func__, "window adjust");
3662           Channel *c;
3663           u_int32_t adjust;
3664           u_int new_rwin;
3665           int r;
3666 
3667           if ((c = channel_lookup(ssh, id)) == NULL) {
3668                     logit("Received window adjust for non-open channel %d.", id);
3669                     return 0;
3670           }
3671 
3672           if (channel_proxy_upstream(c, type, seq, ssh))
3673                     return 0;
3674           if ((r = sshpkt_get_u32(ssh, &adjust)) != 0 ||
3675             (r = sshpkt_get_end(ssh)) != 0) {
3676                     error_fr(r, "parse adjust");
3677                     ssh_packet_disconnect(ssh, "Invalid window adjust message");
3678           }
3679           debug2("channel %d: rcvd adjust %u", c->self, adjust);
3680           if ((new_rwin = c->remote_window + adjust) < c->remote_window) {
3681                     fatal("channel %d: adjust %u overflows remote window %u",
3682                         c->self, adjust, c->remote_window);
3683           }
3684           c->remote_window = new_rwin;
3685           return 0;
3686 }
3687 
3688 int
channel_input_status_confirm(int type,u_int32_t seq,struct ssh * ssh)3689 channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh)
3690 {
3691           int id = channel_parse_id(ssh, __func__, "status confirm");
3692           Channel *c;
3693           struct channel_confirm *cc;
3694 
3695           /* Reset keepalive timeout */
3696           ssh_packet_set_alive_timeouts(ssh, 0);
3697 
3698           debug2_f("type %d id %d", type, id);
3699 
3700           if ((c = channel_lookup(ssh, id)) == NULL) {
3701                     logit_f("%d: unknown", id);
3702                     return 0;
3703           }
3704           if (channel_proxy_upstream(c, type, seq, ssh))
3705                     return 0;
3706         if (sshpkt_get_end(ssh) != 0)
3707                     ssh_packet_disconnect(ssh, "Invalid status confirm message");
3708           if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
3709                     return 0;
3710           cc->cb(ssh, type, c, cc->ctx);
3711           TAILQ_REMOVE(&c->status_confirms, cc, entry);
3712           freezero(cc, sizeof(*cc));
3713           return 0;
3714 }
3715 
3716 /* -- tcp forwarding */
3717 
3718 void
channel_set_af(struct ssh * ssh,int af)3719 channel_set_af(struct ssh *ssh, int af)
3720 {
3721           ssh->chanctxt->IPv4or6 = af;
3722 }
3723 
3724 void
channel_set_hpn(int external_hpn_disabled,int external_hpn_buffer_size)3725 channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size)
3726 {
3727           hpn_disabled = external_hpn_disabled;
3728           hpn_buffer_size = external_hpn_buffer_size;
3729           debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, hpn_buffer_size);
3730 }
3731 
3732 /*
3733  * Determine whether or not a port forward listens to loopback, the
3734  * specified address or wildcard. On the client, a specified bind
3735  * address will always override gateway_ports. On the server, a
3736  * gateway_ports of 1 (``yes'') will override the client's specification
3737  * and force a wildcard bind, whereas a value of 2 (``clientspecified'')
3738  * will bind to whatever address the client asked for.
3739  *
3740  * Special-case listen_addrs are:
3741  *
3742  * "0.0.0.0"               -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
3743  * "" (empty string), "*"  -> wildcard v4/v6
3744  * "localhost"             -> loopback v4/v6
3745  * "127.0.0.1" / "::1"     -> accepted even if gateway_ports isn't set
3746  */
3747 static const char *
channel_fwd_bind_addr(struct ssh * ssh,const char * listen_addr,int * wildcardp,int is_client,struct ForwardOptions * fwd_opts)3748 channel_fwd_bind_addr(struct ssh *ssh, const char *listen_addr, int *wildcardp,
3749     int is_client, struct ForwardOptions *fwd_opts)
3750 {
3751           const char *addr = NULL;
3752           int wildcard = 0;
3753 
3754           if (listen_addr == NULL) {
3755                     /* No address specified: default to gateway_ports setting */
3756                     if (fwd_opts->gateway_ports)
3757                               wildcard = 1;
3758           } else if (fwd_opts->gateway_ports || is_client) {
3759                     if (((ssh->compat & SSH_OLD_FORWARD_ADDR) &&
3760                         strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
3761                         *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
3762                         (!is_client && fwd_opts->gateway_ports == 1)) {
3763                               wildcard = 1;
3764                               /*
3765                                * Notify client if they requested a specific listen
3766                                * address and it was overridden.
3767                                */
3768                               if (*listen_addr != '\0' &&
3769                                   strcmp(listen_addr, "0.0.0.0") != 0 &&
3770                                   strcmp(listen_addr, "*") != 0) {
3771                                         ssh_packet_send_debug(ssh,
3772                                             "Forwarding listen address "
3773                                             "\"%s\" overridden by server "
3774                                             "GatewayPorts", listen_addr);
3775                               }
3776                     } else if (strcmp(listen_addr, "localhost") != 0 ||
3777                         strcmp(listen_addr, "127.0.0.1") == 0 ||
3778                         strcmp(listen_addr, "::1") == 0) {
3779                               /*
3780                                * Accept explicit localhost address when
3781                                * GatewayPorts=yes. The "localhost" hostname is
3782                                * deliberately skipped here so it will listen on all
3783                                * available local address families.
3784                                */
3785                               addr = listen_addr;
3786                     }
3787           } else if (strcmp(listen_addr, "127.0.0.1") == 0 ||
3788               strcmp(listen_addr, "::1") == 0) {
3789                     /*
3790                      * If a specific IPv4/IPv6 localhost address has been
3791                      * requested then accept it even if gateway_ports is in
3792                      * effect. This allows the client to prefer IPv4 or IPv6.
3793                      */
3794                     addr = listen_addr;
3795           }
3796           if (wildcardp != NULL)
3797                     *wildcardp = wildcard;
3798           return addr;
3799 }
3800 
3801 static int
channel_setup_fwd_listener_tcpip(struct ssh * ssh,int type,struct Forward * fwd,int * allocated_listen_port,struct ForwardOptions * fwd_opts)3802 channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
3803     struct Forward *fwd, int *allocated_listen_port,
3804     struct ForwardOptions *fwd_opts)
3805 {
3806           Channel *c;
3807           int sock, r, success = 0, wildcard = 0, is_client;
3808           struct addrinfo hints, *ai, *aitop;
3809           const char *host, *addr;
3810           char ntop[NI_MAXHOST], strport[NI_MAXSERV];
3811           in_port_t *lport_p;
3812 
3813           is_client = (type == SSH_CHANNEL_PORT_LISTENER);
3814 
3815           if (is_client && fwd->connect_path != NULL) {
3816                     host = fwd->connect_path;
3817           } else {
3818                     host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
3819                         fwd->listen_host : fwd->connect_host;
3820                     if (host == NULL) {
3821                               error("No forward host name.");
3822                               return 0;
3823                     }
3824                     if (strlen(host) >= NI_MAXHOST) {
3825                               error("Forward host name too long.");
3826                               return 0;
3827                     }
3828           }
3829 
3830           /* Determine the bind address, cf. channel_fwd_bind_addr() comment */
3831           addr = channel_fwd_bind_addr(ssh, fwd->listen_host, &wildcard,
3832               is_client, fwd_opts);
3833           debug3_f("type %d wildcard %d addr %s", type, wildcard,
3834               (addr == NULL) ? "NULL" : addr);
3835 
3836           /*
3837            * getaddrinfo returns a loopback address if the hostname is
3838            * set to NULL and hints.ai_flags is not AI_PASSIVE
3839            */
3840           memset(&hints, 0, sizeof(hints));
3841           hints.ai_family = ssh->chanctxt->IPv4or6;
3842           hints.ai_flags = wildcard ? AI_PASSIVE : 0;
3843           hints.ai_socktype = SOCK_STREAM;
3844           snprintf(strport, sizeof strport, "%d", fwd->listen_port);
3845           if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
3846                     if (addr == NULL) {
3847                               /* This really shouldn't happen */
3848                               ssh_packet_disconnect(ssh, "getaddrinfo: fatal error: %s",
3849                                   ssh_gai_strerror(r));
3850                     } else {
3851                               error_f("getaddrinfo(%.64s): %s", addr,
3852                                   ssh_gai_strerror(r));
3853                     }
3854                     return 0;
3855           }
3856           if (allocated_listen_port != NULL)
3857                     *allocated_listen_port = 0;
3858           for (ai = aitop; ai; ai = ai->ai_next) {
3859                     switch (ai->ai_family) {
3860                     case AF_INET:
3861                               lport_p = &((struct sockaddr_in *)ai->ai_addr)->
3862                                   sin_port;
3863                               break;
3864                     case AF_INET6:
3865                               lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->
3866                                   sin6_port;
3867                               break;
3868                     default:
3869                               continue;
3870                     }
3871                     /*
3872                      * If allocating a port for -R forwards, then use the
3873                      * same port for all address families.
3874                      */
3875                     if (type == SSH_CHANNEL_RPORT_LISTENER &&
3876                         fwd->listen_port == 0 && allocated_listen_port != NULL &&
3877                         *allocated_listen_port > 0)
3878                               *lport_p = htons(*allocated_listen_port);
3879 
3880                     if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
3881                         strport, sizeof(strport),
3882                         NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
3883                               error_f("getnameinfo failed");
3884                               continue;
3885                     }
3886                     /* Create a port to listen for the host. */
3887                     sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
3888                     if (sock == -1) {
3889                               /* this is no error since kernel may not support ipv6 */
3890                               verbose("socket [%s]:%s: %.100s", ntop, strport,
3891                                   strerror(errno));
3892                               continue;
3893                     }
3894 
3895                     set_reuseaddr(sock);
3896 
3897                     debug("Local forwarding listening on %s port %s.",
3898                         ntop, strport);
3899 
3900                     /* Bind the socket to the address. */
3901                     if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
3902                               /*
3903                                * address can be in if use ipv6 address is
3904                                * already bound
3905                                */
3906                               verbose("bind [%s]:%s: %.100s",
3907                                   ntop, strport, strerror(errno));
3908                               close(sock);
3909                               continue;
3910                     }
3911                     /* Start listening for connections on the socket. */
3912                     if (listen(sock, SSH_LISTEN_BACKLOG) == -1) {
3913                               error("listen [%s]:%s: %.100s", ntop, strport,
3914                                   strerror(errno));
3915                               close(sock);
3916                               continue;
3917                     }
3918 
3919                     /*
3920                      * fwd->listen_port == 0 requests a dynamically allocated port -
3921                      * record what we got.
3922                      */
3923                     if (type == SSH_CHANNEL_RPORT_LISTENER &&
3924                         fwd->listen_port == 0 &&
3925                         allocated_listen_port != NULL &&
3926                         *allocated_listen_port == 0) {
3927                               *allocated_listen_port = get_local_port(sock);
3928                               debug("Allocated listen port %d",
3929                                   *allocated_listen_port);
3930                     }
3931 
3932                     /* Allocate a channel number for the socket. */
3933                     /* explicitly test for hpn disabled option. if true use smaller window size */
3934                     if (hpn_disabled)
3935                     c = channel_new(ssh, "port-listener", type, sock, sock, -1,
3936                         CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
3937                         0, "port listener", 1);
3938                     else
3939                               c = channel_new(ssh, "port listener", type, sock, sock,
3940                                 -1, hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
3941                                 0, "port listener", 1);
3942                     c->path = xstrdup(host);
3943                     c->host_port = fwd->connect_port;
3944                     c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
3945                     if (fwd->listen_port == 0 && allocated_listen_port != NULL &&
3946                         !(ssh->compat & SSH_BUG_DYNAMIC_RPORT))
3947                               c->listening_port = *allocated_listen_port;
3948                     else
3949                               c->listening_port = fwd->listen_port;
3950                     success = 1;
3951           }
3952           if (success == 0)
3953                     error_f("cannot listen to port: %d", fwd->listen_port);
3954           freeaddrinfo(aitop);
3955           return success;
3956 }
3957 
3958 static int
channel_setup_fwd_listener_streamlocal(struct ssh * ssh,int type,struct Forward * fwd,struct ForwardOptions * fwd_opts)3959 channel_setup_fwd_listener_streamlocal(struct ssh *ssh, int type,
3960     struct Forward *fwd, struct ForwardOptions *fwd_opts)
3961 {
3962           struct sockaddr_un sunaddr;
3963           const char *path;
3964           Channel *c;
3965           int port, sock;
3966           mode_t omask;
3967 
3968           switch (type) {
3969           case SSH_CHANNEL_UNIX_LISTENER:
3970                     if (fwd->connect_path != NULL) {
3971                               if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) {
3972                                         error("Local connecting path too long: %s",
3973                                             fwd->connect_path);
3974                                         return 0;
3975                               }
3976                               path = fwd->connect_path;
3977                               port = PORT_STREAMLOCAL;
3978                     } else {
3979                               if (fwd->connect_host == NULL) {
3980                                         error("No forward host name.");
3981                                         return 0;
3982                               }
3983                               if (strlen(fwd->connect_host) >= NI_MAXHOST) {
3984                                         error("Forward host name too long.");
3985                                         return 0;
3986                               }
3987                               path = fwd->connect_host;
3988                               port = fwd->connect_port;
3989                     }
3990                     break;
3991           case SSH_CHANNEL_RUNIX_LISTENER:
3992                     path = fwd->listen_path;
3993                     port = PORT_STREAMLOCAL;
3994                     break;
3995           default:
3996                     error_f("unexpected channel type %d", type);
3997                     return 0;
3998           }
3999 
4000           if (fwd->listen_path == NULL) {
4001                     error("No forward path name.");
4002                     return 0;
4003           }
4004           if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) {
4005                     error("Local listening path too long: %s", fwd->listen_path);
4006                     return 0;
4007           }
4008 
4009           debug3_f("type %d path %s", type, fwd->listen_path);
4010 
4011           /* Start a Unix domain listener. */
4012           omask = umask(fwd_opts->streamlocal_bind_mask);
4013           sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG,
4014               fwd_opts->streamlocal_bind_unlink);
4015           umask(omask);
4016           if (sock < 0)
4017                     return 0;
4018 
4019           debug("Local forwarding listening on path %s.", fwd->listen_path);
4020 
4021           /* Allocate a channel number for the socket. */
4022           c = channel_new(ssh, "unix-listener", type, sock, sock, -1,
4023               CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
4024               0, "unix listener", 1);
4025           c->path = xstrdup(path);
4026           c->host_port = port;
4027           c->listening_port = PORT_STREAMLOCAL;
4028           c->listening_addr = xstrdup(fwd->listen_path);
4029           return 1;
4030 }
4031 
4032 static int
channel_cancel_rport_listener_tcpip(struct ssh * ssh,const char * host,u_short port)4033 channel_cancel_rport_listener_tcpip(struct ssh *ssh,
4034     const char *host, u_short port)
4035 {
4036           u_int i;
4037           int found = 0;
4038 
4039           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
4040                     Channel *c = ssh->chanctxt->channels[i];
4041                     if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)
4042                               continue;
4043                     if (strcmp(c->path, host) == 0 && c->listening_port == port) {
4044                               debug2_f("close channel %d", i);
4045                               channel_free(ssh, c);
4046                               found = 1;
4047                     }
4048           }
4049 
4050           return found;
4051 }
4052 
4053 static int
channel_cancel_rport_listener_streamlocal(struct ssh * ssh,const char * path)4054 channel_cancel_rport_listener_streamlocal(struct ssh *ssh, const char *path)
4055 {
4056           u_int i;
4057           int found = 0;
4058 
4059           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
4060                     Channel *c = ssh->chanctxt->channels[i];
4061                     if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER)
4062                               continue;
4063                     if (c->path == NULL)
4064                               continue;
4065                     if (strcmp(c->path, path) == 0) {
4066                               debug2_f("close channel %d", i);
4067                               channel_free(ssh, c);
4068                               found = 1;
4069                     }
4070           }
4071 
4072           return found;
4073 }
4074 
4075 int
channel_cancel_rport_listener(struct ssh * ssh,struct Forward * fwd)4076 channel_cancel_rport_listener(struct ssh *ssh, struct Forward *fwd)
4077 {
4078           if (fwd->listen_path != NULL) {
4079                     return channel_cancel_rport_listener_streamlocal(ssh,
4080                         fwd->listen_path);
4081           } else {
4082                     return channel_cancel_rport_listener_tcpip(ssh,
4083                         fwd->listen_host, fwd->listen_port);
4084           }
4085 }
4086 
4087 static int
channel_cancel_lport_listener_tcpip(struct ssh * ssh,const char * lhost,u_short lport,int cport,struct ForwardOptions * fwd_opts)4088 channel_cancel_lport_listener_tcpip(struct ssh *ssh,
4089     const char *lhost, u_short lport, int cport,
4090     struct ForwardOptions *fwd_opts)
4091 {
4092           u_int i;
4093           int found = 0;
4094           const char *addr = channel_fwd_bind_addr(ssh, lhost, NULL, 1, fwd_opts);
4095 
4096           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
4097                     Channel *c = ssh->chanctxt->channels[i];
4098                     if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER)
4099                               continue;
4100                     if (c->listening_port != lport)
4101                               continue;
4102                     if (cport == CHANNEL_CANCEL_PORT_STATIC) {
4103                               /* skip dynamic forwardings */
4104                               if (c->host_port == 0)
4105                                         continue;
4106                     } else {
4107                               if (c->host_port != cport)
4108                                         continue;
4109                     }
4110                     if ((c->listening_addr == NULL && addr != NULL) ||
4111                         (c->listening_addr != NULL && addr == NULL))
4112                               continue;
4113                     if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {
4114                               debug2_f("close channel %d", i);
4115                               channel_free(ssh, c);
4116                               found = 1;
4117                     }
4118           }
4119 
4120           return found;
4121 }
4122 
4123 static int
channel_cancel_lport_listener_streamlocal(struct ssh * ssh,const char * path)4124 channel_cancel_lport_listener_streamlocal(struct ssh *ssh, const char *path)
4125 {
4126           u_int i;
4127           int found = 0;
4128 
4129           if (path == NULL) {
4130                     error_f("no path specified.");
4131                     return 0;
4132           }
4133 
4134           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
4135                     Channel *c = ssh->chanctxt->channels[i];
4136                     if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER)
4137                               continue;
4138                     if (c->listening_addr == NULL)
4139                               continue;
4140                     if (strcmp(c->listening_addr, path) == 0) {
4141                               debug2_f("close channel %d", i);
4142                               channel_free(ssh, c);
4143                               found = 1;
4144                     }
4145           }
4146 
4147           return found;
4148 }
4149 
4150 int
channel_cancel_lport_listener(struct ssh * ssh,struct Forward * fwd,int cport,struct ForwardOptions * fwd_opts)4151 channel_cancel_lport_listener(struct ssh *ssh,
4152     struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts)
4153 {
4154           if (fwd->listen_path != NULL) {
4155                     return channel_cancel_lport_listener_streamlocal(ssh,
4156                         fwd->listen_path);
4157           } else {
4158                     return channel_cancel_lport_listener_tcpip(ssh,
4159                         fwd->listen_host, fwd->listen_port, cport, fwd_opts);
4160           }
4161 }
4162 
4163 /* protocol local port fwd, used by ssh */
4164 int
channel_setup_local_fwd_listener(struct ssh * ssh,struct Forward * fwd,struct ForwardOptions * fwd_opts)4165 channel_setup_local_fwd_listener(struct ssh *ssh,
4166     struct Forward *fwd, struct ForwardOptions *fwd_opts)
4167 {
4168           if (fwd->listen_path != NULL) {
4169                     return channel_setup_fwd_listener_streamlocal(ssh,
4170                         SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts);
4171           } else {
4172                     return channel_setup_fwd_listener_tcpip(ssh,
4173                         SSH_CHANNEL_PORT_LISTENER, fwd, NULL, fwd_opts);
4174           }
4175 }
4176 
4177 /* Matches a remote forwarding permission against a requested forwarding */
4178 static int
remote_open_match(struct permission * allowed_open,struct Forward * fwd)4179 remote_open_match(struct permission *allowed_open, struct Forward *fwd)
4180 {
4181           int ret;
4182           char *lhost;
4183 
4184           /* XXX add ACLs for streamlocal */
4185           if (fwd->listen_path != NULL)
4186                     return 1;
4187 
4188           if (fwd->listen_host == NULL || allowed_open->listen_host == NULL)
4189                     return 0;
4190 
4191           if (allowed_open->listen_port != FWD_PERMIT_ANY_PORT &&
4192               allowed_open->listen_port != fwd->listen_port)
4193                     return 0;
4194 
4195           /* Match hostnames case-insensitively */
4196           lhost = xstrdup(fwd->listen_host);
4197           lowercase(lhost);
4198           ret = match_pattern(lhost, allowed_open->listen_host);
4199           free(lhost);
4200 
4201           return ret;
4202 }
4203 
4204 /* Checks whether a requested remote forwarding is permitted */
4205 static int
check_rfwd_permission(struct ssh * ssh,struct Forward * fwd)4206 check_rfwd_permission(struct ssh *ssh, struct Forward *fwd)
4207 {
4208           struct ssh_channels *sc = ssh->chanctxt;
4209           struct permission_set *pset = &sc->remote_perms;
4210           u_int i, permit, permit_adm = 1;
4211           struct permission *perm;
4212 
4213           /* XXX apply GatewayPorts override before checking? */
4214 
4215           permit = pset->all_permitted;
4216           if (!permit) {
4217                     for (i = 0; i < pset->num_permitted_user; i++) {
4218                               perm = &pset->permitted_user[i];
4219                               if (remote_open_match(perm, fwd)) {
4220                                         permit = 1;
4221                                         break;
4222                               }
4223                     }
4224           }
4225 
4226           if (pset->num_permitted_admin > 0) {
4227                     permit_adm = 0;
4228                     for (i = 0; i < pset->num_permitted_admin; i++) {
4229                               perm = &pset->permitted_admin[i];
4230                               if (remote_open_match(perm, fwd)) {
4231                                         permit_adm = 1;
4232                                         break;
4233                               }
4234                     }
4235           }
4236 
4237           return permit && permit_adm;
4238 }
4239 
4240 /* protocol v2 remote port fwd, used by sshd */
4241 int
channel_setup_remote_fwd_listener(struct ssh * ssh,struct Forward * fwd,int * allocated_listen_port,struct ForwardOptions * fwd_opts)4242 channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,
4243     int *allocated_listen_port, struct ForwardOptions *fwd_opts)
4244 {
4245           if (!check_rfwd_permission(ssh, fwd)) {
4246                     ssh_packet_send_debug(ssh, "port forwarding refused");
4247                     if (fwd->listen_path != NULL)
4248                               /* XXX always allowed, see remote_open_match() */
4249                               logit("Received request from %.100s port %d to "
4250                                   "remote forward to path \"%.100s\", "
4251                                   "but the request was denied.",
4252                                   ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
4253                                   fwd->listen_path);
4254                     else if(fwd->listen_host != NULL)
4255                               logit("Received request from %.100s port %d to "
4256                                   "remote forward to host %.100s port %d, "
4257                                   "but the request was denied.",
4258                                   ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
4259                                   fwd->listen_host, fwd->listen_port );
4260                     else
4261                               logit("Received request from %.100s port %d to remote "
4262                                   "forward, but the request was denied.",
4263                                   ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
4264                     return 0;
4265           }
4266           if (fwd->listen_path != NULL) {
4267                     return channel_setup_fwd_listener_streamlocal(ssh,
4268                         SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts);
4269           } else {
4270                     return channel_setup_fwd_listener_tcpip(ssh,
4271                         SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port,
4272                         fwd_opts);
4273           }
4274 }
4275 
4276 /*
4277  * Translate the requested rfwd listen host to something usable for
4278  * this server.
4279  */
4280 static const char *
channel_rfwd_bind_host(const char * listen_host)4281 channel_rfwd_bind_host(const char *listen_host)
4282 {
4283           if (listen_host == NULL) {
4284                     return "localhost";
4285           } else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) {
4286                     return "";
4287           } else
4288                     return listen_host;
4289 }
4290 
4291 /*
4292  * Initiate forwarding of connections to port "port" on remote host through
4293  * the secure channel to host:port from local side.
4294  * Returns handle (index) for updating the dynamic listen port with
4295  * channel_update_permission().
4296  */
4297 int
channel_request_remote_forwarding(struct ssh * ssh,struct Forward * fwd)4298 channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd)
4299 {
4300           int r, success = 0, idx = -1;
4301           const char *host_to_connect, *listen_host, *listen_path;
4302           int port_to_connect, listen_port;
4303 
4304           /* Send the forward request to the remote side. */
4305           if (fwd->listen_path != NULL) {
4306                     if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
4307                         (r = sshpkt_put_cstring(ssh,
4308                         "streamlocal-forward@openssh.com")) != 0 ||
4309                         (r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
4310                         (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 ||
4311                         (r = sshpkt_send(ssh)) != 0 ||
4312                         (r = ssh_packet_write_wait(ssh)) < 0)
4313                               fatal_fr(r, "request streamlocal");
4314           } else {
4315                     if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
4316                         (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 ||
4317                         (r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
4318                         (r = sshpkt_put_cstring(ssh,
4319                         channel_rfwd_bind_host(fwd->listen_host))) != 0 ||
4320                         (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 ||
4321                         (r = sshpkt_send(ssh)) != 0 ||
4322                         (r = ssh_packet_write_wait(ssh)) < 0)
4323                               fatal_fr(r, "request tcpip-forward");
4324           }
4325           /* Assume that server accepts the request */
4326           success = 1;
4327           if (success) {
4328                     /* Record that connection to this host/port is permitted. */
4329                     host_to_connect = listen_host = listen_path = NULL;
4330                     port_to_connect = listen_port = 0;
4331                     if (fwd->connect_path != NULL) {
4332                               host_to_connect = fwd->connect_path;
4333                               port_to_connect = PORT_STREAMLOCAL;
4334                     } else {
4335                               host_to_connect = fwd->connect_host;
4336                               port_to_connect = fwd->connect_port;
4337                     }
4338                     if (fwd->listen_path != NULL) {
4339                               listen_path = fwd->listen_path;
4340                               listen_port = PORT_STREAMLOCAL;
4341                     } else {
4342                               listen_host = fwd->listen_host;
4343                               listen_port = fwd->listen_port;
4344                     }
4345                     idx = permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL,
4346                         host_to_connect, port_to_connect,
4347                         listen_host, listen_path, listen_port, NULL);
4348           }
4349           return idx;
4350 }
4351 
4352 static int
open_match(struct permission * allowed_open,const char * requestedhost,int requestedport)4353 open_match(struct permission *allowed_open, const char *requestedhost,
4354     int requestedport)
4355 {
4356           if (allowed_open->host_to_connect == NULL)
4357                     return 0;
4358           if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT &&
4359               allowed_open->port_to_connect != requestedport)
4360                     return 0;
4361           if (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 &&
4362               strcmp(allowed_open->host_to_connect, requestedhost) != 0)
4363                     return 0;
4364           return 1;
4365 }
4366 
4367 /*
4368  * Note that in the listen host/port case
4369  * we don't support FWD_PERMIT_ANY_PORT and
4370  * need to translate between the configured-host (listen_host)
4371  * and what we've sent to the remote server (channel_rfwd_bind_host)
4372  */
4373 static int
open_listen_match_tcpip(struct permission * allowed_open,const char * requestedhost,u_short requestedport,int translate)4374 open_listen_match_tcpip(struct permission *allowed_open,
4375     const char *requestedhost, u_short requestedport, int translate)
4376 {
4377           const char *allowed_host;
4378 
4379           if (allowed_open->host_to_connect == NULL)
4380                     return 0;
4381           if (allowed_open->listen_port != requestedport)
4382                     return 0;
4383           if (!translate && allowed_open->listen_host == NULL &&
4384               requestedhost == NULL)
4385                     return 1;
4386           allowed_host = translate ?
4387               channel_rfwd_bind_host(allowed_open->listen_host) :
4388               allowed_open->listen_host;
4389           if (allowed_host == NULL || requestedhost == NULL ||
4390               strcmp(allowed_host, requestedhost) != 0)
4391                     return 0;
4392           return 1;
4393 }
4394 
4395 static int
open_listen_match_streamlocal(struct permission * allowed_open,const char * requestedpath)4396 open_listen_match_streamlocal(struct permission *allowed_open,
4397     const char *requestedpath)
4398 {
4399           if (allowed_open->host_to_connect == NULL)
4400                     return 0;
4401           if (allowed_open->listen_port != PORT_STREAMLOCAL)
4402                     return 0;
4403           if (allowed_open->listen_path == NULL ||
4404               strcmp(allowed_open->listen_path, requestedpath) != 0)
4405                     return 0;
4406           return 1;
4407 }
4408 
4409 /*
4410  * Request cancellation of remote forwarding of connection host:port from
4411  * local side.
4412  */
4413 static int
channel_request_rforward_cancel_tcpip(struct ssh * ssh,const char * host,u_short port)4414 channel_request_rforward_cancel_tcpip(struct ssh *ssh,
4415     const char *host, u_short port)
4416 {
4417           struct ssh_channels *sc = ssh->chanctxt;
4418           struct permission_set *pset = &sc->local_perms;
4419           int r;
4420           u_int i;
4421           struct permission *perm = NULL;
4422 
4423           for (i = 0; i < pset->num_permitted_user; i++) {
4424                     perm = &pset->permitted_user[i];
4425                     if (open_listen_match_tcpip(perm, host, port, 0))
4426                               break;
4427                     perm = NULL;
4428           }
4429           if (perm == NULL) {
4430                     debug_f("requested forward not found");
4431                     return -1;
4432           }
4433           if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
4434               (r = sshpkt_put_cstring(ssh, "cancel-tcpip-forward")) != 0 ||
4435               (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
4436               (r = sshpkt_put_cstring(ssh, channel_rfwd_bind_host(host))) != 0 ||
4437               (r = sshpkt_put_u32(ssh, port)) != 0 ||
4438               (r = sshpkt_send(ssh)) != 0)
4439                     fatal_fr(r, "send cancel");
4440 
4441           fwd_perm_clear(perm); /* unregister */
4442 
4443           return 0;
4444 }
4445 
4446 /*
4447  * Request cancellation of remote forwarding of Unix domain socket
4448  * path from local side.
4449  */
4450 static int
channel_request_rforward_cancel_streamlocal(struct ssh * ssh,const char * path)4451 channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
4452 {
4453           struct ssh_channels *sc = ssh->chanctxt;
4454           struct permission_set *pset = &sc->local_perms;
4455           int r;
4456           u_int i;
4457           struct permission *perm = NULL;
4458 
4459           for (i = 0; i < pset->num_permitted_user; i++) {
4460                     perm = &pset->permitted_user[i];
4461                     if (open_listen_match_streamlocal(perm, path))
4462                               break;
4463                     perm = NULL;
4464           }
4465           if (perm == NULL) {
4466                     debug_f("requested forward not found");
4467                     return -1;
4468           }
4469           if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
4470               (r = sshpkt_put_cstring(ssh,
4471               "cancel-streamlocal-forward@openssh.com")) != 0 ||
4472               (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
4473               (r = sshpkt_put_cstring(ssh, path)) != 0 ||
4474               (r = sshpkt_send(ssh)) != 0)
4475                     fatal_fr(r, "send cancel");
4476 
4477           fwd_perm_clear(perm); /* unregister */
4478 
4479           return 0;
4480 }
4481 
4482 /*
4483  * Request cancellation of remote forwarding of a connection from local side.
4484  */
4485 int
channel_request_rforward_cancel(struct ssh * ssh,struct Forward * fwd)4486 channel_request_rforward_cancel(struct ssh *ssh, struct Forward *fwd)
4487 {
4488           if (fwd->listen_path != NULL) {
4489                     return channel_request_rforward_cancel_streamlocal(ssh,
4490                         fwd->listen_path);
4491           } else {
4492                     return channel_request_rforward_cancel_tcpip(ssh,
4493                         fwd->listen_host,
4494                         fwd->listen_port ? fwd->listen_port : fwd->allocated_port);
4495           }
4496 }
4497 
4498 /*
4499  * Permits opening to any host/port if permitted_user[] is empty.  This is
4500  * usually called by the server, because the user could connect to any port
4501  * anyway, and the server has no way to know but to trust the client anyway.
4502  */
4503 void
channel_permit_all(struct ssh * ssh,int where)4504 channel_permit_all(struct ssh *ssh, int where)
4505 {
4506           struct permission_set *pset = permission_set_get(ssh, where);
4507 
4508           if (pset->num_permitted_user == 0)
4509                     pset->all_permitted = 1;
4510 }
4511 
4512 /*
4513  * Permit the specified host/port for forwarding.
4514  */
4515 void
channel_add_permission(struct ssh * ssh,int who,int where,char * host,int port)4516 channel_add_permission(struct ssh *ssh, int who, int where,
4517     char *host, int port)
4518 {
4519           int local = where == FORWARD_LOCAL;
4520           struct permission_set *pset = permission_set_get(ssh, where);
4521 
4522           debug("allow %s forwarding to host %s port %d",
4523               fwd_ident(who, where), host, port);
4524           /*
4525            * Remote forwards set listen_host/port, local forwards set
4526            * host/port_to_connect.
4527            */
4528           permission_set_add(ssh, who, where,
4529               local ? host : 0, local ? port : 0,
4530               local ? NULL : host, NULL, local ? 0 : port, NULL);
4531           pset->all_permitted = 0;
4532 }
4533 
4534 /*
4535  * Administratively disable forwarding.
4536  */
4537 void
channel_disable_admin(struct ssh * ssh,int where)4538 channel_disable_admin(struct ssh *ssh, int where)
4539 {
4540           channel_clear_permission(ssh, FORWARD_ADM, where);
4541           permission_set_add(ssh, FORWARD_ADM, where,
4542               NULL, 0, NULL, NULL, 0, NULL);
4543 }
4544 
4545 /*
4546  * Clear a list of permitted opens.
4547  */
4548 void
channel_clear_permission(struct ssh * ssh,int who,int where)4549 channel_clear_permission(struct ssh *ssh, int who, int where)
4550 {
4551           struct permission **permp;
4552           u_int *npermp;
4553 
4554           permission_set_get_array(ssh, who, where, &permp, &npermp);
4555           *permp = xrecallocarray(*permp, *npermp, 0, sizeof(**permp));
4556           *npermp = 0;
4557 }
4558 
4559 /*
4560  * Update the listen port for a dynamic remote forward, after
4561  * the actual 'newport' has been allocated. If 'newport' < 0 is
4562  * passed then they entry will be invalidated.
4563  */
4564 void
channel_update_permission(struct ssh * ssh,int idx,int newport)4565 channel_update_permission(struct ssh *ssh, int idx, int newport)
4566 {
4567           struct permission_set *pset = &ssh->chanctxt->local_perms;
4568 
4569           if (idx < 0 || (u_int)idx >= pset->num_permitted_user) {
4570                     debug_f("index out of range: %d num_permitted_user %d",
4571                         idx, pset->num_permitted_user);
4572                     return;
4573           }
4574           debug("%s allowed port %d for forwarding to host %s port %d",
4575               newport > 0 ? "Updating" : "Removing",
4576               newport,
4577               pset->permitted_user[idx].host_to_connect,
4578               pset->permitted_user[idx].port_to_connect);
4579           if (newport <= 0)
4580                     fwd_perm_clear(&pset->permitted_user[idx]);
4581           else {
4582                     pset->permitted_user[idx].listen_port =
4583                         (ssh->compat & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
4584           }
4585 }
4586 
4587 /* Try to start non-blocking connect to next host in cctx list */
4588 static int
connect_next(struct channel_connect * cctx)4589 connect_next(struct channel_connect *cctx)
4590 {
4591           int sock, saved_errno;
4592           struct sockaddr_un *sunaddr;
4593           char ntop[NI_MAXHOST];
4594           char strport[MAXIMUM(NI_MAXSERV, sizeof(sunaddr->sun_path))];
4595 
4596           for (; cctx->ai; cctx->ai = cctx->ai->ai_next) {
4597                     switch (cctx->ai->ai_family) {
4598                     case AF_UNIX:
4599                               /* unix:pathname instead of host:port */
4600                               sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr;
4601                               strlcpy(ntop, "unix", sizeof(ntop));
4602                               strlcpy(strport, sunaddr->sun_path, sizeof(strport));
4603                               break;
4604                     case AF_INET:
4605                     case AF_INET6:
4606                               if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen,
4607                                   ntop, sizeof(ntop), strport, sizeof(strport),
4608                                   NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
4609                                         error_f("getnameinfo failed");
4610                                         continue;
4611                               }
4612                               break;
4613                     default:
4614                               continue;
4615                     }
4616                     debug_f("start for host %.100s ([%.100s]:%s)",
4617                         cctx->host, ntop, strport);
4618                     if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype,
4619                         cctx->ai->ai_protocol)) == -1) {
4620                               if (cctx->ai->ai_next == NULL)
4621                                         error("socket: %.100s", strerror(errno));
4622                               else
4623                                         verbose("socket: %.100s", strerror(errno));
4624                               continue;
4625                     }
4626                     if (set_nonblock(sock) == -1)
4627                               fatal_f("set_nonblock(%d)", sock);
4628                     if (connect(sock, cctx->ai->ai_addr,
4629                         cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {
4630                               debug_f("host %.100s ([%.100s]:%s): %.100s",
4631                                   cctx->host, ntop, strport, strerror(errno));
4632                               saved_errno = errno;
4633                               close(sock);
4634                               errno = saved_errno;
4635                               continue; /* fail -- try next */
4636                     }
4637                     if (cctx->ai->ai_family != AF_UNIX)
4638                               set_nodelay(sock);
4639                     debug_f("connect host %.100s ([%.100s]:%s) in progress, fd=%d",
4640                         cctx->host, ntop, strport, sock);
4641                     cctx->ai = cctx->ai->ai_next;
4642                     return sock;
4643           }
4644           return -1;
4645 }
4646 
4647 static void
channel_connect_ctx_free(struct channel_connect * cctx)4648 channel_connect_ctx_free(struct channel_connect *cctx)
4649 {
4650           free(cctx->host);
4651           if (cctx->aitop) {
4652                     if (cctx->aitop->ai_family == AF_UNIX)
4653                               free(cctx->aitop);
4654                     else
4655                               freeaddrinfo(cctx->aitop);
4656           }
4657           memset(cctx, 0, sizeof(*cctx));
4658 }
4659 
4660 /*
4661  * Return connecting socket to remote host:port or local socket path,
4662  * passing back the failure reason if appropriate.
4663  */
4664 static int
connect_to_helper(struct ssh * ssh,const char * name,int port,int socktype,const char * ctype,const char * rname,struct channel_connect * cctx,int * reason,const char ** errmsg)4665 connect_to_helper(struct ssh *ssh, const char *name, int port, int socktype,
4666     const char *ctype, const char *rname, struct channel_connect *cctx,
4667     int *reason, const char **errmsg)
4668 {
4669           struct addrinfo hints;
4670           int gaierr;
4671           int sock = -1;
4672           char strport[NI_MAXSERV];
4673 
4674           if (port == PORT_STREAMLOCAL) {
4675                     struct sockaddr_un *sunaddr;
4676                     struct addrinfo *ai;
4677 
4678                     if (strlen(name) > sizeof(sunaddr->sun_path)) {
4679                               error("%.100s: %.100s", name, strerror(ENAMETOOLONG));
4680                               return -1;
4681                     }
4682 
4683                     /*
4684                      * Fake up a struct addrinfo for AF_UNIX connections.
4685                      * channel_connect_ctx_free() must check ai_family
4686                      * and use free() not freeaddirinfo() for AF_UNIX.
4687                      */
4688                     ai = xmalloc(sizeof(*ai) + sizeof(*sunaddr));
4689                     memset(ai, 0, sizeof(*ai) + sizeof(*sunaddr));
4690                     ai->ai_addr = (struct sockaddr *)(ai + 1);
4691                     ai->ai_addrlen = sizeof(*sunaddr);
4692                     ai->ai_family = AF_UNIX;
4693                     ai->ai_socktype = socktype;
4694                     ai->ai_protocol = PF_UNSPEC;
4695                     sunaddr = (struct sockaddr_un *)ai->ai_addr;
4696                     sunaddr->sun_family = AF_UNIX;
4697                     strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path));
4698                     cctx->aitop = ai;
4699           } else {
4700                     memset(&hints, 0, sizeof(hints));
4701                     hints.ai_family = ssh->chanctxt->IPv4or6;
4702                     hints.ai_socktype = socktype;
4703                     snprintf(strport, sizeof strport, "%d", port);
4704                     if ((gaierr = getaddrinfo(name, strport, &hints, &cctx->aitop))
4705                         != 0) {
4706                               if (errmsg != NULL)
4707                                         *errmsg = ssh_gai_strerror(gaierr);
4708                               if (reason != NULL)
4709                                         *reason = SSH2_OPEN_CONNECT_FAILED;
4710                               error("connect_to %.100s: unknown host (%s)", name,
4711                                   ssh_gai_strerror(gaierr));
4712                               return -1;
4713                     }
4714           }
4715 
4716           cctx->host = xstrdup(name);
4717           cctx->port = port;
4718           cctx->ai = cctx->aitop;
4719 
4720           if ((sock = connect_next(cctx)) == -1) {
4721                     error("connect to %.100s port %d failed: %s",
4722                         name, port, strerror(errno));
4723                     return -1;
4724           }
4725 
4726           return sock;
4727 }
4728 
4729 /* Return CONNECTING channel to remote host:port or local socket path */
4730 static Channel *
connect_to(struct ssh * ssh,const char * host,int port,const char * ctype,const char * rname)4731 connect_to(struct ssh *ssh, const char *host, int port,
4732     const char *ctype, const char *rname)
4733 {
4734           struct channel_connect cctx;
4735           Channel *c;
4736           int sock;
4737 
4738           memset(&cctx, 0, sizeof(cctx));
4739           sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,
4740               &cctx, NULL, NULL);
4741           if (sock == -1) {
4742                     channel_connect_ctx_free(&cctx);
4743                     return NULL;
4744           }
4745           c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,
4746               CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
4747           c->host_port = port;
4748           c->path = xstrdup(host);
4749           c->connect_ctx = cctx;
4750 
4751           return c;
4752 }
4753 
4754 /*
4755  * returns either the newly connected channel or the downstream channel
4756  * that needs to deal with this connection.
4757  */
4758 Channel *
channel_connect_by_listen_address(struct ssh * ssh,const char * listen_host,u_short listen_port,const char * ctype,const char * rname)4759 channel_connect_by_listen_address(struct ssh *ssh, const char *listen_host,
4760     u_short listen_port, const char *ctype, const char *rname)
4761 {
4762           struct ssh_channels *sc = ssh->chanctxt;
4763           struct permission_set *pset = &sc->local_perms;
4764           u_int i;
4765           struct permission *perm;
4766 
4767           for (i = 0; i < pset->num_permitted_user; i++) {
4768                     perm = &pset->permitted_user[i];
4769                     if (open_listen_match_tcpip(perm,
4770                         listen_host, listen_port, 1)) {
4771                               if (perm->downstream)
4772                                         return perm->downstream;
4773                               if (perm->port_to_connect == 0)
4774                                         return rdynamic_connect_prepare(ssh,
4775                                             ctype, rname);
4776                               return connect_to(ssh,
4777                                   perm->host_to_connect, perm->port_to_connect,
4778                                   ctype, rname);
4779                     }
4780           }
4781           error("WARNING: Server requests forwarding for unknown listen_port %d",
4782               listen_port);
4783           return NULL;
4784 }
4785 
4786 Channel *
channel_connect_by_listen_path(struct ssh * ssh,const char * path,const char * ctype,const char * rname)4787 channel_connect_by_listen_path(struct ssh *ssh, const char *path,
4788     const char *ctype, const char *rname)
4789 {
4790           struct ssh_channels *sc = ssh->chanctxt;
4791           struct permission_set *pset = &sc->local_perms;
4792           u_int i;
4793           struct permission *perm;
4794 
4795           for (i = 0; i < pset->num_permitted_user; i++) {
4796                     perm = &pset->permitted_user[i];
4797                     if (open_listen_match_streamlocal(perm, path)) {
4798                               return connect_to(ssh,
4799                                   perm->host_to_connect, perm->port_to_connect,
4800                                   ctype, rname);
4801                     }
4802           }
4803           error("WARNING: Server requests forwarding for unknown path %.100s",
4804               path);
4805           return NULL;
4806 }
4807 
4808 /* Check if connecting to that port is permitted and connect. */
4809 Channel *
channel_connect_to_port(struct ssh * ssh,const char * host,u_short port,const char * ctype,const char * rname,int * reason,const char ** errmsg)4810 channel_connect_to_port(struct ssh *ssh, const char *host, u_short port,
4811     const char *ctype, const char *rname, int *reason, const char **errmsg)
4812 {
4813           struct ssh_channels *sc = ssh->chanctxt;
4814           struct permission_set *pset = &sc->local_perms;
4815           struct channel_connect cctx;
4816           Channel *c;
4817           u_int i, permit, permit_adm = 1;
4818           int sock;
4819           struct permission *perm;
4820 
4821           permit = pset->all_permitted;
4822           if (!permit) {
4823                     for (i = 0; i < pset->num_permitted_user; i++) {
4824                               perm = &pset->permitted_user[i];
4825                               if (open_match(perm, host, port)) {
4826                                         permit = 1;
4827                                         break;
4828                               }
4829                     }
4830           }
4831 
4832           if (pset->num_permitted_admin > 0) {
4833                     permit_adm = 0;
4834                     for (i = 0; i < pset->num_permitted_admin; i++) {
4835                               perm = &pset->permitted_admin[i];
4836                               if (open_match(perm, host, port)) {
4837                                         permit_adm = 1;
4838                                         break;
4839                               }
4840                     }
4841           }
4842 
4843           if (!permit || !permit_adm) {
4844                     logit("Received request from %.100s port %d to connect to "
4845                         "host %.100s port %d, but the request was denied.",
4846                         ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), host, port);
4847                     if (reason != NULL)
4848                               *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
4849                     return NULL;
4850           }
4851 
4852           memset(&cctx, 0, sizeof(cctx));
4853           sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,
4854               &cctx, reason, errmsg);
4855           if (sock == -1) {
4856                     channel_connect_ctx_free(&cctx);
4857                     return NULL;
4858           }
4859 
4860           c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,
4861               CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
4862           c->host_port = port;
4863           c->path = xstrdup(host);
4864           c->connect_ctx = cctx;
4865 
4866           return c;
4867 }
4868 
4869 /* Check if connecting to that path is permitted and connect. */
4870 Channel *
channel_connect_to_path(struct ssh * ssh,const char * path,const char * ctype,const char * rname)4871 channel_connect_to_path(struct ssh *ssh, const char *path, const char *ctype,
4872     const char *rname)
4873 {
4874           struct ssh_channels *sc = ssh->chanctxt;
4875           struct permission_set *pset = &sc->local_perms;
4876           u_int i, permit, permit_adm = 1;
4877           struct permission *perm;
4878 
4879           permit = pset->all_permitted;
4880           if (!permit) {
4881                     for (i = 0; i < pset->num_permitted_user; i++) {
4882                               perm = &pset->permitted_user[i];
4883                               if (open_match(perm, path, PORT_STREAMLOCAL)) {
4884                                         permit = 1;
4885                                         break;
4886                               }
4887                     }
4888           }
4889 
4890           if (pset->num_permitted_admin > 0) {
4891                     permit_adm = 0;
4892                     for (i = 0; i < pset->num_permitted_admin; i++) {
4893                               perm = &pset->permitted_admin[i];
4894                               if (open_match(perm, path, PORT_STREAMLOCAL)) {
4895                                         permit_adm = 1;
4896                                         break;
4897                               }
4898                     }
4899           }
4900 
4901           if (!permit || !permit_adm) {
4902                     logit("Received request to connect to path %.100s, "
4903                         "but the request was denied.", path);
4904                     return NULL;
4905           }
4906           return connect_to(ssh, path, PORT_STREAMLOCAL, ctype, rname);
4907 }
4908 
4909 void
channel_send_window_changes(struct ssh * ssh)4910 channel_send_window_changes(struct ssh *ssh)
4911 {
4912           struct ssh_channels *sc = ssh->chanctxt;
4913           struct winsize ws;
4914           int r;
4915           u_int i;
4916 
4917           for (i = 0; i < sc->channels_alloc; i++) {
4918                     if (sc->channels[i] == NULL || !sc->channels[i]->client_tty ||
4919                         sc->channels[i]->type != SSH_CHANNEL_OPEN)
4920                               continue;
4921                     if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) == -1)
4922                               continue;
4923                     channel_request_start(ssh, i, "window-change", 0);
4924                     if ((r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
4925                         (r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
4926                         (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
4927                         (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0 ||
4928                         (r = sshpkt_send(ssh)) != 0)
4929                               fatal_fr(r, "channel %u; send window-change", i);
4930           }
4931 }
4932 
4933 /* Return RDYNAMIC_OPEN channel: channel allows SOCKS, but is not connected */
4934 static Channel *
rdynamic_connect_prepare(struct ssh * ssh,const char * ctype,const char * rname)4935 rdynamic_connect_prepare(struct ssh *ssh, const char *ctype, const char *rname)
4936 {
4937           Channel *c;
4938           int r;
4939 
4940           c = channel_new(ssh, ctype, SSH_CHANNEL_RDYNAMIC_OPEN, -1, -1, -1,
4941               CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
4942           c->host_port = 0;
4943           c->path = NULL;
4944 
4945           /*
4946            * We need to open the channel before we have a FD,
4947            * so that we can get SOCKS header from peer.
4948            */
4949           if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
4950               (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
4951               (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
4952               (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
4953               (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0)
4954                     fatal_fr(r, "channel %i; confirm", c->self);
4955           return c;
4956 }
4957 
4958 /* Return CONNECTING socket to remote host:port or local socket path */
4959 static int
rdynamic_connect_finish(struct ssh * ssh,Channel * c)4960 rdynamic_connect_finish(struct ssh *ssh, Channel *c)
4961 {
4962           struct ssh_channels *sc = ssh->chanctxt;
4963           struct permission_set *pset = &sc->local_perms;
4964           struct permission *perm;
4965           struct channel_connect cctx;
4966           u_int i, permit_adm = 1;
4967           int sock;
4968 
4969           if (pset->num_permitted_admin > 0) {
4970                     permit_adm = 0;
4971                     for (i = 0; i < pset->num_permitted_admin; i++) {
4972                               perm = &pset->permitted_admin[i];
4973                               if (open_match(perm, c->path, c->host_port)) {
4974                                         permit_adm = 1;
4975                                         break;
4976                               }
4977                     }
4978           }
4979           if (!permit_adm) {
4980                     debug_f("requested forward not permitted");
4981                     return -1;
4982           }
4983 
4984           memset(&cctx, 0, sizeof(cctx));
4985           sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL,
4986               NULL, &cctx, NULL, NULL);
4987           if (sock == -1)
4988                     channel_connect_ctx_free(&cctx);
4989           else {
4990                     /* similar to SSH_CHANNEL_CONNECTING but we've already sent the open */
4991                     c->type = SSH_CHANNEL_RDYNAMIC_FINISH;
4992                     c->connect_ctx = cctx;
4993                     channel_register_fds(ssh, c, sock, sock, -1, 0, 1, 0);
4994           }
4995           return sock;
4996 }
4997 
4998 /* -- X11 forwarding */
4999 
5000 /*
5001  * Creates an internet domain socket for listening for X11 connections.
5002  * Returns 0 and a suitable display number for the DISPLAY variable
5003  * stored in display_numberp , or -1 if an error occurs.
5004  */
5005 int
x11_create_display_inet(struct ssh * ssh,int x11_display_offset,int x11_use_localhost,int single_connection,u_int * display_numberp,int ** chanids)5006 x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
5007     int x11_use_localhost, int single_connection,
5008     u_int *display_numberp, int **chanids)
5009 {
5010           Channel *nc = NULL;
5011           int display_number, sock, port;
5012           struct addrinfo hints, *ai, *aitop;
5013           char strport[NI_MAXSERV];
5014           int gaierr, n, num_socks = 0, socks[NUM_SOCKS];
5015 
5016           if (chanids == NULL || x11_display_offset < 0 ||
5017               x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS)
5018                     return -1;
5019 
5020           for (display_number = x11_display_offset;
5021               display_number < MAX_DISPLAYS;
5022               display_number++) {
5023                     port = X11_BASE_PORT + display_number;
5024                     memset(&hints, 0, sizeof(hints));
5025                     hints.ai_family = ssh->chanctxt->IPv4or6;
5026                     hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
5027                     hints.ai_socktype = SOCK_STREAM;
5028                     snprintf(strport, sizeof strport, "%d", port);
5029                     if ((gaierr = getaddrinfo(NULL, strport,
5030                         &hints, &aitop)) != 0) {
5031                               error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
5032                               return -1;
5033                     }
5034                     for (ai = aitop; ai; ai = ai->ai_next) {
5035                               if (ai->ai_family != AF_INET &&
5036                                   ai->ai_family != AF_INET6)
5037                                         continue;
5038                               sock = socket(ai->ai_family, ai->ai_socktype,
5039                                   ai->ai_protocol);
5040                               if (sock == -1) {
5041                                         error("socket: %.100s", strerror(errno));
5042                                         freeaddrinfo(aitop);
5043                                         return -1;
5044                               }
5045                               set_reuseaddr(sock);
5046                               if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
5047                                         debug2_f("bind port %d: %.100s", port,
5048                                             strerror(errno));
5049                                         close(sock);
5050                                         for (n = 0; n < num_socks; n++)
5051                                                   close(socks[n]);
5052                                         num_socks = 0;
5053                                         break;
5054                               }
5055                               socks[num_socks++] = sock;
5056                               if (num_socks == NUM_SOCKS)
5057                                         break;
5058                     }
5059                     freeaddrinfo(aitop);
5060                     if (num_socks > 0)
5061                               break;
5062           }
5063           if (display_number >= MAX_DISPLAYS) {
5064                     error("Failed to allocate internet-domain X11 display socket.");
5065                     return -1;
5066           }
5067           /* Start listening for connections on the socket. */
5068           for (n = 0; n < num_socks; n++) {
5069                     sock = socks[n];
5070                     if (listen(sock, SSH_LISTEN_BACKLOG) == -1) {
5071                               error("listen: %.100s", strerror(errno));
5072                               close(sock);
5073                               return -1;
5074                     }
5075           }
5076 
5077           /* Allocate a channel for each socket. */
5078           *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
5079           for (n = 0; n < num_socks; n++) {
5080                     sock = socks[n];
5081                     /* Is this really necassary? */
5082                     if (hpn_disabled)
5083                     nc = channel_new(ssh, "x11-listener",
5084                         SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
5085                         CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
5086                         0, "X11 inet listener", 1);
5087                     else
5088                               nc = channel_new(ssh, "x11 listener",
5089                                   SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
5090                                   hpn_buffer_size, CHAN_X11_PACKET_DEFAULT,
5091                                   0, "X11 inet listener", 1);
5092                     nc->single_connection = single_connection;
5093                     (*chanids)[n] = nc->self;
5094           }
5095           (*chanids)[n] = -1;
5096 
5097           /* Return the display number for the DISPLAY environment variable. */
5098           *display_numberp = display_number;
5099           return 0;
5100 }
5101 
5102 static int
connect_local_xsocket(u_int dnr)5103 connect_local_xsocket(u_int dnr)
5104 {
5105           int sock;
5106           struct sockaddr_un addr;
5107 
5108           sock = socket(AF_UNIX, SOCK_STREAM, 0);
5109           if (sock == -1)
5110                     error("socket: %.100s", strerror(errno));
5111           memset(&addr, 0, sizeof(addr));
5112           addr.sun_family = AF_UNIX;
5113           snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
5114           if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
5115                     return sock;
5116           close(sock);
5117           error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
5118           return -1;
5119 }
5120 
5121 int
x11_connect_display(struct ssh * ssh)5122 x11_connect_display(struct ssh *ssh)
5123 {
5124           u_int display_number;
5125           const char *display;
5126           char buf[1024], *cp;
5127           struct addrinfo hints, *ai, *aitop;
5128           char strport[NI_MAXSERV];
5129           int gaierr, sock = 0;
5130 
5131           /* Try to open a socket for the local X server. */
5132           display = getenv("DISPLAY");
5133           if (!display) {
5134                     error("DISPLAY not set.");
5135                     return -1;
5136           }
5137           /*
5138            * Now we decode the value of the DISPLAY variable and make a
5139            * connection to the real X server.
5140            */
5141 
5142           /*
5143            * Check if it is a unix domain socket.  Unix domain displays are in
5144            * one of the following formats: unix:d[.s], :d[.s], ::d[.s]
5145            */
5146           if (strncmp(display, "unix:", 5) == 0 ||
5147               display[0] == ':') {
5148                     /* Connect to the unix domain socket. */
5149                     if (sscanf(strrchr(display, ':') + 1, "%u",
5150                         &display_number) != 1) {
5151                               error("Could not parse display number from DISPLAY: "
5152                                   "%.100s", display);
5153                               return -1;
5154                     }
5155                     /* Create a socket. */
5156                     sock = connect_local_xsocket(display_number);
5157                     if (sock < 0)
5158                               return -1;
5159 
5160                     /* OK, we now have a connection to the display. */
5161                     return sock;
5162           }
5163           /*
5164            * Connect to an inet socket.  The DISPLAY value is supposedly
5165            * hostname:d[.s], where hostname may also be numeric IP address.
5166            */
5167           strlcpy(buf, display, sizeof(buf));
5168           cp = strchr(buf, ':');
5169           if (!cp) {
5170                     error("Could not find ':' in DISPLAY: %.100s", display);
5171                     return -1;
5172           }
5173           *cp = 0;
5174           /*
5175            * buf now contains the host name.  But first we parse the
5176            * display number.
5177            */
5178           if (sscanf(cp + 1, "%u", &display_number) != 1 ||
5179               display_number > UINT16_MAX - X11_BASE_PORT) {
5180                     error("Could not parse display number from DISPLAY: %.100s",
5181                         display);
5182                     return -1;
5183           }
5184 
5185           /* Look up the host address */
5186           memset(&hints, 0, sizeof(hints));
5187           hints.ai_family = ssh->chanctxt->IPv4or6;
5188           hints.ai_socktype = SOCK_STREAM;
5189           snprintf(strport, sizeof strport, "%u", X11_BASE_PORT + display_number);
5190           if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
5191                     error("%.100s: unknown host. (%s)", buf,
5192                     ssh_gai_strerror(gaierr));
5193                     return -1;
5194           }
5195           for (ai = aitop; ai; ai = ai->ai_next) {
5196                     /* Create a socket. */
5197                     sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
5198                     if (sock == -1) {
5199                               debug2("socket: %.100s", strerror(errno));
5200                               continue;
5201                     }
5202                     /* Connect it to the display. */
5203                     if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
5204                               debug2("connect %.100s port %u: %.100s", buf,
5205                                   X11_BASE_PORT + display_number, strerror(errno));
5206                               close(sock);
5207                               continue;
5208                     }
5209                     /* Success */
5210                     break;
5211           }
5212           freeaddrinfo(aitop);
5213           if (!ai) {
5214                     error("connect %.100s port %u: %.100s", buf,
5215                         X11_BASE_PORT + display_number, strerror(errno));
5216                     return -1;
5217           }
5218           set_nodelay(sock);
5219           return sock;
5220 }
5221 
5222 /*
5223  * Requests forwarding of X11 connections, generates fake authentication
5224  * data, and enables authentication spoofing.
5225  * This should be called in the client only.
5226  */
5227 void
x11_request_forwarding_with_spoofing(struct ssh * ssh,int client_session_id,const char * disp,const char * proto,const char * data,int want_reply)5228 x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id,
5229     const char *disp, const char *proto, const char *data, int want_reply)
5230 {
5231           struct ssh_channels *sc = ssh->chanctxt;
5232           u_int data_len = (u_int) strlen(data) / 2;
5233           u_int i, value;
5234           const char *cp;
5235           char *new_data;
5236           int r, screen_number;
5237 
5238           if (sc->x11_saved_display == NULL)
5239                     sc->x11_saved_display = xstrdup(disp);
5240           else if (strcmp(disp, sc->x11_saved_display) != 0) {
5241                     error("x11_request_forwarding_with_spoofing: different "
5242                         "$DISPLAY already forwarded");
5243                     return;
5244           }
5245 
5246           cp = strchr(disp, ':');
5247           if (cp)
5248                     cp = strchr(cp, '.');
5249           if (cp)
5250                     screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL);
5251           else
5252                     screen_number = 0;
5253 
5254           if (sc->x11_saved_proto == NULL) {
5255                     /* Save protocol name. */
5256                     sc->x11_saved_proto = xstrdup(proto);
5257 
5258                     /* Extract real authentication data. */
5259                     sc->x11_saved_data = xmalloc(data_len);
5260                     for (i = 0; i < data_len; i++) {
5261                               if (sscanf(data + 2 * i, "%2x", &value) != 1) {
5262                                         fatal("x11_request_forwarding: bad "
5263                                             "authentication data: %.100s", data);
5264                               }
5265                               sc->x11_saved_data[i] = value;
5266                     }
5267                     sc->x11_saved_data_len = data_len;
5268 
5269                     /* Generate fake data of the same length. */
5270                     sc->x11_fake_data = xmalloc(data_len);
5271                     arc4random_buf(sc->x11_fake_data, data_len);
5272                     sc->x11_fake_data_len = data_len;
5273           }
5274 
5275           /* Convert the fake data into hex. */
5276           new_data = tohex(sc->x11_fake_data, data_len);
5277 
5278           /* Send the request packet. */
5279           channel_request_start(ssh, client_session_id, "x11-req", want_reply);
5280           if ((r = sshpkt_put_u8(ssh, 0)) != 0 || /* bool: single connection */
5281               (r = sshpkt_put_cstring(ssh, proto)) != 0 ||
5282               (r = sshpkt_put_cstring(ssh, new_data)) != 0 ||
5283               (r = sshpkt_put_u32(ssh, screen_number)) != 0 ||
5284               (r = sshpkt_send(ssh)) != 0 ||
5285               (r = ssh_packet_write_wait(ssh)) < 0)
5286                     fatal_fr(r, "send x11-req");
5287           free(new_data);
5288 }
5289 
5290 /*
5291  * Returns whether an x11 channel was used recently (less than a second ago)
5292  */
5293 int
x11_channel_used_recently(struct ssh * ssh)5294 x11_channel_used_recently(struct ssh *ssh) {
5295           u_int i;
5296           Channel *c;
5297           time_t lastused = 0;
5298 
5299           for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
5300                     c = ssh->chanctxt->channels[i];
5301                     if (c == NULL || c->ctype == NULL || c->lastused == 0 ||
5302                         strcmp(c->ctype, "x11-connection") != 0)
5303                               continue;
5304                     lastused = c->lastused;
5305           }
5306           return lastused != 0 && monotime() > lastused + 1;
5307 }
5308