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