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