summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2005-07-04 00:58:44 +0000
committerDamien Miller <djm@cvs.openbsd.org>2005-07-04 00:58:44 +0000
commit2028f0c8649f874bc9bb5706bafa74ae8f537a0a (patch)
treeede1e163a0e213e6bc7ad082fb92e31807e310c0 /usr.bin
parente4d4fc29a2e87ce963753ffbaf9d1008811a7196 (diff)
implement support for X11 and agent forwarding over multiplex slave
connections. Because of protocol limitations, the slave connections inherit the master's DISPLAY and SSH_AUTH_SOCK rather than distinctly forwarding their own. ok dtucker@ "put it in" deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/channels.c61
-rw-r--r--usr.bin/ssh/clientloop.c35
-rw-r--r--usr.bin/ssh/clientloop.h7
-rw-r--r--usr.bin/ssh/misc.c19
-rw-r--r--usr.bin/ssh/misc.h3
-rw-r--r--usr.bin/ssh/ssh.c19
-rw-r--r--usr.bin/ssh/ssh_config.58
7 files changed, 107 insertions, 45 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c
index 75b134c7891..26f193e51aa 100644
--- a/usr.bin/ssh/channels.c
+++ b/usr.bin/ssh/channels.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.218 2005/07/01 13:19:47 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.219 2005/07/04 00:58:42 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -111,6 +111,9 @@ static int all_opens_permitted = 0;
/* Maximum number of fake X11 displays to try. */
#define MAX_DISPLAYS 1000
+/* Saved X11 local (client) display. */
+static char *x11_saved_display = NULL;
+
/* Saved X11 authentication protocol name. */
static char *x11_saved_proto = NULL;
@@ -2921,12 +2924,18 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
const char *proto, const char *data)
{
u_int data_len = (u_int) strlen(data) / 2;
- u_int i, value, len;
+ u_int i, value;
char *new_data;
int screen_number;
const char *cp;
u_int32_t rnd = 0;
+ if (x11_saved_display && strcmp(disp, x11_saved_display) != 0) {
+ error("x11_request_forwarding_with_spoofing: different "
+ "$DISPLAY already forwarded");
+ return;
+ }
+
cp = disp;
if (disp)
cp = strchr(disp, ':');
@@ -2937,33 +2946,31 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
else
screen_number = 0;
- /* Save protocol name. */
- x11_saved_proto = xstrdup(proto);
-
- /*
- * Extract real authentication data and generate fake data of the
- * same length.
- */
- x11_saved_data = xmalloc(data_len);
- x11_fake_data = xmalloc(data_len);
- for (i = 0; i < data_len; i++) {
- if (sscanf(data + 2 * i, "%2x", &value) != 1)
- fatal("x11_request_forwarding: bad authentication data: %.100s", data);
- if (i % 4 == 0)
- rnd = arc4random();
- x11_saved_data[i] = value;
- x11_fake_data[i] = rnd & 0xff;
- rnd >>= 8;
- }
- x11_saved_data_len = data_len;
- x11_fake_data_len = data_len;
+ if (x11_saved_proto == NULL) {
+ /* Save protocol name. */
+ x11_saved_proto = xstrdup(proto);
+ /*
+ * Extract real authentication data and generate fake data
+ * of the same length.
+ */
+ x11_saved_data = xmalloc(data_len);
+ x11_fake_data = xmalloc(data_len);
+ for (i = 0; i < data_len; i++) {
+ if (sscanf(data + 2 * i, "%2x", &value) != 1)
+ fatal("x11_request_forwarding: bad "
+ "authentication data: %.100s", data);
+ if (i % 4 == 0)
+ rnd = arc4random();
+ x11_saved_data[i] = value;
+ x11_fake_data[i] = rnd & 0xff;
+ rnd >>= 8;
+ }
+ x11_saved_data_len = data_len;
+ x11_fake_data_len = data_len;
+ }
/* Convert the fake data into hex. */
- len = 2 * data_len + 1;
- new_data = xmalloc(len);
- for (i = 0; i < data_len; i++)
- snprintf(new_data + 2 * i, len - 2 * i,
- "%02x", (u_char) x11_fake_data[i]);
+ new_data = tohex(x11_fake_data, data_len);
/* Send the request packet. */
if (compat20) {
diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c
index a030cf6e4a7..9611a5e3e73 100644
--- a/usr.bin/ssh/clientloop.c
+++ b/usr.bin/ssh/clientloop.c
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.139 2005/06/17 02:44:32 djm Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.140 2005/07/04 00:58:43 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -140,6 +140,8 @@ int session_ident = -1;
struct confirm_ctx {
int want_tty;
int want_subsys;
+ int want_x_fwd;
+ int want_agent_fwd;
Buffer cmd;
char *term;
struct termios tio;
@@ -631,6 +633,7 @@ static void
client_extra_session2_setup(int id, void *arg)
{
struct confirm_ctx *cctx = arg;
+ const char *display;
Channel *c;
int i;
@@ -639,6 +642,24 @@ client_extra_session2_setup(int id, void *arg)
if ((c = channel_lookup(id)) == NULL)
fatal("%s: no channel for id %d", __func__, id);
+ display = getenv("DISPLAY");
+ if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
+ char *proto, *data;
+ /* Get reasonable local authentication information. */
+ client_x11_get_proto(display, options.xauth_location,
+ options.forward_x11_trusted, &proto, &data);
+ /* Request forwarding with authentication spoofing. */
+ debug("Requesting X11 forwarding with authentication spoofing.");
+ x11_request_forwarding_with_spoofing(id, display, proto, data);
+ /* XXX wait for reply */
+ }
+
+ if (cctx->want_agent_fwd && options.forward_agent) {
+ debug("Requesting authentication agent forwarding.");
+ channel_request_start(id, "auth-agent-req@openssh.com", 0);
+ packet_send();
+ }
+
client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env,
client_subsystem_reply);
@@ -704,7 +725,7 @@ client_process_control(fd_set * readset)
buffer_free(&m);
return;
}
- if ((ver = buffer_get_char(&m)) != 1) {
+ if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
error("%s: wrong client version %d", __func__, ver);
buffer_free(&m);
close(client_fd);
@@ -738,7 +759,7 @@ client_process_control(fd_set * readset)
buffer_clear(&m);
buffer_put_int(&m, allowed);
buffer_put_int(&m, getpid());
- if (ssh_msg_send(client_fd, /* version */1, &m) == -1) {
+ if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
error("%s: client msg_send failed", __func__);
close(client_fd);
buffer_free(&m);
@@ -758,7 +779,7 @@ client_process_control(fd_set * readset)
buffer_clear(&m);
buffer_put_int(&m, allowed);
buffer_put_int(&m, getpid());
- if (ssh_msg_send(client_fd, /* version */1, &m) == -1) {
+ if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
error("%s: client msg_send failed", __func__);
close(client_fd);
buffer_free(&m);
@@ -779,7 +800,7 @@ client_process_control(fd_set * readset)
buffer_free(&m);
return;
}
- if ((ver = buffer_get_char(&m)) != 1) {
+ if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
error("%s: wrong client version %d", __func__, ver);
buffer_free(&m);
close(client_fd);
@@ -790,6 +811,8 @@ client_process_control(fd_set * readset)
memset(cctx, 0, sizeof(*cctx));
cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
+ cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
+ cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
cctx->term = buffer_get_string(&m, &len);
cmd = buffer_get_string(&m, &len);
@@ -823,7 +846,7 @@ client_process_control(fd_set * readset)
/* This roundtrip is just for synchronisation of ttymodes */
buffer_clear(&m);
- if (ssh_msg_send(client_fd, /* version */1, &m) == -1) {
+ if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
error("%s: client msg_send failed", __func__);
close(client_fd);
close(new_fd[0]);
diff --git a/usr.bin/ssh/clientloop.h b/usr.bin/ssh/clientloop.h
index 71c61b5d2a6..aed2d918b1d 100644
--- a/usr.bin/ssh/clientloop.h
+++ b/usr.bin/ssh/clientloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.h,v 1.13 2005/06/16 03:38:36 djm Exp $ */
+/* $OpenBSD: clientloop.h,v 1.14 2005/07/04 00:58:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -43,6 +43,9 @@ void client_global_request_reply_fwd(int, u_int32_t, void *);
void client_session2_setup(int, int, int, const char *, struct termios *,
int, Buffer *, char **, dispatch_fn *);
+/* Multiplexing protocol version */
+#define SSHMUX_VER 1
+
/* Multiplexing control protocol flags */
#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */
#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */
@@ -50,3 +53,5 @@ void client_session2_setup(int, int, int, const char *, struct termios *,
#define SSHMUX_FLAG_TTY (1) /* Request tty on open */
#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */
+#define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */
+#define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */
diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c
index 3c2943dc71e..d83f5d594ee 100644
--- a/usr.bin/ssh/misc.c
+++ b/usr.bin/ssh/misc.c
@@ -24,7 +24,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.32 2005/06/17 02:44:32 djm Exp $");
+RCSID("$OpenBSD: misc.c,v 1.33 2005/07/04 00:58:43 djm Exp $");
#include "misc.h"
#include "log.h"
@@ -500,3 +500,20 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
}
return -1;
}
+
+char *
+tohex(const u_char *d, u_int l)
+{
+ char b[3], *r;
+ u_int i, hl;
+
+ hl = l * 2 + 1;
+ r = xmalloc(hl);
+ *r = '\0';
+ for (i = 0; i < l; i++) {
+ snprintf(b, sizeof(b), "%02x", d[i]);
+ strlcat(r, b, hl);
+ }
+ return (r);
+}
+
diff --git a/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h
index a85fcd134b1..92848b28e1c 100644
--- a/usr.bin/ssh/misc.h
+++ b/usr.bin/ssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.23 2005/06/06 11:20:36 djm Exp $ */
+/* $OpenBSD: misc.h,v 1.24 2005/07/04 00:58:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -26,6 +26,7 @@ char *colon(char *);
long convtime(const char *);
char *tilde_expand_filename(const char *, uid_t);
char *percent_expand(const char *, ...) __attribute__((sentinel));
+char *tohex(const u_char *, u_int);
struct passwd *pwcopy(struct passwd *);
diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c
index b4ea992fb2a..7c46d872e24 100644
--- a/usr.bin/ssh/ssh.c
+++ b/usr.bin/ssh/ssh.c
@@ -40,7 +40,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.246 2005/06/25 22:47:49 djm Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.247 2005/07/04 00:58:43 djm Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@@ -1251,28 +1251,31 @@ control_client(const char *path)
close(fd);
}
- if ((term = getenv("TERM")) == NULL)
- term = "";
+ term = getenv("TERM");
flags = 0;
if (tty_flag)
flags |= SSHMUX_FLAG_TTY;
if (subsystem_flag)
flags |= SSHMUX_FLAG_SUBSYS;
+ if (options.forward_x11)
+ flags |= SSHMUX_FLAG_X11_FWD;
+ if (options.forward_agent)
+ flags |= SSHMUX_FLAG_AGENT_FWD;
buffer_init(&m);
/* Send our command to server */
buffer_put_int(&m, mux_command);
buffer_put_int(&m, flags);
- if (ssh_msg_send(sock, /* version */1, &m) == -1)
+ if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
fatal("%s: msg_send", __func__);
buffer_clear(&m);
/* Get authorisation status and PID of controlee */
if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__);
- if (buffer_get_char(&m) != 1)
+ if (buffer_get_char(&m) != SSHMUX_VER)
fatal("%s: wrong version", __func__);
if (buffer_get_int(&m) != 1)
fatal("Connection to master denied");
@@ -1296,7 +1299,7 @@ control_client(const char *path)
}
/* SSHMUX_COMMAND_OPEN */
- buffer_put_cstring(&m, term);
+ buffer_put_cstring(&m, term ? term : "");
buffer_append(&command, "\0", 1);
buffer_put_cstring(&m, buffer_ptr(&command));
@@ -1318,7 +1321,7 @@ control_client(const char *path)
}
}
- if (ssh_msg_send(sock, /* version */1, &m) == -1)
+ if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
fatal("%s: msg_send", __func__);
mm_send_fd(sock, STDIN_FILENO);
@@ -1329,7 +1332,7 @@ control_client(const char *path)
buffer_clear(&m);
if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__);
- if (buffer_get_char(&m) != 1)
+ if (buffer_get_char(&m) != SSHMUX_VER)
fatal("%s: wrong version", __func__);
buffer_free(&m);
diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5
index 3e7ca8f2822..40774297c13 100644
--- a/usr.bin/ssh/ssh_config.5
+++ b/usr.bin/ssh/ssh_config.5
@@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.57 2005/06/18 04:30:36 djm Exp $
+.\" $OpenBSD: ssh_config.5,v 1.58 2005/07/04 00:58:43 djm Exp $
.Dd September 25, 1999
.Dt SSH_CONFIG 5
.Os
@@ -279,6 +279,12 @@ can not be opened,
.Nm ssh
will continue without connecting to a master instance.
.Pp
+X11 and
+.Xr ssh-agent 4
+forwarding is supported over these multiplexed connections, however the
+display and agent fowarded will be the one belonging to the master
+connection. I.e. it is not possible to forward multiple displays or agents.
+.Pp
Two additional options allow for opportunistic multiplexing: try to use a
master connection but fall back to creating a new one if one does not already
exist.