summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-04-30 10:00:53 +1000
committerDamien Miller <djm@mindrot.org>2000-04-30 10:00:53 +1000
commitbd483e76909905f28d1604125f70c7cf8271f66e (patch)
tree4363a925d1f530b444c5726601ecf9efc684c218 /channels.c
parentc998f9eb7cfb3bfef8c78b0a47bdb6db29a871e8 (diff)
- More OpenBSD updates:
[session.c] - don't call chan_write_failed() if we are not writing [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c] - keysize warnings error() -> log()
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c211
1 files changed, 126 insertions, 85 deletions
diff --git a/channels.c b/channels.c
index a0091586b..1f9b515c3 100644
--- a/channels.c
+++ b/channels.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19#include "includes.h" 19#include "includes.h"
20RCSID("$Id: channels.c,v 1.26 2000/04/19 06:26:13 damien Exp $"); 20RCSID("$Id: channels.c,v 1.27 2000/04/30 00:00:53 damien Exp $");
21 21
22#include "ssh.h" 22#include "ssh.h"
23#include "packet.h" 23#include "packet.h"
@@ -40,9 +40,11 @@ RCSID("$Id: channels.c,v 1.26 2000/04/19 06:26:13 damien Exp $");
40/* Max len of agent socket */ 40/* Max len of agent socket */
41#define MAX_SOCKET_NAME 100 41#define MAX_SOCKET_NAME 100
42 42
43/* default buffer for tcp-fwd-channel */ 43/* default window/packet sizes for tcp/x11-fwd-channel */
44#define CHAN_WINDOW_DEFAULT (8*1024) 44#define CHAN_TCP_WINDOW_DEFAULT (8*1024)
45#define CHAN_PACKET_DEFAULT (CHAN_WINDOW_DEFAULT/2) 45#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2)
46#define CHAN_X11_WINDOW_DEFAULT (4*1024)
47#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2)
46 48
47/* 49/*
48 * Pointer to an array containing all allocated channels. The array is 50 * Pointer to an array containing all allocated channels. The array is
@@ -204,17 +206,15 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
204 c->self = found; 206 c->self = found;
205 c->type = type; 207 c->type = type;
206 c->ctype = ctype; 208 c->ctype = ctype;
207 c->local_window = window;
208 c->local_window_max = window;
209 c->local_consumed = 0;
210 c->local_maxpacket = maxpack;
211 c->remote_window = 0;
212 c->remote_maxpacket = 0;
213 c->rfd = rfd; 209 c->rfd = rfd;
214 c->wfd = wfd; 210 c->wfd = wfd;
215 c->sock = (rfd == wfd) ? rfd : -1; 211 c->sock = (rfd == wfd) ? rfd : -1;
216 c->efd = efd; 212 c->efd = efd;
217 c->extended_usage = extended_usage; 213 c->extended_usage = extended_usage;
214 c->local_window = window;
215 c->local_window_max = window;
216 c->local_consumed = 0;
217 c->local_maxpacket = maxpack;
218 c->remote_id = -1; 218 c->remote_id = -1;
219 c->remote_name = remote_name; 219 c->remote_name = remote_name;
220 c->remote_window = 0; 220 c->remote_window = 0;
@@ -371,6 +371,7 @@ channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
371 * state until the first packet has been completely read. The authentication 371 * state until the first packet has been completely read. The authentication
372 * data in that packet is then substituted by the real data if it matches the 372 * data in that packet is then substituted by the real data if it matches the
373 * fake data, and the channel is put into normal mode. 373 * fake data, and the channel is put into normal mode.
374 * XXX All this happens at the client side.
374 */ 375 */
375int 376int
376x11_open_helper(Channel *c) 377x11_open_helper(Channel *c)
@@ -456,7 +457,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
456} 457}
457 458
458void 459void
459channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset) 460channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
460{ 461{
461 int ret = x11_open_helper(c); 462 int ret = x11_open_helper(c);
462 if (ret == 1) { 463 if (ret == 1) {
@@ -464,7 +465,7 @@ channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset)
464 channel_pre_open_15(c, readset, writeset); 465 channel_pre_open_15(c, readset, writeset);
465 } else if (ret == -1) { 466 } else if (ret == -1) {
466 debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); 467 debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
467 chan_read_failed(c); 468 chan_read_failed(c); /** force close? */
468 chan_write_failed(c); 469 chan_write_failed(c);
469 debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); 470 debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
470 } 471 }
@@ -478,6 +479,7 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
478 int newsock, newch; 479 int newsock, newch;
479 socklen_t addrlen; 480 socklen_t addrlen;
480 char buf[16384], *remote_hostname; 481 char buf[16384], *remote_hostname;
482 int remote_port;
481 483
482 if (FD_ISSET(c->sock, readset)) { 484 if (FD_ISSET(c->sock, readset)) {
483 debug("X11 connection requested."); 485 debug("X11 connection requested.");
@@ -488,16 +490,32 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
488 return; 490 return;
489 } 491 }
490 remote_hostname = get_remote_hostname(newsock); 492 remote_hostname = get_remote_hostname(newsock);
493 remote_port = get_peer_port(newsock);
491 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", 494 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
492 remote_hostname, get_peer_port(newsock)); 495 remote_hostname, remote_port);
496
497 newch = channel_new("x11",
498 SSH_CHANNEL_OPENING, newsock, newsock, -1,
499 c->local_window_max, c->local_maxpacket,
500 0, xstrdup(buf));
501 if (compat20) {
502 packet_start(SSH2_MSG_CHANNEL_OPEN);
503 packet_put_cstring("x11");
504 packet_put_int(newch);
505 packet_put_int(c->local_window_max);
506 packet_put_int(c->local_maxpacket);
507 /* originator host and port */
508 packet_put_cstring(remote_hostname);
509 packet_put_int(remote_port);
510 packet_send();
511 } else {
512 packet_start(SSH_SMSG_X11_OPEN);
513 packet_put_int(newch);
514 if (have_hostname_in_open)
515 packet_put_string(buf, strlen(buf));
516 packet_send();
517 }
493 xfree(remote_hostname); 518 xfree(remote_hostname);
494 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
495 xstrdup(buf));
496 packet_start(SSH_SMSG_X11_OPEN);
497 packet_put_int(newch);
498 if (have_hostname_in_open)
499 packet_put_string(buf, strlen(buf));
500 packet_send();
501 } 519 }
502} 520}
503 521
@@ -597,7 +615,7 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
597 FD_ISSET(c->rfd, readset)) { 615 FD_ISSET(c->rfd, readset)) {
598 len = read(c->rfd, buf, sizeof(buf)); 616 len = read(c->rfd, buf, sizeof(buf));
599 if (len <= 0) { 617 if (len <= 0) {
600 debug("channel %d: read<0 rfd %d len %d", 618 debug("channel %d: read<=0 rfd %d len %d",
601 c->self, c->rfd, len); 619 c->self, c->rfd, len);
602 if (compat13) { 620 if (compat13) {
603 buffer_consume(&c->output, buffer_len(&c->output)); 621 buffer_consume(&c->output, buffer_len(&c->output));
@@ -729,10 +747,13 @@ void
729channel_handler_init_20(void) 747channel_handler_init_20(void)
730{ 748{
731 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; 749 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20;
750 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
732 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; 751 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
752 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
733 753
734 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; 754 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2;
735 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; 755 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
756 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
736} 757}
737 758
738void 759void
@@ -757,7 +778,7 @@ void
757channel_handler_init_15(void) 778channel_handler_init_15(void)
758{ 779{
759 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15; 780 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15;
760 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_15; 781 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
761 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; 782 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
762 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; 783 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
763 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; 784 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
@@ -1428,7 +1449,7 @@ channel_request_local_forwarding(u_short port, const char *host,
1428 ch = channel_new( 1449 ch = channel_new(
1429 "port listener", SSH_CHANNEL_PORT_LISTENER, 1450 "port listener", SSH_CHANNEL_PORT_LISTENER,
1430 sock, sock, -1, 1451 sock, sock, -1,
1431 CHAN_WINDOW_DEFAULT, CHAN_PACKET_DEFAULT, 1452 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1432 0, xstrdup("port listener")); 1453 0, xstrdup("port listener"));
1433 strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); 1454 strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
1434 channels[ch].host_port = host_port; 1455 channels[ch].host_port = host_port;
@@ -1769,8 +1790,10 @@ x11_create_display_inet(int screen_number, int x11_display_offset)
1769 /* Allocate a channel for each socket. */ 1790 /* Allocate a channel for each socket. */
1770 for (n = 0; n < num_socks; n++) { 1791 for (n = 0; n < num_socks; n++) {
1771 sock = socks[n]; 1792 sock = socks[n];
1772 (void) channel_allocate(SSH_CHANNEL_X11_LISTENER, sock, 1793 (void) channel_new("x11 listener",
1773 xstrdup("X11 inet listener")); 1794 SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
1795 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
1796 0, xstrdup("X11 inet listener"));
1774 } 1797 }
1775 1798
1776 /* Return a suitable value for the DISPLAY environment variable. */ 1799 /* Return a suitable value for the DISPLAY environment variable. */
@@ -1810,44 +1833,21 @@ connect_local_xsocket(unsigned int dnr)
1810 return -1; 1833 return -1;
1811} 1834}
1812 1835
1813 1836int
1814/* 1837x11_connect_display(void)
1815 * This is called when SSH_SMSG_X11_OPEN is received. The packet contains
1816 * the remote channel number. We should do whatever we want, and respond
1817 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
1818 */
1819
1820void
1821x11_input_open(int type, int plen)
1822{ 1838{
1823 int remote_channel, display_number, sock = 0, newch; 1839 int display_number, sock = 0;
1824 const char *display; 1840 const char *display;
1825 char buf[1024], *cp, *remote_host; 1841 char buf[1024], *cp;
1826 unsigned int remote_len;
1827 struct addrinfo hints, *ai, *aitop; 1842 struct addrinfo hints, *ai, *aitop;
1828 char strport[NI_MAXSERV]; 1843 char strport[NI_MAXSERV];
1829 int gaierr; 1844 int gaierr;
1830 1845
1831 /* Get remote channel number. */
1832 remote_channel = packet_get_int();
1833
1834 /* Get remote originator name. */
1835 if (have_hostname_in_open) {
1836 remote_host = packet_get_string(&remote_len);
1837 remote_len += 4;
1838 } else {
1839 remote_host = xstrdup("unknown (remote did not supply name)");
1840 remote_len = 0;
1841 }
1842
1843 debug("Received X11 open request.");
1844 packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN);
1845
1846 /* Try to open a socket for the local X server. */ 1846 /* Try to open a socket for the local X server. */
1847 display = getenv("DISPLAY"); 1847 display = getenv("DISPLAY");
1848 if (!display) { 1848 if (!display) {
1849 error("DISPLAY not set."); 1849 error("DISPLAY not set.");
1850 goto fail; 1850 return -1;
1851 } 1851 }
1852 /* 1852 /*
1853 * Now we decode the value of the DISPLAY variable and make a 1853 * Now we decode the value of the DISPLAY variable and make a
@@ -1864,15 +1864,15 @@ x11_input_open(int type, int plen)
1864 if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) { 1864 if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
1865 error("Could not parse display number from DISPLAY: %.100s", 1865 error("Could not parse display number from DISPLAY: %.100s",
1866 display); 1866 display);
1867 goto fail; 1867 return -1;
1868 } 1868 }
1869 /* Create a socket. */ 1869 /* Create a socket. */
1870 sock = connect_local_xsocket(display_number); 1870 sock = connect_local_xsocket(display_number);
1871 if (sock < 0) 1871 if (sock < 0)
1872 goto fail; 1872 return -1;
1873 1873
1874 /* OK, we now have a connection to the display. */ 1874 /* OK, we now have a connection to the display. */
1875 goto success; 1875 return sock;
1876 } 1876 }
1877 /* 1877 /*
1878 * Connect to an inet socket. The DISPLAY value is supposedly 1878 * Connect to an inet socket. The DISPLAY value is supposedly
@@ -1883,14 +1883,14 @@ x11_input_open(int type, int plen)
1883 cp = strchr(buf, ':'); 1883 cp = strchr(buf, ':');
1884 if (!cp) { 1884 if (!cp) {
1885 error("Could not find ':' in DISPLAY: %.100s", display); 1885 error("Could not find ':' in DISPLAY: %.100s", display);
1886 goto fail; 1886 return -1;
1887 } 1887 }
1888 *cp = 0; 1888 *cp = 0;
1889 /* buf now contains the host name. But first we parse the display number. */ 1889 /* buf now contains the host name. But first we parse the display number. */
1890 if (sscanf(cp + 1, "%d", &display_number) != 1) { 1890 if (sscanf(cp + 1, "%d", &display_number) != 1) {
1891 error("Could not parse display number from DISPLAY: %.100s", 1891 error("Could not parse display number from DISPLAY: %.100s",
1892 display); 1892 display);
1893 goto fail; 1893 return -1;
1894 } 1894 }
1895 1895
1896 /* Look up the host address */ 1896 /* Look up the host address */
@@ -1900,7 +1900,7 @@ x11_input_open(int type, int plen)
1900 snprintf(strport, sizeof strport, "%d", 6000 + display_number); 1900 snprintf(strport, sizeof strport, "%d", 6000 + display_number);
1901 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { 1901 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
1902 error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); 1902 error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
1903 goto fail; 1903 return -1;
1904 } 1904 }
1905 for (ai = aitop; ai; ai = ai->ai_next) { 1905 for (ai = aitop; ai; ai = ai->ai_next) {
1906 /* Create a socket. */ 1906 /* Create a socket. */
@@ -1923,31 +1923,60 @@ x11_input_open(int type, int plen)
1923 if (!ai) { 1923 if (!ai) {
1924 error("connect %.100s port %d: %.100s", buf, 6000 + display_number, 1924 error("connect %.100s port %d: %.100s", buf, 6000 + display_number,
1925 strerror(errno)); 1925 strerror(errno));
1926 goto fail; 1926 return -1;
1927 } 1927 }
1928success: 1928 return sock;
1929 /* We have successfully obtained a connection to the real X display. */ 1929}
1930 1930
1931 /* Allocate a channel for this connection. */ 1931/*
1932 if (x11_saved_proto == NULL) 1932 * This is called when SSH_SMSG_X11_OPEN is received. The packet contains
1933 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, remote_host); 1933 * the remote channel number. We should do whatever we want, and respond
1934 else 1934 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
1935 newch = channel_allocate(SSH_CHANNEL_X11_OPEN, sock, remote_host); 1935 */
1936 channels[newch].remote_id = remote_channel;
1937 1936
1938 /* Send a confirmation to the remote host. */ 1937void
1939 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 1938x11_input_open(int type, int plen)
1940 packet_put_int(remote_channel); 1939{
1941 packet_put_int(newch); 1940 int remote_channel, sock = 0, newch;
1942 packet_send(); 1941 char *remote_host;
1942 unsigned int remote_len;
1943 1943
1944 return; 1944 /* Get remote channel number. */
1945 remote_channel = packet_get_int();
1945 1946
1946fail: 1947 /* Get remote originator name. */
1947 /* Send refusal to the remote host. */ 1948 if (have_hostname_in_open) {
1948 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 1949 remote_host = packet_get_string(&remote_len);
1949 packet_put_int(remote_channel); 1950 remote_len += 4;
1950 packet_send(); 1951 } else {
1952 remote_host = xstrdup("unknown (remote did not supply name)");
1953 remote_len = 0;
1954 }
1955
1956 debug("Received X11 open request.");
1957 packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN);
1958
1959 /* Obtain a connection to the real X display. */
1960 sock = x11_connect_display();
1961 if (sock == -1) {
1962 /* Send refusal to the remote host. */
1963 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1964 packet_put_int(remote_channel);
1965 packet_send();
1966 } else {
1967 /* Allocate a channel for this connection. */
1968 newch = channel_allocate(
1969 (x11_saved_proto == NULL) ?
1970 SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN,
1971 sock, remote_host);
1972 channels[newch].remote_id = remote_channel;
1973
1974 /* Send a confirmation to the remote host. */
1975 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1976 packet_put_int(remote_channel);
1977 packet_put_int(newch);
1978 packet_send();
1979 }
1951} 1980}
1952 1981
1953/* 1982/*
@@ -1956,7 +1985,8 @@ fail:
1956 */ 1985 */
1957 1986
1958void 1987void
1959x11_request_forwarding_with_spoofing(const char *proto, const char *data) 1988x11_request_forwarding_with_spoofing(int client_session_id,
1989 const char *proto, const char *data)
1960{ 1990{
1961 unsigned int data_len = (unsigned int) strlen(data) / 2; 1991 unsigned int data_len = (unsigned int) strlen(data) / 2;
1962 unsigned int i, value; 1992 unsigned int i, value;
@@ -2002,9 +2032,14 @@ x11_request_forwarding_with_spoofing(const char *proto, const char *data)
2002 sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]); 2032 sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]);
2003 2033
2004 /* Send the request packet. */ 2034 /* Send the request packet. */
2005 packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); 2035 if (compat20) {
2006 packet_put_string(proto, strlen(proto)); 2036 channel_request_start(client_session_id, "x11-req", 0);
2007 packet_put_string(new_data, strlen(new_data)); 2037 packet_put_char(0); /* XXX bool single connection */
2038 } else {
2039 packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
2040 }
2041 packet_put_cstring(proto);
2042 packet_put_cstring(new_data);
2008 packet_put_int(screen_number); 2043 packet_put_int(screen_number);
2009 packet_send(); 2044 packet_send();
2010 packet_write_wait(); 2045 packet_write_wait();
@@ -2154,20 +2189,26 @@ auth_input_open_request(int type, int plen)
2154} 2189}
2155 2190
2156void 2191void
2157channel_open(int id) 2192channel_start_open(int id)
2158{ 2193{
2159 Channel *c = channel_lookup(id); 2194 Channel *c = channel_lookup(id);
2160 if (c == NULL) { 2195 if (c == NULL) {
2161 log("channel_open: %d: bad id", id); 2196 log("channel_open: %d: bad id", id);
2162 return; 2197 return;
2163 } 2198 }
2199 debug("send channel open %d", id);
2164 packet_start(SSH2_MSG_CHANNEL_OPEN); 2200 packet_start(SSH2_MSG_CHANNEL_OPEN);
2165 packet_put_cstring(c->ctype); 2201 packet_put_cstring(c->ctype);
2166 packet_put_int(c->self); 2202 packet_put_int(c->self);
2167 packet_put_int(c->local_window); 2203 packet_put_int(c->local_window);
2168 packet_put_int(c->local_maxpacket); 2204 packet_put_int(c->local_maxpacket);
2205}
2206void
2207channel_open(int id)
2208{
2209 /* XXX REMOVE ME */
2210 channel_start_open(id);
2169 packet_send(); 2211 packet_send();
2170 debug("channel open %d", id);
2171} 2212}
2172void 2213void
2173channel_request(int id, char *service, int wantconfirm) 2214channel_request(int id, char *service, int wantconfirm)