summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-09-12 06:32:07 +0000
committerDamien Miller <djm@mindrot.org>2017-09-12 17:37:02 +1000
commitdbee4119b502e3f8b6cd3282c69c537fd01d8e16 (patch)
treeb8a3263a79e0920e8d08f188654f1ccb7c254406
parentabd59663df37a42152e37980113ccaa405b9a282 (diff)
upstream commit
refactor channels.c Move static state to a "struct ssh_channels" that is allocated at runtime and tracked as a member of struct ssh. Explicitly pass "struct ssh" to all channels functions. Replace use of the legacy packet APIs in channels.c. Rework sshd_config PermitOpen handling: previously the configuration parser would call directly into the channels layer. After the refactor this is not possible, as the channels structures are allocated at connection time and aren't available when the configuration is parsed. The server config parser now tracks PermitOpen itself and explicitly configures the channels code later. ok markus@ Upstream-ID: 11828f161656b965cc306576422613614bea2d8f
-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);