summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c1194
1 files changed, 682 insertions, 512 deletions
diff --git a/channels.c b/channels.c
index e60ecc614..b87ff9f4f 100644
--- a/channels.c
+++ b/channels.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: channels.c,v 1.19 2000/03/17 12:40:15 damien Exp $"); 19RCSID("$Id: channels.c,v 1.20 2000/04/01 01:09:23 damien Exp $");
20 20
21#include "ssh.h" 21#include "ssh.h"
22#include "packet.h" 22#include "packet.h"
@@ -37,6 +37,10 @@ RCSID("$Id: channels.c,v 1.19 2000/03/17 12:40:15 damien Exp $");
37/* Max len of agent socket */ 37/* Max len of agent socket */
38#define MAX_SOCKET_NAME 100 38#define MAX_SOCKET_NAME 100
39 39
40/* default buffer for tcp-fwd-channel */
41#define CHAN_WINDOW_DEFAULT (8*1024)
42#define CHAN_PACKET_DEFAULT (CHAN_WINDOW_DEFAULT/2)
43
40/* 44/*
41 * Pointer to an array containing all allocated channels. The array is 45 * Pointer to an array containing all allocated channels. The array is
42 * dynamically extended as needed. 46 * dynamically extended as needed.
@@ -81,8 +85,9 @@ unsigned int x11_fake_data_len;
81 * network (which might be behind a firewall). 85 * network (which might be behind a firewall).
82 */ 86 */
83typedef struct { 87typedef struct {
84 char *host; /* Host name. */ 88 char *host_to_connect; /* Connect to 'host'. */
85 u_short port; /* Port number. */ 89 u_short port_to_connect; /* Connect to 'port'. */
90 u_short listen_port; /* Remote side should listen port number. */
86} ForwardPermission; 91} ForwardPermission;
87 92
88/* List of all permitted host/port pairs to connect. */ 93/* List of all permitted host/port pairs to connect. */
@@ -119,20 +124,43 @@ channel_permit_all_opens()
119 all_opens_permitted = 1; 124 all_opens_permitted = 1;
120} 125}
121 126
127/* lookup channel by id */
128
129Channel *
130channel_lookup(int id)
131{
132 Channel *c;
133 if (id < 0 && id > channels_alloc) {
134 log("channel_lookup: %d: bad id", id);
135 return NULL;
136 }
137 c = &channels[id];
138 if (c->type == SSH_CHANNEL_FREE) {
139 log("channel_lookup: %d: bad id: channel free", id);
140 return NULL;
141 }
142 return c;
143}
144
122/* 145/*
123 * Allocate a new channel object and set its type and socket. This will cause 146 * Allocate a new channel object and set its type and socket. This will cause
124 * remote_name to be freed. 147 * remote_name to be freed.
125 */ 148 */
126 149
127int 150int
128channel_allocate(int type, int sock, char *remote_name) 151channel_new(char *ctype, int type, int rfd, int wfd, int efd,
152 int window, int maxpack, int extended_usage, char *remote_name)
129{ 153{
130 int i, found; 154 int i, found;
131 Channel *c; 155 Channel *c;
132 156
133 /* Update the maximum file descriptor value. */ 157 /* Update the maximum file descriptor value. */
134 if (sock > channel_max_fd_value) 158 if (rfd > channel_max_fd_value)
135 channel_max_fd_value = sock; 159 channel_max_fd_value = rfd;
160 if (wfd > channel_max_fd_value)
161 channel_max_fd_value = wfd;
162 if (efd > channel_max_fd_value)
163 channel_max_fd_value = efd;
136 /* XXX set close-on-exec -markus */ 164 /* XXX set close-on-exec -markus */
137 165
138 /* Do initial allocation if this is the first call. */ 166 /* Do initial allocation if this is the first call. */
@@ -167,388 +195,514 @@ channel_allocate(int type, int sock, char *remote_name)
167 c = &channels[found]; 195 c = &channels[found];
168 buffer_init(&c->input); 196 buffer_init(&c->input);
169 buffer_init(&c->output); 197 buffer_init(&c->output);
198 buffer_init(&c->extended);
170 chan_init_iostates(c); 199 chan_init_iostates(c);
171 c->self = found; 200 c->self = found;
172 c->type = type; 201 c->type = type;
173 c->sock = sock; 202 c->ctype = ctype;
203 c->local_window = window;
204 c->local_window_max = window;
205 c->local_consumed = 0;
206 c->local_maxpacket = maxpack;
207 c->remote_window = 0;
208 c->remote_maxpacket = 0;
209 c->rfd = rfd;
210 c->wfd = wfd;
211 c->sock = (rfd == wfd) ? rfd : -1;
212 c->efd = efd;
213 c->extended_usage = extended_usage;
174 c->remote_id = -1; 214 c->remote_id = -1;
175 c->remote_name = remote_name; 215 c->remote_name = remote_name;
216 c->remote_window = 0;
217 c->remote_maxpacket = 0;
218 c->cb_fn = NULL;
219 c->cb_arg = NULL;
220 c->cb_event = 0;
221 c->dettach_user = NULL;
176 debug("channel %d: new [%s]", found, remote_name); 222 debug("channel %d: new [%s]", found, remote_name);
177 return found; 223 return found;
178} 224}
225int
226channel_allocate(int type, int sock, char *remote_name)
227{
228 return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name);
229}
179 230
180/* Free the channel and close its socket. */ 231/* Free the channel and close its socket. */
181 232
182void 233void
183channel_free(int channel) 234channel_free(int id)
184{ 235{
185 if (channel < 0 || channel >= channels_alloc || 236 Channel *c = channel_lookup(id);
186 channels[channel].type == SSH_CHANNEL_FREE) 237 if (c == NULL)
187 packet_disconnect("channel free: bad local channel %d", channel); 238 packet_disconnect("channel free: bad local channel %d", id);
188 239 debug("channel_free: channel %d: status: %s", id, channel_open_message());
189 if (compat13) 240 if (c->sock != -1) {
190 shutdown(channels[channel].sock, SHUT_RDWR); 241 shutdown(c->sock, SHUT_RDWR);
191 close(channels[channel].sock); 242 close(c->sock);
192 buffer_free(&channels[channel].input); 243 }
193 buffer_free(&channels[channel].output); 244 buffer_free(&c->input);
194 channels[channel].type = SSH_CHANNEL_FREE; 245 buffer_free(&c->output);
195 if (channels[channel].remote_name) { 246 buffer_free(&c->extended);
196 xfree(channels[channel].remote_name); 247 c->type = SSH_CHANNEL_FREE;
197 channels[channel].remote_name = NULL; 248 if (c->remote_name) {
249 xfree(c->remote_name);
250 c->remote_name = NULL;
198 } 251 }
199} 252}
200 253
201/* 254/*
202 * This is called just before select() to add any bits relevant to channels 255 * 'channel_pre*' are called just before select() to add any bits relevant to
203 * in the select bitmasks. 256 * channels in the select bitmasks.
257 */
258/*
259 * 'channel_post*': perform any appropriate operations for channels which
260 * have events pending.
204 */ 261 */
262typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset);
263chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];
264chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];
205 265
206void 266void
207channel_prepare_select(fd_set * readset, fd_set * writeset) 267channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset)
208{ 268{
209 int i; 269 FD_SET(c->sock, readset);
210 Channel *ch; 270}
211 unsigned char *ucp;
212 unsigned int proto_len, data_len;
213 271
214 for (i = 0; i < channels_alloc; i++) { 272void
215 ch = &channels[i]; 273channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
216redo: 274{
217 switch (ch->type) { 275 if (buffer_len(&c->input) < packet_get_maxsize())
218 case SSH_CHANNEL_X11_LISTENER: 276 FD_SET(c->sock, readset);
219 case SSH_CHANNEL_PORT_LISTENER: 277 if (buffer_len(&c->output) > 0)
220 case SSH_CHANNEL_AUTH_SOCKET: 278 FD_SET(c->sock, writeset);
221 FD_SET(ch->sock, readset); 279}
222 break;
223 280
224 case SSH_CHANNEL_OPEN: 281void
225 if (compat13) { 282channel_pre_open_15(Channel *c, fd_set * readset, fd_set * writeset)
226 if (buffer_len(&ch->input) < packet_get_maxsize()) 283{
227 FD_SET(ch->sock, readset); 284 /* test whether sockets are 'alive' for read/write */
228 if (buffer_len(&ch->output) > 0) 285 if (c->istate == CHAN_INPUT_OPEN)
229 FD_SET(ch->sock, writeset); 286 if (buffer_len(&c->input) < packet_get_maxsize())
230 break; 287 FD_SET(c->sock, readset);
231 } 288 if (c->ostate == CHAN_OUTPUT_OPEN ||
232 /* test whether sockets are 'alive' for read/write */ 289 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
233 if (ch->istate == CHAN_INPUT_OPEN) 290 if (buffer_len(&c->output) > 0) {
234 if (buffer_len(&ch->input) < packet_get_maxsize()) 291 FD_SET(c->sock, writeset);
235 FD_SET(ch->sock, readset); 292 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
236 if (ch->ostate == CHAN_OUTPUT_OPEN || 293 chan_obuf_empty(c);
237 ch->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 294 }
238 if (buffer_len(&ch->output) > 0) { 295 }
239 FD_SET(ch->sock, writeset); 296}
240 } else if (ch->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
241 chan_obuf_empty(ch);
242 }
243 }
244 break;
245 297
246 case SSH_CHANNEL_INPUT_DRAINING: 298void
247 if (!compat13) 299channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
248 fatal("cannot happen: IN_DRAIN"); 300{
249 if (buffer_len(&ch->input) == 0) { 301 if (buffer_len(&c->input) == 0) {
250 packet_start(SSH_MSG_CHANNEL_CLOSE); 302 packet_start(SSH_MSG_CHANNEL_CLOSE);
251 packet_put_int(ch->remote_id); 303 packet_put_int(c->remote_id);
252 packet_send(); 304 packet_send();
253 ch->type = SSH_CHANNEL_CLOSED; 305 c->type = SSH_CHANNEL_CLOSED;
254 debug("Closing channel %d after input drain.", ch->self); 306 debug("Closing channel %d after input drain.", c->self);
255 break; 307 }
256 } 308}
257 break;
258 309
259 case SSH_CHANNEL_OUTPUT_DRAINING: 310void
260 if (!compat13) 311channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
261 fatal("cannot happen: OUT_DRAIN"); 312{
262 if (buffer_len(&ch->output) == 0) { 313 if (buffer_len(&c->output) == 0)
263 channel_free(i); 314 channel_free(c->self);
264 break; 315 else
265 } 316 FD_SET(c->sock, writeset);
266 FD_SET(ch->sock, writeset); 317}
267 break;
268 318
269 case SSH_CHANNEL_X11_OPEN: 319/*
270 /* 320 * This is a special state for X11 authentication spoofing. An opened X11
271 * This is a special state for X11 authentication 321 * connection (when authentication spoofing is being done) remains in this
272 * spoofing. An opened X11 connection (when 322 * state until the first packet has been completely read. The authentication
273 * authentication spoofing is being done) remains in 323 * data in that packet is then substituted by the real data if it matches the
274 * this state until the first packet has been 324 * fake data, and the channel is put into normal mode.
275 * completely read. The authentication data in that 325 */
276 * packet is then substituted by the real data if it 326int
277 * matches the fake data, and the channel is put into 327x11_open_helper(Channel *c)
278 * normal mode. 328{
279 */ 329 unsigned char *ucp;
280 /* Check if the fixed size part of the packet is in buffer. */ 330 unsigned int proto_len, data_len;
281 if (buffer_len(&ch->output) < 12)
282 break;
283 331
284 /* Parse the lengths of variable-length fields. */ 332 /* Check if the fixed size part of the packet is in buffer. */
285 ucp = (unsigned char *) buffer_ptr(&ch->output); 333 if (buffer_len(&c->output) < 12)
286 if (ucp[0] == 0x42) { /* Byte order MSB first. */ 334 return 0;
287 proto_len = 256 * ucp[6] + ucp[7]; 335
288 data_len = 256 * ucp[8] + ucp[9]; 336 /* Parse the lengths of variable-length fields. */
289 } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */ 337 ucp = (unsigned char *) buffer_ptr(&c->output);
290 proto_len = ucp[6] + 256 * ucp[7]; 338 if (ucp[0] == 0x42) { /* Byte order MSB first. */
291 data_len = ucp[8] + 256 * ucp[9]; 339 proto_len = 256 * ucp[6] + ucp[7];
292 } else { 340 data_len = 256 * ucp[8] + ucp[9];
293 debug("Initial X11 packet contains bad byte order byte: 0x%x", 341 } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */
294 ucp[0]); 342 proto_len = ucp[6] + 256 * ucp[7];
295 ch->type = SSH_CHANNEL_OPEN; 343 data_len = ucp[8] + 256 * ucp[9];
296 goto reject; 344 } else {
297 } 345 debug("Initial X11 packet contains bad byte order byte: 0x%x",
346 ucp[0]);
347 return -1;
348 }
298 349
299 /* Check if the whole packet is in buffer. */ 350 /* Check if the whole packet is in buffer. */
300 if (buffer_len(&ch->output) < 351 if (buffer_len(&c->output) <
301 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) 352 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
302 break; 353 return 0;
303 354
304 /* Check if authentication protocol matches. */ 355 /* Check if authentication protocol matches. */
305 if (proto_len != strlen(x11_saved_proto) || 356 if (proto_len != strlen(x11_saved_proto) ||
306 memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { 357 memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {
307 debug("X11 connection uses different authentication protocol."); 358 debug("X11 connection uses different authentication protocol.");
308 ch->type = SSH_CHANNEL_OPEN; 359 return -1;
309 goto reject; 360 }
310 } 361 /* Check if authentication data matches our fake data. */
311 /* Check if authentication data matches our fake data. */ 362 if (data_len != x11_fake_data_len ||
312 if (data_len != x11_fake_data_len || 363 memcmp(ucp + 12 + ((proto_len + 3) & ~3),
313 memcmp(ucp + 12 + ((proto_len + 3) & ~3), 364 x11_fake_data, x11_fake_data_len) != 0) {
314 x11_fake_data, x11_fake_data_len) != 0) { 365 debug("X11 auth data does not match fake data.");
315 debug("X11 auth data does not match fake data."); 366 return -1;
316 ch->type = SSH_CHANNEL_OPEN; 367 }
317 goto reject; 368 /* Check fake data length */
318 } 369 if (x11_fake_data_len != x11_saved_data_len) {
319 /* Check fake data length */ 370 error("X11 fake_data_len %d != saved_data_len %d",
320 if (x11_fake_data_len != x11_saved_data_len) { 371 x11_fake_data_len, x11_saved_data_len);
321 error("X11 fake_data_len %d != saved_data_len %d", 372 return -1;
322 x11_fake_data_len, x11_saved_data_len); 373 }
323 ch->type = SSH_CHANNEL_OPEN; 374 /*
324 goto reject; 375 * Received authentication protocol and data match
325 } 376 * our fake data. Substitute the fake data with real
326 /* 377 * data.
327 * Received authentication protocol and data match 378 */
328 * our fake data. Substitute the fake data with real 379 memcpy(ucp + 12 + ((proto_len + 3) & ~3),
329 * data. 380 x11_saved_data, x11_saved_data_len);
330 */ 381 return 1;
331 memcpy(ucp + 12 + ((proto_len + 3) & ~3), 382}
332 x11_saved_data, x11_saved_data_len);
333 383
334 /* Start normal processing for the channel. */ 384void
335 ch->type = SSH_CHANNEL_OPEN; 385channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
336 goto redo; 386{
387 int ret = x11_open_helper(c);
388 if (ret == 1) {
389 /* Start normal processing for the channel. */
390 c->type = SSH_CHANNEL_OPEN;
391 } else if (ret == -1) {
392 /*
393 * We have received an X11 connection that has bad
394 * authentication information.
395 */
396 log("X11 connection rejected because of wrong authentication.\r\n");
397 buffer_clear(&c->input);
398 buffer_clear(&c->output);
399 close(c->sock);
400 c->sock = -1;
401 c->type = SSH_CHANNEL_CLOSED;
402 packet_start(SSH_MSG_CHANNEL_CLOSE);
403 packet_put_int(c->remote_id);
404 packet_send();
405 }
406}
337 407
338 reject: 408void
339 /* 409channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset)
340 * We have received an X11 connection that has bad 410{
341 * authentication information. 411 int ret = x11_open_helper(c);
342 */ 412 if (ret == 1) {
343 log("X11 connection rejected because of wrong authentication.\r\n"); 413 c->type = SSH_CHANNEL_OPEN;
344 buffer_clear(&ch->input); 414 } else if (ret == -1) {
345 buffer_clear(&ch->output); 415 debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
346 if (compat13) { 416 chan_read_failed(c);
347 close(ch->sock); 417 chan_write_failed(c);
348 ch->sock = -1; 418 debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
349 ch->type = SSH_CHANNEL_CLOSED; 419 }
350 packet_start(SSH_MSG_CHANNEL_CLOSE); 420}
351 packet_put_int(ch->remote_id);
352 packet_send();
353 } else {
354 debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate);
355 chan_read_failed(ch);
356 chan_write_failed(ch);
357 debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate);
358 }
359 break;
360 421
361 case SSH_CHANNEL_FREE: 422/* This is our fake X11 server socket. */
362 default: 423void
363 continue; 424channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
425{
426 struct sockaddr addr;
427 int newsock, newch;
428 socklen_t addrlen;
429 char buf[16384], *remote_hostname;
430
431 if (FD_ISSET(c->sock, readset)) {
432 debug("X11 connection requested.");
433 addrlen = sizeof(addr);
434 newsock = accept(c->sock, &addr, &addrlen);
435 if (newsock < 0) {
436 error("accept: %.100s", strerror(errno));
437 return;
364 } 438 }
439 remote_hostname = get_remote_hostname(newsock);
440 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
441 remote_hostname, get_peer_port(newsock));
442 xfree(remote_hostname);
443 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
444 xstrdup(buf));
445 packet_start(SSH_SMSG_X11_OPEN);
446 packet_put_int(newch);
447 if (have_hostname_in_open)
448 packet_put_string(buf, strlen(buf));
449 packet_send();
365 } 450 }
366} 451}
367 452
368/* 453/*
369 * After select, perform any appropriate operations for channels which have 454 * This socket is listening for connections to a forwarded TCP/IP port.
370 * events pending.
371 */ 455 */
456void
457channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
458{
459 struct sockaddr addr;
460 int newsock, newch;
461 socklen_t addrlen;
462 char buf[1024], *remote_hostname;
463 int remote_port;
464
465 if (FD_ISSET(c->sock, readset)) {
466 debug("Connection to port %d forwarding "
467 "to %.100s port %d requested.",
468 c->listening_port, c->path, c->host_port);
469 addrlen = sizeof(addr);
470 newsock = accept(c->sock, &addr, &addrlen);
471 if (newsock < 0) {
472 error("accept: %.100s", strerror(errno));
473 return;
474 }
475 remote_hostname = get_remote_hostname(newsock);
476 remote_port = get_peer_port(newsock);
477 snprintf(buf, sizeof buf,
478 "listen port %d for %.100s port %d, "
479 "connect from %.200s port %d",
480 c->listening_port, c->path, c->host_port,
481 remote_hostname, remote_port);
482 newch = channel_new("direct-tcpip",
483 SSH_CHANNEL_OPENING, newsock, newsock, -1,
484 c->local_window_max, c->local_maxpacket,
485 0, xstrdup(buf));
486
487 packet_start(SSH_MSG_PORT_OPEN);
488 packet_put_int(newch);
489 packet_put_string(c->path, strlen(c->path));
490 packet_put_int(c->host_port);
491 if (have_hostname_in_open) {
492 packet_put_string(buf, strlen(buf));
493 }
494 packet_send();
495 xfree(remote_hostname);
496 }
497}
372 498
373void 499/*
374channel_after_select(fd_set * readset, fd_set * writeset) 500 * This is the authentication agent socket listening for connections from
501 * clients.
502 */
503void
504channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
375{ 505{
376 struct sockaddr addr; 506 struct sockaddr addr;
377 int newsock, i, newch, len; 507 int newsock, newch;
378 socklen_t addrlen; 508 socklen_t addrlen;
379 Channel *ch;
380 char buf[16384], *remote_hostname;
381 509
382 /* Loop over all channels... */ 510 if (FD_ISSET(c->sock, readset)) {
383 for (i = 0; i < channels_alloc; i++) { 511 addrlen = sizeof(addr);
384 ch = &channels[i]; 512 newsock = accept(c->sock, &addr, &addrlen);
385 switch (ch->type) { 513 if (newsock < 0) {
386 case SSH_CHANNEL_X11_LISTENER: 514 error("accept from auth socket: %.100s", strerror(errno));
387 /* This is our fake X11 server socket. */ 515 return;
388 if (FD_ISSET(ch->sock, readset)) { 516 }
389 debug("X11 connection requested."); 517 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
390 addrlen = sizeof(addr); 518 xstrdup("accepted auth socket"));
391 newsock = accept(ch->sock, &addr, &addrlen); 519 packet_start(SSH_SMSG_AGENT_OPEN);
392 if (newsock < 0) { 520 packet_put_int(newch);
393 error("accept: %.100s", strerror(errno)); 521 packet_send();
394 break; 522 }
395 } 523}
396 remote_hostname = get_remote_hostname(newsock);
397 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
398 remote_hostname, get_peer_port(newsock));
399 xfree(remote_hostname);
400 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
401 xstrdup(buf));
402 packet_start(SSH_SMSG_X11_OPEN);
403 packet_put_int(newch);
404 if (have_hostname_in_open)
405 packet_put_string(buf, strlen(buf));
406 packet_send();
407 }
408 break;
409 524
410 case SSH_CHANNEL_PORT_LISTENER: 525int
411 /* 526channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
412 * This socket is listening for connections to a 527{
413 * forwarded TCP/IP port. 528 char buf[16*1024];
414 */ 529 int len;
415 if (FD_ISSET(ch->sock, readset)) { 530
416 debug("Connection to port %d forwarding to %.100s port %d requested.", 531 if (c->rfd != -1 &&
417 ch->listening_port, ch->path, ch->host_port); 532 FD_ISSET(c->rfd, readset)) {
418 addrlen = sizeof(addr); 533 len = read(c->rfd, buf, sizeof(buf));
419 newsock = accept(ch->sock, &addr, &addrlen); 534 if (len <= 0) {
420 if (newsock < 0) { 535 debug("channel %d: read<0 rfd %d len %d",
421 error("accept: %.100s", strerror(errno)); 536 c->self, c->rfd, len);
422 break; 537 if (compat13) {
423 } 538 buffer_consume(&c->output, buffer_len(&c->output));
424 remote_hostname = get_remote_hostname(newsock); 539 c->type = SSH_CHANNEL_INPUT_DRAINING;
425 snprintf(buf, sizeof buf, "listen port %d for %.100s port %d, connect from %.200s port %d", 540 debug("Channel %d status set to input draining.", c->self);
426 ch->listening_port, ch->path, ch->host_port, 541 } else {
427 remote_hostname, get_peer_port(newsock)); 542 chan_read_failed(c);
428 xfree(remote_hostname);
429 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
430 xstrdup(buf));
431 packet_start(SSH_MSG_PORT_OPEN);
432 packet_put_int(newch);
433 packet_put_string(ch->path, strlen(ch->path));
434 packet_put_int(ch->host_port);
435 if (have_hostname_in_open)
436 packet_put_string(buf, strlen(buf));
437 packet_send();
438 } 543 }
439 break; 544 return -1;
440 545 }
441 case SSH_CHANNEL_AUTH_SOCKET: 546 buffer_append(&c->input, buf, len);
442 /* 547 }
443 * This is the authentication agent socket listening 548 return 1;
444 * for connections from clients. 549}
445 */ 550int
446 if (FD_ISSET(ch->sock, readset)) { 551channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
447 addrlen = sizeof(addr); 552{
448 newsock = accept(ch->sock, &addr, &addrlen); 553 int len;
449 if (newsock < 0) { 554
450 error("accept from auth socket: %.100s", strerror(errno)); 555 /* Send buffered output data to the socket. */
451 break; 556 if (c->wfd != -1 &&
452 } 557 FD_ISSET(c->wfd, writeset) &&
453 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, 558 buffer_len(&c->output) > 0) {
454 xstrdup("accepted auth socket")); 559 len = write(c->wfd, buffer_ptr(&c->output),
455 packet_start(SSH_SMSG_AGENT_OPEN); 560 buffer_len(&c->output));
456 packet_put_int(newch); 561 if (len <= 0) {
457 packet_send(); 562 if (compat13) {
563 buffer_consume(&c->output, buffer_len(&c->output));
564 debug("Channel %d status set to input draining.", c->self);
565 c->type = SSH_CHANNEL_INPUT_DRAINING;
566 } else {
567 chan_write_failed(c);
458 } 568 }
459 break; 569 return -1;
570 }
571 buffer_consume(&c->output, len);
572 }
573 return 1;
574}
460 575
461 case SSH_CHANNEL_OPEN: 576void
462 /* 577channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset)
463 * This is an open two-way communication channel. It 578{
464 * is not of interest to us at this point what kind 579 channel_handle_rfd(c, readset, writeset);
465 * of data is being transmitted. 580 channel_handle_wfd(c, readset, writeset);
466 */ 581}
467 582
468 /* 583void
469 * Read available incoming data and append it to 584channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
470 * buffer; shutdown socket, if read or write failes 585{
471 */ 586 int len;
472 if (FD_ISSET(ch->sock, readset)) { 587 /* Send buffered output data to the socket. */
473 len = read(ch->sock, buf, sizeof(buf)); 588 if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {
474 if (len <= 0) { 589 len = write(c->sock, buffer_ptr(&c->output),
475 if (compat13) { 590 buffer_len(&c->output));
476 buffer_consume(&ch->output, buffer_len(&ch->output)); 591 if (len <= 0)
477 ch->type = SSH_CHANNEL_INPUT_DRAINING; 592 buffer_consume(&c->output, buffer_len(&c->output));
478 debug("Channel %d status set to input draining.", i); 593 else
479 } else { 594 buffer_consume(&c->output, len);
480 chan_read_failed(ch); 595 }
481 } 596}
482 break;
483 }
484 buffer_append(&ch->input, buf, len);
485 }
486 /* Send buffered output data to the socket. */
487 if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0) {
488 len = write(ch->sock, buffer_ptr(&ch->output),
489 buffer_len(&ch->output));
490 if (len <= 0) {
491 if (compat13) {
492 buffer_consume(&ch->output, buffer_len(&ch->output));
493 debug("Channel %d status set to input draining.", i);
494 ch->type = SSH_CHANNEL_INPUT_DRAINING;
495 } else {
496 chan_write_failed(ch);
497 }
498 break;
499 }
500 buffer_consume(&ch->output, len);
501 }
502 break;
503 597
504 case SSH_CHANNEL_OUTPUT_DRAINING: 598void
505 if (!compat13) 599channel_handler_init_13(void)
506 fatal("cannot happen: OUT_DRAIN"); 600{
507 /* Send buffered output data to the socket. */ 601 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13;
508 if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0) { 602 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13;
509 len = write(ch->sock, buffer_ptr(&ch->output), 603 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
510 buffer_len(&ch->output)); 604 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
511 if (len <= 0) 605 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
512 buffer_consume(&ch->output, buffer_len(&ch->output)); 606 channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining;
513 else 607 channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining;
514 buffer_consume(&ch->output, len); 608
515 } 609 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1;
516 break; 610 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
611 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
612 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
613 channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13;
614}
517 615
518 case SSH_CHANNEL_X11_OPEN: 616void
519 case SSH_CHANNEL_FREE: 617channel_handler_init_15(void)
520 default: 618{
619 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15;
620 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_15;
621 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
622 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
623 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
624
625 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
626 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
627 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
628 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1;
629}
630
631void
632channel_handler_init(void)
633{
634 int i;
635 for(i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
636 channel_pre[i] = NULL;
637 channel_post[i] = NULL;
638 }
639 if (compat13)
640 channel_handler_init_13();
641 else
642 channel_handler_init_15();
643}
644
645void
646channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
647{
648 static int did_init = 0;
649 int i;
650 Channel *c;
651
652 if (!did_init) {
653 channel_handler_init();
654 did_init = 1;
655 }
656 for (i = 0; i < channels_alloc; i++) {
657 c = &channels[i];
658 if (c->type == SSH_CHANNEL_FREE)
521 continue; 659 continue;
522 } 660 if (ftab[c->type] == NULL)
661 continue;
662 (*ftab[c->type])(c, readset, writeset);
663 if (!compat13)
664 chan_delete_if_full_closed(c);
523 } 665 }
524} 666}
525 667
668void
669channel_prepare_select(fd_set * readset, fd_set * writeset)
670{
671 channel_handler(channel_pre, readset, writeset);
672}
673
674void
675channel_after_select(fd_set * readset, fd_set * writeset)
676{
677 channel_handler(channel_post, readset, writeset);
678}
679
526/* If there is data to send to the connection, send some of it now. */ 680/* If there is data to send to the connection, send some of it now. */
527 681
528void 682void
529channel_output_poll() 683channel_output_poll()
530{ 684{
531 int len, i; 685 int len, i;
532 Channel *ch; 686 Channel *c;
533 687
534 for (i = 0; i < channels_alloc; i++) { 688 for (i = 0; i < channels_alloc; i++) {
535 ch = &channels[i]; 689 c = &channels[i];
536 690
537 /* We are only interested in channels that can have buffered incoming data. */ 691 /* We are only interested in channels that can have buffered incoming data. */
538 if (compat13) { 692 if (compat13) {
539 if (ch->type != SSH_CHANNEL_OPEN && 693 if (c->type != SSH_CHANNEL_OPEN &&
540 ch->type != SSH_CHANNEL_INPUT_DRAINING) 694 c->type != SSH_CHANNEL_INPUT_DRAINING)
541 continue; 695 continue;
542 } else { 696 } else {
543 if (ch->type != SSH_CHANNEL_OPEN) 697 if (c->type != SSH_CHANNEL_OPEN)
544 continue; 698 continue;
545 if (ch->istate != CHAN_INPUT_OPEN && 699 if (c->istate != CHAN_INPUT_OPEN &&
546 ch->istate != CHAN_INPUT_WAIT_DRAIN) 700 c->istate != CHAN_INPUT_WAIT_DRAIN)
547 continue; 701 continue;
548 } 702 }
549 703
550 /* Get the amount of buffered data for this channel. */ 704 /* Get the amount of buffered data for this channel. */
551 len = buffer_len(&ch->input); 705 len = buffer_len(&c->input);
552 if (len > 0) { 706 if (len > 0) {
553 /* Send some data for the other side over the secure connection. */ 707 /* Send some data for the other side over the secure connection. */
554 if (packet_is_interactive()) { 708 if (packet_is_interactive()) {
@@ -556,22 +710,26 @@ channel_output_poll()
556 len = 512; 710 len = 512;
557 } else { 711 } else {
558 /* Keep the packets at reasonable size. */ 712 /* Keep the packets at reasonable size. */
559 if (len > packet_get_maxsize()/2) 713 if (len > packet_get_maxsize())
560 len = packet_get_maxsize()/2; 714 len = packet_get_maxsize()/2;
561 } 715 }
562 packet_start(SSH_MSG_CHANNEL_DATA); 716 if (len > 0) {
563 packet_put_int(ch->remote_id); 717 packet_start(SSH_MSG_CHANNEL_DATA);
564 packet_put_string(buffer_ptr(&ch->input), len); 718 packet_put_int(c->remote_id);
565 packet_send(); 719 packet_put_string(buffer_ptr(&c->input), len);
566 buffer_consume(&ch->input, len); 720 packet_send();
567 } else if (ch->istate == CHAN_INPUT_WAIT_DRAIN) { 721 buffer_consume(&c->input, len);
722 c->remote_window -= len;
723debug("channel %d: send data len %d", c->self, len);
724 }
725 } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
568 if (compat13) 726 if (compat13)
569 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); 727 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
570 /* 728 /*
571 * input-buffer is empty and read-socket shutdown: 729 * input-buffer is empty and read-socket shutdown:
572 * tell peer, that we will not send more data: send IEOF 730 * tell peer, that we will not send more data: send IEOF
573 */ 731 */
574 chan_ibuf_empty(ch); 732 chan_ibuf_empty(c);
575 } 733 }
576 } 734 }
577} 735}
@@ -583,35 +741,33 @@ channel_output_poll()
583 */ 741 */
584 742
585void 743void
586channel_input_data(int payload_len) 744channel_input_data(int type, int plen)
587{ 745{
588 int id; 746 int id;
589 char *data; 747 char *data;
590 unsigned int data_len; 748 unsigned int data_len;
591 Channel *ch; 749 Channel *c;
592 750
593 /* Get the channel number and verify it. */ 751 /* Get the channel number and verify it. */
594 id = packet_get_int(); 752 id = packet_get_int();
595 if (id < 0 || id >= channels_alloc) 753 c = channel_lookup(id);
754 if (c == NULL)
596 packet_disconnect("Received data for nonexistent channel %d.", id); 755 packet_disconnect("Received data for nonexistent channel %d.", id);
597 ch = &channels[id];
598
599 if (ch->type == SSH_CHANNEL_FREE)
600 packet_disconnect("Received data for free channel %d.", ch->self);
601 756
602 /* Ignore any data for non-open channels (might happen on close) */ 757 /* Ignore any data for non-open channels (might happen on close) */
603 if (ch->type != SSH_CHANNEL_OPEN && 758 if (c->type != SSH_CHANNEL_OPEN &&
604 ch->type != SSH_CHANNEL_X11_OPEN) 759 c->type != SSH_CHANNEL_X11_OPEN)
605 return; 760 return;
606 761
607 /* same for protocol 1.5 if output end is no longer open */ 762 /* same for protocol 1.5 if output end is no longer open */
608 if (!compat13 && ch->ostate != CHAN_OUTPUT_OPEN) 763 if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN)
609 return; 764 return;
610 765
611 /* Get the data. */ 766 /* Get the data. */
612 data = packet_get_string(&data_len); 767 data = packet_get_string(&data_len);
613 packet_integrity_check(payload_len, 4 + 4 + data_len, SSH_MSG_CHANNEL_DATA); 768
614 buffer_append(&ch->output, data, data_len); 769 packet_integrity_check(plen, 4 + 4 + data_len, SSH_MSG_CHANNEL_DATA);
770 buffer_append(&c->output, data, data_len);
615 xfree(data); 771 xfree(data);
616} 772}
617 773
@@ -624,45 +780,60 @@ int
624channel_not_very_much_buffered_data() 780channel_not_very_much_buffered_data()
625{ 781{
626 unsigned int i; 782 unsigned int i;
627 Channel *ch; 783 Channel *c;
628 784
629 for (i = 0; i < channels_alloc; i++) { 785 for (i = 0; i < channels_alloc; i++) {
630 ch = &channels[i]; 786 c = &channels[i];
631 if (ch->type == SSH_CHANNEL_OPEN) { 787 if (c->type == SSH_CHANNEL_OPEN) {
632 if (buffer_len(&ch->input) > packet_get_maxsize()) 788 if (buffer_len(&c->input) > packet_get_maxsize()) {
789 debug("channel %d: big input buffer %d",
790 c->self, buffer_len(&c->input));
633 return 0; 791 return 0;
634 if (buffer_len(&ch->output) > packet_get_maxsize()) 792 }
793 if (buffer_len(&c->output) > packet_get_maxsize()) {
794 debug("channel %d: big output buffer %d",
795 c->self, buffer_len(&c->output));
635 return 0; 796 return 0;
797 }
636 } 798 }
637 } 799 }
638 return 1; 800 return 1;
639} 801}
640 802
641/* This is called after receiving CHANNEL_CLOSE/IEOF. */ 803void
804channel_input_ieof(int type, int plen)
805{
806 int id;
807 Channel *c;
808
809 packet_integrity_check(plen, 4, type);
810
811 id = packet_get_int();
812 c = channel_lookup(id);
813 if (c == NULL)
814 packet_disconnect("Received ieof for nonexistent channel %d.", id);
815 chan_rcvd_ieof(c);
816}
642 817
643void 818void
644channel_input_close() 819channel_input_close(int type, int plen)
645{ 820{
646 int channel; 821 int id;
822 Channel *c;
647 823
648 /* Get the channel number and verify it. */ 824 packet_integrity_check(plen, 4, type);
649 channel = packet_get_int(); 825
650 if (channel < 0 || channel >= channels_alloc || 826 id = packet_get_int();
651 channels[channel].type == SSH_CHANNEL_FREE) 827 c = channel_lookup(id);
652 packet_disconnect("Received data for nonexistent channel %d.", channel); 828 if (c == NULL)
653 829 packet_disconnect("Received close for nonexistent channel %d.", id);
654 if (!compat13) {
655 /* proto version 1.5 overloads CLOSE with IEOF */
656 chan_rcvd_ieof(&channels[channel]);
657 return;
658 }
659 830
660 /* 831 /*
661 * Send a confirmation that we have closed the channel and no more 832 * Send a confirmation that we have closed the channel and no more
662 * data is coming for it. 833 * data is coming for it.
663 */ 834 */
664 packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); 835 packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
665 packet_put_int(channels[channel].remote_id); 836 packet_put_int(c->remote_id);
666 packet_send(); 837 packet_send();
667 838
668 /* 839 /*
@@ -672,81 +843,80 @@ channel_input_close()
672 * no-one to receive the confirmation. The channel gets freed when 843 * no-one to receive the confirmation. The channel gets freed when
673 * the confirmation arrives. 844 * the confirmation arrives.
674 */ 845 */
675 if (channels[channel].type != SSH_CHANNEL_CLOSED) { 846 if (c->type != SSH_CHANNEL_CLOSED) {
676 /* 847 /*
677 * Not a closed channel - mark it as draining, which will 848 * Not a closed channel - mark it as draining, which will
678 * cause it to be freed later. 849 * cause it to be freed later.
679 */ 850 */
680 buffer_consume(&channels[channel].input, 851 buffer_consume(&c->input, buffer_len(&c->input));
681 buffer_len(&channels[channel].input)); 852 c->type = SSH_CHANNEL_OUTPUT_DRAINING;
682 channels[channel].type = SSH_CHANNEL_OUTPUT_DRAINING;
683 } 853 }
684} 854}
685 855
686/* This is called after receiving CHANNEL_CLOSE_CONFIRMATION/OCLOSE. */ 856/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
687
688void 857void
689channel_input_close_confirmation() 858channel_input_oclose(int type, int plen)
690{ 859{
691 int channel; 860 int id = packet_get_int();
692 861 Channel *c = channel_lookup(id);
693 /* Get the channel number and verify it. */ 862 packet_integrity_check(plen, 4, type);
694 channel = packet_get_int(); 863 if (c == NULL)
695 if (channel < 0 || channel >= channels_alloc) 864 packet_disconnect("Received oclose for nonexistent channel %d.", id);
696 packet_disconnect("Received close confirmation for out-of-range channel %d.", 865 chan_rcvd_oclose(c);
697 channel);
698
699 if (!compat13) {
700 /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
701 chan_rcvd_oclose(&channels[channel]);
702 return;
703 }
704 if (channels[channel].type != SSH_CHANNEL_CLOSED)
705 packet_disconnect("Received close confirmation for non-closed channel %d (type %d).",
706 channel, channels[channel].type);
707
708 /* Free the channel. */
709 channel_free(channel);
710} 866}
711 867
712/* This is called after receiving CHANNEL_OPEN_CONFIRMATION. */ 868void
869channel_input_close_confirmation(int type, int plen)
870{
871 int id = packet_get_int();
872 Channel *c = channel_lookup(id);
873
874 if (c == NULL)
875 packet_disconnect("Received close confirmation for "
876 "out-of-range channel %d.", id);
877 if (c->type != SSH_CHANNEL_CLOSED)
878 packet_disconnect("Received close confirmation for "
879 "non-closed channel %d (type %d).", id, c->type);
880 channel_free(c->self);
881}
713 882
714void 883void
715channel_input_open_confirmation() 884channel_input_open_confirmation(int type, int plen)
716{ 885{
717 int channel, remote_channel; 886 int id, remote_id;
887 Channel *c;
718 888
719 /* Get the channel number and verify it. */ 889 packet_integrity_check(plen, 4 + 4, type);
720 channel = packet_get_int();
721 if (channel < 0 || channel >= channels_alloc ||
722 channels[channel].type != SSH_CHANNEL_OPENING)
723 packet_disconnect("Received open confirmation for non-opening channel %d.",
724 channel);
725 890
726 /* Get remote side's id for this channel. */ 891 id = packet_get_int();
727 remote_channel = packet_get_int(); 892 c = channel_lookup(id);
728 893
894 if (c==NULL || c->type != SSH_CHANNEL_OPENING)
895 packet_disconnect("Received open confirmation for "
896 "non-opening channel %d.", id);
897 remote_id = packet_get_int();
729 /* Record the remote channel number and mark that the channel is now open. */ 898 /* Record the remote channel number and mark that the channel is now open. */
730 channels[channel].remote_id = remote_channel; 899 c->remote_id = remote_id;
731 channels[channel].type = SSH_CHANNEL_OPEN; 900 c->type = SSH_CHANNEL_OPEN;
732} 901}
733 902
734/* This is called after receiving CHANNEL_OPEN_FAILURE from the other side. */
735
736void 903void
737channel_input_open_failure() 904channel_input_open_failure(int type, int plen)
738{ 905{
739 int channel; 906 int id;
907 Channel *c;
740 908
741 /* Get the channel number and verify it. */ 909 packet_integrity_check(plen, 4, type);
742 channel = packet_get_int(); 910
743 if (channel < 0 || channel >= channels_alloc || 911 id = packet_get_int();
744 channels[channel].type != SSH_CHANNEL_OPENING) 912 c = channel_lookup(id);
745 packet_disconnect("Received open failure for non-opening channel %d.", 913
746 channel); 914 if (c==NULL || c->type != SSH_CHANNEL_OPENING)
915 packet_disconnect("Received open failure for "
916 "non-opening channel %d.", id);
747 917
748 /* Free the channel. This will also close the socket. */ 918 /* Free the channel. This will also close the socket. */
749 channel_free(channel); 919 channel_free(id);
750} 920}
751 921
752/* 922/*
@@ -859,15 +1029,16 @@ channel_open_message()
859 case SSH_CHANNEL_X11_OPEN: 1029 case SSH_CHANNEL_X11_OPEN:
860 case SSH_CHANNEL_INPUT_DRAINING: 1030 case SSH_CHANNEL_INPUT_DRAINING:
861 case SSH_CHANNEL_OUTPUT_DRAINING: 1031 case SSH_CHANNEL_OUTPUT_DRAINING:
862 snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d)\r\n", 1032 snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n",
863 c->self, c->remote_name, 1033 c->self, c->remote_name,
864 c->type, c->remote_id, 1034 c->type, c->remote_id,
865 c->istate, buffer_len(&c->input), 1035 c->istate, buffer_len(&c->input),
866 c->ostate, buffer_len(&c->output)); 1036 c->ostate, buffer_len(&c->output),
1037 c->rfd, c->wfd);
867 buffer_append(&buffer, buf, strlen(buf)); 1038 buffer_append(&buffer, buf, strlen(buf));
868 continue; 1039 continue;
869 default: 1040 default:
870 fatal("channel_still_open: bad channel type %d", c->type); 1041 fatal("channel_open_message: bad channel type %d", c->type);
871 /* NOTREACHED */ 1042 /* NOTREACHED */
872 } 1043 }
873 } 1044 }
@@ -950,8 +1121,11 @@ channel_request_local_forwarding(u_short port, const char *host,
950 continue; 1121 continue;
951 } 1122 }
952 /* Allocate a channel number for the socket. */ 1123 /* Allocate a channel number for the socket. */
953 ch = channel_allocate(SSH_CHANNEL_PORT_LISTENER, sock, 1124 ch = channel_new(
954 xstrdup("port listener")); 1125 "port listener", SSH_CHANNEL_PORT_LISTENER,
1126 sock, sock, -1,
1127 CHAN_WINDOW_DEFAULT, CHAN_PACKET_DEFAULT,
1128 0, xstrdup("port listener"));
955 strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); 1129 strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
956 channels[ch].host_port = host_port; 1130 channels[ch].host_port = host_port;
957 channels[ch].listening_port = port; 1131 channels[ch].listening_port = port;
@@ -968,26 +1142,26 @@ channel_request_local_forwarding(u_short port, const char *host,
968 */ 1142 */
969 1143
970void 1144void
971channel_request_remote_forwarding(u_short port, const char *host, 1145channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect,
972 u_short remote_port) 1146 u_short port_to_connect)
973{ 1147{
974 int payload_len; 1148 int payload_len;
975 /* Record locally that connection to this host/port is permitted. */ 1149 /* Record locally that connection to this host/port is permitted. */
976 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) 1150 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
977 fatal("channel_request_remote_forwarding: too many forwards"); 1151 fatal("channel_request_remote_forwarding: too many forwards");
978 1152
979 permitted_opens[num_permitted_opens].host = xstrdup(host); 1153 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
980 permitted_opens[num_permitted_opens].port = remote_port; 1154 permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
1155 permitted_opens[num_permitted_opens].listen_port = listen_port;
981 num_permitted_opens++; 1156 num_permitted_opens++;
982 1157
983 /* Send the forward request to the remote side. */ 1158 /* Send the forward request to the remote side. */
984 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); 1159 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
985 packet_put_int(port); 1160 packet_put_int(port_to_connect);
986 packet_put_string(host, strlen(host)); 1161 packet_put_string(host_to_connect, strlen(host_to_connect));
987 packet_put_int(remote_port); 1162 packet_put_int(listen_port);
988 packet_send(); 1163 packet_send();
989 packet_write_wait(); 1164 packet_write_wait();
990
991 /* 1165 /*
992 * Wait for response from the remote side. It will send a disconnect 1166 * Wait for response from the remote side. It will send a disconnect
993 * message on failure, and we will never see it here. 1167 * message on failure, and we will never see it here.
@@ -1029,63 +1203,14 @@ channel_input_port_forward_request(int is_root)
1029 xfree(hostname); 1203 xfree(hostname);
1030} 1204}
1031 1205
1032/* 1206/* XXX move to aux.c */
1033 * This is called after receiving PORT_OPEN message. This attempts to 1207int
1034 * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION 1208channel_connect_to(const char *host, u_short host_port)
1035 * or CHANNEL_OPEN_FAILURE.
1036 */
1037
1038void
1039channel_input_port_open(int payload_len)
1040{ 1209{
1041 int remote_channel, sock = 0, newch, i;
1042 u_short host_port;
1043 char *host, *originator_string;
1044 unsigned int host_len, originator_len;
1045 struct addrinfo hints, *ai, *aitop; 1210 struct addrinfo hints, *ai, *aitop;
1046 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 1211 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1047 int gaierr; 1212 int gaierr;
1048 1213 int sock = -1;
1049 /* Get remote channel number. */
1050 remote_channel = packet_get_int();
1051
1052 /* Get host name to connect to. */
1053 host = packet_get_string(&host_len);
1054
1055 /* Get port to connect to. */
1056 host_port = packet_get_int();
1057
1058 /* Get remote originator name. */
1059 if (have_hostname_in_open) {
1060 originator_string = packet_get_string(&originator_len);
1061 originator_len += 4; /* size of packet_int */
1062 } else {
1063 originator_string = xstrdup("unknown (remote did not supply name)");
1064 originator_len = 0; /* no originator supplied */
1065 }
1066
1067 packet_integrity_check(payload_len,
1068 4 + 4 + host_len + 4 + originator_len,
1069 SSH_MSG_PORT_OPEN);
1070
1071 /* Check if opening that port is permitted. */
1072 if (!all_opens_permitted) {
1073 /* Go trough all permitted ports. */
1074 for (i = 0; i < num_permitted_opens; i++)
1075 if (permitted_opens[i].port == host_port &&
1076 strcmp(permitted_opens[i].host, host) == 0)
1077 break;
1078
1079 /* Check if we found the requested port among those permitted. */
1080 if (i >= num_permitted_opens) {
1081 /* The port is not permitted. */
1082 log("Received request to connect to %.100s:%d, but the request was denied.",
1083 host, host_port);
1084 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1085 packet_put_int(remote_channel);
1086 packet_send();
1087 }
1088 }
1089 1214
1090 memset(&hints, 0, sizeof(hints)); 1215 memset(&hints, 0, sizeof(hints));
1091 hints.ai_family = IPv4or6; 1216 hints.ai_family = IPv4or6;
@@ -1093,15 +1218,14 @@ channel_input_port_open(int payload_len)
1093 snprintf(strport, sizeof strport, "%d", host_port); 1218 snprintf(strport, sizeof strport, "%d", host_port);
1094 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { 1219 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
1095 error("%.100s: unknown host (%s)", host, gai_strerror(gaierr)); 1220 error("%.100s: unknown host (%s)", host, gai_strerror(gaierr));
1096 goto fail; 1221 return -1;
1097 } 1222 }
1098
1099 for (ai = aitop; ai; ai = ai->ai_next) { 1223 for (ai = aitop; ai; ai = ai->ai_next) {
1100 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 1224 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1101 continue; 1225 continue;
1102 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), 1226 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
1103 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 1227 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
1104 error("channel_input_port_open: getnameinfo failed"); 1228 error("channel_connect_to: getnameinfo failed");
1105 continue; 1229 continue;
1106 } 1230 }
1107 /* Create the socket. */ 1231 /* Create the socket. */
@@ -1121,37 +1245,82 @@ channel_input_port_open(int payload_len)
1121 1245
1122 } 1246 }
1123 freeaddrinfo(aitop); 1247 freeaddrinfo(aitop);
1124
1125 if (!ai) { 1248 if (!ai) {
1126 error("connect %.100s port %d: failed.", host, host_port); 1249 error("connect %.100s port %d: failed.", host, host_port);
1127 goto fail; 1250 return -1;
1128 } 1251 }
1252 /* success */
1253 return sock;
1254}
1129 1255
1130 /* Successful connection. */ 1256/*
1257 * This is called after receiving PORT_OPEN message. This attempts to
1258 * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION
1259 * or CHANNEL_OPEN_FAILURE.
1260 */
1131 1261
1132 /* Allocate a channel for this connection. */ 1262void
1133 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string); 1263channel_input_port_open(int type, int plen)
1134 channels[newch].remote_id = remote_channel; 1264{
1265 u_short host_port;
1266 char *host, *originator_string;
1267 int remote_channel, sock = -1, newch, i, denied;
1268 unsigned int host_len, originator_len;
1135 1269
1136 /* Send a confirmation to the remote host. */ 1270 /* Get remote channel number. */
1137 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 1271 remote_channel = packet_get_int();
1138 packet_put_int(remote_channel);
1139 packet_put_int(newch);
1140 packet_send();
1141 1272
1142 /* Free the argument string. */ 1273 /* Get host name to connect to. */
1143 xfree(host); 1274 host = packet_get_string(&host_len);
1144 1275
1145 return; 1276 /* Get port to connect to. */
1277 host_port = packet_get_int();
1146 1278
1147fail: 1279 /* Get remote originator name. */
1148 /* Free the argument string. */ 1280 if (have_hostname_in_open) {
1149 xfree(host); 1281 originator_string = packet_get_string(&originator_len);
1282 originator_len += 4; /* size of packet_int */
1283 } else {
1284 originator_string = xstrdup("unknown (remote did not supply name)");
1285 originator_len = 0; /* no originator supplied */
1286 }
1150 1287
1151 /* Send refusal to the remote host. */ 1288 packet_integrity_check(plen,
1152 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 1289 4 + 4 + host_len + 4 + originator_len, SSH_MSG_PORT_OPEN);
1153 packet_put_int(remote_channel); 1290
1154 packet_send(); 1291 /* Check if opening that port is permitted. */
1292 denied = 0;
1293 if (!all_opens_permitted) {
1294 /* Go trough all permitted ports. */
1295 for (i = 0; i < num_permitted_opens; i++)
1296 if (permitted_opens[i].port_to_connect == host_port &&
1297 strcmp(permitted_opens[i].host_to_connect, host) == 0)
1298 break;
1299
1300 /* Check if we found the requested port among those permitted. */
1301 if (i >= num_permitted_opens) {
1302 /* The port is not permitted. */
1303 log("Received request to connect to %.100s:%d, but the request was denied.",
1304 host, host_port);
1305 denied = 1;
1306 }
1307 }
1308 sock = denied ? -1 : channel_connect_to(host, host_port);
1309 if (sock > 0) {
1310 /* Allocate a channel for this connection. */
1311 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string);
1312 channels[newch].remote_id = remote_channel;
1313
1314 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1315 packet_put_int(remote_channel);
1316 packet_put_int(newch);
1317 packet_send();
1318 } else {
1319 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1320 packet_put_int(remote_channel);
1321 packet_send();
1322 }
1323 xfree(host);
1155} 1324}
1156 1325
1157/* 1326/*
@@ -1336,7 +1505,7 @@ connect_local_xsocket(unsigned int dnr)
1336 */ 1505 */
1337 1506
1338void 1507void
1339x11_input_open(int payload_len) 1508x11_input_open(int type, int plen)
1340{ 1509{
1341 int remote_channel, display_number, sock = 0, newch; 1510 int remote_channel, display_number, sock = 0, newch;
1342 const char *display; 1511 const char *display;
@@ -1359,7 +1528,7 @@ x11_input_open(int payload_len)
1359 } 1528 }
1360 1529
1361 debug("Received X11 open request."); 1530 debug("Received X11 open request.");
1362 packet_integrity_check(payload_len, 4 + remote_len, SSH_SMSG_X11_OPEN); 1531 packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN);
1363 1532
1364 /* Try to open a socket for the local X server. */ 1533 /* Try to open a socket for the local X server. */
1365 display = getenv("DISPLAY"); 1534 display = getenv("DISPLAY");
@@ -1425,19 +1594,18 @@ x11_input_open(int payload_len)
1425 sock = socket(ai->ai_family, SOCK_STREAM, 0); 1594 sock = socket(ai->ai_family, SOCK_STREAM, 0);
1426 if (sock < 0) { 1595 if (sock < 0) {
1427 debug("socket: %.100s", strerror(errno)); 1596 debug("socket: %.100s", strerror(errno));
1428 continue; 1597 continue;
1429 } 1598 }
1430 /* Connect it to the display. */ 1599 /* Connect it to the display. */
1431 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 1600 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1432 debug("connect %.100s port %d: %.100s", buf, 6000 + display_number, 1601 debug("connect %.100s port %d: %.100s", buf,
1433 strerror(errno)); 1602 6000 + display_number, strerror(errno));
1434 close(sock); 1603 close(sock);
1435 continue; 1604 continue;
1605 }
1606 /* Success */
1607 break;
1436 } 1608 }
1437 /* Success */
1438 break;
1439
1440 } /* (ai = aitop, ai; ai = ai->ai_next) */
1441 freeaddrinfo(aitop); 1609 freeaddrinfo(aitop);
1442 if (!ai) { 1610 if (!ai) {
1443 error("connect %.100s port %d: %.100s", buf, 6000 + display_number, 1611 error("connect %.100s port %d: %.100s", buf, 6000 + display_number,
@@ -1625,11 +1793,13 @@ auth_input_request_forwarding(struct passwd * pw)
1625/* This is called to process an SSH_SMSG_AGENT_OPEN message. */ 1793/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
1626 1794
1627void 1795void
1628auth_input_open_request() 1796auth_input_open_request(int type, int plen)
1629{ 1797{
1630 int remch, sock, newch; 1798 int remch, sock, newch;
1631 char *dummyname; 1799 char *dummyname;
1632 1800
1801 packet_integrity_check(plen, 4, type);
1802
1633 /* Read the remote channel number from the message. */ 1803 /* Read the remote channel number from the message. */
1634 remch = packet_get_int(); 1804 remch = packet_get_int();
1635 1805