summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--README.openssh222
-rw-r--r--auth-rsa.c3
-rw-r--r--auth1.c6
-rw-r--r--authfd.c6
-rw-r--r--channels.c211
-rw-r--r--channels.h7
-rw-r--r--clientloop.c67
-rw-r--r--hostfile.c6
-rw-r--r--session.c91
-rw-r--r--ssh-agent.c6
-rw-r--r--ssh.c102
12 files changed, 368 insertions, 164 deletions
diff --git a/ChangeLog b/ChangeLog
index d5c698b01..ae6348c5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,11 @@
8 - Changed entropy seed code to user per-user seeds only (server seed is 8 - Changed entropy seed code to user per-user seeds only (server seed is
9 saved in root's .ssh directory) 9 saved in root's .ssh directory)
10 - Use atexit() and fatal cleanups to save seed on exit 10 - Use atexit() and fatal cleanups to save seed on exit
11 - More OpenBSD updates:
12 [session.c]
13 - don't call chan_write_failed() if we are not writing
14 [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c]
15 - keysize warnings error() -> log()
11 16
1220000429 1720000429
13 - Merge big update to OpenSSH-2.0 from OpenBSD CVS 18 - Merge big update to OpenSSH-2.0 from OpenBSD CVS
diff --git a/README.openssh2 b/README.openssh2
index fca3173ae..36d3de6ef 100644
--- a/README.openssh2
+++ b/README.openssh2
@@ -1,4 +1,4 @@
1$Id: README.openssh2,v 1.6 2000/04/27 13:42:58 provos Exp $ 1$Id: README.openssh2,v 1.4 2000/04/29 13:57:09 damien Exp $
2 2
3howto: 3howto:
4 1) generate server key: 4 1) generate server key:
@@ -6,7 +6,8 @@ howto:
6 2) enable ssh2: 6 2) enable ssh2:
7 server: add 'Protocol 2,1' to /etc/sshd_config 7 server: add 'Protocol 2,1' to /etc/sshd_config
8 client: ssh -o 'Protocol 2,1', or add to .ssh/config 8 client: ssh -o 'Protocol 2,1', or add to .ssh/config
9 3) interop w/ ssh.com dsa-keys: 9 3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2)
10 interop w/ ssh.com dsa-keys:
10 ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2 11 ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2
11 and vice versa 12 and vice versa
12 ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub 13 ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub
@@ -18,21 +19,20 @@ works:
18 encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc 19 encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc
19 mac: hmac-md5, hmac-sha1, (hmac-ripemd160) 20 mac: hmac-md5, hmac-sha1, (hmac-ripemd160)
20 compression: zlib, none 21 compression: zlib, none
21 secsh-userauth: passwd only 22 secsh-userauth: passwd and pubkey with DSA
22 secsh-connection: pty+shell or command, flow control works (window adjust) 23 secsh-connection: pty+shell or command, flow control works (window adjust)
23 tcp-forwarding: -L works 24 tcp-forwarding: -L works, -R incomplete
24 dss: verification works, 25 x11-fwd
25 key database in ~/.ssh/known_hosts with bits == 0 hack 26 dss/dsa: host key database in ~/.ssh/known_hosts2
26 dss: signature works, keygen w/ openssl
27 client interops w/ sshd2, lshd 27 client interops w/ sshd2, lshd
28 server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0 28 server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0
29 server supports multiple concurrent sessions (e.g. with SSH.com Windows client) 29 server supports multiple concurrent sessions (e.g. with SSH.com Windows client)
30todo: 30todo:
31 re-keying 31 re-keying
32 secsh-connection features: 32 secsh-connection features:
33 tcp-forwarding, agent-fwd, x11-fwd 33 tcp-forwarding, agent-fwd
34 auth other than passwd: 34 auth other than passwd, and DSA-pubkey:
35 pubkey, keyboard-interactive 35 keyboard-interactive, (PGP-pubkey?)
36 config 36 config
37 server-auth w/ old host-keys 37 server-auth w/ old host-keys
38 cleanup 38 cleanup
@@ -41,4 +41,4 @@ todo:
41 sftp 41 sftp
42 42
43-markus 43-markus
44$Date: 2000/04/27 13:42:58 $ 44$Date: 2000/04/29 13:57:09 $
diff --git a/auth-rsa.c b/auth-rsa.c
index c61eab29a..22e3f01f3 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: auth-rsa.c,v 1.18 2000/04/29 13:57:09 damien Exp $"); 19RCSID("$Id: auth-rsa.c,v 1.19 2000/04/30 00:00:53 damien Exp $");
20 20
21#include "rsa.h" 21#include "rsa.h"
22#include "packet.h" 22#include "packet.h"
@@ -256,7 +256,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
256 256
257 /* We have found the desired key. */ 257 /* We have found the desired key. */
258 258
259
260 /* Perform the challenge-response dialog for this key. */ 259 /* Perform the challenge-response dialog for this key. */
261 if (!auth_rsa_challenge_dialog(pk)) { 260 if (!auth_rsa_challenge_dialog(pk)) {
262 /* Wrong response. */ 261 /* Wrong response. */
diff --git a/auth1.c b/auth1.c
index ae5f1cd84..dedf898e9 100644
--- a/auth1.c
+++ b/auth1.c
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6#include "includes.h" 6#include "includes.h"
7RCSID("$OpenBSD: auth1.c,v 1.1 2000/04/26 21:28:32 markus Exp $"); 7RCSID("$OpenBSD: auth1.c,v 1.2 2000/04/29 18:11:52 markus Exp $");
8 8
9#include "xmalloc.h" 9#include "xmalloc.h"
10#include "rsa.h" 10#include "rsa.h"
@@ -262,8 +262,8 @@ do_authloop(struct passwd * pw)
262 packet_get_bignum(client_host_key->n, &nlen); 262 packet_get_bignum(client_host_key->n, &nlen);
263 263
264 if (bits != BN_num_bits(client_host_key->n)) 264 if (bits != BN_num_bits(client_host_key->n))
265 error("Warning: keysize mismatch for client_host_key: " 265 log("Warning: keysize mismatch for client_host_key: "
266 "actual %d, announced %d", BN_num_bits(client_host_key->n), bits); 266 "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
267 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); 267 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
268 268
269 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key); 269 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
diff --git a/authfd.c b/authfd.c
index 3476e799a..36b4d6ce4 100644
--- a/authfd.c
+++ b/authfd.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: authfd.c,v 1.13 2000/04/16 02:31:49 damien Exp $"); 17RCSID("$Id: authfd.c,v 1.14 2000/04/30 00:00:53 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "rsa.h" 20#include "rsa.h"
@@ -217,8 +217,8 @@ ssh_get_next_identity(AuthenticationConnection *auth,
217 *comment = buffer_get_string(&auth->identities, NULL); 217 *comment = buffer_get_string(&auth->identities, NULL);
218 218
219 if (bits != BN_num_bits(n)) 219 if (bits != BN_num_bits(n))
220 error("Warning: identity keysize mismatch: actual %d, announced %u", 220 log("Warning: identity keysize mismatch: actual %d, announced %u",
221 BN_num_bits(n), bits); 221 BN_num_bits(n), bits);
222 222
223 /* Decrement the number of remaining entries. */ 223 /* Decrement the number of remaining entries. */
224 auth->howmany--; 224 auth->howmany--;
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)
diff --git a/channels.h b/channels.h
index cab796440..263934265 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* RCSID("$Id: channels.h,v 1.7 2000/04/16 01:18:41 damien Exp $"); */ 1/* RCSID("$Id: channels.h,v 1.8 2000/04/30 00:00:54 damien Exp $"); */
2 2
3#ifndef CHANNELS_H 3#ifndef CHANNELS_H
4#define CHANNELS_H 4#define CHANNELS_H
@@ -207,7 +207,9 @@ void x11_request_forwarding(void);
207 * Requests forwarding for X11 connections, with authentication spoofing. 207 * Requests forwarding for X11 connections, with authentication spoofing.
208 * This should be called in the client only. 208 * This should be called in the client only.
209 */ 209 */
210void x11_request_forwarding_with_spoofing(const char *proto, const char *data); 210void
211x11_request_forwarding_with_spoofing(int client_session_id,
212 const char *proto, const char *data);
211 213
212/* Sends a message to the server to request authentication fd forwarding. */ 214/* Sends a message to the server to request authentication fd forwarding. */
213void auth_request_forwarding(void); 215void auth_request_forwarding(void);
@@ -230,5 +232,6 @@ void auth_input_open_request(int type, int plen);
230 232
231/* XXX */ 233/* XXX */
232int channel_connect_to(const char *host, u_short host_port); 234int channel_connect_to(const char *host, u_short host_port);
235int x11_connect_display(void);
233 236
234#endif 237#endif
diff --git a/clientloop.c b/clientloop.c
index 0296dac77..0ee9fc32a 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: clientloop.c,v 1.12 2000/04/19 21:42:21 damien Exp $"); 19RCSID("$Id: clientloop.c,v 1.13 2000/04/30 00:00:54 damien Exp $");
20 20
21#include "xmalloc.h" 21#include "xmalloc.h"
22#include "ssh.h" 22#include "ssh.h"
@@ -954,6 +954,69 @@ client_input_exit_status(int type, int plen)
954 quit_pending = 1; 954 quit_pending = 1;
955} 955}
956 956
957/* XXXX move to generic input handler */
958void
959client_input_channel_open(int type, int plen)
960{
961 Channel *c = NULL;
962 char *ctype;
963 int id;
964 unsigned int len;
965 int rchan;
966 int rmaxpack;
967 int rwindow;
968
969 ctype = packet_get_string(&len);
970 rchan = packet_get_int();
971 rwindow = packet_get_int();
972 rmaxpack = packet_get_int();
973
974 log("server_input_open: ctype %s rchan %d win %d max %d",
975 ctype, rchan, rwindow, rmaxpack);
976
977 if (strcmp(ctype, "x11") == 0) {
978 int sock;
979 char *originator;
980 int originator_port;
981 originator = packet_get_string(NULL);
982 originator_port = packet_get_int();
983 packet_done();
984 /* XXX check permission */
985 xfree(originator);
986 /* XXX move to channels.c */
987 sock = x11_connect_display();
988 if (sock >= 0) {
989 id = channel_new("x11", SSH_CHANNEL_X11_OPEN,
990 sock, sock, -1, 4*1024, 32*1024, 0,
991 xstrdup("x11"));
992 c = channel_lookup(id);
993 }
994 }
995/* XXX duplicate : */
996 if (c != NULL) {
997 debug("confirm %s", ctype);
998 c->remote_id = rchan;
999 c->remote_window = rwindow;
1000 c->remote_maxpacket = rmaxpack;
1001
1002 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1003 packet_put_int(c->remote_id);
1004 packet_put_int(c->self);
1005 packet_put_int(c->local_window);
1006 packet_put_int(c->local_maxpacket);
1007 packet_send();
1008 } else {
1009 debug("failure %s", ctype);
1010 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1011 packet_put_int(rchan);
1012 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
1013 packet_put_cstring("bla bla");
1014 packet_put_cstring("");
1015 packet_send();
1016 }
1017 xfree(ctype);
1018}
1019
957void 1020void
958client_init_dispatch_20() 1021client_init_dispatch_20()
959{ 1022{
@@ -962,6 +1025,7 @@ client_init_dispatch_20()
962 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 1025 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
963 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 1026 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
964 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 1027 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
1028 dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
965 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 1029 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
966 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 1030 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
967 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); 1031 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request);
@@ -974,7 +1038,6 @@ client_init_dispatch_13()
974 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); 1038 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
975 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); 1039 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
976 dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); 1040 dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
977 dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
978 dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 1041 dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
979 dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 1042 dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
980 dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); 1043 dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
diff --git a/hostfile.c b/hostfile.c
index e1c2429bd..bac285da5 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: hostfile.c,v 1.17 2000/04/26 20:56:29 markus Exp $"); 17RCSID("$OpenBSD: hostfile.c,v 1.18 2000/04/29 18:11:52 markus Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "match.h" 20#include "match.h"
@@ -70,10 +70,10 @@ hostfile_check_key(int bits, Key *key, const char *host, const char *filename, i
70 if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) 70 if (key == NULL || key->type != KEY_RSA || key->rsa == NULL)
71 return 1; 71 return 1;
72 if (bits != BN_num_bits(key->rsa->n)) { 72 if (bits != BN_num_bits(key->rsa->n)) {
73 error("Warning: %s, line %d: keysize mismatch for host %s: " 73 log("Warning: %s, line %d: keysize mismatch for host %s: "
74 "actual %d vs. announced %d.", 74 "actual %d vs. announced %d.",
75 filename, linenum, host, BN_num_bits(key->rsa->n), bits); 75 filename, linenum, host, BN_num_bits(key->rsa->n), bits);
76 error("Warning: replace %d with %d in %s, line %d.", 76 log("Warning: replace %d with %d in %s, line %d.",
77 bits, BN_num_bits(key->rsa->n), filename, linenum); 77 bits, BN_num_bits(key->rsa->n), filename, linenum);
78 } 78 }
79 return 1; 79 return 1;
diff --git a/session.c b/session.c
index d5c53f11f..de39d8844 100644
--- a/session.c
+++ b/session.c
@@ -34,6 +34,7 @@ typedef struct Session Session;
34struct Session { 34struct Session {
35 int used; 35 int used;
36 int self; 36 int self;
37 int extended;
37 struct passwd *pw; 38 struct passwd *pw;
38 pid_t pid; 39 pid_t pid;
39 /* tty */ 40 /* tty */
@@ -46,6 +47,7 @@ struct Session {
46 int screen; 47 int screen;
47 char *auth_proto; 48 char *auth_proto;
48 char *auth_data; 49 char *auth_data;
50 int single_connection;
49 /* proto 2 */ 51 /* proto 2 */
50 int chanid; 52 int chanid;
51}; 53};
@@ -170,6 +172,7 @@ do_authenticated(struct passwd * pw)
170 channel_permit_all_opens(); 172 channel_permit_all_opens();
171 173
172 s = session_new(); 174 s = session_new();
175 s->pw = pw;
173 176
174 /* 177 /*
175 * We stay in this loop until the client requests to execute a shell 178 * We stay in this loop until the client requests to execute a shell
@@ -279,6 +282,7 @@ do_authenticated(struct passwd * pw)
279 xauthfile, strerror(errno)); 282 xauthfile, strerror(errno));
280 xfree(xauthfile); 283 xfree(xauthfile);
281 xauthfile = NULL; 284 xauthfile = NULL;
285 /* XXXX remove listening channels */
282 break; 286 break;
283 } 287 }
284 strlcat(xauthfile, "/cookies", MAXPATHLEN); 288 strlcat(xauthfile, "/cookies", MAXPATHLEN);
@@ -462,7 +466,7 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw)
462 close(perr[1]); 466 close(perr[1]);
463 467
464 if (compat20) { 468 if (compat20) {
465 session_set_fds(s, pin[1], pout[0], perr[0]); 469 session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1);
466 } else { 470 } else {
467 /* Enter the interactive session. */ 471 /* Enter the interactive session. */
468 server_loop(pid, pin[1], pout[0], perr[0]); 472 server_loop(pid, pin[1], pout[0], perr[0]);
@@ -478,7 +482,7 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw)
478 * handle the case that fdin and fdout are the same. 482 * handle the case that fdin and fdout are the same.
479 */ 483 */
480 if (compat20) { 484 if (compat20) {
481 session_set_fds(s, inout[1], inout[1], err[1]); 485 session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1);
482 } else { 486 } else {
483 server_loop(pid, inout[1], inout[1], err[1]); 487 server_loop(pid, inout[1], inout[1], err[1]);
484 /* server_loop has closed inout[1] and err[1]. */ 488 /* server_loop has closed inout[1] and err[1]. */
@@ -1119,6 +1123,7 @@ session_new(void)
1119 Session *s = &sessions[i]; 1123 Session *s = &sessions[i];
1120 if (! s->used) { 1124 if (! s->used) {
1121 s->pid = 0; 1125 s->pid = 0;
1126 s->extended = 0;
1122 s->chanid = -1; 1127 s->chanid = -1;
1123 s->ptyfd = -1; 1128 s->ptyfd = -1;
1124 s->ttyfd = -1; 1129 s->ttyfd = -1;
@@ -1129,6 +1134,7 @@ session_new(void)
1129 s->auth_data = NULL; 1134 s->auth_data = NULL;
1130 s->auth_proto = NULL; 1135 s->auth_proto = NULL;
1131 s->used = 1; 1136 s->used = 1;
1137 s->pw = NULL;
1132 debug("session_new: session %d", i); 1138 debug("session_new: session %d", i);
1133 return s; 1139 return s;
1134 } 1140 }
@@ -1160,12 +1166,11 @@ session_open(int chanid)
1160 error("no more sessions"); 1166 error("no more sessions");
1161 return 0; 1167 return 0;
1162 } 1168 }
1163 debug("session_open: session %d: link with channel %d", s->self, chanid);
1164 s->chanid = chanid;
1165 s->pw = auth_get_user(); 1169 s->pw = auth_get_user();
1166 if (s->pw == NULL) 1170 if (s->pw == NULL)
1167 fatal("no user for session %i channel %d", 1171 fatal("no user for session %i", s->self);
1168 s->self, s->chanid); 1172 debug("session_open: session %d: link with channel %d", s->self, chanid);
1173 s->chanid = chanid;
1169 return 1; 1174 return 1;
1170} 1175}
1171 1176
@@ -1257,6 +1262,69 @@ session_pty_req(Session *s)
1257 return 1; 1262 return 1;
1258} 1263}
1259 1264
1265int
1266session_subsystem_req(Session *s)
1267{
1268 unsigned int len;
1269 int success = 0;
1270 char *subsys = packet_get_string(&len);
1271
1272 packet_done();
1273 log("subsystem request for %s", subsys);
1274
1275 xfree(subsys);
1276 return success;
1277}
1278
1279int
1280session_x11_req(Session *s)
1281{
1282 if (!options.x11_forwarding) {
1283 debug("X11 forwarding disabled in server configuration file.");
1284 return 0;
1285 }
1286 if (xauthfile != NULL) {
1287 debug("X11 fwd already started.");
1288 return 0;
1289 }
1290
1291 debug("Received request for X11 forwarding with auth spoofing.");
1292 if (s->display != NULL)
1293 packet_disconnect("Protocol error: X11 display already set.");
1294
1295 s->single_connection = packet_get_char();
1296 s->auth_proto = packet_get_string(NULL);
1297 s->auth_data = packet_get_string(NULL);
1298 s->screen = packet_get_int();
1299 packet_done();
1300
1301 s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
1302 if (s->display == NULL) {
1303 xfree(s->auth_proto);
1304 xfree(s->auth_data);
1305 return 0;
1306 }
1307 xauthfile = xmalloc(MAXPATHLEN);
1308 strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
1309 temporarily_use_uid(s->pw->pw_uid);
1310 if (mkdtemp(xauthfile) == NULL) {
1311 restore_uid();
1312 error("private X11 dir: mkdtemp %s failed: %s",
1313 xauthfile, strerror(errno));
1314 xfree(xauthfile);
1315 xauthfile = NULL;
1316 xfree(s->auth_proto);
1317 xfree(s->auth_data);
1318 /* XXXX remove listening channels */
1319 return 0;
1320 }
1321 strlcat(xauthfile, "/cookies", MAXPATHLEN);
1322 open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
1323 restore_uid();
1324 fatal_add_cleanup(xauthfile_cleanup_proc, s);
1325 return 1;
1326}
1327
1260void 1328void
1261session_input_channel_req(int id, void *arg) 1329session_input_channel_req(int id, void *arg)
1262{ 1330{
@@ -1294,6 +1362,8 @@ session_input_channel_req(int id, void *arg)
1294 } else if (strcmp(rtype, "exec") == 0) { 1362 } else if (strcmp(rtype, "exec") == 0) {
1295 char *command = packet_get_string(&len); 1363 char *command = packet_get_string(&len);
1296 packet_done(); 1364 packet_done();
1365 s->extended = 1;
1366 s->extended = 1;
1297 if (s->ttyfd == -1) 1367 if (s->ttyfd == -1)
1298 do_exec_no_pty(s, command, s->pw); 1368 do_exec_no_pty(s, command, s->pw);
1299 else 1369 else
@@ -1302,6 +1372,10 @@ session_input_channel_req(int id, void *arg)
1302 success = 1; 1372 success = 1;
1303 } else if (strcmp(rtype, "pty-req") == 0) { 1373 } else if (strcmp(rtype, "pty-req") == 0) {
1304 success = session_pty_req(s); 1374 success = session_pty_req(s);
1375 } else if (strcmp(rtype, "x11-req") == 0) {
1376 success = session_x11_req(s);
1377 } else if (strcmp(rtype, "subsystem") == 0) {
1378 success = session_subsystem_req(s);
1305 } 1379 }
1306 } 1380 }
1307 if (strcmp(rtype, "window-change") == 0) { 1381 if (strcmp(rtype, "window-change") == 0) {
@@ -1399,7 +1473,8 @@ session_exit_message(Session *s, int status)
1399 * Note that we must not call 'chan_read_failed', since there could 1473 * Note that we must not call 'chan_read_failed', since there could
1400 * be some more data waiting in the pipe. 1474 * be some more data waiting in the pipe.
1401 */ 1475 */
1402 chan_write_failed(c); 1476 if (c->ostate != CHAN_OUTPUT_CLOSED)
1477 chan_write_failed(c);
1403 s->chanid = -1; 1478 s->chanid = -1;
1404} 1479}
1405 1480
@@ -1475,4 +1550,6 @@ do_authenticated2(void)
1475 */ 1550 */
1476 alarm(0); 1551 alarm(0);
1477 server_loop2(); 1552 server_loop2();
1553 if (xauthfile)
1554 xauthfile_cleanup_proc(NULL);
1478} 1555}
diff --git a/ssh-agent.c b/ssh-agent.c
index fb13ce7e1..e9f6b8062 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.30 2000/04/21 00:27:11 djm Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -9,7 +9,7 @@
9 */ 9 */
10 10
11#include "includes.h" 11#include "includes.h"
12RCSID("$OpenBSD: ssh-agent.c,v 1.30 2000/04/21 00:27:11 djm Exp $"); 12RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $");
13 13
14#include "ssh.h" 14#include "ssh.h"
15#include "rsa.h" 15#include "rsa.h"
@@ -178,7 +178,7 @@ process_remove_identity(SocketEntry *e)
178 buffer_get_bignum(&e->input, n); 178 buffer_get_bignum(&e->input, n);
179 179
180 if (bits != BN_num_bits(n)) 180 if (bits != BN_num_bits(n))
181 error("Warning: identity keysize mismatch: actual %d, announced %d", 181 log("Warning: identity keysize mismatch: actual %d, announced %d",
182 BN_num_bits(n), bits); 182 BN_num_bits(n), bits);
183 183
184 /* Check if we have the key. */ 184 /* Check if we have the key. */
diff --git a/ssh.c b/ssh.c
index bdf6180c8..cffd56676 100644
--- a/ssh.c
+++ b/ssh.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$Id: ssh.c,v 1.27 2000/04/29 13:57:12 damien Exp $"); 14RCSID("$Id: ssh.c,v 1.28 2000/04/30 00:00:54 damien Exp $");
15 15
16#include <openssl/evp.h> 16#include <openssl/evp.h>
17#include <openssl/dsa.h> 17#include <openssl/dsa.h>
@@ -664,6 +664,45 @@ main(int ac, char **av)
664 return exit_status; 664 return exit_status;
665} 665}
666 666
667void
668x11_get_proto(char *proto, int proto_len, char *data, int data_len)
669{
670 char line[512];
671 FILE *f;
672 int got_data = 0, i;
673
674#ifdef XAUTH_PATH
675 /* Try to get Xauthority information for the display. */
676 snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null",
677 XAUTH_PATH, getenv("DISPLAY"));
678 f = popen(line, "r");
679 if (f && fgets(line, sizeof(line), f) &&
680 sscanf(line, "%*s %s %s", proto, data) == 2)
681 got_data = 1;
682 if (f)
683 pclose(f);
684#endif /* XAUTH_PATH */
685 /*
686 * If we didn't get authentication data, just make up some
687 * data. The forwarding code will check the validity of the
688 * response anyway, and substitute this data. The X11
689 * server, however, will ignore this fake data and use
690 * whatever authentication mechanisms it was using otherwise
691 * for the local connection.
692 */
693 if (!got_data) {
694 u_int32_t rand = 0;
695
696 strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len);
697 for (i = 0; i < 16; i++) {
698 if (i % 4 == 0)
699 rand = arc4random();
700 snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff);
701 rand >>= 8;
702 }
703 }
704}
705
667int 706int
668ssh_session(void) 707ssh_session(void)
669{ 708{
@@ -737,56 +776,22 @@ ssh_session(void)
737 } 776 }
738 /* Request X11 forwarding if enabled and DISPLAY is set. */ 777 /* Request X11 forwarding if enabled and DISPLAY is set. */
739 if (options.forward_x11 && getenv("DISPLAY") != NULL) { 778 if (options.forward_x11 && getenv("DISPLAY") != NULL) {
740 char line[512], proto[512], data[512]; 779 char proto[512], data[512];
741 FILE *f; 780 /* Get reasonable local authentication information. */
742 int forwarded = 0, got_data = 0, i; 781 x11_get_proto(proto, sizeof proto, data, sizeof data);
743 782 /* Request forwarding with authentication spoofing. */
744#ifdef XAUTH_PATH
745 /* Try to get Xauthority information for the display. */
746 snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null",
747 XAUTH_PATH, getenv("DISPLAY"));
748 f = popen(line, "r");
749 if (f && fgets(line, sizeof(line), f) &&
750 sscanf(line, "%*s %s %s", proto, data) == 2)
751 got_data = 1;
752 if (f)
753 pclose(f);
754#endif /* XAUTH_PATH */
755 /*
756 * If we didn't get authentication data, just make up some
757 * data. The forwarding code will check the validity of the
758 * response anyway, and substitute this data. The X11
759 * server, however, will ignore this fake data and use
760 * whatever authentication mechanisms it was using otherwise
761 * for the local connection.
762 */
763 if (!got_data) {
764 u_int32_t rand = 0;
765
766 strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
767 for (i = 0; i < 16; i++) {
768 if (i % 4 == 0)
769 rand = arc4random();
770 snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);
771 rand >>= 8;
772 }
773 }
774 /*
775 * Got local authentication reasonable information. Request
776 * forwarding with authentication spoofing.
777 */
778 debug("Requesting X11 forwarding with authentication spoofing."); 783 debug("Requesting X11 forwarding with authentication spoofing.");
779 x11_request_forwarding_with_spoofing(proto, data); 784 x11_request_forwarding_with_spoofing(0, proto, data);
780 785
781 /* Read response from the server. */ 786 /* Read response from the server. */
782 type = packet_read(&plen); 787 type = packet_read(&plen);
783 if (type == SSH_SMSG_SUCCESS) { 788 if (type == SSH_SMSG_SUCCESS) {
784 forwarded = 1;
785 interactive = 1; 789 interactive = 1;
786 } else if (type == SSH_SMSG_FAILURE) 790 } else if (type == SSH_SMSG_FAILURE) {
787 log("Warning: Remote host denied X11 forwarding."); 791 log("Warning: Remote host denied X11 forwarding.");
788 else 792 } else {
789 packet_disconnect("Protocol error waiting for X11 forwarding"); 793 packet_disconnect("Protocol error waiting for X11 forwarding");
794 }
790 } 795 }
791 /* Tell the packet module whether this is an interactive session. */ 796 /* Tell the packet module whether this is an interactive session. */
792 packet_set_interactive(interactive, options.keepalives); 797 packet_set_interactive(interactive, options.keepalives);
@@ -909,6 +914,17 @@ client_init(int id, void *arg)
909 packet_send(); 914 packet_send();
910 /* XXX wait for reply */ 915 /* XXX wait for reply */
911 } 916 }
917 if (options.forward_x11 &&
918 getenv("DISPLAY") != NULL) {
919 char proto[512], data[512];
920 /* Get reasonable local authentication information. */
921 x11_get_proto(proto, sizeof proto, data, sizeof data);
922 /* Request forwarding with authentication spoofing. */
923 debug("Requesting X11 forwarding with authentication spoofing.");
924 x11_request_forwarding_with_spoofing(id, proto, data);
925 /* XXX wait for reply */
926 }
927
912 len = buffer_len(&command); 928 len = buffer_len(&command);
913 if (len > 0) { 929 if (len > 0) {
914 if (len > 900) 930 if (len > 900)