Lines Matching +full:forward +full:- +full:channel
73 #include "openbsd-compat/sys-queue.h"
93 /* -- agent forwarding */
96 /* -- X11 forwarding */
102 /* Per-channel callback for pre/post IO actions */
103 typedef void chan_fn(struct ssh *, Channel *c);
106 * Data structure for storing which hosts are permitted for forward requests.
112 /* Overload host_to_connect; we could just make this match Forward */
113 /* XXX - can we use listen_host instead of listen_path? */
120 Channel *downstream; /* Downstream mux*/
149 /* Used to record timeouts per channel type */
161 Channel **channels;
164 * Size of the channel array. All slots of the array must always be
171 * relevant to channels in the c->io_want bitmasks.
174 * channels which have c->io_ready events pending.
179 /* -- tcp forwarding */
183 /* -- X11 forwarding */
209 /* Channel timeouts by type */
218 static void port_open_helper(struct ssh *ssh, Channel *c, char *rtype);
221 /* non-blocking connect helpers */
224 static Channel *rdynamic_connect_prepare(struct ssh *, char *, char *);
225 static int rdynamic_connect_finish(struct ssh *, Channel *);
230 /* -- channel core */
239 sc->channels_alloc = 10; in channel_init_channels()
240 sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels)); in channel_init_channels()
241 sc->IPv4or6 = AF_UNSPEC; in channel_init_channels()
244 ssh->chanctxt = sc; in channel_init_channels()
247 Channel *
250 Channel *c; in channel_by_id()
252 if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) { in channel_by_id()
256 c = ssh->chanctxt->channels[id]; in channel_by_id()
258 logit_f("%d: bad id: channel free", id); in channel_by_id()
264 Channel *
267 Channel *c; in channel_by_remote_id()
270 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_by_remote_id()
271 c = ssh->chanctxt->channels[i]; in channel_by_remote_id()
272 if (c != NULL && c->have_remote_id && c->remote_id == remote_id) in channel_by_remote_id()
279 * Returns the channel if it is allowed to receive protocol messages.
282 Channel *
285 Channel *c; in channel_lookup()
290 switch (c->type) { in channel_lookup()
303 logit("Non-public channel %d, type %d.", id, c->type); in channel_lookup()
308 * Add a timeout for open channels whose c->ctype (or c->xctype if it is set)
315 struct ssh_channels *sc = ssh->chanctxt; in channel_add_timeout()
318 debug2_f("global channel timeout %d seconds", timeout_secs); in channel_add_timeout()
319 sc->global_deadline = timeout_secs; in channel_add_timeout()
322 debug2_f("channel type \"%s\" timeout %d seconds", in channel_add_timeout()
324 sc->timeouts = xrecallocarray(sc->timeouts, sc->ntimeouts, in channel_add_timeout()
325 sc->ntimeouts + 1, sizeof(*sc->timeouts)); in channel_add_timeout()
326 sc->timeouts[sc->ntimeouts].type_pattern = xstrdup(type_pattern); in channel_add_timeout()
327 sc->timeouts[sc->ntimeouts].timeout_secs = timeout_secs; in channel_add_timeout()
328 sc->ntimeouts++; in channel_add_timeout()
331 /* Clears all previously-added channel timeouts */
335 struct ssh_channels *sc = ssh->chanctxt; in channel_clear_timeouts()
339 for (i = 0; i < sc->ntimeouts; i++) in channel_clear_timeouts()
340 free(sc->timeouts[i].type_pattern); in channel_clear_timeouts()
341 free(sc->timeouts); in channel_clear_timeouts()
342 sc->timeouts = NULL; in channel_clear_timeouts()
343 sc->ntimeouts = 0; in channel_clear_timeouts()
349 struct ssh_channels *sc = ssh->chanctxt; in lookup_timeout()
352 for (i = 0; i < sc->ntimeouts; i++) { in lookup_timeout()
353 if (match_pattern(type, sc->timeouts[i].type_pattern)) in lookup_timeout()
354 return sc->timeouts[i].timeout_secs; in lookup_timeout()
361 * Sets "extended type" of a channel; used by session layer to add additional
362 * information about channel types (e.g. shell, login, subsystem) that can then
364 * Will reset c->inactive_deadline as a side-effect.
369 Channel *c; in channel_set_xtype()
372 fatal_f("missing channel %d", id); in channel_set_xtype()
373 if (c->xctype != NULL) in channel_set_xtype()
374 free(c->xctype); in channel_set_xtype()
375 c->xctype = xstrdup(xctype); in channel_set_xtype()
377 c->inactive_deadline = lookup_timeout(ssh, c->xctype); in channel_set_xtype()
378 debug2_f("labeled channel %d as %s (inactive timeout %u)", id, xctype, in channel_set_xtype()
379 c->inactive_deadline); in channel_set_xtype()
383 * update "last used" time on a channel.
387 channel_set_used_time(struct ssh *ssh, Channel *c) in channel_set_used_time()
389 ssh->chanctxt->lastused = monotime(); in channel_set_used_time()
391 c->lastused = ssh->chanctxt->lastused; in channel_set_used_time()
395 * Get the time at which a channel is due to time out for inactivity.
396 * Returns 0 if the channel is not due to time out ever.
399 channel_get_expiry(struct ssh *ssh, Channel *c) in channel_get_expiry()
401 struct ssh_channels *sc = ssh->chanctxt; in channel_get_expiry()
404 if (sc->lastused != 0 && sc->global_deadline != 0) in channel_get_expiry()
405 expiry = sc->lastused + sc->global_deadline; in channel_get_expiry()
406 if (c->lastused != 0 && c->inactive_deadline != 0) { in channel_get_expiry()
407 channel_expiry = c->lastused + c->inactive_deadline; in channel_get_expiry()
415 * Register filedescriptors for a channel, used when allocating a channel or
416 * when the channel consumer/producer is ready, e.g. shell exec'd
419 channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, in channel_register_fds()
424 if (rfd != -1) in channel_register_fds()
426 if (wfd != -1 && wfd != rfd) in channel_register_fds()
428 if (efd != -1 && efd != rfd && efd != wfd) in channel_register_fds()
431 c->rfd = rfd; in channel_register_fds()
432 c->wfd = wfd; in channel_register_fds()
433 c->sock = (rfd == wfd) ? rfd : -1; in channel_register_fds()
434 c->efd = efd; in channel_register_fds()
435 c->extended_usage = extusage; in channel_register_fds()
437 if ((c->isatty = is_tty) != 0) in channel_register_fds()
438 debug2("channel %d: rfd %d isatty", c->self, c->rfd); in channel_register_fds()
441 c->wfd_isatty = is_tty || isatty(c->wfd); in channel_register_fds()
445 c->restore_block = 0; in channel_register_fds()
449 * non-blocking mode if they are TTYs. Otherwise prepare to in channel_register_fds()
453 if (rfd != -1 && !isatty(rfd) && in channel_register_fds()
454 (val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
455 c->restore_flags[0] = val; in channel_register_fds()
456 c->restore_block |= CHANNEL_RESTORE_RFD; in channel_register_fds()
459 if (wfd != -1 && !isatty(wfd) && in channel_register_fds()
460 (val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
461 c->restore_flags[1] = val; in channel_register_fds()
462 c->restore_block |= CHANNEL_RESTORE_WFD; in channel_register_fds()
465 if (efd != -1 && !isatty(efd) && in channel_register_fds()
466 (val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
467 c->restore_flags[2] = val; in channel_register_fds()
468 c->restore_block |= CHANNEL_RESTORE_EFD; in channel_register_fds()
472 if (rfd != -1) in channel_register_fds()
474 if (wfd != -1) in channel_register_fds()
476 if (efd != -1) in channel_register_fds()
479 /* channel might be entering a larval state, so reset global timeout */ in channel_register_fds()
484 * Allocate a new channel object and set its type and socket.
486 Channel *
491 struct ssh_channels *sc = ssh->chanctxt; in channel_new()
493 Channel *c; in channel_new()
496 /* Try to find a free slot where to put the new channel. */ in channel_new()
497 for (i = 0; i < sc->channels_alloc; i++) { in channel_new()
498 if (sc->channels[i] == NULL) { in channel_new()
504 if (i >= sc->channels_alloc) { in channel_new()
509 found = sc->channels_alloc; in channel_new()
510 if (sc->channels_alloc > CHANNELS_MAX_CHANNELS) in channel_new()
512 sc->channels_alloc); in channel_new()
513 sc->channels = xrecallocarray(sc->channels, sc->channels_alloc, in channel_new()
514 sc->channels_alloc + 10, sizeof(*sc->channels)); in channel_new()
515 sc->channels_alloc += 10; in channel_new()
516 debug2("channel: expanding %d", sc->channels_alloc); in channel_new()
518 /* Initialize and return new channel. */ in channel_new()
519 c = sc->channels[found] = xcalloc(1, sizeof(Channel)); in channel_new()
520 if ((c->input = sshbuf_new()) == NULL || in channel_new()
521 (c->output = sshbuf_new()) == NULL || in channel_new()
522 (c->extended = sshbuf_new()) == NULL) in channel_new()
524 if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) in channel_new()
526 c->ostate = CHAN_OUTPUT_OPEN; in channel_new()
527 c->istate = CHAN_INPUT_OPEN; in channel_new()
529 c->self = found; in channel_new()
530 c->type = type; in channel_new()
531 c->ctype = ctype; in channel_new()
532 c->local_window = window; in channel_new()
533 c->local_window_max = window; in channel_new()
534 c->local_maxpacket = maxpack; in channel_new()
535 c->remote_name = xstrdup(remote_name); in channel_new()
536 c->ctl_chan = -1; in channel_new()
537 c->delayed = 1; /* prevent call to channel_post handler */ in channel_new()
538 c->inactive_deadline = lookup_timeout(ssh, c->ctype); in channel_new()
539 TAILQ_INIT(&c->status_confirms); in channel_new()
540 debug("channel %d: new %s [%s] (inactive timeout: %u)", in channel_new()
541 found, c->ctype, remote_name, c->inactive_deadline); in channel_new()
546 channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) in channel_close_fd()
550 if (fd == -1) in channel_close_fd()
554 if (*fdp == c->rfd && in channel_close_fd()
555 (c->restore_block & CHANNEL_RESTORE_RFD) != 0) in channel_close_fd()
556 (void)fcntl(*fdp, F_SETFL, c->restore_flags[0]); in channel_close_fd()
557 else if (*fdp == c->wfd && in channel_close_fd()
558 (c->restore_block & CHANNEL_RESTORE_WFD) != 0) in channel_close_fd()
559 (void)fcntl(*fdp, F_SETFL, c->restore_flags[1]); in channel_close_fd()
560 else if (*fdp == c->efd && in channel_close_fd()
561 (c->restore_block & CHANNEL_RESTORE_EFD) != 0) in channel_close_fd()
562 (void)fcntl(*fdp, F_SETFL, c->restore_flags[2]); in channel_close_fd()
564 if (*fdp == c->rfd) { in channel_close_fd()
565 c->io_want &= ~SSH_CHAN_IO_RFD; in channel_close_fd()
566 c->io_ready &= ~SSH_CHAN_IO_RFD; in channel_close_fd()
567 c->rfd = -1; in channel_close_fd()
568 c->pfds[0] = -1; in channel_close_fd()
570 if (*fdp == c->wfd) { in channel_close_fd()
571 c->io_want &= ~SSH_CHAN_IO_WFD; in channel_close_fd()
572 c->io_ready &= ~SSH_CHAN_IO_WFD; in channel_close_fd()
573 c->wfd = -1; in channel_close_fd()
574 c->pfds[1] = -1; in channel_close_fd()
576 if (*fdp == c->efd) { in channel_close_fd()
577 c->io_want &= ~SSH_CHAN_IO_EFD; in channel_close_fd()
578 c->io_ready &= ~SSH_CHAN_IO_EFD; in channel_close_fd()
579 c->efd = -1; in channel_close_fd()
580 c->pfds[2] = -1; in channel_close_fd()
582 if (*fdp == c->sock) { in channel_close_fd()
583 c->io_want &= ~SSH_CHAN_IO_SOCK; in channel_close_fd()
584 c->io_ready &= ~SSH_CHAN_IO_SOCK; in channel_close_fd()
585 c->sock = -1; in channel_close_fd()
586 c->pfds[3] = -1; in channel_close_fd()
590 *fdp = -1; /* probably redundant */ in channel_close_fd()
594 /* Close all channel fd/socket. */
596 channel_close_fds(struct ssh *ssh, Channel *c) in channel_close_fds()
598 int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; in channel_close_fds()
600 channel_close_fd(ssh, c, &c->sock); in channel_close_fds()
602 channel_close_fd(ssh, c, &c->rfd); in channel_close_fds()
604 channel_close_fd(ssh, c, &c->wfd); in channel_close_fds()
606 channel_close_fd(ssh, c, &c->efd); in channel_close_fds()
612 free(perm->host_to_connect); in fwd_perm_clear()
613 free(perm->listen_host); in fwd_perm_clear()
614 free(perm->listen_path); in fwd_perm_clear()
633 fatal("Unknown forward permission list %d/%d", who, where); in fwd_ident()
640 struct ssh_channels *sc = ssh->chanctxt; in permission_set_get()
644 return &sc->local_perms; in permission_set_get()
647 return &sc->remote_perms; in permission_set_get()
663 *permpp = &pset->permitted_user; in permission_set_get_array()
664 *npermpp = &pset->num_permitted_user; in permission_set_get_array()
667 *permpp = &pset->permitted_admin; in permission_set_get_array()
668 *npermpp = &pset->num_permitted_admin; in permission_set_get_array()
680 Channel *downstream) in permission_set_add()
704 mux_remove_remote_forwardings(struct ssh *ssh, Channel *c) in mux_remove_remote_forwardings()
706 struct ssh_channels *sc = ssh->chanctxt; in mux_remove_remote_forwardings()
707 struct permission_set *pset = &sc->local_perms; in mux_remove_remote_forwardings()
712 for (i = 0; i < pset->num_permitted_user; i++) { in mux_remove_remote_forwardings()
713 perm = &pset->permitted_user[i]; in mux_remove_remote_forwardings()
714 if (perm->downstream != c) in mux_remove_remote_forwardings()
718 debug("channel %d: cleanup remote forward for %s:%u", in mux_remove_remote_forwardings()
719 c->self, perm->listen_host, perm->listen_port); in mux_remove_remote_forwardings()
722 "cancel-tcpip-forward")) != 0 || in mux_remove_remote_forwardings()
725 channel_rfwd_bind_host(perm->listen_host))) != 0 || in mux_remove_remote_forwardings()
726 (r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 || in mux_remove_remote_forwardings()
728 fatal_fr(r, "channel %i", c->self); in mux_remove_remote_forwardings()
734 /* Free the channel and close its fd/socket. */
736 channel_free(struct ssh *ssh, Channel *c) in channel_free()
738 struct ssh_channels *sc = ssh->chanctxt; in channel_free()
741 Channel *other; in channel_free()
744 for (n = 0, i = 0; i < sc->channels_alloc; i++) { in channel_free()
745 if ((other = sc->channels[i]) == NULL) in channel_free()
749 if (c->type == SSH_CHANNEL_MUX_CLIENT && in channel_free()
750 other->type == SSH_CHANNEL_MUX_PROXY && in channel_free()
751 other->mux_ctx == c) { in channel_free()
752 other->mux_ctx = NULL; in channel_free()
753 other->type = SSH_CHANNEL_OPEN; in channel_free()
754 other->istate = CHAN_INPUT_CLOSED; in channel_free()
755 other->ostate = CHAN_OUTPUT_CLOSED; in channel_free()
758 debug("channel %d: free: %s, nchannels %u", c->self, in channel_free()
759 c->remote_name ? c->remote_name : "???", n); in channel_free()
761 if (c->type == SSH_CHANNEL_MUX_CLIENT) { in channel_free()
763 free(c->mux_ctx); in channel_free()
764 c->mux_ctx = NULL; in channel_free()
765 } else if (c->type == SSH_CHANNEL_MUX_LISTENER) { in channel_free()
766 free(c->mux_ctx); in channel_free()
767 c->mux_ctx = NULL; in channel_free()
772 debug3("channel %d: status: %s", c->self, s); in channel_free()
777 sshbuf_free(c->input); in channel_free()
778 sshbuf_free(c->output); in channel_free()
779 sshbuf_free(c->extended); in channel_free()
780 c->input = c->output = c->extended = NULL; in channel_free()
781 free(c->remote_name); in channel_free()
782 c->remote_name = NULL; in channel_free()
783 free(c->path); in channel_free()
784 c->path = NULL; in channel_free()
785 free(c->listening_addr); in channel_free()
786 c->listening_addr = NULL; in channel_free()
787 free(c->xctype); in channel_free()
788 c->xctype = NULL; in channel_free()
789 while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { in channel_free()
790 if (cc->abandon_cb != NULL) in channel_free()
791 cc->abandon_cb(ssh, c, cc->ctx); in channel_free()
792 TAILQ_REMOVE(&c->status_confirms, cc, entry); in channel_free()
795 if (c->filter_cleanup != NULL && c->filter_ctx != NULL) in channel_free()
796 c->filter_cleanup(ssh, c->self, c->filter_ctx); in channel_free()
797 sc->channels[c->self] = NULL; in channel_free()
805 struct ssh_channels *sc = ssh->chanctxt; in channel_free_all()
807 for (i = 0; i < sc->channels_alloc; i++) in channel_free_all()
808 if (sc->channels[i] != NULL) in channel_free_all()
809 channel_free(ssh, sc->channels[i]); in channel_free_all()
811 free(sc->channels); in channel_free_all()
812 sc->channels = NULL; in channel_free_all()
813 sc->channels_alloc = 0; in channel_free_all()
815 free(sc->x11_saved_display); in channel_free_all()
816 sc->x11_saved_display = NULL; in channel_free_all()
818 free(sc->x11_saved_proto); in channel_free_all()
819 sc->x11_saved_proto = NULL; in channel_free_all()
821 free(sc->x11_saved_data); in channel_free_all()
822 sc->x11_saved_data = NULL; in channel_free_all()
823 sc->x11_saved_data_len = 0; in channel_free_all()
825 free(sc->x11_fake_data); in channel_free_all()
826 sc->x11_fake_data = NULL; in channel_free_all()
827 sc->x11_fake_data_len = 0; in channel_free_all()
839 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) in channel_close_all()
840 if (ssh->chanctxt->channels[i] != NULL) in channel_close_all()
841 channel_close_fds(ssh, ssh->chanctxt->channels[i]); in channel_close_all()
851 Channel *c; in channel_stop_listening()
853 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_stop_listening()
854 c = ssh->chanctxt->channels[i]; in channel_stop_listening()
856 switch (c->type) { in channel_stop_listening()
863 channel_close_fd(ssh, c, &c->sock); in channel_stop_listening()
872 * Returns true if no channel has too much buffered data, and false if one or
873 * more channel is overfull.
880 Channel *c; in channel_not_very_much_buffered_data()
882 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_not_very_much_buffered_data()
883 c = ssh->chanctxt->channels[i]; in channel_not_very_much_buffered_data()
884 if (c == NULL || c->type != SSH_CHANNEL_OPEN) in channel_not_very_much_buffered_data()
886 if (sshbuf_len(c->output) > maxsize) { in channel_not_very_much_buffered_data()
887 debug2("channel %d: big output buffer %zu > %u", in channel_not_very_much_buffered_data()
888 c->self, sshbuf_len(c->output), maxsize); in channel_not_very_much_buffered_data()
895 /* Returns true if any channel is still open. */
900 Channel *c; in channel_still_open()
902 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_still_open()
903 c = ssh->chanctxt->channels[i]; in channel_still_open()
906 switch (c->type) { in channel_still_open()
931 fatal_f("bad channel type %d", c->type); in channel_still_open()
938 /* Returns true if a channel with a TTY is open. */
943 Channel *c; in channel_tty_open()
945 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_tty_open()
946 c = ssh->chanctxt->channels[i]; in channel_tty_open()
947 if (c == NULL || c->type != SSH_CHANNEL_OPEN) in channel_tty_open()
949 if (c->client_tty) in channel_tty_open()
955 /* Returns the id of an open channel suitable for keepaliving */
960 Channel *c; in channel_find_open()
962 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_find_open()
963 c = ssh->chanctxt->channels[i]; in channel_find_open()
964 if (c == NULL || !c->have_remote_id) in channel_find_open()
966 switch (c->type) { in channel_find_open()
990 fatal_f("bad channel type %d", c->type); in channel_find_open()
994 return -1; in channel_find_open()
997 /* Returns the state of the channel's extended usage flag */
999 channel_format_extended_usage(const Channel *c) in channel_format_extended_usage()
1001 if (c->efd == -1) in channel_format_extended_usage()
1004 switch (c->extended_usage) { in channel_format_extended_usage()
1017 channel_format_status(const Channel *c) in channel_format_status()
1023 c->type, c->xctype != NULL ? c->xctype : c->ctype, in channel_format_status()
1024 c->have_remote_id ? "r" : "nr", c->remote_id, in channel_format_status()
1025 c->mux_ctx != NULL ? "m" : "nm", c->mux_downstream_id, in channel_format_status()
1026 c->istate, sshbuf_len(c->input), in channel_format_status()
1027 c->ostate, sshbuf_len(c->output), in channel_format_status()
1028 channel_format_extended_usage(c), sshbuf_len(c->extended), in channel_format_status()
1029 c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan, in channel_format_status()
1030 c->have_ctl_child_id ? "c" : "nc", c->ctl_child_id, in channel_format_status()
1031 c->io_want, c->io_ready); in channel_format_status()
1044 Channel *c; in channel_open_message()
1054 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_open_message()
1055 c = ssh->chanctxt->channels[i]; in channel_open_message()
1058 switch (c->type) { in channel_open_message()
1082 c->self, c->remote_name, cp)) != 0) { in channel_open_message()
1089 fatal_f("bad channel type %d", c->type); in channel_open_message()
1100 open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type) in open_preamble()
1106 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in open_preamble()
1107 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in open_preamble()
1108 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) { in open_preamble()
1109 fatal_r(r, "%s: channel %i: open", where, c->self); in open_preamble()
1116 Channel *c = channel_lookup(ssh, id); in channel_send_open()
1123 debug2("channel %d: send open", id); in channel_send_open()
1124 open_preamble(ssh, __func__, c, c->ctype); in channel_send_open()
1126 fatal_fr(r, "channel %i", c->self); in channel_send_open()
1132 Channel *c = channel_lookup(ssh, id); in channel_request_start()
1136 logit_f("%d: unknown channel id", id); in channel_request_start()
1139 if (!c->have_remote_id) in channel_request_start()
1140 fatal_f("channel %d: no remote id", c->self); in channel_request_start()
1142 debug2("channel %d: request %s confirm %d", id, service, wantconfirm); in channel_request_start()
1144 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_request_start()
1147 fatal_fr(r, "channel %i", c->self); in channel_request_start()
1156 Channel *c; in channel_register_status_confirm()
1162 cc->cb = cb; in channel_register_status_confirm()
1163 cc->abandon_cb = abandon_cb; in channel_register_status_confirm()
1164 cc->ctx = ctx; in channel_register_status_confirm()
1165 TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry); in channel_register_status_confirm()
1172 Channel *c = channel_lookup(ssh, id); in channel_register_open_confirm()
1178 c->open_confirm = fn; in channel_register_open_confirm()
1179 c->open_confirm_ctx = ctx; in channel_register_open_confirm()
1186 Channel *c = channel_by_id(ssh, id); in channel_register_cleanup()
1192 c->detach_user = fn; in channel_register_cleanup()
1193 c->detach_close = do_close; in channel_register_cleanup()
1199 Channel *c = channel_by_id(ssh, id); in channel_cancel_cleanup()
1205 c->detach_user = NULL; in channel_cancel_cleanup()
1206 c->detach_close = 0; in channel_cancel_cleanup()
1213 Channel *c = channel_lookup(ssh, id); in channel_register_filter()
1219 c->input_filter = ifn; in channel_register_filter()
1220 c->output_filter = ofn; in channel_register_filter()
1221 c->filter_ctx = ctx; in channel_register_filter()
1222 c->filter_cleanup = cfn; in channel_register_filter()
1229 Channel *c = channel_lookup(ssh, id); in channel_set_fds()
1232 if (c == NULL || c->type != SSH_CHANNEL_LARVAL) in channel_set_fds()
1233 fatal("channel_activate for non-larval channel %d.", id); in channel_set_fds()
1234 if (!c->have_remote_id) in channel_set_fds()
1235 fatal_f("channel %d: no remote id", c->self); in channel_set_fds()
1238 c->type = SSH_CHANNEL_OPEN; in channel_set_fds()
1240 c->local_window = c->local_window_max = window_max; in channel_set_fds()
1243 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_set_fds()
1244 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in channel_set_fds()
1246 fatal_fr(r, "channel %i", c->self); in channel_set_fds()
1250 channel_pre_listener(struct ssh *ssh, Channel *c) in channel_pre_listener()
1252 c->io_want = SSH_CHAN_IO_SOCK_R; in channel_pre_listener()
1256 channel_pre_connecting(struct ssh *ssh, Channel *c) in channel_pre_connecting()
1258 debug3("channel %d: waiting for connection", c->self); in channel_pre_connecting()
1259 c->io_want = SSH_CHAN_IO_SOCK_W; in channel_pre_connecting()
1263 channel_pre_open(struct ssh *ssh, Channel *c) in channel_pre_open()
1265 c->io_want = 0; in channel_pre_open()
1266 if (c->istate == CHAN_INPUT_OPEN && in channel_pre_open()
1267 c->remote_window > 0 && in channel_pre_open()
1268 sshbuf_len(c->input) < c->remote_window && in channel_pre_open()
1269 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0) in channel_pre_open()
1270 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_open()
1271 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_pre_open()
1272 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_open()
1273 if (sshbuf_len(c->output) > 0) { in channel_pre_open()
1274 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_open()
1275 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_open()
1277 debug2("channel %d: " in channel_pre_open()
1278 "obuf_empty delayed efd %d/(%zu)", c->self, in channel_pre_open()
1279 c->efd, sshbuf_len(c->extended)); in channel_pre_open()
1285 if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED && in channel_pre_open()
1286 c->ostate == CHAN_OUTPUT_CLOSED)) { in channel_pre_open()
1287 if (c->extended_usage == CHAN_EXTENDED_WRITE && in channel_pre_open()
1288 sshbuf_len(c->extended) > 0) in channel_pre_open()
1289 c->io_want |= SSH_CHAN_IO_EFD_W; in channel_pre_open()
1290 else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) && in channel_pre_open()
1291 (c->extended_usage == CHAN_EXTENDED_READ || in channel_pre_open()
1292 c->extended_usage == CHAN_EXTENDED_IGNORE) && in channel_pre_open()
1293 sshbuf_len(c->extended) < c->remote_window) in channel_pre_open()
1294 c->io_want |= SSH_CHAN_IO_EFD_R; in channel_pre_open()
1304 * fake data, and the channel is put into normal mode.
1306 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
1311 struct ssh_channels *sc = ssh->chanctxt; in x11_open_helper()
1316 if (sc->x11_refuse_time != 0 && in x11_open_helper()
1317 monotime() >= sc->x11_refuse_time) { in x11_open_helper()
1320 return -1; in x11_open_helper()
1327 /* Parse the lengths of variable-length fields. */ in x11_open_helper()
1338 return -1; in x11_open_helper()
1347 if (proto_len != strlen(sc->x11_saved_proto) || in x11_open_helper()
1348 memcmp(ucp + 12, sc->x11_saved_proto, proto_len) != 0) { in x11_open_helper()
1350 return -1; in x11_open_helper()
1353 if (data_len != sc->x11_fake_data_len || in x11_open_helper()
1355 sc->x11_fake_data, sc->x11_fake_data_len) != 0) { in x11_open_helper()
1357 return -1; in x11_open_helper()
1360 if (sc->x11_fake_data_len != sc->x11_saved_data_len) { in x11_open_helper()
1362 sc->x11_fake_data_len, sc->x11_saved_data_len); in x11_open_helper()
1363 return -1; in x11_open_helper()
1371 sc->x11_saved_data, sc->x11_saved_data_len); in x11_open_helper()
1376 channel_force_close(struct ssh *ssh, Channel *c, int abandon) in channel_force_close()
1378 debug3_f("channel %d: forcibly closing", c->self); in channel_force_close()
1379 if (c->istate == CHAN_INPUT_OPEN) in channel_force_close()
1381 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_force_close()
1382 sshbuf_reset(c->input); in channel_force_close()
1385 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_force_close()
1386 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_force_close()
1387 sshbuf_reset(c->output); in channel_force_close()
1390 if (c->detach_user) in channel_force_close()
1391 c->detach_user(ssh, c->self, 1, NULL); in channel_force_close()
1392 if (c->efd != -1) in channel_force_close()
1393 channel_close_fd(ssh, c, &c->efd); in channel_force_close()
1395 c->type = SSH_CHANNEL_ABANDONED; in channel_force_close()
1397 c->inactive_deadline = 0; in channel_force_close()
1398 c->lastused = 0; in channel_force_close()
1402 channel_pre_x11_open(struct ssh *ssh, Channel *c) in channel_pre_x11_open()
1404 int ret = x11_open_helper(ssh, c->output); in channel_pre_x11_open()
1406 /* c->force_drain = 1; */ in channel_pre_x11_open()
1409 c->type = SSH_CHANNEL_OPEN; in channel_pre_x11_open()
1412 } else if (ret == -1) { in channel_pre_x11_open()
1416 c->self, c->istate, c->ostate); in channel_pre_x11_open()
1422 channel_pre_mux_client(struct ssh *ssh, Channel *c) in channel_pre_mux_client()
1424 c->io_want = 0; in channel_pre_mux_client()
1425 if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause && in channel_pre_mux_client()
1426 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0) in channel_pre_mux_client()
1427 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_mux_client()
1428 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_pre_mux_client()
1430 sshbuf_reset(c->input); in channel_pre_mux_client()
1435 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_pre_mux_client()
1436 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_mux_client()
1437 if (sshbuf_len(c->output) > 0) in channel_pre_mux_client()
1438 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_mux_client()
1439 else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) in channel_pre_mux_client()
1446 channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output) in channel_decode_socks4()
1460 debug2("channel %d: decode socks4", c->self); in channel_decode_socks4()
1471 debug2("channel %d: socks4a request", c->self); in channel_decode_socks4()
1484 debug("channel %d: decode socks4: too long", in channel_decode_socks4()
1485 c->self); in channel_decode_socks4()
1486 return -1; in channel_decode_socks4()
1495 debug_r(r, "channels %d: decode socks4", c->self); in channel_decode_socks4()
1496 return -1; in channel_decode_socks4()
1501 error("channel %d: decode socks4: unterminated user", c->self); in channel_decode_socks4()
1502 return -1; in channel_decode_socks4()
1505 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); in channel_decode_socks4()
1509 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks4()
1510 free(c->path); in channel_decode_socks4()
1511 c->path = NULL; in channel_decode_socks4()
1514 c->path = xstrdup(host); in channel_decode_socks4()
1519 error("channel %d: decode socks4a: host not nul " in channel_decode_socks4()
1520 "terminated", c->self); in channel_decode_socks4()
1521 return -1; in channel_decode_socks4()
1524 debug2("channel %d: decode socks4a: host %s/%d", in channel_decode_socks4()
1525 c->self, p, len); in channel_decode_socks4()
1528 error("channel %d: hostname \"%.100s\" too long", in channel_decode_socks4()
1529 c->self, p); in channel_decode_socks4()
1530 return -1; in channel_decode_socks4()
1532 c->path = xstrdup(p); in channel_decode_socks4()
1534 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks4()
1536 c->host_port = ntohs(s4_req.dest_port); in channel_decode_socks4()
1538 debug2("channel %d: dynamic request: socks4 host %s port %u command %u", in channel_decode_socks4()
1539 c->self, c->path, c->host_port, s4_req.command); in channel_decode_socks4()
1542 debug("channel %d: cannot handle: %s cn %d", in channel_decode_socks4()
1543 c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command); in channel_decode_socks4()
1544 return -1; in channel_decode_socks4()
1551 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks4()
1565 channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output) in channel_decode_socks5()
1580 debug2("channel %d: decode socks5", c->self); in channel_decode_socks5()
1583 return -1; in channel_decode_socks5()
1585 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { in channel_decode_socks5()
1600 debug("channel %d: method SSH_SOCKS5_NOAUTH not found", in channel_decode_socks5()
1601 c->self); in channel_decode_socks5()
1602 return -1; in channel_decode_socks5()
1605 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1609 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks5()
1610 c->flags |= SSH_SOCKS5_AUTHDONE; in channel_decode_socks5()
1611 debug2("channel %d: socks5 auth done", c->self); in channel_decode_socks5()
1614 debug2("channel %d: socks5 post auth", c->self); in channel_decode_socks5()
1621 debug2("channel %d: only socks5 connect supported", c->self); in channel_decode_socks5()
1622 return -1; in channel_decode_socks5()
1631 af = -1; in channel_decode_socks5()
1638 debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); in channel_decode_socks5()
1639 return -1; in channel_decode_socks5()
1647 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1651 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1655 debug_r(r, "channel %d: parse addr/port", c->self); in channel_decode_socks5()
1656 return -1; in channel_decode_socks5()
1659 free(c->path); in channel_decode_socks5()
1660 c->path = NULL; in channel_decode_socks5()
1663 error("channel %d: dynamic request: socks5 hostname " in channel_decode_socks5()
1664 "\"%.100s\" too long", c->self, dest_addr); in channel_decode_socks5()
1665 return -1; in channel_decode_socks5()
1667 c->path = xstrdup(dest_addr); in channel_decode_socks5()
1670 return -1; in channel_decode_socks5()
1671 c->path = xstrdup(ntop); in channel_decode_socks5()
1673 c->host_port = ntohs(dest_port); in channel_decode_socks5()
1675 debug2("channel %d: dynamic request: socks5 host %s port %u command %u", in channel_decode_socks5()
1676 c->self, c->path, c->host_port, s5_req.command); in channel_decode_socks5()
1687 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks5()
1691 Channel *
1696 Channel *c; in channel_connect_stdio_fwd()
1700 c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, in channel_connect_stdio_fwd()
1701 -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, in channel_connect_stdio_fwd()
1702 0, "stdio-forward", nonblock); in channel_connect_stdio_fwd()
1704 c->path = xstrdup(host_to_connect); in channel_connect_stdio_fwd()
1705 c->host_port = port_to_connect; in channel_connect_stdio_fwd()
1706 c->listening_port = 0; in channel_connect_stdio_fwd()
1707 c->force_drain = 1; in channel_connect_stdio_fwd()
1709 channel_register_fds(ssh, c, in, out, -1, 0, 1, 0); in channel_connect_stdio_fwd()
1711 "direct-streamlocal@openssh.com" : "direct-tcpip"); in channel_connect_stdio_fwd()
1718 channel_pre_dynamic(struct ssh *ssh, Channel *c) in channel_pre_dynamic()
1724 c->io_want = 0; in channel_pre_dynamic()
1725 have = sshbuf_len(c->input); in channel_pre_dynamic()
1726 debug2("channel %d: pre_dynamic: have %d", c->self, have); in channel_pre_dynamic()
1727 /* sshbuf_dump(c->input, stderr); */ in channel_pre_dynamic()
1731 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_dynamic()
1735 p = sshbuf_ptr(c->input); in channel_pre_dynamic()
1739 ret = channel_decode_socks4(c, c->input, c->output); in channel_pre_dynamic()
1742 ret = channel_decode_socks5(c, c->input, c->output); in channel_pre_dynamic()
1745 ret = -1; in channel_pre_dynamic()
1751 debug2("channel %d: pre_dynamic: need more", c->self); in channel_pre_dynamic()
1753 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_dynamic()
1754 if (sshbuf_len(c->output)) in channel_pre_dynamic()
1755 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_dynamic()
1758 c->type = SSH_CHANNEL_OPENING; in channel_pre_dynamic()
1759 port_open_helper(ssh, c, "direct-tcpip"); in channel_pre_dynamic()
1763 /* simulate read-error */
1765 rdynamic_close(struct ssh *ssh, Channel *c) in rdynamic_close()
1767 c->type = SSH_CHANNEL_OPEN; in rdynamic_close()
1773 channel_before_prepare_io_rdynamic(struct ssh *ssh, Channel *c) in channel_before_prepare_io_rdynamic()
1779 have = sshbuf_len(c->output); in channel_before_prepare_io_rdynamic()
1780 debug2("channel %d: pre_rdynamic: have %d", c->self, have); in channel_before_prepare_io_rdynamic()
1781 /* sshbuf_dump(c->output, stderr); */ in channel_before_prepare_io_rdynamic()
1783 if (c->flags & CHAN_EOF_RCVD) { in channel_before_prepare_io_rdynamic()
1784 if ((r = sshbuf_consume(c->output, have)) != 0) in channel_before_prepare_io_rdynamic()
1785 fatal_fr(r, "channel %d: consume", c->self); in channel_before_prepare_io_rdynamic()
1793 p = sshbuf_ptr(c->output); in channel_before_prepare_io_rdynamic()
1797 ret = channel_decode_socks4(c, c->output, c->input); in channel_before_prepare_io_rdynamic()
1800 ret = channel_decode_socks5(c, c->output, c->input); in channel_before_prepare_io_rdynamic()
1803 ret = -1; in channel_before_prepare_io_rdynamic()
1809 debug2("channel %d: pre_rdynamic: need more", c->self); in channel_before_prepare_io_rdynamic()
1811 len = sshbuf_len(c->input); in channel_before_prepare_io_rdynamic()
1812 if (len > 0 && len < c->remote_window) { in channel_before_prepare_io_rdynamic()
1814 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_before_prepare_io_rdynamic()
1815 (r = sshpkt_put_stringb(ssh, c->input)) != 0 || in channel_before_prepare_io_rdynamic()
1817 fatal_fr(r, "channel %i: rdynamic", c->self); in channel_before_prepare_io_rdynamic()
1819 if ((r = sshbuf_consume(c->input, len)) != 0) in channel_before_prepare_io_rdynamic()
1820 fatal_fr(r, "channel %d: consume", c->self); in channel_before_prepare_io_rdynamic()
1821 c->remote_window -= len; in channel_before_prepare_io_rdynamic()
1831 channel_post_x11_listener(struct ssh *ssh, Channel *c) in channel_post_x11_listener()
1833 Channel *nc; in channel_post_x11_listener()
1839 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_x11_listener()
1844 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_x11_listener()
1845 if (c->single_connection) { in channel_post_x11_listener()
1848 channel_close_fd(ssh, c, &c->sock); in channel_post_x11_listener()
1852 if (newsock == -1) { in channel_post_x11_listener()
1857 c->notbefore = monotime() + 1; in channel_post_x11_listener()
1866 nc = channel_new(ssh, "x11-connection", in channel_post_x11_listener()
1867 SSH_CHANNEL_OPENING, newsock, newsock, -1, in channel_post_x11_listener()
1868 c->local_window_max, c->local_maxpacket, 0, buf, 1); in channel_post_x11_listener()
1872 fatal_fr(r, "channel %i: reply", c->self); in channel_post_x11_listener()
1875 fatal_fr(r, "channel %i: send", c->self); in channel_post_x11_listener()
1880 port_open_helper(struct ssh *ssh, Channel *c, char *rtype) in port_open_helper()
1882 char *local_ipaddr = get_local_ipaddr(c->sock); in port_open_helper()
1883 int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock); in port_open_helper()
1884 char *remote_ipaddr = get_peer_ipaddr(c->sock); in port_open_helper()
1885 int remote_port = get_peer_port(c->sock); in port_open_helper()
1888 if (remote_port == -1) { in port_open_helper()
1895 free(c->remote_name); in port_open_helper()
1896 xasprintf(&c->remote_name, in port_open_helper()
1899 rtype, c->listening_port, c->path, c->host_port, in port_open_helper()
1903 if (strcmp(rtype, "direct-tcpip") == 0) { in port_open_helper()
1905 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 || in port_open_helper()
1906 (r = sshpkt_put_u32(ssh, c->host_port)) != 0) in port_open_helper()
1907 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1908 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) { in port_open_helper()
1910 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) in port_open_helper()
1911 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1912 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { in port_open_helper()
1914 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) in port_open_helper()
1915 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1918 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 || in port_open_helper()
1920 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1922 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { in port_open_helper()
1925 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1930 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1933 fatal_fr(r, "channel %i: send", c->self); in port_open_helper()
1941 ssh->chanctxt->x11_refuse_time = refuse_time; in channel_set_x11_refuse_time()
1948 channel_post_port_listener(struct ssh *ssh, Channel *c) in channel_post_port_listener()
1950 Channel *nc; in channel_post_port_listener()
1956 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_port_listener()
1960 c->listening_port, c->path, c->host_port); in channel_post_port_listener()
1962 if (c->type == SSH_CHANNEL_RPORT_LISTENER) { in channel_post_port_listener()
1964 rtype = "forwarded-tcpip"; in channel_post_port_listener()
1965 } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) { in channel_post_port_listener()
1967 rtype = "forwarded-streamlocal@openssh.com"; in channel_post_port_listener()
1968 } else if (c->host_port == PORT_STREAMLOCAL) { in channel_post_port_listener()
1970 rtype = "direct-streamlocal@openssh.com"; in channel_post_port_listener()
1971 } else if (c->host_port == 0) { in channel_post_port_listener()
1973 rtype = "dynamic-tcpip"; in channel_post_port_listener()
1976 rtype = "direct-tcpip"; in channel_post_port_listener()
1980 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_port_listener()
1981 if (newsock == -1) { in channel_post_port_listener()
1986 c->notbefore = monotime() + 1; in channel_post_port_listener()
1989 if (c->host_port != PORT_STREAMLOCAL) in channel_post_port_listener()
1991 nc = channel_new(ssh, rtype, nextstate, newsock, newsock, -1, in channel_post_port_listener()
1992 c->local_window_max, c->local_maxpacket, 0, rtype, 1); in channel_post_port_listener()
1993 nc->listening_port = c->listening_port; in channel_post_port_listener()
1994 nc->host_port = c->host_port; in channel_post_port_listener()
1995 if (c->path != NULL) in channel_post_port_listener()
1996 nc->path = xstrdup(c->path); in channel_post_port_listener()
2007 channel_post_auth_listener(struct ssh *ssh, Channel *c) in channel_post_auth_listener()
2009 Channel *nc; in channel_post_auth_listener()
2014 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_auth_listener()
2018 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_auth_listener()
2019 if (newsock == -1) { in channel_post_auth_listener()
2022 c->notbefore = monotime() + 1; in channel_post_auth_listener()
2025 nc = channel_new(ssh, "agent-connection", in channel_post_auth_listener()
2026 SSH_CHANNEL_OPENING, newsock, newsock, -1, in channel_post_auth_listener()
2027 c->local_window_max, c->local_maxpacket, in channel_post_auth_listener()
2029 open_preamble(ssh, __func__, nc, "auth-agent@openssh.com"); in channel_post_auth_listener()
2031 fatal_fr(r, "channel %i", c->self); in channel_post_auth_listener()
2035 channel_post_connecting(struct ssh *ssh, Channel *c) in channel_post_connecting()
2040 if ((c->io_ready & SSH_CHAN_IO_SOCK_W) == 0) in channel_post_connecting()
2042 if (!c->have_remote_id) in channel_post_connecting()
2043 fatal_f("channel %d: no remote id", c->self); in channel_post_connecting()
2045 isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH); in channel_post_connecting()
2047 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) == -1) { in channel_post_connecting()
2053 /* Non-blocking connection completed */ in channel_post_connecting()
2054 debug("channel %d: connected to %s port %d", in channel_post_connecting()
2055 c->self, c->connect_ctx.host, c->connect_ctx.port); in channel_post_connecting()
2056 channel_connect_ctx_free(&c->connect_ctx); in channel_post_connecting()
2057 c->type = SSH_CHANNEL_OPEN; in channel_post_connecting()
2064 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_post_connecting()
2065 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in channel_post_connecting()
2066 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in channel_post_connecting()
2067 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 || in channel_post_connecting()
2069 fatal_fr(r, "channel %i open confirm", c->self); in channel_post_connecting()
2076 /* Non-blocking connection failed */ in channel_post_connecting()
2077 debug("channel %d: connection failed: %s", c->self, strerror(err)); in channel_post_connecting()
2080 if ((sock = connect_next(&c->connect_ctx)) == -1) { in channel_post_connecting()
2083 c->connect_ctx.host, c->connect_ctx.port); in channel_post_connecting()
2084 channel_connect_ctx_free(&c->connect_ctx); in channel_post_connecting()
2090 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_post_connecting()
2096 fatal_fr(r, "channel %i: failure", c->self); in channel_post_connecting()
2101 /* New non-blocking connection in progress */ in channel_post_connecting()
2102 close(c->sock); in channel_post_connecting()
2103 c->sock = c->rfd = c->wfd = sock; in channel_post_connecting()
2107 channel_handle_rfd(struct ssh *ssh, Channel *c) in channel_handle_rfd()
2116 /* Bug on AIX: read(1) can return 0 for a non-closed fd */ in channel_handle_rfd()
2117 pty_zeroread = c->isatty; in channel_handle_rfd()
2120 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; in channel_handle_rfd()
2122 if (!force && (c->io_ready & SSH_CHAN_IO_RFD) == 0) in channel_handle_rfd()
2124 if ((avail = sshbuf_avail(c->input)) == 0) in channel_handle_rfd()
2129 * read directly to the channel buffer. in channel_handle_rfd()
2131 if (!pty_zeroread && c->input_filter == NULL && !c->datagram) { in channel_handle_rfd()
2133 if (c->type == SSH_CHANNEL_OPEN) { in channel_handle_rfd()
2134 if ((have = sshbuf_len(c->input)) >= c->remote_window) in channel_handle_rfd()
2136 if (maxlen > c->remote_window - have) in channel_handle_rfd()
2137 maxlen = c->remote_window - have; in channel_handle_rfd()
2141 if ((r = sshbuf_read(c->rfd, c->input, maxlen, &nr)) != 0) { in channel_handle_rfd()
2145 debug2("channel %d: read failed rfd %d maxlen %zu: %s", in channel_handle_rfd()
2146 c->self, c->rfd, maxlen, ssh_err(r)); in channel_handle_rfd()
2155 len = read(c->rfd, buf, sizeof(buf)); in channel_handle_rfd()
2156 /* fixup AIX zero-length read with errno set to look more like errors */ in channel_handle_rfd()
2158 len = -1; in channel_handle_rfd()
2159 if (len == -1 && (errno == EINTR || in channel_handle_rfd()
2163 debug2("channel %d: read<=0 rfd %d len %zd: %s", in channel_handle_rfd()
2164 c->self, c->rfd, len, in channel_handle_rfd()
2167 if (c->type != SSH_CHANNEL_OPEN) { in channel_handle_rfd()
2168 debug2("channel %d: not open", c->self); in channel_handle_rfd()
2170 return -1; in channel_handle_rfd()
2174 return -1; in channel_handle_rfd()
2177 if (c->input_filter != NULL) { in channel_handle_rfd()
2178 if (c->input_filter(ssh, c, buf, len) == -1) { in channel_handle_rfd()
2179 debug2("channel %d: filter stops", c->self); in channel_handle_rfd()
2182 } else if (c->datagram) { in channel_handle_rfd()
2183 if ((r = sshbuf_put_string(c->input, buf, len)) != 0) in channel_handle_rfd()
2184 fatal_fr(r, "channel %i: put datagram", c->self); in channel_handle_rfd()
2185 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) in channel_handle_rfd()
2186 fatal_fr(r, "channel %i: put data", c->self); in channel_handle_rfd()
2192 channel_handle_wfd(struct ssh *ssh, Channel *c) in channel_handle_wfd()
2199 if ((c->io_ready & SSH_CHAN_IO_WFD) == 0) in channel_handle_wfd()
2201 if (sshbuf_len(c->output) == 0) in channel_handle_wfd()
2205 olen = sshbuf_len(c->output); in channel_handle_wfd()
2206 if (c->output_filter != NULL) { in channel_handle_wfd()
2207 if ((buf = c->output_filter(ssh, c, &data, &dlen)) == NULL) { in channel_handle_wfd()
2208 debug2("channel %d: filter stops", c->self); in channel_handle_wfd()
2209 if (c->type != SSH_CHANNEL_OPEN) in channel_handle_wfd()
2213 return -1; in channel_handle_wfd()
2215 } else if (c->datagram) { in channel_handle_wfd()
2216 if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0) in channel_handle_wfd()
2217 fatal_fr(r, "channel %i: get datagram", c->self); in channel_handle_wfd()
2220 buf = data = sshbuf_mutable_ptr(c->output); in channel_handle_wfd()
2221 dlen = sshbuf_len(c->output); in channel_handle_wfd()
2224 if (c->datagram) { in channel_handle_wfd()
2226 len = write(c->wfd, buf, dlen); in channel_handle_wfd()
2228 if (len == -1 && (errno == EINTR || errno == EAGAIN || in channel_handle_wfd()
2238 if (c->wfd_isatty) in channel_handle_wfd()
2242 len = write(c->wfd, buf, dlen); in channel_handle_wfd()
2243 if (len == -1 && in channel_handle_wfd()
2248 if (c->type != SSH_CHANNEL_OPEN) { in channel_handle_wfd()
2249 debug2("channel %d: not open", c->self); in channel_handle_wfd()
2251 return -1; in channel_handle_wfd()
2255 return -1; in channel_handle_wfd()
2259 if (c->isatty && dlen >= 1 && buf[0] != '\r') { in channel_handle_wfd()
2260 if (tcgetattr(c->wfd, &tio) == 0 && in channel_handle_wfd()
2266 * (4 byte channel id + buf) in channel_handle_wfd()
2270 fatal_fr(r, "channel %i: ignore", c->self); in channel_handle_wfd()
2274 if ((r = sshbuf_consume(c->output, len)) != 0) in channel_handle_wfd()
2275 fatal_fr(r, "channel %i: consume", c->self); in channel_handle_wfd()
2277 c->local_consumed += olen - sshbuf_len(c->output); in channel_handle_wfd()
2283 channel_handle_efd_write(struct ssh *ssh, Channel *c) in channel_handle_efd_write()
2288 if ((c->io_ready & SSH_CHAN_IO_EFD_W) == 0) in channel_handle_efd_write()
2290 if (sshbuf_len(c->extended) == 0) in channel_handle_efd_write()
2293 len = write(c->efd, sshbuf_ptr(c->extended), in channel_handle_efd_write()
2294 sshbuf_len(c->extended)); in channel_handle_efd_write()
2295 debug2("channel %d: written %zd to efd %d", c->self, len, c->efd); in channel_handle_efd_write()
2296 if (len == -1 && (errno == EINTR || errno == EAGAIN || in channel_handle_efd_write()
2300 debug2("channel %d: closing write-efd %d", c->self, c->efd); in channel_handle_efd_write()
2301 channel_close_fd(ssh, c, &c->efd); in channel_handle_efd_write()
2303 if ((r = sshbuf_consume(c->extended, len)) != 0) in channel_handle_efd_write()
2304 fatal_fr(r, "channel %i: consume", c->self); in channel_handle_efd_write()
2305 c->local_consumed += len; in channel_handle_efd_write()
2312 channel_handle_efd_read(struct ssh *ssh, Channel *c) in channel_handle_efd_read()
2318 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; in channel_handle_efd_read()
2320 if (!force && (c->io_ready & SSH_CHAN_IO_EFD_R) == 0) in channel_handle_efd_read()
2323 len = read(c->efd, buf, sizeof(buf)); in channel_handle_efd_read()
2324 debug2("channel %d: read %zd from efd %d", c->self, len, c->efd); in channel_handle_efd_read()
2325 if (len == -1 && (errno == EINTR || ((errno == EAGAIN || in channel_handle_efd_read()
2329 debug2("channel %d: closing read-efd %d", c->self, c->efd); in channel_handle_efd_read()
2330 channel_close_fd(ssh, c, &c->efd); in channel_handle_efd_read()
2334 if (c->extended_usage == CHAN_EXTENDED_IGNORE) in channel_handle_efd_read()
2335 debug3("channel %d: discard efd", c->self); in channel_handle_efd_read()
2336 else if ((r = sshbuf_put(c->extended, buf, len)) != 0) in channel_handle_efd_read()
2337 fatal_fr(r, "channel %i: append", c->self); in channel_handle_efd_read()
2342 channel_handle_efd(struct ssh *ssh, Channel *c) in channel_handle_efd()
2344 if (c->efd == -1) in channel_handle_efd()
2349 if (c->extended_usage == CHAN_EXTENDED_WRITE) in channel_handle_efd()
2351 else if (c->extended_usage == CHAN_EXTENDED_READ || in channel_handle_efd()
2352 c->extended_usage == CHAN_EXTENDED_IGNORE) in channel_handle_efd()
2359 channel_check_window(struct ssh *ssh, Channel *c) in channel_check_window()
2363 if (c->type == SSH_CHANNEL_OPEN && in channel_check_window()
2364 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && in channel_check_window()
2365 ((c->local_window_max - c->local_window > in channel_check_window()
2366 c->local_maxpacket*3) || in channel_check_window()
2367 c->local_window < c->local_window_max/2) && in channel_check_window()
2368 c->local_consumed > 0) { in channel_check_window()
2369 if (!c->have_remote_id) in channel_check_window()
2370 fatal_f("channel %d: no remote id", c->self); in channel_check_window()
2373 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_check_window()
2374 (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 || in channel_check_window()
2376 fatal_fr(r, "channel %i", c->self); in channel_check_window()
2378 debug2("channel %d: window %d sent adjust %d", c->self, in channel_check_window()
2379 c->local_window, c->local_consumed); in channel_check_window()
2380 c->local_window += c->local_consumed; in channel_check_window()
2381 c->local_consumed = 0; in channel_check_window()
2387 channel_post_open(struct ssh *ssh, Channel *c) in channel_post_open()
2396 read_mux(struct ssh *ssh, Channel *c, u_int need) in read_mux()
2403 if (sshbuf_len(c->input) < need) { in read_mux()
2404 rlen = need - sshbuf_len(c->input); in read_mux()
2405 len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF)); in read_mux()
2406 if (len == -1 && (errno == EINTR || errno == EAGAIN)) in read_mux()
2407 return sshbuf_len(c->input); in read_mux()
2409 debug2("channel %d: ctl read<=0 rfd %d len %zd", in read_mux()
2410 c->self, c->rfd, len); in read_mux()
2413 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) in read_mux()
2414 fatal_fr(r, "channel %i: append", c->self); in read_mux()
2416 return sshbuf_len(c->input); in read_mux()
2420 channel_post_mux_client_read(struct ssh *ssh, Channel *c) in channel_post_mux_client_read()
2424 if ((c->io_ready & SSH_CHAN_IO_RFD) == 0) in channel_post_mux_client_read()
2426 if (c->istate != CHAN_INPUT_OPEN && c->istate != CHAN_INPUT_WAIT_DRAIN) in channel_post_mux_client_read()
2428 if (c->mux_pause) in channel_post_mux_client_read()
2438 need = PEEK_U32(sshbuf_ptr(c->input)); in channel_post_mux_client_read()
2441 debug2("channel %d: packet too big %u > %u", in channel_post_mux_client_read()
2442 c->self, CHANNEL_MUX_MAX_PACKET, need); in channel_post_mux_client_read()
2448 if (c->mux_rcb(ssh, c) != 0) { in channel_post_mux_client_read()
2449 debug("channel %d: mux_rcb failed", c->self); in channel_post_mux_client_read()
2456 channel_post_mux_client_write(struct ssh *ssh, Channel *c) in channel_post_mux_client_write()
2461 if ((c->io_ready & SSH_CHAN_IO_WFD) == 0) in channel_post_mux_client_write()
2463 if (sshbuf_len(c->output) == 0) in channel_post_mux_client_write()
2466 len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output)); in channel_post_mux_client_write()
2467 if (len == -1 && (errno == EINTR || errno == EAGAIN)) in channel_post_mux_client_write()
2473 if ((r = sshbuf_consume(c->output, len)) != 0) in channel_post_mux_client_write()
2474 fatal_fr(r, "channel %i: consume", c->self); in channel_post_mux_client_write()
2478 channel_post_mux_client(struct ssh *ssh, Channel *c) in channel_post_mux_client()
2485 channel_post_mux_listener(struct ssh *ssh, Channel *c) in channel_post_mux_listener()
2487 Channel *nc; in channel_post_mux_listener()
2494 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_mux_listener()
2504 if ((newsock = accept(c->sock, (struct sockaddr*)&addr, in channel_post_mux_listener()
2505 &addrlen)) == -1) { in channel_post_mux_listener()
2508 c->notbefore = monotime() + 1; in channel_post_mux_listener()
2512 if (getpeereid(newsock, &euid, &egid) == -1) { in channel_post_mux_listener()
2523 nc = channel_new(ssh, "mux-control", SSH_CHANNEL_MUX_CLIENT, in channel_post_mux_listener()
2524 newsock, newsock, -1, c->local_window_max, in channel_post_mux_listener()
2525 c->local_maxpacket, 0, "mux-control", 1); in channel_post_mux_listener()
2526 nc->mux_rcb = c->mux_rcb; in channel_post_mux_listener()
2527 debug3_f("new mux channel %d fd %d", nc->self, nc->sock); in channel_post_mux_listener()
2529 nc->mux_rcb(ssh, nc); in channel_post_mux_listener()
2531 nc->flags |= CHAN_LOCAL; in channel_post_mux_listener()
2570 sc->channel_pre = pre; in channel_handler_init()
2571 sc->channel_post = post; in channel_handler_init()
2576 channel_garbage_collect(struct ssh *ssh, Channel *c) in channel_garbage_collect()
2580 if (c->detach_user != NULL) { in channel_garbage_collect()
2581 if (!chan_is_dead(ssh, c, c->detach_close)) in channel_garbage_collect()
2584 debug2("channel %d: gc: notify user", c->self); in channel_garbage_collect()
2585 c->detach_user(ssh, c->self, 0, NULL); in channel_garbage_collect()
2587 if (c->detach_user != NULL) in channel_garbage_collect()
2589 debug2("channel %d: gc: user detached", c->self); in channel_garbage_collect()
2593 debug2("channel %d: garbage collecting", c->self); in channel_garbage_collect()
2602 struct ssh_channels *sc = ssh->chanctxt; in channel_handler()
2603 chan_fn **ftab = table == CHAN_PRE ? sc->channel_pre : sc->channel_post; in channel_handler()
2605 Channel *c; in channel_handler()
2609 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { in channel_handler()
2610 c = sc->channels[i]; in channel_handler()
2614 if (ssh_packet_is_rekeying(ssh) && c->type != SSH_CHANNEL_OPEN) in channel_handler()
2616 if (c->delayed) { in channel_handler()
2618 c->delayed = 0; in channel_handler()
2622 if (ftab[c->type] != NULL) { in channel_handler()
2623 if (table == CHAN_PRE && c->type == SSH_CHANNEL_OPEN && in channel_handler()
2626 /* channel closed for inactivity */ in channel_handler()
2627 verbose("channel %d: closing after %u seconds " in channel_handler()
2628 "of inactivity", c->self, in channel_handler()
2629 c->inactive_deadline); in channel_handler()
2631 } else if (c->notbefore <= now) { in channel_handler()
2633 (*ftab[c->type])(ssh, c); in channel_handler()
2636 c->type == SSH_CHANNEL_OPEN && in channel_handler()
2643 * Arrange for poll() wakeup when channel pause in channel_handler()
2647 c->notbefore); in channel_handler()
2657 * the network-input but need to be completed before IO event setup, e.g.
2663 struct ssh_channels *sc = ssh->chanctxt; in channel_before_prepare_io()
2664 Channel *c; in channel_before_prepare_io()
2667 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { in channel_before_prepare_io()
2668 c = sc->channels[i]; in channel_before_prepare_io()
2671 if (c->type == SSH_CHANNEL_RDYNAMIC_OPEN) in channel_before_prepare_io()
2677 dump_channel_poll(const char *func, const char *what, Channel *c, in dump_channel_poll()
2681 debug3("%s: channel %d: %s r%d w%d e%d s%d c->pfds [ %d %d %d %d ] " in dump_channel_poll()
2683 "pfd.ev 0x%02x pfd.rev 0x%02x", func, c->self, what, in dump_channel_poll()
2684 c->rfd, c->wfd, c->efd, c->sock, in dump_channel_poll()
2685 c->pfds[0], c->pfds[1], c->pfds[2], c->pfds[3], in dump_channel_poll()
2686 c->io_want, c->io_ready, in dump_channel_poll()
2687 pollfd_offset, pfd->fd, pfd->events, pfd->revents); in dump_channel_poll()
2691 /* Prepare pollfd entries for a single channel */
2693 channel_prepare_pollfd(Channel *c, u_int *next_pollfd, in channel_prepare_pollfd()
2702 fatal_f("channel %d: bad pfd offset %u (max %u)", in channel_prepare_pollfd()
2703 c->self, p, npfd); in channel_prepare_pollfd()
2705 c->pfds[0] = c->pfds[1] = c->pfds[2] = c->pfds[3] = -1; in channel_prepare_pollfd()
2707 * prepare c->rfd in channel_prepare_pollfd()
2709 * This is a special case, since c->rfd might be the same as in channel_prepare_pollfd()
2710 * c->wfd, c->efd and/or c->sock. Handle those here if they want in channel_prepare_pollfd()
2713 if (c->rfd != -1) { in channel_prepare_pollfd()
2715 if ((c->io_want & SSH_CHAN_IO_RFD) != 0) in channel_prepare_pollfd()
2718 if (c->wfd == c->rfd) { in channel_prepare_pollfd()
2719 if ((c->io_want & SSH_CHAN_IO_WFD) != 0) in channel_prepare_pollfd()
2723 if (c->efd == c->rfd) { in channel_prepare_pollfd()
2724 if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) in channel_prepare_pollfd()
2726 if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) in channel_prepare_pollfd()
2730 if (c->sock == c->rfd) { in channel_prepare_pollfd()
2731 if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) in channel_prepare_pollfd()
2733 if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) in channel_prepare_pollfd()
2738 c->pfds[0] = p; in channel_prepare_pollfd()
2739 pfd[p].fd = c->rfd; in channel_prepare_pollfd()
2745 /* prepare c->wfd if wanting IO and not already handled above */ in channel_prepare_pollfd()
2746 if (c->wfd != -1 && c->rfd != c->wfd) { in channel_prepare_pollfd()
2748 if ((c->io_want & SSH_CHAN_IO_WFD)) in channel_prepare_pollfd()
2752 c->pfds[1] = p; in channel_prepare_pollfd()
2753 pfd[p].fd = c->wfd; in channel_prepare_pollfd()
2759 /* prepare c->efd if wanting IO and not already handled above */ in channel_prepare_pollfd()
2760 if (c->efd != -1 && c->rfd != c->efd) { in channel_prepare_pollfd()
2762 if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) in channel_prepare_pollfd()
2764 if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) in channel_prepare_pollfd()
2768 c->pfds[2] = p; in channel_prepare_pollfd()
2769 pfd[p].fd = c->efd; in channel_prepare_pollfd()
2775 /* prepare c->sock if wanting IO and not already handled above */ in channel_prepare_pollfd()
2776 if (c->sock != -1 && c->rfd != c->sock) { in channel_prepare_pollfd()
2778 if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) in channel_prepare_pollfd()
2780 if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) in channel_prepare_pollfd()
2784 c->pfds[3] = p; in channel_prepare_pollfd()
2785 pfd[p].fd = c->sock; in channel_prepare_pollfd()
2799 struct ssh_channels *sc = ssh->chanctxt; in channel_prepare_poll()
2802 channel_before_prepare_io(ssh); /* might create a new channel */ in channel_prepare_poll()
2804 for (i = 0; i < sc->channels_alloc; i++) { in channel_prepare_poll()
2805 if (sc->channels[i] == NULL) in channel_prepare_poll()
2807 sc->channels[i]->io_want = sc->channels[i]->io_ready = 0; in channel_prepare_poll()
2809 /* Allocate 4x pollfd for each channel (rfd, wfd, efd, sock) */ in channel_prepare_poll()
2810 if (sc->channels_alloc >= (INT_MAX / 4) - npfd_reserved) in channel_prepare_poll()
2812 npfd += sc->channels_alloc * 4; in channel_prepare_poll()
2819 oalloc = sc->channels_alloc; in channel_prepare_poll()
2823 if (oalloc != sc->channels_alloc) { in channel_prepare_poll()
2826 "(was %u, now %u)", oalloc, sc->channels_alloc); in channel_prepare_poll()
2831 for (i = 0; i < sc->channels_alloc; i++) in channel_prepare_poll()
2832 channel_prepare_pollfd(sc->channels[i], &p, *pfdp, npfd); in channel_prepare_poll()
2837 fd_ready(Channel *c, int p, struct pollfd *pfds, u_int npfd, int fd, in fd_ready()
2842 if (fd == -1) in fd_ready()
2844 if (p == -1 || (u_int)p >= npfd) in fd_ready()
2845 fatal_f("channel %d: bad pfd %d (max %u)", c->self, p, npfd); in fd_ready()
2847 if (pfd->fd != fd) { in fd_ready()
2848 fatal("channel %d: inconsistent %s fd=%d pollfd[%u].fd %d " in fd_ready()
2849 "r%d w%d e%d s%d", c->self, what, fd, p, pfd->fd, in fd_ready()
2850 c->rfd, c->wfd, c->efd, c->sock); in fd_ready()
2852 if ((pfd->revents & POLLNVAL) != 0) { in fd_ready()
2853 fatal("channel %d: invalid %s pollfd[%u].fd %d r%d w%d e%d s%d", in fd_ready()
2854 c->self, what, p, pfd->fd, c->rfd, c->wfd, c->efd, c->sock); in fd_ready()
2856 if ((pfd->revents & (revents_mask|POLLHUP|POLLERR)) != 0) in fd_ready()
2857 c->io_ready |= ready & c->io_want; in fd_ready()
2867 struct ssh_channels *sc = ssh->chanctxt; in channel_after_poll()
2870 Channel *c; in channel_after_poll()
2881 /* Convert pollfd into c->io_ready */ in channel_after_poll()
2882 for (i = 0; i < sc->channels_alloc; i++) { in channel_after_poll()
2883 c = sc->channels[i]; in channel_after_poll()
2887 if (c->rfd != -1 && c->wfd != -1 && c->rfd != c->wfd && in channel_after_poll()
2888 (c->rfd == c->efd || c->rfd == c->sock)) { in channel_after_poll()
2890 fatal_f("channel %d: unexpected fds r%d w%d e%d s%d", in channel_after_poll()
2891 c->self, c->rfd, c->wfd, c->efd, c->sock); in channel_after_poll()
2893 c->io_ready = 0; in channel_after_poll()
2895 if (c->rfd != -1 && (p = c->pfds[0]) != -1) { in channel_after_poll()
2896 fd_ready(c, p, pfd, npfd, c->rfd, in channel_after_poll()
2898 if (c->rfd == c->wfd) { in channel_after_poll()
2899 fd_ready(c, p, pfd, npfd, c->wfd, in channel_after_poll()
2902 if (c->rfd == c->efd) { in channel_after_poll()
2903 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2905 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2908 if (c->rfd == c->sock) { in channel_after_poll()
2909 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2911 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2917 if (c->wfd != -1 && c->wfd != c->rfd && in channel_after_poll()
2918 (p = c->pfds[1]) != -1) { in channel_after_poll()
2919 fd_ready(c, p, pfd, npfd, c->wfd, in channel_after_poll()
2924 if (c->efd != -1 && c->efd != c->rfd && in channel_after_poll()
2925 (p = c->pfds[2]) != -1) { in channel_after_poll()
2926 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2928 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2933 if (c->sock != -1 && c->sock != c->rfd && in channel_after_poll()
2934 (p = c->pfds[3]) != -1) { in channel_after_poll()
2935 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2937 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2946 * Enqueue data for channels with open or draining c->input.
2947 * Returns non-zero if a packet was enqueued.
2950 channel_output_poll_input_open(struct ssh *ssh, Channel *c) in channel_output_poll_input_open()
2956 if ((len = sshbuf_len(c->input)) == 0) { in channel_output_poll_input_open()
2957 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_output_poll_input_open()
2959 * input-buffer is empty and read-socket shutdown: in channel_output_poll_input_open()
2966 debug2("channel %d: " in channel_output_poll_input_open()
2968 c->self, c->efd, sshbuf_len(c->extended)); in channel_output_poll_input_open()
2975 if (!c->have_remote_id) in channel_output_poll_input_open()
2976 fatal_f("channel %d: no remote id", c->self); in channel_output_poll_input_open()
2978 if (c->datagram) { in channel_output_poll_input_open()
2980 if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0) in channel_output_poll_input_open()
2981 fatal_fr(r, "channel %i: get datagram", c->self); in channel_output_poll_input_open()
2983 * XXX this does tail-drop on the datagram queue which is in channel_output_poll_input_open()
2984 * usually suboptimal compared to head-drop. Better to have in channel_output_poll_input_open()
2987 if (plen > c->remote_window || plen > c->remote_maxpacket) { in channel_output_poll_input_open()
2988 debug("channel %d: datagram too big", c->self); in channel_output_poll_input_open()
2993 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_input_open()
2996 fatal_fr(r, "channel %i: send datagram", c->self); in channel_output_poll_input_open()
2997 c->remote_window -= plen; in channel_output_poll_input_open()
3002 if (len > c->remote_window) in channel_output_poll_input_open()
3003 len = c->remote_window; in channel_output_poll_input_open()
3004 if (len > c->remote_maxpacket) in channel_output_poll_input_open()
3005 len = c->remote_maxpacket; in channel_output_poll_input_open()
3009 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_input_open()
3010 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 || in channel_output_poll_input_open()
3012 fatal_fr(r, "channel %i: send data", c->self); in channel_output_poll_input_open()
3013 if ((r = sshbuf_consume(c->input, len)) != 0) in channel_output_poll_input_open()
3014 fatal_fr(r, "channel %i: consume", c->self); in channel_output_poll_input_open()
3015 c->remote_window -= len; in channel_output_poll_input_open()
3020 * Enqueue data for channels with open c->extended in read mode.
3021 * Returns non-zero if a packet was enqueued.
3024 channel_output_poll_extended_read(struct ssh *ssh, Channel *c) in channel_output_poll_extended_read()
3029 if ((len = sshbuf_len(c->extended)) == 0) in channel_output_poll_extended_read()
3032 debug2("channel %d: rwin %u elen %zu euse %d", c->self, in channel_output_poll_extended_read()
3033 c->remote_window, sshbuf_len(c->extended), c->extended_usage); in channel_output_poll_extended_read()
3034 if (len > c->remote_window) in channel_output_poll_extended_read()
3035 len = c->remote_window; in channel_output_poll_extended_read()
3036 if (len > c->remote_maxpacket) in channel_output_poll_extended_read()
3037 len = c->remote_maxpacket; in channel_output_poll_extended_read()
3040 if (!c->have_remote_id) in channel_output_poll_extended_read()
3041 fatal_f("channel %d: no remote id", c->self); in channel_output_poll_extended_read()
3043 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_extended_read()
3045 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 || in channel_output_poll_extended_read()
3047 fatal_fr(r, "channel %i: data", c->self); in channel_output_poll_extended_read()
3048 if ((r = sshbuf_consume(c->extended, len)) != 0) in channel_output_poll_extended_read()
3049 fatal_fr(r, "channel %i: consume", c->self); in channel_output_poll_extended_read()
3050 c->remote_window -= len; in channel_output_poll_extended_read()
3051 debug2("channel %d: sent ext data %zu", c->self, len); in channel_output_poll_extended_read()
3057 * Returns non-zero if data was enqueued.
3062 struct ssh_channels *sc = ssh->chanctxt; in channel_output_poll()
3063 Channel *c; in channel_output_poll()
3067 for (i = 0; i < sc->channels_alloc; i++) { in channel_output_poll()
3068 c = sc->channels[i]; in channel_output_poll()
3076 if (c->type != SSH_CHANNEL_OPEN) in channel_output_poll()
3078 if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { in channel_output_poll()
3080 debug3("channel %d: will not send data after close", in channel_output_poll()
3081 c->self); in channel_output_poll()
3085 /* Get the amount of buffered data for this channel. */ in channel_output_poll()
3086 if (c->istate == CHAN_INPUT_OPEN || in channel_output_poll()
3087 c->istate == CHAN_INPUT_WAIT_DRAIN) in channel_output_poll()
3090 if (!(c->flags & CHAN_EOF_SENT) && in channel_output_poll()
3091 c->extended_usage == CHAN_EXTENDED_READ) in channel_output_poll()
3097 /* -- mux proxy support */
3100 * When multiplexing channel messages for mux clients we have to deal
3105 * - We forward all messages (mostly) unmodified to the server.
3106 * - However, in order to route messages from upstream to the correct
3107 * downstream client, we have to replace the channel IDs used by the
3108 * mux clients with a unique channel ID because the mux clients might
3109 * use conflicting channel IDs.
3110 * - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and
3112 * SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID
3113 * with the newly allocated channel ID.
3115 * channels and processed by channel_proxy_upstream(). The local channel ID
3123 * channel. E.g. client_request_forwarded_tcpip() needs to figure
3125 * specific downstream client based on the listen-address/port.
3126 * 6) Agent and X11-Forwarding have a similar problem and are currently
3127 * not supported as the matching session/channel cannot be identified
3133 * channel callback fired on read from mux client, creates
3134 * SSH_CHANNEL_MUX_PROXY channels and translates channel IDs
3135 * on channel creation.
3138 channel_proxy_downstream(struct ssh *ssh, Channel *downstream) in channel_proxy_downstream()
3140 Channel *c = NULL; in channel_proxy_downstream()
3146 int ret = -1, r; in channel_proxy_downstream()
3149 /* sshbuf_dump(downstream->input, stderr); */ in channel_proxy_downstream()
3150 if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have)) in channel_proxy_downstream()
3153 return -1; in channel_proxy_downstream()
3157 return -1; in channel_proxy_downstream()
3162 have -= 2; in channel_proxy_downstream()
3164 debug3_f("channel %u: down->up: type %u", in channel_proxy_downstream()
3165 downstream->self, type); in channel_proxy_downstream()
3179 c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY, in channel_proxy_downstream()
3180 -1, -1, -1, 0, 0, 0, ctype, 1); in channel_proxy_downstream()
3181 c->mux_ctx = downstream; /* point to mux client */ in channel_proxy_downstream()
3182 c->mux_downstream_id = id; /* original downstream id */ in channel_proxy_downstream()
3184 (r = sshbuf_put_u32(modified, c->self)) != 0 || in channel_proxy_downstream()
3206 c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY, in channel_proxy_downstream()
3207 -1, -1, -1, 0, 0, 0, "mux-down-connect", 1); in channel_proxy_downstream()
3208 c->mux_ctx = downstream; /* point to mux client */ in channel_proxy_downstream()
3209 c->mux_downstream_id = id; in channel_proxy_downstream()
3210 c->remote_id = remote_id; in channel_proxy_downstream()
3211 c->have_remote_id = 1; in channel_proxy_downstream()
3213 (r = sshbuf_put_u32(modified, c->self)) != 0 || in channel_proxy_downstream()
3229 if (strcmp(ctype, "tcpip-forward") != 0) { in channel_proxy_downstream()
3240 error_f("tcpip-forward for %s: bad port %u", in channel_proxy_downstream()
3246 -1, listen_host, NULL, (int)listen_port, downstream); in channel_proxy_downstream()
3253 if (c->flags & CHAN_CLOSE_RCVD) in channel_proxy_downstream()
3256 c->flags |= CHAN_CLOSE_SENT; in channel_proxy_downstream()
3285 * receive packets from upstream server and de-multiplex packets
3287 * implemented as a helper for channel input handlers,
3288 * replaces local (proxy) channel ID with downstream channel ID.
3291 channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh) in channel_proxy_upstream()
3294 Channel *downstream; in channel_proxy_upstream()
3301 * need to forward the packets to the mux client. In this case we in channel_proxy_upstream()
3302 * restore the original channel id and keep track of CLOSE messages, in channel_proxy_upstream()
3303 * so we can cleanup the channel. in channel_proxy_upstream()
3305 if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY) in channel_proxy_upstream()
3307 if ((downstream = c->mux_ctx) == NULL) in channel_proxy_upstream()
3322 debug2_f("channel %u: unsupported type %u", c->self, type); in channel_proxy_upstream()
3338 (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 || in channel_proxy_upstream()
3340 (r = sshbuf_put_stringb(downstream->output, b)) != 0) { in channel_proxy_upstream()
3346 debug3_f("channel %u: up->down: type %u", c->self, type); in channel_proxy_upstream()
3353 c->remote_id = PEEK_U32(cp); in channel_proxy_upstream()
3354 c->have_remote_id = 1; in channel_proxy_upstream()
3358 if (c->flags & CHAN_CLOSE_SENT) in channel_proxy_upstream()
3361 c->flags |= CHAN_CLOSE_RCVD; in channel_proxy_upstream()
3368 /* -- protocol input */
3370 /* Parse a channel ID from the current packet */
3382 error_r(r, "%s: bad channel id %u", where, id); in channel_parse_id()
3383 ssh_packet_disconnect(ssh, "Invalid %s channel id", what); in channel_parse_id()
3388 /* Lookup a channel from an ID in the current packet */
3389 static Channel *
3393 Channel *c; in channel_from_packet_id()
3397 "%s packet referred to nonexistent channel %d", what, id); in channel_from_packet_id()
3407 Channel *c = channel_from_packet_id(ssh, __func__, "data"); in channel_input_data()
3413 /* Ignore any data for non-open channels (might happen on close) */ in channel_input_data()
3414 if (c->type != SSH_CHANNEL_OPEN && in channel_input_data()
3415 c->type != SSH_CHANNEL_RDYNAMIC_OPEN && in channel_input_data()
3416 c->type != SSH_CHANNEL_RDYNAMIC_FINISH && in channel_input_data()
3417 c->type != SSH_CHANNEL_X11_OPEN) in channel_input_data()
3423 fatal_fr(r, "channel %i: get data", c->self); in channel_input_data()
3426 if (c->datagram) in channel_input_data()
3434 if (c->ostate != CHAN_OUTPUT_OPEN) { in channel_input_data()
3435 c->local_window -= win_len; in channel_input_data()
3436 c->local_consumed += win_len; in channel_input_data()
3440 if (win_len > c->local_maxpacket) { in channel_input_data()
3441 logit("channel %d: rcvd big packet %zu, maxpack %u", in channel_input_data()
3442 c->self, win_len, c->local_maxpacket); in channel_input_data()
3445 if (win_len > c->local_window) { in channel_input_data()
3446 c->local_window_exceeded += win_len - c->local_window; in channel_input_data()
3447 logit("channel %d: rcvd too much data %zu, win %u/%u " in channel_input_data()
3448 "(excess %u)", c->self, win_len, c->local_window, in channel_input_data()
3449 c->local_window_max, c->local_window_exceeded); in channel_input_data()
3450 c->local_window = 0; in channel_input_data()
3452 if (c->local_window_exceeded > (c->local_window_max / 10)) { in channel_input_data()
3453 ssh_packet_disconnect(ssh, "channel %d: peer ignored " in channel_input_data()
3454 "channel window", c->self); in channel_input_data()
3457 c->local_window -= win_len; in channel_input_data()
3458 c->local_window_exceeded = 0; in channel_input_data()
3461 if (c->datagram) { in channel_input_data()
3462 if ((r = sshbuf_put_string(c->output, data, data_len)) != 0) in channel_input_data()
3463 fatal_fr(r, "channel %i: append datagram", c->self); in channel_input_data()
3464 } else if ((r = sshbuf_put(c->output, data, data_len)) != 0) in channel_input_data()
3465 fatal_fr(r, "channel %i: append data", c->self); in channel_input_data()
3476 Channel *c = channel_from_packet_id(ssh, __func__, "extended data"); in channel_input_extended_data()
3481 if (c->type != SSH_CHANNEL_OPEN) { in channel_input_extended_data()
3482 logit("channel %d: ext data for non open", c->self); in channel_input_extended_data()
3485 if (c->flags & CHAN_EOF_RCVD) { in channel_input_extended_data()
3486 if (ssh->compat & SSH_BUG_EXTEOF) in channel_input_extended_data()
3487 debug("channel %d: accepting ext data after eof", in channel_input_extended_data()
3488 c->self); in channel_input_extended_data()
3491 "after EOF on channel %d.", c->self); in channel_input_extended_data()
3498 if (c->efd == -1 || in channel_input_extended_data()
3499 c->extended_usage != CHAN_EXTENDED_WRITE || in channel_input_extended_data()
3501 logit("channel %d: bad ext data", c->self); in channel_input_extended_data()
3510 if (data_len > c->local_window) { in channel_input_extended_data()
3511 logit("channel %d: rcvd too much extended_data %zu, win %u", in channel_input_extended_data()
3512 c->self, data_len, c->local_window); in channel_input_extended_data()
3515 debug2("channel %d: rcvd ext data %zu", c->self, data_len); in channel_input_extended_data()
3517 if ((r = sshbuf_put(c->extended, data, data_len)) != 0) in channel_input_extended_data()
3519 c->local_window -= data_len; in channel_input_extended_data()
3526 Channel *c = channel_from_packet_id(ssh, __func__, "ieof"); in channel_input_ieof()
3539 if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { in channel_input_ieof()
3540 debug("channel %d: FORCE input drain", c->self); in channel_input_ieof()
3541 c->istate = CHAN_INPUT_WAIT_DRAIN; in channel_input_ieof()
3542 if (sshbuf_len(c->input) == 0) in channel_input_ieof()
3551 Channel *c = channel_from_packet_id(ssh, __func__, "oclose"); in channel_input_oclose()
3567 Channel *c = channel_from_packet_id(ssh, __func__, "open confirmation"); in channel_input_open_confirmation()
3573 if (c->type != SSH_CHANNEL_OPENING) in channel_input_open_confirmation()
3575 "non-opening channel %d.", c->self); in channel_input_open_confirmation()
3577 * Record the remote channel number and mark that the channel in channel_input_open_confirmation()
3580 if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 || in channel_input_open_confirmation()
3588 c->have_remote_id = 1; in channel_input_open_confirmation()
3589 c->remote_window = remote_window; in channel_input_open_confirmation()
3590 c->remote_maxpacket = remote_maxpacket; in channel_input_open_confirmation()
3591 c->type = SSH_CHANNEL_OPEN; in channel_input_open_confirmation()
3592 if (c->open_confirm) { in channel_input_open_confirmation()
3593 debug2_f("channel %d: callback start", c->self); in channel_input_open_confirmation()
3594 c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx); in channel_input_open_confirmation()
3595 debug2_f("channel %d: callback done", c->self); in channel_input_open_confirmation()
3598 debug2("channel %d: open confirm rwindow %u rmax %u", c->self, in channel_input_open_confirmation()
3599 c->remote_window, c->remote_maxpacket); in channel_input_open_confirmation()
3612 return "unknown channel type"; in reason2txt()
3622 Channel *c = channel_from_packet_id(ssh, __func__, "open failure"); in channel_input_open_failure()
3629 if (c->type != SSH_CHANNEL_OPENING) in channel_input_open_failure()
3631 "non-opening channel %d.", c->self); in channel_input_open_failure()
3643 logit("channel %d: open failed: %s%s%s", c->self, in channel_input_open_failure()
3646 if (c->open_confirm) { in channel_input_open_failure()
3647 debug2_f("channel %d: callback start", c->self); in channel_input_open_failure()
3648 c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx); in channel_input_open_failure()
3649 debug2_f("channel %d: callback done", c->self); in channel_input_open_failure()
3651 /* Schedule the channel for cleanup/deletion. */ in channel_input_open_failure()
3660 Channel *c; in channel_input_window_adjust()
3666 logit("Received window adjust for non-open channel %d.", id); in channel_input_window_adjust()
3677 debug2("channel %d: rcvd adjust %u", c->self, adjust); in channel_input_window_adjust()
3678 if ((new_rwin = c->remote_window + adjust) < c->remote_window) { in channel_input_window_adjust()
3679 fatal("channel %d: adjust %u overflows remote window %u", in channel_input_window_adjust()
3680 c->self, adjust, c->remote_window); in channel_input_window_adjust()
3682 c->remote_window = new_rwin; in channel_input_window_adjust()
3690 Channel *c; in channel_input_status_confirm()
3706 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) in channel_input_status_confirm()
3708 cc->cb(ssh, type, c, cc->ctx); in channel_input_status_confirm()
3709 TAILQ_REMOVE(&c->status_confirms, cc, entry); in channel_input_status_confirm()
3714 /* -- tcp forwarding */
3719 ssh->chanctxt->IPv4or6 = af; in channel_set_af()
3724 * Determine whether or not a port forward listens to loopback, the
3731 * Special-case listen_addrs are:
3733 * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
3734 * "" (empty string), "*" -> wildcard v4/v6
3735 * "localhost" -> loopback v4/v6
3736 * "127.0.0.1" / "::1" -> accepted even if gateway_ports isn't set
3747 if (fwd_opts->gateway_ports) in channel_fwd_bind_addr()
3749 } else if (fwd_opts->gateway_ports || is_client) { in channel_fwd_bind_addr()
3750 if (((ssh->compat & SSH_OLD_FORWARD_ADDR) && in channel_fwd_bind_addr()
3753 (!is_client && fwd_opts->gateway_ports == 1)) { in channel_fwd_bind_addr()
3794 struct Forward *fwd, int *allocated_listen_port, in channel_setup_fwd_listener_tcpip()
3797 Channel *c; in channel_setup_fwd_listener_tcpip()
3806 if (is_client && fwd->connect_path != NULL) { in channel_setup_fwd_listener_tcpip()
3807 host = fwd->connect_path; in channel_setup_fwd_listener_tcpip()
3810 fwd->listen_host : fwd->connect_host; in channel_setup_fwd_listener_tcpip()
3812 error("No forward host name."); in channel_setup_fwd_listener_tcpip()
3816 error("Forward host name too long."); in channel_setup_fwd_listener_tcpip()
3822 addr = channel_fwd_bind_addr(ssh, fwd->listen_host, &wildcard, in channel_setup_fwd_listener_tcpip()
3832 hints.ai_family = ssh->chanctxt->IPv4or6; in channel_setup_fwd_listener_tcpip()
3835 snprintf(strport, sizeof strport, "%d", fwd->listen_port); in channel_setup_fwd_listener_tcpip()
3849 for (ai = aitop; ai; ai = ai->ai_next) { in channel_setup_fwd_listener_tcpip()
3850 switch (ai->ai_family) { in channel_setup_fwd_listener_tcpip()
3852 lport_p = &((struct sockaddr_in *)ai->ai_addr)-> in channel_setup_fwd_listener_tcpip()
3856 lport_p = &((struct sockaddr_in6 *)ai->ai_addr)-> in channel_setup_fwd_listener_tcpip()
3863 * If allocating a port for -R forwards, then use the in channel_setup_fwd_listener_tcpip()
3867 fwd->listen_port == 0 && allocated_listen_port != NULL && in channel_setup_fwd_listener_tcpip()
3871 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), in channel_setup_fwd_listener_tcpip()
3878 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); in channel_setup_fwd_listener_tcpip()
3879 if (sock == -1) { in channel_setup_fwd_listener_tcpip()
3887 if (ai->ai_family == AF_INET6) in channel_setup_fwd_listener_tcpip()
3894 if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in channel_setup_fwd_listener_tcpip()
3899 if (!ai->ai_next) in channel_setup_fwd_listener_tcpip()
3910 if (listen(sock, SSH_LISTEN_BACKLOG) == -1) { in channel_setup_fwd_listener_tcpip()
3918 * fwd->listen_port == 0 requests a dynamically allocated port - in channel_setup_fwd_listener_tcpip()
3922 fwd->listen_port == 0 && in channel_setup_fwd_listener_tcpip()
3930 /* Allocate a channel number for the socket. */ in channel_setup_fwd_listener_tcpip()
3931 c = channel_new(ssh, "port-listener", type, sock, sock, -1, in channel_setup_fwd_listener_tcpip()
3934 c->path = xstrdup(host); in channel_setup_fwd_listener_tcpip()
3935 c->host_port = fwd->connect_port; in channel_setup_fwd_listener_tcpip()
3936 c->listening_addr = addr == NULL ? NULL : xstrdup(addr); in channel_setup_fwd_listener_tcpip()
3937 if (fwd->listen_port == 0 && allocated_listen_port != NULL && in channel_setup_fwd_listener_tcpip()
3938 !(ssh->compat & SSH_BUG_DYNAMIC_RPORT)) in channel_setup_fwd_listener_tcpip()
3939 c->listening_port = *allocated_listen_port; in channel_setup_fwd_listener_tcpip()
3941 c->listening_port = fwd->listen_port; in channel_setup_fwd_listener_tcpip()
3945 error_f("cannot listen to port: %d", fwd->listen_port); in channel_setup_fwd_listener_tcpip()
3952 struct Forward *fwd, struct ForwardOptions *fwd_opts) in channel_setup_fwd_listener_streamlocal()
3956 Channel *c; in channel_setup_fwd_listener_streamlocal()
3962 if (fwd->connect_path != NULL) { in channel_setup_fwd_listener_streamlocal()
3963 if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) { in channel_setup_fwd_listener_streamlocal()
3965 fwd->connect_path); in channel_setup_fwd_listener_streamlocal()
3968 path = fwd->connect_path; in channel_setup_fwd_listener_streamlocal()
3971 if (fwd->connect_host == NULL) { in channel_setup_fwd_listener_streamlocal()
3972 error("No forward host name."); in channel_setup_fwd_listener_streamlocal()
3975 if (strlen(fwd->connect_host) >= NI_MAXHOST) { in channel_setup_fwd_listener_streamlocal()
3976 error("Forward host name too long."); in channel_setup_fwd_listener_streamlocal()
3979 path = fwd->connect_host; in channel_setup_fwd_listener_streamlocal()
3980 port = fwd->connect_port; in channel_setup_fwd_listener_streamlocal()
3984 path = fwd->listen_path; in channel_setup_fwd_listener_streamlocal()
3988 error_f("unexpected channel type %d", type); in channel_setup_fwd_listener_streamlocal()
3992 if (fwd->listen_path == NULL) { in channel_setup_fwd_listener_streamlocal()
3993 error("No forward path name."); in channel_setup_fwd_listener_streamlocal()
3996 if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) { in channel_setup_fwd_listener_streamlocal()
3997 error("Local listening path too long: %s", fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4001 debug3_f("type %d path %s", type, fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4004 omask = umask(fwd_opts->streamlocal_bind_mask); in channel_setup_fwd_listener_streamlocal()
4005 sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG, in channel_setup_fwd_listener_streamlocal()
4006 fwd_opts->streamlocal_bind_unlink); in channel_setup_fwd_listener_streamlocal()
4011 debug("Local forwarding listening on path %s.", fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4013 /* Allocate a channel number for the socket. */ in channel_setup_fwd_listener_streamlocal()
4014 c = channel_new(ssh, "unix-listener", type, sock, sock, -1, in channel_setup_fwd_listener_streamlocal()
4017 c->path = xstrdup(path); in channel_setup_fwd_listener_streamlocal()
4018 c->host_port = port; in channel_setup_fwd_listener_streamlocal()
4019 c->listening_port = PORT_STREAMLOCAL; in channel_setup_fwd_listener_streamlocal()
4020 c->listening_addr = xstrdup(fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4031 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_rport_listener_tcpip()
4032 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_rport_listener_tcpip()
4033 if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER) in channel_cancel_rport_listener_tcpip()
4035 if (strcmp(c->path, host) == 0 && c->listening_port == port) { in channel_cancel_rport_listener_tcpip()
4036 debug2_f("close channel %d", i); in channel_cancel_rport_listener_tcpip()
4051 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_rport_listener_streamlocal()
4052 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_rport_listener_streamlocal()
4053 if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER) in channel_cancel_rport_listener_streamlocal()
4055 if (c->path == NULL) in channel_cancel_rport_listener_streamlocal()
4057 if (strcmp(c->path, path) == 0) { in channel_cancel_rport_listener_streamlocal()
4058 debug2_f("close channel %d", i); in channel_cancel_rport_listener_streamlocal()
4068 channel_cancel_rport_listener(struct ssh *ssh, struct Forward *fwd) in channel_cancel_rport_listener()
4070 if (fwd->listen_path != NULL) { in channel_cancel_rport_listener()
4072 fwd->listen_path); in channel_cancel_rport_listener()
4075 fwd->listen_host, fwd->listen_port); in channel_cancel_rport_listener()
4088 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_lport_listener_tcpip()
4089 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_lport_listener_tcpip()
4090 if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER) in channel_cancel_lport_listener_tcpip()
4092 if (c->listening_port != lport) in channel_cancel_lport_listener_tcpip()
4096 if (c->host_port == 0) in channel_cancel_lport_listener_tcpip()
4099 if (c->host_port != cport) in channel_cancel_lport_listener_tcpip()
4102 if ((c->listening_addr == NULL && addr != NULL) || in channel_cancel_lport_listener_tcpip()
4103 (c->listening_addr != NULL && addr == NULL)) in channel_cancel_lport_listener_tcpip()
4105 if (addr == NULL || strcmp(c->listening_addr, addr) == 0) { in channel_cancel_lport_listener_tcpip()
4106 debug2_f("close channel %d", i); in channel_cancel_lport_listener_tcpip()
4126 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_lport_listener_streamlocal()
4127 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_lport_listener_streamlocal()
4128 if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER) in channel_cancel_lport_listener_streamlocal()
4130 if (c->listening_addr == NULL) in channel_cancel_lport_listener_streamlocal()
4132 if (strcmp(c->listening_addr, path) == 0) { in channel_cancel_lport_listener_streamlocal()
4133 debug2_f("close channel %d", i); in channel_cancel_lport_listener_streamlocal()
4144 struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts) in channel_cancel_lport_listener()
4146 if (fwd->listen_path != NULL) { in channel_cancel_lport_listener()
4148 fwd->listen_path); in channel_cancel_lport_listener()
4151 fwd->listen_host, fwd->listen_port, cport, fwd_opts); in channel_cancel_lport_listener()
4158 struct Forward *fwd, struct ForwardOptions *fwd_opts) in channel_setup_local_fwd_listener()
4160 if (fwd->listen_path != NULL) { in channel_setup_local_fwd_listener()
4171 remote_open_match(struct permission *allowed_open, struct Forward *fwd) in remote_open_match()
4177 if (fwd->listen_path != NULL) in remote_open_match()
4180 if (fwd->listen_host == NULL || allowed_open->listen_host == NULL) in remote_open_match()
4183 if (allowed_open->listen_port != FWD_PERMIT_ANY_PORT && in remote_open_match()
4184 allowed_open->listen_port != fwd->listen_port) in remote_open_match()
4187 /* Match hostnames case-insensitively */ in remote_open_match()
4188 lhost = xstrdup(fwd->listen_host); in remote_open_match()
4190 ret = match_pattern(lhost, allowed_open->listen_host); in remote_open_match()
4198 check_rfwd_permission(struct ssh *ssh, struct Forward *fwd) in check_rfwd_permission()
4200 struct ssh_channels *sc = ssh->chanctxt; in check_rfwd_permission()
4201 struct permission_set *pset = &sc->remote_perms; in check_rfwd_permission()
4207 permit = pset->all_permitted; in check_rfwd_permission()
4209 for (i = 0; i < pset->num_permitted_user; i++) { in check_rfwd_permission()
4210 perm = &pset->permitted_user[i]; in check_rfwd_permission()
4218 if (pset->num_permitted_admin > 0) { in check_rfwd_permission()
4220 for (i = 0; i < pset->num_permitted_admin; i++) { in check_rfwd_permission()
4221 perm = &pset->permitted_admin[i]; in check_rfwd_permission()
4234 channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd, in channel_setup_remote_fwd_listener()
4239 if (fwd->listen_path != NULL) in channel_setup_remote_fwd_listener()
4242 "remote forward to path \"%.100s\", " in channel_setup_remote_fwd_listener()
4245 fwd->listen_path); in channel_setup_remote_fwd_listener()
4246 else if(fwd->listen_host != NULL) in channel_setup_remote_fwd_listener()
4248 "remote forward to host %.100s port %d, " in channel_setup_remote_fwd_listener()
4251 fwd->listen_host, fwd->listen_port ); in channel_setup_remote_fwd_listener()
4254 "forward, but the request was denied.", in channel_setup_remote_fwd_listener()
4258 if (fwd->listen_path != NULL) { in channel_setup_remote_fwd_listener()
4285 * the secure channel to host:port from local side.
4290 channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) in channel_request_remote_forwarding()
4292 int r, success = 0, idx = -1; in channel_request_remote_forwarding()
4296 /* Send the forward request to the remote side. */ in channel_request_remote_forwarding()
4297 if (fwd->listen_path != NULL) { in channel_request_remote_forwarding()
4300 "streamlocal-forward@openssh.com")) != 0 || in channel_request_remote_forwarding()
4302 (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 || in channel_request_remote_forwarding()
4308 (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 || in channel_request_remote_forwarding()
4311 channel_rfwd_bind_host(fwd->listen_host))) != 0 || in channel_request_remote_forwarding()
4312 (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 || in channel_request_remote_forwarding()
4315 fatal_fr(r, "request tcpip-forward"); in channel_request_remote_forwarding()
4323 if (fwd->connect_path != NULL) { in channel_request_remote_forwarding()
4324 host_to_connect = fwd->connect_path; in channel_request_remote_forwarding()
4327 host_to_connect = fwd->connect_host; in channel_request_remote_forwarding()
4328 port_to_connect = fwd->connect_port; in channel_request_remote_forwarding()
4330 if (fwd->listen_path != NULL) { in channel_request_remote_forwarding()
4331 listen_path = fwd->listen_path; in channel_request_remote_forwarding()
4334 listen_host = fwd->listen_host; in channel_request_remote_forwarding()
4335 listen_port = fwd->listen_port; in channel_request_remote_forwarding()
4348 if (allowed_open->host_to_connect == NULL) in open_match()
4350 if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT && in open_match()
4351 allowed_open->port_to_connect != requestedport) in open_match()
4353 if (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 && in open_match()
4354 strcmp(allowed_open->host_to_connect, requestedhost) != 0) in open_match()
4362 * need to translate between the configured-host (listen_host)
4371 if (allowed_open->host_to_connect == NULL) in open_listen_match_tcpip()
4373 if (allowed_open->listen_port != requestedport) in open_listen_match_tcpip()
4375 if (!translate && allowed_open->listen_host == NULL && in open_listen_match_tcpip()
4379 channel_rfwd_bind_host(allowed_open->listen_host) : in open_listen_match_tcpip()
4380 allowed_open->listen_host; in open_listen_match_tcpip()
4391 if (allowed_open->host_to_connect == NULL) in open_listen_match_streamlocal()
4393 if (allowed_open->listen_port != PORT_STREAMLOCAL) in open_listen_match_streamlocal()
4395 if (allowed_open->listen_path == NULL || in open_listen_match_streamlocal()
4396 strcmp(allowed_open->listen_path, requestedpath) != 0) in open_listen_match_streamlocal()
4409 struct ssh_channels *sc = ssh->chanctxt; in channel_request_rforward_cancel_tcpip()
4410 struct permission_set *pset = &sc->local_perms; in channel_request_rforward_cancel_tcpip()
4415 for (i = 0; i < pset->num_permitted_user; i++) { in channel_request_rforward_cancel_tcpip()
4416 perm = &pset->permitted_user[i]; in channel_request_rforward_cancel_tcpip()
4422 debug_f("requested forward not found"); in channel_request_rforward_cancel_tcpip()
4423 return -1; in channel_request_rforward_cancel_tcpip()
4426 (r = sshpkt_put_cstring(ssh, "cancel-tcpip-forward")) != 0 || in channel_request_rforward_cancel_tcpip()
4445 struct ssh_channels *sc = ssh->chanctxt; in channel_request_rforward_cancel_streamlocal()
4446 struct permission_set *pset = &sc->local_perms; in channel_request_rforward_cancel_streamlocal()
4451 for (i = 0; i < pset->num_permitted_user; i++) { in channel_request_rforward_cancel_streamlocal()
4452 perm = &pset->permitted_user[i]; in channel_request_rforward_cancel_streamlocal()
4458 debug_f("requested forward not found"); in channel_request_rforward_cancel_streamlocal()
4459 return -1; in channel_request_rforward_cancel_streamlocal()
4463 "cancel-streamlocal-forward@openssh.com")) != 0 || in channel_request_rforward_cancel_streamlocal()
4478 channel_request_rforward_cancel(struct ssh *ssh, struct Forward *fwd) in channel_request_rforward_cancel()
4480 if (fwd->listen_path != NULL) { in channel_request_rforward_cancel()
4482 fwd->listen_path); in channel_request_rforward_cancel()
4485 fwd->listen_host, in channel_request_rforward_cancel()
4486 fwd->listen_port ? fwd->listen_port : fwd->allocated_port); in channel_request_rforward_cancel()
4500 if (pset->num_permitted_user == 0) in channel_permit_all()
4501 pset->all_permitted = 1; in channel_permit_all()
4523 pset->all_permitted = 0; in channel_add_permission()
4552 * Update the listen port for a dynamic remote forward, after
4559 struct permission_set *pset = &ssh->chanctxt->local_perms; in channel_update_permission()
4561 if (idx < 0 || (u_int)idx >= pset->num_permitted_user) { in channel_update_permission()
4563 idx, pset->num_permitted_user); in channel_update_permission()
4569 pset->permitted_user[idx].host_to_connect, in channel_update_permission()
4570 pset->permitted_user[idx].port_to_connect); in channel_update_permission()
4572 fwd_perm_clear(&pset->permitted_user[idx]); in channel_update_permission()
4574 pset->permitted_user[idx].listen_port = in channel_update_permission()
4575 (ssh->compat & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport; in channel_update_permission()
4579 /* Try to start non-blocking connect to next host in cctx list */
4586 char strport[MAXIMUM(NI_MAXSERV, sizeof(sunaddr->sun_path))]; in connect_next()
4588 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { in connect_next()
4589 switch (cctx->ai->ai_family) { in connect_next()
4592 sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr; in connect_next()
4594 strlcpy(strport, sunaddr->sun_path, sizeof(strport)); in connect_next()
4598 if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, in connect_next()
4609 cctx->host, ntop, strport); in connect_next()
4610 if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, in connect_next()
4611 cctx->ai->ai_protocol)) == -1) { in connect_next()
4612 if (cctx->ai->ai_next == NULL) in connect_next()
4618 if (set_nonblock(sock) == -1) in connect_next()
4620 if (connect(sock, cctx->ai->ai_addr, in connect_next()
4621 cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) { in connect_next()
4623 cctx->host, ntop, strport, strerror(errno)); in connect_next()
4627 continue; /* fail -- try next */ in connect_next()
4629 if (cctx->ai->ai_family != AF_UNIX) in connect_next()
4632 cctx->host, ntop, strport, sock); in connect_next()
4633 cctx->ai = cctx->ai->ai_next; in connect_next()
4636 return -1; in connect_next()
4642 free(cctx->host); in channel_connect_ctx_free()
4643 if (cctx->aitop) { in channel_connect_ctx_free()
4644 if (cctx->aitop->ai_family == AF_UNIX) in channel_connect_ctx_free()
4645 free(cctx->aitop); in channel_connect_ctx_free()
4647 freeaddrinfo(cctx->aitop); in channel_connect_ctx_free()
4663 int sock = -1; in connect_to_helper()
4670 if (strlen(name) > sizeof(sunaddr->sun_path)) { in connect_to_helper()
4672 return -1; in connect_to_helper()
4682 ai->ai_addr = (struct sockaddr *)(ai + 1); in connect_to_helper()
4683 ai->ai_addrlen = sizeof(*sunaddr); in connect_to_helper()
4684 ai->ai_family = AF_UNIX; in connect_to_helper()
4685 ai->ai_socktype = socktype; in connect_to_helper()
4686 ai->ai_protocol = PF_UNSPEC; in connect_to_helper()
4687 sunaddr = (struct sockaddr_un *)ai->ai_addr; in connect_to_helper()
4688 sunaddr->sun_family = AF_UNIX; in connect_to_helper()
4689 strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path)); in connect_to_helper()
4690 cctx->aitop = ai; in connect_to_helper()
4693 hints.ai_family = ssh->chanctxt->IPv4or6; in connect_to_helper()
4696 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx->aitop)) in connect_to_helper()
4704 return -1; in connect_to_helper()
4708 cctx->host = xstrdup(name); in connect_to_helper()
4709 cctx->port = port; in connect_to_helper()
4710 cctx->ai = cctx->aitop; in connect_to_helper()
4712 if ((sock = connect_next(cctx)) == -1) { in connect_to_helper()
4715 return -1; in connect_to_helper()
4721 /* Return CONNECTING channel to remote host:port or local socket path */
4722 static Channel *
4727 Channel *c; in connect_to()
4733 if (sock == -1) { in connect_to()
4737 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, in connect_to()
4739 c->host_port = port; in connect_to()
4740 c->path = xstrdup(host); in connect_to()
4741 c->connect_ctx = cctx; in connect_to()
4747 * returns either the newly connected channel or the downstream channel
4750 Channel *
4754 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_by_listen_address()
4755 struct permission_set *pset = &sc->local_perms; in channel_connect_by_listen_address()
4759 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_by_listen_address()
4760 perm = &pset->permitted_user[i]; in channel_connect_by_listen_address()
4763 if (perm->downstream) in channel_connect_by_listen_address()
4764 return perm->downstream; in channel_connect_by_listen_address()
4765 if (perm->port_to_connect == 0) in channel_connect_by_listen_address()
4769 perm->host_to_connect, perm->port_to_connect, in channel_connect_by_listen_address()
4778 Channel *
4782 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_by_listen_path()
4783 struct permission_set *pset = &sc->local_perms; in channel_connect_by_listen_path()
4787 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_by_listen_path()
4788 perm = &pset->permitted_user[i]; in channel_connect_by_listen_path()
4791 perm->host_to_connect, perm->port_to_connect, in channel_connect_by_listen_path()
4801 Channel *
4805 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_to_port()
4806 struct permission_set *pset = &sc->local_perms; in channel_connect_to_port()
4808 Channel *c; in channel_connect_to_port()
4813 permit = pset->all_permitted; in channel_connect_to_port()
4815 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_to_port()
4816 perm = &pset->permitted_user[i]; in channel_connect_to_port()
4824 if (pset->num_permitted_admin > 0) { in channel_connect_to_port()
4826 for (i = 0; i < pset->num_permitted_admin; i++) { in channel_connect_to_port()
4827 perm = &pset->permitted_admin[i]; in channel_connect_to_port()
4847 if (sock == -1) { in channel_connect_to_port()
4852 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, in channel_connect_to_port()
4854 c->host_port = port; in channel_connect_to_port()
4855 c->path = xstrdup(host); in channel_connect_to_port()
4856 c->connect_ctx = cctx; in channel_connect_to_port()
4862 Channel *
4866 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_to_path()
4867 struct permission_set *pset = &sc->local_perms; in channel_connect_to_path()
4871 permit = pset->all_permitted; in channel_connect_to_path()
4873 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_to_path()
4874 perm = &pset->permitted_user[i]; in channel_connect_to_path()
4882 if (pset->num_permitted_admin > 0) { in channel_connect_to_path()
4884 for (i = 0; i < pset->num_permitted_admin; i++) { in channel_connect_to_path()
4885 perm = &pset->permitted_admin[i]; in channel_connect_to_path()
4904 struct ssh_channels *sc = ssh->chanctxt; in channel_send_window_changes()
4909 for (i = 0; i < sc->channels_alloc; i++) { in channel_send_window_changes()
4910 if (sc->channels[i] == NULL || !sc->channels[i]->client_tty || in channel_send_window_changes()
4911 sc->channels[i]->type != SSH_CHANNEL_OPEN) in channel_send_window_changes()
4913 if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) == -1) in channel_send_window_changes()
4915 channel_request_start(ssh, i, "window-change", 0); in channel_send_window_changes()
4921 fatal_fr(r, "channel %u; send window-change", i); in channel_send_window_changes()
4925 /* Return RDYNAMIC_OPEN channel: channel allows SOCKS, but is not connected */
4926 static Channel *
4929 Channel *c; in rdynamic_connect_prepare()
4932 c = channel_new(ssh, ctype, SSH_CHANNEL_RDYNAMIC_OPEN, -1, -1, -1, in rdynamic_connect_prepare()
4934 c->host_port = 0; in rdynamic_connect_prepare()
4935 c->path = NULL; in rdynamic_connect_prepare()
4938 * We need to open the channel before we have a FD, in rdynamic_connect_prepare()
4942 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in rdynamic_connect_prepare()
4943 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in rdynamic_connect_prepare()
4944 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in rdynamic_connect_prepare()
4945 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) in rdynamic_connect_prepare()
4946 fatal_fr(r, "channel %i; confirm", c->self); in rdynamic_connect_prepare()
4952 rdynamic_connect_finish(struct ssh *ssh, Channel *c) in rdynamic_connect_finish()
4954 struct ssh_channels *sc = ssh->chanctxt; in rdynamic_connect_finish()
4955 struct permission_set *pset = &sc->local_perms; in rdynamic_connect_finish()
4961 if (pset->num_permitted_admin > 0) { in rdynamic_connect_finish()
4963 for (i = 0; i < pset->num_permitted_admin; i++) { in rdynamic_connect_finish()
4964 perm = &pset->permitted_admin[i]; in rdynamic_connect_finish()
4965 if (open_match(perm, c->path, c->host_port)) { in rdynamic_connect_finish()
4972 debug_f("requested forward not permitted"); in rdynamic_connect_finish()
4973 return -1; in rdynamic_connect_finish()
4977 sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL, in rdynamic_connect_finish()
4979 if (sock == -1) in rdynamic_connect_finish()
4983 c->type = SSH_CHANNEL_RDYNAMIC_FINISH; in rdynamic_connect_finish()
4984 c->connect_ctx = cctx; in rdynamic_connect_finish()
4985 channel_register_fds(ssh, c, sock, sock, -1, 0, 1, 0); in rdynamic_connect_finish()
4990 /* -- X11 forwarding */
4995 * stored in display_numberp , or -1 if an error occurs.
5002 Channel *nc = NULL; in x11_create_display_inet()
5009 x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS) in x11_create_display_inet()
5010 return -1; in x11_create_display_inet()
5017 hints.ai_family = ssh->chanctxt->IPv4or6; in x11_create_display_inet()
5024 return -1; in x11_create_display_inet()
5026 for (ai = aitop; ai; ai = ai->ai_next) { in x11_create_display_inet()
5027 if (ai->ai_family != AF_INET && in x11_create_display_inet()
5028 ai->ai_family != AF_INET6) in x11_create_display_inet()
5030 sock = socket(ai->ai_family, ai->ai_socktype, in x11_create_display_inet()
5031 ai->ai_protocol); in x11_create_display_inet()
5032 if (sock == -1) { in x11_create_display_inet()
5040 return -1; in x11_create_display_inet()
5043 ai->ai_family); in x11_create_display_inet()
5047 if (ai->ai_family == AF_INET6) in x11_create_display_inet()
5051 if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in x11_create_display_inet()
5069 error("Failed to allocate internet-domain X11 display socket."); in x11_create_display_inet()
5070 return -1; in x11_create_display_inet()
5075 if (listen(sock, SSH_LISTEN_BACKLOG) == -1) { in x11_create_display_inet()
5078 return -1; in x11_create_display_inet()
5082 /* Allocate a channel for each socket. */ in x11_create_display_inet()
5086 nc = channel_new(ssh, "x11-listener", in x11_create_display_inet()
5087 SSH_CHANNEL_X11_LISTENER, sock, sock, -1, in x11_create_display_inet()
5090 nc->single_connection = single_connection; in x11_create_display_inet()
5091 (*chanids)[n] = nc->self; in x11_create_display_inet()
5093 (*chanids)[n] = -1; in x11_create_display_inet()
5107 if (sock == -1) { in connect_local_xsocket_path()
5109 return -1; in connect_local_xsocket_path()
5118 return -1; in connect_local_xsocket_path()
5170 return -1; in x11_connect_display()
5188 return -1; in x11_connect_display()
5206 return -1; in x11_connect_display()
5211 return -1; in x11_connect_display()
5224 return -1; in x11_connect_display()
5232 display_number > UINT16_MAX - X11_BASE_PORT) { in x11_connect_display()
5235 return -1; in x11_connect_display()
5240 hints.ai_family = ssh->chanctxt->IPv4or6; in x11_connect_display()
5246 return -1; in x11_connect_display()
5248 for (ai = aitop; ai; ai = ai->ai_next) { in x11_connect_display()
5250 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); in x11_connect_display()
5251 if (sock == -1) { in x11_connect_display()
5256 if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in x11_connect_display()
5269 return -1; in x11_connect_display()
5284 struct ssh_channels *sc = ssh->chanctxt; in x11_request_forwarding_with_spoofing()
5291 if (sc->x11_saved_display == NULL) in x11_request_forwarding_with_spoofing()
5292 sc->x11_saved_display = xstrdup(disp); in x11_request_forwarding_with_spoofing()
5293 else if (strcmp(disp, sc->x11_saved_display) != 0) { in x11_request_forwarding_with_spoofing()
5307 if (sc->x11_saved_proto == NULL) { in x11_request_forwarding_with_spoofing()
5309 sc->x11_saved_proto = xstrdup(proto); in x11_request_forwarding_with_spoofing()
5312 sc->x11_saved_data = xmalloc(data_len); in x11_request_forwarding_with_spoofing()
5318 sc->x11_saved_data[i] = value; in x11_request_forwarding_with_spoofing()
5320 sc->x11_saved_data_len = data_len; in x11_request_forwarding_with_spoofing()
5323 sc->x11_fake_data = xmalloc(data_len); in x11_request_forwarding_with_spoofing()
5324 arc4random_buf(sc->x11_fake_data, data_len); in x11_request_forwarding_with_spoofing()
5325 sc->x11_fake_data_len = data_len; in x11_request_forwarding_with_spoofing()
5329 new_data = tohex(sc->x11_fake_data, data_len); in x11_request_forwarding_with_spoofing()
5332 channel_request_start(ssh, client_session_id, "x11-req", want_reply); in x11_request_forwarding_with_spoofing()
5339 fatal_fr(r, "send x11-req"); in x11_request_forwarding_with_spoofing()
5344 * Returns whether an x11 channel was used recently (less than a second ago)
5349 Channel *c; in x11_channel_used_recently()
5352 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in x11_channel_used_recently()
5353 c = ssh->chanctxt->channels[i]; in x11_channel_used_recently()
5354 if (c == NULL || c->ctype == NULL || c->lastused == 0 || in x11_channel_used_recently()
5355 strcmp(c->ctype, "x11-connection") != 0) in x11_channel_used_recently()
5357 lastused = c->lastused; in x11_channel_used_recently()