summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c472
1 files changed, 401 insertions, 71 deletions
diff --git a/channels.c b/channels.c
index 9f9e972f4..bef8ad6aa 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.351 2016/07/19 11:38:53 dtucker Exp $ */ 1/* $OpenBSD: channels.c,v 1.356 2016/10/18 17:32:54 dtucker 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
@@ -42,7 +42,6 @@
42#include "includes.h" 42#include "includes.h"
43 43
44#include <sys/types.h> 44#include <sys/types.h>
45#include <sys/param.h> /* MIN MAX */
46#include <sys/stat.h> 45#include <sys/stat.h>
47#include <sys/ioctl.h> 46#include <sys/ioctl.h>
48#include <sys/un.h> 47#include <sys/un.h>
@@ -72,6 +71,7 @@
72#include "ssh.h" 71#include "ssh.h"
73#include "ssh1.h" 72#include "ssh1.h"
74#include "ssh2.h" 73#include "ssh2.h"
74#include "ssherr.h"
75#include "packet.h" 75#include "packet.h"
76#include "log.h" 76#include "log.h"
77#include "misc.h" 77#include "misc.h"
@@ -121,6 +121,7 @@ typedef struct {
121 char *listen_host; /* Remote side should listen address. */ 121 char *listen_host; /* Remote side should listen address. */
122 char *listen_path; /* Remote side should listen path. */ 122 char *listen_path; /* Remote side should listen path. */
123 int listen_port; /* Remote side should listen port. */ 123 int listen_port; /* Remote side should listen port. */
124 Channel *downstream; /* Downstream mux*/
124} ForwardPermission; 125} ForwardPermission;
125 126
126/* List of all permitted host/port pairs to connect by the user. */ 127/* List of all permitted host/port pairs to connect by the user. */
@@ -184,6 +185,7 @@ static int IPv4or6 = AF_UNSPEC;
184 185
185/* helper */ 186/* helper */
186static void port_open_helper(Channel *c, char *rtype); 187static void port_open_helper(Channel *c, char *rtype);
188static const char *channel_rfwd_bind_host(const char *listen_host);
187 189
188/* non-blocking connect helpers */ 190/* non-blocking connect helpers */
189static int connect_next(struct channel_connect *); 191static int connect_next(struct channel_connect *);
@@ -208,6 +210,20 @@ channel_by_id(int id)
208 return c; 210 return c;
209} 211}
210 212
213Channel *
214channel_by_remote_id(int remote_id)
215{
216 Channel *c;
217 u_int i;
218
219 for (i = 0; i < channels_alloc; i++) {
220 c = channels[i];
221 if (c != NULL && c->remote_id == remote_id)
222 return c;
223 }
224 return NULL;
225}
226
211/* 227/*
212 * Returns the channel if it is allowed to receive protocol messages. 228 * Returns the channel if it is allowed to receive protocol messages.
213 * Private channels, like listening sockets, may not receive messages. 229 * Private channels, like listening sockets, may not receive messages.
@@ -230,6 +246,7 @@ channel_lookup(int id)
230 case SSH_CHANNEL_INPUT_DRAINING: 246 case SSH_CHANNEL_INPUT_DRAINING:
231 case SSH_CHANNEL_OUTPUT_DRAINING: 247 case SSH_CHANNEL_OUTPUT_DRAINING:
232 case SSH_CHANNEL_ABANDONED: 248 case SSH_CHANNEL_ABANDONED:
249 case SSH_CHANNEL_MUX_PROXY:
233 return (c); 250 return (c);
234 } 251 }
235 logit("Non-public channel %d, type %d.", id, c->type); 252 logit("Non-public channel %d, type %d.", id, c->type);
@@ -245,9 +262,9 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
245 int extusage, int nonblock, int is_tty) 262 int extusage, int nonblock, int is_tty)
246{ 263{
247 /* Update the maximum file descriptor value. */ 264 /* Update the maximum file descriptor value. */
248 channel_max_fd = MAX(channel_max_fd, rfd); 265 channel_max_fd = MAXIMUM(channel_max_fd, rfd);
249 channel_max_fd = MAX(channel_max_fd, wfd); 266 channel_max_fd = MAXIMUM(channel_max_fd, wfd);
250 channel_max_fd = MAX(channel_max_fd, efd); 267 channel_max_fd = MAXIMUM(channel_max_fd, efd);
251 268
252 if (rfd != -1) 269 if (rfd != -1)
253 fcntl(rfd, F_SETFD, FD_CLOEXEC); 270 fcntl(rfd, F_SETFD, FD_CLOEXEC);
@@ -373,9 +390,9 @@ channel_find_maxfd(void)
373 for (i = 0; i < channels_alloc; i++) { 390 for (i = 0; i < channels_alloc; i++) {
374 c = channels[i]; 391 c = channels[i];
375 if (c != NULL) { 392 if (c != NULL) {
376 max = MAX(max, c->rfd); 393 max = MAXIMUM(max, c->rfd);
377 max = MAX(max, c->wfd); 394 max = MAXIMUM(max, c->wfd);
378 max = MAX(max, c->efd); 395 max = MAXIMUM(max, c->efd);
379 } 396 }
380 } 397 }
381 return max; 398 return max;
@@ -411,14 +428,56 @@ channel_free(Channel *c)
411{ 428{
412 char *s; 429 char *s;
413 u_int i, n; 430 u_int i, n;
431 Channel *other;
414 struct channel_confirm *cc; 432 struct channel_confirm *cc;
415 433
416 for (n = 0, i = 0; i < channels_alloc; i++) 434 for (n = 0, i = 0; i < channels_alloc; i++) {
417 if (channels[i]) 435 if ((other = channels[i]) != NULL) {
418 n++; 436 n++;
437
438 /* detach from mux client and prepare for closing */
439 if (c->type == SSH_CHANNEL_MUX_CLIENT &&
440 other->type == SSH_CHANNEL_MUX_PROXY &&
441 other->mux_ctx == c) {
442 other->mux_ctx = NULL;
443 other->type = SSH_CHANNEL_OPEN;
444 other->istate = CHAN_INPUT_CLOSED;
445 other->ostate = CHAN_OUTPUT_CLOSED;
446 }
447 }
448 }
419 debug("channel %d: free: %s, nchannels %u", c->self, 449 debug("channel %d: free: %s, nchannels %u", c->self,
420 c->remote_name ? c->remote_name : "???", n); 450 c->remote_name ? c->remote_name : "???", n);
421 451
452 /* XXX more MUX cleanup: remove remote forwardings */
453 if (c->type == SSH_CHANNEL_MUX_CLIENT) {
454 for (i = 0; i < (u_int)num_permitted_opens; i++) {
455 if (permitted_opens[i].downstream != c)
456 continue;
457 /* cancel on the server, since mux client is gone */
458 debug("channel %d: cleanup remote forward for %s:%u",
459 c->self,
460 permitted_opens[i].listen_host,
461 permitted_opens[i].listen_port);
462 packet_start(SSH2_MSG_GLOBAL_REQUEST);
463 packet_put_cstring("cancel-tcpip-forward");
464 packet_put_char(0);
465 packet_put_cstring(channel_rfwd_bind_host(
466 permitted_opens[i].listen_host));
467 packet_put_int(permitted_opens[i].listen_port);
468 packet_send();
469 /* unregister */
470 permitted_opens[i].listen_port = 0;
471 permitted_opens[i].port_to_connect = 0;
472 free(permitted_opens[i].host_to_connect);
473 permitted_opens[i].host_to_connect = NULL;
474 free(permitted_opens[i].listen_host);
475 permitted_opens[i].listen_host = NULL;
476 permitted_opens[i].listen_path = NULL;
477 permitted_opens[i].downstream = NULL;
478 }
479 }
480
422 s = channel_open_message(); 481 s = channel_open_message();
423 debug3("channel %d: status: %s", c->self, s); 482 debug3("channel %d: status: %s", c->self, s);
424 free(s); 483 free(s);
@@ -564,6 +623,7 @@ channel_still_open(void)
564 case SSH_CHANNEL_OPEN: 623 case SSH_CHANNEL_OPEN:
565 case SSH_CHANNEL_X11_OPEN: 624 case SSH_CHANNEL_X11_OPEN:
566 case SSH_CHANNEL_MUX_CLIENT: 625 case SSH_CHANNEL_MUX_CLIENT:
626 case SSH_CHANNEL_MUX_PROXY:
567 return 1; 627 return 1;
568 case SSH_CHANNEL_INPUT_DRAINING: 628 case SSH_CHANNEL_INPUT_DRAINING:
569 case SSH_CHANNEL_OUTPUT_DRAINING: 629 case SSH_CHANNEL_OUTPUT_DRAINING:
@@ -597,6 +657,7 @@ channel_find_open(void)
597 case SSH_CHANNEL_RPORT_LISTENER: 657 case SSH_CHANNEL_RPORT_LISTENER:
598 case SSH_CHANNEL_MUX_LISTENER: 658 case SSH_CHANNEL_MUX_LISTENER:
599 case SSH_CHANNEL_MUX_CLIENT: 659 case SSH_CHANNEL_MUX_CLIENT:
660 case SSH_CHANNEL_MUX_PROXY:
600 case SSH_CHANNEL_OPENING: 661 case SSH_CHANNEL_OPENING:
601 case SSH_CHANNEL_CONNECTING: 662 case SSH_CHANNEL_CONNECTING:
602 case SSH_CHANNEL_ZOMBIE: 663 case SSH_CHANNEL_ZOMBIE:
@@ -622,7 +683,6 @@ channel_find_open(void)
622 return -1; 683 return -1;
623} 684}
624 685
625
626/* 686/*
627 * Returns a message describing the currently open forwarded connections, 687 * Returns a message describing the currently open forwarded connections,
628 * suitable for sending to the client. The message contains crlf pairs for 688 * suitable for sending to the client. The message contains crlf pairs for
@@ -651,7 +711,6 @@ channel_open_message(void)
651 case SSH_CHANNEL_AUTH_SOCKET: 711 case SSH_CHANNEL_AUTH_SOCKET:
652 case SSH_CHANNEL_ZOMBIE: 712 case SSH_CHANNEL_ZOMBIE:
653 case SSH_CHANNEL_ABANDONED: 713 case SSH_CHANNEL_ABANDONED:
654 case SSH_CHANNEL_MUX_CLIENT:
655 case SSH_CHANNEL_MUX_LISTENER: 714 case SSH_CHANNEL_MUX_LISTENER:
656 case SSH_CHANNEL_UNIX_LISTENER: 715 case SSH_CHANNEL_UNIX_LISTENER:
657 case SSH_CHANNEL_RUNIX_LISTENER: 716 case SSH_CHANNEL_RUNIX_LISTENER:
@@ -664,6 +723,8 @@ channel_open_message(void)
664 case SSH_CHANNEL_X11_OPEN: 723 case SSH_CHANNEL_X11_OPEN:
665 case SSH_CHANNEL_INPUT_DRAINING: 724 case SSH_CHANNEL_INPUT_DRAINING:
666 case SSH_CHANNEL_OUTPUT_DRAINING: 725 case SSH_CHANNEL_OUTPUT_DRAINING:
726 case SSH_CHANNEL_MUX_PROXY:
727 case SSH_CHANNEL_MUX_CLIENT:
667 snprintf(buf, sizeof buf, 728 snprintf(buf, sizeof buf,
668 " #%d %.300s (t%d r%d i%u/%d o%u/%d fd %d/%d cc %d)\r\n", 729 " #%d %.300s (t%d r%d i%u/%d o%u/%d fd %d/%d cc %d)\r\n",
669 c->self, c->remote_name, 730 c->self, c->remote_name,
@@ -1898,7 +1959,7 @@ read_mux(Channel *c, u_int need)
1898 1959
1899 if (buffer_len(&c->input) < need) { 1960 if (buffer_len(&c->input) < need) {
1900 rlen = need - buffer_len(&c->input); 1961 rlen = need - buffer_len(&c->input);
1901 len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF)); 1962 len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF));
1902 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1963 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1903 return buffer_len(&c->input); 1964 return buffer_len(&c->input);
1904 if (len <= 0) { 1965 if (len <= 0) {
@@ -2201,7 +2262,7 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
2201{ 2262{
2202 u_int n, sz, nfdset; 2263 u_int n, sz, nfdset;
2203 2264
2204 n = MAX(*maxfdp, channel_max_fd); 2265 n = MAXIMUM(*maxfdp, channel_max_fd);
2205 2266
2206 nfdset = howmany(n+1, NFDBITS); 2267 nfdset = howmany(n+1, NFDBITS);
2207 /* Explicitly test here, because xrealloc isn't always called */ 2268 /* Explicitly test here, because xrealloc isn't always called */
@@ -2361,6 +2422,284 @@ channel_output_poll(void)
2361 } 2422 }
2362} 2423}
2363 2424
2425/* -- mux proxy support */
2426
2427/*
2428 * When multiplexing channel messages for mux clients we have to deal
2429 * with downstream messages from the mux client and upstream messages
2430 * from the ssh server:
2431 * 1) Handling downstream messages is straightforward and happens
2432 * in channel_proxy_downstream():
2433 * - We forward all messages (mostly) unmodified to the server.
2434 * - However, in order to route messages from upstream to the correct
2435 * downstream client, we have to replace the channel IDs used by the
2436 * mux clients with a unique channel ID because the mux clients might
2437 * use conflicting channel IDs.
2438 * - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and
2439 * SSH2_MSG_CHANNEL_OPEN_CONFIRMATION messages, create a local
2440 * SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID
2441 * with the newly allocated channel ID.
2442 * 2) Upstream messages are received by matching SSH_CHANNEL_MUX_PROXY
2443 * channels and procesed by channel_proxy_upstream(). The local channel ID
2444 * is then translated back to the original mux client ID.
2445 * 3) In both cases we need to keep track of matching SSH2_MSG_CHANNEL_CLOSE
2446 * messages so we can clean up SSH_CHANNEL_MUX_PROXY channels.
2447 * 4) The SSH_CHANNEL_MUX_PROXY channels also need to closed when the
2448 * downstream mux client are removed.
2449 * 5) Handling SSH2_MSG_CHANNEL_OPEN messages from the upstream server
2450 * requires more work, because they are not addressed to a specific
2451 * channel. E.g. client_request_forwarded_tcpip() needs to figure
2452 * out whether the request is addressed to the local client or a
2453 * specific downstream client based on the listen-address/port.
2454 * 6) Agent and X11-Forwarding have a similar problem and are currenly
2455 * not supported as the matching session/channel cannot be identified
2456 * easily.
2457 */
2458
2459/*
2460 * receive packets from downstream mux clients:
2461 * channel callback fired on read from mux client, creates
2462 * SSH_CHANNEL_MUX_PROXY channels and translates channel IDs
2463 * on channel creation.
2464 */
2465int
2466channel_proxy_downstream(Channel *downstream)
2467{
2468 Channel *c = NULL;
2469 struct ssh *ssh = active_state;
2470 struct sshbuf *original = NULL, *modified = NULL;
2471 const u_char *cp;
2472 char *ctype = NULL, *listen_host = NULL;
2473 u_char type;
2474 size_t have;
2475 int ret = -1, r, idx;
2476 u_int id, remote_id, listen_port;
2477
2478 /* sshbuf_dump(&downstream->input, stderr); */
2479 if ((r = sshbuf_get_string_direct(&downstream->input, &cp, &have))
2480 != 0) {
2481 error("%s: malformed message: %s", __func__, ssh_err(r));
2482 return -1;
2483 }
2484 if (have < 2) {
2485 error("%s: short message", __func__);
2486 return -1;
2487 }
2488 type = cp[1];
2489 /* skip padlen + type */
2490 cp += 2;
2491 have -= 2;
2492 if (ssh_packet_log_type(type))
2493 debug3("%s: channel %u: down->up: type %u", __func__,
2494 downstream->self, type);
2495
2496 switch (type) {
2497 case SSH2_MSG_CHANNEL_OPEN:
2498 if ((original = sshbuf_from(cp, have)) == NULL ||
2499 (modified = sshbuf_new()) == NULL) {
2500 error("%s: alloc", __func__);
2501 goto out;
2502 }
2503 if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||
2504 (r = sshbuf_get_u32(original, &id)) != 0) {
2505 error("%s: parse error %s", __func__, ssh_err(r));
2506 goto out;
2507 }
2508 c = channel_new("mux proxy", SSH_CHANNEL_MUX_PROXY,
2509 -1, -1, -1, 0, 0, 0, ctype, 1);
2510 c->mux_ctx = downstream; /* point to mux client */
2511 c->mux_downstream_id = id; /* original downstream id */
2512 if ((r = sshbuf_put_cstring(modified, ctype)) != 0 ||
2513 (r = sshbuf_put_u32(modified, c->self)) != 0 ||
2514 (r = sshbuf_putb(modified, original)) != 0) {
2515 error("%s: compose error %s", __func__, ssh_err(r));
2516 channel_free(c);
2517 goto out;
2518 }
2519 break;
2520 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
2521 /*
2522 * Almost the same as SSH2_MSG_CHANNEL_OPEN, except then we
2523 * need to parse 'remote_id' instead of 'ctype'.
2524 */
2525 if ((original = sshbuf_from(cp, have)) == NULL ||
2526 (modified = sshbuf_new()) == NULL) {
2527 error("%s: alloc", __func__);
2528 goto out;
2529 }
2530 if ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||
2531 (r = sshbuf_get_u32(original, &id)) != 0) {
2532 error("%s: parse error %s", __func__, ssh_err(r));
2533 goto out;
2534 }
2535 c = channel_new("mux proxy", SSH_CHANNEL_MUX_PROXY,
2536 -1, -1, -1, 0, 0, 0, "mux-down-connect", 1);
2537 c->mux_ctx = downstream; /* point to mux client */
2538 c->mux_downstream_id = id;
2539 c->remote_id = remote_id;
2540 if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
2541 (r = sshbuf_put_u32(modified, c->self)) != 0 ||
2542 (r = sshbuf_putb(modified, original)) != 0) {
2543 error("%s: compose error %s", __func__, ssh_err(r));
2544 channel_free(c);
2545 goto out;
2546 }
2547 break;
2548 case SSH2_MSG_GLOBAL_REQUEST:
2549 if ((original = sshbuf_from(cp, have)) == NULL) {
2550 error("%s: alloc", __func__);
2551 goto out;
2552 }
2553 if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {
2554 error("%s: parse error %s", __func__, ssh_err(r));
2555 goto out;
2556 }
2557 if (strcmp(ctype, "tcpip-forward") != 0) {
2558 error("%s: unsupported request %s", __func__, ctype);
2559 goto out;
2560 }
2561 if ((r = sshbuf_get_u8(original, NULL)) != 0 ||
2562 (r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 ||
2563 (r = sshbuf_get_u32(original, &listen_port)) != 0) {
2564 error("%s: parse error %s", __func__, ssh_err(r));
2565 goto out;
2566 }
2567 if (listen_port > 65535) {
2568 error("%s: tcpip-forward for %s: bad port %u",
2569 __func__, listen_host, listen_port);
2570 goto out;
2571 }
2572 /* Record that connection to this host/port is permitted. */
2573 permitted_opens = xreallocarray(permitted_opens,
2574 num_permitted_opens + 1, sizeof(*permitted_opens));
2575 idx = num_permitted_opens++;
2576 permitted_opens[idx].host_to_connect = xstrdup("<mux>");
2577 permitted_opens[idx].port_to_connect = -1;
2578 permitted_opens[idx].listen_host = listen_host;
2579 permitted_opens[idx].listen_port = (int)listen_port;
2580 permitted_opens[idx].downstream = downstream;
2581 listen_host = NULL;
2582 break;
2583 case SSH2_MSG_CHANNEL_CLOSE:
2584 if (have < 4)
2585 break;
2586 remote_id = PEEK_U32(cp);
2587 if ((c = channel_by_remote_id(remote_id)) != NULL) {
2588 if (c->flags & CHAN_CLOSE_RCVD)
2589 channel_free(c);
2590 else
2591 c->flags |= CHAN_CLOSE_SENT;
2592 }
2593 break;
2594 }
2595 if (modified) {
2596 if ((r = sshpkt_start(ssh, type)) != 0 ||
2597 (r = sshpkt_putb(ssh, modified)) != 0 ||
2598 (r = sshpkt_send(ssh)) != 0) {
2599 error("%s: send %s", __func__, ssh_err(r));
2600 goto out;
2601 }
2602 } else {
2603 if ((r = sshpkt_start(ssh, type)) != 0 ||
2604 (r = sshpkt_put(ssh, cp, have)) != 0 ||
2605 (r = sshpkt_send(ssh)) != 0) {
2606 error("%s: send %s", __func__, ssh_err(r));
2607 goto out;
2608 }
2609 }
2610 ret = 0;
2611 out:
2612 free(ctype);
2613 free(listen_host);
2614 sshbuf_free(original);
2615 sshbuf_free(modified);
2616 return ret;
2617}
2618
2619/*
2620 * receive packets from upstream server and de-multiplex packets
2621 * to correct downstream:
2622 * implemented as a helper for channel input handlers,
2623 * replaces local (proxy) channel ID with downstream channel ID.
2624 */
2625int
2626channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt)
2627{
2628 struct ssh *ssh = active_state;
2629 struct sshbuf *b = NULL;
2630 Channel *downstream;
2631 const u_char *cp = NULL;
2632 size_t len;
2633 int r;
2634
2635 /*
2636 * When receiving packets from the peer we need to check whether we
2637 * need to forward the packets to the mux client. In this case we
2638 * restore the orignal channel id and keep track of CLOSE messages,
2639 * so we can cleanup the channel.
2640 */
2641 if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY)
2642 return 0;
2643 if ((downstream = c->mux_ctx) == NULL)
2644 return 0;
2645 switch (type) {
2646 case SSH2_MSG_CHANNEL_CLOSE:
2647 case SSH2_MSG_CHANNEL_DATA:
2648 case SSH2_MSG_CHANNEL_EOF:
2649 case SSH2_MSG_CHANNEL_EXTENDED_DATA:
2650 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
2651 case SSH2_MSG_CHANNEL_OPEN_FAILURE:
2652 case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
2653 case SSH2_MSG_CHANNEL_SUCCESS:
2654 case SSH2_MSG_CHANNEL_FAILURE:
2655 case SSH2_MSG_CHANNEL_REQUEST:
2656 break;
2657 default:
2658 debug2("%s: channel %u: unsupported type %u", __func__,
2659 c->self, type);
2660 return 0;
2661 }
2662 if ((b = sshbuf_new()) == NULL) {
2663 error("%s: alloc reply", __func__);
2664 goto out;
2665 }
2666 /* get remaining payload (after id) */
2667 cp = sshpkt_ptr(ssh, &len);
2668 if (cp == NULL) {
2669 error("%s: no packet", __func__);
2670 goto out;
2671 }
2672 /* translate id and send to muxclient */
2673 if ((r = sshbuf_put_u8(b, 0)) != 0 || /* padlen */
2674 (r = sshbuf_put_u8(b, type)) != 0 ||
2675 (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||
2676 (r = sshbuf_put(b, cp, len)) != 0 ||
2677 (r = sshbuf_put_stringb(&downstream->output, b)) != 0) {
2678 error("%s: compose for muxclient %s", __func__, ssh_err(r));
2679 goto out;
2680 }
2681 /* sshbuf_dump(b, stderr); */
2682 if (ssh_packet_log_type(type))
2683 debug3("%s: channel %u: up->down: type %u", __func__, c->self,
2684 type);
2685 out:
2686 /* update state */
2687 switch (type) {
2688 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
2689 /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */
2690 if (cp && len > 4)
2691 c->remote_id = PEEK_U32(cp);
2692 break;
2693 case SSH2_MSG_CHANNEL_CLOSE:
2694 if (c->flags & CHAN_CLOSE_SENT)
2695 channel_free(c);
2696 else
2697 c->flags |= CHAN_CLOSE_RCVD;
2698 break;
2699 }
2700 sshbuf_free(b);
2701 return 1;
2702}
2364 2703
2365/* -- protocol input */ 2704/* -- protocol input */
2366 2705
@@ -2378,6 +2717,8 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
2378 c = channel_lookup(id); 2717 c = channel_lookup(id);
2379 if (c == NULL) 2718 if (c == NULL)
2380 packet_disconnect("Received data for nonexistent channel %d.", id); 2719 packet_disconnect("Received data for nonexistent channel %d.", id);
2720 if (channel_proxy_upstream(c, type, seq, ctxt))
2721 return 0;
2381 2722
2382 /* Ignore any data for non-open channels (might happen on close) */ 2723 /* Ignore any data for non-open channels (might happen on close) */
2383 if (c->type != SSH_CHANNEL_OPEN && 2724 if (c->type != SSH_CHANNEL_OPEN &&
@@ -2440,6 +2781,8 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
2440 2781
2441 if (c == NULL) 2782 if (c == NULL)
2442 packet_disconnect("Received extended_data for bad channel %d.", id); 2783 packet_disconnect("Received extended_data for bad channel %d.", id);
2784 if (channel_proxy_upstream(c, type, seq, ctxt))
2785 return 0;
2443 if (c->type != SSH_CHANNEL_OPEN) { 2786 if (c->type != SSH_CHANNEL_OPEN) {
2444 logit("channel %d: ext data for non open", id); 2787 logit("channel %d: ext data for non open", id);
2445 return 0; 2788 return 0;
@@ -2485,6 +2828,8 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
2485 c = channel_lookup(id); 2828 c = channel_lookup(id);
2486 if (c == NULL) 2829 if (c == NULL)
2487 packet_disconnect("Received ieof for nonexistent channel %d.", id); 2830 packet_disconnect("Received ieof for nonexistent channel %d.", id);
2831 if (channel_proxy_upstream(c, type, seq, ctxt))
2832 return 0;
2488 chan_rcvd_ieof(c); 2833 chan_rcvd_ieof(c);
2489 2834
2490 /* XXX force input close */ 2835 /* XXX force input close */
@@ -2509,7 +2854,8 @@ channel_input_close(int type, u_int32_t seq, void *ctxt)
2509 c = channel_lookup(id); 2854 c = channel_lookup(id);
2510 if (c == NULL) 2855 if (c == NULL)
2511 packet_disconnect("Received close for nonexistent channel %d.", id); 2856 packet_disconnect("Received close for nonexistent channel %d.", id);
2512 2857 if (channel_proxy_upstream(c, type, seq, ctxt))
2858 return 0;
2513 /* 2859 /*
2514 * Send a confirmation that we have closed the channel and no more 2860 * Send a confirmation that we have closed the channel and no more
2515 * data is coming for it. 2861 * data is coming for it.
@@ -2544,9 +2890,11 @@ channel_input_oclose(int type, u_int32_t seq, void *ctxt)
2544 int id = packet_get_int(); 2890 int id = packet_get_int();
2545 Channel *c = channel_lookup(id); 2891 Channel *c = channel_lookup(id);
2546 2892
2547 packet_check_eom();
2548 if (c == NULL) 2893 if (c == NULL)
2549 packet_disconnect("Received oclose for nonexistent channel %d.", id); 2894 packet_disconnect("Received oclose for nonexistent channel %d.", id);
2895 if (channel_proxy_upstream(c, type, seq, ctxt))
2896 return 0;
2897 packet_check_eom();
2550 chan_rcvd_oclose(c); 2898 chan_rcvd_oclose(c);
2551 return 0; 2899 return 0;
2552} 2900}
@@ -2558,10 +2906,12 @@ channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
2558 int id = packet_get_int(); 2906 int id = packet_get_int();
2559 Channel *c = channel_lookup(id); 2907 Channel *c = channel_lookup(id);
2560 2908
2561 packet_check_eom();
2562 if (c == NULL) 2909 if (c == NULL)
2563 packet_disconnect("Received close confirmation for " 2910 packet_disconnect("Received close confirmation for "
2564 "out-of-range channel %d.", id); 2911 "out-of-range channel %d.", id);
2912 if (channel_proxy_upstream(c, type, seq, ctxt))
2913 return 0;
2914 packet_check_eom();
2565 if (c->type != SSH_CHANNEL_CLOSED && c->type != SSH_CHANNEL_ABANDONED) 2915 if (c->type != SSH_CHANNEL_CLOSED && c->type != SSH_CHANNEL_ABANDONED)
2566 packet_disconnect("Received close confirmation for " 2916 packet_disconnect("Received close confirmation for "
2567 "non-closed channel %d (type %d).", id, c->type); 2917 "non-closed channel %d (type %d).", id, c->type);
@@ -2579,7 +2929,12 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
2579 id = packet_get_int(); 2929 id = packet_get_int();
2580 c = channel_lookup(id); 2930 c = channel_lookup(id);
2581 2931
2582 if (c==NULL || c->type != SSH_CHANNEL_OPENING) 2932 if (c==NULL)
2933 packet_disconnect("Received open confirmation for "
2934 "unknown channel %d.", id);
2935 if (channel_proxy_upstream(c, type, seq, ctxt))
2936 return 0;
2937 if (c->type != SSH_CHANNEL_OPENING)
2583 packet_disconnect("Received open confirmation for " 2938 packet_disconnect("Received open confirmation for "
2584 "non-opening channel %d.", id); 2939 "non-opening channel %d.", id);
2585 remote_id = packet_get_int(); 2940 remote_id = packet_get_int();
@@ -2629,7 +2984,12 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
2629 id = packet_get_int(); 2984 id = packet_get_int();
2630 c = channel_lookup(id); 2985 c = channel_lookup(id);
2631 2986
2632 if (c==NULL || c->type != SSH_CHANNEL_OPENING) 2987 if (c==NULL)
2988 packet_disconnect("Received open failure for "
2989 "unknown channel %d.", id);
2990 if (channel_proxy_upstream(c, type, seq, ctxt))
2991 return 0;
2992 if (c->type != SSH_CHANNEL_OPENING)
2633 packet_disconnect("Received open failure for " 2993 packet_disconnect("Received open failure for "
2634 "non-opening channel %d.", id); 2994 "non-opening channel %d.", id);
2635 if (compat20) { 2995 if (compat20) {
@@ -2673,6 +3033,8 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
2673 logit("Received window adjust for non-open channel %d.", id); 3033 logit("Received window adjust for non-open channel %d.", id);
2674 return 0; 3034 return 0;
2675 } 3035 }
3036 if (channel_proxy_upstream(c, type, seq, ctxt))
3037 return 0;
2676 adjust = packet_get_int(); 3038 adjust = packet_get_int();
2677 packet_check_eom(); 3039 packet_check_eom();
2678 debug2("channel %d: rcvd adjust %u", id, adjust); 3040 debug2("channel %d: rcvd adjust %u", id, adjust);
@@ -2727,14 +3089,15 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
2727 packet_set_alive_timeouts(0); 3089 packet_set_alive_timeouts(0);
2728 3090
2729 id = packet_get_int(); 3091 id = packet_get_int();
2730 packet_check_eom();
2731
2732 debug2("channel_input_status_confirm: type %d id %d", type, id); 3092 debug2("channel_input_status_confirm: type %d id %d", type, id);
2733 3093
2734 if ((c = channel_lookup(id)) == NULL) { 3094 if ((c = channel_lookup(id)) == NULL) {
2735 logit("channel_input_status_confirm: %d: unknown", id); 3095 logit("channel_input_status_confirm: %d: unknown", id);
2736 return 0; 3096 return 0;
2737 } 3097 }
3098 if (channel_proxy_upstream(c, type, seq, ctxt))
3099 return 0;
3100 packet_check_eom();
2738 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) 3101 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
2739 return 0; 3102 return 0;
2740 cc->cb(type, c, cc->ctx); 3103 cc->cb(type, c, cc->ctx);
@@ -3288,6 +3651,7 @@ channel_request_remote_forwarding(struct Forward *fwd)
3288 permitted_opens[idx].listen_path = NULL; 3651 permitted_opens[idx].listen_path = NULL;
3289 permitted_opens[idx].listen_port = fwd->listen_port; 3652 permitted_opens[idx].listen_port = fwd->listen_port;
3290 } 3653 }
3654 permitted_opens[idx].downstream = NULL;
3291 } 3655 }
3292 return (idx); 3656 return (idx);
3293} 3657}
@@ -3383,6 +3747,7 @@ channel_request_rforward_cancel_tcpip(const char *host, u_short port)
3383 free(permitted_opens[i].listen_host); 3747 free(permitted_opens[i].listen_host);
3384 permitted_opens[i].listen_host = NULL; 3748 permitted_opens[i].listen_host = NULL;
3385 permitted_opens[i].listen_path = NULL; 3749 permitted_opens[i].listen_path = NULL;
3750 permitted_opens[i].downstream = NULL;
3386 3751
3387 return 0; 3752 return 0;
3388} 3753}
@@ -3420,6 +3785,7 @@ channel_request_rforward_cancel_streamlocal(const char *path)
3420 permitted_opens[i].listen_host = NULL; 3785 permitted_opens[i].listen_host = NULL;
3421 free(permitted_opens[i].listen_path); 3786 free(permitted_opens[i].listen_path);
3422 permitted_opens[i].listen_path = NULL; 3787 permitted_opens[i].listen_path = NULL;
3788 permitted_opens[i].downstream = NULL;
3423 3789
3424 return 0; 3790 return 0;
3425} 3791}
@@ -3440,45 +3806,6 @@ channel_request_rforward_cancel(struct Forward *fwd)
3440} 3806}
3441 3807
3442/* 3808/*
3443 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
3444 * listening for the port, and sends back a success reply (or disconnect
3445 * message if there was an error).
3446 */
3447int
3448channel_input_port_forward_request(int is_root, struct ForwardOptions *fwd_opts)
3449{
3450 int success = 0;
3451 struct Forward fwd;
3452
3453 /* Get arguments from the packet. */
3454 memset(&fwd, 0, sizeof(fwd));
3455 fwd.listen_port = packet_get_int();
3456 fwd.connect_host = packet_get_string(NULL);
3457 fwd.connect_port = packet_get_int();
3458
3459#ifndef HAVE_CYGWIN
3460 /*
3461 * Check that an unprivileged user is not trying to forward a
3462 * privileged port.
3463 */
3464 if (fwd.listen_port < IPPORT_RESERVED && !is_root)
3465 packet_disconnect(
3466 "Requested forwarding of port %d but user is not root.",
3467 fwd.listen_port);
3468 if (fwd.connect_port == 0)
3469 packet_disconnect("Dynamic forwarding denied.");
3470#endif
3471
3472 /* Initiate forwarding */
3473 success = channel_setup_local_fwd_listener(&fwd, fwd_opts);
3474
3475 /* Free the argument string. */
3476 free(fwd.connect_host);
3477
3478 return (success ? 0 : -1);
3479}
3480
3481/*
3482 * Permits opening to any host/port if permitted_opens[] is empty. This is 3809 * Permits opening to any host/port if permitted_opens[] is empty. This is
3483 * usually called by the server, because the user could connect to any port 3810 * usually called by the server, because the user could connect to any port
3484 * anyway, and the server has no way to know but to trust the client anyway. 3811 * anyway, and the server has no way to know but to trust the client anyway.
@@ -3502,6 +3829,7 @@ channel_add_permitted_opens(char *host, int port)
3502 permitted_opens[num_permitted_opens].listen_host = NULL; 3829 permitted_opens[num_permitted_opens].listen_host = NULL;
3503 permitted_opens[num_permitted_opens].listen_path = NULL; 3830 permitted_opens[num_permitted_opens].listen_path = NULL;
3504 permitted_opens[num_permitted_opens].listen_port = 0; 3831 permitted_opens[num_permitted_opens].listen_port = 0;
3832 permitted_opens[num_permitted_opens].downstream = NULL;
3505 num_permitted_opens++; 3833 num_permitted_opens++;
3506 3834
3507 all_opens_permitted = 0; 3835 all_opens_permitted = 0;
@@ -3633,7 +3961,7 @@ connect_next(struct channel_connect *cctx)
3633{ 3961{
3634 int sock, saved_errno; 3962 int sock, saved_errno;
3635 struct sockaddr_un *sunaddr; 3963 struct sockaddr_un *sunaddr;
3636 char ntop[NI_MAXHOST], strport[MAX(NI_MAXSERV,sizeof(sunaddr->sun_path))]; 3964 char ntop[NI_MAXHOST], strport[MAXIMUM(NI_MAXSERV,sizeof(sunaddr->sun_path))];
3637 3965
3638 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { 3966 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) {
3639 switch (cctx->ai->ai_family) { 3967 switch (cctx->ai->ai_family) {
@@ -3764,6 +4092,10 @@ connect_to(const char *name, int port, char *ctype, char *rname)
3764 return c; 4092 return c;
3765} 4093}
3766 4094
4095/*
4096 * returns either the newly connected channel or the downstream channel
4097 * that needs to deal with this connection.
4098 */
3767Channel * 4099Channel *
3768channel_connect_by_listen_address(const char *listen_host, 4100channel_connect_by_listen_address(const char *listen_host,
3769 u_short listen_port, char *ctype, char *rname) 4101 u_short listen_port, char *ctype, char *rname)
@@ -3773,6 +4105,8 @@ channel_connect_by_listen_address(const char *listen_host,
3773 for (i = 0; i < num_permitted_opens; i++) { 4105 for (i = 0; i < num_permitted_opens; i++) {
3774 if (open_listen_match_tcpip(&permitted_opens[i], listen_host, 4106 if (open_listen_match_tcpip(&permitted_opens[i], listen_host,
3775 listen_port, 1)) { 4107 listen_port, 1)) {
4108 if (permitted_opens[i].downstream)
4109 return permitted_opens[i].downstream;
3776 return connect_to( 4110 return connect_to(
3777 permitted_opens[i].host_to_connect, 4111 permitted_opens[i].host_to_connect,
3778 permitted_opens[i].port_to_connect, ctype, rname); 4112 permitted_opens[i].port_to_connect, ctype, rname);
@@ -4216,7 +4550,6 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
4216 char *new_data; 4550 char *new_data;
4217 int screen_number; 4551 int screen_number;
4218 const char *cp; 4552 const char *cp;
4219 u_int32_t rnd = 0;
4220 4553
4221 if (x11_saved_display == NULL) 4554 if (x11_saved_display == NULL)
4222 x11_saved_display = xstrdup(disp); 4555 x11_saved_display = xstrdup(disp);
@@ -4237,23 +4570,20 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
4237 if (x11_saved_proto == NULL) { 4570 if (x11_saved_proto == NULL) {
4238 /* Save protocol name. */ 4571 /* Save protocol name. */
4239 x11_saved_proto = xstrdup(proto); 4572 x11_saved_proto = xstrdup(proto);
4240 /* 4573
4241 * Extract real authentication data and generate fake data 4574 /* Extract real authentication data. */
4242 * of the same length.
4243 */
4244 x11_saved_data = xmalloc(data_len); 4575 x11_saved_data = xmalloc(data_len);
4245 x11_fake_data = xmalloc(data_len);
4246 for (i = 0; i < data_len; i++) { 4576 for (i = 0; i < data_len; i++) {
4247 if (sscanf(data + 2 * i, "%2x", &value) != 1) 4577 if (sscanf(data + 2 * i, "%2x", &value) != 1)
4248 fatal("x11_request_forwarding: bad " 4578 fatal("x11_request_forwarding: bad "
4249 "authentication data: %.100s", data); 4579 "authentication data: %.100s", data);
4250 if (i % 4 == 0)
4251 rnd = arc4random();
4252 x11_saved_data[i] = value; 4580 x11_saved_data[i] = value;
4253 x11_fake_data[i] = rnd & 0xff;
4254 rnd >>= 8;
4255 } 4581 }
4256 x11_saved_data_len = data_len; 4582 x11_saved_data_len = data_len;
4583
4584 /* Generate fake data of the same length. */
4585 x11_fake_data = xmalloc(data_len);
4586 arc4random_buf(x11_fake_data, data_len);
4257 x11_fake_data_len = data_len; 4587 x11_fake_data_len = data_len;
4258 } 4588 }
4259 4589