From 0b242b12f247fc000b6667df700d8a4523fc60fe Mon Sep 17 00:00:00 2001 From: damien Date: Sun, 30 Apr 2000 00:00:53 +0000 Subject: [PATCH] - More OpenBSD updates: [session.c] - don't call chan_write_failed() if we are not writing [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c] - keysize warnings error() -> log() --- ChangeLog | 5 ++ README.openssh2 | 18 ++--- auth-rsa.c | 1 - auth1.c | 6 +- authfd.c | 4 +- channels.c | 209 +++++++++++++++++++++++++++++------------------- channels.h | 5 +- clientloop.c | 65 ++++++++++++++- hostfile.c | 6 +- session.c | 91 +++++++++++++++++++-- ssh-agent.c | 6 +- ssh.c | 100 +++++++++++++---------- 12 files changed, 360 insertions(+), 156 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5c698b0..ae6348c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,11 @@ - Changed entropy seed code to user per-user seeds only (server seed is saved in root's .ssh directory) - Use atexit() and fatal cleanups to save seed on exit + - More OpenBSD updates: + [session.c] + - don't call chan_write_failed() if we are not writing + [auth-rsa.c auth1.c authfd.c hostfile.c ssh-agent.c] + - keysize warnings error() -> log() 20000429 - Merge big update to OpenSSH-2.0 from OpenBSD CVS diff --git a/README.openssh2 b/README.openssh2 index 76a6879b..91c0f1ec 100644 --- a/README.openssh2 +++ b/README.openssh2 @@ -6,7 +6,8 @@ howto: 2) enable ssh2: server: add 'Protocol 2,1' to /etc/sshd_config client: ssh -o 'Protocol 2,1', or add to .ssh/config - 3) interop w/ ssh.com dsa-keys: + 3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2) + interop w/ ssh.com dsa-keys: ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2 and vice versa ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub @@ -18,21 +19,20 @@ works: encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc mac: hmac-md5, hmac-sha1, (hmac-ripemd160) compression: zlib, none - secsh-userauth: passwd only + secsh-userauth: passwd and pubkey with DSA secsh-connection: pty+shell or command, flow control works (window adjust) - tcp-forwarding: -L works - dss: verification works, - key database in ~/.ssh/known_hosts with bits == 0 hack - dss: signature works, keygen w/ openssl + tcp-forwarding: -L works, -R incomplete + x11-fwd + dss/dsa: host key database in ~/.ssh/known_hosts2 client interops w/ sshd2, lshd server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0 server supports multiple concurrent sessions (e.g. with SSH.com Windows client) todo: re-keying secsh-connection features: - tcp-forwarding, agent-fwd, x11-fwd - auth other than passwd: - pubkey, keyboard-interactive + tcp-forwarding, agent-fwd + auth other than passwd, and DSA-pubkey: + keyboard-interactive, (PGP-pubkey?) config server-auth w/ old host-keys cleanup diff --git a/auth-rsa.c b/auth-rsa.c index 63aa345b..d7deabf2 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -256,7 +256,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n) /* We have found the desired key. */ - /* Perform the challenge-response dialog for this key. */ if (!auth_rsa_challenge_dialog(pk)) { /* Wrong response. */ diff --git a/auth1.c b/auth1.c index ae5f1cd8..dedf898e 100644 --- a/auth1.c +++ b/auth1.c @@ -4,7 +4,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.1 2000/04/26 21:28:32 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.2 2000/04/29 18:11:52 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -262,8 +262,8 @@ do_authloop(struct passwd * pw) packet_get_bignum(client_host_key->n, &nlen); if (bits != BN_num_bits(client_host_key->n)) - error("Warning: keysize mismatch for client_host_key: " - "actual %d, announced %d", BN_num_bits(client_host_key->n), bits); + log("Warning: keysize mismatch for client_host_key: " + "actual %d, announced %d", BN_num_bits(client_host_key->n), bits); packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); authenticated = auth_rhosts_rsa(pw, client_user, client_host_key); diff --git a/authfd.c b/authfd.c index bea66557..6e0cf5b4 100644 --- a/authfd.c +++ b/authfd.c @@ -217,8 +217,8 @@ ssh_get_next_identity(AuthenticationConnection *auth, *comment = buffer_get_string(&auth->identities, NULL); if (bits != BN_num_bits(n)) - error("Warning: identity keysize mismatch: actual %d, announced %u", - BN_num_bits(n), bits); + log("Warning: identity keysize mismatch: actual %d, announced %u", + BN_num_bits(n), bits); /* Decrement the number of remaining entries. */ auth->howmany--; diff --git a/channels.c b/channels.c index 0f1a5233..1f9d1a43 100644 --- a/channels.c +++ b/channels.c @@ -40,9 +40,11 @@ RCSID("$Id$"); /* Max len of agent socket */ #define MAX_SOCKET_NAME 100 -/* default buffer for tcp-fwd-channel */ -#define CHAN_WINDOW_DEFAULT (8*1024) -#define CHAN_PACKET_DEFAULT (CHAN_WINDOW_DEFAULT/2) +/* default window/packet sizes for tcp/x11-fwd-channel */ +#define CHAN_TCP_WINDOW_DEFAULT (8*1024) +#define CHAN_TCP_PACKET_DEFAULT (CHAN_TCP_WINDOW_DEFAULT/2) +#define CHAN_X11_WINDOW_DEFAULT (4*1024) +#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) /* * 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, c->self = found; c->type = type; c->ctype = ctype; - c->local_window = window; - c->local_window_max = window; - c->local_consumed = 0; - c->local_maxpacket = maxpack; - c->remote_window = 0; - c->remote_maxpacket = 0; c->rfd = rfd; c->wfd = wfd; c->sock = (rfd == wfd) ? rfd : -1; c->efd = efd; c->extended_usage = extended_usage; + c->local_window = window; + c->local_window_max = window; + c->local_consumed = 0; + c->local_maxpacket = maxpack; c->remote_id = -1; c->remote_name = remote_name; c->remote_window = 0; @@ -371,6 +371,7 @@ channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) * state until the first packet has been completely read. The authentication * data in that packet is then substituted by the real data if it matches the * fake data, and the channel is put into normal mode. + * XXX All this happens at the client side. */ int x11_open_helper(Channel *c) @@ -456,7 +457,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) } void -channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset) +channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) { int ret = x11_open_helper(c); if (ret == 1) { @@ -464,7 +465,7 @@ channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset) channel_pre_open_15(c, readset, writeset); } else if (ret == -1) { debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); - chan_read_failed(c); + chan_read_failed(c); /** force close? */ chan_write_failed(c); debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); } @@ -478,6 +479,7 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) int newsock, newch; socklen_t addrlen; char buf[16384], *remote_hostname; + int remote_port; if (FD_ISSET(c->sock, readset)) { debug("X11 connection requested."); @@ -488,16 +490,32 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) return; } remote_hostname = get_remote_hostname(newsock); + remote_port = get_peer_port(newsock); snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", - remote_hostname, get_peer_port(newsock)); + remote_hostname, remote_port); + + newch = channel_new("x11", + SSH_CHANNEL_OPENING, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, + 0, xstrdup(buf)); + if (compat20) { + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("x11"); + packet_put_int(newch); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + /* originator host and port */ + packet_put_cstring(remote_hostname); + packet_put_int(remote_port); + packet_send(); + } else { + packet_start(SSH_SMSG_X11_OPEN); + packet_put_int(newch); + if (have_hostname_in_open) + packet_put_string(buf, strlen(buf)); + packet_send(); + } xfree(remote_hostname); - newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, - xstrdup(buf)); - packet_start(SSH_SMSG_X11_OPEN); - packet_put_int(newch); - if (have_hostname_in_open) - packet_put_string(buf, strlen(buf)); - packet_send(); } } @@ -597,7 +615,7 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) FD_ISSET(c->rfd, readset)) { len = read(c->rfd, buf, sizeof(buf)); if (len <= 0) { - debug("channel %d: read<0 rfd %d len %d", + debug("channel %d: read<=0 rfd %d len %d", c->self, c->rfd, len); if (compat13) { buffer_consume(&c->output, buffer_len(&c->output)); @@ -729,10 +747,13 @@ void channel_handler_init_20(void) { channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; + channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; + channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; } void @@ -757,7 +778,7 @@ void channel_handler_init_15(void) { channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_15; - channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_15; + channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; @@ -1428,7 +1449,7 @@ channel_request_local_forwarding(u_short port, const char *host, ch = channel_new( "port listener", SSH_CHANNEL_PORT_LISTENER, sock, sock, -1, - CHAN_WINDOW_DEFAULT, CHAN_PACKET_DEFAULT, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("port listener")); strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); channels[ch].host_port = host_port; @@ -1769,8 +1790,10 @@ x11_create_display_inet(int screen_number, int x11_display_offset) /* Allocate a channel for each socket. */ for (n = 0; n < num_socks; n++) { sock = socks[n]; - (void) channel_allocate(SSH_CHANNEL_X11_LISTENER, sock, - xstrdup("X11 inet listener")); + (void) channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, xstrdup("X11 inet listener")); } /* Return a suitable value for the DISPLAY environment variable. */ @@ -1810,44 +1833,21 @@ connect_local_xsocket(unsigned int dnr) return -1; } - -/* - * This is called when SSH_SMSG_X11_OPEN is received. The packet contains - * the remote channel number. We should do whatever we want, and respond - * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. - */ - -void -x11_input_open(int type, int plen) +int +x11_connect_display(void) { - int remote_channel, display_number, sock = 0, newch; + int display_number, sock = 0; const char *display; - char buf[1024], *cp, *remote_host; - unsigned int remote_len; + char buf[1024], *cp; struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr; - /* Get remote channel number. */ - remote_channel = packet_get_int(); - - /* Get remote originator name. */ - if (have_hostname_in_open) { - remote_host = packet_get_string(&remote_len); - remote_len += 4; - } else { - remote_host = xstrdup("unknown (remote did not supply name)"); - remote_len = 0; - } - - debug("Received X11 open request."); - packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN); - /* Try to open a socket for the local X server. */ display = getenv("DISPLAY"); if (!display) { error("DISPLAY not set."); - goto fail; + return -1; } /* * Now we decode the value of the DISPLAY variable and make a @@ -1864,15 +1864,15 @@ x11_input_open(int type, int plen) if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) { error("Could not parse display number from DISPLAY: %.100s", display); - goto fail; + return -1; } /* Create a socket. */ sock = connect_local_xsocket(display_number); if (sock < 0) - goto fail; + return -1; /* OK, we now have a connection to the display. */ - goto success; + return sock; } /* * Connect to an inet socket. The DISPLAY value is supposedly @@ -1883,14 +1883,14 @@ x11_input_open(int type, int plen) cp = strchr(buf, ':'); if (!cp) { error("Could not find ':' in DISPLAY: %.100s", display); - goto fail; + return -1; } *cp = 0; /* buf now contains the host name. But first we parse the display number. */ if (sscanf(cp + 1, "%d", &display_number) != 1) { error("Could not parse display number from DISPLAY: %.100s", display); - goto fail; + return -1; } /* Look up the host address */ @@ -1900,7 +1900,7 @@ x11_input_open(int type, int plen) snprintf(strport, sizeof strport, "%d", 6000 + display_number); if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); - goto fail; + return -1; } for (ai = aitop; ai; ai = ai->ai_next) { /* Create a socket. */ @@ -1923,31 +1923,60 @@ x11_input_open(int type, int plen) if (!ai) { error("connect %.100s port %d: %.100s", buf, 6000 + display_number, strerror(errno)); - goto fail; + return -1; } -success: - /* We have successfully obtained a connection to the real X display. */ + return sock; +} - /* Allocate a channel for this connection. */ - if (x11_saved_proto == NULL) - newch = channel_allocate(SSH_CHANNEL_OPEN, sock, remote_host); - else - newch = channel_allocate(SSH_CHANNEL_X11_OPEN, sock, remote_host); - channels[newch].remote_id = remote_channel; +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ - /* Send a confirmation to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); - packet_put_int(remote_channel); - packet_put_int(newch); - packet_send(); +void +x11_input_open(int type, int plen) +{ + int remote_channel, sock = 0, newch; + char *remote_host; + unsigned int remote_len; - return; + /* Get remote channel number. */ + remote_channel = packet_get_int(); -fail: - /* Send refusal to the remote host. */ - packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); - packet_put_int(remote_channel); - packet_send(); + /* Get remote originator name. */ + if (have_hostname_in_open) { + remote_host = packet_get_string(&remote_len); + remote_len += 4; + } else { + remote_host = xstrdup("unknown (remote did not supply name)"); + remote_len = 0; + } + + debug("Received X11 open request."); + packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN); + + /* Obtain a connection to the real X display. */ + sock = x11_connect_display(); + if (sock == -1) { + /* Send refusal to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_channel); + packet_send(); + } else { + /* Allocate a channel for this connection. */ + newch = channel_allocate( + (x11_saved_proto == NULL) ? + SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN, + sock, remote_host); + channels[newch].remote_id = remote_channel; + + /* Send a confirmation to the remote host. */ + packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(remote_channel); + packet_put_int(newch); + packet_send(); + } } /* @@ -1956,7 +1985,8 @@ fail: */ void -x11_request_forwarding_with_spoofing(const char *proto, const char *data) +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data) { unsigned int data_len = (unsigned int) strlen(data) / 2; unsigned int i, value; @@ -2002,9 +2032,14 @@ x11_request_forwarding_with_spoofing(const char *proto, const char *data) sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]); /* Send the request packet. */ - packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); - packet_put_string(proto, strlen(proto)); - packet_put_string(new_data, strlen(new_data)); + if (compat20) { + channel_request_start(client_session_id, "x11-req", 0); + packet_put_char(0); /* XXX bool single connection */ + } else { + packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); + } + packet_put_cstring(proto); + packet_put_cstring(new_data); packet_put_int(screen_number); packet_send(); packet_write_wait(); @@ -2154,20 +2189,26 @@ auth_input_open_request(int type, int plen) } void -channel_open(int id) +channel_start_open(int id) { Channel *c = channel_lookup(id); if (c == NULL) { log("channel_open: %d: bad id", id); return; } + debug("send channel open %d", id); packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring(c->ctype); packet_put_int(c->self); packet_put_int(c->local_window); packet_put_int(c->local_maxpacket); +} +void +channel_open(int id) +{ + /* XXX REMOVE ME */ + channel_start_open(id); packet_send(); - debug("channel open %d", id); } void channel_request(int id, char *service, int wantconfirm) diff --git a/channels.h b/channels.h index 9d98d04d..24fedb32 100644 --- a/channels.h +++ b/channels.h @@ -207,7 +207,9 @@ void x11_request_forwarding(void); * Requests forwarding for X11 connections, with authentication spoofing. * This should be called in the client only. */ -void x11_request_forwarding_with_spoofing(const char *proto, const char *data); +void +x11_request_forwarding_with_spoofing(int client_session_id, + const char *proto, const char *data); /* Sends a message to the server to request authentication fd forwarding. */ void auth_request_forwarding(void); @@ -230,5 +232,6 @@ void auth_input_open_request(int type, int plen); /* XXX */ int channel_connect_to(const char *host, u_short host_port); +int x11_connect_display(void); #endif diff --git a/clientloop.c b/clientloop.c index 148e8b5f..ab671378 100644 --- a/clientloop.c +++ b/clientloop.c @@ -954,6 +954,69 @@ client_input_exit_status(int type, int plen) quit_pending = 1; } +/* XXXX move to generic input handler */ +void +client_input_channel_open(int type, int plen) +{ + Channel *c = NULL; + char *ctype; + int id; + unsigned int len; + int rchan; + int rmaxpack; + int rwindow; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + log("server_input_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "x11") == 0) { + int sock; + char *originator; + int originator_port; + originator = packet_get_string(NULL); + originator_port = packet_get_int(); + packet_done(); + /* XXX check permission */ + xfree(originator); + /* XXX move to channels.c */ + sock = x11_connect_display(); + if (sock >= 0) { + id = channel_new("x11", SSH_CHANNEL_X11_OPEN, + sock, sock, -1, 4*1024, 32*1024, 0, + xstrdup("x11")); + c = channel_lookup(id); + } + } +/* XXX duplicate : */ + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + packet_put_cstring("bla bla"); + packet_put_cstring(""); + packet_send(); + } + xfree(ctype); +} + void client_init_dispatch_20() { @@ -962,6 +1025,7 @@ client_init_dispatch_20() dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); + dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); @@ -974,7 +1038,6 @@ client_init_dispatch_13() dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); - dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); diff --git a/hostfile.c b/hostfile.c index e1c2429b..bac285da 100644 --- a/hostfile.c +++ b/hostfile.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: hostfile.c,v 1.17 2000/04/26 20:56:29 markus Exp $"); +RCSID("$OpenBSD: hostfile.c,v 1.18 2000/04/29 18:11:52 markus Exp $"); #include "packet.h" #include "match.h" @@ -70,10 +70,10 @@ hostfile_check_key(int bits, Key *key, const char *host, const char *filename, i if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) return 1; if (bits != BN_num_bits(key->rsa->n)) { - error("Warning: %s, line %d: keysize mismatch for host %s: " + log("Warning: %s, line %d: keysize mismatch for host %s: " "actual %d vs. announced %d.", filename, linenum, host, BN_num_bits(key->rsa->n), bits); - error("Warning: replace %d with %d in %s, line %d.", + log("Warning: replace %d with %d in %s, line %d.", bits, BN_num_bits(key->rsa->n), filename, linenum); } return 1; diff --git a/session.c b/session.c index d5c53f11..de39d884 100644 --- a/session.c +++ b/session.c @@ -34,6 +34,7 @@ typedef struct Session Session; struct Session { int used; int self; + int extended; struct passwd *pw; pid_t pid; /* tty */ @@ -46,6 +47,7 @@ struct Session { int screen; char *auth_proto; char *auth_data; + int single_connection; /* proto 2 */ int chanid; }; @@ -170,6 +172,7 @@ do_authenticated(struct passwd * pw) channel_permit_all_opens(); s = session_new(); + s->pw = pw; /* * We stay in this loop until the client requests to execute a shell @@ -279,6 +282,7 @@ do_authenticated(struct passwd * pw) xauthfile, strerror(errno)); xfree(xauthfile); xauthfile = NULL; + /* XXXX remove listening channels */ break; } strlcat(xauthfile, "/cookies", MAXPATHLEN); @@ -462,7 +466,7 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) close(perr[1]); if (compat20) { - session_set_fds(s, pin[1], pout[0], perr[0]); + session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1); } else { /* Enter the interactive session. */ 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) * handle the case that fdin and fdout are the same. */ if (compat20) { - session_set_fds(s, inout[1], inout[1], err[1]); + session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1); } else { server_loop(pid, inout[1], inout[1], err[1]); /* server_loop has closed inout[1] and err[1]. */ @@ -1119,6 +1123,7 @@ session_new(void) Session *s = &sessions[i]; if (! s->used) { s->pid = 0; + s->extended = 0; s->chanid = -1; s->ptyfd = -1; s->ttyfd = -1; @@ -1129,6 +1134,7 @@ session_new(void) s->auth_data = NULL; s->auth_proto = NULL; s->used = 1; + s->pw = NULL; debug("session_new: session %d", i); return s; } @@ -1160,12 +1166,11 @@ session_open(int chanid) error("no more sessions"); return 0; } - debug("session_open: session %d: link with channel %d", s->self, chanid); - s->chanid = chanid; s->pw = auth_get_user(); if (s->pw == NULL) - fatal("no user for session %i channel %d", - s->self, s->chanid); + fatal("no user for session %i", s->self); + debug("session_open: session %d: link with channel %d", s->self, chanid); + s->chanid = chanid; return 1; } @@ -1257,6 +1262,69 @@ session_pty_req(Session *s) return 1; } +int +session_subsystem_req(Session *s) +{ + unsigned int len; + int success = 0; + char *subsys = packet_get_string(&len); + + packet_done(); + log("subsystem request for %s", subsys); + + xfree(subsys); + return success; +} + +int +session_x11_req(Session *s) +{ + if (!options.x11_forwarding) { + debug("X11 forwarding disabled in server configuration file."); + return 0; + } + if (xauthfile != NULL) { + debug("X11 fwd already started."); + return 0; + } + + debug("Received request for X11 forwarding with auth spoofing."); + if (s->display != NULL) + packet_disconnect("Protocol error: X11 display already set."); + + s->single_connection = packet_get_char(); + s->auth_proto = packet_get_string(NULL); + s->auth_data = packet_get_string(NULL); + s->screen = packet_get_int(); + packet_done(); + + s->display = x11_create_display_inet(s->screen, options.x11_display_offset); + if (s->display == NULL) { + xfree(s->auth_proto); + xfree(s->auth_data); + return 0; + } + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); + temporarily_use_uid(s->pw->pw_uid); + if (mkdtemp(xauthfile) == NULL) { + restore_uid(); + error("private X11 dir: mkdtemp %s failed: %s", + xauthfile, strerror(errno)); + xfree(xauthfile); + xauthfile = NULL; + xfree(s->auth_proto); + xfree(s->auth_data); + /* XXXX remove listening channels */ + return 0; + } + strlcat(xauthfile, "/cookies", MAXPATHLEN); + open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600); + restore_uid(); + fatal_add_cleanup(xauthfile_cleanup_proc, s); + return 1; +} + void session_input_channel_req(int id, void *arg) { @@ -1294,6 +1362,8 @@ session_input_channel_req(int id, void *arg) } else if (strcmp(rtype, "exec") == 0) { char *command = packet_get_string(&len); packet_done(); + s->extended = 1; + s->extended = 1; if (s->ttyfd == -1) do_exec_no_pty(s, command, s->pw); else @@ -1302,6 +1372,10 @@ session_input_channel_req(int id, void *arg) success = 1; } else if (strcmp(rtype, "pty-req") == 0) { success = session_pty_req(s); + } else if (strcmp(rtype, "x11-req") == 0) { + success = session_x11_req(s); + } else if (strcmp(rtype, "subsystem") == 0) { + success = session_subsystem_req(s); } } if (strcmp(rtype, "window-change") == 0) { @@ -1399,7 +1473,8 @@ session_exit_message(Session *s, int status) * Note that we must not call 'chan_read_failed', since there could * be some more data waiting in the pipe. */ - chan_write_failed(c); + if (c->ostate != CHAN_OUTPUT_CLOSED) + chan_write_failed(c); s->chanid = -1; } @@ -1475,4 +1550,6 @@ do_authenticated2(void) */ alarm(0); server_loop2(); + if (xauthfile) + xauthfile_cleanup_proc(NULL); } diff --git a/ssh-agent.c b/ssh-agent.c index fb13ce7e..e9f6b806 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.30 2000/04/21 00:27:11 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $ */ /* * Author: Tatu Ylonen @@ -9,7 +9,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.30 2000/04/21 00:27:11 djm Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $"); #include "ssh.h" #include "rsa.h" @@ -178,7 +178,7 @@ process_remove_identity(SocketEntry *e) buffer_get_bignum(&e->input, n); if (bits != BN_num_bits(n)) - error("Warning: identity keysize mismatch: actual %d, announced %d", + log("Warning: identity keysize mismatch: actual %d, announced %d", BN_num_bits(n), bits); /* Check if we have the key. */ diff --git a/ssh.c b/ssh.c index 0d3e70e0..b3a06500 100644 --- a/ssh.c +++ b/ssh.c @@ -664,6 +664,45 @@ main(int ac, char **av) return exit_status; } +void +x11_get_proto(char *proto, int proto_len, char *data, int data_len) +{ + char line[512]; + FILE *f; + int got_data = 0, i; + +#ifdef XAUTH_PATH + /* Try to get Xauthority information for the display. */ + snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null", + XAUTH_PATH, getenv("DISPLAY")); + f = popen(line, "r"); + if (f && fgets(line, sizeof(line), f) && + sscanf(line, "%*s %s %s", proto, data) == 2) + got_data = 1; + if (f) + pclose(f); +#endif /* XAUTH_PATH */ + /* + * If we didn't get authentication data, just make up some + * data. The forwarding code will check the validity of the + * response anyway, and substitute this data. The X11 + * server, however, will ignore this fake data and use + * whatever authentication mechanisms it was using otherwise + * for the local connection. + */ + if (!got_data) { + u_int32_t rand = 0; + + strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len); + for (i = 0; i < 16; i++) { + if (i % 4 == 0) + rand = arc4random(); + snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff); + rand >>= 8; + } + } +} + int ssh_session(void) { @@ -737,56 +776,22 @@ ssh_session(void) } /* Request X11 forwarding if enabled and DISPLAY is set. */ if (options.forward_x11 && getenv("DISPLAY") != NULL) { - char line[512], proto[512], data[512]; - FILE *f; - int forwarded = 0, got_data = 0, i; - -#ifdef XAUTH_PATH - /* Try to get Xauthority information for the display. */ - snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null", - XAUTH_PATH, getenv("DISPLAY")); - f = popen(line, "r"); - if (f && fgets(line, sizeof(line), f) && - sscanf(line, "%*s %s %s", proto, data) == 2) - got_data = 1; - if (f) - pclose(f); -#endif /* XAUTH_PATH */ - /* - * If we didn't get authentication data, just make up some - * data. The forwarding code will check the validity of the - * response anyway, and substitute this data. The X11 - * server, however, will ignore this fake data and use - * whatever authentication mechanisms it was using otherwise - * for the local connection. - */ - if (!got_data) { - u_int32_t rand = 0; - - strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto); - for (i = 0; i < 16; i++) { - if (i % 4 == 0) - rand = arc4random(); - snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff); - rand >>= 8; - } - } - /* - * Got local authentication reasonable information. Request - * forwarding with authentication spoofing. - */ + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(proto, data); + x11_request_forwarding_with_spoofing(0, proto, data); /* Read response from the server. */ type = packet_read(&plen); if (type == SSH_SMSG_SUCCESS) { - forwarded = 1; interactive = 1; - } else if (type == SSH_SMSG_FAILURE) + } else if (type == SSH_SMSG_FAILURE) { log("Warning: Remote host denied X11 forwarding."); - else + } else { packet_disconnect("Protocol error waiting for X11 forwarding"); + } } /* Tell the packet module whether this is an interactive session. */ packet_set_interactive(interactive, options.keepalives); @@ -909,6 +914,17 @@ client_init(int id, void *arg) packet_send(); /* XXX wait for reply */ } + if (options.forward_x11 && + getenv("DISPLAY") != NULL) { + char proto[512], data[512]; + /* Get reasonable local authentication information. */ + x11_get_proto(proto, sizeof proto, data, sizeof data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(id, proto, data); + /* XXX wait for reply */ + } + len = buffer_len(&command); if (len > 0) { if (len > 900) -- 2.45.2