diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | README.openssh2 | 22 | ||||
-rw-r--r-- | auth-rsa.c | 3 | ||||
-rw-r--r-- | auth1.c | 6 | ||||
-rw-r--r-- | authfd.c | 6 | ||||
-rw-r--r-- | channels.c | 211 | ||||
-rw-r--r-- | channels.h | 7 | ||||
-rw-r--r-- | clientloop.c | 67 | ||||
-rw-r--r-- | hostfile.c | 6 | ||||
-rw-r--r-- | session.c | 91 | ||||
-rw-r--r-- | ssh-agent.c | 6 | ||||
-rw-r--r-- | ssh.c | 102 |
12 files changed, 368 insertions, 164 deletions
@@ -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 | ||
12 | 20000429 | 17 | 20000429 |
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 | ||
3 | howto: | 3 | howto: |
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) |
30 | todo: | 30 | todo: |
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" |
19 | RCSID("$Id: auth-rsa.c,v 1.18 2000/04/29 13:57:09 damien Exp $"); | 19 | RCSID("$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. */ |
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "includes.h" | 6 | #include "includes.h" |
7 | RCSID("$OpenBSD: auth1.c,v 1.1 2000/04/26 21:28:32 markus Exp $"); | 7 | RCSID("$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); |
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$Id: authfd.c,v 1.13 2000/04/16 02:31:49 damien Exp $"); | 17 | RCSID("$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" |
20 | RCSID("$Id: channels.c,v 1.26 2000/04/19 06:26:13 damien Exp $"); | 20 | RCSID("$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 | */ |
375 | int | 376 | int |
376 | x11_open_helper(Channel *c) | 377 | x11_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 | ||
458 | void | 459 | void |
459 | channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset) | 460 | channel_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 | |||
729 | channel_handler_init_20(void) | 747 | channel_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 | ||
738 | void | 759 | void |
@@ -757,7 +778,7 @@ void | |||
757 | channel_handler_init_15(void) | 778 | channel_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 | 1836 | int | |
1814 | /* | 1837 | x11_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 | |||
1820 | void | ||
1821 | x11_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 | } |
1928 | success: | 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. */ | 1937 | void |
1939 | packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); | 1938 | x11_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 | ||
1946 | fail: | 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 | ||
1958 | void | 1987 | void |
1959 | x11_request_forwarding_with_spoofing(const char *proto, const char *data) | 1988 | x11_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 | ||
2156 | void | 2191 | void |
2157 | channel_open(int id) | 2192 | channel_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 | } | ||
2206 | void | ||
2207 | channel_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 | } |
2172 | void | 2213 | void |
2173 | channel_request(int id, char *service, int wantconfirm) | 2214 | channel_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 | */ |
210 | void x11_request_forwarding_with_spoofing(const char *proto, const char *data); | 210 | void |
211 | x11_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. */ |
213 | void auth_request_forwarding(void); | 215 | void auth_request_forwarding(void); |
@@ -230,5 +232,6 @@ void auth_input_open_request(int type, int plen); | |||
230 | 232 | ||
231 | /* XXX */ | 233 | /* XXX */ |
232 | int channel_connect_to(const char *host, u_short host_port); | 234 | int channel_connect_to(const char *host, u_short host_port); |
235 | int 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" |
19 | RCSID("$Id: clientloop.c,v 1.12 2000/04/19 21:42:21 damien Exp $"); | 19 | RCSID("$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 */ | ||
958 | void | ||
959 | client_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 | |||
957 | void | 1020 | void |
958 | client_init_dispatch_20() | 1021 | client_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" |
17 | RCSID("$OpenBSD: hostfile.c,v 1.17 2000/04/26 20:56:29 markus Exp $"); | 17 | RCSID("$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; |
@@ -34,6 +34,7 @@ typedef struct Session Session; | |||
34 | struct Session { | 34 | struct 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 | ||
1265 | int | ||
1266 | session_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 | |||
1279 | int | ||
1280 | session_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 | |||
1260 | void | 1328 | void |
1261 | session_input_channel_req(int id, void *arg) | 1329 | session_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" |
12 | RCSID("$OpenBSD: ssh-agent.c,v 1.30 2000/04/21 00:27:11 djm Exp $"); | 12 | RCSID("$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. */ |
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: ssh.c,v 1.27 2000/04/29 13:57:12 damien Exp $"); | 14 | RCSID("$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 | ||
667 | void | ||
668 | x11_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 | |||
667 | int | 706 | int |
668 | ssh_session(void) | 707 | ssh_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) |