summaryrefslogtreecommitdiff
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
parent99f95ba82673d33215dce17bfa1512b57f54ec09 (diff)
upstream commit
remove compat20/compat13/compat15 variables ok markus@ Upstream-ID: 43802c035ceb3fef6c50c400e4ecabf12354691c
-rw-r--r--channels.c523
-rw-r--r--channels.h6
-rw-r--r--clientloop.c542
-rw-r--r--compat.c18
-rw-r--r--compat.h6
-rw-r--r--dispatch.c4
-rw-r--r--nchan.c266
-rw-r--r--packet.c395
-rw-r--r--packet.h3
-rw-r--r--ssh-keyscan.c3
-rw-r--r--ssh.c174
-rw-r--r--ssh_api.c3
-rw-r--r--sshconnect.c32
-rw-r--r--sshd.c8
-rw-r--r--ttymodes.c106
15 files changed, 407 insertions, 1682 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);
diff --git a/channels.h b/channels.h
index ce43236d5..77ec4f966 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.121 2017/02/01 02:59:09 dtucker Exp $ */ 1/* $OpenBSD: channels.h,v 1.122 2017/04/30 23:13:25 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -200,11 +200,11 @@ struct Channel {
200 200
201/* check whether 'efd' is still in use */ 201/* check whether 'efd' is still in use */
202#define CHANNEL_EFD_INPUT_ACTIVE(c) \ 202#define CHANNEL_EFD_INPUT_ACTIVE(c) \
203 (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \ 203 (c->extended_usage == CHAN_EXTENDED_READ && \
204 (c->efd != -1 || \ 204 (c->efd != -1 || \
205 buffer_len(&c->extended) > 0)) 205 buffer_len(&c->extended) > 0))
206#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \ 206#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
207 (compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \ 207 (c->extended_usage == CHAN_EXTENDED_WRITE && \
208 c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \ 208 c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
209 buffer_len(&c->extended) > 0)) 209 buffer_len(&c->extended) > 0))
210 210
diff --git a/clientloop.c b/clientloop.c
index 064816234..469a2f00a 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.291 2017/03/10 05:01:13 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.292 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
@@ -207,15 +207,6 @@ leave_non_blocking(void)
207 } 207 }
208} 208}
209 209
210/* Puts stdin terminal in non-blocking mode. */
211
212static void
213enter_non_blocking(void)
214{
215 in_non_blocking_mode = 1;
216 set_nonblock(fileno(stdin));
217}
218
219/* 210/*
220 * Signal handler for the window change signal (SIGWINCH). This just sets a 211 * Signal handler for the window change signal (SIGWINCH). This just sets a
221 * flag indicating that the window has changed. 212 * flag indicating that the window has changed.
@@ -455,91 +446,6 @@ client_x11_get_proto(const char *display, const char *xauth_path,
455} 446}
456 447
457/* 448/*
458 * This is called when the interactive is entered. This checks if there is
459 * an EOF coming on stdin. We must check this explicitly, as select() does
460 * not appear to wake up when redirecting from /dev/null.
461 */
462
463static void
464client_check_initial_eof_on_stdin(void)
465{
466 int len;
467 char buf[1];
468
469 /*
470 * If standard input is to be "redirected from /dev/null", we simply
471 * mark that we have seen an EOF and send an EOF message to the
472 * server. Otherwise, we try to read a single character; it appears
473 * that for some files, such /dev/null, select() never wakes up for
474 * read for this descriptor, which means that we never get EOF. This
475 * way we will get the EOF if stdin comes from /dev/null or similar.
476 */
477 if (stdin_null_flag) {
478 /* Fake EOF on stdin. */
479 debug("Sending eof.");
480 stdin_eof = 1;
481 packet_start(SSH_CMSG_EOF);
482 packet_send();
483 } else {
484 enter_non_blocking();
485
486 /* Check for immediate EOF on stdin. */
487 len = read(fileno(stdin), buf, 1);
488 if (len == 0) {
489 /*
490 * EOF. Record that we have seen it and send
491 * EOF to server.
492 */
493 debug("Sending eof.");
494 stdin_eof = 1;
495 packet_start(SSH_CMSG_EOF);
496 packet_send();
497 } else if (len > 0) {
498 /*
499 * Got data. We must store the data in the buffer,
500 * and also process it as an escape character if
501 * appropriate.
502 */
503 if ((u_char) buf[0] == escape_char1)
504 escape_pending1 = 1;
505 else
506 buffer_append(&stdin_buffer, buf, 1);
507 }
508 leave_non_blocking();
509 }
510}
511
512
513/*
514 * Make packets from buffered stdin data, and buffer them for sending to the
515 * connection.
516 */
517
518static void
519client_make_packets_from_stdin_data(void)
520{
521 u_int len;
522
523 /* Send buffered stdin data to the server. */
524 while (buffer_len(&stdin_buffer) > 0 &&
525 packet_not_very_much_data_to_write()) {
526 len = buffer_len(&stdin_buffer);
527 /* Keep the packets at reasonable size. */
528 if (len > packet_get_maxsize())
529 len = packet_get_maxsize();
530 packet_start(SSH_CMSG_STDIN_DATA);
531 packet_put_string(buffer_ptr(&stdin_buffer), len);
532 packet_send();
533 buffer_consume(&stdin_buffer, len);
534 /* If we have a pending EOF, send it now. */
535 if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
536 packet_start(SSH_CMSG_EOF);
537 packet_send();
538 }
539 }
540}
541
542/*
543 * Checks if the client window has changed, and sends a packet about it to 449 * Checks if the client window has changed, and sends a packet about it to
544 * the server if so. The actual change is detected elsewhere (by a software 450 * the server if so. The actual change is detected elsewhere (by a software
545 * interrupt on Unix); this just checks the flag and sends a message if 451 * interrupt on Unix); this just checks the flag and sends a message if
@@ -549,27 +455,14 @@ client_make_packets_from_stdin_data(void)
549static void 455static void
550client_check_window_change(void) 456client_check_window_change(void)
551{ 457{
552 struct winsize ws; 458 if (!received_window_change_signal)
553
554 if (! received_window_change_signal)
555 return; 459 return;
556 /** XXX race */ 460 /** XXX race */
557 received_window_change_signal = 0; 461 received_window_change_signal = 0;
558 462
559 debug2("client_check_window_change: changed"); 463 debug2("%s: changed", __func__);
560 464
561 if (compat20) { 465 channel_send_window_changes();
562 channel_send_window_changes();
563 } else {
564 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
565 return;
566 packet_start(SSH_CMSG_WINDOW_SIZE);
567 packet_put_int((u_int)ws.ws_row);
568 packet_put_int((u_int)ws.ws_col);
569 packet_put_int((u_int)ws.ws_xpixel);
570 packet_put_int((u_int)ws.ws_ypixel);
571 packet_send();
572 }
573} 466}
574 467
575static int 468static int
@@ -623,35 +516,15 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
623 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 516 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
624 &minwait_secs, rekeying); 517 &minwait_secs, rekeying);
625 518
626 if (!compat20) { 519 /* channel_prepare_select could have closed the last channel */
627 /* Read from the connection, unless our buffers are full. */ 520 if (session_closed && !channel_still_open() &&
628 if (buffer_len(&stdout_buffer) < buffer_high && 521 !packet_have_data_to_write()) {
629 buffer_len(&stderr_buffer) < buffer_high && 522 /* clear mask since we did not call select() */
630 channel_not_very_much_buffered_data()) 523 memset(*readsetp, 0, *nallocp);
631 FD_SET(connection_in, *readsetp); 524 memset(*writesetp, 0, *nallocp);
632 /* 525 return;
633 * Read from stdin, unless we have seen EOF or have very much
634 * buffered data to send to the server.
635 */
636 if (!stdin_eof && packet_not_very_much_data_to_write())
637 FD_SET(fileno(stdin), *readsetp);
638
639 /* Select stdout/stderr if have data in buffer. */
640 if (buffer_len(&stdout_buffer) > 0)
641 FD_SET(fileno(stdout), *writesetp);
642 if (buffer_len(&stderr_buffer) > 0)
643 FD_SET(fileno(stderr), *writesetp);
644 } else { 526 } else {
645 /* channel_prepare_select could have closed the last channel */ 527 FD_SET(connection_in, *readsetp);
646 if (session_closed && !channel_still_open() &&
647 !packet_have_data_to_write()) {
648 /* clear mask since we did not call select() */
649 memset(*readsetp, 0, *nallocp);
650 memset(*writesetp, 0, *nallocp);
651 return;
652 } else {
653 FD_SET(connection_in, *readsetp);
654 }
655 } 528 }
656 529
657 /* Select server connection if have data to write to the server. */ 530 /* Select server connection if have data to write to the server. */
@@ -665,11 +538,11 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
665 */ 538 */
666 539
667 timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ 540 timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
668 if (options.server_alive_interval > 0 && compat20) { 541 if (options.server_alive_interval > 0) {
669 timeout_secs = options.server_alive_interval; 542 timeout_secs = options.server_alive_interval;
670 server_alive_time = now + options.server_alive_interval; 543 server_alive_time = now + options.server_alive_interval;
671 } 544 }
672 if (options.rekey_interval > 0 && compat20 && !rekeying) 545 if (options.rekey_interval > 0 && !rekeying)
673 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); 546 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());
674 set_control_persist_exit_time(); 547 set_control_persist_exit_time();
675 if (control_persist_exit_time > 0) { 548 if (control_persist_exit_time > 0) {
@@ -966,11 +839,6 @@ process_cmdline(void)
966 goto out; 839 goto out;
967 } 840 }
968 841
969 if (delete && !compat20) {
970 logit("Not supported for SSH protocol version 1.");
971 goto out;
972 }
973
974 while (isspace((u_char)*++s)) 842 while (isspace((u_char)*++s))
975 ; 843 ;
976 844
@@ -1027,10 +895,9 @@ out:
1027 895
1028/* reasons to suppress output of an escape command in help output */ 896/* reasons to suppress output of an escape command in help output */
1029#define SUPPRESS_NEVER 0 /* never suppress, always show */ 897#define SUPPRESS_NEVER 0 /* never suppress, always show */
1030#define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */ 898#define SUPPRESS_MUXCLIENT 1 /* don't show in mux client sessions */
1031#define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */ 899#define SUPPRESS_MUXMASTER 2 /* don't show in mux master sessions */
1032#define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */ 900#define SUPPRESS_SYSLOG 4 /* don't show when logging to syslog */
1033#define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */
1034struct escape_help_text { 901struct escape_help_text {
1035 const char *cmd; 902 const char *cmd;
1036 const char *text; 903 const char *text;
@@ -1040,9 +907,9 @@ static struct escape_help_text esc_txt[] = {
1040 {".", "terminate session", SUPPRESS_MUXMASTER}, 907 {".", "terminate session", SUPPRESS_MUXMASTER},
1041 {".", "terminate connection (and any multiplexed sessions)", 908 {".", "terminate connection (and any multiplexed sessions)",
1042 SUPPRESS_MUXCLIENT}, 909 SUPPRESS_MUXCLIENT},
1043 {"B", "send a BREAK to the remote system", SUPPRESS_PROTO1}, 910 {"B", "send a BREAK to the remote system", SUPPRESS_NEVER},
1044 {"C", "open a command line", SUPPRESS_MUXCLIENT}, 911 {"C", "open a command line", SUPPRESS_MUXCLIENT},
1045 {"R", "request rekey", SUPPRESS_PROTO1}, 912 {"R", "request rekey", SUPPRESS_NEVER},
1046 {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT}, 913 {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
1047 {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT}, 914 {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
1048 {"#", "list forwarded connections", SUPPRESS_NEVER}, 915 {"#", "list forwarded connections", SUPPRESS_NEVER},
@@ -1052,8 +919,7 @@ static struct escape_help_text esc_txt[] = {
1052}; 919};
1053 920
1054static void 921static void
1055print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client, 922print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr)
1056 int using_stderr)
1057{ 923{
1058 unsigned int i, suppress_flags; 924 unsigned int i, suppress_flags;
1059 char string[1024]; 925 char string[1024];
@@ -1062,7 +928,7 @@ print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
1062 "Supported escape sequences:\r\n", escape_char); 928 "Supported escape sequences:\r\n", escape_char);
1063 buffer_append(b, string, strlen(string)); 929 buffer_append(b, string, strlen(string));
1064 930
1065 suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) | 931 suppress_flags =
1066 (mux_client ? SUPPRESS_MUXCLIENT : 0) | 932 (mux_client ? SUPPRESS_MUXCLIENT : 0) |
1067 (mux_client ? 0 : SUPPRESS_MUXMASTER) | 933 (mux_client ? 0 : SUPPRESS_MUXMASTER) |
1068 (using_stderr ? 0 : SUPPRESS_SYSLOG); 934 (using_stderr ? 0 : SUPPRESS_SYSLOG);
@@ -1171,26 +1037,20 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1171 continue; 1037 continue;
1172 1038
1173 case 'B': 1039 case 'B':
1174 if (compat20) { 1040 snprintf(string, sizeof string,
1175 snprintf(string, sizeof string, 1041 "%cB\r\n", escape_char);
1176 "%cB\r\n", escape_char); 1042 buffer_append(berr, string, strlen(string));
1177 buffer_append(berr, string, 1043 channel_request_start(c->self, "break", 0);
1178 strlen(string)); 1044 packet_put_int(1000);
1179 channel_request_start(c->self, 1045 packet_send();
1180 "break", 0);
1181 packet_put_int(1000);
1182 packet_send();
1183 }
1184 continue; 1046 continue;
1185 1047
1186 case 'R': 1048 case 'R':
1187 if (compat20) { 1049 if (datafellows & SSH_BUG_NOREKEY)
1188 if (datafellows & SSH_BUG_NOREKEY) 1050 logit("Server does not "
1189 logit("Server does not " 1051 "support re-keying");
1190 "support re-keying"); 1052 else
1191 else 1053 need_rekeying = 1;
1192 need_rekeying = 1;
1193 }
1194 continue; 1054 continue;
1195 1055
1196 case 'V': 1056 case 'V':
@@ -1248,30 +1108,11 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1248 exit(0); 1108 exit(0);
1249 } 1109 }
1250 /* The child continues serving connections. */ 1110 /* The child continues serving connections. */
1251 if (compat20) { 1111 buffer_append(bin, "\004", 1);
1252 buffer_append(bin, "\004", 1); 1112 /* fake EOF on stdin */
1253 /* fake EOF on stdin */ 1113 return -1;
1254 return -1;
1255 } else if (!stdin_eof) {
1256 /*
1257 * Sending SSH_CMSG_EOF alone does not
1258 * always appear to be enough. So we
1259 * try to send an EOF character first.
1260 */
1261 packet_start(SSH_CMSG_STDIN_DATA);
1262 packet_put_string("\004", 1);
1263 packet_send();
1264 /* Close stdin. */
1265 stdin_eof = 1;
1266 if (buffer_len(bin) == 0) {
1267 packet_start(SSH_CMSG_EOF);
1268 packet_send();
1269 }
1270 }
1271 continue;
1272
1273 case '?': 1114 case '?':
1274 print_escape_help(berr, escape_char, compat20, 1115 print_escape_help(berr, escape_char,
1275 (c && c->ctl_chan != -1), 1116 (c && c->ctl_chan != -1),
1276 log_is_on_stderr()); 1117 log_is_on_stderr());
1277 continue; 1118 continue;
@@ -1325,115 +1166,6 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1325 return bytes; 1166 return bytes;
1326} 1167}
1327 1168
1328static void
1329client_process_input(fd_set *readset)
1330{
1331 int len;
1332 char buf[SSH_IOBUFSZ];
1333
1334 /* Read input from stdin. */
1335 if (FD_ISSET(fileno(stdin), readset)) {
1336 /* Read as much as possible. */
1337 len = read(fileno(stdin), buf, sizeof(buf));
1338 if (len < 0 &&
1339 (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
1340 return; /* we'll try again later */
1341 if (len <= 0) {
1342 /*
1343 * Received EOF or error. They are treated
1344 * similarly, except that an error message is printed
1345 * if it was an error condition.
1346 */
1347 if (len < 0) {
1348 snprintf(buf, sizeof buf, "read: %.100s\r\n",
1349 strerror(errno));
1350 buffer_append(&stderr_buffer, buf, strlen(buf));
1351 }
1352 /* Mark that we have seen EOF. */
1353 stdin_eof = 1;
1354 /*
1355 * Send an EOF message to the server unless there is
1356 * data in the buffer. If there is data in the
1357 * buffer, no message will be sent now. Code
1358 * elsewhere will send the EOF when the buffer
1359 * becomes empty if stdin_eof is set.
1360 */
1361 if (buffer_len(&stdin_buffer) == 0) {
1362 packet_start(SSH_CMSG_EOF);
1363 packet_send();
1364 }
1365 } else if (escape_char1 == SSH_ESCAPECHAR_NONE) {
1366 /*
1367 * Normal successful read, and no escape character.
1368 * Just append the data to buffer.
1369 */
1370 buffer_append(&stdin_buffer, buf, len);
1371 } else {
1372 /*
1373 * Normal, successful read. But we have an escape
1374 * character and have to process the characters one
1375 * by one.
1376 */
1377 if (process_escapes(NULL, &stdin_buffer,
1378 &stdout_buffer, &stderr_buffer, buf, len) == -1)
1379 return;
1380 }
1381 }
1382}
1383
1384static void
1385client_process_output(fd_set *writeset)
1386{
1387 int len;
1388 char buf[100];
1389
1390 /* Write buffered output to stdout. */
1391 if (FD_ISSET(fileno(stdout), writeset)) {
1392 /* Write as much data as possible. */
1393 len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
1394 buffer_len(&stdout_buffer));
1395 if (len <= 0) {
1396 if (errno == EINTR || errno == EAGAIN ||
1397 errno == EWOULDBLOCK)
1398 len = 0;
1399 else {
1400 /*
1401 * An error or EOF was encountered. Put an
1402 * error message to stderr buffer.
1403 */
1404 snprintf(buf, sizeof buf,
1405 "write stdout: %.50s\r\n", strerror(errno));
1406 buffer_append(&stderr_buffer, buf, strlen(buf));
1407 quit_pending = 1;
1408 return;
1409 }
1410 }
1411 /* Consume printed data from the buffer. */
1412 buffer_consume(&stdout_buffer, len);
1413 }
1414 /* Write buffered output to stderr. */
1415 if (FD_ISSET(fileno(stderr), writeset)) {
1416 /* Write as much data as possible. */
1417 len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
1418 buffer_len(&stderr_buffer));
1419 if (len <= 0) {
1420 if (errno == EINTR || errno == EAGAIN ||
1421 errno == EWOULDBLOCK)
1422 len = 0;
1423 else {
1424 /*
1425 * EOF or error, but can't even print
1426 * error message.
1427 */
1428 quit_pending = 1;
1429 return;
1430 }
1431 }
1432 /* Consume printed characters from the buffer. */
1433 buffer_consume(&stderr_buffer, len);
1434 }
1435}
1436
1437/* 1169/*
1438 * Get packets from the connection input buffer, and process them as long as 1170 * Get packets from the connection input buffer, and process them as long as
1439 * there are packets available. 1171 * there are packets available.
@@ -1553,18 +1285,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1553 connection_out = packet_get_connection_out(); 1285 connection_out = packet_get_connection_out();
1554 max_fd = MAXIMUM(connection_in, connection_out); 1286 max_fd = MAXIMUM(connection_in, connection_out);
1555 1287
1556 if (!compat20) {
1557 /* enable nonblocking unless tty */
1558 if (!isatty(fileno(stdin)))
1559 set_nonblock(fileno(stdin));
1560 if (!isatty(fileno(stdout)))
1561 set_nonblock(fileno(stdout));
1562 if (!isatty(fileno(stderr)))
1563 set_nonblock(fileno(stderr));
1564 max_fd = MAXIMUM(max_fd, fileno(stdin));
1565 max_fd = MAXIMUM(max_fd, fileno(stdout));
1566 max_fd = MAXIMUM(max_fd, fileno(stderr));
1567 }
1568 quit_pending = 0; 1288 quit_pending = 0;
1569 escape_char1 = escape_char_arg; 1289 escape_char1 = escape_char_arg;
1570 1290
@@ -1592,22 +1312,17 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1592 if (have_pty) 1312 if (have_pty)
1593 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1313 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1594 1314
1595 if (compat20) { 1315 session_ident = ssh2_chan_id;
1596 session_ident = ssh2_chan_id; 1316 if (session_ident != -1) {
1597 if (session_ident != -1) { 1317 if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
1598 if (escape_char_arg != SSH_ESCAPECHAR_NONE) { 1318 channel_register_filter(session_ident,
1599 channel_register_filter(session_ident, 1319 client_simple_escape_filter, NULL,
1600 client_simple_escape_filter, NULL, 1320 client_filter_cleanup,
1601 client_filter_cleanup, 1321 client_new_escape_filter_ctx(
1602 client_new_escape_filter_ctx( 1322 escape_char_arg));
1603 escape_char_arg));
1604 }
1605 channel_register_cleanup(session_ident,
1606 client_channel_closed, 0);
1607 } 1323 }
1608 } else { 1324 channel_register_cleanup(session_ident,
1609 /* Check if we should immediately send eof on stdin. */ 1325 client_channel_closed, 0);
1610 client_check_initial_eof_on_stdin();
1611 } 1326 }
1612 1327
1613 /* Main loop of the client for the interactive session mode. */ 1328 /* Main loop of the client for the interactive session mode. */
@@ -1616,7 +1331,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1616 /* Process buffered packets sent by the server. */ 1331 /* Process buffered packets sent by the server. */
1617 client_process_buffered_input_packets(); 1332 client_process_buffered_input_packets();
1618 1333
1619 if (compat20 && session_closed && !channel_still_open()) 1334 if (session_closed && !channel_still_open())
1620 break; 1335 break;
1621 1336
1622 if (ssh_packet_is_rekeying(active_state)) { 1337 if (ssh_packet_is_rekeying(active_state)) {
@@ -1630,13 +1345,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1630 need_rekeying = 0; 1345 need_rekeying = 0;
1631 } else { 1346 } else {
1632 /* 1347 /*
1633 * Make packets of buffered stdin data, and buffer
1634 * them for sending to the server.
1635 */
1636 if (!compat20)
1637 client_make_packets_from_stdin_data();
1638
1639 /*
1640 * Make packets from buffered channel data, and 1348 * Make packets from buffered channel data, and
1641 * enqueue them for sending to the server. 1349 * enqueue them for sending to the server.
1642 */ 1350 */
@@ -1673,16 +1381,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1673 if (quit_pending) 1381 if (quit_pending)
1674 break; 1382 break;
1675 1383
1676 if (!compat20) {
1677 /* Buffer data from stdin */
1678 client_process_input(readset);
1679 /*
1680 * Process output to stdout and stderr. Output to
1681 * the connection is processed elsewhere (above).
1682 */
1683 client_process_output(writeset);
1684 }
1685
1686 /* 1384 /*
1687 * Send as much buffered packet data as possible to the 1385 * Send as much buffered packet data as possible to the
1688 * sender. 1386 * sender.
@@ -1710,14 +1408,12 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1710 /* Stop watching for window change. */ 1408 /* Stop watching for window change. */
1711 signal(SIGWINCH, SIG_DFL); 1409 signal(SIGWINCH, SIG_DFL);
1712 1410
1713 if (compat20) { 1411 packet_start(SSH2_MSG_DISCONNECT);
1714 packet_start(SSH2_MSG_DISCONNECT); 1412 packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
1715 packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); 1413 packet_put_cstring("disconnected by user");
1716 packet_put_cstring("disconnected by user"); 1414 packet_put_cstring(""); /* language tag */
1717 packet_put_cstring(""); /* language tag */ 1415 packet_send();
1718 packet_send(); 1416 packet_write_wait();
1719 packet_write_wait();
1720 }
1721 1417
1722 channel_free_all(); 1418 channel_free_all();
1723 1419
@@ -1796,92 +1492,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1796 1492
1797/*********/ 1493/*********/
1798 1494
1799static int
1800client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
1801{
1802 u_int data_len;
1803 char *data = packet_get_string(&data_len);
1804 packet_check_eom();
1805 buffer_append(&stdout_buffer, data, data_len);
1806 explicit_bzero(data, data_len);
1807 free(data);
1808 return 0;
1809}
1810static int
1811client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
1812{
1813 u_int data_len;
1814 char *data = packet_get_string(&data_len);
1815 packet_check_eom();
1816 buffer_append(&stderr_buffer, data, data_len);
1817 explicit_bzero(data, data_len);
1818 free(data);
1819 return 0;
1820}
1821static int
1822client_input_exit_status(int type, u_int32_t seq, void *ctxt)
1823{
1824 exit_status = packet_get_int();
1825 packet_check_eom();
1826 /* Acknowledge the exit. */
1827 packet_start(SSH_CMSG_EXIT_CONFIRMATION);
1828 packet_send();
1829 /*
1830 * Must wait for packet to be sent since we are
1831 * exiting the loop.
1832 */
1833 packet_write_wait();
1834 /* Flag that we want to exit. */
1835 quit_pending = 1;
1836 return 0;
1837}
1838
1839static int
1840client_input_agent_open(int type, u_int32_t seq, void *ctxt)
1841{
1842 Channel *c = NULL;
1843 int r, remote_id, sock;
1844
1845 /* Read the remote channel number from the message. */
1846 remote_id = packet_get_int();
1847 packet_check_eom();
1848
1849 /*
1850 * Get a connection to the local authentication agent (this may again
1851 * get forwarded).
1852 */
1853 if ((r = ssh_get_authentication_socket(&sock)) != 0 &&
1854 r != SSH_ERR_AGENT_NOT_PRESENT)
1855 debug("%s: ssh_get_authentication_socket: %s",
1856 __func__, ssh_err(r));
1857
1858
1859 /*
1860 * If we could not connect the agent, send an error message back to
1861 * the server. This should never happen unless the agent dies,
1862 * because authentication forwarding is only enabled if we have an
1863 * agent.
1864 */
1865 if (sock >= 0) {
1866 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
1867 -1, 0, 0, 0, "authentication agent connection", 1);
1868 c->remote_id = remote_id;
1869 c->force_drain = 1;
1870 }
1871 if (c == NULL) {
1872 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1873 packet_put_int(remote_id);
1874 } else {
1875 /* Send a confirmation to the remote host. */
1876 debug("Forwarding authentication connection.");
1877 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1878 packet_put_int(remote_id);
1879 packet_put_int(c->self);
1880 }
1881 packet_send();
1882 return 0;
1883}
1884
1885static Channel * 1495static Channel *
1886client_request_forwarded_tcpip(const char *request_type, int rchan, 1496client_request_forwarded_tcpip(const char *request_type, int rchan,
1887 u_int rwindow, u_int rmaxpack) 1497 u_int rwindow, u_int rmaxpack)
@@ -2032,11 +1642,6 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
2032 if (tun_mode == SSH_TUNMODE_NO) 1642 if (tun_mode == SSH_TUNMODE_NO)
2033 return 0; 1643 return 0;
2034 1644
2035 if (!compat20) {
2036 error("Tunnel forwarding is not supported for protocol 1");
2037 return -1;
2038 }
2039
2040 debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); 1645 debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
2041 1646
2042 /* Open local tunnel device */ 1647 /* Open local tunnel device */
@@ -2687,7 +2292,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2687} 2292}
2688 2293
2689static void 2294static void
2690client_init_dispatch_20(void) 2295client_init_dispatch(void)
2691{ 2296{
2692 dispatch_init(&dispatch_protocol_error); 2297 dispatch_init(&dispatch_protocol_error);
2693 2298
@@ -2712,45 +2317,6 @@ client_init_dispatch_20(void)
2712 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 2317 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
2713} 2318}
2714 2319
2715static void
2716client_init_dispatch_13(void)
2717{
2718 dispatch_init(NULL);
2719 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
2720 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
2721 dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
2722 dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
2723 dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
2724 dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
2725 dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
2726 dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
2727 dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
2728
2729 dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
2730 &client_input_agent_open : &deny_input_open);
2731 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
2732 &x11_input_open : &deny_input_open);
2733}
2734
2735static void
2736client_init_dispatch_15(void)
2737{
2738 client_init_dispatch_13();
2739 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
2740 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
2741}
2742
2743static void
2744client_init_dispatch(void)
2745{
2746 if (compat20)
2747 client_init_dispatch_20();
2748 else if (compat13)
2749 client_init_dispatch_13();
2750 else
2751 client_init_dispatch_15();
2752}
2753
2754void 2320void
2755client_stop_mux(void) 2321client_stop_mux(void)
2756{ 2322{
diff --git a/compat.c b/compat.c
index 945fd349b..156a5ea8e 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.c,v 1.102 2017/04/30 23:11:45 djm Exp $ */ 1/* $OpenBSD: compat.c,v 1.103 2017/04/30 23:13:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -39,24 +39,8 @@
39#include "match.h" 39#include "match.h"
40#include "kex.h" 40#include "kex.h"
41 41
42int compat13 = 0;
43int compat20 = 0;
44int datafellows = 0; 42int datafellows = 0;
45 43
46void
47enable_compat20(void)
48{
49 if (compat20)
50 return;
51 debug("Enabling compatibility mode for protocol 2.0");
52 compat20 = 1;
53}
54void
55enable_compat13(void)
56{
57 debug("Enabling compatibility mode for protocol 1.3");
58 compat13 = 1;
59}
60/* datafellows bug compatibility */ 44/* datafellows bug compatibility */
61u_int 45u_int
62compat_datafellows(const char *version) 46compat_datafellows(const char *version)
diff --git a/compat.h b/compat.h
index 2be290a8a..2e7830f1b 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.h,v 1.48 2015/05/26 23:23:40 dtucker Exp $ */ 1/* $OpenBSD: compat.h,v 1.49 2017/04/30 23:13:25 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -63,15 +63,11 @@
63#define SSH_BUG_HOSTKEYS 0x20000000 63#define SSH_BUG_HOSTKEYS 0x20000000
64#define SSH_BUG_DHGEX_LARGE 0x40000000 64#define SSH_BUG_DHGEX_LARGE 0x40000000
65 65
66void enable_compat13(void);
67void enable_compat20(void);
68u_int compat_datafellows(const char *); 66u_int compat_datafellows(const char *);
69int proto_spec(const char *); 67int proto_spec(const char *);
70char *compat_cipher_proposal(char *); 68char *compat_cipher_proposal(char *);
71char *compat_pkalg_proposal(char *); 69char *compat_pkalg_proposal(char *);
72char *compat_kex_proposal(char *); 70char *compat_kex_proposal(char *);
73 71
74extern int compat13;
75extern int compat20;
76extern int datafellows; 72extern int datafellows;
77#endif 73#endif
diff --git a/dispatch.c b/dispatch.c
index aac933e0a..fa4152a44 100644
--- a/dispatch.c
+++ b/dispatch.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dispatch.c,v 1.27 2015/05/01 07:10:01 djm Exp $ */ 1/* $OpenBSD: dispatch.c,v 1.28 2017/04/30 23:13:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -45,8 +45,6 @@ dispatch_protocol_error(int type, u_int32_t seq, void *ctx)
45 int r; 45 int r;
46 46
47 logit("dispatch_protocol_error: type %d seq %u", type, seq); 47 logit("dispatch_protocol_error: type %d seq %u", type, seq);
48 if (!compat20)
49 fatal("protocol error");
50 if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || 48 if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
51 (r = sshpkt_put_u32(ssh, seq)) != 0 || 49 (r = sshpkt_put_u32(ssh, seq)) != 0 ||
52 (r = sshpkt_send(ssh)) != 0 || 50 (r = sshpkt_send(ssh)) != 0 ||
diff --git a/nchan.c b/nchan.c
index 20f6a2f49..312c0b1e6 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */ 1/* $OpenBSD: nchan.c,v 1.64 2017/04/30 23:13:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -74,9 +74,6 @@
74/* 74/*
75 * ACTIONS: should never update the channel states 75 * ACTIONS: should never update the channel states
76 */ 76 */
77static void chan_send_ieof1(Channel *);
78static void chan_send_oclose1(Channel *);
79static void chan_send_close2(Channel *);
80static void chan_send_eof2(Channel *); 77static void chan_send_eof2(Channel *);
81static void chan_send_eow2(Channel *); 78static void chan_send_eow2(Channel *);
82 79
@@ -96,6 +93,7 @@ chan_set_istate(Channel *c, u_int next)
96 istates[next]); 93 istates[next]);
97 c->istate = next; 94 c->istate = next;
98} 95}
96
99static void 97static void
100chan_set_ostate(Channel *c, u_int next) 98chan_set_ostate(Channel *c, u_int next)
101{ 99{
@@ -106,34 +104,6 @@ chan_set_ostate(Channel *c, u_int next)
106 c->ostate = next; 104 c->ostate = next;
107} 105}
108 106
109/*
110 * SSH1 specific implementation of event functions
111 */
112
113static void
114chan_rcvd_oclose1(Channel *c)
115{
116 debug2("channel %d: rcvd oclose", c->self);
117 switch (c->istate) {
118 case CHAN_INPUT_WAIT_OCLOSE:
119 chan_set_istate(c, CHAN_INPUT_CLOSED);
120 break;
121 case CHAN_INPUT_OPEN:
122 chan_shutdown_read(c);
123 chan_send_ieof1(c);
124 chan_set_istate(c, CHAN_INPUT_CLOSED);
125 break;
126 case CHAN_INPUT_WAIT_DRAIN:
127 /* both local read_failed and remote write_failed */
128 chan_send_ieof1(c);
129 chan_set_istate(c, CHAN_INPUT_CLOSED);
130 break;
131 default:
132 error("channel %d: protocol error: rcvd_oclose for istate %d",
133 c->self, c->istate);
134 return;
135 }
136}
137void 107void
138chan_read_failed(Channel *c) 108chan_read_failed(Channel *c)
139{ 109{
@@ -149,6 +119,7 @@ chan_read_failed(Channel *c)
149 break; 119 break;
150 } 120 }
151} 121}
122
152void 123void
153chan_ibuf_empty(Channel *c) 124chan_ibuf_empty(Channel *c)
154{ 125{
@@ -160,14 +131,9 @@ chan_ibuf_empty(Channel *c)
160 } 131 }
161 switch (c->istate) { 132 switch (c->istate) {
162 case CHAN_INPUT_WAIT_DRAIN: 133 case CHAN_INPUT_WAIT_DRAIN:
163 if (compat20) { 134 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
164 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) 135 chan_send_eof2(c);
165 chan_send_eof2(c); 136 chan_set_istate(c, CHAN_INPUT_CLOSED);
166 chan_set_istate(c, CHAN_INPUT_CLOSED);
167 } else {
168 chan_send_ieof1(c);
169 chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
170 }
171 break; 137 break;
172 default: 138 default:
173 error("channel %d: chan_ibuf_empty for istate %d", 139 error("channel %d: chan_ibuf_empty for istate %d",
@@ -175,44 +141,7 @@ chan_ibuf_empty(Channel *c)
175 break; 141 break;
176 } 142 }
177} 143}
178static void 144
179chan_rcvd_ieof1(Channel *c)
180{
181 debug2("channel %d: rcvd ieof", c->self);
182 switch (c->ostate) {
183 case CHAN_OUTPUT_OPEN:
184 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
185 break;
186 case CHAN_OUTPUT_WAIT_IEOF:
187 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
188 break;
189 default:
190 error("channel %d: protocol error: rcvd_ieof for ostate %d",
191 c->self, c->ostate);
192 break;
193 }
194}
195static void
196chan_write_failed1(Channel *c)
197{
198 debug2("channel %d: write failed", c->self);
199 switch (c->ostate) {
200 case CHAN_OUTPUT_OPEN:
201 chan_shutdown_write(c);
202 chan_send_oclose1(c);
203 chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
204 break;
205 case CHAN_OUTPUT_WAIT_DRAIN:
206 chan_shutdown_write(c);
207 chan_send_oclose1(c);
208 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
209 break;
210 default:
211 error("channel %d: chan_write_failed for ostate %d",
212 c->self, c->ostate);
213 break;
214 }
215}
216void 145void
217chan_obuf_empty(Channel *c) 146chan_obuf_empty(Channel *c)
218{ 147{
@@ -225,8 +154,6 @@ chan_obuf_empty(Channel *c)
225 switch (c->ostate) { 154 switch (c->ostate) {
226 case CHAN_OUTPUT_WAIT_DRAIN: 155 case CHAN_OUTPUT_WAIT_DRAIN:
227 chan_shutdown_write(c); 156 chan_shutdown_write(c);
228 if (!compat20)
229 chan_send_oclose1(c);
230 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 157 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
231 break; 158 break;
232 default: 159 default:
@@ -235,82 +162,6 @@ chan_obuf_empty(Channel *c)
235 break; 162 break;
236 } 163 }
237} 164}
238static void
239chan_send_ieof1(Channel *c)
240{
241 debug2("channel %d: send ieof", c->self);
242 switch (c->istate) {
243 case CHAN_INPUT_OPEN:
244 case CHAN_INPUT_WAIT_DRAIN:
245 packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
246 packet_put_int(c->remote_id);
247 packet_send();
248 break;
249 default:
250 error("channel %d: cannot send ieof for istate %d",
251 c->self, c->istate);
252 break;
253 }
254}
255static void
256chan_send_oclose1(Channel *c)
257{
258 debug2("channel %d: send oclose", c->self);
259 switch (c->ostate) {
260 case CHAN_OUTPUT_OPEN:
261 case CHAN_OUTPUT_WAIT_DRAIN:
262 buffer_clear(&c->output);
263 packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
264 packet_put_int(c->remote_id);
265 packet_send();
266 break;
267 default:
268 error("channel %d: cannot send oclose for ostate %d",
269 c->self, c->ostate);
270 break;
271 }
272}
273
274/*
275 * the same for SSH2
276 */
277static void
278chan_rcvd_close2(Channel *c)
279{
280 debug2("channel %d: rcvd close", c->self);
281 if (!(c->flags & CHAN_LOCAL)) {
282 if (c->flags & CHAN_CLOSE_RCVD)
283 error("channel %d: protocol error: close rcvd twice",
284 c->self);
285 c->flags |= CHAN_CLOSE_RCVD;
286 }
287 if (c->type == SSH_CHANNEL_LARVAL) {
288 /* tear down larval channels immediately */
289 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
290 chan_set_istate(c, CHAN_INPUT_CLOSED);
291 return;
292 }
293 switch (c->ostate) {
294 case CHAN_OUTPUT_OPEN:
295 /*
296 * wait until a data from the channel is consumed if a CLOSE
297 * is received
298 */
299 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
300 break;
301 }
302 switch (c->istate) {
303 case CHAN_INPUT_OPEN:
304 chan_shutdown_read(c);
305 chan_set_istate(c, CHAN_INPUT_CLOSED);
306 break;
307 case CHAN_INPUT_WAIT_DRAIN:
308 if (!(c->flags & CHAN_LOCAL))
309 chan_send_eof2(c);
310 chan_set_istate(c, CHAN_INPUT_CLOSED);
311 break;
312 }
313}
314 165
315void 166void
316chan_rcvd_eow(Channel *c) 167chan_rcvd_eow(Channel *c)
@@ -323,32 +174,7 @@ chan_rcvd_eow(Channel *c)
323 break; 174 break;
324 } 175 }
325} 176}
326static void 177
327chan_rcvd_eof2(Channel *c)
328{
329 debug2("channel %d: rcvd eof", c->self);
330 c->flags |= CHAN_EOF_RCVD;
331 if (c->ostate == CHAN_OUTPUT_OPEN)
332 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
333}
334static void
335chan_write_failed2(Channel *c)
336{
337 debug2("channel %d: write failed", c->self);
338 switch (c->ostate) {
339 case CHAN_OUTPUT_OPEN:
340 case CHAN_OUTPUT_WAIT_DRAIN:
341 chan_shutdown_write(c);
342 if (strcmp(c->ctype, "session") == 0)
343 chan_send_eow2(c);
344 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
345 break;
346 default:
347 error("channel %d: chan_write_failed for ostate %d",
348 c->self, c->ostate);
349 break;
350 }
351}
352static void 178static void
353chan_send_eof2(Channel *c) 179chan_send_eof2(Channel *c)
354{ 180{
@@ -366,6 +192,7 @@ chan_send_eof2(Channel *c)
366 break; 192 break;
367 } 193 }
368} 194}
195
369static void 196static void
370chan_send_close2(Channel *c) 197chan_send_close2(Channel *c)
371{ 198{
@@ -383,6 +210,7 @@ chan_send_close2(Channel *c)
383 c->flags |= CHAN_CLOSE_SENT; 210 c->flags |= CHAN_CLOSE_SENT;
384 } 211 }
385} 212}
213
386static void 214static void
387chan_send_eow2(Channel *c) 215chan_send_eow2(Channel *c)
388{ 216{
@@ -406,30 +234,71 @@ chan_send_eow2(Channel *c)
406void 234void
407chan_rcvd_ieof(Channel *c) 235chan_rcvd_ieof(Channel *c)
408{ 236{
409 if (compat20) 237 debug2("channel %d: rcvd eof", c->self);
410 chan_rcvd_eof2(c); 238 c->flags |= CHAN_EOF_RCVD;
411 else 239 if (c->ostate == CHAN_OUTPUT_OPEN)
412 chan_rcvd_ieof1(c); 240 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
413 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && 241 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
414 buffer_len(&c->output) == 0 && 242 buffer_len(&c->output) == 0 &&
415 !CHANNEL_EFD_OUTPUT_ACTIVE(c)) 243 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
416 chan_obuf_empty(c); 244 chan_obuf_empty(c);
417} 245}
246
418void 247void
419chan_rcvd_oclose(Channel *c) 248chan_rcvd_oclose(Channel *c)
420{ 249{
421 if (compat20) 250 debug2("channel %d: rcvd close", c->self);
422 chan_rcvd_close2(c); 251 if (!(c->flags & CHAN_LOCAL)) {
423 else 252 if (c->flags & CHAN_CLOSE_RCVD)
424 chan_rcvd_oclose1(c); 253 error("channel %d: protocol error: close rcvd twice",
254 c->self);
255 c->flags |= CHAN_CLOSE_RCVD;
256 }
257 if (c->type == SSH_CHANNEL_LARVAL) {
258 /* tear down larval channels immediately */
259 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
260 chan_set_istate(c, CHAN_INPUT_CLOSED);
261 return;
262 }
263 switch (c->ostate) {
264 case CHAN_OUTPUT_OPEN:
265 /*
266 * wait until a data from the channel is consumed if a CLOSE
267 * is received
268 */
269 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
270 break;
271 }
272 switch (c->istate) {
273 case CHAN_INPUT_OPEN:
274 chan_shutdown_read(c);
275 chan_set_istate(c, CHAN_INPUT_CLOSED);
276 break;
277 case CHAN_INPUT_WAIT_DRAIN:
278 if (!(c->flags & CHAN_LOCAL))
279 chan_send_eof2(c);
280 chan_set_istate(c, CHAN_INPUT_CLOSED);
281 break;
282 }
425} 283}
284
426void 285void
427chan_write_failed(Channel *c) 286chan_write_failed(Channel *c)
428{ 287{
429 if (compat20) 288 debug2("channel %d: write failed", c->self);
430 chan_write_failed2(c); 289 switch (c->ostate) {
431 else 290 case CHAN_OUTPUT_OPEN:
432 chan_write_failed1(c); 291 case CHAN_OUTPUT_WAIT_DRAIN:
292 chan_shutdown_write(c);
293 if (strcmp(c->ctype, "session") == 0)
294 chan_send_eow2(c);
295 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
296 break;
297 default:
298 error("channel %d: chan_write_failed for ostate %d",
299 c->self, c->ostate);
300 break;
301 }
433} 302}
434 303
435void 304void
@@ -447,10 +316,6 @@ chan_is_dead(Channel *c, int do_send)
447 } 316 }
448 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 317 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
449 return 0; 318 return 0;
450 if (!compat20) {
451 debug2("channel %d: is dead", c->self);
452 return 1;
453 }
454 if ((datafellows & SSH_BUG_EXTEOF) && 319 if ((datafellows & SSH_BUG_EXTEOF) &&
455 c->extended_usage == CHAN_EXTENDED_WRITE && 320 c->extended_usage == CHAN_EXTENDED_WRITE &&
456 c->efd != -1 && 321 c->efd != -1 &&
@@ -488,7 +353,7 @@ static void
488chan_shutdown_write(Channel *c) 353chan_shutdown_write(Channel *c)
489{ 354{
490 buffer_clear(&c->output); 355 buffer_clear(&c->output);
491 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 356 if (c->type == SSH_CHANNEL_LARVAL)
492 return; 357 return;
493 /* shutdown failure is allowed if write failed already */ 358 /* shutdown failure is allowed if write failed already */
494 debug2("channel %d: close_write", c->self); 359 debug2("channel %d: close_write", c->self);
@@ -504,10 +369,11 @@ chan_shutdown_write(Channel *c)
504 c->self, c->wfd, strerror(errno)); 369 c->self, c->wfd, strerror(errno));
505 } 370 }
506} 371}
372
507static void 373static void
508chan_shutdown_read(Channel *c) 374chan_shutdown_read(Channel *c)
509{ 375{
510 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 376 if (c->type == SSH_CHANNEL_LARVAL)
511 return; 377 return;
512 debug2("channel %d: close_read", c->self); 378 debug2("channel %d: close_read", c->self);
513 if (c->sock != -1) { 379 if (c->sock != -1) {
diff --git a/packet.c b/packet.c
index 5d25ae61d..31499c827 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.248 2017/04/30 23:10:43 djm Exp $ */ 1/* $OpenBSD: packet.c,v 1.249 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
@@ -278,8 +278,8 @@ ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx)
278int 278int
279ssh_packet_is_rekeying(struct ssh *ssh) 279ssh_packet_is_rekeying(struct ssh *ssh)
280{ 280{
281 return compat20 && 281 return ssh->state->rekeying ||
282 (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0)); 282 (ssh->kex != NULL && ssh->kex->done == 0);
283} 283}
284 284
285/* 285/*
@@ -698,7 +698,7 @@ ssh_packet_start_compression(struct ssh *ssh, int level)
698{ 698{
699 int r; 699 int r;
700 700
701 if (ssh->state->packet_compression && !compat20) 701 if (ssh->state->packet_compression)
702 return SSH_ERR_INTERNAL_ERROR; 702 return SSH_ERR_INTERNAL_ERROR;
703 ssh->state->packet_compression = 1; 703 ssh->state->packet_compression = 1;
704 if ((r = ssh_packet_init_compression(ssh)) != 0 || 704 if ((r = ssh_packet_init_compression(ssh)) != 0 ||
@@ -814,99 +814,6 @@ ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen,
814 fatal("no SSH protocol 1 support"); 814 fatal("no SSH protocol 1 support");
815} 815}
816 816
817/*
818 * Finalizes and sends the packet. If the encryption key has been set,
819 * encrypts the packet before sending.
820 */
821
822int
823ssh_packet_send1(struct ssh *ssh)
824{
825 struct session_state *state = ssh->state;
826 u_char buf[8], *cp;
827 int r, padding, len;
828 u_int checksum;
829
830 /*
831 * If using packet compression, compress the payload of the outgoing
832 * packet.
833 */
834 if (state->packet_compression) {
835 sshbuf_reset(state->compression_buffer);
836 /* Skip padding. */
837 if ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0)
838 goto out;
839 /* padding */
840 if ((r = sshbuf_put(state->compression_buffer,
841 "\0\0\0\0\0\0\0\0", 8)) != 0)
842 goto out;
843 if ((r = compress_buffer(ssh, state->outgoing_packet,
844 state->compression_buffer)) != 0)
845 goto out;
846 sshbuf_reset(state->outgoing_packet);
847 if ((r = sshbuf_putb(state->outgoing_packet,
848 state->compression_buffer)) != 0)
849 goto out;
850 }
851 /* Compute packet length without padding (add checksum, remove padding). */
852 len = sshbuf_len(state->outgoing_packet) + 4 - 8;
853
854 /* Insert padding. Initialized to zero in packet_start1() */
855 padding = 8 - len % 8;
856 if (!cipher_ctx_is_plaintext(state->send_context)) {
857 cp = sshbuf_mutable_ptr(state->outgoing_packet);
858 if (cp == NULL) {
859 r = SSH_ERR_INTERNAL_ERROR;
860 goto out;
861 }
862 arc4random_buf(cp + 8 - padding, padding);
863 }
864 if ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0)
865 goto out;
866
867 /* Add check bytes. */
868 checksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet),
869 sshbuf_len(state->outgoing_packet));
870 POKE_U32(buf, checksum);
871 if ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0)
872 goto out;
873
874#ifdef PACKET_DEBUG
875 fprintf(stderr, "packet_send plain: ");
876 sshbuf_dump(state->outgoing_packet, stderr);
877#endif
878
879 /* Append to output. */
880 POKE_U32(buf, len);
881 if ((r = sshbuf_put(state->output, buf, 4)) != 0)
882 goto out;
883 if ((r = sshbuf_reserve(state->output,
884 sshbuf_len(state->outgoing_packet), &cp)) != 0)
885 goto out;
886 if ((r = cipher_crypt(state->send_context, 0, cp,
887 sshbuf_ptr(state->outgoing_packet),
888 sshbuf_len(state->outgoing_packet), 0, 0)) != 0)
889 goto out;
890
891#ifdef PACKET_DEBUG
892 fprintf(stderr, "encrypted: ");
893 sshbuf_dump(state->output, stderr);
894#endif
895 state->p_send.packets++;
896 state->p_send.bytes += len +
897 sshbuf_len(state->outgoing_packet);
898 sshbuf_reset(state->outgoing_packet);
899
900 /*
901 * Note that the packet is now only buffered in output. It won't be
902 * actually sent until ssh_packet_write_wait or ssh_packet_write_poll
903 * is called.
904 */
905 r = 0;
906 out:
907 return r;
908}
909
910int 817int
911ssh_set_newkeys(struct ssh *ssh, int mode) 818ssh_set_newkeys(struct ssh *ssh, int mode)
912{ 819{
@@ -1397,13 +1304,6 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1397 r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); 1304 r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);
1398 if (r != 0) 1305 if (r != 0)
1399 break; 1306 break;
1400 if (!compat20 && (
1401 *typep == SSH_SMSG_SUCCESS
1402 || *typep == SSH_SMSG_FAILURE
1403 || *typep == SSH_CMSG_EOF
1404 || *typep == SSH_CMSG_EXIT_CONFIRMATION))
1405 if ((r = sshpkt_get_end(ssh)) != 0)
1406 break;
1407 /* If we got a packet, return it. */ 1307 /* If we got a packet, return it. */
1408 if (*typep != SSH_MSG_NONE) 1308 if (*typep != SSH_MSG_NONE)
1409 break; 1309 break;
@@ -1924,75 +1824,48 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1924 1824
1925 for (;;) { 1825 for (;;) {
1926 msg = NULL; 1826 msg = NULL;
1927 if (compat20) { 1827 r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
1928 r = ssh_packet_read_poll2(ssh, typep, seqnr_p); 1828 if (r != 0)
1929 if (r != 0) 1829 return r;
1930 return r; 1830 if (*typep) {
1931 if (*typep) { 1831 state->keep_alive_timeouts = 0;
1932 state->keep_alive_timeouts = 0; 1832 DBG(debug("received packet type %d", *typep));
1933 DBG(debug("received packet type %d", *typep)); 1833 }
1934 } 1834 switch (*typep) {
1935 switch (*typep) { 1835 case SSH2_MSG_IGNORE:
1936 case SSH2_MSG_IGNORE: 1836 debug3("Received SSH2_MSG_IGNORE");
1937 debug3("Received SSH2_MSG_IGNORE"); 1837 break;
1938 break; 1838 case SSH2_MSG_DEBUG:
1939 case SSH2_MSG_DEBUG: 1839 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
1940 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || 1840 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
1941 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || 1841 (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
1942 (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
1943 free(msg);
1944 return r;
1945 }
1946 debug("Remote: %.900s", msg);
1947 free(msg);
1948 break;
1949 case SSH2_MSG_DISCONNECT:
1950 if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
1951 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
1952 return r;
1953 /* Ignore normal client exit notifications */
1954 do_log2(ssh->state->server_side &&
1955 reason == SSH2_DISCONNECT_BY_APPLICATION ?
1956 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
1957 "Received disconnect from %s port %d:"
1958 "%u: %.400s", ssh_remote_ipaddr(ssh),
1959 ssh_remote_port(ssh), reason, msg);
1960 free(msg);
1961 return SSH_ERR_DISCONNECTED;
1962 case SSH2_MSG_UNIMPLEMENTED:
1963 if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
1964 return r;
1965 debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
1966 seqnr);
1967 break;
1968 default:
1969 return 0;
1970 }
1971 } else {
1972 r = ssh_packet_read_poll1(ssh, typep);
1973 switch (*typep) {
1974 case SSH_MSG_NONE:
1975 return SSH_MSG_NONE;
1976 case SSH_MSG_IGNORE:
1977 break;
1978 case SSH_MSG_DEBUG:
1979 if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
1980 return r;
1981 debug("Remote: %.900s", msg);
1982 free(msg);
1983 break;
1984 case SSH_MSG_DISCONNECT:
1985 if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
1986 return r;
1987 error("Received disconnect from %s port %d: "
1988 "%.400s", ssh_remote_ipaddr(ssh),
1989 ssh_remote_port(ssh), msg);
1990 free(msg); 1842 free(msg);
1991 return SSH_ERR_DISCONNECTED; 1843 return r;
1992 default:
1993 DBG(debug("received packet type %d", *typep));
1994 return 0;
1995 } 1844 }
1845 debug("Remote: %.900s", msg);
1846 free(msg);
1847 break;
1848 case SSH2_MSG_DISCONNECT:
1849 if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
1850 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
1851 return r;
1852 /* Ignore normal client exit notifications */
1853 do_log2(ssh->state->server_side &&
1854 reason == SSH2_DISCONNECT_BY_APPLICATION ?
1855 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
1856 "Received disconnect from %s port %d:"
1857 "%u: %.400s", ssh_remote_ipaddr(ssh),
1858 ssh_remote_port(ssh), reason, msg);
1859 free(msg);
1860 return SSH_ERR_DISCONNECTED;
1861 case SSH2_MSG_UNIMPLEMENTED:
1862 if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
1863 return r;
1864 debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
1865 seqnr);
1866 break;
1867 default:
1868 return 0;
1996 } 1869 }
1997 } 1870 }
1998} 1871}
@@ -2044,27 +1917,19 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...)
2044 va_list args; 1917 va_list args;
2045 int r; 1918 int r;
2046 1919
2047 if (compat20 && (ssh->compat & SSH_BUG_DEBUG)) 1920 if ((ssh->compat & SSH_BUG_DEBUG))
2048 return; 1921 return;
2049 1922
2050 va_start(args, fmt); 1923 va_start(args, fmt);
2051 vsnprintf(buf, sizeof(buf), fmt, args); 1924 vsnprintf(buf, sizeof(buf), fmt, args);
2052 va_end(args); 1925 va_end(args);
2053 1926
2054 if (compat20) { 1927 if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||
2055 if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 || 1928 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */
2056 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */ 1929 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
2057 (r = sshpkt_put_cstring(ssh, buf)) != 0 || 1930 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
2058 (r = sshpkt_put_cstring(ssh, "")) != 0 || 1931 (r = sshpkt_send(ssh)) != 0 ||
2059 (r = sshpkt_send(ssh)) != 0) 1932 (r = ssh_packet_write_wait(ssh)) != 0)
2060 fatal("%s: %s", __func__, ssh_err(r));
2061 } else {
2062 if ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 ||
2063 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
2064 (r = sshpkt_send(ssh)) != 0)
2065 fatal("%s: %s", __func__, ssh_err(r));
2066 }
2067 if ((r = ssh_packet_write_wait(ssh)) != 0)
2068 fatal("%s: %s", __func__, ssh_err(r)); 1933 fatal("%s: %s", __func__, ssh_err(r));
2069} 1934}
2070 1935
@@ -2385,8 +2250,7 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes)
2385 u_int32_t rnd = 0; 2250 u_int32_t rnd = 0;
2386 int r, i; 2251 int r, i;
2387 2252
2388 if ((r = sshpkt_start(ssh, compat20 ? 2253 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
2389 SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 ||
2390 (r = sshpkt_put_u32(ssh, nbytes)) != 0) 2254 (r = sshpkt_put_u32(ssh, nbytes)) != 0)
2391 fatal("%s: %s", __func__, ssh_err(r)); 2255 fatal("%s: %s", __func__, ssh_err(r));
2392 for (i = 0; i < nbytes; i++) { 2256 for (i = 0; i < nbytes; i++) {
@@ -2531,38 +2395,22 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)
2531 struct session_state *state = ssh->state; 2395 struct session_state *state = ssh->state;
2532 u_char *p; 2396 u_char *p;
2533 size_t slen, rlen; 2397 size_t slen, rlen;
2534 int r, ssh1cipher; 2398 int r;
2535 2399
2536 if (!compat20) { 2400 if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
2537 ssh1cipher = cipher_ctx_get_number(state->receive_context); 2401 (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
2538 slen = cipher_get_keyiv_len(state->send_context); 2402 (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
2539 rlen = cipher_get_keyiv_len(state->receive_context); 2403 (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
2540 if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 || 2404 (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
2541 (r = sshbuf_put_u32(m, ssh1cipher)) != 0 || 2405 (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
2542 (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 || 2406 (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
2543 (r = sshbuf_put_u32(m, slen)) != 0 || 2407 (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
2544 (r = sshbuf_reserve(m, slen, &p)) != 0 || 2408 (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
2545 (r = cipher_get_keyiv(state->send_context, p, slen)) != 0 || 2409 (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
2546 (r = sshbuf_put_u32(m, rlen)) != 0 || 2410 (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
2547 (r = sshbuf_reserve(m, rlen, &p)) != 0 || 2411 (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
2548 (r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0) 2412 (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0)
2549 return r; 2413 return r;
2550 } else {
2551 if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
2552 (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
2553 (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
2554 (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
2555 (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
2556 (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
2557 (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
2558 (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
2559 (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
2560 (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
2561 (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
2562 (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
2563 (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0)
2564 return r;
2565 }
2566 2414
2567 slen = cipher_get_keycontext(state->send_context, NULL); 2415 slen = cipher_get_keycontext(state->send_context, NULL);
2568 rlen = cipher_get_keycontext(state->receive_context, NULL); 2416 rlen = cipher_get_keycontext(state->receive_context, NULL);
@@ -2701,53 +2549,34 @@ int
2701ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) 2549ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
2702{ 2550{
2703 struct session_state *state = ssh->state; 2551 struct session_state *state = ssh->state;
2704 const u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output; 2552 const u_char *keyin, *keyout, *input, *output;
2705 size_t ssh1keylen, rlen, slen, ilen, olen; 2553 size_t rlen, slen, ilen, olen;
2706 int r; 2554 int r;
2707 u_int ssh1cipher = 0; 2555
2708 2556 if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
2709 if (!compat20) { 2557 (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||
2710 if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 || 2558 (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||
2711 (r = sshbuf_get_u32(m, &ssh1cipher)) != 0 || 2559 (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
2712 (r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 || 2560 (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
2713 (r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 || 2561 (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
2714 (r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0) 2562 (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
2715 return r; 2563 (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
2716 if (ssh1cipher > INT_MAX) 2564 (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
2717 return SSH_ERR_KEY_UNKNOWN_CIPHER; 2565 (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
2718 ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, 2566 (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
2719 (int)ssh1cipher); 2567 (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
2720 if (cipher_get_keyiv_len(state->send_context) != (int)slen || 2568 (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
2721 cipher_get_keyiv_len(state->receive_context) != (int)rlen) 2569 return r;
2722 return SSH_ERR_INVALID_FORMAT; 2570 /*
2723 if ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 || 2571 * We set the time here so that in post-auth privsep slave we
2724 (r = cipher_set_keyiv(state->receive_context, ivin)) != 0) 2572 * count from the completion of the authentication.
2725 return r; 2573 */
2726 } else { 2574 state->rekey_time = monotime();
2727 if ((r = kex_from_blob(m, &ssh->kex)) != 0 || 2575 /* XXX ssh_set_newkeys overrides p_read.packets? XXX */
2728 (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || 2576 if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
2729 (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || 2577 (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
2730 (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 || 2578 return r;
2731 (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 || 2579
2732 (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
2733 (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
2734 (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
2735 (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
2736 (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
2737 (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
2738 (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
2739 (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
2740 return r;
2741 /*
2742 * We set the time here so that in post-auth privsep slave we
2743 * count from the completion of the authentication.
2744 */
2745 state->rekey_time = monotime();
2746 /* XXX ssh_set_newkeys overrides p_read.packets? XXX */
2747 if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
2748 (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
2749 return r;
2750 }
2751 if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || 2580 if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 ||
2752 (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) 2581 (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0)
2753 return r; 2582 return r;
@@ -2925,15 +2754,13 @@ sshpkt_ptr(struct ssh *ssh, size_t *lenp)
2925int 2754int
2926sshpkt_start(struct ssh *ssh, u_char type) 2755sshpkt_start(struct ssh *ssh, u_char type)
2927{ 2756{
2928 u_char buf[9]; 2757 u_char buf[6]; /* u32 packet length, u8 pad len, u8 type */
2929 int len;
2930 2758
2931 DBG(debug("packet_start[%d]", type)); 2759 DBG(debug("packet_start[%d]", type));
2932 len = compat20 ? 6 : 9; 2760 memset(buf, 0, sizeof(buf));
2933 memset(buf, 0, len - 1); 2761 buf[sizeof(buf) - 1] = type;
2934 buf[len - 1] = type;
2935 sshbuf_reset(ssh->state->outgoing_packet); 2762 sshbuf_reset(ssh->state->outgoing_packet);
2936 return sshbuf_put(ssh->state->outgoing_packet, buf, len); 2763 return sshbuf_put(ssh->state->outgoing_packet, buf, sizeof(buf));
2937} 2764}
2938 2765
2939static int 2766static int
@@ -2973,10 +2800,7 @@ sshpkt_send(struct ssh *ssh)
2973{ 2800{
2974 if (ssh->state && ssh->state->mux) 2801 if (ssh->state && ssh->state->mux)
2975 return ssh_packet_send_mux(ssh); 2802 return ssh_packet_send_mux(ssh);
2976 if (compat20) 2803 return ssh_packet_send2(ssh);
2977 return ssh_packet_send2(ssh);
2978 else
2979 return ssh_packet_send1(ssh);
2980} 2804}
2981 2805
2982int 2806int
@@ -2990,19 +2814,12 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...)
2990 vsnprintf(buf, sizeof(buf), fmt, args); 2814 vsnprintf(buf, sizeof(buf), fmt, args);
2991 va_end(args); 2815 va_end(args);
2992 2816
2993 if (compat20) { 2817 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
2994 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || 2818 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
2995 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || 2819 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
2996 (r = sshpkt_put_cstring(ssh, buf)) != 0 || 2820 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
2997 (r = sshpkt_put_cstring(ssh, "")) != 0 || 2821 (r = sshpkt_send(ssh)) != 0)
2998 (r = sshpkt_send(ssh)) != 0) 2822 return r;
2999 return r;
3000 } else {
3001 if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 ||
3002 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
3003 (r = sshpkt_send(ssh)) != 0)
3004 return r;
3005 }
3006 return 0; 2823 return 0;
3007} 2824}
3008 2825
diff --git a/packet.h b/packet.h
index 0d25b352c..a1a1990b0 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.h,v 1.76 2017/02/03 23:03:33 djm Exp $ */ 1/* $OpenBSD: packet.h,v 1.77 2017/04/30 23:13:25 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -112,7 +112,6 @@ int ssh_packet_set_log_preamble(struct ssh *, const char *, ...)
112 112
113int ssh_packet_log_type(u_char); 113int ssh_packet_log_type(u_char);
114 114
115int ssh_packet_send1(struct ssh *);
116int ssh_packet_send2_wrapped(struct ssh *); 115int ssh_packet_send2_wrapped(struct ssh *);
117int ssh_packet_send2(struct ssh *); 116int ssh_packet_send2(struct ssh *);
118 117
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index 3231ee342..6a9292487 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keyscan.c,v 1.110 2017/04/30 23:10:43 djm Exp $ */ 1/* $OpenBSD: ssh-keyscan.c,v 1.111 2017/04/30 23:13:25 djm Exp $ */
2/* 2/*
3 * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. 3 * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
4 * 4 *
@@ -221,7 +221,6 @@ keygrab_ssh2(con *c)
221 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; 221 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
222 int r; 222 int r;
223 223
224 enable_compat20();
225 switch (c->c_keytype) { 224 switch (c->c_keytype) {
226 case KT_DSA: 225 case KT_DSA:
227 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? 226 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
diff --git a/ssh.c b/ssh.c
index 766a1790d..a682ce91a 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.454 2017/04/30 23:11:45 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.455 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
@@ -209,7 +209,6 @@ usage(void)
209 exit(255); 209 exit(255);
210} 210}
211 211
212static int ssh_session(void);
213static int ssh_session2(void); 212static int ssh_session2(void);
214static void load_public_identity_files(void); 213static void load_public_identity_files(void);
215static void main_sigchld_handler(int); 214static void main_sigchld_handler(int);
@@ -1243,7 +1242,6 @@ main(int ac, char **av)
1243 if ((sock = muxclient(options.control_path)) >= 0) { 1242 if ((sock = muxclient(options.control_path)) >= 0) {
1244 packet_set_connection(sock, sock); 1243 packet_set_connection(sock, sock);
1245 ssh = active_state; /* XXX */ 1244 ssh = active_state; /* XXX */
1246 enable_compat20(); /* XXX */
1247 packet_set_mux(); 1245 packet_set_mux();
1248 goto skip_connect; 1246 goto skip_connect;
1249 } 1247 }
@@ -1447,7 +1445,7 @@ main(int ac, char **av)
1447 } 1445 }
1448 1446
1449 skip_connect: 1447 skip_connect:
1450 exit_status = compat20 ? ssh_session2() : ssh_session(); 1448 exit_status = ssh_session2();
1451 packet_close(); 1449 packet_close();
1452 1450
1453 if (options.control_path != NULL && muxserver_sock != -1) 1451 if (options.control_path != NULL && muxserver_sock != -1)
@@ -1591,8 +1589,6 @@ ssh_init_stdio_forwarding(void)
1591 1589
1592 if (options.stdio_forward_host == NULL) 1590 if (options.stdio_forward_host == NULL)
1593 return; 1591 return;
1594 if (!compat20)
1595 fatal("stdio forwarding require Protocol 2");
1596 1592
1597 debug3("%s: %s:%d", __func__, options.stdio_forward_host, 1593 debug3("%s: %s:%d", __func__, options.stdio_forward_host,
1598 options.stdio_forward_port); 1594 options.stdio_forward_port);
@@ -1691,172 +1687,6 @@ check_agent_present(void)
1691 } 1687 }
1692} 1688}
1693 1689
1694static int
1695ssh_session(void)
1696{
1697 int type;
1698 int interactive = 0;
1699 int have_tty = 0;
1700 struct winsize ws;
1701 char *cp;
1702 const char *display;
1703 char *proto = NULL, *data = NULL;
1704
1705 /* Enable compression if requested. */
1706 if (options.compression) {
1707 debug("Requesting compression at level %d.",
1708 options.compression_level);
1709
1710 if (options.compression_level < 1 ||
1711 options.compression_level > 9)
1712 fatal("Compression level must be from 1 (fast) to "
1713 "9 (slow, best).");
1714
1715 /* Send the request. */
1716 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
1717 packet_put_int(options.compression_level);
1718 packet_send();
1719 packet_write_wait();
1720 type = packet_read();
1721 if (type == SSH_SMSG_SUCCESS)
1722 packet_start_compression(options.compression_level);
1723 else if (type == SSH_SMSG_FAILURE)
1724 logit("Warning: Remote host refused compression.");
1725 else
1726 packet_disconnect("Protocol error waiting for "
1727 "compression response.");
1728 }
1729 /* Allocate a pseudo tty if appropriate. */
1730 if (tty_flag) {
1731 debug("Requesting pty.");
1732
1733 /* Start the packet. */
1734 packet_start(SSH_CMSG_REQUEST_PTY);
1735
1736 /* Store TERM in the packet. There is no limit on the
1737 length of the string. */
1738 cp = getenv("TERM");
1739 if (!cp)
1740 cp = "";
1741 packet_put_cstring(cp);
1742
1743 /* Store window size in the packet. */
1744 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
1745 memset(&ws, 0, sizeof(ws));
1746 packet_put_int((u_int)ws.ws_row);
1747 packet_put_int((u_int)ws.ws_col);
1748 packet_put_int((u_int)ws.ws_xpixel);
1749 packet_put_int((u_int)ws.ws_ypixel);
1750
1751 /* Store tty modes in the packet. */
1752 tty_make_modes(fileno(stdin), NULL);
1753
1754 /* Send the packet, and wait for it to leave. */
1755 packet_send();
1756 packet_write_wait();
1757
1758 /* Read response from the server. */
1759 type = packet_read();
1760 if (type == SSH_SMSG_SUCCESS) {
1761 interactive = 1;
1762 have_tty = 1;
1763 } else if (type == SSH_SMSG_FAILURE)
1764 logit("Warning: Remote host failed or refused to "
1765 "allocate a pseudo tty.");
1766 else
1767 packet_disconnect("Protocol error waiting for pty "
1768 "request response.");
1769 }
1770 /* Request X11 forwarding if enabled and DISPLAY is set. */
1771 display = getenv("DISPLAY");
1772 if (display == NULL && options.forward_x11)
1773 debug("X11 forwarding requested but DISPLAY not set");
1774 if (options.forward_x11 && client_x11_get_proto(display,
1775 options.xauth_location, options.forward_x11_trusted,
1776 options.forward_x11_timeout, &proto, &data) == 0) {
1777 /* Request forwarding with authentication spoofing. */
1778 debug("Requesting X11 forwarding with authentication "
1779 "spoofing.");
1780 x11_request_forwarding_with_spoofing(0, display, proto,
1781 data, 0);
1782 /* Read response from the server. */
1783 type = packet_read();
1784 if (type == SSH_SMSG_SUCCESS) {
1785 interactive = 1;
1786 } else if (type == SSH_SMSG_FAILURE) {
1787 logit("Warning: Remote host denied X11 forwarding.");
1788 } else {
1789 packet_disconnect("Protocol error waiting for X11 "
1790 "forwarding");
1791 }
1792 }
1793 /* Tell the packet module whether this is an interactive session. */
1794 packet_set_interactive(interactive,
1795 options.ip_qos_interactive, options.ip_qos_bulk);
1796
1797 /* Request authentication agent forwarding if appropriate. */
1798 check_agent_present();
1799
1800 if (options.forward_agent) {
1801 debug("Requesting authentication agent forwarding.");
1802 auth_request_forwarding();
1803
1804 /* Read response from the server. */
1805 type = packet_read();
1806 packet_check_eom();
1807 if (type != SSH_SMSG_SUCCESS)
1808 logit("Warning: Remote host denied authentication agent forwarding.");
1809 }
1810
1811 /* Initiate port forwardings. */
1812 ssh_init_stdio_forwarding();
1813 ssh_init_forwarding();
1814
1815 /* Execute a local command */
1816 if (options.local_command != NULL &&
1817 options.permit_local_command)
1818 ssh_local_cmd(options.local_command);
1819
1820 /*
1821 * If requested and we are not interested in replies to remote
1822 * forwarding requests, then let ssh continue in the background.
1823 */
1824 if (fork_after_authentication_flag) {
1825 if (options.exit_on_forward_failure &&
1826 options.num_remote_forwards > 0) {
1827 debug("deferring postauth fork until remote forward "
1828 "confirmation received");
1829 } else
1830 fork_postauth();
1831 }
1832
1833 /*
1834 * If a command was specified on the command line, execute the
1835 * command now. Otherwise request the server to start a shell.
1836 */
1837 if (buffer_len(&command) > 0) {
1838 int len = buffer_len(&command);
1839 if (len > 900)
1840 len = 900;
1841 debug("Sending command: %.*s", len,
1842 (u_char *)buffer_ptr(&command));
1843 packet_start(SSH_CMSG_EXEC_CMD);
1844 packet_put_string(buffer_ptr(&command), buffer_len(&command));
1845 packet_send();
1846 packet_write_wait();
1847 } else {
1848 debug("Requesting shell.");
1849 packet_start(SSH_CMSG_EXEC_SHELL);
1850 packet_send();
1851 packet_write_wait();
1852 }
1853
1854 /* Enter the interactive session. */
1855 return client_loop(have_tty, tty_flag ?
1856 options.escape_char : SSH_ESCAPECHAR_NONE, 0);
1857}
1858
1859/* request pty/x11/agent/tcpfwd/shell for channel */
1860static void 1690static void
1861ssh_session2_setup(int id, int success, void *arg) 1691ssh_session2_setup(int id, int success, void *arg)
1862{ 1692{
diff --git a/ssh_api.c b/ssh_api.c
index 2a9f1497c..c84b4e713 100644
--- a/ssh_api.c
+++ b/ssh_api.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh_api.c,v 1.7 2016/05/04 14:22:33 markus Exp $ */ 1/* $OpenBSD: ssh_api.c,v 1.8 2017/04/30 23:13:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2012 Markus Friedl. All rights reserved. 3 * Copyright (c) 2012 Markus Friedl. All rights reserved.
4 * 4 *
@@ -371,7 +371,6 @@ _ssh_read_banner(struct ssh *ssh, char **bannerp)
371 } 371 }
372 if (remote_major != 2) 372 if (remote_major != 2)
373 return SSH_ERR_PROTOCOL_MISMATCH; 373 return SSH_ERR_PROTOCOL_MISMATCH;
374 enable_compat20();
375 chop(buf); 374 chop(buf);
376 debug("Remote version string %.100s", buf); 375 debug("Remote version string %.100s", buf);
377 if ((*bannerp = strdup(buf)) == NULL) 376 if ((*bannerp = strdup(buf)) == NULL)
diff --git a/sshconnect.c b/sshconnect.c
index d48f2e06c..d01d2c82d 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.275 2017/04/30 23:11:45 djm Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.276 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
@@ -524,13 +524,8 @@ static void
524send_client_banner(int connection_out, int minor1) 524send_client_banner(int connection_out, int minor1)
525{ 525{
526 /* Send our own protocol version identification. */ 526 /* Send our own protocol version identification. */
527 if (compat20) { 527 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
528 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", 528 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
529 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
530 } else {
531 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n",
532 PROTOCOL_MAJOR_1, minor1, SSH_VERSION);
533 }
534 if (atomicio(vwrite, connection_out, client_version_string, 529 if (atomicio(vwrite, connection_out, client_version_string,
535 strlen(client_version_string)) != strlen(client_version_string)) 530 strlen(client_version_string)) != strlen(client_version_string))
536 fatal("write: %.100s", strerror(errno)); 531 fatal("write: %.100s", strerror(errno));
@@ -559,7 +554,6 @@ ssh_exchange_identification(int timeout_ms)
559 fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask); 554 fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
560 fdset = xcalloc(1, fdsetsz); 555 fdset = xcalloc(1, fdsetsz);
561 556
562 enable_compat20();
563 send_client_banner(connection_out, 0); 557 send_client_banner(connection_out, 0);
564 client_banner_sent = 1; 558 client_banner_sent = 1;
565 559
@@ -628,15 +622,12 @@ ssh_exchange_identification(int timeout_ms)
628 mismatch = 0; 622 mismatch = 0;
629 623
630 switch (remote_major) { 624 switch (remote_major) {
625 case 2:
626 break;
631 case 1: 627 case 1:
632 if (remote_minor == 99) 628 if (remote_minor != 99)
633 enable_compat20();
634 else
635 mismatch = 1; 629 mismatch = 1;
636 break; 630 break;
637 case 2:
638 enable_compat20();
639 break;
640 default: 631 default:
641 mismatch = 1; 632 mismatch = 1;
642 break; 633 break;
@@ -1243,8 +1234,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1243 host_key->cert->principals[i]); 1234 host_key->cert->principals[i]);
1244 } 1235 }
1245 } else { 1236 } else {
1246 debug("Server host key: %s %s", compat20 ? 1237 debug("Server host key: %s %s", sshkey_ssh_name(host_key), fp);
1247 sshkey_ssh_name(host_key) : sshkey_type(host_key), fp);
1248 } 1238 }
1249 1239
1250 if (sshkey_equal(previous_host_key, host_key)) { 1240 if (sshkey_equal(previous_host_key, host_key)) {
@@ -1349,12 +1339,8 @@ ssh_login(Sensitive *sensitive, const char *orighost,
1349 /* key exchange */ 1339 /* key exchange */
1350 /* authenticate user */ 1340 /* authenticate user */
1351 debug("Authenticating to %s:%d as '%s'", host, port, server_user); 1341 debug("Authenticating to %s:%d as '%s'", host, port, server_user);
1352 if (compat20) { 1342 ssh_kex2(host, hostaddr, port);
1353 ssh_kex2(host, hostaddr, port); 1343 ssh_userauth2(local_user, server_user, host, sensitive);
1354 ssh_userauth2(local_user, server_user, host, sensitive);
1355 } else {
1356 fatal("ssh1 is not supported");
1357 }
1358 free(local_user); 1344 free(local_user);
1359} 1345}
1360 1346
diff --git a/sshd.c b/sshd.c
index 197c4ec8e..d18da6bdf 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.485 2017/03/15 03:52:30 deraadt Exp $ */ 1/* $OpenBSD: sshd.c,v 1.486 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
@@ -450,10 +450,8 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
450 chop(server_version_string); 450 chop(server_version_string);
451 debug("Local version string %.200s", server_version_string); 451 debug("Local version string %.200s", server_version_string);
452 452
453 if (remote_major == 2 || 453 if (remote_major != 2 ||
454 (remote_major == 1 && remote_minor == 99)) { 454 (remote_major == 1 && remote_minor != 99)) {
455 enable_compat20();
456 } else {
457 s = "Protocol major versions differ.\n"; 455 s = "Protocol major versions differ.\n";
458 (void) atomicio(vwrite, sock_out, s, strlen(s)); 456 (void) atomicio(vwrite, sock_out, s, strlen(s));
459 close(sock_in); 457 close(sock_in);
diff --git a/ttymodes.c b/ttymodes.c
index db772c39c..2fc783b2f 100644
--- a/ttymodes.c
+++ b/ttymodes.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ttymodes.c,v 1.30 2016/05/04 14:22:33 markus Exp $ */ 1/* $OpenBSD: ttymodes.c,v 1.31 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
@@ -283,18 +283,10 @@ tty_make_modes(int fd, struct termios *tiop)
283 int baud; 283 int baud;
284 Buffer buf; 284 Buffer buf;
285 int tty_op_ospeed, tty_op_ispeed; 285 int tty_op_ospeed, tty_op_ispeed;
286 void (*put_arg)(Buffer *, u_int);
287 286
288 buffer_init(&buf); 287 buffer_init(&buf);
289 if (compat20) { 288 tty_op_ospeed = TTY_OP_OSPEED_PROTO2;
290 tty_op_ospeed = TTY_OP_OSPEED_PROTO2; 289 tty_op_ispeed = TTY_OP_ISPEED_PROTO2;
291 tty_op_ispeed = TTY_OP_ISPEED_PROTO2;
292 put_arg = buffer_put_int;
293 } else {
294 tty_op_ospeed = TTY_OP_OSPEED_PROTO1;
295 tty_op_ispeed = TTY_OP_ISPEED_PROTO1;
296 put_arg = (void (*)(Buffer *, u_int)) buffer_put_char;
297 }
298 290
299 if (tiop == NULL) { 291 if (tiop == NULL) {
300 if (fd == -1) { 292 if (fd == -1) {
@@ -319,11 +311,11 @@ tty_make_modes(int fd, struct termios *tiop)
319 /* Store values of mode flags. */ 311 /* Store values of mode flags. */
320#define TTYCHAR(NAME, OP) \ 312#define TTYCHAR(NAME, OP) \
321 buffer_put_char(&buf, OP); \ 313 buffer_put_char(&buf, OP); \
322 put_arg(&buf, special_char_encode(tio.c_cc[NAME])); 314 buffer_put_int(&buf, special_char_encode(tio.c_cc[NAME]));
323 315
324#define TTYMODE(NAME, FIELD, OP) \ 316#define TTYMODE(NAME, FIELD, OP) \
325 buffer_put_char(&buf, OP); \ 317 buffer_put_char(&buf, OP); \
326 put_arg(&buf, ((tio.FIELD & NAME) != 0)); 318 buffer_put_int(&buf, ((tio.FIELD & NAME) != 0));
327 319
328#include "ttymodes.h" 320#include "ttymodes.h"
329 321
@@ -333,10 +325,7 @@ tty_make_modes(int fd, struct termios *tiop)
333end: 325end:
334 /* Mark end of mode data. */ 326 /* Mark end of mode data. */
335 buffer_put_char(&buf, TTY_OP_END); 327 buffer_put_char(&buf, TTY_OP_END);
336 if (compat20) 328 packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
337 packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
338 else
339 packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
340 buffer_free(&buf); 329 buffer_free(&buf);
341} 330}
342 331
@@ -351,19 +340,10 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
351 int opcode, baud; 340 int opcode, baud;
352 int n_bytes = 0; 341 int n_bytes = 0;
353 int failure = 0; 342 int failure = 0;
354 u_int (*get_arg)(void); 343
355 int arg_size; 344 *n_bytes_ptr = packet_get_int();
356 345 if (*n_bytes_ptr == 0)
357 if (compat20) { 346 return;
358 *n_bytes_ptr = packet_get_int();
359 if (*n_bytes_ptr == 0)
360 return;
361 get_arg = packet_get_int;
362 arg_size = 4;
363 } else {
364 get_arg = packet_get_char;
365 arg_size = 1;
366 }
367 347
368 /* 348 /*
369 * Get old attributes for the terminal. We will modify these 349 * Get old attributes for the terminal. We will modify these
@@ -404,13 +384,13 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
404 384
405#define TTYCHAR(NAME, OP) \ 385#define TTYCHAR(NAME, OP) \
406 case OP: \ 386 case OP: \
407 n_bytes += arg_size; \ 387 n_bytes += 4; \
408 tio.c_cc[NAME] = special_char_decode(get_arg()); \ 388 tio.c_cc[NAME] = special_char_decode(packet_get_int()); \
409 break; 389 break;
410#define TTYMODE(NAME, FIELD, OP) \ 390#define TTYMODE(NAME, FIELD, OP) \
411 case OP: \ 391 case OP: \
412 n_bytes += arg_size; \ 392 n_bytes += 4; \
413 if (get_arg()) \ 393 if (packet_get_int()) \
414 tio.FIELD |= NAME; \ 394 tio.FIELD |= NAME; \
415 else \ 395 else \
416 tio.FIELD &= ~NAME; \ 396 tio.FIELD &= ~NAME; \
@@ -424,51 +404,21 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
424 default: 404 default:
425 debug("Ignoring unsupported tty mode opcode %d (0x%x)", 405 debug("Ignoring unsupported tty mode opcode %d (0x%x)",
426 opcode, opcode); 406 opcode, opcode);
427 if (!compat20) { 407 /*
428 /* 408 * SSH2:
429 * SSH1: 409 * Opcodes 1 to 159 are defined to have a uint32
430 * Opcodes 1 to 127 are defined to have 410 * argument.
431 * a one-byte argument. 411 * Opcodes 160 to 255 are undefined and cause parsing
432 * Opcodes 128 to 159 are defined to have 412 * to stop.
433 * an integer argument. 413 */
434 */ 414 if (opcode > 0 && opcode < 160) {
435 if (opcode > 0 && opcode < 128) { 415 n_bytes += 4;
436 n_bytes += 1; 416 (void) packet_get_int();
437 (void) packet_get_char(); 417 break;
438 break;
439 } else if (opcode >= 128 && opcode < 160) {
440 n_bytes += 4;
441 (void) packet_get_int();
442 break;
443 } else {
444 /*
445 * It is a truly undefined opcode (160 to 255).
446 * We have no idea about its arguments. So we
447 * must stop parsing. Note that some data
448 * may be left in the packet; hopefully there
449 * is nothing more coming after the mode data.
450 */
451 logit("parse_tty_modes: unknown opcode %d",
452 opcode);
453 goto set;
454 }
455 } else { 418 } else {
456 /* 419 logit("parse_tty_modes: unknown opcode %d",
457 * SSH2: 420 opcode);
458 * Opcodes 1 to 159 are defined to have 421 goto set;
459 * a uint32 argument.
460 * Opcodes 160 to 255 are undefined and
461 * cause parsing to stop.
462 */
463 if (opcode > 0 && opcode < 160) {
464 n_bytes += 4;
465 (void) packet_get_int();
466 break;
467 } else {
468 logit("parse_tty_modes: unknown opcode %d",
469 opcode);
470 goto set;
471 }
472 } 422 }
473 } 423 }
474 } 424 }