summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-04-30 23:13:25 +0000
committerDamien Miller <djm@mindrot.org>2017-05-01 09:42:37 +1000
commit97f4d3083b036ce3e68d6346a6140a22123d5864 (patch)
tree301c95453934721eca9855cd01b1d0da089e3246 /channels.c
parent99f95ba82673d33215dce17bfa1512b57f54ec09 (diff)
upstream commit
remove compat20/compat13/compat15 variables ok markus@ Upstream-ID: 43802c035ceb3fef6c50c400e4ecabf12354691c
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c523
1 files changed, 130 insertions, 393 deletions
diff --git a/channels.c b/channels.c
index d030fcdd9..5a7e56ed0 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker Exp $ */ 1/* $OpenBSD: channels.c,v 1.358 2017/04/30 23:13:25 djm 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
@@ -571,14 +571,6 @@ channel_not_very_much_buffered_data(void)
571 for (i = 0; i < channels_alloc; i++) { 571 for (i = 0; i < channels_alloc; i++) {
572 c = channels[i]; 572 c = channels[i];
573 if (c != NULL && c->type == SSH_CHANNEL_OPEN) { 573 if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
574#if 0
575 if (!compat20 &&
576 buffer_len(&c->input) > packet_get_maxsize()) {
577 debug2("channel %d: big input buffer %d",
578 c->self, buffer_len(&c->input));
579 return 0;
580 }
581#endif
582 if (buffer_len(&c->output) > packet_get_maxsize()) { 574 if (buffer_len(&c->output) > packet_get_maxsize()) {
583 debug2("channel %d: big output buffer %u > %u", 575 debug2("channel %d: big output buffer %u > %u",
584 c->self, buffer_len(&c->output), 576 c->self, buffer_len(&c->output),
@@ -616,8 +608,6 @@ channel_still_open(void)
616 case SSH_CHANNEL_RUNIX_LISTENER: 608 case SSH_CHANNEL_RUNIX_LISTENER:
617 continue; 609 continue;
618 case SSH_CHANNEL_LARVAL: 610 case SSH_CHANNEL_LARVAL:
619 if (!compat20)
620 fatal("cannot happen: SSH_CHANNEL_LARVAL");
621 continue; 611 continue;
622 case SSH_CHANNEL_OPENING: 612 case SSH_CHANNEL_OPENING:
623 case SSH_CHANNEL_OPEN: 613 case SSH_CHANNEL_OPEN:
@@ -627,11 +617,9 @@ channel_still_open(void)
627 return 1; 617 return 1;
628 case SSH_CHANNEL_INPUT_DRAINING: 618 case SSH_CHANNEL_INPUT_DRAINING:
629 case SSH_CHANNEL_OUTPUT_DRAINING: 619 case SSH_CHANNEL_OUTPUT_DRAINING:
630 if (!compat13) 620 fatal("cannot happen: OUT_DRAIN");
631 fatal("cannot happen: OUT_DRAIN");
632 return 1;
633 default: 621 default:
634 fatal("channel_still_open: bad channel type %d", c->type); 622 fatal("%s: bad channel type %d", __func__, c->type);
635 /* NOTREACHED */ 623 /* NOTREACHED */
636 } 624 }
637 } 625 }
@@ -672,11 +660,9 @@ channel_find_open(void)
672 return i; 660 return i;
673 case SSH_CHANNEL_INPUT_DRAINING: 661 case SSH_CHANNEL_INPUT_DRAINING:
674 case SSH_CHANNEL_OUTPUT_DRAINING: 662 case SSH_CHANNEL_OUTPUT_DRAINING:
675 if (!compat13) 663 fatal("cannot happen: OUT_DRAIN");
676 fatal("cannot happen: OUT_DRAIN");
677 return i;
678 default: 664 default:
679 fatal("channel_find_open: bad channel type %d", c->type); 665 fatal("%s: bad channel type %d", __func__, c->type);
680 /* NOTREACHED */ 666 /* NOTREACHED */
681 } 667 }
682 } 668 }
@@ -896,22 +882,11 @@ channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset)
896} 882}
897 883
898static void 884static void
899channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)
900{
901 if (buffer_len(&c->input) < packet_get_maxsize())
902 FD_SET(c->sock, readset);
903 if (buffer_len(&c->output) > 0)
904 FD_SET(c->sock, writeset);
905}
906
907static void
908channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) 885channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
909{ 886{
910 u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
911
912 if (c->istate == CHAN_INPUT_OPEN && 887 if (c->istate == CHAN_INPUT_OPEN &&
913 limit > 0 && 888 c->remote_window > 0 &&
914 buffer_len(&c->input) < limit && 889 buffer_len(&c->input) < c->remote_window &&
915 buffer_check_alloc(&c->input, CHAN_RBUF)) 890 buffer_check_alloc(&c->input, CHAN_RBUF))
916 FD_SET(c->rfd, readset); 891 FD_SET(c->rfd, readset);
917 if (c->ostate == CHAN_OUTPUT_OPEN || 892 if (c->ostate == CHAN_OUTPUT_OPEN ||
@@ -927,8 +902,8 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
927 } 902 }
928 } 903 }
929 /** XXX check close conditions, too */ 904 /** XXX check close conditions, too */
930 if (compat20 && c->efd != -1 && 905 if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED &&
931 !(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) { 906 c->ostate == CHAN_OUTPUT_CLOSED)) {
932 if (c->extended_usage == CHAN_EXTENDED_WRITE && 907 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
933 buffer_len(&c->extended) > 0) 908 buffer_len(&c->extended) > 0)
934 FD_SET(c->efd, writeset); 909 FD_SET(c->efd, writeset);
@@ -941,29 +916,6 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
941 /* XXX: What about efd? races? */ 916 /* XXX: What about efd? races? */
942} 917}
943 918
944/* ARGSUSED */
945static void
946channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)
947{
948 if (buffer_len(&c->input) == 0) {
949 packet_start(SSH_MSG_CHANNEL_CLOSE);
950 packet_put_int(c->remote_id);
951 packet_send();
952 c->type = SSH_CHANNEL_CLOSED;
953 debug2("channel %d: closing after input drain.", c->self);
954 }
955}
956
957/* ARGSUSED */
958static void
959channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
960{
961 if (buffer_len(&c->output) == 0)
962 chan_mark_dead(c);
963 else
964 FD_SET(c->sock, writeset);
965}
966
967/* 919/*
968 * This is a special state for X11 authentication spoofing. An opened X11 920 * This is a special state for X11 authentication spoofing. An opened X11
969 * connection (when authentication spoofing is being done) remains in this 921 * connection (when authentication spoofing is being done) remains in this
@@ -1039,32 +991,6 @@ x11_open_helper(Buffer *b)
1039} 991}
1040 992
1041static void 993static void
1042channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)
1043{
1044 int ret = x11_open_helper(&c->output);
1045
1046 if (ret == 1) {
1047 /* Start normal processing for the channel. */
1048 c->type = SSH_CHANNEL_OPEN;
1049 channel_pre_open_13(c, readset, writeset);
1050 } else if (ret == -1) {
1051 /*
1052 * We have received an X11 connection that has bad
1053 * authentication information.
1054 */
1055 logit("X11 connection rejected because of wrong authentication.");
1056 buffer_clear(&c->input);
1057 buffer_clear(&c->output);
1058 channel_close_fd(&c->sock);
1059 c->sock = -1;
1060 c->type = SSH_CHANNEL_CLOSED;
1061 packet_start(SSH_MSG_CHANNEL_CLOSE);
1062 packet_put_int(c->remote_id);
1063 packet_send();
1064 }
1065}
1066
1067static void
1068channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset) 994channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
1069{ 995{
1070 int ret = x11_open_helper(&c->output); 996 int ret = x11_open_helper(&c->output);
@@ -1081,11 +1007,7 @@ channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
1081 buffer_clear(&c->input); 1007 buffer_clear(&c->input);
1082 chan_ibuf_empty(c); 1008 chan_ibuf_empty(c);
1083 buffer_clear(&c->output); 1009 buffer_clear(&c->output);
1084 /* for proto v1, the peer will send an IEOF */ 1010 chan_write_failed(c);
1085 if (compat20)
1086 chan_write_failed(c);
1087 else
1088 c->type = SSH_CHANNEL_OPEN;
1089 debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); 1011 debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
1090 } 1012 }
1091} 1013}
@@ -1449,28 +1371,19 @@ channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
1449 nc = channel_new("accepted x11 socket", 1371 nc = channel_new("accepted x11 socket",
1450 SSH_CHANNEL_OPENING, newsock, newsock, -1, 1372 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1451 c->local_window_max, c->local_maxpacket, 0, buf, 1); 1373 c->local_window_max, c->local_maxpacket, 0, buf, 1);
1452 if (compat20) { 1374 packet_start(SSH2_MSG_CHANNEL_OPEN);
1453 packet_start(SSH2_MSG_CHANNEL_OPEN); 1375 packet_put_cstring("x11");
1454 packet_put_cstring("x11"); 1376 packet_put_int(nc->self);
1455 packet_put_int(nc->self); 1377 packet_put_int(nc->local_window_max);
1456 packet_put_int(nc->local_window_max); 1378 packet_put_int(nc->local_maxpacket);
1457 packet_put_int(nc->local_maxpacket); 1379 /* originator ipaddr and port */
1458 /* originator ipaddr and port */ 1380 packet_put_cstring(remote_ipaddr);
1459 packet_put_cstring(remote_ipaddr); 1381 if (datafellows & SSH_BUG_X11FWD) {
1460 if (datafellows & SSH_BUG_X11FWD) { 1382 debug2("ssh2 x11 bug compat mode");
1461 debug2("ssh2 x11 bug compat mode");
1462 } else {
1463 packet_put_int(remote_port);
1464 }
1465 packet_send();
1466 } else { 1383 } else {
1467 packet_start(SSH_SMSG_X11_OPEN); 1384 packet_put_int(remote_port);
1468 packet_put_int(nc->self);
1469 if (packet_get_protocol_flags() &
1470 SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
1471 packet_put_cstring(buf);
1472 packet_send();
1473 } 1385 }
1386 packet_send();
1474 free(remote_ipaddr); 1387 free(remote_ipaddr);
1475 } 1388 }
1476} 1389}
@@ -1500,46 +1413,35 @@ port_open_helper(Channel *c, char *rtype)
1500 free(c->remote_name); 1413 free(c->remote_name);
1501 c->remote_name = xstrdup(buf); 1414 c->remote_name = xstrdup(buf);
1502 1415
1503 if (compat20) { 1416 packet_start(SSH2_MSG_CHANNEL_OPEN);
1504 packet_start(SSH2_MSG_CHANNEL_OPEN); 1417 packet_put_cstring(rtype);
1505 packet_put_cstring(rtype); 1418 packet_put_int(c->self);
1506 packet_put_int(c->self); 1419 packet_put_int(c->local_window_max);
1507 packet_put_int(c->local_window_max); 1420 packet_put_int(c->local_maxpacket);
1508 packet_put_int(c->local_maxpacket); 1421 if (strcmp(rtype, "direct-tcpip") == 0) {
1509 if (strcmp(rtype, "direct-tcpip") == 0) { 1422 /* target host, port */
1510 /* target host, port */
1511 packet_put_cstring(c->path);
1512 packet_put_int(c->host_port);
1513 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
1514 /* target path */
1515 packet_put_cstring(c->path);
1516 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1517 /* listen path */
1518 packet_put_cstring(c->path);
1519 } else {
1520 /* listen address, port */
1521 packet_put_cstring(c->path);
1522 packet_put_int(local_port);
1523 }
1524 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1525 /* reserved for future owner/mode info */
1526 packet_put_cstring("");
1527 } else {
1528 /* originator host and port */
1529 packet_put_cstring(remote_ipaddr);
1530 packet_put_int((u_int)remote_port);
1531 }
1532 packet_send();
1533 } else {
1534 packet_start(SSH_MSG_PORT_OPEN);
1535 packet_put_int(c->self);
1536 packet_put_cstring(c->path); 1423 packet_put_cstring(c->path);
1537 packet_put_int(c->host_port); 1424 packet_put_int(c->host_port);
1538 if (packet_get_protocol_flags() & 1425 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
1539 SSH_PROTOFLAG_HOST_IN_FWD_OPEN) 1426 /* target path */
1540 packet_put_cstring(c->remote_name); 1427 packet_put_cstring(c->path);
1541 packet_send(); 1428 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1429 /* listen path */
1430 packet_put_cstring(c->path);
1431 } else {
1432 /* listen address, port */
1433 packet_put_cstring(c->path);
1434 packet_put_int(local_port);
1435 }
1436 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1437 /* reserved for future owner/mode info */
1438 packet_put_cstring("");
1439 } else {
1440 /* originator host and port */
1441 packet_put_cstring(remote_ipaddr);
1442 packet_put_int((u_int)remote_port);
1542 } 1443 }
1444 packet_send();
1543 free(remote_ipaddr); 1445 free(remote_ipaddr);
1544 free(local_ipaddr); 1446 free(local_ipaddr);
1545} 1447}
@@ -1649,16 +1551,11 @@ channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
1649 SSH_CHANNEL_OPENING, newsock, newsock, -1, 1551 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1650 c->local_window_max, c->local_maxpacket, 1552 c->local_window_max, c->local_maxpacket,
1651 0, "accepted auth socket", 1); 1553 0, "accepted auth socket", 1);
1652 if (compat20) { 1554 packet_start(SSH2_MSG_CHANNEL_OPEN);
1653 packet_start(SSH2_MSG_CHANNEL_OPEN); 1555 packet_put_cstring("auth-agent@openssh.com");
1654 packet_put_cstring("auth-agent@openssh.com"); 1556 packet_put_int(nc->self);
1655 packet_put_int(nc->self); 1557 packet_put_int(c->local_window_max);
1656 packet_put_int(c->local_window_max); 1558 packet_put_int(c->local_maxpacket);
1657 packet_put_int(c->local_maxpacket);
1658 } else {
1659 packet_start(SSH_SMSG_AGENT_OPEN);
1660 packet_put_int(nc->self);
1661 }
1662 packet_send(); 1559 packet_send();
1663 } 1560 }
1664} 1561}
@@ -1680,17 +1577,11 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1680 c->self, c->connect_ctx.host, c->connect_ctx.port); 1577 c->self, c->connect_ctx.host, c->connect_ctx.port);
1681 channel_connect_ctx_free(&c->connect_ctx); 1578 channel_connect_ctx_free(&c->connect_ctx);
1682 c->type = SSH_CHANNEL_OPEN; 1579 c->type = SSH_CHANNEL_OPEN;
1683 if (compat20) { 1580 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1684 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 1581 packet_put_int(c->remote_id);
1685 packet_put_int(c->remote_id); 1582 packet_put_int(c->self);
1686 packet_put_int(c->self); 1583 packet_put_int(c->local_window);
1687 packet_put_int(c->local_window); 1584 packet_put_int(c->local_maxpacket);
1688 packet_put_int(c->local_maxpacket);
1689 } else {
1690 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1691 packet_put_int(c->remote_id);
1692 packet_put_int(c->self);
1693 }
1694 } else { 1585 } else {
1695 debug("channel %d: connection failed: %s", 1586 debug("channel %d: connection failed: %s",
1696 c->self, strerror(err)); 1587 c->self, strerror(err));
@@ -1705,17 +1596,12 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1705 error("connect_to %.100s port %d: failed.", 1596 error("connect_to %.100s port %d: failed.",
1706 c->connect_ctx.host, c->connect_ctx.port); 1597 c->connect_ctx.host, c->connect_ctx.port);
1707 channel_connect_ctx_free(&c->connect_ctx); 1598 channel_connect_ctx_free(&c->connect_ctx);
1708 if (compat20) { 1599 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1709 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 1600 packet_put_int(c->remote_id);
1710 packet_put_int(c->remote_id); 1601 packet_put_int(SSH2_OPEN_CONNECT_FAILED);
1711 packet_put_int(SSH2_OPEN_CONNECT_FAILED); 1602 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1712 if (!(datafellows & SSH_BUG_OPENFAILURE)) { 1603 packet_put_cstring(strerror(err));
1713 packet_put_cstring(strerror(err)); 1604 packet_put_cstring("");
1714 packet_put_cstring("");
1715 }
1716 } else {
1717 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1718 packet_put_int(c->remote_id);
1719 } 1605 }
1720 chan_mark_dead(c); 1606 chan_mark_dead(c);
1721 } 1607 }
@@ -1749,10 +1635,6 @@ channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
1749 debug2("channel %d: not open", c->self); 1635 debug2("channel %d: not open", c->self);
1750 chan_mark_dead(c); 1636 chan_mark_dead(c);
1751 return -1; 1637 return -1;
1752 } else if (compat13) {
1753 buffer_clear(&c->output);
1754 c->type = SSH_CHANNEL_INPUT_DRAINING;
1755 debug2("channel %d: input draining.", c->self);
1756 } else { 1638 } else {
1757 chan_read_failed(c); 1639 chan_read_failed(c);
1758 } 1640 }
@@ -1820,7 +1702,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
1820 } 1702 }
1821#ifdef _AIX 1703#ifdef _AIX
1822 /* XXX: Later AIX versions can't push as much data to tty */ 1704 /* XXX: Later AIX versions can't push as much data to tty */
1823 if (compat20 && c->wfd_isatty) 1705 if (c->wfd_isatty)
1824 dlen = MIN(dlen, 8*1024); 1706 dlen = MIN(dlen, 8*1024);
1825#endif 1707#endif
1826 1708
@@ -1833,17 +1715,13 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
1833 debug2("channel %d: not open", c->self); 1715 debug2("channel %d: not open", c->self);
1834 chan_mark_dead(c); 1716 chan_mark_dead(c);
1835 return -1; 1717 return -1;
1836 } else if (compat13) {
1837 buffer_clear(&c->output);
1838 debug2("channel %d: input draining.", c->self);
1839 c->type = SSH_CHANNEL_INPUT_DRAINING;
1840 } else { 1718 } else {
1841 chan_write_failed(c); 1719 chan_write_failed(c);
1842 } 1720 }
1843 return -1; 1721 return -1;
1844 } 1722 }
1845#ifndef BROKEN_TCGETATTR_ICANON 1723#ifndef BROKEN_TCGETATTR_ICANON
1846 if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') { 1724 if (c->isatty && dlen >= 1 && buf[0] != '\r') {
1847 if (tcgetattr(c->wfd, &tio) == 0 && 1725 if (tcgetattr(c->wfd, &tio) == 0 &&
1848 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { 1726 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
1849 /* 1727 /*
@@ -1860,7 +1738,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
1860 buffer_consume(&c->output, len); 1738 buffer_consume(&c->output, len);
1861 } 1739 }
1862 out: 1740 out:
1863 if (compat20 && olen > 0) 1741 if (olen > 0)
1864 c->local_consumed += olen - buffer_len(&c->output); 1742 c->local_consumed += olen - buffer_len(&c->output);
1865 return 1; 1743 return 1;
1866} 1744}
@@ -1944,8 +1822,6 @@ channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
1944{ 1822{
1945 channel_handle_rfd(c, readset, writeset); 1823 channel_handle_rfd(c, readset, writeset);
1946 channel_handle_wfd(c, readset, writeset); 1824 channel_handle_wfd(c, readset, writeset);
1947 if (!compat20)
1948 return;
1949 channel_handle_efd(c, readset, writeset); 1825 channel_handle_efd(c, readset, writeset);
1950 channel_check_window(c); 1826 channel_check_window(c);
1951} 1827}
@@ -1979,9 +1855,6 @@ channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
1979 u_int need; 1855 u_int need;
1980 ssize_t len; 1856 ssize_t len;
1981 1857
1982 if (!compat20)
1983 fatal("%s: entered with !compat20", __func__);
1984
1985 if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) && 1858 if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) &&
1986 (c->istate == CHAN_INPUT_OPEN || 1859 (c->istate == CHAN_INPUT_OPEN ||
1987 c->istate == CHAN_INPUT_WAIT_DRAIN)) { 1860 c->istate == CHAN_INPUT_WAIT_DRAIN)) {
@@ -2074,26 +1947,15 @@ channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
2074 nc->flags |= CHAN_LOCAL; 1947 nc->flags |= CHAN_LOCAL;
2075} 1948}
2076 1949
2077/* ARGSUSED */
2078static void 1950static void
2079channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset) 1951channel_handler_init(void)
2080{ 1952{
2081 int len; 1953 int i;
2082 1954
2083 /* Send buffered output data to the socket. */ 1955 for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
2084 if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) { 1956 channel_pre[i] = NULL;
2085 len = write(c->sock, buffer_ptr(&c->output), 1957 channel_post[i] = NULL;
2086 buffer_len(&c->output));
2087 if (len <= 0)
2088 buffer_clear(&c->output);
2089 else
2090 buffer_consume(&c->output, len);
2091 } 1958 }
2092}
2093
2094static void
2095channel_handler_init_20(void)
2096{
2097 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open; 1959 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
2098 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; 1960 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
2099 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; 1961 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
@@ -2120,64 +1982,6 @@ channel_handler_init_20(void)
2120 channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client; 1982 channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;
2121} 1983}
2122 1984
2123static void
2124channel_handler_init_13(void)
2125{
2126 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13;
2127 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13;
2128 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
2129 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
2130 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
2131 channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining;
2132 channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining;
2133 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
2134 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
2135
2136 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
2137 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
2138 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
2139 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
2140 channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13;
2141 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
2142 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
2143}
2144
2145static void
2146channel_handler_init_15(void)
2147{
2148 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
2149 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
2150 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
2151 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
2152 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
2153 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
2154 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
2155
2156 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
2157 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
2158 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
2159 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
2160 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
2161 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
2162}
2163
2164static void
2165channel_handler_init(void)
2166{
2167 int i;
2168
2169 for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
2170 channel_pre[i] = NULL;
2171 channel_post[i] = NULL;
2172 }
2173 if (compat20)
2174 channel_handler_init_20();
2175 else if (compat13)
2176 channel_handler_init_13();
2177 else
2178 channel_handler_init_15();
2179}
2180
2181/* gc dead channels */ 1985/* gc dead channels */
2182static void 1986static void
2183channel_garbage_collect(Channel *c) 1987channel_garbage_collect(Channel *c)
@@ -2312,16 +2116,9 @@ channel_output_poll(void)
2312 * We are only interested in channels that can have buffered 2116 * We are only interested in channels that can have buffered
2313 * incoming data. 2117 * incoming data.
2314 */ 2118 */
2315 if (compat13) { 2119 if (c->type != SSH_CHANNEL_OPEN)
2316 if (c->type != SSH_CHANNEL_OPEN && 2120 continue;
2317 c->type != SSH_CHANNEL_INPUT_DRAINING) 2121 if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
2318 continue;
2319 } else {
2320 if (c->type != SSH_CHANNEL_OPEN)
2321 continue;
2322 }
2323 if (compat20 &&
2324 (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
2325 /* XXX is this true? */ 2122 /* XXX is this true? */
2326 debug3("channel %d: will not send data after close", c->self); 2123 debug3("channel %d: will not send data after close", c->self);
2327 continue; 2124 continue;
@@ -2359,24 +2156,12 @@ channel_output_poll(void)
2359 * Send some data for the other side over the secure 2156 * Send some data for the other side over the secure
2360 * connection. 2157 * connection.
2361 */ 2158 */
2362 if (compat20) { 2159 if (len > c->remote_window)
2363 if (len > c->remote_window) 2160 len = c->remote_window;
2364 len = c->remote_window; 2161 if (len > c->remote_maxpacket)
2365 if (len > c->remote_maxpacket) 2162 len = c->remote_maxpacket;
2366 len = c->remote_maxpacket;
2367 } else {
2368 if (packet_is_interactive()) {
2369 if (len > 1024)
2370 len = 512;
2371 } else {
2372 /* Keep the packets at reasonable size. */
2373 if (len > packet_get_maxsize()/2)
2374 len = packet_get_maxsize()/2;
2375 }
2376 }
2377 if (len > 0) { 2163 if (len > 0) {
2378 packet_start(compat20 ? 2164 packet_start(SSH2_MSG_CHANNEL_DATA);
2379 SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
2380 packet_put_int(c->remote_id); 2165 packet_put_int(c->remote_id);
2381 packet_put_string(buffer_ptr(&c->input), len); 2166 packet_put_string(buffer_ptr(&c->input), len);
2382 packet_send(); 2167 packet_send();
@@ -2384,8 +2169,6 @@ channel_output_poll(void)
2384 c->remote_window -= len; 2169 c->remote_window -= len;
2385 } 2170 }
2386 } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { 2171 } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
2387 if (compat13)
2388 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
2389 /* 2172 /*
2390 * input-buffer is empty and read-socket shutdown: 2173 * input-buffer is empty and read-socket shutdown:
2391 * tell peer, that we will not send more data: send IEOF. 2174 * tell peer, that we will not send more data: send IEOF.
@@ -2398,8 +2181,7 @@ channel_output_poll(void)
2398 chan_ibuf_empty(c); 2181 chan_ibuf_empty(c);
2399 } 2182 }
2400 /* Send extended data, i.e. stderr */ 2183 /* Send extended data, i.e. stderr */
2401 if (compat20 && 2184 if (!(c->flags & CHAN_EOF_SENT) &&
2402 !(c->flags & CHAN_EOF_SENT) &&
2403 c->remote_window > 0 && 2185 c->remote_window > 0 &&
2404 (len = buffer_len(&c->extended)) > 0 && 2186 (len = buffer_len(&c->extended)) > 0 &&
2405 c->extended_usage == CHAN_EXTENDED_READ) { 2187 c->extended_usage == CHAN_EXTENDED_READ) {
@@ -2738,26 +2520,23 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
2738 * that window updates are sent back. Otherwise the connection might 2520 * that window updates are sent back. Otherwise the connection might
2739 * deadlock. 2521 * deadlock.
2740 */ 2522 */
2741 if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) { 2523 if (c->ostate != CHAN_OUTPUT_OPEN) {
2742 if (compat20) { 2524 c->local_window -= win_len;
2743 c->local_window -= win_len; 2525 c->local_consumed += win_len;
2744 c->local_consumed += win_len;
2745 }
2746 return 0; 2526 return 0;
2747 } 2527 }
2748 2528
2749 if (compat20) { 2529 if (win_len > c->local_maxpacket) {
2750 if (win_len > c->local_maxpacket) { 2530 logit("channel %d: rcvd big packet %d, maxpack %d",
2751 logit("channel %d: rcvd big packet %d, maxpack %d", 2531 c->self, win_len, c->local_maxpacket);
2752 c->self, win_len, c->local_maxpacket); 2532 }
2753 } 2533 if (win_len > c->local_window) {
2754 if (win_len > c->local_window) { 2534 logit("channel %d: rcvd too much data %d, win %d",
2755 logit("channel %d: rcvd too much data %d, win %d", 2535 c->self, win_len, c->local_window);
2756 c->self, win_len, c->local_window); 2536 return 0;
2757 return 0;
2758 }
2759 c->local_window -= win_len;
2760 } 2537 }
2538 c->local_window -= win_len;
2539
2761 if (c->datagram) 2540 if (c->datagram)
2762 buffer_put_string(&c->output, data, data_len); 2541 buffer_put_string(&c->output, data, data_len);
2763 else 2542 else
@@ -2942,17 +2721,15 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
2942 c->remote_id = remote_id; 2721 c->remote_id = remote_id;
2943 c->type = SSH_CHANNEL_OPEN; 2722 c->type = SSH_CHANNEL_OPEN;
2944 2723
2945 if (compat20) { 2724 c->remote_window = packet_get_int();
2946 c->remote_window = packet_get_int(); 2725 c->remote_maxpacket = packet_get_int();
2947 c->remote_maxpacket = packet_get_int(); 2726 if (c->open_confirm) {
2948 if (c->open_confirm) { 2727 debug2("callback start");
2949 debug2("callback start"); 2728 c->open_confirm(c->self, 1, c->open_confirm_ctx);
2950 c->open_confirm(c->self, 1, c->open_confirm_ctx); 2729 debug2("callback done");
2951 debug2("callback done");
2952 }
2953 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
2954 c->remote_window, c->remote_maxpacket);
2955 } 2730 }
2731 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
2732 c->remote_window, c->remote_maxpacket);
2956 packet_check_eom(); 2733 packet_check_eom();
2957 return 0; 2734 return 0;
2958} 2735}
@@ -2992,21 +2769,19 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
2992 if (c->type != SSH_CHANNEL_OPENING) 2769 if (c->type != SSH_CHANNEL_OPENING)
2993 packet_disconnect("Received open failure for " 2770 packet_disconnect("Received open failure for "
2994 "non-opening channel %d.", id); 2771 "non-opening channel %d.", id);
2995 if (compat20) { 2772 reason = packet_get_int();
2996 reason = packet_get_int(); 2773 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
2997 if (!(datafellows & SSH_BUG_OPENFAILURE)) { 2774 msg = packet_get_string(NULL);
2998 msg = packet_get_string(NULL); 2775 lang = packet_get_string(NULL);
2999 lang = packet_get_string(NULL); 2776 }
3000 } 2777 logit("channel %d: open failed: %s%s%s", id,
3001 logit("channel %d: open failed: %s%s%s", id, 2778 reason2txt(reason), msg ? ": ": "", msg ? msg : "");
3002 reason2txt(reason), msg ? ": ": "", msg ? msg : ""); 2779 free(msg);
3003 free(msg); 2780 free(lang);
3004 free(lang); 2781 if (c->open_confirm) {
3005 if (c->open_confirm) { 2782 debug2("callback start");
3006 debug2("callback start"); 2783 c->open_confirm(c->self, 0, c->open_confirm_ctx);
3007 c->open_confirm(c->self, 0, c->open_confirm_ctx); 2784 debug2("callback done");
3008 debug2("callback done");
3009 }
3010 } 2785 }
3011 packet_check_eom(); 2786 packet_check_eom();
3012 /* Schedule the channel for cleanup/deletion. */ 2787 /* Schedule the channel for cleanup/deletion. */
@@ -3022,9 +2797,6 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
3022 int id; 2797 int id;
3023 u_int adjust, tmp; 2798 u_int adjust, tmp;
3024 2799
3025 if (!compat20)
3026 return 0;
3027
3028 /* Get the channel number and verify it. */ 2800 /* Get the channel number and verify it. */
3029 id = packet_get_int(); 2801 id = packet_get_int();
3030 c = channel_lookup(id); 2802 c = channel_lookup(id);
@@ -3581,49 +3353,24 @@ channel_rfwd_bind_host(const char *listen_host)
3581int 3353int
3582channel_request_remote_forwarding(struct Forward *fwd) 3354channel_request_remote_forwarding(struct Forward *fwd)
3583{ 3355{
3584 int type, success = 0, idx = -1; 3356 int success = 0, idx = -1;
3585 3357
3586 /* Send the forward request to the remote side. */ 3358 /* Send the forward request to the remote side. */
3587 if (compat20) { 3359 packet_start(SSH2_MSG_GLOBAL_REQUEST);
3588 packet_start(SSH2_MSG_GLOBAL_REQUEST); 3360 if (fwd->listen_path != NULL) {
3589 if (fwd->listen_path != NULL) { 3361 packet_put_cstring("streamlocal-forward@openssh.com");
3590 packet_put_cstring("streamlocal-forward@openssh.com"); 3362 packet_put_char(1); /* boolean: want reply */
3591 packet_put_char(1); /* boolean: want reply */ 3363 packet_put_cstring(fwd->listen_path);
3592 packet_put_cstring(fwd->listen_path);
3593 } else {
3594 packet_put_cstring("tcpip-forward");
3595 packet_put_char(1); /* boolean: want reply */
3596 packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host));
3597 packet_put_int(fwd->listen_port);
3598 }
3599 packet_send();
3600 packet_write_wait();
3601 /* Assume that server accepts the request */
3602 success = 1;
3603 } else if (fwd->listen_path == NULL) {
3604 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
3605 packet_put_int(fwd->listen_port);
3606 packet_put_cstring(fwd->connect_host);
3607 packet_put_int(fwd->connect_port);
3608 packet_send();
3609 packet_write_wait();
3610
3611 /* Wait for response from the remote side. */
3612 type = packet_read();
3613 switch (type) {
3614 case SSH_SMSG_SUCCESS:
3615 success = 1;
3616 break;
3617 case SSH_SMSG_FAILURE:
3618 break;
3619 default:
3620 /* Unknown packet */
3621 packet_disconnect("Protocol error for port forward request:"
3622 "received packet type %d.", type);
3623 }
3624 } else { 3364 } else {
3625 logit("Warning: Server does not support remote stream local forwarding."); 3365 packet_put_cstring("tcpip-forward");
3366 packet_put_char(1); /* boolean: want reply */
3367 packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host));
3368 packet_put_int(fwd->listen_port);
3626 } 3369 }
3370 packet_send();
3371 packet_write_wait();
3372 /* Assume that server accepts the request */
3373 success = 1;
3627 if (success) { 3374 if (success) {
3628 /* Record that connection to this host/port is permitted. */ 3375 /* Record that connection to this host/port is permitted. */
3629 permitted_opens = xreallocarray(permitted_opens, 3376 permitted_opens = xreallocarray(permitted_opens,
@@ -3722,9 +3469,6 @@ channel_request_rforward_cancel_tcpip(const char *host, u_short port)
3722{ 3469{
3723 int i; 3470 int i;
3724 3471
3725 if (!compat20)
3726 return -1;
3727
3728 for (i = 0; i < num_permitted_opens; i++) { 3472 for (i = 0; i < num_permitted_opens; i++) {
3729 if (open_listen_match_tcpip(&permitted_opens[i], host, port, 0)) 3473 if (open_listen_match_tcpip(&permitted_opens[i], host, port, 0))
3730 break; 3474 break;
@@ -3761,9 +3505,6 @@ channel_request_rforward_cancel_streamlocal(const char *path)
3761{ 3505{
3762 int i; 3506 int i;
3763 3507
3764 if (!compat20)
3765 return -1;
3766
3767 for (i = 0; i < num_permitted_opens; i++) { 3508 for (i = 0; i < num_permitted_opens; i++) {
3768 if (open_listen_match_streamlocal(&permitted_opens[i], path)) 3509 if (open_listen_match_streamlocal(&permitted_opens[i], path))
3769 break; 3510 break;
@@ -4644,12 +4385,8 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
4644 new_data = tohex(x11_fake_data, data_len); 4385 new_data = tohex(x11_fake_data, data_len);
4645 4386
4646 /* Send the request packet. */ 4387 /* Send the request packet. */
4647 if (compat20) { 4388 channel_request_start(client_session_id, "x11-req", want_reply);
4648 channel_request_start(client_session_id, "x11-req", want_reply); 4389 packet_put_char(0); /* XXX bool single connection */
4649 packet_put_char(0); /* XXX bool single connection */
4650 } else {
4651 packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
4652 }
4653 packet_put_cstring(proto); 4390 packet_put_cstring(proto);
4654 packet_put_cstring(new_data); 4391 packet_put_cstring(new_data);
4655 packet_put_int(screen_number); 4392 packet_put_int(screen_number);