Coverage Report

Created: 2026-10-23 07:09

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