summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auth-options.c11
-rw-r--r--auth.c3
-rw-r--r--channels.c3011
-rw-r--r--channels.h180
-rw-r--r--clientloop.c191
-rw-r--r--clientloop.h31
-rw-r--r--monitor.c5
-rw-r--r--monitor_wrap.c4
-rw-r--r--mux.c193
-rw-r--r--nchan.c114
-rw-r--r--packet.c68
-rw-r--r--packet.h8
-rw-r--r--servconf.c87
-rw-r--r--servconf.h14
-rw-r--r--serverloop.c105
-rw-r--r--serverloop.h6
-rw-r--r--session.c223
-rw-r--r--session.h16
-rw-r--r--ssh.c88
-rw-r--r--sshbuf.h3
-rw-r--r--sshconnect.c38
-rw-r--r--sshconnect.h8
-rw-r--r--sshd.c19
-rw-r--r--ssherr.c4
-rw-r--r--ssherr.h3
25 files changed, 2441 insertions, 1992 deletions
diff --git a/auth-options.c b/auth-options.c
index 0a191dbba..bed00eef0 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.73 2017/05/31 10:54:00 markus Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.74 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -61,9 +61,13 @@ char *authorized_principals = NULL;
61 61
62extern ServerOptions options; 62extern ServerOptions options;
63 63
64/* XXX refactor to be stateless */
65
64void 66void
65auth_clear_options(void) 67auth_clear_options(void)
66{ 68{
69 struct ssh *ssh = active_state; /* XXX */
70
67 no_agent_forwarding_flag = 0; 71 no_agent_forwarding_flag = 0;
68 no_port_forwarding_flag = 0; 72 no_port_forwarding_flag = 0;
69 no_pty_flag = 0; 73 no_pty_flag = 0;
@@ -81,7 +85,7 @@ auth_clear_options(void)
81 free(authorized_principals); 85 free(authorized_principals);
82 authorized_principals = NULL; 86 authorized_principals = NULL;
83 forced_tun_device = -1; 87 forced_tun_device = -1;
84 channel_clear_permitted_opens(); 88 channel_clear_permitted_opens(ssh);
85} 89}
86 90
87/* 91/*
@@ -117,6 +121,7 @@ match_flag(const char *opt, int allow_negate, char **optsp, const char *msg)
117/* 121/*
118 * return 1 if access is granted, 0 if not. 122 * return 1 if access is granted, 0 if not.
119 * side effect: sets key option flags 123 * side effect: sets key option flags
124 * XXX remove side effects; fill structure instead.
120 */ 125 */
121int 126int
122auth_parse_options(struct passwd *pw, char *opts, const char *file, 127auth_parse_options(struct passwd *pw, char *opts, const char *file,
@@ -380,7 +385,7 @@ auth_parse_options(struct passwd *pw, char *opts, const char *file,
380 goto bad_option; 385 goto bad_option;
381 } 386 }
382 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) 387 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0)
383 channel_add_permitted_opens(host, port); 388 channel_add_permitted_opens(ssh, host, port);
384 free(patterns); 389 free(patterns);
385 goto next_option; 390 goto next_option;
386 } 391 }
diff --git a/auth.c b/auth.c
index 7f073e0f3..a44906174 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.123 2017/08/18 05:36:45 djm Exp $ */ 1/* $OpenBSD: auth.c,v 1.124 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -567,6 +567,7 @@ getpwnamallow(const char *user)
567 ci->user = user; 567 ci->user = user;
568 parse_server_match_config(&options, ci); 568 parse_server_match_config(&options, ci);
569 log_change_level(options.log_level); 569 log_change_level(options.log_level);
570 process_permitopen(ssh, &options);
570 571
571#if defined(_AIX) && defined(HAVE_SETAUTHDB) 572#if defined(_AIX) && defined(HAVE_SETAUTHDB)
572 aix_setauthdb(user); 573 aix_setauthdb(user);
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}
diff --git a/channels.h b/channels.h
index 5ecb4d7c0..f04c43afa 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.127 2017/08/30 03:59:08 djm Exp $ */ 1/* $OpenBSD: channels.h,v 1.128 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -64,16 +64,18 @@
64struct ssh; 64struct ssh;
65struct Channel; 65struct Channel;
66typedef struct Channel Channel; 66typedef struct Channel Channel;
67struct fwd_perm_list;
67 68
68typedef void channel_open_fn(int, int, void *); 69typedef void channel_open_fn(struct ssh *, int, int, void *);
69typedef void channel_callback_fn(int, void *); 70typedef void channel_callback_fn(struct ssh *, int, void *);
70typedef int channel_infilter_fn(struct Channel *, char *, int); 71typedef int channel_infilter_fn(struct ssh *, struct Channel *, char *, int);
71typedef void channel_filter_cleanup_fn(int, void *); 72typedef void channel_filter_cleanup_fn(struct ssh *, int, void *);
72typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); 73typedef u_char *channel_outfilter_fn(struct ssh *, struct Channel *,
74 u_char **, size_t *);
73 75
74/* Channel success/failure callbacks */ 76/* Channel success/failure callbacks */
75typedef void channel_confirm_cb(int, struct Channel *, void *); 77typedef void channel_confirm_cb(struct ssh *, int, struct Channel *, void *);
76typedef void channel_confirm_abandon_cb(struct Channel *, void *); 78typedef void channel_confirm_abandon_cb(struct ssh *, struct Channel *, void *);
77struct channel_confirm { 79struct channel_confirm {
78 TAILQ_ENTRY(channel_confirm) entry; 80 TAILQ_ENTRY(channel_confirm) entry;
79 channel_confirm_cb *cb; 81 channel_confirm_cb *cb;
@@ -90,12 +92,13 @@ struct channel_connect {
90}; 92};
91 93
92/* Callbacks for mux channels back into client-specific code */ 94/* Callbacks for mux channels back into client-specific code */
93typedef int mux_callback_fn(struct Channel *); 95typedef int mux_callback_fn(struct ssh *, struct Channel *);
94 96
95struct Channel { 97struct Channel {
96 int type; /* channel type/state */ 98 int type; /* channel type/state */
97 int self; /* my own channel identifier */ 99 int self; /* my own channel identifier */
98 int remote_id; /* channel identifier for remote peer */ 100 int remote_id; /* channel identifier for remote peer */
101 /* XXX should be uint32_t */
99 u_int istate; /* input from channel (state of receive half) */ 102 u_int istate; /* input from channel (state of receive half) */
100 u_int ostate; /* output to channel (state of transmit half) */ 103 u_int ostate; /* output to channel (state of transmit half) */
101 int flags; /* close sent/rcvd */ 104 int flags; /* close sent/rcvd */
@@ -116,11 +119,12 @@ struct Channel {
116 * to a matching pre-select handler. 119 * to a matching pre-select handler.
117 * this way post-select handlers are not 120 * this way post-select handlers are not
118 * accidentally called if a FD gets reused */ 121 * accidentally called if a FD gets reused */
119 Buffer input; /* data read from socket, to be sent over 122 struct sshbuf *input; /* data read from socket, to be sent over
120 * encrypted connection */ 123 * encrypted connection */
121 Buffer output; /* data received over encrypted connection for 124 struct sshbuf *output; /* data received over encrypted connection for
122 * send on socket */ 125 * send on socket */
123 Buffer extended; 126 struct sshbuf *extended;
127
124 char *path; 128 char *path;
125 /* path for unix domain sockets, or host name for forwards */ 129 /* path for unix domain sockets, or host name for forwards */
126 int listening_port; /* port being listened for forwards */ 130 int listening_port; /* port being listened for forwards */
@@ -156,6 +160,7 @@ struct Channel {
156 int datagram; 160 int datagram;
157 161
158 /* non-blocking connect */ 162 /* non-blocking connect */
163 /* XXX make this a pointer so the structure can be opaque */
159 struct channel_connect connect_ctx; 164 struct channel_connect connect_ctx;
160 165
161 /* multiplexing protocol hook, called for each packet received */ 166 /* multiplexing protocol hook, called for each packet received */
@@ -195,44 +200,55 @@ struct Channel {
195#define CHAN_EOF_RCVD 0x08 200#define CHAN_EOF_RCVD 0x08
196#define CHAN_LOCAL 0x10 201#define CHAN_LOCAL 0x10
197 202
198#define CHAN_RBUF 16*1024 203/* Read buffer size */
204#define CHAN_RBUF (16*1024)
205
206/* Hard limit on number of channels */
207#define CHANNELS_MAX_CHANNELS (16*1024)
199 208
200/* check whether 'efd' is still in use */ 209/* check whether 'efd' is still in use */
201#define CHANNEL_EFD_INPUT_ACTIVE(c) \ 210#define CHANNEL_EFD_INPUT_ACTIVE(c) \
202 (c->extended_usage == CHAN_EXTENDED_READ && \ 211 (c->extended_usage == CHAN_EXTENDED_READ && \
203 (c->efd != -1 || \ 212 (c->efd != -1 || \
204 buffer_len(&c->extended) > 0)) 213 sshbuf_len(c->extended) > 0))
205#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \ 214#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
206 (c->extended_usage == CHAN_EXTENDED_WRITE && \ 215 (c->extended_usage == CHAN_EXTENDED_WRITE && \
207 c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \ 216 c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
208 buffer_len(&c->extended) > 0)) 217 sshbuf_len(c->extended) > 0))
218
219/* Add channel management structures to SSH transport instance */
220void channel_init_channels(struct ssh *ssh);
209 221
210/* channel management */ 222/* channel management */
211 223
212Channel *channel_by_id(int); 224Channel *channel_by_id(struct ssh *, int);
213Channel *channel_by_remote_id(int); 225Channel *channel_by_remote_id(struct ssh *, int);
214Channel *channel_lookup(int); 226Channel *channel_lookup(struct ssh *, int);
215Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); 227Channel *channel_new(struct ssh *, char *, int, int, int, int,
216void channel_set_fds(int, int, int, int, int, int, int, u_int); 228 u_int, u_int, int, char *, int);
217void channel_free(Channel *); 229void channel_set_fds(struct ssh *, int, int, int, int, int,
218void channel_free_all(void); 230 int, int, u_int);
219void channel_stop_listening(void); 231void channel_free(struct ssh *, Channel *);
220 232void channel_free_all(struct ssh *);
221void channel_send_open(int); 233void channel_stop_listening(struct ssh *);
222void channel_request_start(int, char *, int); 234
223void channel_register_cleanup(int, channel_callback_fn *, int); 235void channel_send_open(struct ssh *, int);
224void channel_register_open_confirm(int, channel_open_fn *, void *); 236void channel_request_start(struct ssh *, int, char *, int);
225void channel_register_filter(int, channel_infilter_fn *, 237void channel_register_cleanup(struct ssh *, int,
226 channel_outfilter_fn *, channel_filter_cleanup_fn *, void *); 238 channel_callback_fn *, int);
227void channel_register_status_confirm(int, channel_confirm_cb *, 239void channel_register_open_confirm(struct ssh *, int,
228 channel_confirm_abandon_cb *, void *); 240 channel_open_fn *, void *);
229void channel_cancel_cleanup(int); 241void channel_register_filter(struct ssh *, int, channel_infilter_fn *,
230int channel_close_fd(int *); 242 channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
231void channel_send_window_changes(void); 243void channel_register_status_confirm(struct ssh *, int,
244 channel_confirm_cb *, channel_confirm_abandon_cb *, void *);
245void channel_cancel_cleanup(struct ssh *, int);
246int channel_close_fd(struct ssh *, int *);
247void channel_send_window_changes(struct ssh *);
232 248
233/* mux proxy support */ 249/* mux proxy support */
234 250
235int channel_proxy_downstream(Channel *mc); 251int channel_proxy_downstream(struct ssh *, Channel *mc);
236int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *); 252int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *);
237 253
238/* protocol handler */ 254/* protocol handler */
@@ -252,63 +268,69 @@ int channel_input_status_confirm(int, u_int32_t, struct ssh *);
252void channel_prepare_select(struct ssh *, fd_set **, fd_set **, int *, 268void channel_prepare_select(struct ssh *, fd_set **, fd_set **, int *,
253 u_int*, time_t*); 269 u_int*, time_t*);
254void channel_after_select(struct ssh *, fd_set *, fd_set *); 270void channel_after_select(struct ssh *, fd_set *, fd_set *);
255void channel_output_poll(void); 271void channel_output_poll(struct ssh *);
256 272
257int channel_not_very_much_buffered_data(void); 273int channel_not_very_much_buffered_data(struct ssh *);
258void channel_close_all(void); 274void channel_close_all(struct ssh *);
259int channel_still_open(void); 275int channel_still_open(struct ssh *);
260char *channel_open_message(void); 276char *channel_open_message(struct ssh *);
261int channel_find_open(void); 277int channel_find_open(struct ssh *);
262 278
263/* tcp forwarding */ 279/* tcp forwarding */
264struct Forward; 280struct Forward;
265struct ForwardOptions; 281struct ForwardOptions;
266void channel_set_af(int af); 282void channel_set_af(struct ssh *, int af);
267void channel_permit_all_opens(void); 283void channel_permit_all_opens(struct ssh *);
268void channel_add_permitted_opens(char *, int); 284void channel_add_permitted_opens(struct ssh *, char *, int);
269int channel_add_adm_permitted_opens(char *, int); 285int channel_add_adm_permitted_opens(struct ssh *, char *, int);
270void channel_disable_adm_local_opens(void); 286void channel_copy_adm_permitted_opens(struct ssh *,
271void channel_update_permitted_opens(int, int); 287 const struct fwd_perm_list *);
272void channel_clear_permitted_opens(void); 288void channel_disable_adm_local_opens(struct ssh *);
273void channel_clear_adm_permitted_opens(void); 289void channel_update_permitted_opens(struct ssh *, int, int);
274void channel_print_adm_permitted_opens(void); 290void channel_clear_permitted_opens(struct ssh *);
275Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *, 291void channel_clear_adm_permitted_opens(struct ssh *);
276 const char **); 292void channel_print_adm_permitted_opens(struct ssh *);
277Channel *channel_connect_to_path(const char *, char *, char *); 293Channel *channel_connect_to_port(struct ssh *, const char *, u_short,
278Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); 294 char *, char *, int *, const char **);
279Channel *channel_connect_by_listen_address(const char *, u_short, 295Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
280 char *, char *); 296Channel *channel_connect_stdio_fwd(struct ssh *, const char*,
281Channel *channel_connect_by_listen_path(const char *, char *, char *); 297 u_short, int, int);
282int channel_request_remote_forwarding(struct Forward *); 298Channel *channel_connect_by_listen_address(struct ssh *, const char *,
283int channel_setup_local_fwd_listener(struct Forward *, struct ForwardOptions *); 299 u_short, char *, char *);
284int channel_request_rforward_cancel(struct Forward *); 300Channel *channel_connect_by_listen_path(struct ssh *, const char *,
285int channel_setup_remote_fwd_listener(struct Forward *, int *, struct ForwardOptions *); 301 char *, char *);
286int channel_cancel_rport_listener(struct Forward *); 302int channel_request_remote_forwarding(struct ssh *, struct Forward *);
287int channel_cancel_lport_listener(struct Forward *, int, struct ForwardOptions *); 303int channel_setup_local_fwd_listener(struct ssh *, struct Forward *,
304 struct ForwardOptions *);
305int channel_request_rforward_cancel(struct ssh *, struct Forward *);
306int channel_setup_remote_fwd_listener(struct ssh *, struct Forward *,
307 int *, struct ForwardOptions *);
308int channel_cancel_rport_listener(struct ssh *, struct Forward *);
309int channel_cancel_lport_listener(struct ssh *, struct Forward *,
310 int, struct ForwardOptions *);
288int permitopen_port(const char *); 311int permitopen_port(const char *);
289 312
290/* x11 forwarding */ 313/* x11 forwarding */
291 314
292void channel_set_x11_refuse_time(u_int); 315void channel_set_x11_refuse_time(struct ssh *, u_int);
293int x11_connect_display(void); 316int x11_connect_display(struct ssh *);
294int x11_create_display_inet(int, int, int, u_int *, int **); 317int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
295void x11_request_forwarding_with_spoofing(int, const char *, const char *, 318void x11_request_forwarding_with_spoofing(struct ssh *, int,
296 const char *, int); 319 const char *, const char *, const char *, int);
297 320
298/* channel close */ 321/* channel close */
299 322
300int chan_is_dead(Channel *, int); 323int chan_is_dead(struct ssh *, Channel *, int);
301void chan_mark_dead(Channel *); 324void chan_mark_dead(struct ssh *, Channel *);
302 325
303/* channel events */ 326/* channel events */
304 327
305void chan_rcvd_oclose(Channel *); 328void chan_rcvd_oclose(struct ssh *, Channel *);
306void chan_rcvd_eow(Channel *); /* SSH2-only */ 329void chan_rcvd_eow(struct ssh *, Channel *);
307void chan_read_failed(Channel *); 330void chan_read_failed(struct ssh *, Channel *);
308void chan_ibuf_empty(Channel *); 331void chan_ibuf_empty(struct ssh *, Channel *);
309 332void chan_rcvd_ieof(struct ssh *, Channel *);
310void chan_rcvd_ieof(Channel *); 333void chan_write_failed(struct ssh *, Channel *);
311void chan_write_failed(Channel *); 334void chan_obuf_empty(struct ssh *, Channel *);
312void chan_obuf_empty(Channel *);
313 335
314#endif 336#endif
diff --git a/clientloop.c b/clientloop.c
index 2934c4763..1218b3b71 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.302 2017/08/30 03:59:08 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.303 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -177,6 +177,7 @@ struct channel_reply_ctx {
177}; 177};
178 178
179/* Global request success/failure callbacks */ 179/* Global request success/failure callbacks */
180/* XXX move to struct ssh? */
180struct global_confirm { 181struct global_confirm {
181 TAILQ_ENTRY(global_confirm) entry; 182 TAILQ_ENTRY(global_confirm) entry;
182 global_confirm_cb *cb; 183 global_confirm_cb *cb;
@@ -244,13 +245,13 @@ get_current_time(void)
244 * control master process, or if there is no ControlPersist timeout. 245 * control master process, or if there is no ControlPersist timeout.
245 */ 246 */
246static void 247static void
247set_control_persist_exit_time(void) 248set_control_persist_exit_time(struct ssh *ssh)
248{ 249{
249 if (muxserver_sock == -1 || !options.control_persist 250 if (muxserver_sock == -1 || !options.control_persist
250 || options.control_persist_timeout == 0) { 251 || options.control_persist_timeout == 0) {
251 /* not using a ControlPersist timeout */ 252 /* not using a ControlPersist timeout */
252 control_persist_exit_time = 0; 253 control_persist_exit_time = 0;
253 } else if (channel_still_open()) { 254 } else if (channel_still_open(ssh)) {
254 /* some client connections are still open */ 255 /* some client connections are still open */
255 if (control_persist_exit_time > 0) 256 if (control_persist_exit_time > 0)
256 debug2("%s: cancel scheduled exit", __func__); 257 debug2("%s: cancel scheduled exit", __func__);
@@ -288,8 +289,9 @@ client_x11_display_valid(const char *display)
288#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" 289#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
289#define X11_TIMEOUT_SLACK 60 290#define X11_TIMEOUT_SLACK 60
290int 291int
291client_x11_get_proto(const char *display, const char *xauth_path, 292client_x11_get_proto(struct ssh *ssh, const char *display,
292 u_int trusted, u_int timeout, char **_proto, char **_data) 293 const char *xauth_path, u_int trusted, u_int timeout,
294 char **_proto, char **_data)
293{ 295{
294 char cmd[1024], line[512], xdisplay[512]; 296 char cmd[1024], line[512], xdisplay[512];
295 char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; 297 char xauthfile[PATH_MAX], xauthdir[PATH_MAX];
@@ -373,7 +375,8 @@ client_x11_get_proto(const char *display, const char *xauth_path,
373 x11_refuse_time = UINT_MAX; 375 x11_refuse_time = UINT_MAX;
374 else 376 else
375 x11_refuse_time = now + timeout; 377 x11_refuse_time = now + timeout;
376 channel_set_x11_refuse_time(x11_refuse_time); 378 channel_set_x11_refuse_time(ssh,
379 x11_refuse_time);
377 } 380 }
378 if (system(cmd) == 0) 381 if (system(cmd) == 0)
379 generated = 1; 382 generated = 1;
@@ -446,7 +449,7 @@ client_x11_get_proto(const char *display, const char *xauth_path,
446 */ 449 */
447 450
448static void 451static void
449client_check_window_change(void) 452client_check_window_change(struct ssh *ssh)
450{ 453{
451 if (!received_window_change_signal) 454 if (!received_window_change_signal)
452 return; 455 return;
@@ -455,7 +458,7 @@ client_check_window_change(void)
455 458
456 debug2("%s: changed", __func__); 459 debug2("%s: changed", __func__);
457 460
458 channel_send_window_changes(); 461 channel_send_window_changes(ssh);
459} 462}
460 463
461static int 464static int
@@ -466,7 +469,7 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
466 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) 469 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
467 return 0; 470 return 0;
468 if (gc->cb != NULL) 471 if (gc->cb != NULL)
469 gc->cb(type, seq, gc->ctx); 472 gc->cb(ssh, type, seq, gc->ctx);
470 if (--gc->ref_count <= 0) { 473 if (--gc->ref_count <= 0) {
471 TAILQ_REMOVE(&global_confirms, gc, entry); 474 TAILQ_REMOVE(&global_confirms, gc, entry);
472 explicit_bzero(gc, sizeof(*gc)); 475 explicit_bzero(gc, sizeof(*gc));
@@ -497,7 +500,8 @@ server_alive_check(void)
497 * one of the file descriptors). 500 * one of the file descriptors).
498 */ 501 */
499static void 502static void
500client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, 503client_wait_until_can_do_something(struct ssh *ssh,
504 fd_set **readsetp, fd_set **writesetp,
501 int *maxfdp, u_int *nallocp, int rekeying) 505 int *maxfdp, u_int *nallocp, int rekeying)
502{ 506{
503 struct timeval tv, *tvp; 507 struct timeval tv, *tvp;
@@ -510,7 +514,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
510 nallocp, &minwait_secs); 514 nallocp, &minwait_secs);
511 515
512 /* channel_prepare_select could have closed the last channel */ 516 /* channel_prepare_select could have closed the last channel */
513 if (session_closed && !channel_still_open() && 517 if (session_closed && !channel_still_open(ssh) &&
514 !packet_have_data_to_write()) { 518 !packet_have_data_to_write()) {
515 /* clear mask since we did not call select() */ 519 /* clear mask since we did not call select() */
516 memset(*readsetp, 0, *nallocp); 520 memset(*readsetp, 0, *nallocp);
@@ -537,7 +541,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
537 } 541 }
538 if (options.rekey_interval > 0 && !rekeying) 542 if (options.rekey_interval > 0 && !rekeying)
539 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); 543 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());
540 set_control_persist_exit_time(); 544 set_control_persist_exit_time(ssh);
541 if (control_persist_exit_time > 0) { 545 if (control_persist_exit_time > 0) {
542 timeout_secs = MINIMUM(timeout_secs, 546 timeout_secs = MINIMUM(timeout_secs,
543 control_persist_exit_time - now); 547 control_persist_exit_time - now);
@@ -668,7 +672,7 @@ client_process_net_input(fd_set *readset)
668} 672}
669 673
670static void 674static void
671client_status_confirm(int type, Channel *c, void *ctx) 675client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx)
672{ 676{
673 struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; 677 struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx;
674 char errmsg[256]; 678 char errmsg[256];
@@ -707,8 +711,7 @@ client_status_confirm(int type, Channel *c, void *ctx)
707 * their stderr. 711 * their stderr.
708 */ 712 */
709 if (tochan) { 713 if (tochan) {
710 buffer_append(&c->extended, errmsg, 714 buffer_append(c->extended, errmsg, strlen(errmsg));
711 strlen(errmsg));
712 } else 715 } else
713 error("%s", errmsg); 716 error("%s", errmsg);
714 if (cr->action == CONFIRM_TTY) { 717 if (cr->action == CONFIRM_TTY) {
@@ -719,23 +722,23 @@ client_status_confirm(int type, Channel *c, void *ctx)
719 if (c->self == session_ident) 722 if (c->self == session_ident)
720 leave_raw_mode(0); 723 leave_raw_mode(0);
721 else 724 else
722 mux_tty_alloc_failed(c); 725 mux_tty_alloc_failed(ssh, c);
723 } else if (cr->action == CONFIRM_CLOSE) { 726 } else if (cr->action == CONFIRM_CLOSE) {
724 chan_read_failed(c); 727 chan_read_failed(ssh, c);
725 chan_write_failed(c); 728 chan_write_failed(ssh, c);
726 } 729 }
727 } 730 }
728 free(cr); 731 free(cr);
729} 732}
730 733
731static void 734static void
732client_abandon_status_confirm(Channel *c, void *ctx) 735client_abandon_status_confirm(struct ssh *ssh, Channel *c, void *ctx)
733{ 736{
734 free(ctx); 737 free(ctx);
735} 738}
736 739
737void 740void
738client_expect_confirm(int id, const char *request, 741client_expect_confirm(struct ssh *ssh, int id, const char *request,
739 enum confirm_action action) 742 enum confirm_action action)
740{ 743{
741 struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr)); 744 struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr));
@@ -743,7 +746,7 @@ client_expect_confirm(int id, const char *request,
743 cr->request_type = request; 746 cr->request_type = request;
744 cr->action = action; 747 cr->action = action;
745 748
746 channel_register_status_confirm(id, client_status_confirm, 749 channel_register_status_confirm(ssh, id, client_status_confirm,
747 client_abandon_status_confirm, cr); 750 client_abandon_status_confirm, cr);
748} 751}
749 752
@@ -769,7 +772,7 @@ client_register_global_confirm(global_confirm_cb *cb, void *ctx)
769} 772}
770 773
771static void 774static void
772process_cmdline(void) 775process_cmdline(struct ssh *ssh)
773{ 776{
774 void (*handler)(int); 777 void (*handler)(int);
775 char *s, *cmd; 778 char *s, *cmd;
@@ -843,12 +846,12 @@ process_cmdline(void)
843 goto out; 846 goto out;
844 } 847 }
845 if (remote) 848 if (remote)
846 ok = channel_request_rforward_cancel(&fwd) == 0; 849 ok = channel_request_rforward_cancel(ssh, &fwd) == 0;
847 else if (dynamic) 850 else if (dynamic)
848 ok = channel_cancel_lport_listener(&fwd, 851 ok = channel_cancel_lport_listener(ssh, &fwd,
849 0, &options.fwd_opts) > 0; 852 0, &options.fwd_opts) > 0;
850 else 853 else
851 ok = channel_cancel_lport_listener(&fwd, 854 ok = channel_cancel_lport_listener(ssh, &fwd,
852 CHANNEL_CANCEL_PORT_STATIC, 855 CHANNEL_CANCEL_PORT_STATIC,
853 &options.fwd_opts) > 0; 856 &options.fwd_opts) > 0;
854 if (!ok) { 857 if (!ok) {
@@ -862,13 +865,13 @@ process_cmdline(void)
862 goto out; 865 goto out;
863 } 866 }
864 if (local || dynamic) { 867 if (local || dynamic) {
865 if (!channel_setup_local_fwd_listener(&fwd, 868 if (!channel_setup_local_fwd_listener(ssh, &fwd,
866 &options.fwd_opts)) { 869 &options.fwd_opts)) {
867 logit("Port forwarding failed."); 870 logit("Port forwarding failed.");
868 goto out; 871 goto out;
869 } 872 }
870 } else { 873 } else {
871 if (channel_request_remote_forwarding(&fwd) < 0) { 874 if (channel_request_remote_forwarding(ssh, &fwd) < 0) {
872 logit("Port forwarding failed."); 875 logit("Port forwarding failed.");
873 goto out; 876 goto out;
874 } 877 }
@@ -945,7 +948,8 @@ print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr)
945 * Process the characters one by one. 948 * Process the characters one by one.
946 */ 949 */
947static int 950static int
948process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, 951process_escapes(struct ssh *ssh, Channel *c,
952 Buffer *bin, Buffer *bout, Buffer *berr,
949 char *buf, int len) 953 char *buf, int len)
950{ 954{
951 char string[1024]; 955 char string[1024];
@@ -981,13 +985,15 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
981 buffer_append(berr, string, strlen(string)); 985 buffer_append(berr, string, strlen(string));
982 986
983 if (c && c->ctl_chan != -1) { 987 if (c && c->ctl_chan != -1) {
984 chan_read_failed(c); 988 chan_read_failed(ssh, c);
985 chan_write_failed(c); 989 chan_write_failed(ssh, c);
986 if (c->detach_user) 990 if (c->detach_user) {
987 c->detach_user(c->self, NULL); 991 c->detach_user(ssh,
992 c->self, NULL);
993 }
988 c->type = SSH_CHANNEL_ABANDONED; 994 c->type = SSH_CHANNEL_ABANDONED;
989 buffer_clear(&c->input); 995 buffer_clear(c->input);
990 chan_ibuf_empty(c); 996 chan_ibuf_empty(ssh, c);
991 return 0; 997 return 0;
992 } else 998 } else
993 quit_pending = 1; 999 quit_pending = 1;
@@ -1025,7 +1031,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1025 snprintf(string, sizeof string, 1031 snprintf(string, sizeof string,
1026 "%cB\r\n", efc->escape_char); 1032 "%cB\r\n", efc->escape_char);
1027 buffer_append(berr, string, strlen(string)); 1033 buffer_append(berr, string, strlen(string));
1028 channel_request_start(c->self, "break", 0); 1034 channel_request_start(ssh, c->self, "break", 0);
1029 packet_put_int(1000); 1035 packet_put_int(1000);
1030 packet_send(); 1036 packet_send();
1031 continue; 1037 continue;
@@ -1077,7 +1083,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1077 options.request_tty == REQUEST_TTY_FORCE); 1083 options.request_tty == REQUEST_TTY_FORCE);
1078 1084
1079 /* Stop listening for new connections. */ 1085 /* Stop listening for new connections. */
1080 channel_stop_listening(); 1086 channel_stop_listening(ssh);
1081 1087
1082 snprintf(string, sizeof string, 1088 snprintf(string, sizeof string,
1083 "%c& [backgrounded]\n", efc->escape_char); 1089 "%c& [backgrounded]\n", efc->escape_char);
@@ -1107,7 +1113,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1107 snprintf(string, sizeof string, "%c#\r\n", 1113 snprintf(string, sizeof string, "%c#\r\n",
1108 efc->escape_char); 1114 efc->escape_char);
1109 buffer_append(berr, string, strlen(string)); 1115 buffer_append(berr, string, strlen(string));
1110 s = channel_open_message(); 1116 s = channel_open_message(ssh);
1111 buffer_append(berr, s, strlen(s)); 1117 buffer_append(berr, s, strlen(s));
1112 free(s); 1118 free(s);
1113 continue; 1119 continue;
@@ -1115,7 +1121,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1115 case 'C': 1121 case 'C':
1116 if (c && c->ctl_chan != -1) 1122 if (c && c->ctl_chan != -1)
1117 goto noescape; 1123 goto noescape;
1118 process_cmdline(); 1124 process_cmdline(ssh);
1119 continue; 1125 continue;
1120 1126
1121 default: 1127 default:
@@ -1186,25 +1192,25 @@ client_new_escape_filter_ctx(int escape_char)
1186 1192
1187/* Free the escape filter context on channel free */ 1193/* Free the escape filter context on channel free */
1188void 1194void
1189client_filter_cleanup(int cid, void *ctx) 1195client_filter_cleanup(struct ssh *ssh, int cid, void *ctx)
1190{ 1196{
1191 free(ctx); 1197 free(ctx);
1192} 1198}
1193 1199
1194int 1200int
1195client_simple_escape_filter(Channel *c, char *buf, int len) 1201client_simple_escape_filter(struct ssh *ssh, Channel *c, char *buf, int len)
1196{ 1202{
1197 if (c->extended_usage != CHAN_EXTENDED_WRITE) 1203 if (c->extended_usage != CHAN_EXTENDED_WRITE)
1198 return 0; 1204 return 0;
1199 1205
1200 return process_escapes(c, &c->input, &c->output, &c->extended, 1206 return process_escapes(ssh, c, c->input, c->output, c->extended,
1201 buf, len); 1207 buf, len);
1202} 1208}
1203 1209
1204static void 1210static void
1205client_channel_closed(int id, void *arg) 1211client_channel_closed(struct ssh *ssh, int id, void *arg)
1206{ 1212{
1207 channel_cancel_cleanup(id); 1213 channel_cancel_cleanup(ssh, id);
1208 session_closed = 1; 1214 session_closed = 1;
1209 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1215 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1210} 1216}
@@ -1215,9 +1221,9 @@ client_channel_closed(int id, void *arg)
1215 * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character 1221 * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character
1216 * used as an escape character for terminating or suspending the session. 1222 * used as an escape character for terminating or suspending the session.
1217 */ 1223 */
1218
1219int 1224int
1220client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) 1225client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1226 int ssh2_chan_id)
1221{ 1227{
1222 fd_set *readset = NULL, *writeset = NULL; 1228 fd_set *readset = NULL, *writeset = NULL;
1223 double start_time, total_time; 1229 double start_time, total_time;
@@ -1295,13 +1301,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1295 session_ident = ssh2_chan_id; 1301 session_ident = ssh2_chan_id;
1296 if (session_ident != -1) { 1302 if (session_ident != -1) {
1297 if (escape_char_arg != SSH_ESCAPECHAR_NONE) { 1303 if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
1298 channel_register_filter(session_ident, 1304 channel_register_filter(ssh, session_ident,
1299 client_simple_escape_filter, NULL, 1305 client_simple_escape_filter, NULL,
1300 client_filter_cleanup, 1306 client_filter_cleanup,
1301 client_new_escape_filter_ctx( 1307 client_new_escape_filter_ctx(
1302 escape_char_arg)); 1308 escape_char_arg));
1303 } 1309 }
1304 channel_register_cleanup(session_ident, 1310 channel_register_cleanup(ssh, session_ident,
1305 client_channel_closed, 0); 1311 client_channel_closed, 0);
1306 } 1312 }
1307 1313
@@ -1311,15 +1317,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1311 /* Process buffered packets sent by the server. */ 1317 /* Process buffered packets sent by the server. */
1312 client_process_buffered_input_packets(); 1318 client_process_buffered_input_packets();
1313 1319
1314 if (session_closed && !channel_still_open()) 1320 if (session_closed && !channel_still_open(ssh))
1315 break; 1321 break;
1316 1322
1317 if (ssh_packet_is_rekeying(active_state)) { 1323 if (ssh_packet_is_rekeying(ssh)) {
1318 debug("rekeying in progress"); 1324 debug("rekeying in progress");
1319 } else if (need_rekeying) { 1325 } else if (need_rekeying) {
1320 /* manual rekey request */ 1326 /* manual rekey request */
1321 debug("need rekeying"); 1327 debug("need rekeying");
1322 if ((r = kex_start_rekex(active_state)) != 0) 1328 if ((r = kex_start_rekex(ssh)) != 0)
1323 fatal("%s: kex_start_rekex: %s", __func__, 1329 fatal("%s: kex_start_rekex: %s", __func__,
1324 ssh_err(r)); 1330 ssh_err(r));
1325 need_rekeying = 0; 1331 need_rekeying = 0;
@@ -1329,13 +1335,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1329 * enqueue them for sending to the server. 1335 * enqueue them for sending to the server.
1330 */ 1336 */
1331 if (packet_not_very_much_data_to_write()) 1337 if (packet_not_very_much_data_to_write())
1332 channel_output_poll(); 1338 channel_output_poll(ssh);
1333 1339
1334 /* 1340 /*
1335 * Check if the window size has changed, and buffer a 1341 * Check if the window size has changed, and buffer a
1336 * message about it to the server if so. 1342 * message about it to the server if so.
1337 */ 1343 */
1338 client_check_window_change(); 1344 client_check_window_change(ssh);
1339 1345
1340 if (quit_pending) 1346 if (quit_pending)
1341 break; 1347 break;
@@ -1345,15 +1351,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1345 * available on one of the descriptors). 1351 * available on one of the descriptors).
1346 */ 1352 */
1347 max_fd2 = max_fd; 1353 max_fd2 = max_fd;
1348 client_wait_until_can_do_something(&readset, &writeset, 1354 client_wait_until_can_do_something(ssh, &readset, &writeset,
1349 &max_fd2, &nalloc, ssh_packet_is_rekeying(active_state)); 1355 &max_fd2, &nalloc, ssh_packet_is_rekeying(ssh));
1350 1356
1351 if (quit_pending) 1357 if (quit_pending)
1352 break; 1358 break;
1353 1359
1354 /* Do channel operations unless rekeying in progress. */ 1360 /* Do channel operations unless rekeying in progress. */
1355 if (!ssh_packet_is_rekeying(active_state)) 1361 if (!ssh_packet_is_rekeying(ssh))
1356 channel_after_select(active_state, readset, writeset); 1362 channel_after_select(ssh, readset, writeset);
1357 1363
1358 /* Buffer input from the connection. */ 1364 /* Buffer input from the connection. */
1359 client_process_net_input(readset); 1365 client_process_net_input(readset);
@@ -1395,7 +1401,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1395 packet_send(); 1401 packet_send();
1396 packet_write_wait(); 1402 packet_write_wait();
1397 1403
1398 channel_free_all(); 1404 channel_free_all(ssh);
1399 1405
1400 if (have_pty) 1406 if (have_pty)
1401 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1407 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
@@ -1463,8 +1469,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1463/*********/ 1469/*********/
1464 1470
1465static Channel * 1471static Channel *
1466client_request_forwarded_tcpip(const char *request_type, int rchan, 1472client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
1467 u_int rwindow, u_int rmaxpack) 1473 int rchan, u_int rwindow, u_int rmaxpack)
1468{ 1474{
1469 Channel *c = NULL; 1475 Channel *c = NULL;
1470 struct sshbuf *b = NULL; 1476 struct sshbuf *b = NULL;
@@ -1482,7 +1488,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
1482 debug("%s: listen %s port %d, originator %s port %d", __func__, 1488 debug("%s: listen %s port %d, originator %s port %d", __func__,
1483 listen_address, listen_port, originator_address, originator_port); 1489 listen_address, listen_port, originator_address, originator_port);
1484 1490
1485 c = channel_connect_by_listen_address(listen_address, listen_port, 1491 c = channel_connect_by_listen_address(ssh, listen_address, listen_port,
1486 "forwarded-tcpip", originator_address); 1492 "forwarded-tcpip", originator_address);
1487 1493
1488 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { 1494 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
@@ -1501,7 +1507,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
1501 (r = sshbuf_put_u32(b, listen_port)) != 0 || 1507 (r = sshbuf_put_u32(b, listen_port)) != 0 ||
1502 (r = sshbuf_put_cstring(b, originator_address)) != 0 || 1508 (r = sshbuf_put_cstring(b, originator_address)) != 0 ||
1503 (r = sshbuf_put_u32(b, originator_port)) != 0 || 1509 (r = sshbuf_put_u32(b, originator_port)) != 0 ||
1504 (r = sshbuf_put_stringb(&c->output, b)) != 0) { 1510 (r = sshbuf_put_stringb(c->output, b)) != 0) {
1505 error("%s: compose for muxclient %s", __func__, 1511 error("%s: compose for muxclient %s", __func__,
1506 ssh_err(r)); 1512 ssh_err(r));
1507 goto out; 1513 goto out;
@@ -1516,7 +1522,8 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
1516} 1522}
1517 1523
1518static Channel * 1524static Channel *
1519client_request_forwarded_streamlocal(const char *request_type, int rchan) 1525client_request_forwarded_streamlocal(struct ssh *ssh,
1526 const char *request_type, int rchan)
1520{ 1527{
1521 Channel *c = NULL; 1528 Channel *c = NULL;
1522 char *listen_path; 1529 char *listen_path;
@@ -1530,14 +1537,14 @@ client_request_forwarded_streamlocal(const char *request_type, int rchan)
1530 1537
1531 debug("%s: %s", __func__, listen_path); 1538 debug("%s: %s", __func__, listen_path);
1532 1539
1533 c = channel_connect_by_listen_path(listen_path, 1540 c = channel_connect_by_listen_path(ssh, listen_path,
1534 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); 1541 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal");
1535 free(listen_path); 1542 free(listen_path);
1536 return c; 1543 return c;
1537} 1544}
1538 1545
1539static Channel * 1546static Channel *
1540client_request_x11(const char *request_type, int rchan) 1547client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
1541{ 1548{
1542 Channel *c = NULL; 1549 Channel *c = NULL;
1543 char *originator; 1550 char *originator;
@@ -1567,10 +1574,10 @@ client_request_x11(const char *request_type, int rchan)
1567 debug("client_request_x11: request from %s %d", originator, 1574 debug("client_request_x11: request from %s %d", originator,
1568 originator_port); 1575 originator_port);
1569 free(originator); 1576 free(originator);
1570 sock = x11_connect_display(); 1577 sock = x11_connect_display(ssh);
1571 if (sock < 0) 1578 if (sock < 0)
1572 return NULL; 1579 return NULL;
1573 c = channel_new("x11", 1580 c = channel_new(ssh, "x11",
1574 SSH_CHANNEL_X11_OPEN, sock, sock, -1, 1581 SSH_CHANNEL_X11_OPEN, sock, sock, -1,
1575 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); 1582 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
1576 c->force_drain = 1; 1583 c->force_drain = 1;
@@ -1578,7 +1585,7 @@ client_request_x11(const char *request_type, int rchan)
1578} 1585}
1579 1586
1580static Channel * 1587static Channel *
1581client_request_agent(const char *request_type, int rchan) 1588client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
1582{ 1589{
1583 Channel *c = NULL; 1590 Channel *c = NULL;
1584 int r, sock; 1591 int r, sock;
@@ -1595,7 +1602,7 @@ client_request_agent(const char *request_type, int rchan)
1595 __func__, ssh_err(r)); 1602 __func__, ssh_err(r));
1596 return NULL; 1603 return NULL;
1597 } 1604 }
1598 c = channel_new("authentication agent connection", 1605 c = channel_new(ssh, "authentication agent connection",
1599 SSH_CHANNEL_OPEN, sock, sock, -1, 1606 SSH_CHANNEL_OPEN, sock, sock, -1,
1600 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, 1607 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
1601 "authentication agent connection", 1); 1608 "authentication agent connection", 1);
@@ -1604,7 +1611,8 @@ client_request_agent(const char *request_type, int rchan)
1604} 1611}
1605 1612
1606int 1613int
1607client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) 1614client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1615 int local_tun, int remote_tun)
1608{ 1616{
1609 Channel *c; 1617 Channel *c;
1610 int fd; 1618 int fd;
@@ -1620,7 +1628,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
1620 return -1; 1628 return -1;
1621 } 1629 }
1622 1630
1623 c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, 1631 c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
1624 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); 1632 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
1625 c->datagram = 1; 1633 c->datagram = 1;
1626 1634
@@ -1660,14 +1668,14 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
1660 ctype, rchan, rwindow, rmaxpack); 1668 ctype, rchan, rwindow, rmaxpack);
1661 1669
1662 if (strcmp(ctype, "forwarded-tcpip") == 0) { 1670 if (strcmp(ctype, "forwarded-tcpip") == 0) {
1663 c = client_request_forwarded_tcpip(ctype, rchan, rwindow, 1671 c = client_request_forwarded_tcpip(ssh, ctype, rchan, rwindow,
1664 rmaxpack); 1672 rmaxpack);
1665 } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { 1673 } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) {
1666 c = client_request_forwarded_streamlocal(ctype, rchan); 1674 c = client_request_forwarded_streamlocal(ssh, ctype, rchan);
1667 } else if (strcmp(ctype, "x11") == 0) { 1675 } else if (strcmp(ctype, "x11") == 0) {
1668 c = client_request_x11(ctype, rchan); 1676 c = client_request_x11(ssh, ctype, rchan);
1669 } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { 1677 } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
1670 c = client_request_agent(ctype, rchan); 1678 c = client_request_agent(ssh, ctype, rchan);
1671 } 1679 }
1672 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { 1680 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
1673 debug3("proxied to downstream: %s", ctype); 1681 debug3("proxied to downstream: %s", ctype);
@@ -1707,7 +1715,7 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
1707 char *rtype; 1715 char *rtype;
1708 1716
1709 id = packet_get_int(); 1717 id = packet_get_int();
1710 c = channel_lookup(id); 1718 c = channel_lookup(ssh, id);
1711 if (channel_proxy_upstream(c, type, seq, ssh)) 1719 if (channel_proxy_upstream(c, type, seq, ssh))
1712 return 0; 1720 return 0;
1713 rtype = packet_get_string(NULL); 1721 rtype = packet_get_string(NULL);
@@ -1723,11 +1731,11 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
1723 "unknown channel", id); 1731 "unknown channel", id);
1724 } else if (strcmp(rtype, "eow@openssh.com") == 0) { 1732 } else if (strcmp(rtype, "eow@openssh.com") == 0) {
1725 packet_check_eom(); 1733 packet_check_eom();
1726 chan_rcvd_eow(c); 1734 chan_rcvd_eow(ssh, c);
1727 } else if (strcmp(rtype, "exit-status") == 0) { 1735 } else if (strcmp(rtype, "exit-status") == 0) {
1728 exitval = packet_get_int(); 1736 exitval = packet_get_int();
1729 if (c->ctl_chan != -1) { 1737 if (c->ctl_chan != -1) {
1730 mux_exit_message(c, exitval); 1738 mux_exit_message(ssh, c, exitval);
1731 success = 1; 1739 success = 1;
1732 } else if (id == session_ident) { 1740 } else if (id == session_ident) {
1733 /* Record exit value of local session */ 1741 /* Record exit value of local session */
@@ -1895,9 +1903,9 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
1895} 1903}
1896 1904
1897static void 1905static void
1898client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) 1906client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
1907 u_int32_t seq, void *_ctx)
1899{ 1908{
1900 struct ssh *ssh = active_state; /* XXX */
1901 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; 1909 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
1902 size_t i, ndone; 1910 size_t i, ndone;
1903 struct sshbuf *signdata; 1911 struct sshbuf *signdata;
@@ -2161,7 +2169,7 @@ client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
2161} 2169}
2162 2170
2163void 2171void
2164client_session2_setup(int id, int want_tty, int want_subsystem, 2172client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2165 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) 2173 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)
2166{ 2174{
2167 int len; 2175 int len;
@@ -2169,8 +2177,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2169 2177
2170 debug2("%s: id %d", __func__, id); 2178 debug2("%s: id %d", __func__, id);
2171 2179
2172 if ((c = channel_lookup(id)) == NULL) 2180 if ((c = channel_lookup(ssh, id)) == NULL)
2173 fatal("client_session2_setup: channel %d: unknown channel", id); 2181 fatal("%s: channel %d: unknown channel", __func__, id);
2174 2182
2175 packet_set_interactive(want_tty, 2183 packet_set_interactive(want_tty,
2176 options.ip_qos_interactive, options.ip_qos_bulk); 2184 options.ip_qos_interactive, options.ip_qos_bulk);
@@ -2182,8 +2190,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2182 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) 2190 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)
2183 memset(&ws, 0, sizeof(ws)); 2191 memset(&ws, 0, sizeof(ws));
2184 2192
2185 channel_request_start(id, "pty-req", 1); 2193 channel_request_start(ssh, id, "pty-req", 1);
2186 client_expect_confirm(id, "PTY allocation", CONFIRM_TTY); 2194 client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY);
2187 packet_put_cstring(term != NULL ? term : ""); 2195 packet_put_cstring(term != NULL ? term : "");
2188 packet_put_int((u_int)ws.ws_col); 2196 packet_put_int((u_int)ws.ws_col);
2189 packet_put_int((u_int)ws.ws_row); 2197 packet_put_int((u_int)ws.ws_row);
@@ -2226,7 +2234,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2226 } 2234 }
2227 2235
2228 debug("Sending env %s = %s", name, val); 2236 debug("Sending env %s = %s", name, val);
2229 channel_request_start(id, "env", 0); 2237 channel_request_start(ssh, id, "env", 0);
2230 packet_put_cstring(name); 2238 packet_put_cstring(name);
2231 packet_put_cstring(val); 2239 packet_put_cstring(val);
2232 packet_send(); 2240 packet_send();
@@ -2241,19 +2249,20 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2241 if (want_subsystem) { 2249 if (want_subsystem) {
2242 debug("Sending subsystem: %.*s", 2250 debug("Sending subsystem: %.*s",
2243 len, (u_char*)buffer_ptr(cmd)); 2251 len, (u_char*)buffer_ptr(cmd));
2244 channel_request_start(id, "subsystem", 1); 2252 channel_request_start(ssh, id, "subsystem", 1);
2245 client_expect_confirm(id, "subsystem", CONFIRM_CLOSE); 2253 client_expect_confirm(ssh, id, "subsystem",
2254 CONFIRM_CLOSE);
2246 } else { 2255 } else {
2247 debug("Sending command: %.*s", 2256 debug("Sending command: %.*s",
2248 len, (u_char*)buffer_ptr(cmd)); 2257 len, (u_char*)buffer_ptr(cmd));
2249 channel_request_start(id, "exec", 1); 2258 channel_request_start(ssh, id, "exec", 1);
2250 client_expect_confirm(id, "exec", CONFIRM_CLOSE); 2259 client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE);
2251 } 2260 }
2252 packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 2261 packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
2253 packet_send(); 2262 packet_send();
2254 } else { 2263 } else {
2255 channel_request_start(id, "shell", 1); 2264 channel_request_start(ssh, id, "shell", 1);
2256 client_expect_confirm(id, "shell", CONFIRM_CLOSE); 2265 client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
2257 packet_send(); 2266 packet_send();
2258 } 2267 }
2259} 2268}
diff --git a/clientloop.h b/clientloop.h
index ae83aa8cf..a1975ccc8 100644
--- a/clientloop.h
+++ b/clientloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.h,v 1.33 2016/09/30 09:19:13 markus Exp $ */ 1/* $OpenBSD: clientloop.h,v 1.34 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,28 +37,31 @@
37 37
38#include <termios.h> 38#include <termios.h>
39 39
40struct ssh;
41
40/* Client side main loop for the interactive session. */ 42/* Client side main loop for the interactive session. */
41int client_loop(int, int, int); 43int client_loop(struct ssh *, int, int, int);
42int client_x11_get_proto(const char *, const char *, u_int, u_int, 44int client_x11_get_proto(struct ssh *, const char *, const char *,
43 char **, char **); 45 u_int, u_int, char **, char **);
44void client_global_request_reply_fwd(int, u_int32_t, void *); 46void client_global_request_reply_fwd(int, u_int32_t, void *);
45void client_session2_setup(int, int, int, const char *, struct termios *, 47void client_session2_setup(struct ssh *, int, int, int,
46 int, Buffer *, char **); 48 const char *, struct termios *, int, Buffer *, char **);
47int client_request_tun_fwd(int, int, int); 49int client_request_tun_fwd(struct ssh *, int, int, int);
48void client_stop_mux(void); 50void client_stop_mux(void);
49 51
50/* Escape filter for protocol 2 sessions */ 52/* Escape filter for protocol 2 sessions */
51void *client_new_escape_filter_ctx(int); 53void *client_new_escape_filter_ctx(int);
52void client_filter_cleanup(int, void *); 54void client_filter_cleanup(struct ssh *, int, void *);
53int client_simple_escape_filter(Channel *, char *, int); 55int client_simple_escape_filter(struct ssh *, Channel *, char *, int);
54 56
55/* Global request confirmation callbacks */ 57/* Global request confirmation callbacks */
56typedef void global_confirm_cb(int, u_int32_t seq, void *); 58typedef void global_confirm_cb(struct ssh *, int, u_int32_t, void *);
57void client_register_global_confirm(global_confirm_cb *, void *); 59void client_register_global_confirm(global_confirm_cb *, void *);
58 60
59/* Channel request confirmation callbacks */ 61/* Channel request confirmation callbacks */
60enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY }; 62enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY };
61void client_expect_confirm(int, const char *, enum confirm_action); 63void client_expect_confirm(struct ssh *, int, const char *,
64 enum confirm_action);
62 65
63/* Multiplexing protocol version */ 66/* Multiplexing protocol version */
64#define SSHMUX_VER 4 67#define SSHMUX_VER 4
@@ -73,8 +76,8 @@ void client_expect_confirm(int, const char *, enum confirm_action);
73#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */ 76#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */
74#define SSHMUX_COMMAND_PROXY 8 /* Open new connection */ 77#define SSHMUX_COMMAND_PROXY 8 /* Open new connection */
75 78
76void muxserver_listen(void); 79void muxserver_listen(struct ssh *);
77int muxclient(const char *); 80int muxclient(const char *);
78void mux_exit_message(Channel *, int); 81void mux_exit_message(struct ssh *, Channel *, int);
79void mux_tty_alloc_failed(Channel *); 82void mux_tty_alloc_failed(struct ssh *ssh, Channel *);
80 83
diff --git a/monitor.c b/monitor.c
index 8a7897bde..bdb4e8552 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.172 2017/06/24 06:34:38 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.173 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -1519,13 +1519,14 @@ mm_answer_pty_cleanup(int sock, Buffer *m)
1519int 1519int
1520mm_answer_term(int sock, Buffer *req) 1520mm_answer_term(int sock, Buffer *req)
1521{ 1521{
1522 struct ssh *ssh = active_state; /* XXX */
1522 extern struct monitor *pmonitor; 1523 extern struct monitor *pmonitor;
1523 int res, status; 1524 int res, status;
1524 1525
1525 debug3("%s: tearing down sessions", __func__); 1526 debug3("%s: tearing down sessions", __func__);
1526 1527
1527 /* The child is terminating */ 1528 /* The child is terminating */
1528 session_destroy_all(&mm_session_close); 1529 session_destroy_all(ssh, &mm_session_close);
1529 1530
1530#ifdef USE_PAM 1531#ifdef USE_PAM
1531 if (options.use_pam) 1532 if (options.use_pam)
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 25f3e9678..287af0667 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.92 2017/05/30 14:10:53 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.93 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -242,6 +242,7 @@ mm_key_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
242struct passwd * 242struct passwd *
243mm_getpwnamallow(const char *username) 243mm_getpwnamallow(const char *username)
244{ 244{
245 struct ssh *ssh = active_state; /* XXX */
245 Buffer m; 246 Buffer m;
246 struct passwd *pw; 247 struct passwd *pw;
247 u_int len, i; 248 u_int len, i;
@@ -296,6 +297,7 @@ out:
296 297
297 copy_set_server_options(&options, newopts, 1); 298 copy_set_server_options(&options, newopts, 1);
298 log_change_level(options.log_level); 299 log_change_level(options.log_level);
300 process_permitopen(ssh, &options);
299 free(newopts); 301 free(newopts);
300 302
301 buffer_free(&m); 303 buffer_free(&m);
diff --git a/mux.c b/mux.c
index 3dde4da40..9eee287b9 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.65 2017/06/09 06:47:13 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.66 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -161,22 +161,32 @@ struct mux_master_state {
161#define MUX_FWD_REMOTE 2 161#define MUX_FWD_REMOTE 2
162#define MUX_FWD_DYNAMIC 3 162#define MUX_FWD_DYNAMIC 3
163 163
164static void mux_session_confirm(int, int, void *); 164static void mux_session_confirm(struct ssh *, int, int, void *);
165static void mux_stdio_confirm(int, int, void *); 165static void mux_stdio_confirm(struct ssh *, int, int, void *);
166 166
167static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); 167static int process_mux_master_hello(struct ssh *, u_int,
168static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); 168 Channel *, struct sshbuf *, struct sshbuf *);
169static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *); 169static int process_mux_new_session(struct ssh *, u_int,
170static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *); 170 Channel *, struct sshbuf *, struct sshbuf *);
171static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); 171static int process_mux_alive_check(struct ssh *, u_int,
172static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); 172 Channel *, struct sshbuf *, struct sshbuf *);
173static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); 173static int process_mux_terminate(struct ssh *, u_int,
174static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); 174 Channel *, struct sshbuf *, struct sshbuf *);
175static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *); 175static int process_mux_open_fwd(struct ssh *, u_int,
176 Channel *, struct sshbuf *, struct sshbuf *);
177static int process_mux_close_fwd(struct ssh *, u_int,
178 Channel *, struct sshbuf *, struct sshbuf *);
179static int process_mux_stdio_fwd(struct ssh *, u_int,
180 Channel *, struct sshbuf *, struct sshbuf *);
181static int process_mux_stop_listening(struct ssh *, u_int,
182 Channel *, struct sshbuf *, struct sshbuf *);
183static int process_mux_proxy(struct ssh *, u_int,
184 Channel *, struct sshbuf *, struct sshbuf *);
176 185
177static const struct { 186static const struct {
178 u_int type; 187 u_int type;
179 int (*handler)(u_int, Channel *, Buffer *, Buffer *); 188 int (*handler)(struct ssh *, u_int, Channel *,
189 struct sshbuf *, struct sshbuf *);
180} mux_master_handlers[] = { 190} mux_master_handlers[] = {
181 { MUX_MSG_HELLO, process_mux_master_hello }, 191 { MUX_MSG_HELLO, process_mux_master_hello },
182 { MUX_C_NEW_SESSION, process_mux_new_session }, 192 { MUX_C_NEW_SESSION, process_mux_new_session },
@@ -193,36 +203,36 @@ static const struct {
193/* Cleanup callback fired on closure of mux slave _session_ channel */ 203/* Cleanup callback fired on closure of mux slave _session_ channel */
194/* ARGSUSED */ 204/* ARGSUSED */
195static void 205static void
196mux_master_session_cleanup_cb(int cid, void *unused) 206mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused)
197{ 207{
198 Channel *cc, *c = channel_by_id(cid); 208 Channel *cc, *c = channel_by_id(ssh, cid);
199 209
200 debug3("%s: entering for channel %d", __func__, cid); 210 debug3("%s: entering for channel %d", __func__, cid);
201 if (c == NULL) 211 if (c == NULL)
202 fatal("%s: channel_by_id(%i) == NULL", __func__, cid); 212 fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
203 if (c->ctl_chan != -1) { 213 if (c->ctl_chan != -1) {
204 if ((cc = channel_by_id(c->ctl_chan)) == NULL) 214 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
205 fatal("%s: channel %d missing control channel %d", 215 fatal("%s: channel %d missing control channel %d",
206 __func__, c->self, c->ctl_chan); 216 __func__, c->self, c->ctl_chan);
207 c->ctl_chan = -1; 217 c->ctl_chan = -1;
208 cc->remote_id = -1; 218 cc->remote_id = -1;
209 chan_rcvd_oclose(cc); 219 chan_rcvd_oclose(ssh, cc);
210 } 220 }
211 channel_cancel_cleanup(c->self); 221 channel_cancel_cleanup(ssh, c->self);
212} 222}
213 223
214/* Cleanup callback fired on closure of mux slave _control_ channel */ 224/* Cleanup callback fired on closure of mux slave _control_ channel */
215/* ARGSUSED */ 225/* ARGSUSED */
216static void 226static void
217mux_master_control_cleanup_cb(int cid, void *unused) 227mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused)
218{ 228{
219 Channel *sc, *c = channel_by_id(cid); 229 Channel *sc, *c = channel_by_id(ssh, cid);
220 230
221 debug3("%s: entering for channel %d", __func__, cid); 231 debug3("%s: entering for channel %d", __func__, cid);
222 if (c == NULL) 232 if (c == NULL)
223 fatal("%s: channel_by_id(%i) == NULL", __func__, cid); 233 fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
224 if (c->remote_id != -1) { 234 if (c->remote_id != -1) {
225 if ((sc = channel_by_id(c->remote_id)) == NULL) 235 if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)
226 fatal("%s: channel %d missing session channel %d", 236 fatal("%s: channel %d missing session channel %d",
227 __func__, c->self, c->remote_id); 237 __func__, c->self, c->remote_id);
228 c->remote_id = -1; 238 c->remote_id = -1;
@@ -230,15 +240,15 @@ mux_master_control_cleanup_cb(int cid, void *unused)
230 if (sc->type != SSH_CHANNEL_OPEN && 240 if (sc->type != SSH_CHANNEL_OPEN &&
231 sc->type != SSH_CHANNEL_OPENING) { 241 sc->type != SSH_CHANNEL_OPENING) {
232 debug2("%s: channel %d: not open", __func__, sc->self); 242 debug2("%s: channel %d: not open", __func__, sc->self);
233 chan_mark_dead(sc); 243 chan_mark_dead(ssh, sc);
234 } else { 244 } else {
235 if (sc->istate == CHAN_INPUT_OPEN) 245 if (sc->istate == CHAN_INPUT_OPEN)
236 chan_read_failed(sc); 246 chan_read_failed(ssh, sc);
237 if (sc->ostate == CHAN_OUTPUT_OPEN) 247 if (sc->ostate == CHAN_OUTPUT_OPEN)
238 chan_write_failed(sc); 248 chan_write_failed(ssh, sc);
239 } 249 }
240 } 250 }
241 channel_cancel_cleanup(c->self); 251 channel_cancel_cleanup(ssh, c->self);
242} 252}
243 253
244/* Check mux client environment variables before passing them to mux master. */ 254/* Check mux client environment variables before passing them to mux master. */
@@ -266,7 +276,8 @@ env_permitted(char *env)
266/* Mux master protocol message handlers */ 276/* Mux master protocol message handlers */
267 277
268static int 278static int
269process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) 279process_mux_master_hello(struct ssh *ssh, u_int rid,
280 Channel *c, Buffer *m, Buffer *r)
270{ 281{
271 u_int ver; 282 u_int ver;
272 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; 283 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
@@ -308,7 +319,8 @@ process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
308} 319}
309 320
310static int 321static int
311process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) 322process_mux_new_session(struct ssh *ssh, u_int rid,
323 Channel *c, Buffer *m, Buffer *r)
312{ 324{
313 Channel *nc; 325 Channel *nc;
314 struct mux_session_confirm_ctx *cctx; 326 struct mux_session_confirm_ctx *cctx;
@@ -453,7 +465,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
453 packetmax >>= 1; 465 packetmax >>= 1;
454 } 466 }
455 467
456 nc = channel_new("session", SSH_CHANNEL_OPENING, 468 nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING,
457 new_fd[0], new_fd[1], new_fd[2], window, packetmax, 469 new_fd[0], new_fd[1], new_fd[2], window, packetmax,
458 CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); 470 CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
459 471
@@ -461,7 +473,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
461 c->remote_id = nc->self; /* link control -> session channel */ 473 c->remote_id = nc->self; /* link control -> session channel */
462 474
463 if (cctx->want_tty && escape_char != 0xffffffff) { 475 if (cctx->want_tty && escape_char != 0xffffffff) {
464 channel_register_filter(nc->self, 476 channel_register_filter(ssh, nc->self,
465 client_simple_escape_filter, NULL, 477 client_simple_escape_filter, NULL,
466 client_filter_cleanup, 478 client_filter_cleanup,
467 client_new_escape_filter_ctx((int)escape_char)); 479 client_new_escape_filter_ctx((int)escape_char));
@@ -470,17 +482,19 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
470 debug2("%s: channel_new: %d linked to control channel %d", 482 debug2("%s: channel_new: %d linked to control channel %d",
471 __func__, nc->self, nc->ctl_chan); 483 __func__, nc->self, nc->ctl_chan);
472 484
473 channel_send_open(nc->self); 485 channel_send_open(ssh, nc->self);
474 channel_register_open_confirm(nc->self, mux_session_confirm, cctx); 486 channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx);
475 c->mux_pause = 1; /* stop handling messages until open_confirm done */ 487 c->mux_pause = 1; /* stop handling messages until open_confirm done */
476 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); 488 channel_register_cleanup(ssh, nc->self,
489 mux_master_session_cleanup_cb, 1);
477 490
478 /* reply is deferred, sent by mux_session_confirm */ 491 /* reply is deferred, sent by mux_session_confirm */
479 return 0; 492 return 0;
480} 493}
481 494
482static int 495static int
483process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) 496process_mux_alive_check(struct ssh *ssh, u_int rid,
497 Channel *c, Buffer *m, Buffer *r)
484{ 498{
485 debug2("%s: channel %d: alive check", __func__, c->self); 499 debug2("%s: channel %d: alive check", __func__, c->self);
486 500
@@ -493,7 +507,8 @@ process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)
493} 507}
494 508
495static int 509static int
496process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) 510process_mux_terminate(struct ssh *ssh, u_int rid,
511 Channel *c, Buffer *m, Buffer *r)
497{ 512{
498 debug2("%s: channel %d: terminate request", __func__, c->self); 513 debug2("%s: channel %d: terminate request", __func__, c->self);
499 514
@@ -582,7 +597,7 @@ compare_forward(struct Forward *a, struct Forward *b)
582} 597}
583 598
584static void 599static void
585mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 600mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
586{ 601{
587 struct mux_channel_confirm_ctx *fctx = ctxt; 602 struct mux_channel_confirm_ctx *fctx = ctxt;
588 char *failmsg = NULL; 603 char *failmsg = NULL;
@@ -590,7 +605,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
590 Channel *c; 605 Channel *c;
591 Buffer out; 606 Buffer out;
592 607
593 if ((c = channel_by_id(fctx->cid)) == NULL) { 608 if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {
594 /* no channel for reply */ 609 /* no channel for reply */
595 error("%s: unknown channel", __func__); 610 error("%s: unknown channel", __func__);
596 return; 611 return;
@@ -616,7 +631,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
616 buffer_put_int(&out, MUX_S_REMOTE_PORT); 631 buffer_put_int(&out, MUX_S_REMOTE_PORT);
617 buffer_put_int(&out, fctx->rid); 632 buffer_put_int(&out, fctx->rid);
618 buffer_put_int(&out, rfwd->allocated_port); 633 buffer_put_int(&out, rfwd->allocated_port);
619 channel_update_permitted_opens(rfwd->handle, 634 channel_update_permitted_opens(ssh, rfwd->handle,
620 rfwd->allocated_port); 635 rfwd->allocated_port);
621 } else { 636 } else {
622 buffer_put_int(&out, MUX_S_OK); 637 buffer_put_int(&out, MUX_S_OK);
@@ -625,7 +640,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
625 goto out; 640 goto out;
626 } else { 641 } else {
627 if (rfwd->listen_port == 0) 642 if (rfwd->listen_port == 0)
628 channel_update_permitted_opens(rfwd->handle, -1); 643 channel_update_permitted_opens(ssh, rfwd->handle, -1);
629 if (rfwd->listen_path != NULL) 644 if (rfwd->listen_path != NULL)
630 xasprintf(&failmsg, "remote port forwarding failed for " 645 xasprintf(&failmsg, "remote port forwarding failed for "
631 "listen path %s", rfwd->listen_path); 646 "listen path %s", rfwd->listen_path);
@@ -651,7 +666,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
651 buffer_put_cstring(&out, failmsg); 666 buffer_put_cstring(&out, failmsg);
652 free(failmsg); 667 free(failmsg);
653 out: 668 out:
654 buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); 669 buffer_put_string(c->output, buffer_ptr(&out), buffer_len(&out));
655 buffer_free(&out); 670 buffer_free(&out);
656 if (c->mux_pause <= 0) 671 if (c->mux_pause <= 0)
657 fatal("%s: mux_pause %d", __func__, c->mux_pause); 672 fatal("%s: mux_pause %d", __func__, c->mux_pause);
@@ -659,7 +674,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
659} 674}
660 675
661static int 676static int
662process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 677process_mux_open_fwd(struct ssh *ssh, u_int rid,
678 Channel *c, Buffer *m, Buffer *r)
663{ 679{
664 struct Forward fwd; 680 struct Forward fwd;
665 char *fwd_desc = NULL; 681 char *fwd_desc = NULL;
@@ -727,13 +743,16 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
727 fwd.listen_port); 743 fwd.listen_port);
728 goto invalid; 744 goto invalid;
729 } 745 }
730 if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536) 746 if ((fwd.connect_port != PORT_STREAMLOCAL &&
731 || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { 747 fwd.connect_port >= 65536) ||
748 (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE &&
749 fwd.connect_port == 0)) {
732 logit("%s: invalid connect port %u", __func__, 750 logit("%s: invalid connect port %u", __func__,
733 fwd.connect_port); 751 fwd.connect_port);
734 goto invalid; 752 goto invalid;
735 } 753 }
736 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) { 754 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL &&
755 fwd.connect_path == NULL) {
737 logit("%s: missing connect host", __func__); 756 logit("%s: missing connect host", __func__);
738 goto invalid; 757 goto invalid;
739 } 758 }
@@ -784,7 +803,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
784 } 803 }
785 804
786 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { 805 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
787 if (!channel_setup_local_fwd_listener(&fwd, 806 if (!channel_setup_local_fwd_listener(ssh, &fwd,
788 &options.fwd_opts)) { 807 &options.fwd_opts)) {
789 fail: 808 fail:
790 logit("slave-requested %s failed", fwd_desc); 809 logit("slave-requested %s failed", fwd_desc);
@@ -798,7 +817,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
798 } else { 817 } else {
799 struct mux_channel_confirm_ctx *fctx; 818 struct mux_channel_confirm_ctx *fctx;
800 819
801 fwd.handle = channel_request_remote_forwarding(&fwd); 820 fwd.handle = channel_request_remote_forwarding(ssh, &fwd);
802 if (fwd.handle < 0) 821 if (fwd.handle < 0)
803 goto fail; 822 goto fail;
804 add_remote_forward(&options, &fwd); 823 add_remote_forward(&options, &fwd);
@@ -827,7 +846,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
827} 846}
828 847
829static int 848static int
830process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 849process_mux_close_fwd(struct ssh *ssh, u_int rid,
850 Channel *c, Buffer *m, Buffer *r)
831{ 851{
832 struct Forward fwd, *found_fwd; 852 struct Forward fwd, *found_fwd;
833 char *fwd_desc = NULL; 853 char *fwd_desc = NULL;
@@ -908,11 +928,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
908 * However, for dynamic allocated listen ports we need 928 * However, for dynamic allocated listen ports we need
909 * to use the actual listen port. 929 * to use the actual listen port.
910 */ 930 */
911 if (channel_request_rforward_cancel(found_fwd) == -1) 931 if (channel_request_rforward_cancel(ssh, found_fwd) == -1)
912 error_reason = "port not in permitted opens"; 932 error_reason = "port not in permitted opens";
913 } else { /* local and dynamic forwards */ 933 } else { /* local and dynamic forwards */
914 /* Ditto */ 934 /* Ditto */
915 if (channel_cancel_lport_listener(&fwd, fwd.connect_port, 935 if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port,
916 &options.fwd_opts) == -1) 936 &options.fwd_opts) == -1)
917 error_reason = "port not found"; 937 error_reason = "port not found";
918 } 938 }
@@ -942,7 +962,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
942} 962}
943 963
944static int 964static int
945process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 965process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
966 Channel *c, Buffer *m, Buffer *r)
946{ 967{
947 Channel *nc; 968 Channel *nc;
948 char *reserved, *chost; 969 char *reserved, *chost;
@@ -1018,7 +1039,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
1018 if (!isatty(new_fd[1])) 1039 if (!isatty(new_fd[1]))
1019 set_nonblock(new_fd[1]); 1040 set_nonblock(new_fd[1]);
1020 1041
1021 nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]); 1042 nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]);
1022 1043
1023 nc->ctl_chan = c->self; /* link session -> control channel */ 1044 nc->ctl_chan = c->self; /* link session -> control channel */
1024 c->remote_id = nc->self; /* link control -> session channel */ 1045 c->remote_id = nc->self; /* link control -> session channel */
@@ -1026,11 +1047,12 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
1026 debug2("%s: channel_new: %d linked to control channel %d", 1047 debug2("%s: channel_new: %d linked to control channel %d",
1027 __func__, nc->self, nc->ctl_chan); 1048 __func__, nc->self, nc->ctl_chan);
1028 1049
1029 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); 1050 channel_register_cleanup(ssh, nc->self,
1051 mux_master_session_cleanup_cb, 1);
1030 1052
1031 cctx = xcalloc(1, sizeof(*cctx)); 1053 cctx = xcalloc(1, sizeof(*cctx));
1032 cctx->rid = rid; 1054 cctx->rid = rid;
1033 channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx); 1055 channel_register_open_confirm(ssh, nc->self, mux_stdio_confirm, cctx);
1034 c->mux_pause = 1; /* stop handling messages until open_confirm done */ 1056 c->mux_pause = 1; /* stop handling messages until open_confirm done */
1035 1057
1036 /* reply is deferred, sent by mux_session_confirm */ 1058 /* reply is deferred, sent by mux_session_confirm */
@@ -1039,7 +1061,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
1039 1061
1040/* Callback on open confirmation in mux master for a mux stdio fwd session. */ 1062/* Callback on open confirmation in mux master for a mux stdio fwd session. */
1041static void 1063static void
1042mux_stdio_confirm(int id, int success, void *arg) 1064mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1043{ 1065{
1044 struct mux_stdio_confirm_ctx *cctx = arg; 1066 struct mux_stdio_confirm_ctx *cctx = arg;
1045 Channel *c, *cc; 1067 Channel *c, *cc;
@@ -1047,9 +1069,9 @@ mux_stdio_confirm(int id, int success, void *arg)
1047 1069
1048 if (cctx == NULL) 1070 if (cctx == NULL)
1049 fatal("%s: cctx == NULL", __func__); 1071 fatal("%s: cctx == NULL", __func__);
1050 if ((c = channel_by_id(id)) == NULL) 1072 if ((c = channel_by_id(ssh, id)) == NULL)
1051 fatal("%s: no channel for id %d", __func__, id); 1073 fatal("%s: no channel for id %d", __func__, id);
1052 if ((cc = channel_by_id(c->ctl_chan)) == NULL) 1074 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
1053 fatal("%s: channel %d lacks control channel %d", __func__, 1075 fatal("%s: channel %d lacks control channel %d", __func__,
1054 id, c->ctl_chan); 1076 id, c->ctl_chan);
1055 1077
@@ -1072,7 +1094,7 @@ mux_stdio_confirm(int id, int success, void *arg)
1072 1094
1073 done: 1095 done:
1074 /* Send reply */ 1096 /* Send reply */
1075 buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); 1097 buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply));
1076 buffer_free(&reply); 1098 buffer_free(&reply);
1077 1099
1078 if (cc->mux_pause <= 0) 1100 if (cc->mux_pause <= 0)
@@ -1083,7 +1105,8 @@ mux_stdio_confirm(int id, int success, void *arg)
1083} 1105}
1084 1106
1085static int 1107static int
1086process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) 1108process_mux_stop_listening(struct ssh *ssh, u_int rid,
1109 Channel *c, Buffer *m, Buffer *r)
1087{ 1110{
1088 debug("%s: channel %d: stop listening", __func__, c->self); 1111 debug("%s: channel %d: stop listening", __func__, c->self);
1089 1112
@@ -1100,7 +1123,7 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
1100 } 1123 }
1101 1124
1102 if (mux_listener_channel != NULL) { 1125 if (mux_listener_channel != NULL) {
1103 channel_free(mux_listener_channel); 1126 channel_free(ssh, mux_listener_channel);
1104 client_stop_mux(); 1127 client_stop_mux();
1105 free(options.control_path); 1128 free(options.control_path);
1106 options.control_path = NULL; 1129 options.control_path = NULL;
@@ -1116,7 +1139,8 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
1116} 1139}
1117 1140
1118static int 1141static int
1119process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) 1142process_mux_proxy(struct ssh *ssh, u_int rid,
1143 Channel *c, Buffer *m, Buffer *r)
1120{ 1144{
1121 debug("%s: channel %d: proxy request", __func__, c->self); 1145 debug("%s: channel %d: proxy request", __func__, c->self);
1122 1146
@@ -1129,7 +1153,7 @@ process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r)
1129 1153
1130/* Channel callbacks fired on read/write from mux slave fd */ 1154/* Channel callbacks fired on read/write from mux slave fd */
1131static int 1155static int
1132mux_master_read_cb(Channel *c) 1156mux_master_read_cb(struct ssh *ssh, Channel *c)
1133{ 1157{
1134 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; 1158 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
1135 Buffer in, out; 1159 Buffer in, out;
@@ -1141,7 +1165,7 @@ mux_master_read_cb(Channel *c)
1141 if (c->mux_ctx == NULL) { 1165 if (c->mux_ctx == NULL) {
1142 state = xcalloc(1, sizeof(*state)); 1166 state = xcalloc(1, sizeof(*state));
1143 c->mux_ctx = state; 1167 c->mux_ctx = state;
1144 channel_register_cleanup(c->self, 1168 channel_register_cleanup(ssh, c->self,
1145 mux_master_control_cleanup_cb, 0); 1169 mux_master_control_cleanup_cb, 0);
1146 1170
1147 /* Send hello */ 1171 /* Send hello */
@@ -1149,7 +1173,7 @@ mux_master_read_cb(Channel *c)
1149 buffer_put_int(&out, MUX_MSG_HELLO); 1173 buffer_put_int(&out, MUX_MSG_HELLO);
1150 buffer_put_int(&out, SSHMUX_VER); 1174 buffer_put_int(&out, SSHMUX_VER);
1151 /* no extensions */ 1175 /* no extensions */
1152 buffer_put_string(&c->output, buffer_ptr(&out), 1176 buffer_put_string(c->output, buffer_ptr(&out),
1153 buffer_len(&out)); 1177 buffer_len(&out));
1154 buffer_free(&out); 1178 buffer_free(&out);
1155 debug3("%s: channel %d: hello sent", __func__, c->self); 1179 debug3("%s: channel %d: hello sent", __func__, c->self);
@@ -1160,7 +1184,7 @@ mux_master_read_cb(Channel *c)
1160 buffer_init(&out); 1184 buffer_init(&out);
1161 1185
1162 /* Channel code ensures that we receive whole packets */ 1186 /* Channel code ensures that we receive whole packets */
1163 if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) { 1187 if ((ptr = buffer_get_string_ptr_ret(c->input, &have)) == NULL) {
1164 malf: 1188 malf:
1165 error("%s: malformed message", __func__); 1189 error("%s: malformed message", __func__);
1166 goto out; 1190 goto out;
@@ -1186,7 +1210,8 @@ mux_master_read_cb(Channel *c)
1186 1210
1187 for (i = 0; mux_master_handlers[i].handler != NULL; i++) { 1211 for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
1188 if (type == mux_master_handlers[i].type) { 1212 if (type == mux_master_handlers[i].type) {
1189 ret = mux_master_handlers[i].handler(rid, c, &in, &out); 1213 ret = mux_master_handlers[i].handler(ssh, rid,
1214 c, &in, &out);
1190 break; 1215 break;
1191 } 1216 }
1192 } 1217 }
@@ -1199,7 +1224,7 @@ mux_master_read_cb(Channel *c)
1199 } 1224 }
1200 /* Enqueue reply packet */ 1225 /* Enqueue reply packet */
1201 if (buffer_len(&out) != 0) { 1226 if (buffer_len(&out) != 0) {
1202 buffer_put_string(&c->output, buffer_ptr(&out), 1227 buffer_put_string(c->output, buffer_ptr(&out),
1203 buffer_len(&out)); 1228 buffer_len(&out));
1204 } 1229 }
1205 out: 1230 out:
@@ -1209,7 +1234,7 @@ mux_master_read_cb(Channel *c)
1209} 1234}
1210 1235
1211void 1236void
1212mux_exit_message(Channel *c, int exitval) 1237mux_exit_message(struct ssh *ssh, Channel *c, int exitval)
1213{ 1238{
1214 Buffer m; 1239 Buffer m;
1215 Channel *mux_chan; 1240 Channel *mux_chan;
@@ -1217,7 +1242,7 @@ mux_exit_message(Channel *c, int exitval)
1217 debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, 1242 debug3("%s: channel %d: exit message, exitval %d", __func__, c->self,
1218 exitval); 1243 exitval);
1219 1244
1220 if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) 1245 if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
1221 fatal("%s: channel %d missing mux channel %d", 1246 fatal("%s: channel %d missing mux channel %d",
1222 __func__, c->self, c->ctl_chan); 1247 __func__, c->self, c->ctl_chan);
1223 1248
@@ -1227,19 +1252,19 @@ mux_exit_message(Channel *c, int exitval)
1227 buffer_put_int(&m, c->self); 1252 buffer_put_int(&m, c->self);
1228 buffer_put_int(&m, exitval); 1253 buffer_put_int(&m, exitval);
1229 1254
1230 buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); 1255 buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m));
1231 buffer_free(&m); 1256 buffer_free(&m);
1232} 1257}
1233 1258
1234void 1259void
1235mux_tty_alloc_failed(Channel *c) 1260mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
1236{ 1261{
1237 Buffer m; 1262 Buffer m;
1238 Channel *mux_chan; 1263 Channel *mux_chan;
1239 1264
1240 debug3("%s: channel %d: TTY alloc failed", __func__, c->self); 1265 debug3("%s: channel %d: TTY alloc failed", __func__, c->self);
1241 1266
1242 if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) 1267 if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
1243 fatal("%s: channel %d missing mux channel %d", 1268 fatal("%s: channel %d missing mux channel %d",
1244 __func__, c->self, c->ctl_chan); 1269 __func__, c->self, c->ctl_chan);
1245 1270
@@ -1248,13 +1273,13 @@ mux_tty_alloc_failed(Channel *c)
1248 buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); 1273 buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL);
1249 buffer_put_int(&m, c->self); 1274 buffer_put_int(&m, c->self);
1250 1275
1251 buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); 1276 buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m));
1252 buffer_free(&m); 1277 buffer_free(&m);
1253} 1278}
1254 1279
1255/* Prepare a mux master to listen on a Unix domain socket. */ 1280/* Prepare a mux master to listen on a Unix domain socket. */
1256void 1281void
1257muxserver_listen(void) 1282muxserver_listen(struct ssh *ssh)
1258{ 1283{
1259 mode_t old_umask; 1284 mode_t old_umask;
1260 char *orig_control_path = options.control_path; 1285 char *orig_control_path = options.control_path;
@@ -1327,7 +1352,7 @@ muxserver_listen(void)
1327 1352
1328 set_nonblock(muxserver_sock); 1353 set_nonblock(muxserver_sock);
1329 1354
1330 mux_listener_channel = channel_new("mux listener", 1355 mux_listener_channel = channel_new(ssh, "mux listener",
1331 SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, 1356 SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
1332 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 1357 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1333 0, options.control_path, 1); 1358 0, options.control_path, 1);
@@ -1338,7 +1363,7 @@ muxserver_listen(void)
1338 1363
1339/* Callback on open confirmation in mux master for a mux client session. */ 1364/* Callback on open confirmation in mux master for a mux client session. */
1340static void 1365static void
1341mux_session_confirm(int id, int success, void *arg) 1366mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
1342{ 1367{
1343 struct mux_session_confirm_ctx *cctx = arg; 1368 struct mux_session_confirm_ctx *cctx = arg;
1344 const char *display; 1369 const char *display;
@@ -1348,9 +1373,9 @@ mux_session_confirm(int id, int success, void *arg)
1348 1373
1349 if (cctx == NULL) 1374 if (cctx == NULL)
1350 fatal("%s: cctx == NULL", __func__); 1375 fatal("%s: cctx == NULL", __func__);
1351 if ((c = channel_by_id(id)) == NULL) 1376 if ((c = channel_by_id(ssh, id)) == NULL)
1352 fatal("%s: no channel for id %d", __func__, id); 1377 fatal("%s: no channel for id %d", __func__, id);
1353 if ((cc = channel_by_id(c->ctl_chan)) == NULL) 1378 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
1354 fatal("%s: channel %d lacks control channel %d", __func__, 1379 fatal("%s: channel %d lacks control channel %d", __func__,
1355 id, c->ctl_chan); 1380 id, c->ctl_chan);
1356 1381
@@ -1369,27 +1394,27 @@ mux_session_confirm(int id, int success, void *arg)
1369 char *proto, *data; 1394 char *proto, *data;
1370 1395
1371 /* Get reasonable local authentication information. */ 1396 /* Get reasonable local authentication information. */
1372 if (client_x11_get_proto(display, options.xauth_location, 1397 if (client_x11_get_proto(ssh, display, options.xauth_location,
1373 options.forward_x11_trusted, options.forward_x11_timeout, 1398 options.forward_x11_trusted, options.forward_x11_timeout,
1374 &proto, &data) == 0) { 1399 &proto, &data) == 0) {
1375 /* Request forwarding with authentication spoofing. */ 1400 /* Request forwarding with authentication spoofing. */
1376 debug("Requesting X11 forwarding with authentication " 1401 debug("Requesting X11 forwarding with authentication "
1377 "spoofing."); 1402 "spoofing.");
1378 x11_request_forwarding_with_spoofing(id, display, proto, 1403 x11_request_forwarding_with_spoofing(ssh, id,
1379 data, 1); 1404 display, proto, data, 1);
1380 /* XXX exit_on_forward_failure */ 1405 /* XXX exit_on_forward_failure */
1381 client_expect_confirm(id, "X11 forwarding", 1406 client_expect_confirm(ssh, id, "X11 forwarding",
1382 CONFIRM_WARN); 1407 CONFIRM_WARN);
1383 } 1408 }
1384 } 1409 }
1385 1410
1386 if (cctx->want_agent_fwd && options.forward_agent) { 1411 if (cctx->want_agent_fwd && options.forward_agent) {
1387 debug("Requesting authentication agent forwarding."); 1412 debug("Requesting authentication agent forwarding.");
1388 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1413 channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
1389 packet_send(); 1414 packet_send();
1390 } 1415 }
1391 1416
1392 client_session2_setup(id, cctx->want_tty, cctx->want_subsys, 1417 client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,
1393 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); 1418 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
1394 1419
1395 debug3("%s: sending success reply", __func__); 1420 debug3("%s: sending success reply", __func__);
@@ -1401,7 +1426,7 @@ mux_session_confirm(int id, int success, void *arg)
1401 1426
1402 done: 1427 done:
1403 /* Send reply */ 1428 /* Send reply */
1404 buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); 1429 buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply));
1405 buffer_free(&reply); 1430 buffer_free(&reply);
1406 1431
1407 if (cc->mux_pause <= 0) 1432 if (cc->mux_pause <= 0)
diff --git a/nchan.c b/nchan.c
index 36da8904a..74c855c90 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.65 2017/04/30 23:28:42 djm Exp $ */ 1/* $OpenBSD: nchan.c,v 1.66 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -34,7 +34,8 @@
34 34
35#include "openbsd-compat/sys-queue.h" 35#include "openbsd-compat/sys-queue.h"
36#include "ssh2.h" 36#include "ssh2.h"
37#include "buffer.h" 37#include "sshbuf.h"
38#include "ssherr.h"
38#include "packet.h" 39#include "packet.h"
39#include "channels.h" 40#include "channels.h"
40#include "compat.h" 41#include "compat.h"
@@ -73,15 +74,15 @@
73/* 74/*
74 * ACTIONS: should never update the channel states 75 * ACTIONS: should never update the channel states
75 */ 76 */
76static void chan_send_eof2(Channel *); 77static void chan_send_eof2(struct ssh *, Channel *);
77static void chan_send_eow2(Channel *); 78static void chan_send_eow2(struct ssh *, Channel *);
78 79
79/* helper */ 80/* helper */
80static void chan_shutdown_write(Channel *); 81static void chan_shutdown_write(struct ssh *, Channel *);
81static void chan_shutdown_read(Channel *); 82static void chan_shutdown_read(struct ssh *, Channel *);
82 83
83static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 84static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
84static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 85static const char *istates[] = { "open", "drain", "wait_oclose", "closed" };
85 86
86static void 87static void
87chan_set_istate(Channel *c, u_int next) 88chan_set_istate(Channel *c, u_int next)
@@ -104,12 +105,12 @@ chan_set_ostate(Channel *c, u_int next)
104} 105}
105 106
106void 107void
107chan_read_failed(Channel *c) 108chan_read_failed(struct ssh *ssh, Channel *c)
108{ 109{
109 debug2("channel %d: read failed", c->self); 110 debug2("channel %d: read failed", c->self);
110 switch (c->istate) { 111 switch (c->istate) {
111 case CHAN_INPUT_OPEN: 112 case CHAN_INPUT_OPEN:
112 chan_shutdown_read(c); 113 chan_shutdown_read(ssh, c);
113 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); 114 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
114 break; 115 break;
115 default: 116 default:
@@ -120,10 +121,10 @@ chan_read_failed(Channel *c)
120} 121}
121 122
122void 123void
123chan_ibuf_empty(Channel *c) 124chan_ibuf_empty(struct ssh *ssh, Channel *c)
124{ 125{
125 debug2("channel %d: ibuf empty", c->self); 126 debug2("channel %d: ibuf empty", c->self);
126 if (buffer_len(&c->input)) { 127 if (sshbuf_len(c->input)) {
127 error("channel %d: chan_ibuf_empty for non empty buffer", 128 error("channel %d: chan_ibuf_empty for non empty buffer",
128 c->self); 129 c->self);
129 return; 130 return;
@@ -131,7 +132,7 @@ chan_ibuf_empty(Channel *c)
131 switch (c->istate) { 132 switch (c->istate) {
132 case CHAN_INPUT_WAIT_DRAIN: 133 case CHAN_INPUT_WAIT_DRAIN:
133 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) 134 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
134 chan_send_eof2(c); 135 chan_send_eof2(ssh, c);
135 chan_set_istate(c, CHAN_INPUT_CLOSED); 136 chan_set_istate(c, CHAN_INPUT_CLOSED);
136 break; 137 break;
137 default: 138 default:
@@ -142,17 +143,17 @@ chan_ibuf_empty(Channel *c)
142} 143}
143 144
144void 145void
145chan_obuf_empty(Channel *c) 146chan_obuf_empty(struct ssh *ssh, Channel *c)
146{ 147{
147 debug2("channel %d: obuf empty", c->self); 148 debug2("channel %d: obuf empty", c->self);
148 if (buffer_len(&c->output)) { 149 if (sshbuf_len(c->output)) {
149 error("channel %d: chan_obuf_empty for non empty buffer", 150 error("channel %d: chan_obuf_empty for non empty buffer",
150 c->self); 151 c->self);
151 return; 152 return;
152 } 153 }
153 switch (c->ostate) { 154 switch (c->ostate) {
154 case CHAN_OUTPUT_WAIT_DRAIN: 155 case CHAN_OUTPUT_WAIT_DRAIN:
155 chan_shutdown_write(c); 156 chan_shutdown_write(ssh, c);
156 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 157 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
157 break; 158 break;
158 default: 159 default:
@@ -163,26 +164,29 @@ chan_obuf_empty(Channel *c)
163} 164}
164 165
165void 166void
166chan_rcvd_eow(Channel *c) 167chan_rcvd_eow(struct ssh *ssh, Channel *c)
167{ 168{
168 debug2("channel %d: rcvd eow", c->self); 169 debug2("channel %d: rcvd eow", c->self);
169 switch (c->istate) { 170 switch (c->istate) {
170 case CHAN_INPUT_OPEN: 171 case CHAN_INPUT_OPEN:
171 chan_shutdown_read(c); 172 chan_shutdown_read(ssh, c);
172 chan_set_istate(c, CHAN_INPUT_CLOSED); 173 chan_set_istate(c, CHAN_INPUT_CLOSED);
173 break; 174 break;
174 } 175 }
175} 176}
176 177
177static void 178static void
178chan_send_eof2(Channel *c) 179chan_send_eof2(struct ssh *ssh, Channel *c)
179{ 180{
181 int r;
182
180 debug2("channel %d: send eof", c->self); 183 debug2("channel %d: send eof", c->self);
181 switch (c->istate) { 184 switch (c->istate) {
182 case CHAN_INPUT_WAIT_DRAIN: 185 case CHAN_INPUT_WAIT_DRAIN:
183 packet_start(SSH2_MSG_CHANNEL_EOF); 186 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
184 packet_put_int(c->remote_id); 187 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
185 packet_send(); 188 (r = sshpkt_send(ssh)) != 0)
189 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
186 c->flags |= CHAN_EOF_SENT; 190 c->flags |= CHAN_EOF_SENT;
187 break; 191 break;
188 default: 192 default:
@@ -193,8 +197,10 @@ chan_send_eof2(Channel *c)
193} 197}
194 198
195static void 199static void
196chan_send_close2(Channel *c) 200chan_send_close2(struct ssh *ssh, Channel *c)
197{ 201{
202 int r;
203
198 debug2("channel %d: send close", c->self); 204 debug2("channel %d: send close", c->self);
199 if (c->ostate != CHAN_OUTPUT_CLOSED || 205 if (c->ostate != CHAN_OUTPUT_CLOSED ||
200 c->istate != CHAN_INPUT_CLOSED) { 206 c->istate != CHAN_INPUT_CLOSED) {
@@ -203,16 +209,19 @@ chan_send_close2(Channel *c)
203 } else if (c->flags & CHAN_CLOSE_SENT) { 209 } else if (c->flags & CHAN_CLOSE_SENT) {
204 error("channel %d: already sent close", c->self); 210 error("channel %d: already sent close", c->self);
205 } else { 211 } else {
206 packet_start(SSH2_MSG_CHANNEL_CLOSE); 212 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
207 packet_put_int(c->remote_id); 213 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
208 packet_send(); 214 (r = sshpkt_send(ssh)) != 0)
215 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
209 c->flags |= CHAN_CLOSE_SENT; 216 c->flags |= CHAN_CLOSE_SENT;
210 } 217 }
211} 218}
212 219
213static void 220static void
214chan_send_eow2(Channel *c) 221chan_send_eow2(struct ssh *ssh, Channel *c)
215{ 222{
223 int r;
224
216 debug2("channel %d: send eow", c->self); 225 debug2("channel %d: send eow", c->self);
217 if (c->ostate == CHAN_OUTPUT_CLOSED) { 226 if (c->ostate == CHAN_OUTPUT_CLOSED) {
218 error("channel %d: must not sent eow on closed output", 227 error("channel %d: must not sent eow on closed output",
@@ -221,30 +230,31 @@ chan_send_eow2(Channel *c)
221 } 230 }
222 if (!(datafellows & SSH_NEW_OPENSSH)) 231 if (!(datafellows & SSH_NEW_OPENSSH))
223 return; 232 return;
224 packet_start(SSH2_MSG_CHANNEL_REQUEST); 233 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
225 packet_put_int(c->remote_id); 234 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
226 packet_put_cstring("eow@openssh.com"); 235 (r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 ||
227 packet_put_char(0); 236 (r = sshpkt_put_u8(ssh, 0)) != 0 ||
228 packet_send(); 237 (r = sshpkt_send(ssh)) != 0)
238 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
229} 239}
230 240
231/* shared */ 241/* shared */
232 242
233void 243void
234chan_rcvd_ieof(Channel *c) 244chan_rcvd_ieof(struct ssh *ssh, Channel *c)
235{ 245{
236 debug2("channel %d: rcvd eof", c->self); 246 debug2("channel %d: rcvd eof", c->self);
237 c->flags |= CHAN_EOF_RCVD; 247 c->flags |= CHAN_EOF_RCVD;
238 if (c->ostate == CHAN_OUTPUT_OPEN) 248 if (c->ostate == CHAN_OUTPUT_OPEN)
239 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 249 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
240 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && 250 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
241 buffer_len(&c->output) == 0 && 251 sshbuf_len(c->output) == 0 &&
242 !CHANNEL_EFD_OUTPUT_ACTIVE(c)) 252 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
243 chan_obuf_empty(c); 253 chan_obuf_empty(ssh, c);
244} 254}
245 255
246void 256void
247chan_rcvd_oclose(Channel *c) 257chan_rcvd_oclose(struct ssh *ssh, Channel *c)
248{ 258{
249 debug2("channel %d: rcvd close", c->self); 259 debug2("channel %d: rcvd close", c->self);
250 if (!(c->flags & CHAN_LOCAL)) { 260 if (!(c->flags & CHAN_LOCAL)) {
@@ -270,27 +280,27 @@ chan_rcvd_oclose(Channel *c)
270 } 280 }
271 switch (c->istate) { 281 switch (c->istate) {
272 case CHAN_INPUT_OPEN: 282 case CHAN_INPUT_OPEN:
273 chan_shutdown_read(c); 283 chan_shutdown_read(ssh, c);
274 chan_set_istate(c, CHAN_INPUT_CLOSED); 284 chan_set_istate(c, CHAN_INPUT_CLOSED);
275 break; 285 break;
276 case CHAN_INPUT_WAIT_DRAIN: 286 case CHAN_INPUT_WAIT_DRAIN:
277 if (!(c->flags & CHAN_LOCAL)) 287 if (!(c->flags & CHAN_LOCAL))
278 chan_send_eof2(c); 288 chan_send_eof2(ssh, c);
279 chan_set_istate(c, CHAN_INPUT_CLOSED); 289 chan_set_istate(c, CHAN_INPUT_CLOSED);
280 break; 290 break;
281 } 291 }
282} 292}
283 293
284void 294void
285chan_write_failed(Channel *c) 295chan_write_failed(struct ssh *ssh, Channel *c)
286{ 296{
287 debug2("channel %d: write failed", c->self); 297 debug2("channel %d: write failed", c->self);
288 switch (c->ostate) { 298 switch (c->ostate) {
289 case CHAN_OUTPUT_OPEN: 299 case CHAN_OUTPUT_OPEN:
290 case CHAN_OUTPUT_WAIT_DRAIN: 300 case CHAN_OUTPUT_WAIT_DRAIN:
291 chan_shutdown_write(c); 301 chan_shutdown_write(ssh, c);
292 if (strcmp(c->ctype, "session") == 0) 302 if (strcmp(c->ctype, "session") == 0)
293 chan_send_eow2(c); 303 chan_send_eow2(ssh, c);
294 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 304 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
295 break; 305 break;
296 default: 306 default:
@@ -301,13 +311,13 @@ chan_write_failed(Channel *c)
301} 311}
302 312
303void 313void
304chan_mark_dead(Channel *c) 314chan_mark_dead(struct ssh *ssh, Channel *c)
305{ 315{
306 c->type = SSH_CHANNEL_ZOMBIE; 316 c->type = SSH_CHANNEL_ZOMBIE;
307} 317}
308 318
309int 319int
310chan_is_dead(Channel *c, int do_send) 320chan_is_dead(struct ssh *ssh, Channel *c, int do_send)
311{ 321{
312 if (c->type == SSH_CHANNEL_ZOMBIE) { 322 if (c->type == SSH_CHANNEL_ZOMBIE) {
313 debug2("channel %d: zombie", c->self); 323 debug2("channel %d: zombie", c->self);
@@ -318,9 +328,9 @@ chan_is_dead(Channel *c, int do_send)
318 if ((datafellows & SSH_BUG_EXTEOF) && 328 if ((datafellows & SSH_BUG_EXTEOF) &&
319 c->extended_usage == CHAN_EXTENDED_WRITE && 329 c->extended_usage == CHAN_EXTENDED_WRITE &&
320 c->efd != -1 && 330 c->efd != -1 &&
321 buffer_len(&c->extended) > 0) { 331 sshbuf_len(c->extended) > 0) {
322 debug2("channel %d: active efd: %d len %d", 332 debug2("channel %d: active efd: %d len %zu",
323 c->self, c->efd, buffer_len(&c->extended)); 333 c->self, c->efd, sshbuf_len(c->extended));
324 return 0; 334 return 0;
325 } 335 }
326 if (c->flags & CHAN_LOCAL) { 336 if (c->flags & CHAN_LOCAL) {
@@ -329,7 +339,7 @@ chan_is_dead(Channel *c, int do_send)
329 } 339 }
330 if (!(c->flags & CHAN_CLOSE_SENT)) { 340 if (!(c->flags & CHAN_CLOSE_SENT)) {
331 if (do_send) { 341 if (do_send) {
332 chan_send_close2(c); 342 chan_send_close2(ssh, c);
333 } else { 343 } else {
334 /* channel would be dead if we sent a close */ 344 /* channel would be dead if we sent a close */
335 if (c->flags & CHAN_CLOSE_RCVD) { 345 if (c->flags & CHAN_CLOSE_RCVD) {
@@ -349,9 +359,9 @@ chan_is_dead(Channel *c, int do_send)
349 359
350/* helper */ 360/* helper */
351static void 361static void
352chan_shutdown_write(Channel *c) 362chan_shutdown_write(struct ssh *ssh, Channel *c)
353{ 363{
354 buffer_clear(&c->output); 364 sshbuf_reset(c->output);
355 if (c->type == SSH_CHANNEL_LARVAL) 365 if (c->type == SSH_CHANNEL_LARVAL)
356 return; 366 return;
357 /* shutdown failure is allowed if write failed already */ 367 /* shutdown failure is allowed if write failed already */
@@ -362,7 +372,7 @@ chan_shutdown_write(Channel *c)
362 "shutdown() failed for fd %d: %.100s", 372 "shutdown() failed for fd %d: %.100s",
363 c->self, c->sock, strerror(errno)); 373 c->self, c->sock, strerror(errno));
364 } else { 374 } else {
365 if (channel_close_fd(&c->wfd) < 0) 375 if (channel_close_fd(ssh, &c->wfd) < 0)
366 logit("channel %d: chan_shutdown_write: " 376 logit("channel %d: chan_shutdown_write: "
367 "close() failed for fd %d: %.100s", 377 "close() failed for fd %d: %.100s",
368 c->self, c->wfd, strerror(errno)); 378 c->self, c->wfd, strerror(errno));
@@ -370,7 +380,7 @@ chan_shutdown_write(Channel *c)
370} 380}
371 381
372static void 382static void
373chan_shutdown_read(Channel *c) 383chan_shutdown_read(struct ssh *ssh, Channel *c)
374{ 384{
375 if (c->type == SSH_CHANNEL_LARVAL) 385 if (c->type == SSH_CHANNEL_LARVAL)
376 return; 386 return;
@@ -388,7 +398,7 @@ chan_shutdown_read(Channel *c)
388 c->self, c->sock, c->istate, c->ostate, 398 c->self, c->sock, c->istate, c->ostate,
389 strerror(errno)); 399 strerror(errno));
390 } else { 400 } else {
391 if (channel_close_fd(&c->rfd) < 0) 401 if (channel_close_fd(ssh, &c->rfd) < 0)
392 logit("channel %d: chan_shutdown_read: " 402 logit("channel %d: chan_shutdown_read: "
393 "close() failed for fd %d: %.100s", 403 "close() failed for fd %d: %.100s",
394 c->self, c->rfd, strerror(errno)); 404 c->self, c->rfd, strerror(errno));
diff --git a/packet.c b/packet.c
index ff69b6601..f114ea52c 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.263 2017/07/23 23:37:02 djm Exp $ */ 1/* $OpenBSD: packet.c,v 1.264 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2090,35 +2090,6 @@ ssh_packet_get_maxsize(struct ssh *ssh)
2090 return ssh->state->max_packet_size; 2090 return ssh->state->max_packet_size;
2091} 2091}
2092 2092
2093/*
2094 * 9.2. Ignored Data Message
2095 *
2096 * byte SSH_MSG_IGNORE
2097 * string data
2098 *
2099 * All implementations MUST understand (and ignore) this message at any
2100 * time (after receiving the protocol version). No implementation is
2101 * required to send them. This message can be used as an additional
2102 * protection measure against advanced traffic analysis techniques.
2103 */
2104void
2105ssh_packet_send_ignore(struct ssh *ssh, int nbytes)
2106{
2107 u_int32_t rnd = 0;
2108 int r, i;
2109
2110 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
2111 (r = sshpkt_put_u32(ssh, nbytes)) != 0)
2112 fatal("%s: %s", __func__, ssh_err(r));
2113 for (i = 0; i < nbytes; i++) {
2114 if (i % 4 == 0)
2115 rnd = arc4random();
2116 if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0)
2117 fatal("%s: %s", __func__, ssh_err(r));
2118 rnd >>= 8;
2119 }
2120}
2121
2122void 2093void
2123ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds) 2094ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds)
2124{ 2095{
@@ -2539,6 +2510,12 @@ sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp)
2539} 2510}
2540 2511
2541int 2512int
2513sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp)
2514{
2515 return sshbuf_peek_string_direct(ssh->state->incoming_packet, valp, lenp);
2516}
2517
2518int
2542sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp) 2519sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp)
2543{ 2520{
2544 return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp); 2521 return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp);
@@ -2621,6 +2598,37 @@ ssh_packet_send_mux(struct ssh *ssh)
2621 return 0; 2598 return 0;
2622} 2599}
2623 2600
2601/*
2602 * 9.2. Ignored Data Message
2603 *
2604 * byte SSH_MSG_IGNORE
2605 * string data
2606 *
2607 * All implementations MUST understand (and ignore) this message at any
2608 * time (after receiving the protocol version). No implementation is
2609 * required to send them. This message can be used as an additional
2610 * protection measure against advanced traffic analysis techniques.
2611 */
2612int
2613sshpkt_msg_ignore(struct ssh *ssh, u_int nbytes)
2614{
2615 u_int32_t rnd = 0;
2616 int r;
2617 u_int i;
2618
2619 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
2620 (r = sshpkt_put_u32(ssh, nbytes)) != 0)
2621 return r;
2622 for (i = 0; i < nbytes; i++) {
2623 if (i % 4 == 0)
2624 rnd = arc4random();
2625 if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0)
2626 return r;
2627 rnd >>= 8;
2628 }
2629 return 0;
2630}
2631
2624/* send it */ 2632/* send it */
2625 2633
2626int 2634int
diff --git a/packet.h b/packet.h
index 6ce6dd560..40837e9db 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.h,v 1.81 2017/05/31 08:09:45 markus Exp $ */ 1/* $OpenBSD: packet.h,v 1.82 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -80,6 +80,9 @@ struct ssh {
80 /* Client/Server authentication context */ 80 /* Client/Server authentication context */
81 void *authctxt; 81 void *authctxt;
82 82
83 /* Channels context */
84 struct ssh_channels *chanctxt;
85
83 /* APP data */ 86 /* APP data */
84 void *app_data; 87 void *app_data;
85}; 88};
@@ -143,7 +146,6 @@ int ssh_packet_not_very_much_data_to_write(struct ssh *);
143 146
144int ssh_packet_connection_is_on_socket(struct ssh *); 147int ssh_packet_connection_is_on_socket(struct ssh *);
145int ssh_packet_remaining(struct ssh *); 148int ssh_packet_remaining(struct ssh *);
146void ssh_packet_send_ignore(struct ssh *, int);
147 149
148void tty_make_modes(int, struct termios *); 150void tty_make_modes(int, struct termios *);
149void tty_parse_modes(int, int *); 151void tty_parse_modes(int, int *);
@@ -174,6 +176,7 @@ int sshpkt_disconnect(struct ssh *, const char *fmt, ...)
174 __attribute__((format(printf, 2, 3))); 176 __attribute__((format(printf, 2, 3)));
175int sshpkt_add_padding(struct ssh *, u_char); 177int sshpkt_add_padding(struct ssh *, u_char);
176void sshpkt_fatal(struct ssh *ssh, const char *tag, int r); 178void sshpkt_fatal(struct ssh *ssh, const char *tag, int r);
179int sshpkt_msg_ignore(struct ssh *, u_int);
177 180
178int sshpkt_put(struct ssh *ssh, const void *v, size_t len); 181int sshpkt_put(struct ssh *ssh, const void *v, size_t len);
179int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b); 182int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b);
@@ -192,6 +195,7 @@ int sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp);
192int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp); 195int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp);
193int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); 196int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp);
194int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); 197int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
198int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
195int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); 199int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp);
196int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); 200int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g);
197int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); 201int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v);
diff --git a/servconf.c b/servconf.c
index ed1fc71cf..e0e43c3dd 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.309 2017/06/24 06:34:38 djm Exp $ */ 2/* $OpenBSD: servconf.c,v 1.310 2017/09/12 06:32:07 djm Exp $ */
3/* 3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved 5 * All rights reserved
@@ -149,7 +149,7 @@ initialize_server_options(ServerOptions *options)
149 options->num_authkeys_files = 0; 149 options->num_authkeys_files = 0;
150 options->num_accept_env = 0; 150 options->num_accept_env = 0;
151 options->permit_tun = -1; 151 options->permit_tun = -1;
152 options->num_permitted_opens = -1; 152 options->permitted_opens = NULL;
153 options->adm_forced_command = NULL; 153 options->adm_forced_command = NULL;
154 options->chroot_directory = NULL; 154 options->chroot_directory = NULL;
155 options->authorized_keys_command = NULL; 155 options->authorized_keys_command = NULL;
@@ -697,6 +697,44 @@ process_queued_listen_addrs(ServerOptions *options)
697 options->num_queued_listens = 0; 697 options->num_queued_listens = 0;
698} 698}
699 699
700/*
701 * Inform channels layer of permitopen options from configuration.
702 */
703void
704process_permitopen(struct ssh *ssh, ServerOptions *options)
705{
706 u_int i;
707 int port;
708 char *host, *arg, *oarg;
709
710 channel_clear_adm_permitted_opens(ssh);
711 if (options->num_permitted_opens == 0)
712 return; /* permit any */
713
714 /* handle keywords: "any" / "none" */
715 if (options->num_permitted_opens == 1 &&
716 strcmp(options->permitted_opens[0], "any") == 0)
717 return;
718 if (options->num_permitted_opens == 1 &&
719 strcmp(options->permitted_opens[0], "none") == 0) {
720 channel_disable_adm_local_opens(ssh);
721 return;
722 }
723 /* Otherwise treat it as a list of permitted host:port */
724 for (i = 0; i < options->num_permitted_opens; i++) {
725 oarg = arg = xstrdup(options->permitted_opens[i]);
726 host = hpdelim(&arg);
727 if (host == NULL)
728 fatal("%s: missing host in PermitOpen", __func__);
729 host = cleanhostname(host);
730 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
731 fatal("%s: bad port number in PermitOpen", __func__);
732 /* Send it to channels layer */
733 channel_add_adm_permitted_opens(ssh, host, port);
734 free(oarg);
735 }
736}
737
700struct connection_info * 738struct connection_info *
701get_connection_info(int populate, int use_dns) 739get_connection_info(int populate, int use_dns)
702{ 740{
@@ -954,7 +992,7 @@ process_server_config_line(ServerOptions *options, char *line,
954 const char *filename, int linenum, int *activep, 992 const char *filename, int linenum, int *activep,
955 struct connection_info *connectinfo) 993 struct connection_info *connectinfo)
956{ 994{
957 char *cp, **charptr, *arg, *p; 995 char *cp, **charptr, *arg, *arg2, *p;
958 int cmdline = 0, *intptr, value, value2, n, port; 996 int cmdline = 0, *intptr, value, value2, n, port;
959 SyslogFacility *log_facility_ptr; 997 SyslogFacility *log_facility_ptr;
960 LogLevel *log_level_ptr; 998 LogLevel *log_level_ptr;
@@ -1625,24 +1663,17 @@ process_server_config_line(ServerOptions *options, char *line,
1625 if (!arg || *arg == '\0') 1663 if (!arg || *arg == '\0')
1626 fatal("%s line %d: missing PermitOpen specification", 1664 fatal("%s line %d: missing PermitOpen specification",
1627 filename, linenum); 1665 filename, linenum);
1628 n = options->num_permitted_opens; /* modified later */ 1666 i = options->num_permitted_opens; /* modified later */
1629 if (strcmp(arg, "any") == 0) { 1667 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1630 if (*activep && n == -1) { 1668 if (*activep && i == 0)
1631 channel_clear_adm_permitted_opens();
1632 options->num_permitted_opens = 0;
1633 }
1634 break;
1635 }
1636 if (strcmp(arg, "none") == 0) {
1637 if (*activep && n == -1) {
1638 options->num_permitted_opens = 1; 1669 options->num_permitted_opens = 1;
1639 channel_disable_adm_local_opens(); 1670 options->permitted_opens = xcalloc(1,
1640 } 1671 sizeof(*options->permitted_opens));
1672 options->permitted_opens[0] = xstrdup(arg);
1641 break; 1673 break;
1642 } 1674 }
1643 if (*activep && n == -1)
1644 channel_clear_adm_permitted_opens();
1645 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { 1675 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1676 arg2 = xstrdup(arg);
1646 p = hpdelim(&arg); 1677 p = hpdelim(&arg);
1647 if (p == NULL) 1678 if (p == NULL)
1648 fatal("%s line %d: missing host in PermitOpen", 1679 fatal("%s line %d: missing host in PermitOpen",
@@ -1651,9 +1682,16 @@ process_server_config_line(ServerOptions *options, char *line,
1651 if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 1682 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1652 fatal("%s line %d: bad port number in " 1683 fatal("%s line %d: bad port number in "
1653 "PermitOpen", filename, linenum); 1684 "PermitOpen", filename, linenum);
1654 if (*activep && n == -1) 1685 if (*activep && i == 0) {
1655 options->num_permitted_opens = 1686 options->permitted_opens = xrecallocarray(
1656 channel_add_adm_permitted_opens(p, port); 1687 options->permitted_opens,
1688 options->num_permitted_opens,
1689 options->num_permitted_opens + 1,
1690 sizeof(*options->permitted_opens));
1691 i = options->num_permitted_opens++;
1692 options->permitted_opens[i] = arg2;
1693 } else
1694 free(arg2);
1657 } 1695 }
1658 break; 1696 break;
1659 1697
@@ -2352,5 +2390,12 @@ dump_config(ServerOptions *o)
2352 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, 2390 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
2353 o->rekey_interval); 2391 o->rekey_interval);
2354 2392
2355 channel_print_adm_permitted_opens(); 2393 printf("permitopen");
2394 if (o->num_permitted_opens == 0)
2395 printf(" any");
2396 else {
2397 for (i = 0; i < o->num_permitted_opens; i++)
2398 printf(" %s", o->permitted_opens[i]);
2399 }
2400 printf("\n");
2356} 2401}
diff --git a/servconf.h b/servconf.h
index c2848a765..ffcbc3319 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.124 2017/06/24 06:34:38 djm Exp $ */ 1/* $OpenBSD: servconf.h,v 1.125 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -48,12 +48,19 @@
48#define FORWARD_LOCAL (1<<1) 48#define FORWARD_LOCAL (1<<1)
49#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) 49#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL)
50 50
51/* PermitOpen */
52#define PERMITOPEN_ANY 0
53#define PERMITOPEN_NONE -2
54
51#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ 55#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
52#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ 56#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
53 57
54/* Magic name for internal sftp-server */ 58/* Magic name for internal sftp-server */
55#define INTERNAL_SFTP_NAME "internal-sftp" 59#define INTERNAL_SFTP_NAME "internal-sftp"
56 60
61struct ssh;
62struct fwd_perm_list;
63
57typedef struct { 64typedef struct {
58 u_int num_ports; 65 u_int num_ports;
59 u_int ports_from_cmdline; 66 u_int ports_from_cmdline;
@@ -169,7 +176,8 @@ typedef struct {
169 176
170 int permit_tun; 177 int permit_tun;
171 178
172 int num_permitted_opens; 179 char **permitted_opens;
180 u_int num_permitted_opens; /* May also be one of PERMITOPEN_* */
173 181
174 char *chroot_directory; 182 char *chroot_directory;
175 char *revoked_keys_file; 183 char *revoked_keys_file;
@@ -229,6 +237,7 @@ struct connection_info {
229 M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \ 237 M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
230 M_CP_STRARRAYOPT(accept_env, num_accept_env); \ 238 M_CP_STRARRAYOPT(accept_env, num_accept_env); \
231 M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \ 239 M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
240 M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
232 } while (0) 241 } while (0)
233 242
234struct connection_info *get_connection_info(int, int); 243struct connection_info *get_connection_info(int, int);
@@ -236,6 +245,7 @@ void initialize_server_options(ServerOptions *);
236void fill_default_server_options(ServerOptions *); 245void fill_default_server_options(ServerOptions *);
237int process_server_config_line(ServerOptions *, char *, const char *, int, 246int process_server_config_line(ServerOptions *, char *, const char *, int,
238 int *, struct connection_info *); 247 int *, struct connection_info *);
248void process_permitopen(struct ssh *ssh, ServerOptions *options);
239void load_server_config(const char *, Buffer *); 249void load_server_config(const char *, Buffer *);
240void parse_server_config(ServerOptions *, const char *, Buffer *, 250void parse_server_config(ServerOptions *, const char *, Buffer *,
241 struct connection_info *); 251 struct connection_info *);
diff --git a/serverloop.c b/serverloop.c
index bc56709b1..567159410 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.196 2017/08/30 03:59:08 djm Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.197 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -165,7 +165,7 @@ sigterm_handler(int sig)
165} 165}
166 166
167static void 167static void
168client_alive_check(void) 168client_alive_check(struct ssh *ssh)
169{ 169{
170 int channel_id; 170 int channel_id;
171 171
@@ -179,12 +179,13 @@ client_alive_check(void)
179 * send a bogus global/channel request with "wantreply", 179 * send a bogus global/channel request with "wantreply",
180 * we should get back a failure 180 * we should get back a failure
181 */ 181 */
182 if ((channel_id = channel_find_open()) == -1) { 182 if ((channel_id = channel_find_open(ssh)) == -1) {
183 packet_start(SSH2_MSG_GLOBAL_REQUEST); 183 packet_start(SSH2_MSG_GLOBAL_REQUEST);
184 packet_put_cstring("keepalive@openssh.com"); 184 packet_put_cstring("keepalive@openssh.com");
185 packet_put_char(1); /* boolean: want reply */ 185 packet_put_char(1); /* boolean: want reply */
186 } else { 186 } else {
187 channel_request_start(channel_id, "keepalive@openssh.com", 1); 187 channel_request_start(ssh, channel_id,
188 "keepalive@openssh.com", 1);
188 } 189 }
189 packet_send(); 190 packet_send();
190} 191}
@@ -196,7 +197,8 @@ client_alive_check(void)
196 * for the duration of the wait (0 = infinite). 197 * for the duration of the wait (0 = infinite).
197 */ 198 */
198static void 199static void
199wait_until_can_do_something(int connection_in, int connection_out, 200wait_until_can_do_something(struct ssh *ssh,
201 int connection_in, int connection_out,
200 fd_set **readsetp, fd_set **writesetp, int *maxfdp, 202 fd_set **readsetp, fd_set **writesetp, int *maxfdp,
201 u_int *nallocp, u_int64_t max_time_ms) 203 u_int *nallocp, u_int64_t max_time_ms)
202{ 204{
@@ -207,7 +209,7 @@ wait_until_can_do_something(int connection_in, int connection_out,
207 static time_t last_client_time; 209 static time_t last_client_time;
208 210
209 /* Allocate and update select() masks for channel descriptors. */ 211 /* Allocate and update select() masks for channel descriptors. */
210 channel_prepare_select(active_state, readsetp, writesetp, maxfdp, 212 channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
211 nallocp, &minwait_secs); 213 nallocp, &minwait_secs);
212 214
213 /* XXX need proper deadline system for rekey/client alive */ 215 /* XXX need proper deadline system for rekey/client alive */
@@ -273,12 +275,12 @@ wait_until_can_do_something(int connection_in, int connection_out,
273 time_t now = monotime(); 275 time_t now = monotime();
274 276
275 if (ret == 0) { /* timeout */ 277 if (ret == 0) { /* timeout */
276 client_alive_check(); 278 client_alive_check(ssh);
277 } else if (FD_ISSET(connection_in, *readsetp)) { 279 } else if (FD_ISSET(connection_in, *readsetp)) {
278 last_client_time = now; 280 last_client_time = now;
279 } else if (last_client_time != 0 && last_client_time + 281 } else if (last_client_time != 0 && last_client_time +
280 options.client_alive_interval <= now) { 282 options.client_alive_interval <= now) {
281 client_alive_check(); 283 client_alive_check(ssh);
282 last_client_time = now; 284 last_client_time = now;
283 } 285 }
284 } 286 }
@@ -291,9 +293,8 @@ wait_until_can_do_something(int connection_in, int connection_out,
291 * in buffers and processed later. 293 * in buffers and processed later.
292 */ 294 */
293static int 295static int
294process_input(fd_set *readset, int connection_in) 296process_input(struct ssh *ssh, fd_set *readset, int connection_in)
295{ 297{
296 struct ssh *ssh = active_state; /* XXX */
297 int len; 298 int len;
298 char buf[16384]; 299 char buf[16384];
299 300
@@ -333,13 +334,13 @@ process_output(fd_set *writeset, int connection_out)
333} 334}
334 335
335static void 336static void
336process_buffered_input_packets(void) 337process_buffered_input_packets(struct ssh *ssh)
337{ 338{
338 ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, NULL); 339 ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, NULL);
339} 340}
340 341
341static void 342static void
342collect_children(void) 343collect_children(struct ssh *ssh)
343{ 344{
344 pid_t pid; 345 pid_t pid;
345 sigset_t oset, nset; 346 sigset_t oset, nset;
@@ -354,14 +355,14 @@ collect_children(void)
354 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || 355 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
355 (pid < 0 && errno == EINTR)) 356 (pid < 0 && errno == EINTR))
356 if (pid > 0) 357 if (pid > 0)
357 session_close_by_pid(pid, status); 358 session_close_by_pid(ssh, pid, status);
358 child_terminated = 0; 359 child_terminated = 0;
359 } 360 }
360 sigprocmask(SIG_SETMASK, &oset, NULL); 361 sigprocmask(SIG_SETMASK, &oset, NULL);
361} 362}
362 363
363void 364void
364server_loop2(Authctxt *authctxt) 365server_loop2(struct ssh *ssh, Authctxt *authctxt)
365{ 366{
366 fd_set *readset = NULL, *writeset = NULL; 367 fd_set *readset = NULL, *writeset = NULL;
367 int max_fd; 368 int max_fd;
@@ -389,18 +390,17 @@ server_loop2(Authctxt *authctxt)
389 server_init_dispatch(); 390 server_init_dispatch();
390 391
391 for (;;) { 392 for (;;) {
392 process_buffered_input_packets(); 393 process_buffered_input_packets(ssh);
393 394
394 if (!ssh_packet_is_rekeying(active_state) && 395 if (!ssh_packet_is_rekeying(ssh) &&
395 packet_not_very_much_data_to_write()) 396 packet_not_very_much_data_to_write())
396 channel_output_poll(); 397 channel_output_poll(ssh);
397 if (options.rekey_interval > 0 && 398 if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh))
398 !ssh_packet_is_rekeying(active_state))
399 rekey_timeout_ms = packet_get_rekey_timeout() * 1000; 399 rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
400 else 400 else
401 rekey_timeout_ms = 0; 401 rekey_timeout_ms = 0;
402 402
403 wait_until_can_do_something(connection_in, connection_out, 403 wait_until_can_do_something(ssh, connection_in, connection_out,
404 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); 404 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
405 405
406 if (received_sigterm) { 406 if (received_sigterm) {
@@ -409,23 +409,23 @@ server_loop2(Authctxt *authctxt)
409 cleanup_exit(255); 409 cleanup_exit(255);
410 } 410 }
411 411
412 collect_children(); 412 collect_children(ssh);
413 if (!ssh_packet_is_rekeying(active_state)) 413 if (!ssh_packet_is_rekeying(ssh))
414 channel_after_select(active_state, readset, writeset); 414 channel_after_select(ssh, readset, writeset);
415 if (process_input(readset, connection_in) < 0) 415 if (process_input(ssh, readset, connection_in) < 0)
416 break; 416 break;
417 process_output(writeset, connection_out); 417 process_output(writeset, connection_out);
418 } 418 }
419 collect_children(); 419 collect_children(ssh);
420 420
421 free(readset); 421 free(readset);
422 free(writeset); 422 free(writeset);
423 423
424 /* free all channels, no more reads and writes */ 424 /* free all channels, no more reads and writes */
425 channel_free_all(); 425 channel_free_all(ssh);
426 426
427 /* free remaining sessions, e.g. remove wtmp entries */ 427 /* free remaining sessions, e.g. remove wtmp entries */
428 session_destroy_all(NULL); 428 session_destroy_all(ssh, NULL);
429} 429}
430 430
431static int 431static int
@@ -442,7 +442,7 @@ server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
442} 442}
443 443
444static Channel * 444static Channel *
445server_request_direct_tcpip(int *reason, const char **errmsg) 445server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
446{ 446{
447 Channel *c = NULL; 447 Channel *c = NULL;
448 char *target, *originator; 448 char *target, *originator;
@@ -460,7 +460,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
460 /* XXX fine grained permissions */ 460 /* XXX fine grained permissions */
461 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && 461 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
462 !no_port_forwarding_flag && !options.disable_forwarding) { 462 !no_port_forwarding_flag && !options.disable_forwarding) {
463 c = channel_connect_to_port(target, target_port, 463 c = channel_connect_to_port(ssh, target, target_port,
464 "direct-tcpip", "direct-tcpip", reason, errmsg); 464 "direct-tcpip", "direct-tcpip", reason, errmsg);
465 } else { 465 } else {
466 logit("refused local port forward: " 466 logit("refused local port forward: "
@@ -477,7 +477,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
477} 477}
478 478
479static Channel * 479static Channel *
480server_request_direct_streamlocal(void) 480server_request_direct_streamlocal(struct ssh *ssh)
481{ 481{
482 Channel *c = NULL; 482 Channel *c = NULL;
483 char *target, *originator; 483 char *target, *originator;
@@ -499,7 +499,7 @@ server_request_direct_streamlocal(void)
499 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && 499 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
500 !no_port_forwarding_flag && !options.disable_forwarding && 500 !no_port_forwarding_flag && !options.disable_forwarding &&
501 (pw->pw_uid == 0 || use_privsep)) { 501 (pw->pw_uid == 0 || use_privsep)) {
502 c = channel_connect_to_path(target, 502 c = channel_connect_to_path(ssh, target,
503 "direct-streamlocal@openssh.com", "direct-streamlocal"); 503 "direct-streamlocal@openssh.com", "direct-streamlocal");
504 } else { 504 } else {
505 logit("refused streamlocal port forward: " 505 logit("refused streamlocal port forward: "
@@ -514,7 +514,7 @@ server_request_direct_streamlocal(void)
514} 514}
515 515
516static Channel * 516static Channel *
517server_request_tun(void) 517server_request_tun(struct ssh *ssh)
518{ 518{
519 Channel *c = NULL; 519 Channel *c = NULL;
520 int mode, tun; 520 int mode, tun;
@@ -544,7 +544,7 @@ server_request_tun(void)
544 sock = tun_open(tun, mode); 544 sock = tun_open(tun, mode);
545 if (sock < 0) 545 if (sock < 0)
546 goto done; 546 goto done;
547 c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, 547 c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
548 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); 548 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
549 c->datagram = 1; 549 c->datagram = 1;
550#if defined(SSH_TUN_FILTER) 550#if defined(SSH_TUN_FILTER)
@@ -560,7 +560,7 @@ server_request_tun(void)
560} 560}
561 561
562static Channel * 562static Channel *
563server_request_session(void) 563server_request_session(struct ssh *ssh)
564{ 564{
565 Channel *c; 565 Channel *c;
566 566
@@ -578,15 +578,15 @@ server_request_session(void)
578 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all 578 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
579 * CHANNEL_REQUEST messages is registered. 579 * CHANNEL_REQUEST messages is registered.
580 */ 580 */
581 c = channel_new("session", SSH_CHANNEL_LARVAL, 581 c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL,
582 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 582 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
583 0, "server-session", 1); 583 0, "server-session", 1);
584 if (session_open(the_authctxt, c->self) != 1) { 584 if (session_open(the_authctxt, c->self) != 1) {
585 debug("session open failed, free channel %d", c->self); 585 debug("session open failed, free channel %d", c->self);
586 channel_free(c); 586 channel_free(ssh, c);
587 return NULL; 587 return NULL;
588 } 588 }
589 channel_register_cleanup(c->self, session_close_by_channel, 0); 589 channel_register_cleanup(ssh, c->self, session_close_by_channel, 0);
590 return c; 590 return c;
591} 591}
592 592
@@ -608,13 +608,13 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
608 ctype, rchan, rwindow, rmaxpack); 608 ctype, rchan, rwindow, rmaxpack);
609 609
610 if (strcmp(ctype, "session") == 0) { 610 if (strcmp(ctype, "session") == 0) {
611 c = server_request_session(); 611 c = server_request_session(ssh);
612 } else if (strcmp(ctype, "direct-tcpip") == 0) { 612 } else if (strcmp(ctype, "direct-tcpip") == 0) {
613 c = server_request_direct_tcpip(&reason, &errmsg); 613 c = server_request_direct_tcpip(ssh, &reason, &errmsg);
614 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { 614 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) {
615 c = server_request_direct_streamlocal(); 615 c = server_request_direct_streamlocal(ssh);
616 } else if (strcmp(ctype, "tun@openssh.com") == 0) { 616 } else if (strcmp(ctype, "tun@openssh.com") == 0) {
617 c = server_request_tun(); 617 c = server_request_tun(ssh);
618 } 618 }
619 if (c != NULL) { 619 if (c != NULL) {
620 debug("server_input_channel_open: confirm %s", ctype); 620 debug("server_input_channel_open: confirm %s", ctype);
@@ -645,9 +645,8 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
645} 645}
646 646
647static int 647static int
648server_input_hostkeys_prove(struct sshbuf **respp) 648server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
649{ 649{
650 struct ssh *ssh = active_state; /* XXX */
651 struct sshbuf *resp = NULL; 650 struct sshbuf *resp = NULL;
652 struct sshbuf *sigbuf = NULL; 651 struct sshbuf *sigbuf = NULL;
653 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; 652 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
@@ -750,7 +749,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
750 packet_send_debug("Server has disabled port forwarding."); 749 packet_send_debug("Server has disabled port forwarding.");
751 } else { 750 } else {
752 /* Start listening on the port */ 751 /* Start listening on the port */
753 success = channel_setup_remote_fwd_listener(&fwd, 752 success = channel_setup_remote_fwd_listener(ssh, &fwd,
754 &allocated_listen_port, &options.fwd_opts); 753 &allocated_listen_port, &options.fwd_opts);
755 } 754 }
756 free(fwd.listen_host); 755 free(fwd.listen_host);
@@ -768,7 +767,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
768 debug("%s: cancel-tcpip-forward addr %s port %d", __func__, 767 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
769 fwd.listen_host, fwd.listen_port); 768 fwd.listen_host, fwd.listen_port);
770 769
771 success = channel_cancel_rport_listener(&fwd); 770 success = channel_cancel_rport_listener(ssh, &fwd);
772 free(fwd.listen_host); 771 free(fwd.listen_host);
773 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { 772 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
774 struct Forward fwd; 773 struct Forward fwd;
@@ -787,7 +786,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
787 "streamlocal forwarding."); 786 "streamlocal forwarding.");
788 } else { 787 } else {
789 /* Start listening on the socket */ 788 /* Start listening on the socket */
790 success = channel_setup_remote_fwd_listener( 789 success = channel_setup_remote_fwd_listener(ssh,
791 &fwd, NULL, &options.fwd_opts); 790 &fwd, NULL, &options.fwd_opts);
792 } 791 }
793 free(fwd.listen_path); 792 free(fwd.listen_path);
@@ -799,19 +798,19 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
799 debug("%s: cancel-streamlocal-forward path %s", __func__, 798 debug("%s: cancel-streamlocal-forward path %s", __func__,
800 fwd.listen_path); 799 fwd.listen_path);
801 800
802 success = channel_cancel_rport_listener(&fwd); 801 success = channel_cancel_rport_listener(ssh, &fwd);
803 free(fwd.listen_path); 802 free(fwd.listen_path);
804 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { 803 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
805 no_more_sessions = 1; 804 no_more_sessions = 1;
806 success = 1; 805 success = 1;
807 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { 806 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
808 success = server_input_hostkeys_prove(&resp); 807 success = server_input_hostkeys_prove(ssh, &resp);
809 } 808 }
810 if (want_reply) { 809 if (want_reply) {
811 packet_start(success ? 810 packet_start(success ?
812 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 811 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
813 if (success && resp != NULL) 812 if (success && resp != NULL)
814 ssh_packet_put_raw(active_state, sshbuf_ptr(resp), 813 ssh_packet_put_raw(ssh, sshbuf_ptr(resp),
815 sshbuf_len(resp)); 814 sshbuf_len(resp));
816 packet_send(); 815 packet_send();
817 packet_write_wait(); 816 packet_write_wait();
@@ -835,15 +834,15 @@ server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
835 debug("server_input_channel_req: channel %d request %s reply %d", 834 debug("server_input_channel_req: channel %d request %s reply %d",
836 id, rtype, reply); 835 id, rtype, reply);
837 836
838 if ((c = channel_lookup(id)) == NULL) 837 if ((c = channel_lookup(ssh, id)) == NULL)
839 packet_disconnect("server_input_channel_req: " 838 packet_disconnect("server_input_channel_req: "
840 "unknown channel %d", id); 839 "unknown channel %d", id);
841 if (!strcmp(rtype, "eow@openssh.com")) { 840 if (!strcmp(rtype, "eow@openssh.com")) {
842 packet_check_eom(); 841 packet_check_eom();
843 chan_rcvd_eow(c); 842 chan_rcvd_eow(ssh, c);
844 } else if ((c->type == SSH_CHANNEL_LARVAL || 843 } else if ((c->type == SSH_CHANNEL_LARVAL ||
845 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) 844 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
846 success = session_input_channel_req(c, rtype); 845 success = session_input_channel_req(ssh, c, rtype);
847 if (reply && !(c->flags & CHAN_CLOSE_SENT)) { 846 if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
848 packet_start(success ? 847 packet_start(success ?
849 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 848 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
diff --git a/serverloop.h b/serverloop.h
index d5fbda16f..fd2cf63f7 100644
--- a/serverloop.h
+++ b/serverloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.h,v 1.7 2016/08/13 17:47:41 markus Exp $ */ 1/* $OpenBSD: serverloop.h,v 1.8 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -21,6 +21,8 @@
21#ifndef SERVERLOOP_H 21#ifndef SERVERLOOP_H
22#define SERVERLOOP_H 22#define SERVERLOOP_H
23 23
24void server_loop2(Authctxt *); 24struct ssh;
25
26void server_loop2(struct ssh *, Authctxt *);
25 27
26#endif 28#endif
diff --git a/session.c b/session.c
index cd03fd423..4bccb62d1 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.c,v 1.291 2017/08/18 05:36:45 djm Exp $ */ 1/* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -113,24 +113,24 @@
113/* func */ 113/* func */
114 114
115Session *session_new(void); 115Session *session_new(void);
116void session_set_fds(Session *, int, int, int, int, int); 116void session_set_fds(struct ssh *, Session *, int, int, int, int, int);
117void session_pty_cleanup(Session *); 117void session_pty_cleanup(Session *);
118void session_proctitle(Session *); 118void session_proctitle(Session *);
119int session_setup_x11fwd(Session *); 119int session_setup_x11fwd(struct ssh *, Session *);
120int do_exec_pty(Session *, const char *); 120int do_exec_pty(struct ssh *, Session *, const char *);
121int do_exec_no_pty(Session *, const char *); 121int do_exec_no_pty(struct ssh *, Session *, const char *);
122int do_exec(Session *, const char *); 122int do_exec(struct ssh *, Session *, const char *);
123void do_login(Session *, const char *); 123void do_login(struct ssh *, Session *, const char *);
124void do_child(struct ssh *, Session *, const char *);
124#ifdef LOGIN_NEEDS_UTMPX 125#ifdef LOGIN_NEEDS_UTMPX
125static void do_pre_login(Session *s); 126static void do_pre_login(Session *s);
126#endif 127#endif
127void do_child(Session *, const char *);
128void do_motd(void); 128void do_motd(void);
129int check_quietlogin(Session *, const char *); 129int check_quietlogin(Session *, const char *);
130 130
131static void do_authenticated2(Authctxt *); 131static void do_authenticated2(struct ssh *, Authctxt *);
132 132
133static int session_pty_req(Session *); 133static int session_pty_req(struct ssh *, Session *);
134 134
135/* import */ 135/* import */
136extern ServerOptions options; 136extern ServerOptions options;
@@ -183,7 +183,7 @@ auth_sock_cleanup_proc(struct passwd *pw)
183} 183}
184 184
185static int 185static int
186auth_input_request_forwarding(struct passwd * pw) 186auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
187{ 187{
188 Channel *nc; 188 Channel *nc;
189 int sock = -1; 189 int sock = -1;
@@ -223,7 +223,7 @@ auth_input_request_forwarding(struct passwd * pw)
223 goto authsock_err; 223 goto authsock_err;
224 224
225 /* Allocate a channel for the authentication agent socket. */ 225 /* Allocate a channel for the authentication agent socket. */
226 nc = channel_new("auth socket", 226 nc = channel_new(ssh, "auth socket",
227 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, 227 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
228 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 228 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
229 0, "auth socket", 1); 229 0, "auth socket", 1);
@@ -288,7 +288,7 @@ prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
288} 288}
289 289
290void 290void
291do_authenticated(Authctxt *authctxt) 291do_authenticated(struct ssh *ssh, Authctxt *authctxt)
292{ 292{
293 setproctitle("%s", authctxt->pw->pw_name); 293 setproctitle("%s", authctxt->pw->pw_name);
294 294
@@ -296,17 +296,17 @@ do_authenticated(Authctxt *authctxt)
296 /* XXX - streamlocal? */ 296 /* XXX - streamlocal? */
297 if (no_port_forwarding_flag || options.disable_forwarding || 297 if (no_port_forwarding_flag || options.disable_forwarding ||
298 (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) 298 (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
299 channel_disable_adm_local_opens(); 299 channel_disable_adm_local_opens(ssh);
300 else 300 else
301 channel_permit_all_opens(); 301 channel_permit_all_opens(ssh);
302 302
303 auth_debug_send(); 303 auth_debug_send();
304 304
305 prepare_auth_info_file(authctxt->pw, authctxt->session_info); 305 prepare_auth_info_file(authctxt->pw, authctxt->session_info);
306 306
307 do_authenticated2(authctxt); 307 do_authenticated2(ssh, authctxt);
308 308
309 do_cleanup(authctxt); 309 do_cleanup(ssh, authctxt);
310} 310}
311 311
312/* Check untrusted xauth strings for metacharacters */ 312/* Check untrusted xauth strings for metacharacters */
@@ -331,7 +331,7 @@ xauth_valid_string(const char *s)
331 * setting up file descriptors and such. 331 * setting up file descriptors and such.
332 */ 332 */
333int 333int
334do_exec_no_pty(Session *s, const char *command) 334do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
335{ 335{
336 pid_t pid; 336 pid_t pid;
337 337
@@ -456,7 +456,7 @@ do_exec_no_pty(Session *s, const char *command)
456#endif 456#endif
457 457
458 /* Do processing for the child (exec command etc). */ 458 /* Do processing for the child (exec command etc). */
459 do_child(s, command); 459 do_child(ssh, s, command);
460 /* NOTREACHED */ 460 /* NOTREACHED */
461 default: 461 default:
462 break; 462 break;
@@ -487,7 +487,7 @@ do_exec_no_pty(Session *s, const char *command)
487 close(pout[1]); 487 close(pout[1]);
488 close(perr[1]); 488 close(perr[1]);
489 489
490 session_set_fds(s, pin[1], pout[0], perr[0], 490 session_set_fds(ssh, s, pin[1], pout[0], perr[0],
491 s->is_subsystem, 0); 491 s->is_subsystem, 0);
492#else 492#else
493 /* We are the parent. Close the child sides of the socket pairs. */ 493 /* We are the parent. Close the child sides of the socket pairs. */
@@ -511,7 +511,7 @@ do_exec_no_pty(Session *s, const char *command)
511 * lastlog, and other such operations. 511 * lastlog, and other such operations.
512 */ 512 */
513int 513int
514do_exec_pty(Session *s, const char *command) 514do_exec_pty(struct ssh *ssh, Session *s, const char *command)
515{ 515{
516 int fdout, ptyfd, ttyfd, ptymaster; 516 int fdout, ptyfd, ttyfd, ptymaster;
517 pid_t pid; 517 pid_t pid;
@@ -580,13 +580,13 @@ do_exec_pty(Session *s, const char *command)
580 cray_init_job(s->pw); /* set up cray jid and tmpdir */ 580 cray_init_job(s->pw); /* set up cray jid and tmpdir */
581#endif /* _UNICOS */ 581#endif /* _UNICOS */
582#ifndef HAVE_OSF_SIA 582#ifndef HAVE_OSF_SIA
583 do_login(s, command); 583 do_login(ssh, s, command);
584#endif 584#endif
585 /* 585 /*
586 * Do common processing for the child, such as execing 586 * Do common processing for the child, such as execing
587 * the command. 587 * the command.
588 */ 588 */
589 do_child(s, command); 589 do_child(ssh, s, command);
590 /* NOTREACHED */ 590 /* NOTREACHED */
591 default: 591 default:
592 break; 592 break;
@@ -608,7 +608,7 @@ do_exec_pty(Session *s, const char *command)
608 s->ptymaster = ptymaster; 608 s->ptymaster = ptymaster;
609 packet_set_interactive(1, 609 packet_set_interactive(1,
610 options.ip_qos_interactive, options.ip_qos_bulk); 610 options.ip_qos_interactive, options.ip_qos_bulk);
611 session_set_fds(s, ptyfd, fdout, -1, 1, 1); 611 session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1);
612 return 0; 612 return 0;
613} 613}
614 614
@@ -646,9 +646,8 @@ do_pre_login(Session *s)
646 * to be forced, execute that instead. 646 * to be forced, execute that instead.
647 */ 647 */
648int 648int
649do_exec(Session *s, const char *command) 649do_exec(struct ssh *ssh, Session *s, const char *command)
650{ 650{
651 struct ssh *ssh = active_state; /* XXX */
652 int ret; 651 int ret;
653 const char *forced = NULL, *tty = NULL; 652 const char *forced = NULL, *tty = NULL;
654 char session_type[1024]; 653 char session_type[1024];
@@ -707,9 +706,9 @@ do_exec(Session *s, const char *command)
707 } 706 }
708#endif 707#endif
709 if (s->ttyfd != -1) 708 if (s->ttyfd != -1)
710 ret = do_exec_pty(s, command); 709 ret = do_exec_pty(ssh, s, command);
711 else 710 else
712 ret = do_exec_no_pty(s, command); 711 ret = do_exec_no_pty(ssh, s, command);
713 712
714 original_command = NULL; 713 original_command = NULL;
715 714
@@ -725,9 +724,8 @@ do_exec(Session *s, const char *command)
725 724
726/* administrative, login(1)-like work */ 725/* administrative, login(1)-like work */
727void 726void
728do_login(Session *s, const char *command) 727do_login(struct ssh *ssh, Session *s, const char *command)
729{ 728{
730 struct ssh *ssh = active_state; /* XXX */
731 socklen_t fromlen; 729 socklen_t fromlen;
732 struct sockaddr_storage from; 730 struct sockaddr_storage from;
733 struct passwd * pw = s->pw; 731 struct passwd * pw = s->pw;
@@ -960,9 +958,8 @@ copy_environment(char **source, char ***env, u_int *envsize)
960} 958}
961 959
962static char ** 960static char **
963do_setup_env(Session *s, const char *shell) 961do_setup_env(struct ssh *ssh, Session *s, const char *shell)
964{ 962{
965 struct ssh *ssh = active_state; /* XXX */
966 char buf[256]; 963 char buf[256];
967 u_int i, envsize; 964 u_int i, envsize;
968 char **env, *laddr; 965 char **env, *laddr;
@@ -1421,7 +1418,7 @@ do_pwchange(Session *s)
1421} 1418}
1422 1419
1423static void 1420static void
1424child_close_fds(void) 1421child_close_fds(struct ssh *ssh)
1425{ 1422{
1426 extern int auth_sock; 1423 extern int auth_sock;
1427 1424
@@ -1441,7 +1438,7 @@ child_close_fds(void)
1441 * open in the parent. 1438 * open in the parent.
1442 */ 1439 */
1443 /* XXX better use close-on-exec? -markus */ 1440 /* XXX better use close-on-exec? -markus */
1444 channel_close_all(); 1441 channel_close_all(ssh);
1445 1442
1446 /* 1443 /*
1447 * Close any extra file descriptors. Note that there may still be 1444 * Close any extra file descriptors. Note that there may still be
@@ -1465,7 +1462,7 @@ child_close_fds(void)
1465 */ 1462 */
1466#define ARGV_MAX 10 1463#define ARGV_MAX 10
1467void 1464void
1468do_child(Session *s, const char *command) 1465do_child(struct ssh *ssh, Session *s, const char *command)
1469{ 1466{
1470 extern char **environ; 1467 extern char **environ;
1471 char **env; 1468 char **env;
@@ -1481,7 +1478,7 @@ do_child(Session *s, const char *command)
1481 /* Force a password change */ 1478 /* Force a password change */
1482 if (s->authctxt->force_pwchange) { 1479 if (s->authctxt->force_pwchange) {
1483 do_setusercontext(pw); 1480 do_setusercontext(pw);
1484 child_close_fds(); 1481 child_close_fds(ssh);
1485 do_pwchange(s); 1482 do_pwchange(s);
1486 exit(1); 1483 exit(1);
1487 } 1484 }
@@ -1530,7 +1527,7 @@ do_child(Session *s, const char *command)
1530 * Make sure $SHELL points to the shell from the password file, 1527 * Make sure $SHELL points to the shell from the password file,
1531 * even if shell is overridden from login.conf 1528 * even if shell is overridden from login.conf
1532 */ 1529 */
1533 env = do_setup_env(s, shell); 1530 env = do_setup_env(ssh, s, shell);
1534 1531
1535#ifdef HAVE_LOGIN_CAP 1532#ifdef HAVE_LOGIN_CAP
1536 shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); 1533 shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
@@ -1543,7 +1540,7 @@ do_child(Session *s, const char *command)
1543 * closed before building the environment, as we call 1540 * closed before building the environment, as we call
1544 * ssh_remote_ipaddr there. 1541 * ssh_remote_ipaddr there.
1545 */ 1542 */
1546 child_close_fds(); 1543 child_close_fds(ssh);
1547 1544
1548 /* 1545 /*
1549 * Must take new environment into use so that .ssh/rc, 1546 * Must take new environment into use so that .ssh/rc,
@@ -1840,7 +1837,7 @@ session_by_pid(pid_t pid)
1840} 1837}
1841 1838
1842static int 1839static int
1843session_window_change_req(Session *s) 1840session_window_change_req(struct ssh *ssh, Session *s)
1844{ 1841{
1845 s->col = packet_get_int(); 1842 s->col = packet_get_int();
1846 s->row = packet_get_int(); 1843 s->row = packet_get_int();
@@ -1852,7 +1849,7 @@ session_window_change_req(Session *s)
1852} 1849}
1853 1850
1854static int 1851static int
1855session_pty_req(Session *s) 1852session_pty_req(struct ssh *ssh, Session *s)
1856{ 1853{
1857 u_int len; 1854 u_int len;
1858 int n_bytes; 1855 int n_bytes;
@@ -1905,7 +1902,7 @@ session_pty_req(Session *s)
1905} 1902}
1906 1903
1907static int 1904static int
1908session_subsystem_req(Session *s) 1905session_subsystem_req(struct ssh *ssh, Session *s)
1909{ 1906{
1910 struct stat st; 1907 struct stat st;
1911 u_int len; 1908 u_int len;
@@ -1932,7 +1929,7 @@ session_subsystem_req(Session *s)
1932 s->is_subsystem = SUBSYSTEM_EXT; 1929 s->is_subsystem = SUBSYSTEM_EXT;
1933 debug("subsystem: exec() %s", cmd); 1930 debug("subsystem: exec() %s", cmd);
1934 } 1931 }
1935 success = do_exec(s, cmd) == 0; 1932 success = do_exec(ssh, s, cmd) == 0;
1936 break; 1933 break;
1937 } 1934 }
1938 } 1935 }
@@ -1945,7 +1942,7 @@ session_subsystem_req(Session *s)
1945} 1942}
1946 1943
1947static int 1944static int
1948session_x11_req(Session *s) 1945session_x11_req(struct ssh *ssh, Session *s)
1949{ 1946{
1950 int success; 1947 int success;
1951 1948
@@ -1962,7 +1959,7 @@ session_x11_req(Session *s)
1962 1959
1963 if (xauth_valid_string(s->auth_proto) && 1960 if (xauth_valid_string(s->auth_proto) &&
1964 xauth_valid_string(s->auth_data)) 1961 xauth_valid_string(s->auth_data))
1965 success = session_setup_x11fwd(s); 1962 success = session_setup_x11fwd(ssh, s);
1966 else { 1963 else {
1967 success = 0; 1964 success = 0;
1968 error("Invalid X11 forwarding data"); 1965 error("Invalid X11 forwarding data");
@@ -1977,26 +1974,26 @@ session_x11_req(Session *s)
1977} 1974}
1978 1975
1979static int 1976static int
1980session_shell_req(Session *s) 1977session_shell_req(struct ssh *ssh, Session *s)
1981{ 1978{
1982 packet_check_eom(); 1979 packet_check_eom();
1983 return do_exec(s, NULL) == 0; 1980 return do_exec(ssh, s, NULL) == 0;
1984} 1981}
1985 1982
1986static int 1983static int
1987session_exec_req(Session *s) 1984session_exec_req(struct ssh *ssh, Session *s)
1988{ 1985{
1989 u_int len, success; 1986 u_int len, success;
1990 1987
1991 char *command = packet_get_string(&len); 1988 char *command = packet_get_string(&len);
1992 packet_check_eom(); 1989 packet_check_eom();
1993 success = do_exec(s, command) == 0; 1990 success = do_exec(ssh, s, command) == 0;
1994 free(command); 1991 free(command);
1995 return success; 1992 return success;
1996} 1993}
1997 1994
1998static int 1995static int
1999session_break_req(Session *s) 1996session_break_req(struct ssh *ssh, Session *s)
2000{ 1997{
2001 1998
2002 packet_get_int(); /* ignored */ 1999 packet_get_int(); /* ignored */
@@ -2008,7 +2005,7 @@ session_break_req(Session *s)
2008} 2005}
2009 2006
2010static int 2007static int
2011session_env_req(Session *s) 2008session_env_req(struct ssh *ssh, Session *s)
2012{ 2009{
2013 char *name, *val; 2010 char *name, *val;
2014 u_int name_len, val_len, i; 2011 u_int name_len, val_len, i;
@@ -2043,7 +2040,7 @@ session_env_req(Session *s)
2043} 2040}
2044 2041
2045static int 2042static int
2046session_auth_agent_req(Session *s) 2043session_auth_agent_req(struct ssh *ssh, Session *s)
2047{ 2044{
2048 static int called = 0; 2045 static int called = 0;
2049 packet_check_eom(); 2046 packet_check_eom();
@@ -2055,22 +2052,21 @@ session_auth_agent_req(Session *s)
2055 return 0; 2052 return 0;
2056 } else { 2053 } else {
2057 called = 1; 2054 called = 1;
2058 return auth_input_request_forwarding(s->pw); 2055 return auth_input_request_forwarding(ssh, s->pw);
2059 } 2056 }
2060} 2057}
2061 2058
2062int 2059int
2063session_input_channel_req(Channel *c, const char *rtype) 2060session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype)
2064{ 2061{
2065 int success = 0; 2062 int success = 0;
2066 Session *s; 2063 Session *s;
2067 2064
2068 if ((s = session_by_channel(c->self)) == NULL) { 2065 if ((s = session_by_channel(c->self)) == NULL) {
2069 logit("session_input_channel_req: no session %d req %.100s", 2066 logit("%s: no session %d req %.100s", __func__, c->self, rtype);
2070 c->self, rtype);
2071 return 0; 2067 return 0;
2072 } 2068 }
2073 debug("session_input_channel_req: session %d req %s", s->self, rtype); 2069 debug("%s: session %d req %s", __func__, s->self, rtype);
2074 2070
2075 /* 2071 /*
2076 * a session is in LARVAL state until a shell, a command 2072 * a session is in LARVAL state until a shell, a command
@@ -2078,33 +2074,33 @@ session_input_channel_req(Channel *c, const char *rtype)
2078 */ 2074 */
2079 if (c->type == SSH_CHANNEL_LARVAL) { 2075 if (c->type == SSH_CHANNEL_LARVAL) {
2080 if (strcmp(rtype, "shell") == 0) { 2076 if (strcmp(rtype, "shell") == 0) {
2081 success = session_shell_req(s); 2077 success = session_shell_req(ssh, s);
2082 } else if (strcmp(rtype, "exec") == 0) { 2078 } else if (strcmp(rtype, "exec") == 0) {
2083 success = session_exec_req(s); 2079 success = session_exec_req(ssh, s);
2084 } else if (strcmp(rtype, "pty-req") == 0) { 2080 } else if (strcmp(rtype, "pty-req") == 0) {
2085 success = session_pty_req(s); 2081 success = session_pty_req(ssh, s);
2086 } else if (strcmp(rtype, "x11-req") == 0) { 2082 } else if (strcmp(rtype, "x11-req") == 0) {
2087 success = session_x11_req(s); 2083 success = session_x11_req(ssh, s);
2088 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 2084 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
2089 success = session_auth_agent_req(s); 2085 success = session_auth_agent_req(ssh, s);
2090 } else if (strcmp(rtype, "subsystem") == 0) { 2086 } else if (strcmp(rtype, "subsystem") == 0) {
2091 success = session_subsystem_req(s); 2087 success = session_subsystem_req(ssh, s);
2092 } else if (strcmp(rtype, "env") == 0) { 2088 } else if (strcmp(rtype, "env") == 0) {
2093 success = session_env_req(s); 2089 success = session_env_req(ssh, s);
2094 } 2090 }
2095 } 2091 }
2096 if (strcmp(rtype, "window-change") == 0) { 2092 if (strcmp(rtype, "window-change") == 0) {
2097 success = session_window_change_req(s); 2093 success = session_window_change_req(ssh, s);
2098 } else if (strcmp(rtype, "break") == 0) { 2094 } else if (strcmp(rtype, "break") == 0) {
2099 success = session_break_req(s); 2095 success = session_break_req(ssh, s);
2100 } 2096 }
2101 2097
2102 return success; 2098 return success;
2103} 2099}
2104 2100
2105void 2101void
2106session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, 2102session_set_fds(struct ssh *ssh, Session *s,
2107 int is_tty) 2103 int fdin, int fdout, int fderr, int ignore_fderr, int is_tty)
2108{ 2104{
2109 /* 2105 /*
2110 * now that have a child and a pipe to the child, 2106 * now that have a child and a pipe to the child,
@@ -2112,7 +2108,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
2112 */ 2108 */
2113 if (s->chanid == -1) 2109 if (s->chanid == -1)
2114 fatal("no channel for session %d", s->self); 2110 fatal("no channel for session %d", s->self);
2115 channel_set_fds(s->chanid, 2111 channel_set_fds(ssh, s->chanid,
2116 fdout, fdin, fderr, 2112 fdout, fdin, fderr,
2117 ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 2113 ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2118 1, is_tty, CHAN_SES_WINDOW_DEFAULT); 2114 1, is_tty, CHAN_SES_WINDOW_DEFAULT);
@@ -2183,40 +2179,40 @@ sig2name(int sig)
2183} 2179}
2184 2180
2185static void 2181static void
2186session_close_x11(int id) 2182session_close_x11(struct ssh *ssh, int id)
2187{ 2183{
2188 Channel *c; 2184 Channel *c;
2189 2185
2190 if ((c = channel_by_id(id)) == NULL) { 2186 if ((c = channel_by_id(ssh, id)) == NULL) {
2191 debug("session_close_x11: x11 channel %d missing", id); 2187 debug("%s: x11 channel %d missing", __func__, id);
2192 } else { 2188 } else {
2193 /* Detach X11 listener */ 2189 /* Detach X11 listener */
2194 debug("session_close_x11: detach x11 channel %d", id); 2190 debug("%s: detach x11 channel %d", __func__, id);
2195 channel_cancel_cleanup(id); 2191 channel_cancel_cleanup(ssh, id);
2196 if (c->ostate != CHAN_OUTPUT_CLOSED) 2192 if (c->ostate != CHAN_OUTPUT_CLOSED)
2197 chan_mark_dead(c); 2193 chan_mark_dead(ssh, c);
2198 } 2194 }
2199} 2195}
2200 2196
2201static void 2197static void
2202session_close_single_x11(int id, void *arg) 2198session_close_single_x11(struct ssh *ssh, int id, void *arg)
2203{ 2199{
2204 Session *s; 2200 Session *s;
2205 u_int i; 2201 u_int i;
2206 2202
2207 debug3("session_close_single_x11: channel %d", id); 2203 debug3("%s: channel %d", __func__, id);
2208 channel_cancel_cleanup(id); 2204 channel_cancel_cleanup(ssh, id);
2209 if ((s = session_by_x11_channel(id)) == NULL) 2205 if ((s = session_by_x11_channel(id)) == NULL)
2210 fatal("session_close_single_x11: no x11 channel %d", id); 2206 fatal("%s: no x11 channel %d", __func__, id);
2211 for (i = 0; s->x11_chanids[i] != -1; i++) { 2207 for (i = 0; s->x11_chanids[i] != -1; i++) {
2212 debug("session_close_single_x11: session %d: " 2208 debug("%s: session %d: closing channel %d",
2213 "closing channel %d", s->self, s->x11_chanids[i]); 2209 __func__, s->self, s->x11_chanids[i]);
2214 /* 2210 /*
2215 * The channel "id" is already closing, but make sure we 2211 * The channel "id" is already closing, but make sure we
2216 * close all of its siblings. 2212 * close all of its siblings.
2217 */ 2213 */
2218 if (s->x11_chanids[i] != id) 2214 if (s->x11_chanids[i] != id)
2219 session_close_x11(s->x11_chanids[i]); 2215 session_close_x11(ssh, s->x11_chanids[i]);
2220 } 2216 }
2221 free(s->x11_chanids); 2217 free(s->x11_chanids);
2222 s->x11_chanids = NULL; 2218 s->x11_chanids = NULL;
@@ -2231,22 +2227,22 @@ session_close_single_x11(int id, void *arg)
2231} 2227}
2232 2228
2233static void 2229static void
2234session_exit_message(Session *s, int status) 2230session_exit_message(struct ssh *ssh, Session *s, int status)
2235{ 2231{
2236 Channel *c; 2232 Channel *c;
2237 2233
2238 if ((c = channel_lookup(s->chanid)) == NULL) 2234 if ((c = channel_lookup(ssh, s->chanid)) == NULL)
2239 fatal("session_exit_message: session %d: no channel %d", 2235 fatal("%s: session %d: no channel %d",
2240 s->self, s->chanid); 2236 __func__, s->self, s->chanid);
2241 debug("session_exit_message: session %d channel %d pid %ld", 2237 debug("%s: session %d channel %d pid %ld",
2242 s->self, s->chanid, (long)s->pid); 2238 __func__, s->self, s->chanid, (long)s->pid);
2243 2239
2244 if (WIFEXITED(status)) { 2240 if (WIFEXITED(status)) {
2245 channel_request_start(s->chanid, "exit-status", 0); 2241 channel_request_start(ssh, s->chanid, "exit-status", 0);
2246 packet_put_int(WEXITSTATUS(status)); 2242 packet_put_int(WEXITSTATUS(status));
2247 packet_send(); 2243 packet_send();
2248 } else if (WIFSIGNALED(status)) { 2244 } else if (WIFSIGNALED(status)) {
2249 channel_request_start(s->chanid, "exit-signal", 0); 2245 channel_request_start(ssh, s->chanid, "exit-signal", 0);
2250 packet_put_cstring(sig2name(WTERMSIG(status))); 2246 packet_put_cstring(sig2name(WTERMSIG(status)));
2251#ifdef WCOREDUMP 2247#ifdef WCOREDUMP
2252 packet_put_char(WCOREDUMP(status)? 1 : 0); 2248 packet_put_char(WCOREDUMP(status)? 1 : 0);
@@ -2262,14 +2258,14 @@ session_exit_message(Session *s, int status)
2262 } 2258 }
2263 2259
2264 /* disconnect channel */ 2260 /* disconnect channel */
2265 debug("session_exit_message: release channel %d", s->chanid); 2261 debug("%s: release channel %d", __func__, s->chanid);
2266 2262
2267 /* 2263 /*
2268 * Adjust cleanup callback attachment to send close messages when 2264 * Adjust cleanup callback attachment to send close messages when
2269 * the channel gets EOF. The session will be then be closed 2265 * the channel gets EOF. The session will be then be closed
2270 * by session_close_by_channel when the childs close their fds. 2266 * by session_close_by_channel when the childs close their fds.
2271 */ 2267 */
2272 channel_register_cleanup(c->self, session_close_by_channel, 1); 2268 channel_register_cleanup(ssh, c->self, session_close_by_channel, 1);
2273 2269
2274 /* 2270 /*
2275 * emulate a write failure with 'chan_write_failed', nobody will be 2271 * emulate a write failure with 'chan_write_failed', nobody will be
@@ -2278,13 +2274,12 @@ session_exit_message(Session *s, int status)
2278 * be some more data waiting in the pipe. 2274 * be some more data waiting in the pipe.
2279 */ 2275 */
2280 if (c->ostate != CHAN_OUTPUT_CLOSED) 2276 if (c->ostate != CHAN_OUTPUT_CLOSED)
2281 chan_write_failed(c); 2277 chan_write_failed(ssh, c);
2282} 2278}
2283 2279
2284void 2280void
2285session_close(Session *s) 2281session_close(struct ssh *ssh, Session *s)
2286{ 2282{
2287 struct ssh *ssh = active_state; /* XXX */
2288 u_int i; 2283 u_int i;
2289 2284
2290 verbose("Close session: user %s from %.200s port %d id %d", 2285 verbose("Close session: user %s from %.200s port %d id %d",
@@ -2314,16 +2309,15 @@ session_close(Session *s)
2314} 2309}
2315 2310
2316void 2311void
2317session_close_by_pid(pid_t pid, int status) 2312session_close_by_pid(struct ssh *ssh, pid_t pid, int status)
2318{ 2313{
2319 Session *s = session_by_pid(pid); 2314 Session *s = session_by_pid(pid);
2320 if (s == NULL) { 2315 if (s == NULL) {
2321 debug("session_close_by_pid: no session for pid %ld", 2316 debug("%s: no session for pid %ld", __func__, (long)pid);
2322 (long)pid);
2323 return; 2317 return;
2324 } 2318 }
2325 if (s->chanid != -1) 2319 if (s->chanid != -1)
2326 session_exit_message(s, status); 2320 session_exit_message(ssh, s, status);
2327 if (s->ttyfd != -1) 2321 if (s->ttyfd != -1)
2328 session_pty_cleanup(s); 2322 session_pty_cleanup(s);
2329 s->pid = 0; 2323 s->pid = 0;
@@ -2334,19 +2328,18 @@ session_close_by_pid(pid_t pid, int status)
2334 * the session 'child' itself dies 2328 * the session 'child' itself dies
2335 */ 2329 */
2336void 2330void
2337session_close_by_channel(int id, void *arg) 2331session_close_by_channel(struct ssh *ssh, int id, void *arg)
2338{ 2332{
2339 Session *s = session_by_channel(id); 2333 Session *s = session_by_channel(id);
2340 u_int i; 2334 u_int i;
2341 2335
2342 if (s == NULL) { 2336 if (s == NULL) {
2343 debug("session_close_by_channel: no session for id %d", id); 2337 debug("%s: no session for id %d", __func__, id);
2344 return; 2338 return;
2345 } 2339 }
2346 debug("session_close_by_channel: channel %d child %ld", 2340 debug("%s: channel %d child %ld", __func__, id, (long)s->pid);
2347 id, (long)s->pid);
2348 if (s->pid != 0) { 2341 if (s->pid != 0) {
2349 debug("session_close_by_channel: channel %d: has child", id); 2342 debug("%s: channel %d: has child", __func__, id);
2350 /* 2343 /*
2351 * delay detach of session, but release pty, since 2344 * delay detach of session, but release pty, since
2352 * the fd's to the child are already closed 2345 * the fd's to the child are already closed
@@ -2356,22 +2349,22 @@ session_close_by_channel(int id, void *arg)
2356 return; 2349 return;
2357 } 2350 }
2358 /* detach by removing callback */ 2351 /* detach by removing callback */
2359 channel_cancel_cleanup(s->chanid); 2352 channel_cancel_cleanup(ssh, s->chanid);
2360 2353
2361 /* Close any X11 listeners associated with this session */ 2354 /* Close any X11 listeners associated with this session */
2362 if (s->x11_chanids != NULL) { 2355 if (s->x11_chanids != NULL) {
2363 for (i = 0; s->x11_chanids[i] != -1; i++) { 2356 for (i = 0; s->x11_chanids[i] != -1; i++) {
2364 session_close_x11(s->x11_chanids[i]); 2357 session_close_x11(ssh, s->x11_chanids[i]);
2365 s->x11_chanids[i] = -1; 2358 s->x11_chanids[i] = -1;
2366 } 2359 }
2367 } 2360 }
2368 2361
2369 s->chanid = -1; 2362 s->chanid = -1;
2370 session_close(s); 2363 session_close(ssh, s);
2371} 2364}
2372 2365
2373void 2366void
2374session_destroy_all(void (*closefunc)(Session *)) 2367session_destroy_all(struct ssh *ssh, void (*closefunc)(Session *))
2375{ 2368{
2376 int i; 2369 int i;
2377 for (i = 0; i < sessions_nalloc; i++) { 2370 for (i = 0; i < sessions_nalloc; i++) {
@@ -2380,7 +2373,7 @@ session_destroy_all(void (*closefunc)(Session *))
2380 if (closefunc != NULL) 2373 if (closefunc != NULL)
2381 closefunc(s); 2374 closefunc(s);
2382 else 2375 else
2383 session_close(s); 2376 session_close(ssh, s);
2384 } 2377 }
2385 } 2378 }
2386} 2379}
@@ -2423,7 +2416,7 @@ session_proctitle(Session *s)
2423} 2416}
2424 2417
2425int 2418int
2426session_setup_x11fwd(Session *s) 2419session_setup_x11fwd(struct ssh *ssh, Session *s)
2427{ 2420{
2428 struct stat st; 2421 struct stat st;
2429 char display[512], auth_display[512]; 2422 char display[512], auth_display[512];
@@ -2447,14 +2440,14 @@ session_setup_x11fwd(Session *s)
2447 debug("X11 display already set."); 2440 debug("X11 display already set.");
2448 return 0; 2441 return 0;
2449 } 2442 }
2450 if (x11_create_display_inet(options.x11_display_offset, 2443 if (x11_create_display_inet(ssh, options.x11_display_offset,
2451 options.x11_use_localhost, s->single_connection, 2444 options.x11_use_localhost, s->single_connection,
2452 &s->display_number, &s->x11_chanids) == -1) { 2445 &s->display_number, &s->x11_chanids) == -1) {
2453 debug("x11_create_display_inet failed."); 2446 debug("x11_create_display_inet failed.");
2454 return 0; 2447 return 0;
2455 } 2448 }
2456 for (i = 0; s->x11_chanids[i] != -1; i++) { 2449 for (i = 0; s->x11_chanids[i] != -1; i++) {
2457 channel_register_cleanup(s->x11_chanids[i], 2450 channel_register_cleanup(ssh, s->x11_chanids[i],
2458 session_close_single_x11, 0); 2451 session_close_single_x11, 0);
2459 } 2452 }
2460 2453
@@ -2499,13 +2492,13 @@ session_setup_x11fwd(Session *s)
2499} 2492}
2500 2493
2501static void 2494static void
2502do_authenticated2(Authctxt *authctxt) 2495do_authenticated2(struct ssh *ssh, Authctxt *authctxt)
2503{ 2496{
2504 server_loop2(authctxt); 2497 server_loop2(ssh, authctxt);
2505} 2498}
2506 2499
2507void 2500void
2508do_cleanup(Authctxt *authctxt) 2501do_cleanup(struct ssh *ssh, Authctxt *authctxt)
2509{ 2502{
2510 static int called = 0; 2503 static int called = 0;
2511 2504
@@ -2561,7 +2554,7 @@ do_cleanup(Authctxt *authctxt)
2561 * or if running in monitor. 2554 * or if running in monitor.
2562 */ 2555 */
2563 if (!use_privsep || mm_is_monitor()) 2556 if (!use_privsep || mm_is_monitor())
2564 session_destroy_all(session_pty_cleanup2); 2557 session_destroy_all(ssh, session_pty_cleanup2);
2565} 2558}
2566 2559
2567/* Return a name for the remote host that fits inside utmp_size */ 2560/* Return a name for the remote host that fits inside utmp_size */
diff --git a/session.h b/session.h
index 74c557db6..54dd1f0ca 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.h,v 1.34 2017/08/18 05:36:45 djm Exp $ */ 1/* $OpenBSD: session.h,v 1.35 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -62,20 +62,20 @@ struct Session {
62 } *env; 62 } *env;
63}; 63};
64 64
65void do_authenticated(Authctxt *); 65void do_authenticated(struct ssh *, Authctxt *);
66void do_cleanup(Authctxt *); 66void do_cleanup(struct ssh *, Authctxt *);
67 67
68int session_open(Authctxt *, int); 68int session_open(Authctxt *, int);
69void session_unused(int); 69void session_unused(int);
70int session_input_channel_req(Channel *, const char *); 70int session_input_channel_req(struct ssh *, Channel *, const char *);
71void session_close_by_pid(pid_t, int); 71void session_close_by_pid(struct ssh *ssh, pid_t, int);
72void session_close_by_channel(int, void *); 72void session_close_by_channel(struct ssh *, int, void *);
73void session_destroy_all(void (*)(Session *)); 73void session_destroy_all(struct ssh *, void (*)(Session *));
74void session_pty_cleanup2(Session *); 74void session_pty_cleanup2(Session *);
75 75
76Session *session_new(void); 76Session *session_new(void);
77Session *session_by_tty(char *); 77Session *session_by_tty(char *);
78void session_close(Session *); 78void session_close(struct ssh *, Session *);
79void do_setusercontext(struct passwd *); 79void do_setusercontext(struct passwd *);
80 80
81const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); 81const char *session_get_remote_name_or_ip(struct ssh *, u_int, int);
diff --git a/ssh.c b/ssh.c
index 019d1d31c..ecc50f37e 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.462 2017/08/12 06:46:01 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.463 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -208,7 +208,7 @@ usage(void)
208 exit(255); 208 exit(255);
209} 209}
210 210
211static int ssh_session2(void); 211static int ssh_session2(struct ssh *);
212static void load_public_identity_files(void); 212static void load_public_identity_files(void);
213static void main_sigchld_handler(int); 213static void main_sigchld_handler(int);
214 214
@@ -596,6 +596,14 @@ main(int ac, char **av)
596 */ 596 */
597 initialize_options(&options); 597 initialize_options(&options);
598 598
599 /*
600 * Prepare main ssh transport/connection structures
601 */
602 if ((ssh = ssh_alloc_session_state()) == NULL)
603 fatal("Couldn't allocate session state");
604 channel_init_channels(ssh);
605 active_state = ssh; /* XXX legacy API compat */
606
599 /* Parse command-line arguments. */ 607 /* Parse command-line arguments. */
600 host = NULL; 608 host = NULL;
601 use_syslog = 0; 609 use_syslog = 0;
@@ -1108,7 +1116,7 @@ main(int ac, char **av)
1108 1116
1109 if (options.port == 0) 1117 if (options.port == 0)
1110 options.port = default_ssh_port(); 1118 options.port = default_ssh_port();
1111 channel_set_af(options.address_family); 1119 channel_set_af(ssh, options.address_family);
1112 1120
1113 /* Tidy and check options */ 1121 /* Tidy and check options */
1114 if (options.host_key_alias != NULL) 1122 if (options.host_key_alias != NULL)
@@ -1253,8 +1261,7 @@ main(int ac, char **av)
1253 if (options.control_path != NULL) { 1261 if (options.control_path != NULL) {
1254 int sock; 1262 int sock;
1255 if ((sock = muxclient(options.control_path)) >= 0) { 1263 if ((sock = muxclient(options.control_path)) >= 0) {
1256 packet_set_connection(sock, sock); 1264 ssh_packet_set_connection(ssh, sock, sock);
1257 ssh = active_state; /* XXX */
1258 packet_set_mux(); 1265 packet_set_mux();
1259 goto skip_connect; 1266 goto skip_connect;
1260 } 1267 }
@@ -1274,7 +1281,7 @@ main(int ac, char **av)
1274 timeout_ms = options.connection_timeout * 1000; 1281 timeout_ms = options.connection_timeout * 1000;
1275 1282
1276 /* Open a connection to the remote host. */ 1283 /* Open a connection to the remote host. */
1277 if (ssh_connect(host, addrs, &hostaddr, options.port, 1284 if (ssh_connect(ssh, host, addrs, &hostaddr, options.port,
1278 options.address_family, options.connection_attempts, 1285 options.address_family, options.connection_attempts,
1279 &timeout_ms, options.tcp_keep_alive, 1286 &timeout_ms, options.tcp_keep_alive,
1280 options.use_privileged_port) != 0) 1287 options.use_privileged_port) != 0)
@@ -1457,7 +1464,7 @@ main(int ac, char **av)
1457 } 1464 }
1458 1465
1459 skip_connect: 1466 skip_connect:
1460 exit_status = ssh_session2(); 1467 exit_status = ssh_session2(ssh);
1461 packet_close(); 1468 packet_close();
1462 1469
1463 if (options.control_path != NULL && muxserver_sock != -1) 1470 if (options.control_path != NULL && muxserver_sock != -1)
@@ -1530,7 +1537,7 @@ fork_postauth(void)
1530 1537
1531/* Callback for remote forward global requests */ 1538/* Callback for remote forward global requests */
1532static void 1539static void
1533ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 1540ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
1534{ 1541{
1535 struct Forward *rfwd = (struct Forward *)ctxt; 1542 struct Forward *rfwd = (struct Forward *)ctxt;
1536 1543
@@ -1548,10 +1555,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1548 logit("Allocated port %u for remote forward to %s:%d", 1555 logit("Allocated port %u for remote forward to %s:%d",
1549 rfwd->allocated_port, 1556 rfwd->allocated_port,
1550 rfwd->connect_host, rfwd->connect_port); 1557 rfwd->connect_host, rfwd->connect_port);
1551 channel_update_permitted_opens(rfwd->handle, 1558 channel_update_permitted_opens(ssh,
1552 rfwd->allocated_port); 1559 rfwd->handle, rfwd->allocated_port);
1553 } else { 1560 } else {
1554 channel_update_permitted_opens(rfwd->handle, -1); 1561 channel_update_permitted_opens(ssh, rfwd->handle, -1);
1555 } 1562 }
1556 } 1563 }
1557 1564
@@ -1580,21 +1587,21 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1580} 1587}
1581 1588
1582static void 1589static void
1583client_cleanup_stdio_fwd(int id, void *arg) 1590client_cleanup_stdio_fwd(struct ssh *ssh, int id, void *arg)
1584{ 1591{
1585 debug("stdio forwarding: done"); 1592 debug("stdio forwarding: done");
1586 cleanup_exit(0); 1593 cleanup_exit(0);
1587} 1594}
1588 1595
1589static void 1596static void
1590ssh_stdio_confirm(int id, int success, void *arg) 1597ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1591{ 1598{
1592 if (!success) 1599 if (!success)
1593 fatal("stdio forwarding failed"); 1600 fatal("stdio forwarding failed");
1594} 1601}
1595 1602
1596static void 1603static void
1597ssh_init_stdio_forwarding(void) 1604ssh_init_stdio_forwarding(struct ssh *ssh)
1598{ 1605{
1599 Channel *c; 1606 Channel *c;
1600 int in, out; 1607 int in, out;
@@ -1608,15 +1615,15 @@ ssh_init_stdio_forwarding(void)
1608 if ((in = dup(STDIN_FILENO)) < 0 || 1615 if ((in = dup(STDIN_FILENO)) < 0 ||
1609 (out = dup(STDOUT_FILENO)) < 0) 1616 (out = dup(STDOUT_FILENO)) < 0)
1610 fatal("channel_connect_stdio_fwd: dup() in/out failed"); 1617 fatal("channel_connect_stdio_fwd: dup() in/out failed");
1611 if ((c = channel_connect_stdio_fwd(options.stdio_forward_host, 1618 if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host,
1612 options.stdio_forward_port, in, out)) == NULL) 1619 options.stdio_forward_port, in, out)) == NULL)
1613 fatal("%s: channel_connect_stdio_fwd failed", __func__); 1620 fatal("%s: channel_connect_stdio_fwd failed", __func__);
1614 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); 1621 channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0);
1615 channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL); 1622 channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL);
1616} 1623}
1617 1624
1618static void 1625static void
1619ssh_init_forwarding(void) 1626ssh_init_forwarding(struct ssh *ssh)
1620{ 1627{
1621 int success = 0; 1628 int success = 0;
1622 int i; 1629 int i;
@@ -1635,7 +1642,7 @@ ssh_init_forwarding(void)
1635 options.local_forwards[i].connect_path : 1642 options.local_forwards[i].connect_path :
1636 options.local_forwards[i].connect_host, 1643 options.local_forwards[i].connect_host,
1637 options.local_forwards[i].connect_port); 1644 options.local_forwards[i].connect_port);
1638 success += channel_setup_local_fwd_listener( 1645 success += channel_setup_local_fwd_listener(ssh,
1639 &options.local_forwards[i], &options.fwd_opts); 1646 &options.local_forwards[i], &options.fwd_opts);
1640 } 1647 }
1641 if (i > 0 && success != i && options.exit_on_forward_failure) 1648 if (i > 0 && success != i && options.exit_on_forward_failure)
@@ -1657,7 +1664,7 @@ ssh_init_forwarding(void)
1657 options.remote_forwards[i].connect_host, 1664 options.remote_forwards[i].connect_host,
1658 options.remote_forwards[i].connect_port); 1665 options.remote_forwards[i].connect_port);
1659 options.remote_forwards[i].handle = 1666 options.remote_forwards[i].handle =
1660 channel_request_remote_forwarding( 1667 channel_request_remote_forwarding(ssh,
1661 &options.remote_forwards[i]); 1668 &options.remote_forwards[i]);
1662 if (options.remote_forwards[i].handle < 0) { 1669 if (options.remote_forwards[i].handle < 0) {
1663 if (options.exit_on_forward_failure) 1670 if (options.exit_on_forward_failure)
@@ -1666,14 +1673,15 @@ ssh_init_forwarding(void)
1666 logit("Warning: Could not request remote " 1673 logit("Warning: Could not request remote "
1667 "forwarding."); 1674 "forwarding.");
1668 } else { 1675 } else {
1669 client_register_global_confirm(ssh_confirm_remote_forward, 1676 client_register_global_confirm(
1677 ssh_confirm_remote_forward,
1670 &options.remote_forwards[i]); 1678 &options.remote_forwards[i]);
1671 } 1679 }
1672 } 1680 }
1673 1681
1674 /* Initiate tunnel forwarding. */ 1682 /* Initiate tunnel forwarding. */
1675 if (options.tun_open != SSH_TUNMODE_NO) { 1683 if (options.tun_open != SSH_TUNMODE_NO) {
1676 if (client_request_tun_fwd(options.tun_open, 1684 if (client_request_tun_fwd(ssh, options.tun_open,
1677 options.tun_local, options.tun_remote) == -1) { 1685 options.tun_local, options.tun_remote) == -1) {
1678 if (options.exit_on_forward_failure) 1686 if (options.exit_on_forward_failure)
1679 fatal("Could not request tunnel forwarding."); 1687 fatal("Could not request tunnel forwarding.");
@@ -1700,7 +1708,7 @@ check_agent_present(void)
1700} 1708}
1701 1709
1702static void 1710static void
1703ssh_session2_setup(int id, int success, void *arg) 1711ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
1704{ 1712{
1705 extern char **environ; 1713 extern char **environ;
1706 const char *display; 1714 const char *display;
@@ -1713,15 +1721,15 @@ ssh_session2_setup(int id, int success, void *arg)
1713 display = getenv("DISPLAY"); 1721 display = getenv("DISPLAY");
1714 if (display == NULL && options.forward_x11) 1722 if (display == NULL && options.forward_x11)
1715 debug("X11 forwarding requested but DISPLAY not set"); 1723 debug("X11 forwarding requested but DISPLAY not set");
1716 if (options.forward_x11 && client_x11_get_proto(display, 1724 if (options.forward_x11 && client_x11_get_proto(ssh, display,
1717 options.xauth_location, options.forward_x11_trusted, 1725 options.xauth_location, options.forward_x11_trusted,
1718 options.forward_x11_timeout, &proto, &data) == 0) { 1726 options.forward_x11_timeout, &proto, &data) == 0) {
1719 /* Request forwarding with authentication spoofing. */ 1727 /* Request forwarding with authentication spoofing. */
1720 debug("Requesting X11 forwarding with authentication " 1728 debug("Requesting X11 forwarding with authentication "
1721 "spoofing."); 1729 "spoofing.");
1722 x11_request_forwarding_with_spoofing(id, display, proto, 1730 x11_request_forwarding_with_spoofing(ssh, id, display, proto,
1723 data, 1); 1731 data, 1);
1724 client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); 1732 client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN);
1725 /* XXX exit_on_forward_failure */ 1733 /* XXX exit_on_forward_failure */
1726 interactive = 1; 1734 interactive = 1;
1727 } 1735 }
@@ -1729,7 +1737,7 @@ ssh_session2_setup(int id, int success, void *arg)
1729 check_agent_present(); 1737 check_agent_present();
1730 if (options.forward_agent) { 1738 if (options.forward_agent) {
1731 debug("Requesting authentication agent forwarding."); 1739 debug("Requesting authentication agent forwarding.");
1732 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1740 channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
1733 packet_send(); 1741 packet_send();
1734 } 1742 }
1735 1743
@@ -1737,13 +1745,13 @@ ssh_session2_setup(int id, int success, void *arg)
1737 packet_set_interactive(interactive, 1745 packet_set_interactive(interactive,
1738 options.ip_qos_interactive, options.ip_qos_bulk); 1746 options.ip_qos_interactive, options.ip_qos_bulk);
1739 1747
1740 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1748 client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"),
1741 NULL, fileno(stdin), &command, environ); 1749 NULL, fileno(stdin), &command, environ);
1742} 1750}
1743 1751
1744/* open new channel for a session */ 1752/* open new channel for a session */
1745static int 1753static int
1746ssh_session2_open(void) 1754ssh_session2_open(struct ssh *ssh)
1747{ 1755{
1748 Channel *c; 1756 Channel *c;
1749 int window, packetmax, in, out, err; 1757 int window, packetmax, in, out, err;
@@ -1773,34 +1781,34 @@ ssh_session2_open(void)
1773 window >>= 1; 1781 window >>= 1;
1774 packetmax >>= 1; 1782 packetmax >>= 1;
1775 } 1783 }
1776 c = channel_new( 1784 c = channel_new(ssh,
1777 "session", SSH_CHANNEL_OPENING, in, out, err, 1785 "session", SSH_CHANNEL_OPENING, in, out, err,
1778 window, packetmax, CHAN_EXTENDED_WRITE, 1786 window, packetmax, CHAN_EXTENDED_WRITE,
1779 "client-session", /*nonblock*/0); 1787 "client-session", /*nonblock*/0);
1780 1788
1781 debug3("ssh_session2_open: channel_new: %d", c->self); 1789 debug3("%s: channel_new: %d", __func__, c->self);
1782 1790
1783 channel_send_open(c->self); 1791 channel_send_open(ssh, c->self);
1784 if (!no_shell_flag) 1792 if (!no_shell_flag)
1785 channel_register_open_confirm(c->self, 1793 channel_register_open_confirm(ssh, c->self,
1786 ssh_session2_setup, NULL); 1794 ssh_session2_setup, NULL);
1787 1795
1788 return c->self; 1796 return c->self;
1789} 1797}
1790 1798
1791static int 1799static int
1792ssh_session2(void) 1800ssh_session2(struct ssh *ssh)
1793{ 1801{
1794 int id = -1; 1802 int id = -1;
1795 1803
1796 /* XXX should be pre-session */ 1804 /* XXX should be pre-session */
1797 if (!options.control_persist) 1805 if (!options.control_persist)
1798 ssh_init_stdio_forwarding(); 1806 ssh_init_stdio_forwarding(ssh);
1799 ssh_init_forwarding(); 1807 ssh_init_forwarding(ssh);
1800 1808
1801 /* Start listening for multiplex clients */ 1809 /* Start listening for multiplex clients */
1802 if (!packet_get_mux()) 1810 if (!packet_get_mux())
1803 muxserver_listen(); 1811 muxserver_listen(ssh);
1804 1812
1805 /* 1813 /*
1806 * If we are in control persist mode and have a working mux listen 1814 * If we are in control persist mode and have a working mux listen
@@ -1828,10 +1836,10 @@ ssh_session2(void)
1828 * stdio forward setup that we skipped earlier. 1836 * stdio forward setup that we skipped earlier.
1829 */ 1837 */
1830 if (options.control_persist && muxserver_sock == -1) 1838 if (options.control_persist && muxserver_sock == -1)
1831 ssh_init_stdio_forwarding(); 1839 ssh_init_stdio_forwarding(ssh);
1832 1840
1833 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1841 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1834 id = ssh_session2_open(); 1842 id = ssh_session2_open(ssh);
1835 else { 1843 else {
1836 packet_set_interactive( 1844 packet_set_interactive(
1837 options.control_master == SSHCTL_MASTER_NO, 1845 options.control_master == SSHCTL_MASTER_NO,
@@ -1866,7 +1874,7 @@ ssh_session2(void)
1866 fork_postauth(); 1874 fork_postauth();
1867 } 1875 }
1868 1876
1869 return client_loop(tty_flag, tty_flag ? 1877 return client_loop(ssh, tty_flag, tty_flag ?
1870 options.escape_char : SSH_ESCAPECHAR_NONE, id); 1878 options.escape_char : SSH_ESCAPECHAR_NONE, id);
1871} 1879}
1872 1880
diff --git a/sshbuf.h b/sshbuf.h
index 1ac4b8c0a..77f1e9e6d 100644
--- a/sshbuf.h
+++ b/sshbuf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf.h,v 1.8 2016/11/25 23:22:04 djm Exp $ */ 1/* $OpenBSD: sshbuf.h,v 1.9 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -211,6 +211,7 @@ int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
211/* Another variant: "peeks" into the buffer without modifying it */ 211/* Another variant: "peeks" into the buffer without modifying it */
212int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, 212int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
213 size_t *lenp); 213 size_t *lenp);
214/* XXX peek_u8 / peek_u32 */
214 215
215/* 216/*
216 * Functions to extract or store SSH wire encoded bignums and elliptic 217 * Functions to extract or store SSH wire encoded bignums and elliptic
diff --git a/sshconnect.c b/sshconnect.c
index 2842d9e59..608566207 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.285 2017/09/03 23:33:13 djm Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.286 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -105,7 +105,7 @@ expand_proxy_command(const char *proxy_command, const char *user,
105 * a connected fd back to us. 105 * a connected fd back to us.
106 */ 106 */
107static int 107static int
108ssh_proxy_fdpass_connect(const char *host, u_short port, 108ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
109 const char *proxy_command) 109 const char *proxy_command)
110{ 110{
111 char *command_string; 111 char *command_string;
@@ -176,7 +176,8 @@ ssh_proxy_fdpass_connect(const char *host, u_short port,
176 fatal("Couldn't wait for child: %s", strerror(errno)); 176 fatal("Couldn't wait for child: %s", strerror(errno));
177 177
178 /* Set the connection file descriptors. */ 178 /* Set the connection file descriptors. */
179 packet_set_connection(sock, sock); 179 if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
180 return -1; /* ssh_packet_set_connection logs error */
180 181
181 return 0; 182 return 0;
182} 183}
@@ -185,7 +186,8 @@ ssh_proxy_fdpass_connect(const char *host, u_short port,
185 * Connect to the given ssh server using a proxy command. 186 * Connect to the given ssh server using a proxy command.
186 */ 187 */
187static int 188static int
188ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) 189ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
190 const char *proxy_command)
189{ 191{
190 char *command_string; 192 char *command_string;
191 int pin[2], pout[2]; 193 int pin[2], pout[2];
@@ -252,9 +254,9 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
252 free(command_string); 254 free(command_string);
253 255
254 /* Set the connection file descriptors. */ 256 /* Set the connection file descriptors. */
255 packet_set_connection(pout[0], pin[1]); 257 if (ssh_packet_set_connection(ssh, pout[0], pin[1]) == NULL)
258 return -1; /* ssh_packet_set_connection logs error */
256 259
257 /* Indicate OK return */
258 return 0; 260 return 0;
259} 261}
260 262
@@ -410,7 +412,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
410 * the daemon. 412 * the daemon.
411 */ 413 */
412static int 414static int
413ssh_connect_direct(const char *host, struct addrinfo *aitop, 415ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
414 struct sockaddr_storage *hostaddr, u_short port, int family, 416 struct sockaddr_storage *hostaddr, u_short port, int family,
415 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) 417 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
416{ 418{
@@ -484,27 +486,31 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop,
484 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 486 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
485 487
486 /* Set the connection. */ 488 /* Set the connection. */
487 packet_set_connection(sock, sock); 489 if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
490 return -1; /* ssh_packet_set_connection logs error */
488 491
489 return 0; 492 return 0;
490} 493}
491 494
492int 495int
493ssh_connect(const char *host, struct addrinfo *addrs, 496ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs,
494 struct sockaddr_storage *hostaddr, u_short port, int family, 497 struct sockaddr_storage *hostaddr, u_short port, int family,
495 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) 498 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
496{ 499{
497 if (options.proxy_command == NULL) { 500 if (options.proxy_command == NULL) {
498 return ssh_connect_direct(host, addrs, hostaddr, port, family, 501 return ssh_connect_direct(ssh, host, addrs, hostaddr, port,
499 connection_attempts, timeout_ms, want_keepalive, needpriv); 502 family, connection_attempts, timeout_ms, want_keepalive,
503 needpriv);
500 } else if (strcmp(options.proxy_command, "-") == 0) { 504 } else if (strcmp(options.proxy_command, "-") == 0) {
501 packet_set_connection(STDIN_FILENO, STDOUT_FILENO); 505 if ((ssh_packet_set_connection(ssh,
502 return 0; /* Always succeeds */ 506 STDIN_FILENO, STDOUT_FILENO)) == NULL)
507 return -1; /* ssh_packet_set_connection logs error */
508 return 0;
503 } else if (options.proxy_use_fdpass) { 509 } else if (options.proxy_use_fdpass) {
504 return ssh_proxy_fdpass_connect(host, port, 510 return ssh_proxy_fdpass_connect(ssh, host, port,
505 options.proxy_command); 511 options.proxy_command);
506 } 512 }
507 return ssh_proxy_connect(host, port, options.proxy_command); 513 return ssh_proxy_connect(ssh, host, port, options.proxy_command);
508} 514}
509 515
510static void 516static void
diff --git a/sshconnect.h b/sshconnect.h
index f4e73f7b1..b5029e234 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.h,v 1.30 2017/05/30 08:52:19 markus Exp $ */ 1/* $OpenBSD: sshconnect.h,v 1.31 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -32,8 +32,10 @@ struct Sensitive {
32}; 32};
33 33
34struct addrinfo; 34struct addrinfo;
35int ssh_connect(const char *, struct addrinfo *, struct sockaddr_storage *, 35struct ssh;
36 u_short, int, int, int *, int, int); 36
37int ssh_connect(struct ssh *, const char *, struct addrinfo *,
38 struct sockaddr_storage *, u_short, int, int, int *, int, int);
37void ssh_kill_proxy_command(void); 39void ssh_kill_proxy_command(void);
38 40
39void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, 41void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short,
diff --git a/sshd.c b/sshd.c
index 1d19ce679..51a1aaf6e 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.491 2017/07/01 13:50:45 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.492 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1621,9 +1621,6 @@ main(int ac, char **av)
1621 "enabled authentication methods"); 1621 "enabled authentication methods");
1622 } 1622 }
1623 1623
1624 /* set default channel AF */
1625 channel_set_af(options.address_family);
1626
1627 /* Check that there are no remaining arguments. */ 1624 /* Check that there are no remaining arguments. */
1628 if (optind < ac) { 1625 if (optind < ac) {
1629 fprintf(stderr, "Extra argument %s.\n", av[optind]); 1626 fprintf(stderr, "Extra argument %s.\n", av[optind]);
@@ -1955,8 +1952,14 @@ main(int ac, char **av)
1955 packet_set_connection(sock_in, sock_out); 1952 packet_set_connection(sock_in, sock_out);
1956 packet_set_server(); 1953 packet_set_server();
1957 ssh = active_state; /* XXX */ 1954 ssh = active_state; /* XXX */
1955
1958 check_ip_options(ssh); 1956 check_ip_options(ssh);
1959 1957
1958 /* Prepare the channels layer */
1959 channel_init_channels(ssh);
1960 channel_set_af(ssh, options.address_family);
1961 process_permitopen(ssh, &options);
1962
1960 /* Set SO_KEEPALIVE if requested. */ 1963 /* Set SO_KEEPALIVE if requested. */
1961 if (options.tcp_keep_alive && packet_connection_is_on_socket() && 1964 if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
1962 setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) 1965 setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
@@ -2080,10 +2083,10 @@ main(int ac, char **av)
2080 options.client_alive_count_max); 2083 options.client_alive_count_max);
2081 2084
2082 /* Try to send all our hostkeys to the client */ 2085 /* Try to send all our hostkeys to the client */
2083 notify_hostkeys(active_state); 2086 notify_hostkeys(ssh);
2084 2087
2085 /* Start session. */ 2088 /* Start session. */
2086 do_authenticated(authctxt); 2089 do_authenticated(ssh, authctxt);
2087 2090
2088 /* The connection has been terminated. */ 2091 /* The connection has been terminated. */
2089 packet_get_bytes(&ibytes, &obytes); 2092 packet_get_bytes(&ibytes, &obytes);
@@ -2211,8 +2214,10 @@ do_ssh2_kex(void)
2211void 2214void
2212cleanup_exit(int i) 2215cleanup_exit(int i)
2213{ 2216{
2217 struct ssh *ssh = active_state; /* XXX */
2218
2214 if (the_authctxt) { 2219 if (the_authctxt) {
2215 do_cleanup(the_authctxt); 2220 do_cleanup(ssh, the_authctxt);
2216 if (use_privsep && privsep_is_preauth && 2221 if (use_privsep && privsep_is_preauth &&
2217 pmonitor != NULL && pmonitor->m_pid > 1) { 2222 pmonitor != NULL && pmonitor->m_pid > 1) {
2218 debug("Killing privsep child %d", pmonitor->m_pid); 2223 debug("Killing privsep child %d", pmonitor->m_pid);
diff --git a/ssherr.c b/ssherr.c
index 4bd5f59cc..3c0009d69 100644
--- a/ssherr.c
+++ b/ssherr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssherr.c,v 1.6 2017/05/07 23:15:59 djm Exp $ */ 1/* $OpenBSD: ssherr.c,v 1.7 2017/09/12 06:32:08 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -137,6 +137,8 @@ ssh_err(int n)
137 return "Protocol error"; 137 return "Protocol error";
138 case SSH_ERR_KEY_LENGTH: 138 case SSH_ERR_KEY_LENGTH:
139 return "Invalid key length"; 139 return "Invalid key length";
140 case SSH_ERR_NUMBER_TOO_LARGE:
141 return "number is too large";
140 default: 142 default:
141 return "unknown error"; 143 return "unknown error";
142 } 144 }
diff --git a/ssherr.h b/ssherr.h
index a30781620..c0b59211e 100644
--- a/ssherr.h
+++ b/ssherr.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssherr.h,v 1.4 2017/05/07 23:15:59 djm Exp $ */ 1/* $OpenBSD: ssherr.h,v 1.5 2017/09/12 06:32:08 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -78,6 +78,7 @@
78#define SSH_ERR_CONN_CORRUPT -54 78#define SSH_ERR_CONN_CORRUPT -54
79#define SSH_ERR_PROTOCOL_ERROR -55 79#define SSH_ERR_PROTOCOL_ERROR -55
80#define SSH_ERR_KEY_LENGTH -56 80#define SSH_ERR_KEY_LENGTH -56
81#define SSH_ERR_NUMBER_TOO_LARGE -57
81 82
82/* Translate a numeric error code to a human-readable error string */ 83/* Translate a numeric error code to a human-readable error string */
83const char *ssh_err(int n); 84const char *ssh_err(int n);