Lines Matching +full:data +full:- +full:channel

36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
73 #include "openbsd-compat/sys-queue.h"
93 /* -- agent forwarding */
96 /* -- X11 forwarding */
100 /* Per-channel callback for pre/post IO actions */
101 typedef void chan_fn(struct ssh *, Channel *c);
104 * Data structure for storing which hosts are permitted for forward requests.
111 /* XXX - can we use listen_host instead of listen_path? */
118 Channel *downstream; /* Downstream mux*/
147 /* Used to record timeouts per channel type */
159 Channel **channels;
162 * Size of the channel array. All slots of the array must always be
169 * relevant to channels in the c->io_want bitmasks.
172 * channels which have c->io_ready events pending.
177 /* -- tcp forwarding */
181 /* -- X11 forwarding */
189 /* Saved X11 authentication data. This is the real data. */
197 * Fake X11 authentication data. This is what the server will be
199 * real data.
207 /* Channel timeouts by type */
216 static void port_open_helper(struct ssh *ssh, Channel *c, char *rtype);
219 /* non-blocking connect helpers */
222 static Channel *rdynamic_connect_prepare(struct ssh *, char *, char *);
223 static int rdynamic_connect_finish(struct ssh *, Channel *);
228 /* -- channel core */
237 sc->channels_alloc = 10; in channel_init_channels()
238 sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels)); in channel_init_channels()
239 sc->IPv4or6 = AF_UNSPEC; in channel_init_channels()
242 ssh->chanctxt = sc; in channel_init_channels()
245 Channel *
248 Channel *c; in channel_by_id()
250 if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) { in channel_by_id()
254 c = ssh->chanctxt->channels[id]; in channel_by_id()
256 logit_f("%d: bad id: channel free", id); in channel_by_id()
262 Channel *
265 Channel *c; in channel_by_remote_id()
268 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_by_remote_id()
269 c = ssh->chanctxt->channels[i]; in channel_by_remote_id()
270 if (c != NULL && c->have_remote_id && c->remote_id == remote_id) in channel_by_remote_id()
277 * Returns the channel if it is allowed to receive protocol messages.
280 Channel *
283 Channel *c; in channel_lookup()
288 switch (c->type) { in channel_lookup()
301 logit("Non-public channel %d, type %d.", id, c->type); in channel_lookup()
306 * Add a timeout for open channels whose c->ctype (or c->xctype if it is set)
313 struct ssh_channels *sc = ssh->chanctxt; in channel_add_timeout()
316 debug2_f("global channel timeout %d seconds", timeout_secs); in channel_add_timeout()
317 sc->global_deadline = timeout_secs; in channel_add_timeout()
320 debug2_f("channel type \"%s\" timeout %d seconds", in channel_add_timeout()
322 sc->timeouts = xrecallocarray(sc->timeouts, sc->ntimeouts, in channel_add_timeout()
323 sc->ntimeouts + 1, sizeof(*sc->timeouts)); in channel_add_timeout()
324 sc->timeouts[sc->ntimeouts].type_pattern = xstrdup(type_pattern); in channel_add_timeout()
325 sc->timeouts[sc->ntimeouts].timeout_secs = timeout_secs; in channel_add_timeout()
326 sc->ntimeouts++; in channel_add_timeout()
329 /* Clears all previously-added channel timeouts */
333 struct ssh_channels *sc = ssh->chanctxt; in channel_clear_timeouts()
337 for (i = 0; i < sc->ntimeouts; i++) in channel_clear_timeouts()
338 free(sc->timeouts[i].type_pattern); in channel_clear_timeouts()
339 free(sc->timeouts); in channel_clear_timeouts()
340 sc->timeouts = NULL; in channel_clear_timeouts()
341 sc->ntimeouts = 0; in channel_clear_timeouts()
347 struct ssh_channels *sc = ssh->chanctxt; in lookup_timeout()
350 for (i = 0; i < sc->ntimeouts; i++) { in lookup_timeout()
351 if (match_pattern(type, sc->timeouts[i].type_pattern)) in lookup_timeout()
352 return sc->timeouts[i].timeout_secs; in lookup_timeout()
359 * Sets "extended type" of a channel; used by session layer to add additional
360 * information about channel types (e.g. shell, login, subsystem) that can then
362 * Will reset c->inactive_deadline as a side-effect.
367 Channel *c; in channel_set_xtype()
370 fatal_f("missing channel %d", id); in channel_set_xtype()
371 if (c->xctype != NULL) in channel_set_xtype()
372 free(c->xctype); in channel_set_xtype()
373 c->xctype = xstrdup(xctype); in channel_set_xtype()
375 c->inactive_deadline = lookup_timeout(ssh, c->xctype); in channel_set_xtype()
376 debug2_f("labeled channel %d as %s (inactive timeout %u)", id, xctype, in channel_set_xtype()
377 c->inactive_deadline); in channel_set_xtype()
381 * update "last used" time on a channel.
385 channel_set_used_time(struct ssh *ssh, Channel *c) in channel_set_used_time()
387 ssh->chanctxt->lastused = monotime(); in channel_set_used_time()
389 c->lastused = ssh->chanctxt->lastused; in channel_set_used_time()
393 * Get the time at which a channel is due to time out for inactivity.
394 * Returns 0 if the channel is not due to time out ever.
397 channel_get_expiry(struct ssh *ssh, Channel *c) in channel_get_expiry()
399 struct ssh_channels *sc = ssh->chanctxt; in channel_get_expiry()
402 if (sc->lastused != 0 && sc->global_deadline != 0) in channel_get_expiry()
403 expiry = sc->lastused + sc->global_deadline; in channel_get_expiry()
404 if (c->lastused != 0 && c->inactive_deadline != 0) { in channel_get_expiry()
405 channel_expiry = c->lastused + c->inactive_deadline; in channel_get_expiry()
413 * Register filedescriptors for a channel, used when allocating a channel or
414 * when the channel consumer/producer is ready, e.g. shell exec'd
417 channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, in channel_register_fds()
422 if (rfd != -1) in channel_register_fds()
424 if (wfd != -1 && wfd != rfd) in channel_register_fds()
426 if (efd != -1 && efd != rfd && efd != wfd) in channel_register_fds()
429 c->rfd = rfd; in channel_register_fds()
430 c->wfd = wfd; in channel_register_fds()
431 c->sock = (rfd == wfd) ? rfd : -1; in channel_register_fds()
432 c->efd = efd; in channel_register_fds()
433 c->extended_usage = extusage; in channel_register_fds()
435 if ((c->isatty = is_tty) != 0) in channel_register_fds()
436 debug2("channel %d: rfd %d isatty", c->self, c->rfd); in channel_register_fds()
438 /* XXX: Later AIX versions can't push as much data to tty */ in channel_register_fds()
439 c->wfd_isatty = is_tty || isatty(c->wfd); in channel_register_fds()
443 c->restore_block = 0; in channel_register_fds()
447 * non-blocking mode if they are TTYs. Otherwise prepare to in channel_register_fds()
451 if (rfd != -1 && !isatty(rfd) && in channel_register_fds()
452 (val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
453 c->restore_flags[0] = val; in channel_register_fds()
454 c->restore_block |= CHANNEL_RESTORE_RFD; in channel_register_fds()
457 if (wfd != -1 && !isatty(wfd) && in channel_register_fds()
458 (val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
459 c->restore_flags[1] = val; in channel_register_fds()
460 c->restore_block |= CHANNEL_RESTORE_WFD; in channel_register_fds()
463 if (efd != -1 && !isatty(efd) && in channel_register_fds()
464 (val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
465 c->restore_flags[2] = val; in channel_register_fds()
466 c->restore_block |= CHANNEL_RESTORE_EFD; in channel_register_fds()
470 if (rfd != -1) in channel_register_fds()
472 if (wfd != -1) in channel_register_fds()
474 if (efd != -1) in channel_register_fds()
477 /* channel might be entering a larval state, so reset global timeout */ in channel_register_fds()
482 * Allocate a new channel object and set its type and socket.
484 Channel *
489 struct ssh_channels *sc = ssh->chanctxt; in channel_new()
491 Channel *c; in channel_new()
494 /* Try to find a free slot where to put the new channel. */ in channel_new()
495 for (i = 0; i < sc->channels_alloc; i++) { in channel_new()
496 if (sc->channels[i] == NULL) { in channel_new()
502 if (i >= sc->channels_alloc) { in channel_new()
507 found = sc->channels_alloc; in channel_new()
508 if (sc->channels_alloc > CHANNELS_MAX_CHANNELS) in channel_new()
510 sc->channels_alloc); in channel_new()
511 sc->channels = xrecallocarray(sc->channels, sc->channels_alloc, in channel_new()
512 sc->channels_alloc + 10, sizeof(*sc->channels)); in channel_new()
513 sc->channels_alloc += 10; in channel_new()
514 debug2("channel: expanding %d", sc->channels_alloc); in channel_new()
516 /* Initialize and return new channel. */ in channel_new()
517 c = sc->channels[found] = xcalloc(1, sizeof(Channel)); in channel_new()
518 if ((c->input = sshbuf_new()) == NULL || in channel_new()
519 (c->output = sshbuf_new()) == NULL || in channel_new()
520 (c->extended = sshbuf_new()) == NULL) in channel_new()
522 if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) in channel_new()
524 c->ostate = CHAN_OUTPUT_OPEN; in channel_new()
525 c->istate = CHAN_INPUT_OPEN; in channel_new()
527 c->self = found; in channel_new()
528 c->type = type; in channel_new()
529 c->ctype = ctype; in channel_new()
530 c->local_window = window; in channel_new()
531 c->local_window_max = window; in channel_new()
532 c->local_maxpacket = maxpack; in channel_new()
533 c->remote_name = xstrdup(remote_name); in channel_new()
534 c->ctl_chan = -1; in channel_new()
535 c->delayed = 1; /* prevent call to channel_post handler */ in channel_new()
536 c->inactive_deadline = lookup_timeout(ssh, c->ctype); in channel_new()
537 TAILQ_INIT(&c->status_confirms); in channel_new()
538 debug("channel %d: new %s [%s] (inactive timeout: %u)", in channel_new()
539 found, c->ctype, remote_name, c->inactive_deadline); in channel_new()
544 channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) in channel_close_fd()
548 if (fd == -1) in channel_close_fd()
552 if (*fdp == c->rfd && in channel_close_fd()
553 (c->restore_block & CHANNEL_RESTORE_RFD) != 0) in channel_close_fd()
554 (void)fcntl(*fdp, F_SETFL, c->restore_flags[0]); in channel_close_fd()
555 else if (*fdp == c->wfd && in channel_close_fd()
556 (c->restore_block & CHANNEL_RESTORE_WFD) != 0) in channel_close_fd()
557 (void)fcntl(*fdp, F_SETFL, c->restore_flags[1]); in channel_close_fd()
558 else if (*fdp == c->efd && in channel_close_fd()
559 (c->restore_block & CHANNEL_RESTORE_EFD) != 0) in channel_close_fd()
560 (void)fcntl(*fdp, F_SETFL, c->restore_flags[2]); in channel_close_fd()
562 if (*fdp == c->rfd) { in channel_close_fd()
563 c->io_want &= ~SSH_CHAN_IO_RFD; in channel_close_fd()
564 c->io_ready &= ~SSH_CHAN_IO_RFD; in channel_close_fd()
565 c->rfd = -1; in channel_close_fd()
566 c->pfds[0] = -1; in channel_close_fd()
568 if (*fdp == c->wfd) { in channel_close_fd()
569 c->io_want &= ~SSH_CHAN_IO_WFD; in channel_close_fd()
570 c->io_ready &= ~SSH_CHAN_IO_WFD; in channel_close_fd()
571 c->wfd = -1; in channel_close_fd()
572 c->pfds[1] = -1; in channel_close_fd()
574 if (*fdp == c->efd) { in channel_close_fd()
575 c->io_want &= ~SSH_CHAN_IO_EFD; in channel_close_fd()
576 c->io_ready &= ~SSH_CHAN_IO_EFD; in channel_close_fd()
577 c->efd = -1; in channel_close_fd()
578 c->pfds[2] = -1; in channel_close_fd()
580 if (*fdp == c->sock) { in channel_close_fd()
581 c->io_want &= ~SSH_CHAN_IO_SOCK; in channel_close_fd()
582 c->io_ready &= ~SSH_CHAN_IO_SOCK; in channel_close_fd()
583 c->sock = -1; in channel_close_fd()
584 c->pfds[3] = -1; in channel_close_fd()
588 *fdp = -1; /* probably redundant */ in channel_close_fd()
592 /* Close all channel fd/socket. */
594 channel_close_fds(struct ssh *ssh, Channel *c) in channel_close_fds()
596 int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; in channel_close_fds()
598 channel_close_fd(ssh, c, &c->sock); in channel_close_fds()
600 channel_close_fd(ssh, c, &c->rfd); in channel_close_fds()
602 channel_close_fd(ssh, c, &c->wfd); in channel_close_fds()
604 channel_close_fd(ssh, c, &c->efd); in channel_close_fds()
610 free(perm->host_to_connect); in fwd_perm_clear()
611 free(perm->listen_host); in fwd_perm_clear()
612 free(perm->listen_path); in fwd_perm_clear()
638 struct ssh_channels *sc = ssh->chanctxt; in permission_set_get()
642 return &sc->local_perms; in permission_set_get()
645 return &sc->remote_perms; in permission_set_get()
661 *permpp = &pset->permitted_user; in permission_set_get_array()
662 *npermpp = &pset->num_permitted_user; in permission_set_get_array()
665 *permpp = &pset->permitted_admin; in permission_set_get_array()
666 *npermpp = &pset->num_permitted_admin; in permission_set_get_array()
678 Channel *downstream) in permission_set_add()
702 mux_remove_remote_forwardings(struct ssh *ssh, Channel *c) in mux_remove_remote_forwardings()
704 struct ssh_channels *sc = ssh->chanctxt; in mux_remove_remote_forwardings()
705 struct permission_set *pset = &sc->local_perms; in mux_remove_remote_forwardings()
710 for (i = 0; i < pset->num_permitted_user; i++) { in mux_remove_remote_forwardings()
711 perm = &pset->permitted_user[i]; in mux_remove_remote_forwardings()
712 if (perm->downstream != c) in mux_remove_remote_forwardings()
716 debug("channel %d: cleanup remote forward for %s:%u", in mux_remove_remote_forwardings()
717 c->self, perm->listen_host, perm->listen_port); in mux_remove_remote_forwardings()
720 "cancel-tcpip-forward")) != 0 || in mux_remove_remote_forwardings()
723 channel_rfwd_bind_host(perm->listen_host))) != 0 || in mux_remove_remote_forwardings()
724 (r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 || in mux_remove_remote_forwardings()
726 fatal_fr(r, "channel %i", c->self); in mux_remove_remote_forwardings()
732 /* Free the channel and close its fd/socket. */
734 channel_free(struct ssh *ssh, Channel *c) in channel_free()
736 struct ssh_channels *sc = ssh->chanctxt; in channel_free()
739 Channel *other; in channel_free()
742 for (n = 0, i = 0; i < sc->channels_alloc; i++) { in channel_free()
743 if ((other = sc->channels[i]) == NULL) in channel_free()
747 if (c->type == SSH_CHANNEL_MUX_CLIENT && in channel_free()
748 other->type == SSH_CHANNEL_MUX_PROXY && in channel_free()
749 other->mux_ctx == c) { in channel_free()
750 other->mux_ctx = NULL; in channel_free()
751 other->type = SSH_CHANNEL_OPEN; in channel_free()
752 other->istate = CHAN_INPUT_CLOSED; in channel_free()
753 other->ostate = CHAN_OUTPUT_CLOSED; in channel_free()
756 debug("channel %d: free: %s, nchannels %u", c->self, in channel_free()
757 c->remote_name ? c->remote_name : "???", n); in channel_free()
759 if (c->type == SSH_CHANNEL_MUX_CLIENT) { in channel_free()
761 free(c->mux_ctx); in channel_free()
762 c->mux_ctx = NULL; in channel_free()
763 } else if (c->type == SSH_CHANNEL_MUX_LISTENER) { in channel_free()
764 free(c->mux_ctx); in channel_free()
765 c->mux_ctx = NULL; in channel_free()
770 debug3("channel %d: status: %s", c->self, s); in channel_free()
775 sshbuf_free(c->input); in channel_free()
776 sshbuf_free(c->output); in channel_free()
777 sshbuf_free(c->extended); in channel_free()
778 c->input = c->output = c->extended = NULL; in channel_free()
779 free(c->remote_name); in channel_free()
780 c->remote_name = NULL; in channel_free()
781 free(c->path); in channel_free()
782 c->path = NULL; in channel_free()
783 free(c->listening_addr); in channel_free()
784 c->listening_addr = NULL; in channel_free()
785 free(c->xctype); in channel_free()
786 c->xctype = NULL; in channel_free()
787 while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { in channel_free()
788 if (cc->abandon_cb != NULL) in channel_free()
789 cc->abandon_cb(ssh, c, cc->ctx); in channel_free()
790 TAILQ_REMOVE(&c->status_confirms, cc, entry); in channel_free()
793 if (c->filter_cleanup != NULL && c->filter_ctx != NULL) in channel_free()
794 c->filter_cleanup(ssh, c->self, c->filter_ctx); in channel_free()
795 sc->channels[c->self] = NULL; in channel_free()
803 struct ssh_channels *sc = ssh->chanctxt; in channel_free_all()
805 for (i = 0; i < sc->channels_alloc; i++) in channel_free_all()
806 if (sc->channels[i] != NULL) in channel_free_all()
807 channel_free(ssh, sc->channels[i]); in channel_free_all()
809 free(sc->channels); in channel_free_all()
810 sc->channels = NULL; in channel_free_all()
811 sc->channels_alloc = 0; in channel_free_all()
813 free(sc->x11_saved_display); in channel_free_all()
814 sc->x11_saved_display = NULL; in channel_free_all()
816 free(sc->x11_saved_proto); in channel_free_all()
817 sc->x11_saved_proto = NULL; in channel_free_all()
819 free(sc->x11_saved_data); in channel_free_all()
820 sc->x11_saved_data = NULL; in channel_free_all()
821 sc->x11_saved_data_len = 0; in channel_free_all()
823 free(sc->x11_fake_data); in channel_free_all()
824 sc->x11_fake_data = NULL; in channel_free_all()
825 sc->x11_fake_data_len = 0; in channel_free_all()
837 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) in channel_close_all()
838 if (ssh->chanctxt->channels[i] != NULL) in channel_close_all()
839 channel_close_fds(ssh, ssh->chanctxt->channels[i]); in channel_close_all()
849 Channel *c; in channel_stop_listening()
851 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_stop_listening()
852 c = ssh->chanctxt->channels[i]; in channel_stop_listening()
854 switch (c->type) { in channel_stop_listening()
861 channel_close_fd(ssh, c, &c->sock); in channel_stop_listening()
870 * Returns true if no channel has too much buffered data, and false if one or
871 * more channel is overfull.
878 Channel *c; in channel_not_very_much_buffered_data()
880 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_not_very_much_buffered_data()
881 c = ssh->chanctxt->channels[i]; in channel_not_very_much_buffered_data()
882 if (c == NULL || c->type != SSH_CHANNEL_OPEN) in channel_not_very_much_buffered_data()
884 if (sshbuf_len(c->output) > maxsize) { in channel_not_very_much_buffered_data()
885 debug2("channel %d: big output buffer %zu > %u", in channel_not_very_much_buffered_data()
886 c->self, sshbuf_len(c->output), maxsize); in channel_not_very_much_buffered_data()
893 /* Returns true if any channel is still open. */
898 Channel *c; in channel_still_open()
900 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_still_open()
901 c = ssh->chanctxt->channels[i]; in channel_still_open()
904 switch (c->type) { in channel_still_open()
929 fatal_f("bad channel type %d", c->type); in channel_still_open()
936 /* Returns true if a channel with a TTY is open. */
941 Channel *c; in channel_tty_open()
943 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_tty_open()
944 c = ssh->chanctxt->channels[i]; in channel_tty_open()
945 if (c == NULL || c->type != SSH_CHANNEL_OPEN) in channel_tty_open()
947 if (c->client_tty) in channel_tty_open()
953 /* Returns the id of an open channel suitable for keepaliving */
958 Channel *c; in channel_find_open()
960 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_find_open()
961 c = ssh->chanctxt->channels[i]; in channel_find_open()
962 if (c == NULL || !c->have_remote_id) in channel_find_open()
964 switch (c->type) { in channel_find_open()
988 fatal_f("bad channel type %d", c->type); in channel_find_open()
992 return -1; in channel_find_open()
995 /* Returns the state of the channel's extended usage flag */
997 channel_format_extended_usage(const Channel *c) in channel_format_extended_usage()
999 if (c->efd == -1) in channel_format_extended_usage()
1002 switch (c->extended_usage) { in channel_format_extended_usage()
1015 channel_format_status(const Channel *c) in channel_format_status()
1021 c->type, c->xctype != NULL ? c->xctype : c->ctype, in channel_format_status()
1022 c->have_remote_id ? "r" : "nr", c->remote_id, in channel_format_status()
1023 c->mux_ctx != NULL ? "m" : "nm", c->mux_downstream_id, in channel_format_status()
1024 c->istate, sshbuf_len(c->input), in channel_format_status()
1025 c->ostate, sshbuf_len(c->output), in channel_format_status()
1026 channel_format_extended_usage(c), sshbuf_len(c->extended), in channel_format_status()
1027 c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan, in channel_format_status()
1028 c->have_ctl_child_id ? "c" : "nc", c->ctl_child_id, in channel_format_status()
1029 c->io_want, c->io_ready); in channel_format_status()
1042 Channel *c; in channel_open_message()
1052 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_open_message()
1053 c = ssh->chanctxt->channels[i]; in channel_open_message()
1056 switch (c->type) { in channel_open_message()
1080 c->self, c->remote_name, cp)) != 0) { in channel_open_message()
1087 fatal_f("bad channel type %d", c->type); in channel_open_message()
1098 open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type) in open_preamble()
1104 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in open_preamble()
1105 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in open_preamble()
1106 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) { in open_preamble()
1107 fatal_r(r, "%s: channel %i: open", where, c->self); in open_preamble()
1114 Channel *c = channel_lookup(ssh, id); in channel_send_open()
1121 debug2("channel %d: send open", id); in channel_send_open()
1122 open_preamble(ssh, __func__, c, c->ctype); in channel_send_open()
1124 fatal_fr(r, "channel %i", c->self); in channel_send_open()
1130 Channel *c = channel_lookup(ssh, id); in channel_request_start()
1134 logit_f("%d: unknown channel id", id); in channel_request_start()
1137 if (!c->have_remote_id) in channel_request_start()
1138 fatal_f("channel %d: no remote id", c->self); in channel_request_start()
1140 debug2("channel %d: request %s confirm %d", id, service, wantconfirm); in channel_request_start()
1142 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_request_start()
1145 fatal_fr(r, "channel %i", c->self); in channel_request_start()
1154 Channel *c; in channel_register_status_confirm()
1160 cc->cb = cb; in channel_register_status_confirm()
1161 cc->abandon_cb = abandon_cb; in channel_register_status_confirm()
1162 cc->ctx = ctx; in channel_register_status_confirm()
1163 TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry); in channel_register_status_confirm()
1170 Channel *c = channel_lookup(ssh, id); in channel_register_open_confirm()
1176 c->open_confirm = fn; in channel_register_open_confirm()
1177 c->open_confirm_ctx = ctx; in channel_register_open_confirm()
1184 Channel *c = channel_by_id(ssh, id); in channel_register_cleanup()
1190 c->detach_user = fn; in channel_register_cleanup()
1191 c->detach_close = do_close; in channel_register_cleanup()
1197 Channel *c = channel_by_id(ssh, id); in channel_cancel_cleanup()
1203 c->detach_user = NULL; in channel_cancel_cleanup()
1204 c->detach_close = 0; in channel_cancel_cleanup()
1211 Channel *c = channel_lookup(ssh, id); in channel_register_filter()
1217 c->input_filter = ifn; in channel_register_filter()
1218 c->output_filter = ofn; in channel_register_filter()
1219 c->filter_ctx = ctx; in channel_register_filter()
1220 c->filter_cleanup = cfn; in channel_register_filter()
1227 Channel *c = channel_lookup(ssh, id); in channel_set_fds()
1230 if (c == NULL || c->type != SSH_CHANNEL_LARVAL) in channel_set_fds()
1231 fatal("channel_activate for non-larval channel %d.", id); in channel_set_fds()
1232 if (!c->have_remote_id) in channel_set_fds()
1233 fatal_f("channel %d: no remote id", c->self); in channel_set_fds()
1236 c->type = SSH_CHANNEL_OPEN; in channel_set_fds()
1238 c->local_window = c->local_window_max = window_max; in channel_set_fds()
1241 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_set_fds()
1242 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in channel_set_fds()
1244 fatal_fr(r, "channel %i", c->self); in channel_set_fds()
1248 channel_pre_listener(struct ssh *ssh, Channel *c) in channel_pre_listener()
1250 c->io_want = SSH_CHAN_IO_SOCK_R; in channel_pre_listener()
1254 channel_pre_connecting(struct ssh *ssh, Channel *c) in channel_pre_connecting()
1256 debug3("channel %d: waiting for connection", c->self); in channel_pre_connecting()
1257 c->io_want = SSH_CHAN_IO_SOCK_W; in channel_pre_connecting()
1261 channel_pre_open(struct ssh *ssh, Channel *c) in channel_pre_open()
1263 c->io_want = 0; in channel_pre_open()
1264 if (c->istate == CHAN_INPUT_OPEN && in channel_pre_open()
1265 c->remote_window > 0 && in channel_pre_open()
1266 sshbuf_len(c->input) < c->remote_window && in channel_pre_open()
1267 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0) in channel_pre_open()
1268 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_open()
1269 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_pre_open()
1270 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_open()
1271 if (sshbuf_len(c->output) > 0) { in channel_pre_open()
1272 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_open()
1273 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_open()
1275 debug2("channel %d: " in channel_pre_open()
1276 "obuf_empty delayed efd %d/(%zu)", c->self, in channel_pre_open()
1277 c->efd, sshbuf_len(c->extended)); in channel_pre_open()
1283 if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED && in channel_pre_open()
1284 c->ostate == CHAN_OUTPUT_CLOSED)) { in channel_pre_open()
1285 if (c->extended_usage == CHAN_EXTENDED_WRITE && in channel_pre_open()
1286 sshbuf_len(c->extended) > 0) in channel_pre_open()
1287 c->io_want |= SSH_CHAN_IO_EFD_W; in channel_pre_open()
1288 else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) && in channel_pre_open()
1289 (c->extended_usage == CHAN_EXTENDED_READ || in channel_pre_open()
1290 c->extended_usage == CHAN_EXTENDED_IGNORE) && in channel_pre_open()
1291 sshbuf_len(c->extended) < c->remote_window) in channel_pre_open()
1292 c->io_want |= SSH_CHAN_IO_EFD_R; in channel_pre_open()
1301 * data in that packet is then substituted by the real data if it matches the
1302 * fake data, and the channel is put into normal mode.
1304 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
1309 struct ssh_channels *sc = ssh->chanctxt; in x11_open_helper()
1314 if (sc->x11_refuse_time != 0 && in x11_open_helper()
1315 monotime() >= sc->x11_refuse_time) { in x11_open_helper()
1318 return -1; in x11_open_helper()
1325 /* Parse the lengths of variable-length fields. */ in x11_open_helper()
1336 return -1; in x11_open_helper()
1345 if (proto_len != strlen(sc->x11_saved_proto) || in x11_open_helper()
1346 memcmp(ucp + 12, sc->x11_saved_proto, proto_len) != 0) { in x11_open_helper()
1348 return -1; in x11_open_helper()
1350 /* Check if authentication data matches our fake data. */ in x11_open_helper()
1351 if (data_len != sc->x11_fake_data_len || in x11_open_helper()
1353 sc->x11_fake_data, sc->x11_fake_data_len) != 0) { in x11_open_helper()
1354 debug2("X11 auth data does not match fake data."); in x11_open_helper()
1355 return -1; in x11_open_helper()
1357 /* Check fake data length */ in x11_open_helper()
1358 if (sc->x11_fake_data_len != sc->x11_saved_data_len) { in x11_open_helper()
1360 sc->x11_fake_data_len, sc->x11_saved_data_len); in x11_open_helper()
1361 return -1; in x11_open_helper()
1364 * Received authentication protocol and data match in x11_open_helper()
1365 * our fake data. Substitute the fake data with real in x11_open_helper()
1366 * data. in x11_open_helper()
1369 sc->x11_saved_data, sc->x11_saved_data_len); in x11_open_helper()
1374 channel_force_close(struct ssh *ssh, Channel *c, int abandon) in channel_force_close()
1376 debug3_f("channel %d: forcibly closing", c->self); in channel_force_close()
1377 if (c->istate == CHAN_INPUT_OPEN) in channel_force_close()
1379 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_force_close()
1380 sshbuf_reset(c->input); in channel_force_close()
1383 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_force_close()
1384 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_force_close()
1385 sshbuf_reset(c->output); in channel_force_close()
1388 if (c->detach_user) in channel_force_close()
1389 c->detach_user(ssh, c->self, 1, NULL); in channel_force_close()
1390 if (c->efd != -1) in channel_force_close()
1391 channel_close_fd(ssh, c, &c->efd); in channel_force_close()
1393 c->type = SSH_CHANNEL_ABANDONED; in channel_force_close()
1395 c->inactive_deadline = 0; in channel_force_close()
1396 c->lastused = 0; in channel_force_close()
1400 channel_pre_x11_open(struct ssh *ssh, Channel *c) in channel_pre_x11_open()
1402 int ret = x11_open_helper(ssh, c->output); in channel_pre_x11_open()
1404 /* c->force_drain = 1; */ in channel_pre_x11_open()
1407 c->type = SSH_CHANNEL_OPEN; in channel_pre_x11_open()
1410 } else if (ret == -1) { in channel_pre_x11_open()
1414 c->self, c->istate, c->ostate); in channel_pre_x11_open()
1420 channel_pre_mux_client(struct ssh *ssh, Channel *c) in channel_pre_mux_client()
1422 c->io_want = 0; in channel_pre_mux_client()
1423 if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause && in channel_pre_mux_client()
1424 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0) in channel_pre_mux_client()
1425 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_mux_client()
1426 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_pre_mux_client()
1428 sshbuf_reset(c->input); in channel_pre_mux_client()
1433 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_pre_mux_client()
1434 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_mux_client()
1435 if (sshbuf_len(c->output) > 0) in channel_pre_mux_client()
1436 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_mux_client()
1437 else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) in channel_pre_mux_client()
1444 channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output) in channel_decode_socks4()
1458 debug2("channel %d: decode socks4", c->self); in channel_decode_socks4()
1469 debug2("channel %d: socks4a request", c->self); in channel_decode_socks4()
1482 debug("channel %d: decode socks4: too long", in channel_decode_socks4()
1483 c->self); in channel_decode_socks4()
1484 return -1; in channel_decode_socks4()
1493 debug_r(r, "channels %d: decode socks4", c->self); in channel_decode_socks4()
1494 return -1; in channel_decode_socks4()
1499 error("channel %d: decode socks4: unterminated user", c->self); in channel_decode_socks4()
1500 return -1; in channel_decode_socks4()
1503 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); in channel_decode_socks4()
1507 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks4()
1508 free(c->path); in channel_decode_socks4()
1509 c->path = NULL; in channel_decode_socks4()
1512 c->path = xstrdup(host); in channel_decode_socks4()
1517 error("channel %d: decode socks4a: host not nul " in channel_decode_socks4()
1518 "terminated", c->self); in channel_decode_socks4()
1519 return -1; in channel_decode_socks4()
1522 debug2("channel %d: decode socks4a: host %s/%d", in channel_decode_socks4()
1523 c->self, p, len); in channel_decode_socks4()
1526 error("channel %d: hostname \"%.100s\" too long", in channel_decode_socks4()
1527 c->self, p); in channel_decode_socks4()
1528 return -1; in channel_decode_socks4()
1530 c->path = xstrdup(p); in channel_decode_socks4()
1532 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks4()
1534 c->host_port = ntohs(s4_req.dest_port); in channel_decode_socks4()
1536 debug2("channel %d: dynamic request: socks4 host %s port %u command %u", in channel_decode_socks4()
1537 c->self, c->path, c->host_port, s4_req.command); in channel_decode_socks4()
1540 debug("channel %d: cannot handle: %s cn %d", in channel_decode_socks4()
1541 c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command); in channel_decode_socks4()
1542 return -1; in channel_decode_socks4()
1549 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks4()
1563 channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output) in channel_decode_socks5()
1578 debug2("channel %d: decode socks5", c->self); in channel_decode_socks5()
1581 return -1; in channel_decode_socks5()
1583 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { in channel_decode_socks5()
1598 debug("channel %d: method SSH_SOCKS5_NOAUTH not found", in channel_decode_socks5()
1599 c->self); in channel_decode_socks5()
1600 return -1; in channel_decode_socks5()
1603 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1607 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks5()
1608 c->flags |= SSH_SOCKS5_AUTHDONE; in channel_decode_socks5()
1609 debug2("channel %d: socks5 auth done", c->self); in channel_decode_socks5()
1612 debug2("channel %d: socks5 post auth", c->self); in channel_decode_socks5()
1619 debug2("channel %d: only socks5 connect supported", c->self); in channel_decode_socks5()
1620 return -1; in channel_decode_socks5()
1629 af = -1; in channel_decode_socks5()
1636 debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); in channel_decode_socks5()
1637 return -1; in channel_decode_socks5()
1645 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1649 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1653 debug_r(r, "channel %d: parse addr/port", c->self); in channel_decode_socks5()
1654 return -1; in channel_decode_socks5()
1657 free(c->path); in channel_decode_socks5()
1658 c->path = NULL; in channel_decode_socks5()
1661 error("channel %d: dynamic request: socks5 hostname " in channel_decode_socks5()
1662 "\"%.100s\" too long", c->self, dest_addr); in channel_decode_socks5()
1663 return -1; in channel_decode_socks5()
1665 c->path = xstrdup(dest_addr); in channel_decode_socks5()
1668 return -1; in channel_decode_socks5()
1669 c->path = xstrdup(ntop); in channel_decode_socks5()
1671 c->host_port = ntohs(dest_port); in channel_decode_socks5()
1673 debug2("channel %d: dynamic request: socks5 host %s port %u command %u", in channel_decode_socks5()
1674 c->self, c->path, c->host_port, s5_req.command); in channel_decode_socks5()
1685 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks5()
1689 Channel *
1694 Channel *c; in channel_connect_stdio_fwd()
1698 c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, in channel_connect_stdio_fwd()
1699 -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, in channel_connect_stdio_fwd()
1700 0, "stdio-forward", nonblock); in channel_connect_stdio_fwd()
1702 c->path = xstrdup(host_to_connect); in channel_connect_stdio_fwd()
1703 c->host_port = port_to_connect; in channel_connect_stdio_fwd()
1704 c->listening_port = 0; in channel_connect_stdio_fwd()
1705 c->force_drain = 1; in channel_connect_stdio_fwd()
1707 channel_register_fds(ssh, c, in, out, -1, 0, 1, 0); in channel_connect_stdio_fwd()
1709 "direct-streamlocal@openssh.com" : "direct-tcpip"); in channel_connect_stdio_fwd()
1716 channel_pre_dynamic(struct ssh *ssh, Channel *c) in channel_pre_dynamic()
1722 c->io_want = 0; in channel_pre_dynamic()
1723 have = sshbuf_len(c->input); in channel_pre_dynamic()
1724 debug2("channel %d: pre_dynamic: have %d", c->self, have); in channel_pre_dynamic()
1725 /* sshbuf_dump(c->input, stderr); */ in channel_pre_dynamic()
1729 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_dynamic()
1733 p = sshbuf_ptr(c->input); in channel_pre_dynamic()
1737 ret = channel_decode_socks4(c, c->input, c->output); in channel_pre_dynamic()
1740 ret = channel_decode_socks5(c, c->input, c->output); in channel_pre_dynamic()
1743 ret = -1; in channel_pre_dynamic()
1749 debug2("channel %d: pre_dynamic: need more", c->self); in channel_pre_dynamic()
1751 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_dynamic()
1752 if (sshbuf_len(c->output)) in channel_pre_dynamic()
1753 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_dynamic()
1756 c->type = SSH_CHANNEL_OPENING; in channel_pre_dynamic()
1757 port_open_helper(ssh, c, "direct-tcpip"); in channel_pre_dynamic()
1761 /* simulate read-error */
1763 rdynamic_close(struct ssh *ssh, Channel *c) in rdynamic_close()
1765 c->type = SSH_CHANNEL_OPEN; in rdynamic_close()
1771 channel_before_prepare_io_rdynamic(struct ssh *ssh, Channel *c) in channel_before_prepare_io_rdynamic()
1777 have = sshbuf_len(c->output); in channel_before_prepare_io_rdynamic()
1778 debug2("channel %d: pre_rdynamic: have %d", c->self, have); in channel_before_prepare_io_rdynamic()
1779 /* sshbuf_dump(c->output, stderr); */ in channel_before_prepare_io_rdynamic()
1781 if (c->flags & CHAN_EOF_RCVD) { in channel_before_prepare_io_rdynamic()
1782 if ((r = sshbuf_consume(c->output, have)) != 0) in channel_before_prepare_io_rdynamic()
1783 fatal_fr(r, "channel %d: consume", c->self); in channel_before_prepare_io_rdynamic()
1791 p = sshbuf_ptr(c->output); in channel_before_prepare_io_rdynamic()
1795 ret = channel_decode_socks4(c, c->output, c->input); in channel_before_prepare_io_rdynamic()
1798 ret = channel_decode_socks5(c, c->output, c->input); in channel_before_prepare_io_rdynamic()
1801 ret = -1; in channel_before_prepare_io_rdynamic()
1807 debug2("channel %d: pre_rdynamic: need more", c->self); in channel_before_prepare_io_rdynamic()
1809 len = sshbuf_len(c->input); in channel_before_prepare_io_rdynamic()
1810 if (len > 0 && len < c->remote_window) { in channel_before_prepare_io_rdynamic()
1812 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_before_prepare_io_rdynamic()
1813 (r = sshpkt_put_stringb(ssh, c->input)) != 0 || in channel_before_prepare_io_rdynamic()
1815 fatal_fr(r, "channel %i: rdynamic", c->self); in channel_before_prepare_io_rdynamic()
1817 if ((r = sshbuf_consume(c->input, len)) != 0) in channel_before_prepare_io_rdynamic()
1818 fatal_fr(r, "channel %d: consume", c->self); in channel_before_prepare_io_rdynamic()
1819 c->remote_window -= len; in channel_before_prepare_io_rdynamic()
1829 channel_post_x11_listener(struct ssh *ssh, Channel *c) in channel_post_x11_listener()
1831 Channel *nc; in channel_post_x11_listener()
1837 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_x11_listener()
1842 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_x11_listener()
1843 if (c->single_connection) { in channel_post_x11_listener()
1846 channel_close_fd(ssh, c, &c->sock); in channel_post_x11_listener()
1850 if (newsock == -1) { in channel_post_x11_listener()
1855 c->notbefore = monotime() + 1; in channel_post_x11_listener()
1864 nc = channel_new(ssh, "x11-connection", in channel_post_x11_listener()
1865 SSH_CHANNEL_OPENING, newsock, newsock, -1, in channel_post_x11_listener()
1866 c->local_window_max, c->local_maxpacket, 0, buf, 1); in channel_post_x11_listener()
1870 fatal_fr(r, "channel %i: reply", c->self); in channel_post_x11_listener()
1873 fatal_fr(r, "channel %i: send", c->self); in channel_post_x11_listener()
1878 port_open_helper(struct ssh *ssh, Channel *c, char *rtype) in port_open_helper()
1880 char *local_ipaddr = get_local_ipaddr(c->sock); in port_open_helper()
1881 int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock); in port_open_helper()
1882 char *remote_ipaddr = get_peer_ipaddr(c->sock); in port_open_helper()
1883 int remote_port = get_peer_port(c->sock); in port_open_helper()
1886 if (remote_port == -1) { in port_open_helper()
1893 free(c->remote_name); in port_open_helper()
1894 xasprintf(&c->remote_name, in port_open_helper()
1897 rtype, c->listening_port, c->path, c->host_port, in port_open_helper()
1901 if (strcmp(rtype, "direct-tcpip") == 0) { in port_open_helper()
1903 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 || in port_open_helper()
1904 (r = sshpkt_put_u32(ssh, c->host_port)) != 0) in port_open_helper()
1905 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1906 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) { in port_open_helper()
1908 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) in port_open_helper()
1909 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1910 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { in port_open_helper()
1912 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) in port_open_helper()
1913 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1916 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 || in port_open_helper()
1918 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1920 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { in port_open_helper()
1923 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1928 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1931 fatal_fr(r, "channel %i: send", c->self); in port_open_helper()
1939 ssh->chanctxt->x11_refuse_time = refuse_time; in channel_set_x11_refuse_time()
1946 channel_post_port_listener(struct ssh *ssh, Channel *c) in channel_post_port_listener()
1948 Channel *nc; in channel_post_port_listener()
1954 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_port_listener()
1958 c->listening_port, c->path, c->host_port); in channel_post_port_listener()
1960 if (c->type == SSH_CHANNEL_RPORT_LISTENER) { in channel_post_port_listener()
1962 rtype = "forwarded-tcpip"; in channel_post_port_listener()
1963 } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) { in channel_post_port_listener()
1965 rtype = "forwarded-streamlocal@openssh.com"; in channel_post_port_listener()
1966 } else if (c->host_port == PORT_STREAMLOCAL) { in channel_post_port_listener()
1968 rtype = "direct-streamlocal@openssh.com"; in channel_post_port_listener()
1969 } else if (c->host_port == 0) { in channel_post_port_listener()
1971 rtype = "dynamic-tcpip"; in channel_post_port_listener()
1974 rtype = "direct-tcpip"; in channel_post_port_listener()
1978 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_port_listener()
1979 if (newsock == -1) { in channel_post_port_listener()
1984 c->notbefore = monotime() + 1; in channel_post_port_listener()
1987 if (c->host_port != PORT_STREAMLOCAL) in channel_post_port_listener()
1989 nc = channel_new(ssh, rtype, nextstate, newsock, newsock, -1, in channel_post_port_listener()
1990 c->local_window_max, c->local_maxpacket, 0, rtype, 1); in channel_post_port_listener()
1991 nc->listening_port = c->listening_port; in channel_post_port_listener()
1992 nc->host_port = c->host_port; in channel_post_port_listener()
1993 if (c->path != NULL) in channel_post_port_listener()
1994 nc->path = xstrdup(c->path); in channel_post_port_listener()
2005 channel_post_auth_listener(struct ssh *ssh, Channel *c) in channel_post_auth_listener()
2007 Channel *nc; in channel_post_auth_listener()
2012 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_auth_listener()
2016 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_auth_listener()
2017 if (newsock == -1) { in channel_post_auth_listener()
2020 c->notbefore = monotime() + 1; in channel_post_auth_listener()
2023 nc = channel_new(ssh, "agent-connection", in channel_post_auth_listener()
2024 SSH_CHANNEL_OPENING, newsock, newsock, -1, in channel_post_auth_listener()
2025 c->local_window_max, c->local_maxpacket, in channel_post_auth_listener()
2027 open_preamble(ssh, __func__, nc, "auth-agent@openssh.com"); in channel_post_auth_listener()
2029 fatal_fr(r, "channel %i", c->self); in channel_post_auth_listener()
2033 channel_post_connecting(struct ssh *ssh, Channel *c) in channel_post_connecting()
2038 if ((c->io_ready & SSH_CHAN_IO_SOCK_W) == 0) in channel_post_connecting()
2040 if (!c->have_remote_id) in channel_post_connecting()
2041 fatal_f("channel %d: no remote id", c->self); in channel_post_connecting()
2043 isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH); in channel_post_connecting()
2045 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) == -1) { in channel_post_connecting()
2051 /* Non-blocking connection completed */ in channel_post_connecting()
2052 debug("channel %d: connected to %s port %d", in channel_post_connecting()
2053 c->self, c->connect_ctx.host, c->connect_ctx.port); in channel_post_connecting()
2054 channel_connect_ctx_free(&c->connect_ctx); in channel_post_connecting()
2055 c->type = SSH_CHANNEL_OPEN; in channel_post_connecting()
2062 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_post_connecting()
2063 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in channel_post_connecting()
2064 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in channel_post_connecting()
2065 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 || in channel_post_connecting()
2067 fatal_fr(r, "channel %i open confirm", c->self); in channel_post_connecting()
2074 /* Non-blocking connection failed */ in channel_post_connecting()
2075 debug("channel %d: connection failed: %s", c->self, strerror(err)); in channel_post_connecting()
2078 if ((sock = connect_next(&c->connect_ctx)) == -1) { in channel_post_connecting()
2081 c->connect_ctx.host, c->connect_ctx.port); in channel_post_connecting()
2082 channel_connect_ctx_free(&c->connect_ctx); in channel_post_connecting()
2088 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_post_connecting()
2094 fatal_fr(r, "channel %i: failure", c->self); in channel_post_connecting()
2099 /* New non-blocking connection in progress */ in channel_post_connecting()
2100 close(c->sock); in channel_post_connecting()
2101 c->sock = c->rfd = c->wfd = sock; in channel_post_connecting()
2105 channel_handle_rfd(struct ssh *ssh, Channel *c) in channel_handle_rfd()
2114 /* Bug on AIX: read(1) can return 0 for a non-closed fd */ in channel_handle_rfd()
2115 pty_zeroread = c->isatty; in channel_handle_rfd()
2118 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; in channel_handle_rfd()
2120 if (!force && (c->io_ready & SSH_CHAN_IO_RFD) == 0) in channel_handle_rfd()
2122 if ((avail = sshbuf_avail(c->input)) == 0) in channel_handle_rfd()
2127 * read directly to the channel buffer. in channel_handle_rfd()
2129 if (!pty_zeroread && c->input_filter == NULL && !c->datagram) { in channel_handle_rfd()
2131 if (c->type == SSH_CHANNEL_OPEN) { in channel_handle_rfd()
2132 if ((have = sshbuf_len(c->input)) >= c->remote_window) in channel_handle_rfd()
2134 if (maxlen > c->remote_window - have) in channel_handle_rfd()
2135 maxlen = c->remote_window - have; in channel_handle_rfd()
2139 if ((r = sshbuf_read(c->rfd, c->input, maxlen, &nr)) != 0) { in channel_handle_rfd()
2143 debug2("channel %d: read failed rfd %d maxlen %zu: %s", in channel_handle_rfd()
2144 c->self, c->rfd, maxlen, ssh_err(r)); in channel_handle_rfd()
2153 len = read(c->rfd, buf, sizeof(buf)); in channel_handle_rfd()
2154 /* fixup AIX zero-length read with errno set to look more like errors */ in channel_handle_rfd()
2156 len = -1; in channel_handle_rfd()
2157 if (len == -1 && (errno == EINTR || in channel_handle_rfd()
2161 debug2("channel %d: read<=0 rfd %d len %zd: %s", in channel_handle_rfd()
2162 c->self, c->rfd, len, in channel_handle_rfd()
2165 if (c->type != SSH_CHANNEL_OPEN) { in channel_handle_rfd()
2166 debug2("channel %d: not open", c->self); in channel_handle_rfd()
2168 return -1; in channel_handle_rfd()
2172 return -1; in channel_handle_rfd()
2175 if (c->input_filter != NULL) { in channel_handle_rfd()
2176 if (c->input_filter(ssh, c, buf, len) == -1) { in channel_handle_rfd()
2177 debug2("channel %d: filter stops", c->self); in channel_handle_rfd()
2180 } else if (c->datagram) { in channel_handle_rfd()
2181 if ((r = sshbuf_put_string(c->input, buf, len)) != 0) in channel_handle_rfd()
2182 fatal_fr(r, "channel %i: put datagram", c->self); in channel_handle_rfd()
2183 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) in channel_handle_rfd()
2184 fatal_fr(r, "channel %i: put data", c->self); in channel_handle_rfd()
2190 channel_handle_wfd(struct ssh *ssh, Channel *c) in channel_handle_wfd()
2193 u_char *data = NULL, *buf; /* XXX const; need filter API change */ in channel_handle_wfd() local
2197 if ((c->io_ready & SSH_CHAN_IO_WFD) == 0) in channel_handle_wfd()
2199 if (sshbuf_len(c->output) == 0) in channel_handle_wfd()
2202 /* Send buffered output data to the socket. */ in channel_handle_wfd()
2203 olen = sshbuf_len(c->output); in channel_handle_wfd()
2204 if (c->output_filter != NULL) { in channel_handle_wfd()
2205 if ((buf = c->output_filter(ssh, c, &data, &dlen)) == NULL) { in channel_handle_wfd()
2206 debug2("channel %d: filter stops", c->self); in channel_handle_wfd()
2207 if (c->type != SSH_CHANNEL_OPEN) in channel_handle_wfd()
2211 return -1; in channel_handle_wfd()
2213 } else if (c->datagram) { in channel_handle_wfd()
2214 if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0) in channel_handle_wfd()
2215 fatal_fr(r, "channel %i: get datagram", c->self); in channel_handle_wfd()
2216 buf = data; in channel_handle_wfd()
2218 buf = data = sshbuf_mutable_ptr(c->output); in channel_handle_wfd()
2219 dlen = sshbuf_len(c->output); in channel_handle_wfd()
2222 if (c->datagram) { in channel_handle_wfd()
2224 len = write(c->wfd, buf, dlen); in channel_handle_wfd()
2225 free(data); in channel_handle_wfd()
2226 if (len == -1 && (errno == EINTR || errno == EAGAIN || in channel_handle_wfd()
2235 /* XXX: Later AIX versions can't push as much data to tty */ in channel_handle_wfd()
2236 if (c->wfd_isatty) in channel_handle_wfd()
2240 len = write(c->wfd, buf, dlen); in channel_handle_wfd()
2241 if (len == -1 && in channel_handle_wfd()
2246 if (c->type != SSH_CHANNEL_OPEN) { in channel_handle_wfd()
2247 debug2("channel %d: not open", c->self); in channel_handle_wfd()
2249 return -1; in channel_handle_wfd()
2253 return -1; in channel_handle_wfd()
2257 if (c->isatty && dlen >= 1 && buf[0] != '\r') { in channel_handle_wfd()
2258 if (tcgetattr(c->wfd, &tio) == 0 && in channel_handle_wfd()
2264 * (4 byte channel id + buf) in channel_handle_wfd()
2268 fatal_fr(r, "channel %i: ignore", c->self); in channel_handle_wfd()
2272 if ((r = sshbuf_consume(c->output, len)) != 0) in channel_handle_wfd()
2273 fatal_fr(r, "channel %i: consume", c->self); in channel_handle_wfd()
2275 c->local_consumed += olen - sshbuf_len(c->output); in channel_handle_wfd()
2281 channel_handle_efd_write(struct ssh *ssh, Channel *c) in channel_handle_efd_write()
2286 if ((c->io_ready & SSH_CHAN_IO_EFD_W) == 0) in channel_handle_efd_write()
2288 if (sshbuf_len(c->extended) == 0) in channel_handle_efd_write()
2291 len = write(c->efd, sshbuf_ptr(c->extended), in channel_handle_efd_write()
2292 sshbuf_len(c->extended)); in channel_handle_efd_write()
2293 debug2("channel %d: written %zd to efd %d", c->self, len, c->efd); in channel_handle_efd_write()
2294 if (len == -1 && (errno == EINTR || errno == EAGAIN || in channel_handle_efd_write()
2298 debug2("channel %d: closing write-efd %d", c->self, c->efd); in channel_handle_efd_write()
2299 channel_close_fd(ssh, c, &c->efd); in channel_handle_efd_write()
2301 if ((r = sshbuf_consume(c->extended, len)) != 0) in channel_handle_efd_write()
2302 fatal_fr(r, "channel %i: consume", c->self); in channel_handle_efd_write()
2303 c->local_consumed += len; in channel_handle_efd_write()
2310 channel_handle_efd_read(struct ssh *ssh, Channel *c) in channel_handle_efd_read()
2316 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; in channel_handle_efd_read()
2318 if (!force && (c->io_ready & SSH_CHAN_IO_EFD_R) == 0) in channel_handle_efd_read()
2321 len = read(c->efd, buf, sizeof(buf)); in channel_handle_efd_read()
2322 debug2("channel %d: read %zd from efd %d", c->self, len, c->efd); in channel_handle_efd_read()
2323 if (len == -1 && (errno == EINTR || ((errno == EAGAIN || in channel_handle_efd_read()
2327 debug2("channel %d: closing read-efd %d", c->self, c->efd); in channel_handle_efd_read()
2328 channel_close_fd(ssh, c, &c->efd); in channel_handle_efd_read()
2332 if (c->extended_usage == CHAN_EXTENDED_IGNORE) in channel_handle_efd_read()
2333 debug3("channel %d: discard efd", c->self); in channel_handle_efd_read()
2334 else if ((r = sshbuf_put(c->extended, buf, len)) != 0) in channel_handle_efd_read()
2335 fatal_fr(r, "channel %i: append", c->self); in channel_handle_efd_read()
2340 channel_handle_efd(struct ssh *ssh, Channel *c) in channel_handle_efd()
2342 if (c->efd == -1) in channel_handle_efd()
2347 if (c->extended_usage == CHAN_EXTENDED_WRITE) in channel_handle_efd()
2349 else if (c->extended_usage == CHAN_EXTENDED_READ || in channel_handle_efd()
2350 c->extended_usage == CHAN_EXTENDED_IGNORE) in channel_handle_efd()
2357 channel_check_window(struct ssh *ssh, Channel *c) in channel_check_window()
2361 if (c->type == SSH_CHANNEL_OPEN && in channel_check_window()
2362 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && in channel_check_window()
2363 ((c->local_window_max - c->local_window > in channel_check_window()
2364 c->local_maxpacket*3) || in channel_check_window()
2365 c->local_window < c->local_window_max/2) && in channel_check_window()
2366 c->local_consumed > 0) { in channel_check_window()
2367 if (!c->have_remote_id) in channel_check_window()
2368 fatal_f("channel %d: no remote id", c->self); in channel_check_window()
2371 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_check_window()
2372 (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 || in channel_check_window()
2374 fatal_fr(r, "channel %i", c->self); in channel_check_window()
2376 debug2("channel %d: window %d sent adjust %d", c->self, in channel_check_window()
2377 c->local_window, c->local_consumed); in channel_check_window()
2378 c->local_window += c->local_consumed; in channel_check_window()
2379 c->local_consumed = 0; in channel_check_window()
2385 channel_post_open(struct ssh *ssh, Channel *c) in channel_post_open()
2394 read_mux(struct ssh *ssh, Channel *c, u_int need) in read_mux()
2401 if (sshbuf_len(c->input) < need) { in read_mux()
2402 rlen = need - sshbuf_len(c->input); in read_mux()
2403 len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF)); in read_mux()
2404 if (len == -1 && (errno == EINTR || errno == EAGAIN)) in read_mux()
2405 return sshbuf_len(c->input); in read_mux()
2407 debug2("channel %d: ctl read<=0 rfd %d len %zd", in read_mux()
2408 c->self, c->rfd, len); in read_mux()
2411 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) in read_mux()
2412 fatal_fr(r, "channel %i: append", c->self); in read_mux()
2414 return sshbuf_len(c->input); in read_mux()
2418 channel_post_mux_client_read(struct ssh *ssh, Channel *c) in channel_post_mux_client_read()
2422 if ((c->io_ready & SSH_CHAN_IO_RFD) == 0) in channel_post_mux_client_read()
2424 if (c->istate != CHAN_INPUT_OPEN && c->istate != CHAN_INPUT_WAIT_DRAIN) in channel_post_mux_client_read()
2426 if (c->mux_pause) in channel_post_mux_client_read()
2436 need = PEEK_U32(sshbuf_ptr(c->input)); in channel_post_mux_client_read()
2439 debug2("channel %d: packet too big %u > %u", in channel_post_mux_client_read()
2440 c->self, CHANNEL_MUX_MAX_PACKET, need); in channel_post_mux_client_read()
2446 if (c->mux_rcb(ssh, c) != 0) { in channel_post_mux_client_read()
2447 debug("channel %d: mux_rcb failed", c->self); in channel_post_mux_client_read()
2454 channel_post_mux_client_write(struct ssh *ssh, Channel *c) in channel_post_mux_client_write()
2459 if ((c->io_ready & SSH_CHAN_IO_WFD) == 0) in channel_post_mux_client_write()
2461 if (sshbuf_len(c->output) == 0) in channel_post_mux_client_write()
2464 len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output)); in channel_post_mux_client_write()
2465 if (len == -1 && (errno == EINTR || errno == EAGAIN)) in channel_post_mux_client_write()
2471 if ((r = sshbuf_consume(c->output, len)) != 0) in channel_post_mux_client_write()
2472 fatal_fr(r, "channel %i: consume", c->self); in channel_post_mux_client_write()
2476 channel_post_mux_client(struct ssh *ssh, Channel *c) in channel_post_mux_client()
2483 channel_post_mux_listener(struct ssh *ssh, Channel *c) in channel_post_mux_listener()
2485 Channel *nc; in channel_post_mux_listener()
2492 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_mux_listener()
2502 if ((newsock = accept(c->sock, (struct sockaddr*)&addr, in channel_post_mux_listener()
2503 &addrlen)) == -1) { in channel_post_mux_listener()
2506 c->notbefore = monotime() + 1; in channel_post_mux_listener()
2510 if (getpeereid(newsock, &euid, &egid) == -1) { in channel_post_mux_listener()
2521 nc = channel_new(ssh, "mux-control", SSH_CHANNEL_MUX_CLIENT, in channel_post_mux_listener()
2522 newsock, newsock, -1, c->local_window_max, in channel_post_mux_listener()
2523 c->local_maxpacket, 0, "mux-control", 1); in channel_post_mux_listener()
2524 nc->mux_rcb = c->mux_rcb; in channel_post_mux_listener()
2525 debug3_f("new mux channel %d fd %d", nc->self, nc->sock); in channel_post_mux_listener()
2527 nc->mux_rcb(ssh, nc); in channel_post_mux_listener()
2529 nc->flags |= CHAN_LOCAL; in channel_post_mux_listener()
2568 sc->channel_pre = pre; in channel_handler_init()
2569 sc->channel_post = post; in channel_handler_init()
2574 channel_garbage_collect(struct ssh *ssh, Channel *c) in channel_garbage_collect()
2578 if (c->detach_user != NULL) { in channel_garbage_collect()
2579 if (!chan_is_dead(ssh, c, c->detach_close)) in channel_garbage_collect()
2582 debug2("channel %d: gc: notify user", c->self); in channel_garbage_collect()
2583 c->detach_user(ssh, c->self, 0, NULL); in channel_garbage_collect()
2585 if (c->detach_user != NULL) in channel_garbage_collect()
2587 debug2("channel %d: gc: user detached", c->self); in channel_garbage_collect()
2591 debug2("channel %d: garbage collecting", c->self); in channel_garbage_collect()
2600 struct ssh_channels *sc = ssh->chanctxt; in channel_handler()
2601 chan_fn **ftab = table == CHAN_PRE ? sc->channel_pre : sc->channel_post; in channel_handler()
2603 Channel *c; in channel_handler()
2607 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { in channel_handler()
2608 c = sc->channels[i]; in channel_handler()
2612 if (ssh_packet_is_rekeying(ssh) && c->type != SSH_CHANNEL_OPEN) in channel_handler()
2614 if (c->delayed) { in channel_handler()
2616 c->delayed = 0; in channel_handler()
2620 if (ftab[c->type] != NULL) { in channel_handler()
2621 if (table == CHAN_PRE && c->type == SSH_CHANNEL_OPEN && in channel_handler()
2624 /* channel closed for inactivity */ in channel_handler()
2625 verbose("channel %d: closing after %u seconds " in channel_handler()
2626 "of inactivity", c->self, in channel_handler()
2627 c->inactive_deadline); in channel_handler()
2629 } else if (c->notbefore <= now) { in channel_handler()
2631 (*ftab[c->type])(ssh, c); in channel_handler()
2634 c->type == SSH_CHANNEL_OPEN && in channel_handler()
2641 * Arrange for poll() wakeup when channel pause in channel_handler()
2645 c->notbefore); in channel_handler()
2655 * the network-input but need to be completed before IO event setup, e.g.
2661 struct ssh_channels *sc = ssh->chanctxt; in channel_before_prepare_io()
2662 Channel *c; in channel_before_prepare_io()
2665 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { in channel_before_prepare_io()
2666 c = sc->channels[i]; in channel_before_prepare_io()
2669 if (c->type == SSH_CHANNEL_RDYNAMIC_OPEN) in channel_before_prepare_io()
2675 dump_channel_poll(const char *func, const char *what, Channel *c, in dump_channel_poll()
2679 debug3("%s: channel %d: %s r%d w%d e%d s%d c->pfds [ %d %d %d %d ] " in dump_channel_poll()
2681 "pfd.ev 0x%02x pfd.rev 0x%02x", func, c->self, what, in dump_channel_poll()
2682 c->rfd, c->wfd, c->efd, c->sock, in dump_channel_poll()
2683 c->pfds[0], c->pfds[1], c->pfds[2], c->pfds[3], in dump_channel_poll()
2684 c->io_want, c->io_ready, in dump_channel_poll()
2685 pollfd_offset, pfd->fd, pfd->events, pfd->revents); in dump_channel_poll()
2689 /* Prepare pollfd entries for a single channel */
2691 channel_prepare_pollfd(Channel *c, u_int *next_pollfd, in channel_prepare_pollfd()
2700 fatal_f("channel %d: bad pfd offset %u (max %u)", in channel_prepare_pollfd()
2701 c->self, p, npfd); in channel_prepare_pollfd()
2703 c->pfds[0] = c->pfds[1] = c->pfds[2] = c->pfds[3] = -1; in channel_prepare_pollfd()
2705 * prepare c->rfd in channel_prepare_pollfd()
2707 * This is a special case, since c->rfd might be the same as in channel_prepare_pollfd()
2708 * c->wfd, c->efd and/or c->sock. Handle those here if they want in channel_prepare_pollfd()
2711 if (c->rfd != -1) { in channel_prepare_pollfd()
2713 if ((c->io_want & SSH_CHAN_IO_RFD) != 0) in channel_prepare_pollfd()
2716 if (c->wfd == c->rfd) { in channel_prepare_pollfd()
2717 if ((c->io_want & SSH_CHAN_IO_WFD) != 0) in channel_prepare_pollfd()
2721 if (c->efd == c->rfd) { in channel_prepare_pollfd()
2722 if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) in channel_prepare_pollfd()
2724 if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) in channel_prepare_pollfd()
2728 if (c->sock == c->rfd) { in channel_prepare_pollfd()
2729 if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) in channel_prepare_pollfd()
2731 if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) in channel_prepare_pollfd()
2736 c->pfds[0] = p; in channel_prepare_pollfd()
2737 pfd[p].fd = c->rfd; in channel_prepare_pollfd()
2743 /* prepare c->wfd if wanting IO and not already handled above */ in channel_prepare_pollfd()
2744 if (c->wfd != -1 && c->rfd != c->wfd) { in channel_prepare_pollfd()
2746 if ((c->io_want & SSH_CHAN_IO_WFD)) in channel_prepare_pollfd()
2750 c->pfds[1] = p; in channel_prepare_pollfd()
2751 pfd[p].fd = c->wfd; in channel_prepare_pollfd()
2757 /* prepare c->efd if wanting IO and not already handled above */ in channel_prepare_pollfd()
2758 if (c->efd != -1 && c->rfd != c->efd) { in channel_prepare_pollfd()
2760 if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) in channel_prepare_pollfd()
2762 if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) in channel_prepare_pollfd()
2766 c->pfds[2] = p; in channel_prepare_pollfd()
2767 pfd[p].fd = c->efd; in channel_prepare_pollfd()
2773 /* prepare c->sock if wanting IO and not already handled above */ in channel_prepare_pollfd()
2774 if (c->sock != -1 && c->rfd != c->sock) { in channel_prepare_pollfd()
2776 if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) in channel_prepare_pollfd()
2778 if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) in channel_prepare_pollfd()
2782 c->pfds[3] = p; in channel_prepare_pollfd()
2783 pfd[p].fd = c->sock; in channel_prepare_pollfd()
2797 struct ssh_channels *sc = ssh->chanctxt; in channel_prepare_poll()
2800 channel_before_prepare_io(ssh); /* might create a new channel */ in channel_prepare_poll()
2802 for (i = 0; i < sc->channels_alloc; i++) { in channel_prepare_poll()
2803 if (sc->channels[i] == NULL) in channel_prepare_poll()
2805 sc->channels[i]->io_want = sc->channels[i]->io_ready = 0; in channel_prepare_poll()
2807 /* Allocate 4x pollfd for each channel (rfd, wfd, efd, sock) */ in channel_prepare_poll()
2808 if (sc->channels_alloc >= (INT_MAX / 4) - npfd_reserved) in channel_prepare_poll()
2810 npfd += sc->channels_alloc * 4; in channel_prepare_poll()
2817 oalloc = sc->channels_alloc; in channel_prepare_poll()
2821 if (oalloc != sc->channels_alloc) { in channel_prepare_poll()
2824 "(was %u, now %u)", oalloc, sc->channels_alloc); in channel_prepare_poll()
2829 for (i = 0; i < sc->channels_alloc; i++) in channel_prepare_poll()
2830 channel_prepare_pollfd(sc->channels[i], &p, *pfdp, npfd); in channel_prepare_poll()
2835 fd_ready(Channel *c, int p, struct pollfd *pfds, u_int npfd, int fd, in fd_ready()
2840 if (fd == -1) in fd_ready()
2842 if (p == -1 || (u_int)p >= npfd) in fd_ready()
2843 fatal_f("channel %d: bad pfd %d (max %u)", c->self, p, npfd); in fd_ready()
2845 if (pfd->fd != fd) { in fd_ready()
2846 fatal("channel %d: inconsistent %s fd=%d pollfd[%u].fd %d " in fd_ready()
2847 "r%d w%d e%d s%d", c->self, what, fd, p, pfd->fd, in fd_ready()
2848 c->rfd, c->wfd, c->efd, c->sock); in fd_ready()
2850 if ((pfd->revents & POLLNVAL) != 0) { in fd_ready()
2851 fatal("channel %d: invalid %s pollfd[%u].fd %d r%d w%d e%d s%d", in fd_ready()
2852 c->self, what, p, pfd->fd, c->rfd, c->wfd, c->efd, c->sock); in fd_ready()
2854 if ((pfd->revents & (revents_mask|POLLHUP|POLLERR)) != 0) in fd_ready()
2855 c->io_ready |= ready & c->io_want; in fd_ready()
2865 struct ssh_channels *sc = ssh->chanctxt; in channel_after_poll()
2868 Channel *c; in channel_after_poll()
2879 /* Convert pollfd into c->io_ready */ in channel_after_poll()
2880 for (i = 0; i < sc->channels_alloc; i++) { in channel_after_poll()
2881 c = sc->channels[i]; in channel_after_poll()
2885 if (c->rfd != -1 && c->wfd != -1 && c->rfd != c->wfd && in channel_after_poll()
2886 (c->rfd == c->efd || c->rfd == c->sock)) { in channel_after_poll()
2888 fatal_f("channel %d: unexpected fds r%d w%d e%d s%d", in channel_after_poll()
2889 c->self, c->rfd, c->wfd, c->efd, c->sock); in channel_after_poll()
2891 c->io_ready = 0; in channel_after_poll()
2893 if (c->rfd != -1 && (p = c->pfds[0]) != -1) { in channel_after_poll()
2894 fd_ready(c, p, pfd, npfd, c->rfd, in channel_after_poll()
2896 if (c->rfd == c->wfd) { in channel_after_poll()
2897 fd_ready(c, p, pfd, npfd, c->wfd, in channel_after_poll()
2900 if (c->rfd == c->efd) { in channel_after_poll()
2901 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2903 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2906 if (c->rfd == c->sock) { in channel_after_poll()
2907 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2909 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2915 if (c->wfd != -1 && c->wfd != c->rfd && in channel_after_poll()
2916 (p = c->pfds[1]) != -1) { in channel_after_poll()
2917 fd_ready(c, p, pfd, npfd, c->wfd, in channel_after_poll()
2922 if (c->efd != -1 && c->efd != c->rfd && in channel_after_poll()
2923 (p = c->pfds[2]) != -1) { in channel_after_poll()
2924 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2926 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2931 if (c->sock != -1 && c->sock != c->rfd && in channel_after_poll()
2932 (p = c->pfds[3]) != -1) { in channel_after_poll()
2933 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2935 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2944 * Enqueue data for channels with open or draining c->input.
2945 * Returns non-zero if a packet was enqueued.
2948 channel_output_poll_input_open(struct ssh *ssh, Channel *c) in channel_output_poll_input_open()
2954 if ((len = sshbuf_len(c->input)) == 0) { in channel_output_poll_input_open()
2955 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_output_poll_input_open()
2957 * input-buffer is empty and read-socket shutdown: in channel_output_poll_input_open()
2958 * tell peer, that we will not send more data: in channel_output_poll_input_open()
2960 * hack for extended data: delay EOF if EFD still in channel_output_poll_input_open()
2964 debug2("channel %d: " in channel_output_poll_input_open()
2966 c->self, c->efd, sshbuf_len(c->extended)); in channel_output_poll_input_open()
2973 if (!c->have_remote_id) in channel_output_poll_input_open()
2974 fatal_f("channel %d: no remote id", c->self); in channel_output_poll_input_open()
2976 if (c->datagram) { in channel_output_poll_input_open()
2978 if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0) in channel_output_poll_input_open()
2979 fatal_fr(r, "channel %i: get datagram", c->self); in channel_output_poll_input_open()
2981 * XXX this does tail-drop on the datagram queue which is in channel_output_poll_input_open()
2982 * usually suboptimal compared to head-drop. Better to have in channel_output_poll_input_open()
2985 if (plen > c->remote_window || plen > c->remote_maxpacket) { in channel_output_poll_input_open()
2986 debug("channel %d: datagram too big", c->self); in channel_output_poll_input_open()
2991 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_input_open()
2994 fatal_fr(r, "channel %i: send datagram", c->self); in channel_output_poll_input_open()
2995 c->remote_window -= plen; in channel_output_poll_input_open()
2999 /* Enqueue packet for buffered data. */ in channel_output_poll_input_open()
3000 if (len > c->remote_window) in channel_output_poll_input_open()
3001 len = c->remote_window; in channel_output_poll_input_open()
3002 if (len > c->remote_maxpacket) in channel_output_poll_input_open()
3003 len = c->remote_maxpacket; in channel_output_poll_input_open()
3007 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_input_open()
3008 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 || in channel_output_poll_input_open()
3010 fatal_fr(r, "channel %i: send data", c->self); in channel_output_poll_input_open()
3011 if ((r = sshbuf_consume(c->input, len)) != 0) in channel_output_poll_input_open()
3012 fatal_fr(r, "channel %i: consume", c->self); in channel_output_poll_input_open()
3013 c->remote_window -= len; in channel_output_poll_input_open()
3018 * Enqueue data for channels with open c->extended in read mode.
3019 * Returns non-zero if a packet was enqueued.
3022 channel_output_poll_extended_read(struct ssh *ssh, Channel *c) in channel_output_poll_extended_read()
3027 if ((len = sshbuf_len(c->extended)) == 0) in channel_output_poll_extended_read()
3030 debug2("channel %d: rwin %u elen %zu euse %d", c->self, in channel_output_poll_extended_read()
3031 c->remote_window, sshbuf_len(c->extended), c->extended_usage); in channel_output_poll_extended_read()
3032 if (len > c->remote_window) in channel_output_poll_extended_read()
3033 len = c->remote_window; in channel_output_poll_extended_read()
3034 if (len > c->remote_maxpacket) in channel_output_poll_extended_read()
3035 len = c->remote_maxpacket; in channel_output_poll_extended_read()
3038 if (!c->have_remote_id) in channel_output_poll_extended_read()
3039 fatal_f("channel %d: no remote id", c->self); in channel_output_poll_extended_read()
3041 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_extended_read()
3043 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 || in channel_output_poll_extended_read()
3045 fatal_fr(r, "channel %i: data", c->self); in channel_output_poll_extended_read()
3046 if ((r = sshbuf_consume(c->extended, len)) != 0) in channel_output_poll_extended_read()
3047 fatal_fr(r, "channel %i: consume", c->self); in channel_output_poll_extended_read()
3048 c->remote_window -= len; in channel_output_poll_extended_read()
3049 debug2("channel %d: sent ext data %zu", c->self, len); in channel_output_poll_extended_read()
3054 * If there is data to send to the connection, enqueue some of it now.
3055 * Returns non-zero if data was enqueued.
3060 struct ssh_channels *sc = ssh->chanctxt; in channel_output_poll()
3061 Channel *c; in channel_output_poll()
3065 for (i = 0; i < sc->channels_alloc; i++) { in channel_output_poll()
3066 c = sc->channels[i]; in channel_output_poll()
3072 * incoming data. in channel_output_poll()
3074 if (c->type != SSH_CHANNEL_OPEN) in channel_output_poll()
3076 if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { in channel_output_poll()
3078 debug3("channel %d: will not send data after close", in channel_output_poll()
3079 c->self); in channel_output_poll()
3083 /* Get the amount of buffered data for this channel. */ in channel_output_poll()
3084 if (c->istate == CHAN_INPUT_OPEN || in channel_output_poll()
3085 c->istate == CHAN_INPUT_WAIT_DRAIN) in channel_output_poll()
3087 /* Send extended data, i.e. stderr */ in channel_output_poll()
3088 if (!(c->flags & CHAN_EOF_SENT) && in channel_output_poll()
3089 c->extended_usage == CHAN_EXTENDED_READ) in channel_output_poll()
3095 /* -- mux proxy support */
3098 * When multiplexing channel messages for mux clients we have to deal
3103 * - We forward all messages (mostly) unmodified to the server.
3104 * - However, in order to route messages from upstream to the correct
3105 * downstream client, we have to replace the channel IDs used by the
3106 * mux clients with a unique channel ID because the mux clients might
3107 * use conflicting channel IDs.
3108 * - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and
3110 * SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID
3111 * with the newly allocated channel ID.
3113 * channels and processed by channel_proxy_upstream(). The local channel ID
3121 * channel. E.g. client_request_forwarded_tcpip() needs to figure
3123 * specific downstream client based on the listen-address/port.
3124 * 6) Agent and X11-Forwarding have a similar problem and are currently
3125 * not supported as the matching session/channel cannot be identified
3131 * channel callback fired on read from mux client, creates
3132 * SSH_CHANNEL_MUX_PROXY channels and translates channel IDs
3133 * on channel creation.
3136 channel_proxy_downstream(struct ssh *ssh, Channel *downstream) in channel_proxy_downstream()
3138 Channel *c = NULL; in channel_proxy_downstream()
3144 int ret = -1, r; in channel_proxy_downstream()
3147 /* sshbuf_dump(downstream->input, stderr); */ in channel_proxy_downstream()
3148 if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have)) in channel_proxy_downstream()
3151 return -1; in channel_proxy_downstream()
3155 return -1; in channel_proxy_downstream()
3160 have -= 2; in channel_proxy_downstream()
3162 debug3_f("channel %u: down->up: type %u", in channel_proxy_downstream()
3163 downstream->self, type); in channel_proxy_downstream()
3177 c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY, in channel_proxy_downstream()
3178 -1, -1, -1, 0, 0, 0, ctype, 1); in channel_proxy_downstream()
3179 c->mux_ctx = downstream; /* point to mux client */ in channel_proxy_downstream()
3180 c->mux_downstream_id = id; /* original downstream id */ in channel_proxy_downstream()
3182 (r = sshbuf_put_u32(modified, c->self)) != 0 || in channel_proxy_downstream()
3204 c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY, in channel_proxy_downstream()
3205 -1, -1, -1, 0, 0, 0, "mux-down-connect", 1); in channel_proxy_downstream()
3206 c->mux_ctx = downstream; /* point to mux client */ in channel_proxy_downstream()
3207 c->mux_downstream_id = id; in channel_proxy_downstream()
3208 c->remote_id = remote_id; in channel_proxy_downstream()
3209 c->have_remote_id = 1; in channel_proxy_downstream()
3211 (r = sshbuf_put_u32(modified, c->self)) != 0 || in channel_proxy_downstream()
3227 if (strcmp(ctype, "tcpip-forward") != 0) { in channel_proxy_downstream()
3238 error_f("tcpip-forward for %s: bad port %u", in channel_proxy_downstream()
3244 -1, listen_host, NULL, (int)listen_port, downstream); in channel_proxy_downstream()
3251 if (c->flags & CHAN_CLOSE_RCVD) in channel_proxy_downstream()
3254 c->flags |= CHAN_CLOSE_SENT; in channel_proxy_downstream()
3283 * receive packets from upstream server and de-multiplex packets
3285 * implemented as a helper for channel input handlers,
3286 * replaces local (proxy) channel ID with downstream channel ID.
3289 channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh) in channel_proxy_upstream()
3292 Channel *downstream; in channel_proxy_upstream()
3300 * restore the original channel id and keep track of CLOSE messages, in channel_proxy_upstream()
3301 * so we can cleanup the channel. in channel_proxy_upstream()
3303 if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY) in channel_proxy_upstream()
3305 if ((downstream = c->mux_ctx) == NULL) in channel_proxy_upstream()
3320 debug2_f("channel %u: unsupported type %u", c->self, type); in channel_proxy_upstream()
3336 (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 || in channel_proxy_upstream()
3338 (r = sshbuf_put_stringb(downstream->output, b)) != 0) { in channel_proxy_upstream()
3344 debug3_f("channel %u: up->down: type %u", c->self, type); in channel_proxy_upstream()
3351 c->remote_id = PEEK_U32(cp); in channel_proxy_upstream()
3352 c->have_remote_id = 1; in channel_proxy_upstream()
3356 if (c->flags & CHAN_CLOSE_SENT) in channel_proxy_upstream()
3359 c->flags |= CHAN_CLOSE_RCVD; in channel_proxy_upstream()
3366 /* -- protocol input */
3368 /* Parse a channel ID from the current packet */
3380 error_r(r, "%s: bad channel id %u", where, id); in channel_parse_id()
3381 ssh_packet_disconnect(ssh, "Invalid %s channel id", what); in channel_parse_id()
3386 /* Lookup a channel from an ID in the current packet */
3387 static Channel *
3391 Channel *c; in channel_from_packet_id()
3395 "%s packet referred to nonexistent channel %d", what, id); in channel_from_packet_id()
3403 const u_char *data; in channel_input_data() local
3405 Channel *c = channel_from_packet_id(ssh, __func__, "data"); in channel_input_data()
3411 /* Ignore any data for non-open channels (might happen on close) */ in channel_input_data()
3412 if (c->type != SSH_CHANNEL_OPEN && in channel_input_data()
3413 c->type != SSH_CHANNEL_RDYNAMIC_OPEN && in channel_input_data()
3414 c->type != SSH_CHANNEL_RDYNAMIC_FINISH && in channel_input_data()
3415 c->type != SSH_CHANNEL_X11_OPEN) in channel_input_data()
3418 /* Get the data. */ in channel_input_data()
3419 if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 || in channel_input_data()
3421 fatal_fr(r, "channel %i: get data", c->self); in channel_input_data()
3424 if (c->datagram) in channel_input_data()
3428 * The sending side reduces its window as it sends data, so we in channel_input_data()
3429 * must 'fake' consumption of the data in order to ensure that window in channel_input_data()
3432 if (c->ostate != CHAN_OUTPUT_OPEN) { in channel_input_data()
3433 c->local_window -= win_len; in channel_input_data()
3434 c->local_consumed += win_len; in channel_input_data()
3438 if (win_len > c->local_maxpacket) { in channel_input_data()
3439 logit("channel %d: rcvd big packet %zu, maxpack %u", in channel_input_data()
3440 c->self, win_len, c->local_maxpacket); in channel_input_data()
3443 if (win_len > c->local_window) { in channel_input_data()
3444 c->local_window_exceeded += win_len - c->local_window; in channel_input_data()
3445 logit("channel %d: rcvd too much data %zu, win %u/%u " in channel_input_data()
3446 "(excess %u)", c->self, win_len, c->local_window, in channel_input_data()
3447 c->local_window_max, c->local_window_exceeded); in channel_input_data()
3448 c->local_window = 0; in channel_input_data()
3450 if (c->local_window_exceeded > (c->local_window_max / 10)) { in channel_input_data()
3451 ssh_packet_disconnect(ssh, "channel %d: peer ignored " in channel_input_data()
3452 "channel window", c->self); in channel_input_data()
3455 c->local_window -= win_len; in channel_input_data()
3456 c->local_window_exceeded = 0; in channel_input_data()
3459 if (c->datagram) { in channel_input_data()
3460 if ((r = sshbuf_put_string(c->output, data, data_len)) != 0) in channel_input_data()
3461 fatal_fr(r, "channel %i: append datagram", c->self); in channel_input_data()
3462 } else if ((r = sshbuf_put(c->output, data, data_len)) != 0) in channel_input_data()
3463 fatal_fr(r, "channel %i: append data", c->self); in channel_input_data()
3471 const u_char *data; in channel_input_extended_data() local
3474 Channel *c = channel_from_packet_id(ssh, __func__, "extended data"); in channel_input_extended_data()
3479 if (c->type != SSH_CHANNEL_OPEN) { in channel_input_extended_data()
3480 logit("channel %d: ext data for non open", c->self); in channel_input_extended_data()
3483 if (c->flags & CHAN_EOF_RCVD) { in channel_input_extended_data()
3484 if (ssh->compat & SSH_BUG_EXTEOF) in channel_input_extended_data()
3485 debug("channel %d: accepting ext data after eof", in channel_input_extended_data()
3486 c->self); in channel_input_extended_data()
3489 "after EOF on channel %d.", c->self); in channel_input_extended_data()
3496 if (c->efd == -1 || in channel_input_extended_data()
3497 c->extended_usage != CHAN_EXTENDED_WRITE || in channel_input_extended_data()
3499 logit("channel %d: bad ext data", c->self); in channel_input_extended_data()
3502 if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 || in channel_input_extended_data()
3504 error_fr(r, "parse data"); in channel_input_extended_data()
3508 if (data_len > c->local_window) { in channel_input_extended_data()
3509 logit("channel %d: rcvd too much extended_data %zu, win %u", in channel_input_extended_data()
3510 c->self, data_len, c->local_window); in channel_input_extended_data()
3513 debug2("channel %d: rcvd ext data %zu", c->self, data_len); in channel_input_extended_data()
3515 if ((r = sshbuf_put(c->extended, data, data_len)) != 0) in channel_input_extended_data()
3517 c->local_window -= data_len; in channel_input_extended_data()
3524 Channel *c = channel_from_packet_id(ssh, __func__, "ieof"); in channel_input_ieof()
3528 error_fr(r, "parse data"); in channel_input_ieof()
3537 if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { in channel_input_ieof()
3538 debug("channel %d: FORCE input drain", c->self); in channel_input_ieof()
3539 c->istate = CHAN_INPUT_WAIT_DRAIN; in channel_input_ieof()
3540 if (sshbuf_len(c->input) == 0) in channel_input_ieof()
3549 Channel *c = channel_from_packet_id(ssh, __func__, "oclose"); in channel_input_oclose()
3555 error_fr(r, "parse data"); in channel_input_oclose()
3565 Channel *c = channel_from_packet_id(ssh, __func__, "open confirmation"); in channel_input_open_confirmation()
3571 if (c->type != SSH_CHANNEL_OPENING) in channel_input_open_confirmation()
3573 "non-opening channel %d.", c->self); in channel_input_open_confirmation()
3575 * Record the remote channel number and mark that the channel in channel_input_open_confirmation()
3578 if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 || in channel_input_open_confirmation()
3586 c->have_remote_id = 1; in channel_input_open_confirmation()
3587 c->remote_window = remote_window; in channel_input_open_confirmation()
3588 c->remote_maxpacket = remote_maxpacket; in channel_input_open_confirmation()
3589 c->type = SSH_CHANNEL_OPEN; in channel_input_open_confirmation()
3590 if (c->open_confirm) { in channel_input_open_confirmation()
3591 debug2_f("channel %d: callback start", c->self); in channel_input_open_confirmation()
3592 c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx); in channel_input_open_confirmation()
3593 debug2_f("channel %d: callback done", c->self); in channel_input_open_confirmation()
3596 debug2("channel %d: open confirm rwindow %u rmax %u", c->self, in channel_input_open_confirmation()
3597 c->remote_window, c->remote_maxpacket); in channel_input_open_confirmation()
3610 return "unknown channel type"; in reason2txt()
3620 Channel *c = channel_from_packet_id(ssh, __func__, "open failure"); in channel_input_open_failure()
3627 if (c->type != SSH_CHANNEL_OPENING) in channel_input_open_failure()
3629 "non-opening channel %d.", c->self); in channel_input_open_failure()
3641 logit("channel %d: open failed: %s%s%s", c->self, in channel_input_open_failure()
3644 if (c->open_confirm) { in channel_input_open_failure()
3645 debug2_f("channel %d: callback start", c->self); in channel_input_open_failure()
3646 c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx); in channel_input_open_failure()
3647 debug2_f("channel %d: callback done", c->self); in channel_input_open_failure()
3649 /* Schedule the channel for cleanup/deletion. */ in channel_input_open_failure()
3658 Channel *c; in channel_input_window_adjust()
3664 logit("Received window adjust for non-open channel %d.", id); in channel_input_window_adjust()
3675 debug2("channel %d: rcvd adjust %u", c->self, adjust); in channel_input_window_adjust()
3676 if ((new_rwin = c->remote_window + adjust) < c->remote_window) { in channel_input_window_adjust()
3677 fatal("channel %d: adjust %u overflows remote window %u", in channel_input_window_adjust()
3678 c->self, adjust, c->remote_window); in channel_input_window_adjust()
3680 c->remote_window = new_rwin; in channel_input_window_adjust()
3688 Channel *c; in channel_input_status_confirm()
3704 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) in channel_input_status_confirm()
3706 cc->cb(ssh, type, c, cc->ctx); in channel_input_status_confirm()
3707 TAILQ_REMOVE(&c->status_confirms, cc, entry); in channel_input_status_confirm()
3712 /* -- tcp forwarding */
3717 ssh->chanctxt->IPv4or6 = af; in channel_set_af()
3729 * Special-case listen_addrs are:
3731 * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
3732 * "" (empty string), "*" -> wildcard v4/v6
3733 * "localhost" -> loopback v4/v6
3734 * "127.0.0.1" / "::1" -> accepted even if gateway_ports isn't set
3745 if (fwd_opts->gateway_ports) in channel_fwd_bind_addr()
3747 } else if (fwd_opts->gateway_ports || is_client) { in channel_fwd_bind_addr()
3748 if (((ssh->compat & SSH_OLD_FORWARD_ADDR) && in channel_fwd_bind_addr()
3751 (!is_client && fwd_opts->gateway_ports == 1)) { in channel_fwd_bind_addr()
3795 Channel *c; in channel_setup_fwd_listener_tcpip()
3804 if (is_client && fwd->connect_path != NULL) { in channel_setup_fwd_listener_tcpip()
3805 host = fwd->connect_path; in channel_setup_fwd_listener_tcpip()
3808 fwd->listen_host : fwd->connect_host; in channel_setup_fwd_listener_tcpip()
3820 addr = channel_fwd_bind_addr(ssh, fwd->listen_host, &wildcard, in channel_setup_fwd_listener_tcpip()
3830 hints.ai_family = ssh->chanctxt->IPv4or6; in channel_setup_fwd_listener_tcpip()
3833 snprintf(strport, sizeof strport, "%d", fwd->listen_port); in channel_setup_fwd_listener_tcpip()
3847 for (ai = aitop; ai; ai = ai->ai_next) { in channel_setup_fwd_listener_tcpip()
3848 switch (ai->ai_family) { in channel_setup_fwd_listener_tcpip()
3850 lport_p = &((struct sockaddr_in *)ai->ai_addr)-> in channel_setup_fwd_listener_tcpip()
3854 lport_p = &((struct sockaddr_in6 *)ai->ai_addr)-> in channel_setup_fwd_listener_tcpip()
3861 * If allocating a port for -R forwards, then use the in channel_setup_fwd_listener_tcpip()
3865 fwd->listen_port == 0 && allocated_listen_port != NULL && in channel_setup_fwd_listener_tcpip()
3869 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), in channel_setup_fwd_listener_tcpip()
3876 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); in channel_setup_fwd_listener_tcpip()
3877 if (sock == -1) { in channel_setup_fwd_listener_tcpip()
3885 if (ai->ai_family == AF_INET6) in channel_setup_fwd_listener_tcpip()
3892 if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in channel_setup_fwd_listener_tcpip()
3897 if (!ai->ai_next) in channel_setup_fwd_listener_tcpip()
3908 if (listen(sock, SSH_LISTEN_BACKLOG) == -1) { in channel_setup_fwd_listener_tcpip()
3916 * fwd->listen_port == 0 requests a dynamically allocated port - in channel_setup_fwd_listener_tcpip()
3920 fwd->listen_port == 0 && in channel_setup_fwd_listener_tcpip()
3928 /* Allocate a channel number for the socket. */ in channel_setup_fwd_listener_tcpip()
3929 c = channel_new(ssh, "port-listener", type, sock, sock, -1, in channel_setup_fwd_listener_tcpip()
3932 c->path = xstrdup(host); in channel_setup_fwd_listener_tcpip()
3933 c->host_port = fwd->connect_port; in channel_setup_fwd_listener_tcpip()
3934 c->listening_addr = addr == NULL ? NULL : xstrdup(addr); in channel_setup_fwd_listener_tcpip()
3935 if (fwd->listen_port == 0 && allocated_listen_port != NULL && in channel_setup_fwd_listener_tcpip()
3936 !(ssh->compat & SSH_BUG_DYNAMIC_RPORT)) in channel_setup_fwd_listener_tcpip()
3937 c->listening_port = *allocated_listen_port; in channel_setup_fwd_listener_tcpip()
3939 c->listening_port = fwd->listen_port; in channel_setup_fwd_listener_tcpip()
3943 error_f("cannot listen to port: %d", fwd->listen_port); in channel_setup_fwd_listener_tcpip()
3954 Channel *c; in channel_setup_fwd_listener_streamlocal()
3960 if (fwd->connect_path != NULL) { in channel_setup_fwd_listener_streamlocal()
3961 if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) { in channel_setup_fwd_listener_streamlocal()
3963 fwd->connect_path); in channel_setup_fwd_listener_streamlocal()
3966 path = fwd->connect_path; in channel_setup_fwd_listener_streamlocal()
3969 if (fwd->connect_host == NULL) { in channel_setup_fwd_listener_streamlocal()
3973 if (strlen(fwd->connect_host) >= NI_MAXHOST) { in channel_setup_fwd_listener_streamlocal()
3977 path = fwd->connect_host; in channel_setup_fwd_listener_streamlocal()
3978 port = fwd->connect_port; in channel_setup_fwd_listener_streamlocal()
3982 path = fwd->listen_path; in channel_setup_fwd_listener_streamlocal()
3986 error_f("unexpected channel type %d", type); in channel_setup_fwd_listener_streamlocal()
3990 if (fwd->listen_path == NULL) { in channel_setup_fwd_listener_streamlocal()
3994 if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) { in channel_setup_fwd_listener_streamlocal()
3995 error("Local listening path too long: %s", fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
3999 debug3_f("type %d path %s", type, fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4002 omask = umask(fwd_opts->streamlocal_bind_mask); in channel_setup_fwd_listener_streamlocal()
4003 sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG, in channel_setup_fwd_listener_streamlocal()
4004 fwd_opts->streamlocal_bind_unlink); in channel_setup_fwd_listener_streamlocal()
4009 debug("Local forwarding listening on path %s.", fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4011 /* Allocate a channel number for the socket. */ in channel_setup_fwd_listener_streamlocal()
4012 c = channel_new(ssh, "unix-listener", type, sock, sock, -1, in channel_setup_fwd_listener_streamlocal()
4015 c->path = xstrdup(path); in channel_setup_fwd_listener_streamlocal()
4016 c->host_port = port; in channel_setup_fwd_listener_streamlocal()
4017 c->listening_port = PORT_STREAMLOCAL; in channel_setup_fwd_listener_streamlocal()
4018 c->listening_addr = xstrdup(fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4029 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_rport_listener_tcpip()
4030 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_rport_listener_tcpip()
4031 if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER) in channel_cancel_rport_listener_tcpip()
4033 if (strcmp(c->path, host) == 0 && c->listening_port == port) { in channel_cancel_rport_listener_tcpip()
4034 debug2_f("close channel %d", i); in channel_cancel_rport_listener_tcpip()
4049 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_rport_listener_streamlocal()
4050 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_rport_listener_streamlocal()
4051 if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER) in channel_cancel_rport_listener_streamlocal()
4053 if (c->path == NULL) in channel_cancel_rport_listener_streamlocal()
4055 if (strcmp(c->path, path) == 0) { in channel_cancel_rport_listener_streamlocal()
4056 debug2_f("close channel %d", i); in channel_cancel_rport_listener_streamlocal()
4068 if (fwd->listen_path != NULL) { in channel_cancel_rport_listener()
4070 fwd->listen_path); in channel_cancel_rport_listener()
4073 fwd->listen_host, fwd->listen_port); in channel_cancel_rport_listener()
4086 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_lport_listener_tcpip()
4087 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_lport_listener_tcpip()
4088 if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER) in channel_cancel_lport_listener_tcpip()
4090 if (c->listening_port != lport) in channel_cancel_lport_listener_tcpip()
4094 if (c->host_port == 0) in channel_cancel_lport_listener_tcpip()
4097 if (c->host_port != cport) in channel_cancel_lport_listener_tcpip()
4100 if ((c->listening_addr == NULL && addr != NULL) || in channel_cancel_lport_listener_tcpip()
4101 (c->listening_addr != NULL && addr == NULL)) in channel_cancel_lport_listener_tcpip()
4103 if (addr == NULL || strcmp(c->listening_addr, addr) == 0) { in channel_cancel_lport_listener_tcpip()
4104 debug2_f("close channel %d", i); in channel_cancel_lport_listener_tcpip()
4124 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_lport_listener_streamlocal()
4125 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_lport_listener_streamlocal()
4126 if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER) in channel_cancel_lport_listener_streamlocal()
4128 if (c->listening_addr == NULL) in channel_cancel_lport_listener_streamlocal()
4130 if (strcmp(c->listening_addr, path) == 0) { in channel_cancel_lport_listener_streamlocal()
4131 debug2_f("close channel %d", i); in channel_cancel_lport_listener_streamlocal()
4144 if (fwd->listen_path != NULL) { in channel_cancel_lport_listener()
4146 fwd->listen_path); in channel_cancel_lport_listener()
4149 fwd->listen_host, fwd->listen_port, cport, fwd_opts); in channel_cancel_lport_listener()
4158 if (fwd->listen_path != NULL) { in channel_setup_local_fwd_listener()
4175 if (fwd->listen_path != NULL) in remote_open_match()
4178 if (fwd->listen_host == NULL || allowed_open->listen_host == NULL) in remote_open_match()
4181 if (allowed_open->listen_port != FWD_PERMIT_ANY_PORT && in remote_open_match()
4182 allowed_open->listen_port != fwd->listen_port) in remote_open_match()
4185 /* Match hostnames case-insensitively */ in remote_open_match()
4186 lhost = xstrdup(fwd->listen_host); in remote_open_match()
4188 ret = match_pattern(lhost, allowed_open->listen_host); in remote_open_match()
4198 struct ssh_channels *sc = ssh->chanctxt; in check_rfwd_permission()
4199 struct permission_set *pset = &sc->remote_perms; in check_rfwd_permission()
4205 permit = pset->all_permitted; in check_rfwd_permission()
4207 for (i = 0; i < pset->num_permitted_user; i++) { in check_rfwd_permission()
4208 perm = &pset->permitted_user[i]; in check_rfwd_permission()
4216 if (pset->num_permitted_admin > 0) { in check_rfwd_permission()
4218 for (i = 0; i < pset->num_permitted_admin; i++) { in check_rfwd_permission()
4219 perm = &pset->permitted_admin[i]; in check_rfwd_permission()
4237 if (fwd->listen_path != NULL) in channel_setup_remote_fwd_listener()
4243 fwd->listen_path); in channel_setup_remote_fwd_listener()
4244 else if(fwd->listen_host != NULL) in channel_setup_remote_fwd_listener()
4249 fwd->listen_host, fwd->listen_port ); in channel_setup_remote_fwd_listener()
4256 if (fwd->listen_path != NULL) { in channel_setup_remote_fwd_listener()
4283 * the secure channel to host:port from local side.
4290 int r, success = 0, idx = -1; in channel_request_remote_forwarding()
4295 if (fwd->listen_path != NULL) { in channel_request_remote_forwarding()
4298 "streamlocal-forward@openssh.com")) != 0 || in channel_request_remote_forwarding()
4300 (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 || in channel_request_remote_forwarding()
4306 (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 || in channel_request_remote_forwarding()
4309 channel_rfwd_bind_host(fwd->listen_host))) != 0 || in channel_request_remote_forwarding()
4310 (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 || in channel_request_remote_forwarding()
4313 fatal_fr(r, "request tcpip-forward"); in channel_request_remote_forwarding()
4321 if (fwd->connect_path != NULL) { in channel_request_remote_forwarding()
4322 host_to_connect = fwd->connect_path; in channel_request_remote_forwarding()
4325 host_to_connect = fwd->connect_host; in channel_request_remote_forwarding()
4326 port_to_connect = fwd->connect_port; in channel_request_remote_forwarding()
4328 if (fwd->listen_path != NULL) { in channel_request_remote_forwarding()
4329 listen_path = fwd->listen_path; in channel_request_remote_forwarding()
4332 listen_host = fwd->listen_host; in channel_request_remote_forwarding()
4333 listen_port = fwd->listen_port; in channel_request_remote_forwarding()
4346 if (allowed_open->host_to_connect == NULL) in open_match()
4348 if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT && in open_match()
4349 allowed_open->port_to_connect != requestedport) in open_match()
4351 if (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 && in open_match()
4352 strcmp(allowed_open->host_to_connect, requestedhost) != 0) in open_match()
4360 * need to translate between the configured-host (listen_host)
4369 if (allowed_open->host_to_connect == NULL) in open_listen_match_tcpip()
4371 if (allowed_open->listen_port != requestedport) in open_listen_match_tcpip()
4373 if (!translate && allowed_open->listen_host == NULL && in open_listen_match_tcpip()
4377 channel_rfwd_bind_host(allowed_open->listen_host) : in open_listen_match_tcpip()
4378 allowed_open->listen_host; in open_listen_match_tcpip()
4389 if (allowed_open->host_to_connect == NULL) in open_listen_match_streamlocal()
4391 if (allowed_open->listen_port != PORT_STREAMLOCAL) in open_listen_match_streamlocal()
4393 if (allowed_open->listen_path == NULL || in open_listen_match_streamlocal()
4394 strcmp(allowed_open->listen_path, requestedpath) != 0) in open_listen_match_streamlocal()
4407 struct ssh_channels *sc = ssh->chanctxt; in channel_request_rforward_cancel_tcpip()
4408 struct permission_set *pset = &sc->local_perms; in channel_request_rforward_cancel_tcpip()
4413 for (i = 0; i < pset->num_permitted_user; i++) { in channel_request_rforward_cancel_tcpip()
4414 perm = &pset->permitted_user[i]; in channel_request_rforward_cancel_tcpip()
4421 return -1; in channel_request_rforward_cancel_tcpip()
4424 (r = sshpkt_put_cstring(ssh, "cancel-tcpip-forward")) != 0 || in channel_request_rforward_cancel_tcpip()
4443 struct ssh_channels *sc = ssh->chanctxt; in channel_request_rforward_cancel_streamlocal()
4444 struct permission_set *pset = &sc->local_perms; in channel_request_rforward_cancel_streamlocal()
4449 for (i = 0; i < pset->num_permitted_user; i++) { in channel_request_rforward_cancel_streamlocal()
4450 perm = &pset->permitted_user[i]; in channel_request_rforward_cancel_streamlocal()
4457 return -1; in channel_request_rforward_cancel_streamlocal()
4461 "cancel-streamlocal-forward@openssh.com")) != 0 || in channel_request_rforward_cancel_streamlocal()
4478 if (fwd->listen_path != NULL) { in channel_request_rforward_cancel()
4480 fwd->listen_path); in channel_request_rforward_cancel()
4483 fwd->listen_host, in channel_request_rforward_cancel()
4484 fwd->listen_port ? fwd->listen_port : fwd->allocated_port); in channel_request_rforward_cancel()
4498 if (pset->num_permitted_user == 0) in channel_permit_all()
4499 pset->all_permitted = 1; in channel_permit_all()
4521 pset->all_permitted = 0; in channel_add_permission()
4557 struct permission_set *pset = &ssh->chanctxt->local_perms; in channel_update_permission()
4559 if (idx < 0 || (u_int)idx >= pset->num_permitted_user) { in channel_update_permission()
4561 idx, pset->num_permitted_user); in channel_update_permission()
4567 pset->permitted_user[idx].host_to_connect, in channel_update_permission()
4568 pset->permitted_user[idx].port_to_connect); in channel_update_permission()
4570 fwd_perm_clear(&pset->permitted_user[idx]); in channel_update_permission()
4572 pset->permitted_user[idx].listen_port = in channel_update_permission()
4573 (ssh->compat & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport; in channel_update_permission()
4577 /* Try to start non-blocking connect to next host in cctx list */
4584 char strport[MAXIMUM(NI_MAXSERV, sizeof(sunaddr->sun_path))]; in connect_next()
4586 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { in connect_next()
4587 switch (cctx->ai->ai_family) { in connect_next()
4590 sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr; in connect_next()
4592 strlcpy(strport, sunaddr->sun_path, sizeof(strport)); in connect_next()
4596 if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, in connect_next()
4607 cctx->host, ntop, strport); in connect_next()
4608 if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, in connect_next()
4609 cctx->ai->ai_protocol)) == -1) { in connect_next()
4610 if (cctx->ai->ai_next == NULL) in connect_next()
4616 if (set_nonblock(sock) == -1) in connect_next()
4618 if (connect(sock, cctx->ai->ai_addr, in connect_next()
4619 cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) { in connect_next()
4621 cctx->host, ntop, strport, strerror(errno)); in connect_next()
4625 continue; /* fail -- try next */ in connect_next()
4627 if (cctx->ai->ai_family != AF_UNIX) in connect_next()
4630 cctx->host, ntop, strport, sock); in connect_next()
4631 cctx->ai = cctx->ai->ai_next; in connect_next()
4634 return -1; in connect_next()
4640 free(cctx->host); in channel_connect_ctx_free()
4641 if (cctx->aitop) { in channel_connect_ctx_free()
4642 if (cctx->aitop->ai_family == AF_UNIX) in channel_connect_ctx_free()
4643 free(cctx->aitop); in channel_connect_ctx_free()
4645 freeaddrinfo(cctx->aitop); in channel_connect_ctx_free()
4661 int sock = -1; in connect_to_helper()
4668 if (strlen(name) > sizeof(sunaddr->sun_path)) { in connect_to_helper()
4670 return -1; in connect_to_helper()
4680 ai->ai_addr = (struct sockaddr *)(ai + 1); in connect_to_helper()
4681 ai->ai_addrlen = sizeof(*sunaddr); in connect_to_helper()
4682 ai->ai_family = AF_UNIX; in connect_to_helper()
4683 ai->ai_socktype = socktype; in connect_to_helper()
4684 ai->ai_protocol = PF_UNSPEC; in connect_to_helper()
4685 sunaddr = (struct sockaddr_un *)ai->ai_addr; in connect_to_helper()
4686 sunaddr->sun_family = AF_UNIX; in connect_to_helper()
4687 strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path)); in connect_to_helper()
4688 cctx->aitop = ai; in connect_to_helper()
4691 hints.ai_family = ssh->chanctxt->IPv4or6; in connect_to_helper()
4694 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx->aitop)) in connect_to_helper()
4702 return -1; in connect_to_helper()
4706 cctx->host = xstrdup(name); in connect_to_helper()
4707 cctx->port = port; in connect_to_helper()
4708 cctx->ai = cctx->aitop; in connect_to_helper()
4710 if ((sock = connect_next(cctx)) == -1) { in connect_to_helper()
4713 return -1; in connect_to_helper()
4719 /* Return CONNECTING channel to remote host:port or local socket path */
4720 static Channel *
4725 Channel *c; in connect_to()
4731 if (sock == -1) { in connect_to()
4735 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, in connect_to()
4737 c->host_port = port; in connect_to()
4738 c->path = xstrdup(host); in connect_to()
4739 c->connect_ctx = cctx; in connect_to()
4745 * returns either the newly connected channel or the downstream channel
4748 Channel *
4752 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_by_listen_address()
4753 struct permission_set *pset = &sc->local_perms; in channel_connect_by_listen_address()
4757 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_by_listen_address()
4758 perm = &pset->permitted_user[i]; in channel_connect_by_listen_address()
4761 if (perm->downstream) in channel_connect_by_listen_address()
4762 return perm->downstream; in channel_connect_by_listen_address()
4763 if (perm->port_to_connect == 0) in channel_connect_by_listen_address()
4767 perm->host_to_connect, perm->port_to_connect, in channel_connect_by_listen_address()
4776 Channel *
4780 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_by_listen_path()
4781 struct permission_set *pset = &sc->local_perms; in channel_connect_by_listen_path()
4785 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_by_listen_path()
4786 perm = &pset->permitted_user[i]; in channel_connect_by_listen_path()
4789 perm->host_to_connect, perm->port_to_connect, in channel_connect_by_listen_path()
4799 Channel *
4803 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_to_port()
4804 struct permission_set *pset = &sc->local_perms; in channel_connect_to_port()
4806 Channel *c; in channel_connect_to_port()
4811 permit = pset->all_permitted; in channel_connect_to_port()
4813 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_to_port()
4814 perm = &pset->permitted_user[i]; in channel_connect_to_port()
4822 if (pset->num_permitted_admin > 0) { in channel_connect_to_port()
4824 for (i = 0; i < pset->num_permitted_admin; i++) { in channel_connect_to_port()
4825 perm = &pset->permitted_admin[i]; in channel_connect_to_port()
4845 if (sock == -1) { in channel_connect_to_port()
4850 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, in channel_connect_to_port()
4852 c->host_port = port; in channel_connect_to_port()
4853 c->path = xstrdup(host); in channel_connect_to_port()
4854 c->connect_ctx = cctx; in channel_connect_to_port()
4860 Channel *
4864 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_to_path()
4865 struct permission_set *pset = &sc->local_perms; in channel_connect_to_path()
4869 permit = pset->all_permitted; in channel_connect_to_path()
4871 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_to_path()
4872 perm = &pset->permitted_user[i]; in channel_connect_to_path()
4880 if (pset->num_permitted_admin > 0) { in channel_connect_to_path()
4882 for (i = 0; i < pset->num_permitted_admin; i++) { in channel_connect_to_path()
4883 perm = &pset->permitted_admin[i]; in channel_connect_to_path()
4902 struct ssh_channels *sc = ssh->chanctxt; in channel_send_window_changes()
4907 for (i = 0; i < sc->channels_alloc; i++) { in channel_send_window_changes()
4908 if (sc->channels[i] == NULL || !sc->channels[i]->client_tty || in channel_send_window_changes()
4909 sc->channels[i]->type != SSH_CHANNEL_OPEN) in channel_send_window_changes()
4911 if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) == -1) in channel_send_window_changes()
4913 channel_request_start(ssh, i, "window-change", 0); in channel_send_window_changes()
4919 fatal_fr(r, "channel %u; send window-change", i); in channel_send_window_changes()
4923 /* Return RDYNAMIC_OPEN channel: channel allows SOCKS, but is not connected */
4924 static Channel *
4927 Channel *c; in rdynamic_connect_prepare()
4930 c = channel_new(ssh, ctype, SSH_CHANNEL_RDYNAMIC_OPEN, -1, -1, -1, in rdynamic_connect_prepare()
4932 c->host_port = 0; in rdynamic_connect_prepare()
4933 c->path = NULL; in rdynamic_connect_prepare()
4936 * We need to open the channel before we have a FD, in rdynamic_connect_prepare()
4940 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in rdynamic_connect_prepare()
4941 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in rdynamic_connect_prepare()
4942 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in rdynamic_connect_prepare()
4943 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) in rdynamic_connect_prepare()
4944 fatal_fr(r, "channel %i; confirm", c->self); in rdynamic_connect_prepare()
4950 rdynamic_connect_finish(struct ssh *ssh, Channel *c) in rdynamic_connect_finish()
4952 struct ssh_channels *sc = ssh->chanctxt; in rdynamic_connect_finish()
4953 struct permission_set *pset = &sc->local_perms; in rdynamic_connect_finish()
4959 if (pset->num_permitted_admin > 0) { in rdynamic_connect_finish()
4961 for (i = 0; i < pset->num_permitted_admin; i++) { in rdynamic_connect_finish()
4962 perm = &pset->permitted_admin[i]; in rdynamic_connect_finish()
4963 if (open_match(perm, c->path, c->host_port)) { in rdynamic_connect_finish()
4971 return -1; in rdynamic_connect_finish()
4975 sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL, in rdynamic_connect_finish()
4977 if (sock == -1) in rdynamic_connect_finish()
4981 c->type = SSH_CHANNEL_RDYNAMIC_FINISH; in rdynamic_connect_finish()
4982 c->connect_ctx = cctx; in rdynamic_connect_finish()
4983 channel_register_fds(ssh, c, sock, sock, -1, 0, 1, 0); in rdynamic_connect_finish()
4988 /* -- X11 forwarding */
4993 * stored in display_numberp , or -1 if an error occurs.
5000 Channel *nc = NULL; in x11_create_display_inet()
5008 return -1; in x11_create_display_inet()
5015 hints.ai_family = ssh->chanctxt->IPv4or6; in x11_create_display_inet()
5022 return -1; in x11_create_display_inet()
5024 for (ai = aitop; ai; ai = ai->ai_next) { in x11_create_display_inet()
5025 if (ai->ai_family != AF_INET && in x11_create_display_inet()
5026 ai->ai_family != AF_INET6) in x11_create_display_inet()
5028 sock = socket(ai->ai_family, ai->ai_socktype, in x11_create_display_inet()
5029 ai->ai_protocol); in x11_create_display_inet()
5030 if (sock == -1) { in x11_create_display_inet()
5038 return -1; in x11_create_display_inet()
5041 ai->ai_family); in x11_create_display_inet()
5045 if (ai->ai_family == AF_INET6) in x11_create_display_inet()
5049 if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in x11_create_display_inet()
5067 error("Failed to allocate internet-domain X11 display socket."); in x11_create_display_inet()
5068 return -1; in x11_create_display_inet()
5073 if (listen(sock, SSH_LISTEN_BACKLOG) == -1) { in x11_create_display_inet()
5076 return -1; in x11_create_display_inet()
5080 /* Allocate a channel for each socket. */ in x11_create_display_inet()
5084 nc = channel_new(ssh, "x11-listener", in x11_create_display_inet()
5085 SSH_CHANNEL_X11_LISTENER, sock, sock, -1, in x11_create_display_inet()
5088 nc->single_connection = single_connection; in x11_create_display_inet()
5089 (*chanids)[n] = nc->self; in x11_create_display_inet()
5091 (*chanids)[n] = -1; in x11_create_display_inet()
5105 if (sock == -1) { in connect_local_xsocket_path()
5107 return -1; in connect_local_xsocket_path()
5116 return -1; in connect_local_xsocket_path()
5168 return -1; in x11_connect_display()
5186 return -1; in x11_connect_display()
5204 return -1; in x11_connect_display()
5209 return -1; in x11_connect_display()
5222 return -1; in x11_connect_display()
5232 return -1; in x11_connect_display()
5237 hints.ai_family = ssh->chanctxt->IPv4or6; in x11_connect_display()
5243 return -1; in x11_connect_display()
5245 for (ai = aitop; ai; ai = ai->ai_next) { in x11_connect_display()
5247 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); in x11_connect_display()
5248 if (sock == -1) { in x11_connect_display()
5253 if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in x11_connect_display()
5266 return -1; in x11_connect_display()
5274 * data, and enables authentication spoofing.
5279 const char *disp, const char *proto, const char *data, int want_reply) in x11_request_forwarding_with_spoofing() argument
5281 struct ssh_channels *sc = ssh->chanctxt; in x11_request_forwarding_with_spoofing()
5282 u_int data_len = (u_int) strlen(data) / 2; in x11_request_forwarding_with_spoofing()
5288 if (sc->x11_saved_display == NULL) in x11_request_forwarding_with_spoofing()
5289 sc->x11_saved_display = xstrdup(disp); in x11_request_forwarding_with_spoofing()
5290 else if (strcmp(disp, sc->x11_saved_display) != 0) { in x11_request_forwarding_with_spoofing()
5304 if (sc->x11_saved_proto == NULL) { in x11_request_forwarding_with_spoofing()
5306 sc->x11_saved_proto = xstrdup(proto); in x11_request_forwarding_with_spoofing()
5308 /* Extract real authentication data. */ in x11_request_forwarding_with_spoofing()
5309 sc->x11_saved_data = xmalloc(data_len); in x11_request_forwarding_with_spoofing()
5311 if (sscanf(data + 2 * i, "%2x", &value) != 1) { in x11_request_forwarding_with_spoofing()
5313 "authentication data: %.100s", data); in x11_request_forwarding_with_spoofing()
5315 sc->x11_saved_data[i] = value; in x11_request_forwarding_with_spoofing()
5317 sc->x11_saved_data_len = data_len; in x11_request_forwarding_with_spoofing()
5319 /* Generate fake data of the same length. */ in x11_request_forwarding_with_spoofing()
5320 sc->x11_fake_data = xmalloc(data_len); in x11_request_forwarding_with_spoofing()
5321 arc4random_buf(sc->x11_fake_data, data_len); in x11_request_forwarding_with_spoofing()
5322 sc->x11_fake_data_len = data_len; in x11_request_forwarding_with_spoofing()
5325 /* Convert the fake data into hex. */ in x11_request_forwarding_with_spoofing()
5326 new_data = tohex(sc->x11_fake_data, data_len); in x11_request_forwarding_with_spoofing()
5329 channel_request_start(ssh, client_session_id, "x11-req", want_reply); in x11_request_forwarding_with_spoofing()
5336 fatal_fr(r, "send x11-req"); in x11_request_forwarding_with_spoofing()