summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c84
1 files changed, 33 insertions, 51 deletions
diff --git a/channels.c b/channels.c
index 83442be06..bdee1f386 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.375 2017/09/24 13:45:34 djm Exp $ */ 1/* $OpenBSD: channels.c,v 1.379 2018/02/05 05:36:49 tb Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -436,10 +436,15 @@ channel_close_fd(struct ssh *ssh, int *fdp)
436static void 436static void
437channel_close_fds(struct ssh *ssh, Channel *c) 437channel_close_fds(struct ssh *ssh, Channel *c)
438{ 438{
439 int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd;
440
439 channel_close_fd(ssh, &c->sock); 441 channel_close_fd(ssh, &c->sock);
440 channel_close_fd(ssh, &c->rfd); 442 if (rfd != sock)
441 channel_close_fd(ssh, &c->wfd); 443 channel_close_fd(ssh, &c->rfd);
442 channel_close_fd(ssh, &c->efd); 444 if (wfd != sock && wfd != rfd)
445 channel_close_fd(ssh, &c->wfd);
446 if (efd != sock && efd != rfd && efd != wfd)
447 channel_close_fd(ssh, &c->efd);
443} 448}
444 449
445static void 450static void
@@ -1582,13 +1587,8 @@ channel_post_x11_listener(struct ssh *ssh, Channel *c,
1582 SSH_CHANNEL_OPENING, newsock, newsock, -1, 1587 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1583 c->local_window_max, c->local_maxpacket, 0, buf, 1); 1588 c->local_window_max, c->local_maxpacket, 0, buf, 1);
1584 open_preamble(ssh, __func__, nc, "x11"); 1589 open_preamble(ssh, __func__, nc, "x11");
1585 if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0) { 1590 if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
1586 fatal("%s: channel %i: reply %s", __func__, 1591 (r = sshpkt_put_u32(ssh, remote_port)) != 0) {
1587 c->self, ssh_err(r));
1588 }
1589 if ((datafellows & SSH_BUG_X11FWD) != 0)
1590 debug2("channel %d: ssh2 x11 bug compat mode", nc->self);
1591 else if ((r = sshpkt_put_u32(ssh, remote_port)) != 0) {
1592 fatal("%s: channel %i: reply %s", __func__, 1592 fatal("%s: channel %i: reply %s", __func__,
1593 c->self, ssh_err(r)); 1593 c->self, ssh_err(r));
1594 } 1594 }
@@ -1668,19 +1668,6 @@ port_open_helper(struct ssh *ssh, Channel *c, char *rtype)
1668 free(local_ipaddr); 1668 free(local_ipaddr);
1669} 1669}
1670 1670
1671static void
1672channel_set_reuseaddr(int fd)
1673{
1674 int on = 1;
1675
1676 /*
1677 * Set socket options.
1678 * Allow local port reuse in TIME_WAIT.
1679 */
1680 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
1681 error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
1682}
1683
1684void 1671void
1685channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time) 1672channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)
1686{ 1673{
@@ -1837,15 +1824,13 @@ channel_post_connecting(struct ssh *ssh, Channel *c,
1837 if ((r = sshpkt_start(ssh, 1824 if ((r = sshpkt_start(ssh,
1838 SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 || 1825 SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
1839 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || 1826 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1840 (r = sshpkt_put_u32(ssh, SSH2_OPEN_CONNECT_FAILED)) 1827 (r = sshpkt_put_u32(ssh,
1841 != 0) 1828 SSH2_OPEN_CONNECT_FAILED)) != 0 ||
1842 fatal("%s: channel %i: failure: %s", __func__, 1829 (r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
1843 c->self, ssh_err(r)); 1830 (r = sshpkt_put_cstring(ssh, "")) != 0) {
1844 if ((datafellows & SSH_BUG_OPENFAILURE) == 0 &&
1845 ((r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
1846 (r = sshpkt_put_cstring(ssh, "")) != 0))
1847 fatal("%s: channel %i: failure: %s", __func__, 1831 fatal("%s: channel %i: failure: %s", __func__,
1848 c->self, ssh_err(r)); 1832 c->self, ssh_err(r));
1833 }
1849 if ((r = sshpkt_send(ssh)) != 0) 1834 if ((r = sshpkt_send(ssh)) != 0)
1850 fatal("%s: channel %i: %s", __func__, c->self, 1835 fatal("%s: channel %i: %s", __func__, c->self,
1851 ssh_err(r)); 1836 ssh_err(r));
@@ -3123,13 +3108,11 @@ channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)
3123 error("%s: reason: %s", __func__, ssh_err(r)); 3108 error("%s: reason: %s", __func__, ssh_err(r));
3124 packet_disconnect("Invalid open failure message"); 3109 packet_disconnect("Invalid open failure message");
3125 } 3110 }
3126 if ((datafellows & SSH_BUG_OPENFAILURE) == 0) { 3111 /* skip language */
3127 /* skip language */ 3112 if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||
3128 if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 || 3113 (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0) {
3129 (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0) { 3114 error("%s: message/lang: %s", __func__, ssh_err(r));
3130 error("%s: message/lang: %s", __func__, ssh_err(r)); 3115 packet_disconnect("Invalid open failure message");
3131 packet_disconnect("Invalid open failure message");
3132 }
3133 } 3116 }
3134 ssh_packet_check_eom(ssh); 3117 ssh_packet_check_eom(ssh);
3135 logit("channel %d: open failed: %s%s%s", c->self, 3118 logit("channel %d: open failed: %s%s%s", c->self,
@@ -3364,11 +3347,12 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
3364 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 3347 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
3365 if (sock < 0) { 3348 if (sock < 0) {
3366 /* this is no error since kernel may not support ipv6 */ 3349 /* this is no error since kernel may not support ipv6 */
3367 verbose("socket: %.100s", strerror(errno)); 3350 verbose("socket [%s]:%s: %.100s", ntop, strport,
3351 strerror(errno));
3368 continue; 3352 continue;
3369 } 3353 }
3370 3354
3371 channel_set_reuseaddr(sock); 3355 set_reuseaddr(sock);
3372 if (ai->ai_family == AF_INET6) 3356 if (ai->ai_family == AF_INET6)
3373 sock_set_v6only(sock); 3357 sock_set_v6only(sock);
3374 3358
@@ -3382,9 +3366,11 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
3382 * already bound 3366 * already bound
3383 */ 3367 */
3384 if (!ai->ai_next) 3368 if (!ai->ai_next)
3385 error("bind: %.100s", strerror(errno)); 3369 error("bind [%s]:%s: %.100s",
3370 ntop, strport, strerror(errno));
3386 else 3371 else
3387 verbose("bind: %.100s", strerror(errno)); 3372 verbose("bind [%s]:%s: %.100s",
3373 ntop, strport, strerror(errno));
3388 3374
3389 close(sock); 3375 close(sock);
3390 continue; 3376 continue;
@@ -3392,6 +3378,8 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
3392 /* Start listening for connections on the socket. */ 3378 /* Start listening for connections on the socket. */
3393 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { 3379 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
3394 error("listen: %.100s", strerror(errno)); 3380 error("listen: %.100s", strerror(errno));
3381 error("listen [%s]:%s: %.100s", ntop, strport,
3382 strerror(errno));
3395 close(sock); 3383 close(sock);
3396 continue; 3384 continue;
3397 } 3385 }
@@ -3672,15 +3660,9 @@ static const char *
3672channel_rfwd_bind_host(const char *listen_host) 3660channel_rfwd_bind_host(const char *listen_host)
3673{ 3661{
3674 if (listen_host == NULL) { 3662 if (listen_host == NULL) {
3675 if (datafellows & SSH_BUG_RFWD_ADDR) 3663 return "localhost";
3676 return "127.0.0.1";
3677 else
3678 return "localhost";
3679 } else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) { 3664 } else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) {
3680 if (datafellows & SSH_BUG_RFWD_ADDR) 3665 return "";
3681 return "0.0.0.0";
3682 else
3683 return "";
3684 } else 3666 } else
3685 return listen_host; 3667 return listen_host;
3686} 3668}
@@ -4439,7 +4421,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
4439 if (ai->ai_family == AF_INET6) 4421 if (ai->ai_family == AF_INET6)
4440 sock_set_v6only(sock); 4422 sock_set_v6only(sock);
4441 if (x11_use_localhost) 4423 if (x11_use_localhost)
4442 channel_set_reuseaddr(sock); 4424 set_reuseaddr(sock);
4443 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 4425 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
4444 debug2("%s: bind port %d: %.100s", __func__, 4426 debug2("%s: bind port %d: %.100s", __func__,
4445 port, strerror(errno)); 4427 port, strerror(errno));