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