diff options
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 84 |
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) | |||
436 | static void | 436 | static void |
437 | channel_close_fds(struct ssh *ssh, Channel *c) | 437 | channel_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 | ||
445 | static void | 450 | static 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 | ||
1671 | static void | ||
1672 | channel_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 | |||
1684 | void | 1671 | void |
1685 | channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time) | 1672 | channel_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 * | |||
3672 | channel_rfwd_bind_host(const char *listen_host) | 3660 | channel_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)); |