Lines Matching +full:io +full:- +full:multiplex

73 #include "openbsd-compat/sys-queue.h"
93 /* -- agent forwarding */
96 /* -- tcp forwarding */
97 /* special-case port number meaning allow any port */
100 /* special-case wildcard meaning allow any host */
103 /* -- X11 forwarding */
107 /* Per-channel callback for pre/post IO actions */
118 /* XXX - can we use listen_host instead of listen_path? */
175 * 'channel_pre*' are called just before IO to add any bits
176 * relevant to channels in the c->io_want bitmasks.
179 * channels which have c->io_ready events pending.
184 /* -- tcp forwarding */
188 /* -- X11 forwarding */
226 /* non-blocking connect helpers */
235 /* -- channel core */
244 sc->channels_alloc = 10; in channel_init_channels()
245 sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels)); in channel_init_channels()
246 sc->IPv4or6 = AF_UNSPEC; in channel_init_channels()
249 ssh->chanctxt = sc; in channel_init_channels()
257 if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) { in channel_by_id()
261 c = ssh->chanctxt->channels[id]; in channel_by_id()
275 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_by_remote_id()
276 c = ssh->chanctxt->channels[i]; in channel_by_remote_id()
277 if (c != NULL && c->have_remote_id && c->remote_id == remote_id) in channel_by_remote_id()
295 switch (c->type) { in channel_lookup()
308 logit("Non-public channel %d, type %d.", id, c->type); in channel_lookup()
313 * Add a timeout for open channels whose c->ctype (or c->xctype if it is set)
320 struct ssh_channels *sc = ssh->chanctxt; in channel_add_timeout()
324 sc->global_deadline = timeout_secs; in channel_add_timeout()
329 sc->timeouts = xrecallocarray(sc->timeouts, sc->ntimeouts, in channel_add_timeout()
330 sc->ntimeouts + 1, sizeof(*sc->timeouts)); in channel_add_timeout()
331 sc->timeouts[sc->ntimeouts].type_pattern = xstrdup(type_pattern); in channel_add_timeout()
332 sc->timeouts[sc->ntimeouts].timeout_secs = timeout_secs; in channel_add_timeout()
333 sc->ntimeouts++; in channel_add_timeout()
336 /* Clears all previously-added channel timeouts */
340 struct ssh_channels *sc = ssh->chanctxt; in channel_clear_timeouts()
344 for (i = 0; i < sc->ntimeouts; i++) in channel_clear_timeouts()
345 free(sc->timeouts[i].type_pattern); in channel_clear_timeouts()
346 free(sc->timeouts); in channel_clear_timeouts()
347 sc->timeouts = NULL; in channel_clear_timeouts()
348 sc->ntimeouts = 0; in channel_clear_timeouts()
354 struct ssh_channels *sc = ssh->chanctxt; in lookup_timeout()
357 for (i = 0; i < sc->ntimeouts; i++) { in lookup_timeout()
358 if (match_pattern(type, sc->timeouts[i].type_pattern)) in lookup_timeout()
359 return sc->timeouts[i].timeout_secs; in lookup_timeout()
369 * Will reset c->inactive_deadline as a side-effect.
378 if (c->xctype != NULL) in channel_set_xtype()
379 free(c->xctype); in channel_set_xtype()
380 c->xctype = xstrdup(xctype); in channel_set_xtype()
382 c->inactive_deadline = lookup_timeout(ssh, c->xctype); in channel_set_xtype()
384 c->inactive_deadline); in channel_set_xtype()
394 ssh->chanctxt->lastused = monotime(); in channel_set_used_time()
396 c->lastused = ssh->chanctxt->lastused; in channel_set_used_time()
406 struct ssh_channels *sc = ssh->chanctxt; in channel_get_expiry()
409 if (sc->lastused != 0 && sc->global_deadline != 0) in channel_get_expiry()
410 expiry = sc->lastused + sc->global_deadline; in channel_get_expiry()
411 if (c->lastused != 0 && c->inactive_deadline != 0) { in channel_get_expiry()
412 channel_expiry = c->lastused + c->inactive_deadline; in channel_get_expiry()
429 if (rfd != -1) in channel_register_fds()
431 if (wfd != -1 && wfd != rfd) in channel_register_fds()
433 if (efd != -1 && efd != rfd && efd != wfd) in channel_register_fds()
436 c->rfd = rfd; in channel_register_fds()
437 c->wfd = wfd; in channel_register_fds()
438 c->sock = (rfd == wfd) ? rfd : -1; in channel_register_fds()
439 c->efd = efd; in channel_register_fds()
440 c->extended_usage = extusage; in channel_register_fds()
442 if ((c->isatty = is_tty) != 0) in channel_register_fds()
443 debug2("channel %d: rfd %d isatty", c->self, c->rfd); in channel_register_fds()
446 c->wfd_isatty = is_tty || isatty(c->wfd); in channel_register_fds()
450 c->restore_block = 0; in channel_register_fds()
454 * non-blocking mode if they are TTYs. Otherwise prepare to in channel_register_fds()
458 if (rfd != -1 && !isatty(rfd) && in channel_register_fds()
459 (val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
460 c->restore_flags[0] = val; in channel_register_fds()
461 c->restore_block |= CHANNEL_RESTORE_RFD; in channel_register_fds()
464 if (wfd != -1 && !isatty(wfd) && in channel_register_fds()
465 (val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
466 c->restore_flags[1] = val; in channel_register_fds()
467 c->restore_block |= CHANNEL_RESTORE_WFD; in channel_register_fds()
470 if (efd != -1 && !isatty(efd) && in channel_register_fds()
471 (val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) { in channel_register_fds()
472 c->restore_flags[2] = val; in channel_register_fds()
473 c->restore_block |= CHANNEL_RESTORE_EFD; in channel_register_fds()
477 if (rfd != -1) in channel_register_fds()
479 if (wfd != -1) in channel_register_fds()
481 if (efd != -1) in channel_register_fds()
496 struct ssh_channels *sc = ssh->chanctxt; in channel_new()
502 for (i = 0; i < sc->channels_alloc; i++) { in channel_new()
503 if (sc->channels[i] == NULL) { in channel_new()
509 if (i >= sc->channels_alloc) { in channel_new()
514 found = sc->channels_alloc; in channel_new()
515 if (sc->channels_alloc > CHANNELS_MAX_CHANNELS) in channel_new()
517 sc->channels_alloc); in channel_new()
518 sc->channels = xrecallocarray(sc->channels, sc->channels_alloc, in channel_new()
519 sc->channels_alloc + 10, sizeof(*sc->channels)); in channel_new()
520 sc->channels_alloc += 10; in channel_new()
521 debug2("channel: expanding %d", sc->channels_alloc); in channel_new()
524 c = sc->channels[found] = xcalloc(1, sizeof(Channel)); in channel_new()
525 if ((c->input = sshbuf_new()) == NULL || in channel_new()
526 (c->output = sshbuf_new()) == NULL || in channel_new()
527 (c->extended = sshbuf_new()) == NULL) in channel_new()
529 if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0) in channel_new()
531 c->ostate = CHAN_OUTPUT_OPEN; in channel_new()
532 c->istate = CHAN_INPUT_OPEN; in channel_new()
534 c->self = found; in channel_new()
535 c->type = type; in channel_new()
536 c->ctype = ctype; in channel_new()
537 c->local_window = window; in channel_new()
538 c->local_window_max = window; in channel_new()
539 c->local_maxpacket = maxpack; in channel_new()
540 c->remote_name = xstrdup(remote_name); in channel_new()
541 c->ctl_chan = -1; in channel_new()
542 c->delayed = 1; /* prevent call to channel_post handler */ in channel_new()
543 c->inactive_deadline = lookup_timeout(ssh, c->ctype); in channel_new()
544 TAILQ_INIT(&c->status_confirms); in channel_new()
546 found, c->ctype, remote_name, c->inactive_deadline); in channel_new()
555 if (fd == -1) in channel_close_fd()
559 if (*fdp == c->rfd && in channel_close_fd()
560 (c->restore_block & CHANNEL_RESTORE_RFD) != 0) in channel_close_fd()
561 (void)fcntl(*fdp, F_SETFL, c->restore_flags[0]); in channel_close_fd()
562 else if (*fdp == c->wfd && in channel_close_fd()
563 (c->restore_block & CHANNEL_RESTORE_WFD) != 0) in channel_close_fd()
564 (void)fcntl(*fdp, F_SETFL, c->restore_flags[1]); in channel_close_fd()
565 else if (*fdp == c->efd && in channel_close_fd()
566 (c->restore_block & CHANNEL_RESTORE_EFD) != 0) in channel_close_fd()
567 (void)fcntl(*fdp, F_SETFL, c->restore_flags[2]); in channel_close_fd()
569 if (*fdp == c->rfd) { in channel_close_fd()
570 c->io_want &= ~SSH_CHAN_IO_RFD; in channel_close_fd()
571 c->io_ready &= ~SSH_CHAN_IO_RFD; in channel_close_fd()
572 c->rfd = -1; in channel_close_fd()
573 c->pfds[0] = -1; in channel_close_fd()
575 if (*fdp == c->wfd) { in channel_close_fd()
576 c->io_want &= ~SSH_CHAN_IO_WFD; in channel_close_fd()
577 c->io_ready &= ~SSH_CHAN_IO_WFD; in channel_close_fd()
578 c->wfd = -1; in channel_close_fd()
579 c->pfds[1] = -1; in channel_close_fd()
581 if (*fdp == c->efd) { in channel_close_fd()
582 c->io_want &= ~SSH_CHAN_IO_EFD; in channel_close_fd()
583 c->io_ready &= ~SSH_CHAN_IO_EFD; in channel_close_fd()
584 c->efd = -1; in channel_close_fd()
585 c->pfds[2] = -1; in channel_close_fd()
587 if (*fdp == c->sock) { in channel_close_fd()
588 c->io_want &= ~SSH_CHAN_IO_SOCK; in channel_close_fd()
589 c->io_ready &= ~SSH_CHAN_IO_SOCK; in channel_close_fd()
590 c->sock = -1; in channel_close_fd()
591 c->pfds[3] = -1; in channel_close_fd()
595 *fdp = -1; /* probably redundant */ in channel_close_fd()
603 int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; in channel_close_fds()
605 channel_close_fd(ssh, c, &c->sock); in channel_close_fds()
607 channel_close_fd(ssh, c, &c->rfd); in channel_close_fds()
609 channel_close_fd(ssh, c, &c->wfd); in channel_close_fds()
611 channel_close_fd(ssh, c, &c->efd); in channel_close_fds()
617 free(perm->host_to_connect); in fwd_perm_clear()
618 free(perm->listen_host); in fwd_perm_clear()
619 free(perm->listen_path); in fwd_perm_clear()
645 struct ssh_channels *sc = ssh->chanctxt; in permission_set_get()
649 return &sc->local_perms; in permission_set_get()
652 return &sc->remote_perms; in permission_set_get()
668 *permpp = &pset->permitted_user; in permission_set_get_array()
669 *npermpp = &pset->num_permitted_user; in permission_set_get_array()
672 *permpp = &pset->permitted_admin; in permission_set_get_array()
673 *npermpp = &pset->num_permitted_admin; in permission_set_get_array()
711 struct ssh_channels *sc = ssh->chanctxt; in mux_remove_remote_forwardings()
712 struct permission_set *pset = &sc->local_perms; in mux_remove_remote_forwardings()
717 for (i = 0; i < pset->num_permitted_user; i++) { in mux_remove_remote_forwardings()
718 perm = &pset->permitted_user[i]; in mux_remove_remote_forwardings()
719 if (perm->downstream != c) in mux_remove_remote_forwardings()
724 c->self, perm->listen_host, perm->listen_port); in mux_remove_remote_forwardings()
727 "cancel-tcpip-forward")) != 0 || in mux_remove_remote_forwardings()
730 channel_rfwd_bind_host(perm->listen_host))) != 0 || in mux_remove_remote_forwardings()
731 (r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 || in mux_remove_remote_forwardings()
733 fatal_fr(r, "channel %i", c->self); in mux_remove_remote_forwardings()
743 struct ssh_channels *sc = ssh->chanctxt; in channel_free()
749 for (n = 0, i = 0; i < sc->channels_alloc; i++) { in channel_free()
750 if ((other = sc->channels[i]) == NULL) in channel_free()
754 if (c->type == SSH_CHANNEL_MUX_CLIENT && in channel_free()
755 other->type == SSH_CHANNEL_MUX_PROXY && in channel_free()
756 other->mux_ctx == c) { in channel_free()
757 other->mux_ctx = NULL; in channel_free()
758 other->type = SSH_CHANNEL_OPEN; in channel_free()
759 other->istate = CHAN_INPUT_CLOSED; in channel_free()
760 other->ostate = CHAN_OUTPUT_CLOSED; in channel_free()
763 debug("channel %d: free: %s, nchannels %u", c->self, in channel_free()
764 c->remote_name ? c->remote_name : "???", n); in channel_free()
766 if (c->type == SSH_CHANNEL_MUX_CLIENT) { in channel_free()
768 free(c->mux_ctx); in channel_free()
769 c->mux_ctx = NULL; in channel_free()
770 } else if (c->type == SSH_CHANNEL_MUX_LISTENER) { in channel_free()
771 free(c->mux_ctx); in channel_free()
772 c->mux_ctx = NULL; in channel_free()
777 debug3("channel %d: status: %s", c->self, s); in channel_free()
782 sshbuf_free(c->input); in channel_free()
783 sshbuf_free(c->output); in channel_free()
784 sshbuf_free(c->extended); in channel_free()
785 c->input = c->output = c->extended = NULL; in channel_free()
786 free(c->remote_name); in channel_free()
787 c->remote_name = NULL; in channel_free()
788 free(c->path); in channel_free()
789 c->path = NULL; in channel_free()
790 free(c->listening_addr); in channel_free()
791 c->listening_addr = NULL; in channel_free()
792 free(c->xctype); in channel_free()
793 c->xctype = NULL; in channel_free()
794 while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { in channel_free()
795 if (cc->abandon_cb != NULL) in channel_free()
796 cc->abandon_cb(ssh, c, cc->ctx); in channel_free()
797 TAILQ_REMOVE(&c->status_confirms, cc, entry); in channel_free()
800 if (c->filter_cleanup != NULL && c->filter_ctx != NULL) in channel_free()
801 c->filter_cleanup(ssh, c->self, c->filter_ctx); in channel_free()
802 sc->channels[c->self] = NULL; in channel_free()
810 struct ssh_channels *sc = ssh->chanctxt; in channel_free_all()
812 for (i = 0; i < sc->channels_alloc; i++) in channel_free_all()
813 if (sc->channels[i] != NULL) in channel_free_all()
814 channel_free(ssh, sc->channels[i]); in channel_free_all()
816 free(sc->channels); in channel_free_all()
817 sc->channels = NULL; in channel_free_all()
818 sc->channels_alloc = 0; in channel_free_all()
820 free(sc->x11_saved_display); in channel_free_all()
821 sc->x11_saved_display = NULL; in channel_free_all()
823 free(sc->x11_saved_proto); in channel_free_all()
824 sc->x11_saved_proto = NULL; in channel_free_all()
826 free(sc->x11_saved_data); in channel_free_all()
827 sc->x11_saved_data = NULL; in channel_free_all()
828 sc->x11_saved_data_len = 0; in channel_free_all()
830 free(sc->x11_fake_data); in channel_free_all()
831 sc->x11_fake_data = NULL; in channel_free_all()
832 sc->x11_fake_data_len = 0; in channel_free_all()
844 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) in channel_close_all()
845 if (ssh->chanctxt->channels[i] != NULL) in channel_close_all()
846 channel_close_fds(ssh, ssh->chanctxt->channels[i]); in channel_close_all()
858 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_stop_listening()
859 c = ssh->chanctxt->channels[i]; in channel_stop_listening()
861 switch (c->type) { in channel_stop_listening()
868 channel_close_fd(ssh, c, &c->sock); in channel_stop_listening()
887 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_not_very_much_buffered_data()
888 c = ssh->chanctxt->channels[i]; in channel_not_very_much_buffered_data()
889 if (c == NULL || c->type != SSH_CHANNEL_OPEN) in channel_not_very_much_buffered_data()
891 if (sshbuf_len(c->output) > maxsize) { in channel_not_very_much_buffered_data()
893 c->self, sshbuf_len(c->output), maxsize); in channel_not_very_much_buffered_data()
907 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_still_open()
908 c = ssh->chanctxt->channels[i]; in channel_still_open()
911 switch (c->type) { in channel_still_open()
936 fatal_f("bad channel type %d", c->type); in channel_still_open()
950 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_tty_open()
951 c = ssh->chanctxt->channels[i]; in channel_tty_open()
952 if (c == NULL || c->type != SSH_CHANNEL_OPEN) in channel_tty_open()
954 if (c->client_tty) in channel_tty_open()
967 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_find_open()
968 c = ssh->chanctxt->channels[i]; in channel_find_open()
969 if (c == NULL || !c->have_remote_id) in channel_find_open()
971 switch (c->type) { in channel_find_open()
995 fatal_f("bad channel type %d", c->type); in channel_find_open()
999 return -1; in channel_find_open()
1006 if (c->efd == -1) in channel_format_extended_usage()
1009 switch (c->extended_usage) { in channel_format_extended_usage()
1027 "fd %d/%d/%d sock %d cc %d io 0x%02x/0x%02x", in channel_format_status()
1028 c->type, c->xctype != NULL ? c->xctype : c->ctype, in channel_format_status()
1029 c->have_remote_id ? "r" : "nr", c->remote_id, in channel_format_status()
1030 c->istate, sshbuf_len(c->input), in channel_format_status()
1031 c->ostate, sshbuf_len(c->output), in channel_format_status()
1032 channel_format_extended_usage(c), sshbuf_len(c->extended), in channel_format_status()
1033 c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan, in channel_format_status()
1034 c->io_want, c->io_ready); in channel_format_status()
1057 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_open_message()
1058 c = ssh->chanctxt->channels[i]; in channel_open_message()
1061 switch (c->type) { in channel_open_message()
1085 c->self, c->remote_name, cp)) != 0) { in channel_open_message()
1092 fatal_f("bad channel type %d", c->type); in channel_open_message()
1109 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in open_preamble()
1110 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in open_preamble()
1111 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) { in open_preamble()
1112 fatal_r(r, "%s: channel %i: open", where, c->self); in open_preamble()
1127 open_preamble(ssh, __func__, c, c->ctype); in channel_send_open()
1129 fatal_fr(r, "channel %i", c->self); in channel_send_open()
1142 if (!c->have_remote_id) in channel_request_start()
1143 fatal_f("channel %d: no remote id", c->self); in channel_request_start()
1147 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_request_start()
1150 fatal_fr(r, "channel %i", c->self); in channel_request_start()
1165 cc->cb = cb; in channel_register_status_confirm()
1166 cc->abandon_cb = abandon_cb; in channel_register_status_confirm()
1167 cc->ctx = ctx; in channel_register_status_confirm()
1168 TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry); in channel_register_status_confirm()
1181 c->open_confirm = fn; in channel_register_open_confirm()
1182 c->open_confirm_ctx = ctx; in channel_register_open_confirm()
1195 c->detach_user = fn; in channel_register_cleanup()
1196 c->detach_close = do_close; in channel_register_cleanup()
1208 c->detach_user = NULL; in channel_cancel_cleanup()
1209 c->detach_close = 0; in channel_cancel_cleanup()
1222 c->input_filter = ifn; in channel_register_filter()
1223 c->output_filter = ofn; in channel_register_filter()
1224 c->filter_ctx = ctx; in channel_register_filter()
1225 c->filter_cleanup = cfn; in channel_register_filter()
1235 if (c == NULL || c->type != SSH_CHANNEL_LARVAL) in channel_set_fds()
1236 fatal("channel_activate for non-larval channel %d.", id); in channel_set_fds()
1237 if (!c->have_remote_id) in channel_set_fds()
1238 fatal_f("channel %d: no remote id", c->self); in channel_set_fds()
1241 c->type = SSH_CHANNEL_OPEN; in channel_set_fds()
1243 c->local_window = c->local_window_max = window_max; in channel_set_fds()
1246 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_set_fds()
1247 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in channel_set_fds()
1249 fatal_fr(r, "channel %i", c->self); in channel_set_fds()
1255 c->io_want = SSH_CHAN_IO_SOCK_R; in channel_pre_listener()
1261 debug3("channel %d: waiting for connection", c->self); in channel_pre_connecting()
1262 c->io_want = SSH_CHAN_IO_SOCK_W; in channel_pre_connecting()
1268 c->io_want = 0; in channel_pre_open()
1269 if (c->istate == CHAN_INPUT_OPEN && in channel_pre_open()
1270 c->remote_window > 0 && in channel_pre_open()
1271 sshbuf_len(c->input) < c->remote_window && in channel_pre_open()
1272 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0) in channel_pre_open()
1273 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_open()
1274 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_pre_open()
1275 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_open()
1276 if (sshbuf_len(c->output) > 0) { in channel_pre_open()
1277 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_open()
1278 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_open()
1281 "obuf_empty delayed efd %d/(%zu)", c->self, in channel_pre_open()
1282 c->efd, sshbuf_len(c->extended)); in channel_pre_open()
1288 if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED && in channel_pre_open()
1289 c->ostate == CHAN_OUTPUT_CLOSED)) { in channel_pre_open()
1290 if (c->extended_usage == CHAN_EXTENDED_WRITE && in channel_pre_open()
1291 sshbuf_len(c->extended) > 0) in channel_pre_open()
1292 c->io_want |= SSH_CHAN_IO_EFD_W; in channel_pre_open()
1293 else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) && in channel_pre_open()
1294 (c->extended_usage == CHAN_EXTENDED_READ || in channel_pre_open()
1295 c->extended_usage == CHAN_EXTENDED_IGNORE) && in channel_pre_open()
1296 sshbuf_len(c->extended) < c->remote_window) in channel_pre_open()
1297 c->io_want |= SSH_CHAN_IO_EFD_R; in channel_pre_open()
1309 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
1314 struct ssh_channels *sc = ssh->chanctxt; in x11_open_helper()
1319 if (sc->x11_refuse_time != 0 && in x11_open_helper()
1320 monotime() >= sc->x11_refuse_time) { in x11_open_helper()
1323 return -1; in x11_open_helper()
1330 /* Parse the lengths of variable-length fields. */ in x11_open_helper()
1341 return -1; in x11_open_helper()
1350 if (proto_len != strlen(sc->x11_saved_proto) || in x11_open_helper()
1351 memcmp(ucp + 12, sc->x11_saved_proto, proto_len) != 0) { in x11_open_helper()
1353 return -1; in x11_open_helper()
1356 if (data_len != sc->x11_fake_data_len || in x11_open_helper()
1358 sc->x11_fake_data, sc->x11_fake_data_len) != 0) { in x11_open_helper()
1360 return -1; in x11_open_helper()
1363 if (sc->x11_fake_data_len != sc->x11_saved_data_len) { in x11_open_helper()
1365 sc->x11_fake_data_len, sc->x11_saved_data_len); in x11_open_helper()
1366 return -1; in x11_open_helper()
1374 sc->x11_saved_data, sc->x11_saved_data_len); in x11_open_helper()
1381 debug3_f("channel %d: forcibly closing", c->self); in channel_force_close()
1382 if (c->istate == CHAN_INPUT_OPEN) in channel_force_close()
1384 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_force_close()
1385 sshbuf_reset(c->input); in channel_force_close()
1388 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_force_close()
1389 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_force_close()
1390 sshbuf_reset(c->output); in channel_force_close()
1393 if (c->detach_user) in channel_force_close()
1394 c->detach_user(ssh, c->self, 1, NULL); in channel_force_close()
1395 if (c->efd != -1) in channel_force_close()
1396 channel_close_fd(ssh, c, &c->efd); in channel_force_close()
1398 c->type = SSH_CHANNEL_ABANDONED; in channel_force_close()
1400 c->inactive_deadline = 0; in channel_force_close()
1401 c->lastused = 0; in channel_force_close()
1407 int ret = x11_open_helper(ssh, c->output); in channel_pre_x11_open()
1409 /* c->force_drain = 1; */ in channel_pre_x11_open()
1412 c->type = SSH_CHANNEL_OPEN; in channel_pre_x11_open()
1415 } else if (ret == -1) { in channel_pre_x11_open()
1419 c->self, c->istate, c->ostate); in channel_pre_x11_open()
1427 c->io_want = 0; in channel_pre_mux_client()
1428 if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause && in channel_pre_mux_client()
1429 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0) in channel_pre_mux_client()
1430 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_mux_client()
1431 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_pre_mux_client()
1433 sshbuf_reset(c->input); in channel_pre_mux_client()
1438 if (c->ostate == CHAN_OUTPUT_OPEN || in channel_pre_mux_client()
1439 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { in channel_pre_mux_client()
1440 if (sshbuf_len(c->output) > 0) in channel_pre_mux_client()
1441 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_mux_client()
1442 else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) in channel_pre_mux_client()
1463 debug2("channel %d: decode socks4", c->self); in channel_decode_socks4()
1474 debug2("channel %d: socks4a request", c->self); in channel_decode_socks4()
1488 c->self); in channel_decode_socks4()
1489 return -1; in channel_decode_socks4()
1498 debug_r(r, "channels %d: decode socks4", c->self); in channel_decode_socks4()
1499 return -1; in channel_decode_socks4()
1504 error("channel %d: decode socks4: unterminated user", c->self); in channel_decode_socks4()
1505 return -1; in channel_decode_socks4()
1508 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); in channel_decode_socks4()
1512 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks4()
1513 free(c->path); in channel_decode_socks4()
1514 c->path = NULL; in channel_decode_socks4()
1517 c->path = xstrdup(host); in channel_decode_socks4()
1523 "terminated", c->self); in channel_decode_socks4()
1524 return -1; in channel_decode_socks4()
1528 c->self, p, len); in channel_decode_socks4()
1532 c->self, p); in channel_decode_socks4()
1533 return -1; in channel_decode_socks4()
1535 c->path = xstrdup(p); in channel_decode_socks4()
1537 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks4()
1539 c->host_port = ntohs(s4_req.dest_port); in channel_decode_socks4()
1542 c->self, c->path, c->host_port, s4_req.command); in channel_decode_socks4()
1546 c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command); in channel_decode_socks4()
1547 return -1; in channel_decode_socks4()
1554 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks4()
1583 debug2("channel %d: decode socks5", c->self); in channel_decode_socks5()
1586 return -1; in channel_decode_socks5()
1588 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { in channel_decode_socks5()
1604 c->self); in channel_decode_socks5()
1605 return -1; in channel_decode_socks5()
1608 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1612 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks5()
1613 c->flags |= SSH_SOCKS5_AUTHDONE; in channel_decode_socks5()
1614 debug2("channel %d: socks5 auth done", c->self); in channel_decode_socks5()
1617 debug2("channel %d: socks5 post auth", c->self); in channel_decode_socks5()
1624 debug2("channel %d: only socks5 connect supported", c->self); in channel_decode_socks5()
1625 return -1; in channel_decode_socks5()
1634 af = -1; in channel_decode_socks5()
1641 debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); in channel_decode_socks5()
1642 return -1; in channel_decode_socks5()
1650 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1654 fatal_fr(r, "channel %d: consume", c->self); in channel_decode_socks5()
1658 debug_r(r, "channel %d: parse addr/port", c->self); in channel_decode_socks5()
1659 return -1; in channel_decode_socks5()
1662 free(c->path); in channel_decode_socks5()
1663 c->path = NULL; in channel_decode_socks5()
1667 "\"%.100s\" too long", c->self, dest_addr); in channel_decode_socks5()
1668 return -1; in channel_decode_socks5()
1670 c->path = xstrdup(dest_addr); in channel_decode_socks5()
1673 return -1; in channel_decode_socks5()
1674 c->path = xstrdup(ntop); in channel_decode_socks5()
1676 c->host_port = ntohs(dest_port); in channel_decode_socks5()
1679 c->self, c->path, c->host_port, s5_req.command); in channel_decode_socks5()
1690 fatal_fr(r, "channel %d: append reply", c->self); in channel_decode_socks5()
1703 c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, in channel_connect_stdio_fwd()
1704 -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, in channel_connect_stdio_fwd()
1705 0, "stdio-forward", nonblock); in channel_connect_stdio_fwd()
1707 c->path = xstrdup(host_to_connect); in channel_connect_stdio_fwd()
1708 c->host_port = port_to_connect; in channel_connect_stdio_fwd()
1709 c->listening_port = 0; in channel_connect_stdio_fwd()
1710 c->force_drain = 1; in channel_connect_stdio_fwd()
1712 channel_register_fds(ssh, c, in, out, -1, 0, 1, 0); in channel_connect_stdio_fwd()
1714 "direct-streamlocal@openssh.com" : "direct-tcpip"); in channel_connect_stdio_fwd()
1727 c->io_want = 0; in channel_pre_dynamic()
1728 have = sshbuf_len(c->input); in channel_pre_dynamic()
1729 debug2("channel %d: pre_dynamic: have %d", c->self, have); in channel_pre_dynamic()
1730 /* sshbuf_dump(c->input, stderr); */ in channel_pre_dynamic()
1734 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_dynamic()
1738 p = sshbuf_ptr(c->input); in channel_pre_dynamic()
1742 ret = channel_decode_socks4(c, c->input, c->output); in channel_pre_dynamic()
1745 ret = channel_decode_socks5(c, c->input, c->output); in channel_pre_dynamic()
1748 ret = -1; in channel_pre_dynamic()
1754 debug2("channel %d: pre_dynamic: need more", c->self); in channel_pre_dynamic()
1756 c->io_want |= SSH_CHAN_IO_RFD; in channel_pre_dynamic()
1757 if (sshbuf_len(c->output)) in channel_pre_dynamic()
1758 c->io_want |= SSH_CHAN_IO_WFD; in channel_pre_dynamic()
1761 c->type = SSH_CHANNEL_OPENING; in channel_pre_dynamic()
1762 port_open_helper(ssh, c, "direct-tcpip"); in channel_pre_dynamic()
1766 /* simulate read-error */
1770 c->type = SSH_CHANNEL_OPEN; in rdynamic_close()
1782 have = sshbuf_len(c->output); in channel_before_prepare_io_rdynamic()
1783 debug2("channel %d: pre_rdynamic: have %d", c->self, have); in channel_before_prepare_io_rdynamic()
1784 /* sshbuf_dump(c->output, stderr); */ in channel_before_prepare_io_rdynamic()
1786 if (c->flags & CHAN_EOF_RCVD) { in channel_before_prepare_io_rdynamic()
1787 if ((r = sshbuf_consume(c->output, have)) != 0) in channel_before_prepare_io_rdynamic()
1788 fatal_fr(r, "channel %d: consume", c->self); in channel_before_prepare_io_rdynamic()
1796 p = sshbuf_ptr(c->output); in channel_before_prepare_io_rdynamic()
1800 ret = channel_decode_socks4(c, c->output, c->input); in channel_before_prepare_io_rdynamic()
1803 ret = channel_decode_socks5(c, c->output, c->input); in channel_before_prepare_io_rdynamic()
1806 ret = -1; in channel_before_prepare_io_rdynamic()
1812 debug2("channel %d: pre_rdynamic: need more", c->self); in channel_before_prepare_io_rdynamic()
1814 len = sshbuf_len(c->input); in channel_before_prepare_io_rdynamic()
1815 if (len > 0 && len < c->remote_window) { in channel_before_prepare_io_rdynamic()
1817 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_before_prepare_io_rdynamic()
1818 (r = sshpkt_put_stringb(ssh, c->input)) != 0 || in channel_before_prepare_io_rdynamic()
1820 fatal_fr(r, "channel %i: rdynamic", c->self); in channel_before_prepare_io_rdynamic()
1822 if ((r = sshbuf_consume(c->input, len)) != 0) in channel_before_prepare_io_rdynamic()
1823 fatal_fr(r, "channel %d: consume", c->self); in channel_before_prepare_io_rdynamic()
1824 c->remote_window -= len; in channel_before_prepare_io_rdynamic()
1842 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_x11_listener()
1847 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_x11_listener()
1848 if (c->single_connection) { in channel_post_x11_listener()
1851 channel_close_fd(ssh, c, &c->sock); in channel_post_x11_listener()
1855 if (newsock == -1) { in channel_post_x11_listener()
1860 c->notbefore = monotime() + 1; in channel_post_x11_listener()
1869 nc = channel_new(ssh, "x11-connection", in channel_post_x11_listener()
1870 SSH_CHANNEL_OPENING, newsock, newsock, -1, in channel_post_x11_listener()
1871 c->local_window_max, c->local_maxpacket, 0, buf, 1); in channel_post_x11_listener()
1875 fatal_fr(r, "channel %i: reply", c->self); in channel_post_x11_listener()
1878 fatal_fr(r, "channel %i: send", c->self); in channel_post_x11_listener()
1885 char *local_ipaddr = get_local_ipaddr(c->sock); in port_open_helper()
1886 int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock); in port_open_helper()
1887 char *remote_ipaddr = get_peer_ipaddr(c->sock); in port_open_helper()
1888 int remote_port = get_peer_port(c->sock); in port_open_helper()
1891 if (remote_port == -1) { in port_open_helper()
1898 free(c->remote_name); in port_open_helper()
1899 xasprintf(&c->remote_name, in port_open_helper()
1902 rtype, c->listening_port, c->path, c->host_port, in port_open_helper()
1906 if (strcmp(rtype, "direct-tcpip") == 0) { in port_open_helper()
1908 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 || in port_open_helper()
1909 (r = sshpkt_put_u32(ssh, c->host_port)) != 0) in port_open_helper()
1910 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1911 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) { in port_open_helper()
1913 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) in port_open_helper()
1914 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1915 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { in port_open_helper()
1917 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()
1921 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 || in port_open_helper()
1923 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1925 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { in port_open_helper()
1928 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1933 fatal_fr(r, "channel %i: reply", c->self); in port_open_helper()
1936 fatal_fr(r, "channel %i: send", c->self); in port_open_helper()
1944 ssh->chanctxt->x11_refuse_time = refuse_time; in channel_set_x11_refuse_time()
1959 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_port_listener()
1963 c->listening_port, c->path, c->host_port); in channel_post_port_listener()
1965 if (c->type == SSH_CHANNEL_RPORT_LISTENER) { in channel_post_port_listener()
1967 rtype = "forwarded-tcpip"; in channel_post_port_listener()
1968 } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) { in channel_post_port_listener()
1970 rtype = "forwarded-streamlocal@openssh.com"; in channel_post_port_listener()
1971 } else if (c->host_port == PORT_STREAMLOCAL) { in channel_post_port_listener()
1973 rtype = "direct-streamlocal@openssh.com"; in channel_post_port_listener()
1974 } else if (c->host_port == 0) { in channel_post_port_listener()
1976 rtype = "dynamic-tcpip"; in channel_post_port_listener()
1979 rtype = "direct-tcpip"; in channel_post_port_listener()
1983 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_port_listener()
1984 if (newsock == -1) { in channel_post_port_listener()
1989 c->notbefore = monotime() + 1; in channel_post_port_listener()
1992 if (c->host_port != PORT_STREAMLOCAL) in channel_post_port_listener()
1994 nc = channel_new(ssh, rtype, nextstate, newsock, newsock, -1, in channel_post_port_listener()
1995 c->local_window_max, c->local_maxpacket, 0, rtype, 1); in channel_post_port_listener()
1996 nc->listening_port = c->listening_port; in channel_post_port_listener()
1997 nc->host_port = c->host_port; in channel_post_port_listener()
1998 if (c->path != NULL) in channel_post_port_listener()
1999 nc->path = xstrdup(c->path); in channel_post_port_listener()
2017 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_auth_listener()
2021 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); in channel_post_auth_listener()
2022 if (newsock == -1) { in channel_post_auth_listener()
2025 c->notbefore = monotime() + 1; in channel_post_auth_listener()
2028 nc = channel_new(ssh, "agent-connection", in channel_post_auth_listener()
2029 SSH_CHANNEL_OPENING, newsock, newsock, -1, in channel_post_auth_listener()
2030 c->local_window_max, c->local_maxpacket, in channel_post_auth_listener()
2032 open_preamble(ssh, __func__, nc, "auth-agent@openssh.com"); in channel_post_auth_listener()
2034 fatal_fr(r, "channel %i", c->self); in channel_post_auth_listener()
2043 if ((c->io_ready & SSH_CHAN_IO_SOCK_W) == 0) in channel_post_connecting()
2045 if (!c->have_remote_id) in channel_post_connecting()
2046 fatal_f("channel %d: no remote id", c->self); in channel_post_connecting()
2048 isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH); in channel_post_connecting()
2050 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) == -1) { in channel_post_connecting()
2056 /* Non-blocking connection completed */ in channel_post_connecting()
2058 c->self, c->connect_ctx.host, c->connect_ctx.port); in channel_post_connecting()
2059 channel_connect_ctx_free(&c->connect_ctx); in channel_post_connecting()
2060 c->type = SSH_CHANNEL_OPEN; in channel_post_connecting()
2067 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_post_connecting()
2068 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in channel_post_connecting()
2069 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in channel_post_connecting()
2070 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 || in channel_post_connecting()
2072 fatal_fr(r, "channel %i open confirm", c->self); in channel_post_connecting()
2079 /* Non-blocking connection failed */ in channel_post_connecting()
2080 debug("channel %d: connection failed: %s", c->self, strerror(err)); in channel_post_connecting()
2083 if ((sock = connect_next(&c->connect_ctx)) == -1) { in channel_post_connecting()
2086 c->connect_ctx.host, c->connect_ctx.port); in channel_post_connecting()
2087 channel_connect_ctx_free(&c->connect_ctx); in channel_post_connecting()
2093 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_post_connecting()
2099 fatal_fr(r, "channel %i: failure", c->self); in channel_post_connecting()
2104 /* New non-blocking connection in progress */ in channel_post_connecting()
2105 close(c->sock); in channel_post_connecting()
2106 c->sock = c->rfd = c->wfd = sock; in channel_post_connecting()
2119 /* Bug on AIX: read(1) can return 0 for a non-closed fd */ in channel_handle_rfd()
2120 pty_zeroread = c->isatty; in channel_handle_rfd()
2123 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; in channel_handle_rfd()
2125 if (!force && (c->io_ready & SSH_CHAN_IO_RFD) == 0) in channel_handle_rfd()
2127 if ((avail = sshbuf_avail(c->input)) == 0) in channel_handle_rfd()
2134 if (!pty_zeroread && c->input_filter == NULL && !c->datagram) { in channel_handle_rfd()
2136 if (c->type == SSH_CHANNEL_OPEN) { in channel_handle_rfd()
2137 if ((have = sshbuf_len(c->input)) >= c->remote_window) in channel_handle_rfd()
2139 if (maxlen > c->remote_window - have) in channel_handle_rfd()
2140 maxlen = c->remote_window - have; in channel_handle_rfd()
2144 if ((r = sshbuf_read(c->rfd, c->input, maxlen, &nr)) != 0) { in channel_handle_rfd()
2149 c->self, c->rfd, maxlen, ssh_err(r)); in channel_handle_rfd()
2158 len = read(c->rfd, buf, sizeof(buf)); in channel_handle_rfd()
2159 /* fixup AIX zero-length read with errno set to look more like errors */ in channel_handle_rfd()
2161 len = -1; in channel_handle_rfd()
2162 if (len == -1 && (errno == EINTR || in channel_handle_rfd()
2167 c->self, c->rfd, len, in channel_handle_rfd()
2170 if (c->type != SSH_CHANNEL_OPEN) { in channel_handle_rfd()
2171 debug2("channel %d: not open", c->self); in channel_handle_rfd()
2173 return -1; in channel_handle_rfd()
2177 return -1; in channel_handle_rfd()
2180 if (c->input_filter != NULL) { in channel_handle_rfd()
2181 if (c->input_filter(ssh, c, buf, len) == -1) { in channel_handle_rfd()
2182 debug2("channel %d: filter stops", c->self); in channel_handle_rfd()
2185 } else if (c->datagram) { in channel_handle_rfd()
2186 if ((r = sshbuf_put_string(c->input, buf, len)) != 0) in channel_handle_rfd()
2187 fatal_fr(r, "channel %i: put datagram", c->self); in channel_handle_rfd()
2188 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) in channel_handle_rfd()
2189 fatal_fr(r, "channel %i: put data", c->self); in channel_handle_rfd()
2202 if ((c->io_ready & SSH_CHAN_IO_WFD) == 0) in channel_handle_wfd()
2204 if (sshbuf_len(c->output) == 0) in channel_handle_wfd()
2208 olen = sshbuf_len(c->output); in channel_handle_wfd()
2209 if (c->output_filter != NULL) { in channel_handle_wfd()
2210 if ((buf = c->output_filter(ssh, c, &data, &dlen)) == NULL) { in channel_handle_wfd()
2211 debug2("channel %d: filter stops", c->self); in channel_handle_wfd()
2212 if (c->type != SSH_CHANNEL_OPEN) in channel_handle_wfd()
2216 return -1; in channel_handle_wfd()
2218 } else if (c->datagram) { in channel_handle_wfd()
2219 if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0) in channel_handle_wfd()
2220 fatal_fr(r, "channel %i: get datagram", c->self); in channel_handle_wfd()
2223 buf = data = sshbuf_mutable_ptr(c->output); in channel_handle_wfd()
2224 dlen = sshbuf_len(c->output); in channel_handle_wfd()
2227 if (c->datagram) { in channel_handle_wfd()
2229 len = write(c->wfd, buf, dlen); in channel_handle_wfd()
2231 if (len == -1 && (errno == EINTR || errno == EAGAIN || in channel_handle_wfd()
2241 if (c->wfd_isatty) in channel_handle_wfd()
2245 len = write(c->wfd, buf, dlen); in channel_handle_wfd()
2246 if (len == -1 && in channel_handle_wfd()
2251 if (c->type != SSH_CHANNEL_OPEN) { in channel_handle_wfd()
2252 debug2("channel %d: not open", c->self); in channel_handle_wfd()
2254 return -1; in channel_handle_wfd()
2258 return -1; in channel_handle_wfd()
2262 if (c->isatty && dlen >= 1 && buf[0] != '\r') { in channel_handle_wfd()
2263 if (tcgetattr(c->wfd, &tio) == 0 && in channel_handle_wfd()
2273 fatal_fr(r, "channel %i: ignore", c->self); in channel_handle_wfd()
2277 if ((r = sshbuf_consume(c->output, len)) != 0) in channel_handle_wfd()
2278 fatal_fr(r, "channel %i: consume", c->self); in channel_handle_wfd()
2280 c->local_consumed += olen - sshbuf_len(c->output); in channel_handle_wfd()
2291 if ((c->io_ready & SSH_CHAN_IO_EFD_W) == 0) in channel_handle_efd_write()
2293 if (sshbuf_len(c->extended) == 0) in channel_handle_efd_write()
2296 len = write(c->efd, sshbuf_ptr(c->extended), in channel_handle_efd_write()
2297 sshbuf_len(c->extended)); in channel_handle_efd_write()
2298 debug2("channel %d: written %zd to efd %d", c->self, len, c->efd); in channel_handle_efd_write()
2299 if (len == -1 && (errno == EINTR || errno == EAGAIN || in channel_handle_efd_write()
2303 debug2("channel %d: closing write-efd %d", c->self, c->efd); in channel_handle_efd_write()
2304 channel_close_fd(ssh, c, &c->efd); in channel_handle_efd_write()
2306 if ((r = sshbuf_consume(c->extended, len)) != 0) in channel_handle_efd_write()
2307 fatal_fr(r, "channel %i: consume", c->self); in channel_handle_efd_write()
2308 c->local_consumed += len; in channel_handle_efd_write()
2321 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; in channel_handle_efd_read()
2323 if (!force && (c->io_ready & SSH_CHAN_IO_EFD_R) == 0) in channel_handle_efd_read()
2326 len = read(c->efd, buf, sizeof(buf)); in channel_handle_efd_read()
2327 debug2("channel %d: read %zd from efd %d", c->self, len, c->efd); in channel_handle_efd_read()
2328 if (len == -1 && (errno == EINTR || ((errno == EAGAIN || in channel_handle_efd_read()
2332 debug2("channel %d: closing read-efd %d", c->self, c->efd); in channel_handle_efd_read()
2333 channel_close_fd(ssh, c, &c->efd); in channel_handle_efd_read()
2337 if (c->extended_usage == CHAN_EXTENDED_IGNORE) in channel_handle_efd_read()
2338 debug3("channel %d: discard efd", c->self); in channel_handle_efd_read()
2339 else if ((r = sshbuf_put(c->extended, buf, len)) != 0) in channel_handle_efd_read()
2340 fatal_fr(r, "channel %i: append", c->self); in channel_handle_efd_read()
2347 if (c->efd == -1) in channel_handle_efd()
2352 if (c->extended_usage == CHAN_EXTENDED_WRITE) in channel_handle_efd()
2354 else if (c->extended_usage == CHAN_EXTENDED_READ || in channel_handle_efd()
2355 c->extended_usage == CHAN_EXTENDED_IGNORE) in channel_handle_efd()
2366 if (c->type == SSH_CHANNEL_OPEN && in channel_check_window()
2367 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && in channel_check_window()
2368 ((c->local_window_max - c->local_window > in channel_check_window()
2369 c->local_maxpacket*3) || in channel_check_window()
2370 c->local_window < c->local_window_max/2) && in channel_check_window()
2371 c->local_consumed > 0) { in channel_check_window()
2372 if (!c->have_remote_id) in channel_check_window()
2373 fatal_f("channel %d: no remote id", c->self); in channel_check_window()
2376 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_check_window()
2377 (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 || in channel_check_window()
2379 fatal_fr(r, "channel %i", c->self); in channel_check_window()
2381 debug2("channel %d: window %d sent adjust %d", c->self, in channel_check_window()
2382 c->local_window, c->local_consumed); in channel_check_window()
2383 c->local_window += c->local_consumed; in channel_check_window()
2384 c->local_consumed = 0; in channel_check_window()
2406 if (sshbuf_len(c->input) < need) { in read_mux()
2407 rlen = need - sshbuf_len(c->input); in read_mux()
2408 len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF)); in read_mux()
2409 if (len == -1 && (errno == EINTR || errno == EAGAIN)) in read_mux()
2410 return sshbuf_len(c->input); in read_mux()
2413 c->self, c->rfd, len); in read_mux()
2416 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) in read_mux()
2417 fatal_fr(r, "channel %i: append", c->self); in read_mux()
2419 return sshbuf_len(c->input); in read_mux()
2427 if ((c->io_ready & SSH_CHAN_IO_RFD) == 0) in channel_post_mux_client_read()
2429 if (c->istate != CHAN_INPUT_OPEN && c->istate != CHAN_INPUT_WAIT_DRAIN) in channel_post_mux_client_read()
2431 if (c->mux_pause) in channel_post_mux_client_read()
2441 need = PEEK_U32(sshbuf_ptr(c->input)); in channel_post_mux_client_read()
2445 c->self, CHANNEL_MUX_MAX_PACKET, need); in channel_post_mux_client_read()
2451 if (c->mux_rcb(ssh, c) != 0) { in channel_post_mux_client_read()
2452 debug("channel %d: mux_rcb failed", c->self); in channel_post_mux_client_read()
2464 if ((c->io_ready & SSH_CHAN_IO_WFD) == 0) in channel_post_mux_client_write()
2466 if (sshbuf_len(c->output) == 0) in channel_post_mux_client_write()
2469 len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output)); in channel_post_mux_client_write()
2470 if (len == -1 && (errno == EINTR || errno == EAGAIN)) in channel_post_mux_client_write()
2476 if ((r = sshbuf_consume(c->output, len)) != 0) in channel_post_mux_client_write()
2477 fatal_fr(r, "channel %i: consume", c->self); in channel_post_mux_client_write()
2497 if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0) in channel_post_mux_listener()
2507 if ((newsock = accept(c->sock, (struct sockaddr*)&addr, in channel_post_mux_listener()
2508 &addrlen)) == -1) { in channel_post_mux_listener()
2511 c->notbefore = monotime() + 1; in channel_post_mux_listener()
2515 if (getpeereid(newsock, &euid, &egid) == -1) { in channel_post_mux_listener()
2521 error("multiplex uid mismatch: peer euid %u != uid %u", in channel_post_mux_listener()
2526 nc = channel_new(ssh, "mux-control", SSH_CHANNEL_MUX_CLIENT, in channel_post_mux_listener()
2527 newsock, newsock, -1, c->local_window_max, in channel_post_mux_listener()
2528 c->local_maxpacket, 0, "mux-control", 1); in channel_post_mux_listener()
2529 nc->mux_rcb = c->mux_rcb; in channel_post_mux_listener()
2530 debug3_f("new mux channel %d fd %d", nc->self, nc->sock); in channel_post_mux_listener()
2532 nc->mux_rcb(ssh, nc); in channel_post_mux_listener()
2534 nc->flags |= CHAN_LOCAL; in channel_post_mux_listener()
2573 sc->channel_pre = pre; in channel_handler_init()
2574 sc->channel_post = post; in channel_handler_init()
2583 if (c->detach_user != NULL) { in channel_garbage_collect()
2584 if (!chan_is_dead(ssh, c, c->detach_close)) in channel_garbage_collect()
2587 debug2("channel %d: gc: notify user", c->self); in channel_garbage_collect()
2588 c->detach_user(ssh, c->self, 0, NULL); in channel_garbage_collect()
2590 if (c->detach_user != NULL) in channel_garbage_collect()
2592 debug2("channel %d: gc: user detached", c->self); in channel_garbage_collect()
2596 debug2("channel %d: garbage collecting", c->self); in channel_garbage_collect()
2605 struct ssh_channels *sc = ssh->chanctxt; in channel_handler()
2606 chan_fn **ftab = table == CHAN_PRE ? sc->channel_pre : sc->channel_post; in channel_handler()
2612 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { in channel_handler()
2613 c = sc->channels[i]; in channel_handler()
2616 /* Try to keep IO going while rekeying */ in channel_handler()
2617 if (ssh_packet_is_rekeying(ssh) && c->type != SSH_CHANNEL_OPEN) in channel_handler()
2619 if (c->delayed) { in channel_handler()
2621 c->delayed = 0; in channel_handler()
2625 if (ftab[c->type] != NULL) { in channel_handler()
2626 if (table == CHAN_PRE && c->type == SSH_CHANNEL_OPEN && in channel_handler()
2631 "of inactivity", c->self, in channel_handler()
2632 c->inactive_deadline); in channel_handler()
2634 } else if (c->notbefore <= now) { in channel_handler()
2636 (*ftab[c->type])(ssh, c); in channel_handler()
2639 c->type == SSH_CHANNEL_OPEN && in channel_handler()
2650 c->notbefore); in channel_handler()
2658 * Create sockets before preparing IO.
2660 * the network-input but need to be completed before IO event setup, e.g.
2666 struct ssh_channels *sc = ssh->chanctxt; in channel_before_prepare_io()
2670 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { in channel_before_prepare_io()
2671 c = sc->channels[i]; in channel_before_prepare_io()
2674 if (c->type == SSH_CHANNEL_RDYNAMIC_OPEN) in channel_before_prepare_io()
2684 debug3("%s: channel %d: %s r%d w%d e%d s%d c->pfds [ %d %d %d %d ] " in dump_channel_poll()
2686 "pfd.ev 0x%02x pfd.rev 0x%02x", func, c->self, what, in dump_channel_poll()
2687 c->rfd, c->wfd, c->efd, c->sock, in dump_channel_poll()
2688 c->pfds[0], c->pfds[1], c->pfds[2], c->pfds[3], in dump_channel_poll()
2689 c->io_want, c->io_ready, in dump_channel_poll()
2690 pollfd_offset, pfd->fd, pfd->events, pfd->revents); in dump_channel_poll()
2706 c->self, p, npfd); in channel_prepare_pollfd()
2708 c->pfds[0] = c->pfds[1] = c->pfds[2] = c->pfds[3] = -1; in channel_prepare_pollfd()
2710 * prepare c->rfd in channel_prepare_pollfd()
2712 * This is a special case, since c->rfd might be the same as in channel_prepare_pollfd()
2713 * c->wfd, c->efd and/or c->sock. Handle those here if they want in channel_prepare_pollfd()
2714 * IO too. in channel_prepare_pollfd()
2716 if (c->rfd != -1) { in channel_prepare_pollfd()
2718 if ((c->io_want & SSH_CHAN_IO_RFD) != 0) in channel_prepare_pollfd()
2721 if (c->wfd == c->rfd) { in channel_prepare_pollfd()
2722 if ((c->io_want & SSH_CHAN_IO_WFD) != 0) in channel_prepare_pollfd()
2726 if (c->efd == c->rfd) { in channel_prepare_pollfd()
2727 if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) in channel_prepare_pollfd()
2729 if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) in channel_prepare_pollfd()
2733 if (c->sock == c->rfd) { in channel_prepare_pollfd()
2734 if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) in channel_prepare_pollfd()
2736 if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) in channel_prepare_pollfd()
2741 c->pfds[0] = p; in channel_prepare_pollfd()
2742 pfd[p].fd = c->rfd; in channel_prepare_pollfd()
2748 /* prepare c->wfd if wanting IO and not already handled above */ in channel_prepare_pollfd()
2749 if (c->wfd != -1 && c->rfd != c->wfd) { in channel_prepare_pollfd()
2751 if ((c->io_want & SSH_CHAN_IO_WFD)) in channel_prepare_pollfd()
2755 c->pfds[1] = p; in channel_prepare_pollfd()
2756 pfd[p].fd = c->wfd; in channel_prepare_pollfd()
2762 /* prepare c->efd if wanting IO and not already handled above */ in channel_prepare_pollfd()
2763 if (c->efd != -1 && c->rfd != c->efd) { in channel_prepare_pollfd()
2765 if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) in channel_prepare_pollfd()
2767 if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) in channel_prepare_pollfd()
2771 c->pfds[2] = p; in channel_prepare_pollfd()
2772 pfd[p].fd = c->efd; in channel_prepare_pollfd()
2778 /* prepare c->sock if wanting IO and not already handled above */ in channel_prepare_pollfd()
2779 if (c->sock != -1 && c->rfd != c->sock) { in channel_prepare_pollfd()
2781 if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) in channel_prepare_pollfd()
2783 if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) in channel_prepare_pollfd()
2787 c->pfds[3] = p; in channel_prepare_pollfd()
2788 pfd[p].fd = c->sock; in channel_prepare_pollfd()
2802 struct ssh_channels *sc = ssh->chanctxt; in channel_prepare_poll()
2807 for (i = 0; i < sc->channels_alloc; i++) { in channel_prepare_poll()
2808 if (sc->channels[i] == NULL) in channel_prepare_poll()
2810 sc->channels[i]->io_want = sc->channels[i]->io_ready = 0; in channel_prepare_poll()
2813 if (sc->channels_alloc >= (INT_MAX / 4) - npfd_reserved) in channel_prepare_poll()
2815 npfd += sc->channels_alloc * 4; in channel_prepare_poll()
2822 oalloc = sc->channels_alloc; in channel_prepare_poll()
2826 if (oalloc != sc->channels_alloc) { in channel_prepare_poll()
2829 "(was %u, now %u)", oalloc, sc->channels_alloc); in channel_prepare_poll()
2834 for (i = 0; i < sc->channels_alloc; i++) in channel_prepare_poll()
2835 channel_prepare_pollfd(sc->channels[i], &p, *pfdp, npfd); in channel_prepare_poll()
2845 if (fd == -1) in fd_ready()
2847 if (p == -1 || (u_int)p >= npfd) in fd_ready()
2848 fatal_f("channel %d: bad pfd %d (max %u)", c->self, p, npfd); in fd_ready()
2850 if (pfd->fd != fd) { in fd_ready()
2852 "r%d w%d e%d s%d", c->self, what, fd, p, pfd->fd, in fd_ready()
2853 c->rfd, c->wfd, c->efd, c->sock); in fd_ready()
2855 if ((pfd->revents & POLLNVAL) != 0) { in fd_ready()
2857 c->self, what, p, pfd->fd, c->rfd, c->wfd, c->efd, c->sock); in fd_ready()
2859 if ((pfd->revents & (revents_mask|POLLHUP|POLLERR)) != 0) in fd_ready()
2860 c->io_ready |= ready & c->io_want; in fd_ready()
2870 struct ssh_channels *sc = ssh->chanctxt; in channel_after_poll()
2884 /* Convert pollfd into c->io_ready */ in channel_after_poll()
2885 for (i = 0; i < sc->channels_alloc; i++) { in channel_after_poll()
2886 c = sc->channels[i]; in channel_after_poll()
2890 if (c->rfd != -1 && c->wfd != -1 && c->rfd != c->wfd && in channel_after_poll()
2891 (c->rfd == c->efd || c->rfd == c->sock)) { in channel_after_poll()
2894 c->self, c->rfd, c->wfd, c->efd, c->sock); in channel_after_poll()
2896 c->io_ready = 0; in channel_after_poll()
2898 if (c->rfd != -1 && (p = c->pfds[0]) != -1) { in channel_after_poll()
2899 fd_ready(c, p, pfd, npfd, c->rfd, in channel_after_poll()
2901 if (c->rfd == c->wfd) { in channel_after_poll()
2902 fd_ready(c, p, pfd, npfd, c->wfd, in channel_after_poll()
2905 if (c->rfd == c->efd) { in channel_after_poll()
2906 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2908 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2911 if (c->rfd == c->sock) { in channel_after_poll()
2912 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2914 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2920 if (c->wfd != -1 && c->wfd != c->rfd && in channel_after_poll()
2921 (p = c->pfds[1]) != -1) { in channel_after_poll()
2922 fd_ready(c, p, pfd, npfd, c->wfd, in channel_after_poll()
2927 if (c->efd != -1 && c->efd != c->rfd && in channel_after_poll()
2928 (p = c->pfds[2]) != -1) { in channel_after_poll()
2929 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2931 fd_ready(c, p, pfd, npfd, c->efd, in channel_after_poll()
2936 if (c->sock != -1 && c->sock != c->rfd && in channel_after_poll()
2937 (p = c->pfds[3]) != -1) { in channel_after_poll()
2938 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2940 fd_ready(c, p, pfd, npfd, c->sock, in channel_after_poll()
2949 * Enqueue data for channels with open or draining c->input.
2950 * Returns non-zero if a packet was enqueued.
2959 if ((len = sshbuf_len(c->input)) == 0) { in channel_output_poll_input_open()
2960 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { in channel_output_poll_input_open()
2962 * input-buffer is empty and read-socket shutdown: in channel_output_poll_input_open()
2971 c->self, c->efd, sshbuf_len(c->extended)); in channel_output_poll_input_open()
2978 if (!c->have_remote_id) in channel_output_poll_input_open()
2979 fatal_f("channel %d: no remote id", c->self); in channel_output_poll_input_open()
2981 if (c->datagram) { in channel_output_poll_input_open()
2983 if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0) in channel_output_poll_input_open()
2984 fatal_fr(r, "channel %i: get datagram", c->self); in channel_output_poll_input_open()
2986 * XXX this does tail-drop on the datagram queue which is in channel_output_poll_input_open()
2987 * usually suboptimal compared to head-drop. Better to have in channel_output_poll_input_open()
2990 if (plen > c->remote_window || plen > c->remote_maxpacket) { in channel_output_poll_input_open()
2991 debug("channel %d: datagram too big", c->self); in channel_output_poll_input_open()
2996 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_input_open()
2999 fatal_fr(r, "channel %i: send datagram", c->self); in channel_output_poll_input_open()
3000 c->remote_window -= plen; in channel_output_poll_input_open()
3005 if (len > c->remote_window) in channel_output_poll_input_open()
3006 len = c->remote_window; in channel_output_poll_input_open()
3007 if (len > c->remote_maxpacket) in channel_output_poll_input_open()
3008 len = c->remote_maxpacket; in channel_output_poll_input_open()
3012 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_input_open()
3013 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 || in channel_output_poll_input_open()
3015 fatal_fr(r, "channel %i: send data", c->self); in channel_output_poll_input_open()
3016 if ((r = sshbuf_consume(c->input, len)) != 0) in channel_output_poll_input_open()
3017 fatal_fr(r, "channel %i: consume", c->self); in channel_output_poll_input_open()
3018 c->remote_window -= len; in channel_output_poll_input_open()
3023 * Enqueue data for channels with open c->extended in read mode.
3024 * Returns non-zero if a packet was enqueued.
3032 if ((len = sshbuf_len(c->extended)) == 0) in channel_output_poll_extended_read()
3035 debug2("channel %d: rwin %u elen %zu euse %d", c->self, in channel_output_poll_extended_read()
3036 c->remote_window, sshbuf_len(c->extended), c->extended_usage); in channel_output_poll_extended_read()
3037 if (len > c->remote_window) in channel_output_poll_extended_read()
3038 len = c->remote_window; in channel_output_poll_extended_read()
3039 if (len > c->remote_maxpacket) in channel_output_poll_extended_read()
3040 len = c->remote_maxpacket; in channel_output_poll_extended_read()
3043 if (!c->have_remote_id) in channel_output_poll_extended_read()
3044 fatal_f("channel %d: no remote id", c->self); in channel_output_poll_extended_read()
3046 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in channel_output_poll_extended_read()
3048 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 || in channel_output_poll_extended_read()
3050 fatal_fr(r, "channel %i: data", c->self); in channel_output_poll_extended_read()
3051 if ((r = sshbuf_consume(c->extended, len)) != 0) in channel_output_poll_extended_read()
3052 fatal_fr(r, "channel %i: consume", c->self); in channel_output_poll_extended_read()
3053 c->remote_window -= len; in channel_output_poll_extended_read()
3054 debug2("channel %d: sent ext data %zu", c->self, len); in channel_output_poll_extended_read()
3060 * Returns non-zero if data was enqueued.
3065 struct ssh_channels *sc = ssh->chanctxt; in channel_output_poll()
3070 for (i = 0; i < sc->channels_alloc; i++) { in channel_output_poll()
3071 c = sc->channels[i]; in channel_output_poll()
3079 if (c->type != SSH_CHANNEL_OPEN) in channel_output_poll()
3081 if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { in channel_output_poll()
3084 c->self); in channel_output_poll()
3089 if (c->istate == CHAN_INPUT_OPEN || in channel_output_poll()
3090 c->istate == CHAN_INPUT_WAIT_DRAIN) in channel_output_poll()
3093 if (!(c->flags & CHAN_EOF_SENT) && in channel_output_poll()
3094 c->extended_usage == CHAN_EXTENDED_READ) in channel_output_poll()
3100 /* -- mux proxy support */
3108 * - We forward all messages (mostly) unmodified to the server.
3109 * - However, in order to route messages from upstream to the correct
3113 * - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and
3128 * specific downstream client based on the listen-address/port.
3129 * 6) Agent and X11-Forwarding have a similar problem and are currently
3149 int ret = -1, r; in channel_proxy_downstream()
3152 /* sshbuf_dump(downstream->input, stderr); */ in channel_proxy_downstream()
3153 if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have)) in channel_proxy_downstream()
3156 return -1; in channel_proxy_downstream()
3160 return -1; in channel_proxy_downstream()
3165 have -= 2; in channel_proxy_downstream()
3167 debug3_f("channel %u: down->up: type %u", in channel_proxy_downstream()
3168 downstream->self, type); in channel_proxy_downstream()
3182 c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY, in channel_proxy_downstream()
3183 -1, -1, -1, 0, 0, 0, ctype, 1); in channel_proxy_downstream()
3184 c->mux_ctx = downstream; /* point to mux client */ in channel_proxy_downstream()
3185 c->mux_downstream_id = id; /* original downstream id */ in channel_proxy_downstream()
3187 (r = sshbuf_put_u32(modified, c->self)) != 0 || in channel_proxy_downstream()
3209 c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY, in channel_proxy_downstream()
3210 -1, -1, -1, 0, 0, 0, "mux-down-connect", 1); in channel_proxy_downstream()
3211 c->mux_ctx = downstream; /* point to mux client */ in channel_proxy_downstream()
3212 c->mux_downstream_id = id; in channel_proxy_downstream()
3213 c->remote_id = remote_id; in channel_proxy_downstream()
3214 c->have_remote_id = 1; in channel_proxy_downstream()
3216 (r = sshbuf_put_u32(modified, c->self)) != 0 || in channel_proxy_downstream()
3232 if (strcmp(ctype, "tcpip-forward") != 0) { in channel_proxy_downstream()
3243 error_f("tcpip-forward for %s: bad port %u", in channel_proxy_downstream()
3249 -1, listen_host, NULL, (int)listen_port, downstream); in channel_proxy_downstream()
3256 if (c->flags & CHAN_CLOSE_RCVD) in channel_proxy_downstream()
3259 c->flags |= CHAN_CLOSE_SENT; in channel_proxy_downstream()
3288 * receive packets from upstream server and de-multiplex packets
3308 if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY) in channel_proxy_upstream()
3310 if ((downstream = c->mux_ctx) == NULL) in channel_proxy_upstream()
3325 debug2_f("channel %u: unsupported type %u", c->self, type); in channel_proxy_upstream()
3341 (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 || in channel_proxy_upstream()
3343 (r = sshbuf_put_stringb(downstream->output, b)) != 0) { in channel_proxy_upstream()
3349 debug3_f("channel %u: up->down: type %u", c->self, type); in channel_proxy_upstream()
3356 c->remote_id = PEEK_U32(cp); in channel_proxy_upstream()
3357 c->have_remote_id = 1; in channel_proxy_upstream()
3361 if (c->flags & CHAN_CLOSE_SENT) in channel_proxy_upstream()
3364 c->flags |= CHAN_CLOSE_RCVD; in channel_proxy_upstream()
3371 /* -- protocol input */
3416 /* Ignore any data for non-open channels (might happen on close) */ in channel_input_data()
3417 if (c->type != SSH_CHANNEL_OPEN && in channel_input_data()
3418 c->type != SSH_CHANNEL_RDYNAMIC_OPEN && in channel_input_data()
3419 c->type != SSH_CHANNEL_RDYNAMIC_FINISH && in channel_input_data()
3420 c->type != SSH_CHANNEL_X11_OPEN) in channel_input_data()
3426 fatal_fr(r, "channel %i: get data", c->self); in channel_input_data()
3429 if (c->datagram) in channel_input_data()
3437 if (c->ostate != CHAN_OUTPUT_OPEN) { in channel_input_data()
3438 c->local_window -= win_len; in channel_input_data()
3439 c->local_consumed += win_len; in channel_input_data()
3443 if (win_len > c->local_maxpacket) { in channel_input_data()
3445 c->self, win_len, c->local_maxpacket); in channel_input_data()
3448 if (win_len > c->local_window) { in channel_input_data()
3449 c->local_window_exceeded += win_len - c->local_window; in channel_input_data()
3451 "(excess %u)", c->self, win_len, c->local_window, in channel_input_data()
3452 c->local_window_max, c->local_window_exceeded); in channel_input_data()
3453 c->local_window = 0; in channel_input_data()
3455 if (c->local_window_exceeded > (c->local_window_max / 10)) { in channel_input_data()
3457 "channel window", c->self); in channel_input_data()
3460 c->local_window -= win_len; in channel_input_data()
3461 c->local_window_exceeded = 0; in channel_input_data()
3464 if (c->datagram) { in channel_input_data()
3465 if ((r = sshbuf_put_string(c->output, data, data_len)) != 0) in channel_input_data()
3466 fatal_fr(r, "channel %i: append datagram", c->self); in channel_input_data()
3467 } else if ((r = sshbuf_put(c->output, data, data_len)) != 0) in channel_input_data()
3468 fatal_fr(r, "channel %i: append data", c->self); in channel_input_data()
3484 if (c->type != SSH_CHANNEL_OPEN) { in channel_input_extended_data()
3485 logit("channel %d: ext data for non open", c->self); in channel_input_extended_data()
3488 if (c->flags & CHAN_EOF_RCVD) { in channel_input_extended_data()
3489 if (ssh->compat & SSH_BUG_EXTEOF) in channel_input_extended_data()
3491 c->self); in channel_input_extended_data()
3494 "after EOF on channel %d.", c->self); in channel_input_extended_data()
3501 if (c->efd == -1 || in channel_input_extended_data()
3502 c->extended_usage != CHAN_EXTENDED_WRITE || in channel_input_extended_data()
3504 logit("channel %d: bad ext data", c->self); in channel_input_extended_data()
3513 if (data_len > c->local_window) { in channel_input_extended_data()
3515 c->self, data_len, c->local_window); in channel_input_extended_data()
3518 debug2("channel %d: rcvd ext data %zu", c->self, data_len); in channel_input_extended_data()
3520 if ((r = sshbuf_put(c->extended, data, data_len)) != 0) in channel_input_extended_data()
3522 c->local_window -= data_len; in channel_input_extended_data()
3542 if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { in channel_input_ieof()
3543 debug("channel %d: FORCE input drain", c->self); in channel_input_ieof()
3544 c->istate = CHAN_INPUT_WAIT_DRAIN; in channel_input_ieof()
3545 if (sshbuf_len(c->input) == 0) in channel_input_ieof()
3576 if (c->type != SSH_CHANNEL_OPENING) in channel_input_open_confirmation()
3578 "non-opening channel %d.", c->self); in channel_input_open_confirmation()
3583 if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 || in channel_input_open_confirmation()
3591 c->have_remote_id = 1; in channel_input_open_confirmation()
3592 c->remote_window = remote_window; in channel_input_open_confirmation()
3593 c->remote_maxpacket = remote_maxpacket; in channel_input_open_confirmation()
3594 c->type = SSH_CHANNEL_OPEN; in channel_input_open_confirmation()
3595 if (c->open_confirm) { in channel_input_open_confirmation()
3596 debug2_f("channel %d: callback start", c->self); in channel_input_open_confirmation()
3597 c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx); in channel_input_open_confirmation()
3598 debug2_f("channel %d: callback done", c->self); in channel_input_open_confirmation()
3601 debug2("channel %d: open confirm rwindow %u rmax %u", c->self, in channel_input_open_confirmation()
3602 c->remote_window, c->remote_maxpacket); in channel_input_open_confirmation()
3632 if (c->type != SSH_CHANNEL_OPENING) in channel_input_open_failure()
3634 "non-opening channel %d.", c->self); in channel_input_open_failure()
3646 logit("channel %d: open failed: %s%s%s", c->self, in channel_input_open_failure()
3649 if (c->open_confirm) { in channel_input_open_failure()
3650 debug2_f("channel %d: callback start", c->self); in channel_input_open_failure()
3651 c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx); in channel_input_open_failure()
3652 debug2_f("channel %d: callback done", c->self); in channel_input_open_failure()
3669 logit("Received window adjust for non-open channel %d.", id); in channel_input_window_adjust()
3680 debug2("channel %d: rcvd adjust %u", c->self, adjust); in channel_input_window_adjust()
3681 if ((new_rwin = c->remote_window + adjust) < c->remote_window) { in channel_input_window_adjust()
3683 c->self, adjust, c->remote_window); in channel_input_window_adjust()
3685 c->remote_window = new_rwin; in channel_input_window_adjust()
3709 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) in channel_input_status_confirm()
3711 cc->cb(ssh, type, c, cc->ctx); in channel_input_status_confirm()
3712 TAILQ_REMOVE(&c->status_confirms, cc, entry); in channel_input_status_confirm()
3717 /* -- tcp forwarding */
3722 ssh->chanctxt->IPv4or6 = af; in channel_set_af()
3734 * Special-case listen_addrs are:
3736 * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
3737 * "" (empty string), "*" -> wildcard v4/v6
3738 * "localhost" -> loopback v4/v6
3739 * "127.0.0.1" / "::1" -> accepted even if gateway_ports isn't set
3750 if (fwd_opts->gateway_ports) in channel_fwd_bind_addr()
3752 } else if (fwd_opts->gateway_ports || is_client) { in channel_fwd_bind_addr()
3753 if (((ssh->compat & SSH_OLD_FORWARD_ADDR) && in channel_fwd_bind_addr()
3756 (!is_client && fwd_opts->gateway_ports == 1)) { in channel_fwd_bind_addr()
3809 if (is_client && fwd->connect_path != NULL) { in channel_setup_fwd_listener_tcpip()
3810 host = fwd->connect_path; in channel_setup_fwd_listener_tcpip()
3813 fwd->listen_host : fwd->connect_host; in channel_setup_fwd_listener_tcpip()
3825 addr = channel_fwd_bind_addr(ssh, fwd->listen_host, &wildcard, in channel_setup_fwd_listener_tcpip()
3835 hints.ai_family = ssh->chanctxt->IPv4or6; in channel_setup_fwd_listener_tcpip()
3838 snprintf(strport, sizeof strport, "%d", fwd->listen_port); in channel_setup_fwd_listener_tcpip()
3852 for (ai = aitop; ai; ai = ai->ai_next) { in channel_setup_fwd_listener_tcpip()
3853 switch (ai->ai_family) { in channel_setup_fwd_listener_tcpip()
3855 lport_p = &((struct sockaddr_in *)ai->ai_addr)-> in channel_setup_fwd_listener_tcpip()
3859 lport_p = &((struct sockaddr_in6 *)ai->ai_addr)-> in channel_setup_fwd_listener_tcpip()
3866 * If allocating a port for -R forwards, then use the in channel_setup_fwd_listener_tcpip()
3870 fwd->listen_port == 0 && allocated_listen_port != NULL && in channel_setup_fwd_listener_tcpip()
3874 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), in channel_setup_fwd_listener_tcpip()
3881 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); in channel_setup_fwd_listener_tcpip()
3882 if (sock == -1) { in channel_setup_fwd_listener_tcpip()
3890 if (ai->ai_family == AF_INET6) in channel_setup_fwd_listener_tcpip()
3897 if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in channel_setup_fwd_listener_tcpip()
3902 if (!ai->ai_next) in channel_setup_fwd_listener_tcpip()
3913 if (listen(sock, SSH_LISTEN_BACKLOG) == -1) { in channel_setup_fwd_listener_tcpip()
3921 * fwd->listen_port == 0 requests a dynamically allocated port - in channel_setup_fwd_listener_tcpip()
3925 fwd->listen_port == 0 && in channel_setup_fwd_listener_tcpip()
3934 c = channel_new(ssh, "port-listener", type, sock, sock, -1, in channel_setup_fwd_listener_tcpip()
3937 c->path = xstrdup(host); in channel_setup_fwd_listener_tcpip()
3938 c->host_port = fwd->connect_port; in channel_setup_fwd_listener_tcpip()
3939 c->listening_addr = addr == NULL ? NULL : xstrdup(addr); in channel_setup_fwd_listener_tcpip()
3940 if (fwd->listen_port == 0 && allocated_listen_port != NULL && in channel_setup_fwd_listener_tcpip()
3941 !(ssh->compat & SSH_BUG_DYNAMIC_RPORT)) in channel_setup_fwd_listener_tcpip()
3942 c->listening_port = *allocated_listen_port; in channel_setup_fwd_listener_tcpip()
3944 c->listening_port = fwd->listen_port; in channel_setup_fwd_listener_tcpip()
3948 error_f("cannot listen to port: %d", fwd->listen_port); in channel_setup_fwd_listener_tcpip()
3965 if (fwd->connect_path != NULL) { in channel_setup_fwd_listener_streamlocal()
3966 if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) { in channel_setup_fwd_listener_streamlocal()
3968 fwd->connect_path); in channel_setup_fwd_listener_streamlocal()
3971 path = fwd->connect_path; in channel_setup_fwd_listener_streamlocal()
3974 if (fwd->connect_host == NULL) { in channel_setup_fwd_listener_streamlocal()
3978 if (strlen(fwd->connect_host) >= NI_MAXHOST) { in channel_setup_fwd_listener_streamlocal()
3982 path = fwd->connect_host; in channel_setup_fwd_listener_streamlocal()
3983 port = fwd->connect_port; in channel_setup_fwd_listener_streamlocal()
3987 path = fwd->listen_path; in channel_setup_fwd_listener_streamlocal()
3995 if (fwd->listen_path == NULL) { in channel_setup_fwd_listener_streamlocal()
3999 if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) { in channel_setup_fwd_listener_streamlocal()
4000 error("Local listening path too long: %s", fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4004 debug3_f("type %d path %s", type, fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4007 omask = umask(fwd_opts->streamlocal_bind_mask); in channel_setup_fwd_listener_streamlocal()
4008 sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG, in channel_setup_fwd_listener_streamlocal()
4009 fwd_opts->streamlocal_bind_unlink); in channel_setup_fwd_listener_streamlocal()
4014 debug("Local forwarding listening on path %s.", fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4017 c = channel_new(ssh, "unix-listener", type, sock, sock, -1, in channel_setup_fwd_listener_streamlocal()
4020 c->path = xstrdup(path); in channel_setup_fwd_listener_streamlocal()
4021 c->host_port = port; in channel_setup_fwd_listener_streamlocal()
4022 c->listening_port = PORT_STREAMLOCAL; in channel_setup_fwd_listener_streamlocal()
4023 c->listening_addr = xstrdup(fwd->listen_path); in channel_setup_fwd_listener_streamlocal()
4034 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_rport_listener_tcpip()
4035 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_rport_listener_tcpip()
4036 if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER) in channel_cancel_rport_listener_tcpip()
4038 if (strcmp(c->path, host) == 0 && c->listening_port == port) { in channel_cancel_rport_listener_tcpip()
4054 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_rport_listener_streamlocal()
4055 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_rport_listener_streamlocal()
4056 if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER) in channel_cancel_rport_listener_streamlocal()
4058 if (c->path == NULL) in channel_cancel_rport_listener_streamlocal()
4060 if (strcmp(c->path, path) == 0) { in channel_cancel_rport_listener_streamlocal()
4073 if (fwd->listen_path != NULL) { in channel_cancel_rport_listener()
4075 fwd->listen_path); in channel_cancel_rport_listener()
4078 fwd->listen_host, fwd->listen_port); in channel_cancel_rport_listener()
4091 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_lport_listener_tcpip()
4092 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_lport_listener_tcpip()
4093 if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER) in channel_cancel_lport_listener_tcpip()
4095 if (c->listening_port != lport) in channel_cancel_lport_listener_tcpip()
4099 if (c->host_port == 0) in channel_cancel_lport_listener_tcpip()
4102 if (c->host_port != cport) in channel_cancel_lport_listener_tcpip()
4105 if ((c->listening_addr == NULL && addr != NULL) || in channel_cancel_lport_listener_tcpip()
4106 (c->listening_addr != NULL && addr == NULL)) in channel_cancel_lport_listener_tcpip()
4108 if (addr == NULL || strcmp(c->listening_addr, addr) == 0) { in channel_cancel_lport_listener_tcpip()
4129 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { in channel_cancel_lport_listener_streamlocal()
4130 Channel *c = ssh->chanctxt->channels[i]; in channel_cancel_lport_listener_streamlocal()
4131 if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER) in channel_cancel_lport_listener_streamlocal()
4133 if (c->listening_addr == NULL) in channel_cancel_lport_listener_streamlocal()
4135 if (strcmp(c->listening_addr, path) == 0) { in channel_cancel_lport_listener_streamlocal()
4149 if (fwd->listen_path != NULL) { in channel_cancel_lport_listener()
4151 fwd->listen_path); in channel_cancel_lport_listener()
4154 fwd->listen_host, fwd->listen_port, cport, fwd_opts); in channel_cancel_lport_listener()
4163 if (fwd->listen_path != NULL) { in channel_setup_local_fwd_listener()
4180 if (fwd->listen_path != NULL) in remote_open_match()
4183 if (fwd->listen_host == NULL || allowed_open->listen_host == NULL) in remote_open_match()
4186 if (allowed_open->listen_port != FWD_PERMIT_ANY_PORT && in remote_open_match()
4187 allowed_open->listen_port != fwd->listen_port) in remote_open_match()
4190 /* Match hostnames case-insensitively */ in remote_open_match()
4191 lhost = xstrdup(fwd->listen_host); in remote_open_match()
4193 ret = match_pattern(lhost, allowed_open->listen_host); in remote_open_match()
4203 struct ssh_channels *sc = ssh->chanctxt; in check_rfwd_permission()
4204 struct permission_set *pset = &sc->remote_perms; in check_rfwd_permission()
4210 permit = pset->all_permitted; in check_rfwd_permission()
4212 for (i = 0; i < pset->num_permitted_user; i++) { in check_rfwd_permission()
4213 perm = &pset->permitted_user[i]; in check_rfwd_permission()
4221 if (pset->num_permitted_admin > 0) { in check_rfwd_permission()
4223 for (i = 0; i < pset->num_permitted_admin; i++) { in check_rfwd_permission()
4224 perm = &pset->permitted_admin[i]; in check_rfwd_permission()
4242 if (fwd->listen_path != NULL) in channel_setup_remote_fwd_listener()
4248 fwd->listen_path); in channel_setup_remote_fwd_listener()
4249 else if(fwd->listen_host != NULL) in channel_setup_remote_fwd_listener()
4254 fwd->listen_host, fwd->listen_port ); in channel_setup_remote_fwd_listener()
4261 if (fwd->listen_path != NULL) { in channel_setup_remote_fwd_listener()
4295 int r, success = 0, idx = -1; in channel_request_remote_forwarding()
4300 if (fwd->listen_path != NULL) { in channel_request_remote_forwarding()
4303 "streamlocal-forward@openssh.com")) != 0 || in channel_request_remote_forwarding()
4305 (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 || in channel_request_remote_forwarding()
4311 (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 || in channel_request_remote_forwarding()
4314 channel_rfwd_bind_host(fwd->listen_host))) != 0 || in channel_request_remote_forwarding()
4315 (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 || in channel_request_remote_forwarding()
4318 fatal_fr(r, "request tcpip-forward"); in channel_request_remote_forwarding()
4326 if (fwd->connect_path != NULL) { in channel_request_remote_forwarding()
4327 host_to_connect = fwd->connect_path; in channel_request_remote_forwarding()
4330 host_to_connect = fwd->connect_host; in channel_request_remote_forwarding()
4331 port_to_connect = fwd->connect_port; in channel_request_remote_forwarding()
4333 if (fwd->listen_path != NULL) { in channel_request_remote_forwarding()
4334 listen_path = fwd->listen_path; in channel_request_remote_forwarding()
4337 listen_host = fwd->listen_host; in channel_request_remote_forwarding()
4338 listen_port = fwd->listen_port; in channel_request_remote_forwarding()
4351 if (allowed_open->host_to_connect == NULL) in open_match()
4353 if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT && in open_match()
4354 allowed_open->port_to_connect != requestedport) in open_match()
4356 if (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 && in open_match()
4357 strcmp(allowed_open->host_to_connect, requestedhost) != 0) in open_match()
4365 * need to translate between the configured-host (listen_host)
4374 if (allowed_open->host_to_connect == NULL) in open_listen_match_tcpip()
4376 if (allowed_open->listen_port != requestedport) in open_listen_match_tcpip()
4378 if (!translate && allowed_open->listen_host == NULL && in open_listen_match_tcpip()
4382 channel_rfwd_bind_host(allowed_open->listen_host) : in open_listen_match_tcpip()
4383 allowed_open->listen_host; in open_listen_match_tcpip()
4394 if (allowed_open->host_to_connect == NULL) in open_listen_match_streamlocal()
4396 if (allowed_open->listen_port != PORT_STREAMLOCAL) in open_listen_match_streamlocal()
4398 if (allowed_open->listen_path == NULL || in open_listen_match_streamlocal()
4399 strcmp(allowed_open->listen_path, requestedpath) != 0) in open_listen_match_streamlocal()
4412 struct ssh_channels *sc = ssh->chanctxt; in channel_request_rforward_cancel_tcpip()
4413 struct permission_set *pset = &sc->local_perms; in channel_request_rforward_cancel_tcpip()
4418 for (i = 0; i < pset->num_permitted_user; i++) { in channel_request_rforward_cancel_tcpip()
4419 perm = &pset->permitted_user[i]; in channel_request_rforward_cancel_tcpip()
4426 return -1; in channel_request_rforward_cancel_tcpip()
4429 (r = sshpkt_put_cstring(ssh, "cancel-tcpip-forward")) != 0 || in channel_request_rforward_cancel_tcpip()
4448 struct ssh_channels *sc = ssh->chanctxt; in channel_request_rforward_cancel_streamlocal()
4449 struct permission_set *pset = &sc->local_perms; in channel_request_rforward_cancel_streamlocal()
4454 for (i = 0; i < pset->num_permitted_user; i++) { in channel_request_rforward_cancel_streamlocal()
4455 perm = &pset->permitted_user[i]; in channel_request_rforward_cancel_streamlocal()
4462 return -1; in channel_request_rforward_cancel_streamlocal()
4466 "cancel-streamlocal-forward@openssh.com")) != 0 || in channel_request_rforward_cancel_streamlocal()
4483 if (fwd->listen_path != NULL) { in channel_request_rforward_cancel()
4485 fwd->listen_path); in channel_request_rforward_cancel()
4488 fwd->listen_host, in channel_request_rforward_cancel()
4489 fwd->listen_port ? fwd->listen_port : fwd->allocated_port); in channel_request_rforward_cancel()
4503 if (pset->num_permitted_user == 0) in channel_permit_all()
4504 pset->all_permitted = 1; in channel_permit_all()
4526 pset->all_permitted = 0; in channel_add_permission()
4562 struct permission_set *pset = &ssh->chanctxt->local_perms; in channel_update_permission()
4564 if (idx < 0 || (u_int)idx >= pset->num_permitted_user) { in channel_update_permission()
4566 idx, pset->num_permitted_user); in channel_update_permission()
4572 pset->permitted_user[idx].host_to_connect, in channel_update_permission()
4573 pset->permitted_user[idx].port_to_connect); in channel_update_permission()
4575 fwd_perm_clear(&pset->permitted_user[idx]); in channel_update_permission()
4577 pset->permitted_user[idx].listen_port = in channel_update_permission()
4578 (ssh->compat & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport; in channel_update_permission()
4582 /* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */
4592 return -1; in permitopen_port()
4595 /* Try to start non-blocking connect to next host in cctx list */
4602 char strport[MAXIMUM(NI_MAXSERV, sizeof(sunaddr->sun_path))]; in connect_next()
4604 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { in connect_next()
4605 switch (cctx->ai->ai_family) { in connect_next()
4608 sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr; in connect_next()
4610 strlcpy(strport, sunaddr->sun_path, sizeof(strport)); in connect_next()
4614 if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, in connect_next()
4625 cctx->host, ntop, strport); in connect_next()
4626 if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, in connect_next()
4627 cctx->ai->ai_protocol)) == -1) { in connect_next()
4628 if (cctx->ai->ai_next == NULL) in connect_next()
4634 if (set_nonblock(sock) == -1) in connect_next()
4636 if (connect(sock, cctx->ai->ai_addr, in connect_next()
4637 cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) { in connect_next()
4639 cctx->host, ntop, strport, strerror(errno)); in connect_next()
4643 continue; /* fail -- try next */ in connect_next()
4645 if (cctx->ai->ai_family != AF_UNIX) in connect_next()
4648 cctx->host, ntop, strport, sock); in connect_next()
4649 cctx->ai = cctx->ai->ai_next; in connect_next()
4652 return -1; in connect_next()
4658 free(cctx->host); in channel_connect_ctx_free()
4659 if (cctx->aitop) { in channel_connect_ctx_free()
4660 if (cctx->aitop->ai_family == AF_UNIX) in channel_connect_ctx_free()
4661 free(cctx->aitop); in channel_connect_ctx_free()
4663 freeaddrinfo(cctx->aitop); in channel_connect_ctx_free()
4679 int sock = -1; in connect_to_helper()
4686 if (strlen(name) > sizeof(sunaddr->sun_path)) { in connect_to_helper()
4688 return -1; in connect_to_helper()
4698 ai->ai_addr = (struct sockaddr *)(ai + 1); in connect_to_helper()
4699 ai->ai_addrlen = sizeof(*sunaddr); in connect_to_helper()
4700 ai->ai_family = AF_UNIX; in connect_to_helper()
4701 ai->ai_socktype = socktype; in connect_to_helper()
4702 ai->ai_protocol = PF_UNSPEC; in connect_to_helper()
4703 sunaddr = (struct sockaddr_un *)ai->ai_addr; in connect_to_helper()
4704 sunaddr->sun_family = AF_UNIX; in connect_to_helper()
4705 strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path)); in connect_to_helper()
4706 cctx->aitop = ai; in connect_to_helper()
4709 hints.ai_family = ssh->chanctxt->IPv4or6; in connect_to_helper()
4712 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx->aitop)) in connect_to_helper()
4720 return -1; in connect_to_helper()
4724 cctx->host = xstrdup(name); in connect_to_helper()
4725 cctx->port = port; in connect_to_helper()
4726 cctx->ai = cctx->aitop; in connect_to_helper()
4728 if ((sock = connect_next(cctx)) == -1) { in connect_to_helper()
4731 return -1; in connect_to_helper()
4749 if (sock == -1) { in connect_to()
4753 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, in connect_to()
4755 c->host_port = port; in connect_to()
4756 c->path = xstrdup(host); in connect_to()
4757 c->connect_ctx = cctx; in connect_to()
4770 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_by_listen_address()
4771 struct permission_set *pset = &sc->local_perms; in channel_connect_by_listen_address()
4775 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_by_listen_address()
4776 perm = &pset->permitted_user[i]; in channel_connect_by_listen_address()
4779 if (perm->downstream) in channel_connect_by_listen_address()
4780 return perm->downstream; in channel_connect_by_listen_address()
4781 if (perm->port_to_connect == 0) in channel_connect_by_listen_address()
4785 perm->host_to_connect, perm->port_to_connect, in channel_connect_by_listen_address()
4798 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_by_listen_path()
4799 struct permission_set *pset = &sc->local_perms; in channel_connect_by_listen_path()
4803 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_by_listen_path()
4804 perm = &pset->permitted_user[i]; in channel_connect_by_listen_path()
4807 perm->host_to_connect, perm->port_to_connect, in channel_connect_by_listen_path()
4821 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_to_port()
4822 struct permission_set *pset = &sc->local_perms; in channel_connect_to_port()
4829 permit = pset->all_permitted; in channel_connect_to_port()
4831 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_to_port()
4832 perm = &pset->permitted_user[i]; in channel_connect_to_port()
4840 if (pset->num_permitted_admin > 0) { in channel_connect_to_port()
4842 for (i = 0; i < pset->num_permitted_admin; i++) { in channel_connect_to_port()
4843 perm = &pset->permitted_admin[i]; in channel_connect_to_port()
4863 if (sock == -1) { in channel_connect_to_port()
4868 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, in channel_connect_to_port()
4870 c->host_port = port; in channel_connect_to_port()
4871 c->path = xstrdup(host); in channel_connect_to_port()
4872 c->connect_ctx = cctx; in channel_connect_to_port()
4882 struct ssh_channels *sc = ssh->chanctxt; in channel_connect_to_path()
4883 struct permission_set *pset = &sc->local_perms; in channel_connect_to_path()
4887 permit = pset->all_permitted; in channel_connect_to_path()
4889 for (i = 0; i < pset->num_permitted_user; i++) { in channel_connect_to_path()
4890 perm = &pset->permitted_user[i]; in channel_connect_to_path()
4898 if (pset->num_permitted_admin > 0) { in channel_connect_to_path()
4900 for (i = 0; i < pset->num_permitted_admin; i++) { in channel_connect_to_path()
4901 perm = &pset->permitted_admin[i]; in channel_connect_to_path()
4920 struct ssh_channels *sc = ssh->chanctxt; in channel_send_window_changes()
4925 for (i = 0; i < sc->channels_alloc; i++) { in channel_send_window_changes()
4926 if (sc->channels[i] == NULL || !sc->channels[i]->client_tty || in channel_send_window_changes()
4927 sc->channels[i]->type != SSH_CHANNEL_OPEN) in channel_send_window_changes()
4929 if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) == -1) in channel_send_window_changes()
4931 channel_request_start(ssh, i, "window-change", 0); in channel_send_window_changes()
4937 fatal_fr(r, "channel %u; send window-change", i); in channel_send_window_changes()
4948 c = channel_new(ssh, ctype, SSH_CHANNEL_RDYNAMIC_OPEN, -1, -1, -1, in rdynamic_connect_prepare()
4950 c->host_port = 0; in rdynamic_connect_prepare()
4951 c->path = NULL; in rdynamic_connect_prepare()
4958 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || in rdynamic_connect_prepare()
4959 (r = sshpkt_put_u32(ssh, c->self)) != 0 || in rdynamic_connect_prepare()
4960 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 || in rdynamic_connect_prepare()
4961 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) in rdynamic_connect_prepare()
4962 fatal_fr(r, "channel %i; confirm", c->self); in rdynamic_connect_prepare()
4970 struct ssh_channels *sc = ssh->chanctxt; in rdynamic_connect_finish()
4971 struct permission_set *pset = &sc->local_perms; in rdynamic_connect_finish()
4977 if (pset->num_permitted_admin > 0) { in rdynamic_connect_finish()
4979 for (i = 0; i < pset->num_permitted_admin; i++) { in rdynamic_connect_finish()
4980 perm = &pset->permitted_admin[i]; in rdynamic_connect_finish()
4981 if (open_match(perm, c->path, c->host_port)) { in rdynamic_connect_finish()
4989 return -1; in rdynamic_connect_finish()
4993 sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL, in rdynamic_connect_finish()
4995 if (sock == -1) in rdynamic_connect_finish()
4999 c->type = SSH_CHANNEL_RDYNAMIC_FINISH; in rdynamic_connect_finish()
5000 c->connect_ctx = cctx; in rdynamic_connect_finish()
5001 channel_register_fds(ssh, c, sock, sock, -1, 0, 1, 0); in rdynamic_connect_finish()
5006 /* -- X11 forwarding */
5011 * stored in display_numberp , or -1 if an error occurs.
5026 return -1; in x11_create_display_inet()
5033 hints.ai_family = ssh->chanctxt->IPv4or6; in x11_create_display_inet()
5040 return -1; in x11_create_display_inet()
5042 for (ai = aitop; ai; ai = ai->ai_next) { in x11_create_display_inet()
5043 if (ai->ai_family != AF_INET && in x11_create_display_inet()
5044 ai->ai_family != AF_INET6) in x11_create_display_inet()
5046 sock = socket(ai->ai_family, ai->ai_socktype, in x11_create_display_inet()
5047 ai->ai_protocol); in x11_create_display_inet()
5048 if (sock == -1) { in x11_create_display_inet()
5056 return -1; in x11_create_display_inet()
5059 ai->ai_family); in x11_create_display_inet()
5063 if (ai->ai_family == AF_INET6) in x11_create_display_inet()
5067 if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in x11_create_display_inet()
5085 error("Failed to allocate internet-domain X11 display socket."); in x11_create_display_inet()
5086 return -1; in x11_create_display_inet()
5091 if (listen(sock, SSH_LISTEN_BACKLOG) == -1) { in x11_create_display_inet()
5094 return -1; in x11_create_display_inet()
5102 nc = channel_new(ssh, "x11-listener", in x11_create_display_inet()
5103 SSH_CHANNEL_X11_LISTENER, sock, sock, -1, in x11_create_display_inet()
5106 nc->single_connection = single_connection; in x11_create_display_inet()
5107 (*chanids)[n] = nc->self; in x11_create_display_inet()
5109 (*chanids)[n] = -1; in x11_create_display_inet()
5123 if (sock == -1) { in connect_local_xsocket_path()
5125 return -1; in connect_local_xsocket_path()
5134 return -1; in connect_local_xsocket_path()
5186 return -1; in x11_connect_display()
5204 return -1; in x11_connect_display()
5222 return -1; in x11_connect_display()
5227 return -1; in x11_connect_display()
5240 return -1; in x11_connect_display()
5250 return -1; in x11_connect_display()
5255 hints.ai_family = ssh->chanctxt->IPv4or6; in x11_connect_display()
5261 return -1; in x11_connect_display()
5263 for (ai = aitop; ai; ai = ai->ai_next) { in x11_connect_display()
5265 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); in x11_connect_display()
5266 if (sock == -1) { in x11_connect_display()
5271 if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { in x11_connect_display()
5284 return -1; in x11_connect_display()
5299 struct ssh_channels *sc = ssh->chanctxt; in x11_request_forwarding_with_spoofing()
5306 if (sc->x11_saved_display == NULL) in x11_request_forwarding_with_spoofing()
5307 sc->x11_saved_display = xstrdup(disp); in x11_request_forwarding_with_spoofing()
5308 else if (strcmp(disp, sc->x11_saved_display) != 0) { in x11_request_forwarding_with_spoofing()
5322 if (sc->x11_saved_proto == NULL) { in x11_request_forwarding_with_spoofing()
5324 sc->x11_saved_proto = xstrdup(proto); in x11_request_forwarding_with_spoofing()
5327 sc->x11_saved_data = xmalloc(data_len); in x11_request_forwarding_with_spoofing()
5333 sc->x11_saved_data[i] = value; in x11_request_forwarding_with_spoofing()
5335 sc->x11_saved_data_len = data_len; in x11_request_forwarding_with_spoofing()
5338 sc->x11_fake_data = xmalloc(data_len); in x11_request_forwarding_with_spoofing()
5339 arc4random_buf(sc->x11_fake_data, data_len); in x11_request_forwarding_with_spoofing()
5340 sc->x11_fake_data_len = data_len; in x11_request_forwarding_with_spoofing()
5344 new_data = tohex(sc->x11_fake_data, data_len); in x11_request_forwarding_with_spoofing()
5347 channel_request_start(ssh, client_session_id, "x11-req", want_reply); in x11_request_forwarding_with_spoofing()
5354 fatal_fr(r, "send x11-req"); in x11_request_forwarding_with_spoofing()