[BACK]Return to channels.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / crypto / external / bsd / openssh / dist

Annotation of src/crypto/external/bsd/openssh/dist/channels.c, Revision 1.21.2.2

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

CVSweb <webmaster@jp.NetBSD.org>