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