]> andersk Git - openssh.git/commitdiff
- djm@cvs.openbsd.org 2005/07/04 00:58:43
authordjm <djm>
Tue, 5 Jul 2005 23:44:19 +0000 (23:44 +0000)
committerdjm <djm>
Tue, 5 Jul 2005 23:44:19 +0000 (23:44 +0000)
     [channels.c clientloop.c clientloop.h misc.c misc.h ssh.c ssh_config.5]
     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@

ChangeLog
channels.c
clientloop.c
clientloop.h
misc.c
misc.h
ssh.c
ssh_config.5

index 5869d7a76a2c77d2fb5512c87107a3eb6e59049c..0c26a7a23f815efc593041fb3ce72d5f724aa404 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,13 @@
    - markus@cvs.openbsd.org 2005/07/01 13:19:47
      [channels.c]
      don't free() if getaddrinfo() fails; report mpech@
+   - djm@cvs.openbsd.org 2005/07/04 00:58:43
+     [channels.c clientloop.c clientloop.h misc.c misc.h ssh.c ssh_config.5]
+     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@
 
 20050626
  - (djm) OpenBSD CVS Sync
index b5890232898d8b75a23bc33348c6073783870ec2..14ff166ae457ed48993e61ed0e7f1031c49cb991 100644 (file)
@@ -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;
 
@@ -2955,12 +2958,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, ':');
@@ -2971,33 +2980,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) {
index a030cf6e4a7da6ba33a9e50adbf326ea0b91a8ae..9611a5e3e73a56c4699d77b43358606fa26f1843 100644 (file)
@@ -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]);
index 71c61b5d2a697cad30ba55df6f92c6e16710fea9..aed2d918b1d7acdb2bf342f69120d27959febf3d 100644 (file)
@@ -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/misc.c b/misc.c
index c5ca0ce38db7be54235394b0a26e1f14182511a2..808b7ba27be9761d04be95e86d04c40f1f92e3f4 100644 (file)
--- a/misc.c
+++ b/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"
@@ -506,3 +506,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/misc.h b/misc.h
index a85fcd134b1f22276f8e8add0debc4503bf0204f..92848b28e1c10f30ca917d5ee7ae74a3633ae070 100644 (file)
--- a/misc.h
+++ b/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/ssh.c b/ssh.c
index 67af53e69cf0f6e7705561466d7fb708ea36b720..43d97abccf7b6c2e009ef8f700e9014a1096c76d 100644 (file)
--- a/ssh.c
+++ b/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>
@@ -1250,41 +1250,44 @@ control_client(const char *path)
                        error("Control socket connect(%.100s): %s", path,
                            strerror(errno));
                }
-               close(sock);
-               return;
-       }
-
-       if (stdin_null_flag) {
-               if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
-                       fatal("open(/dev/null): %s", strerror(errno));
-               if (dup2(fd, STDIN_FILENO) == -1)
-                       fatal("dup2: %s", strerror(errno));
-               if (fd > STDERR_FILENO)
-                       close(fd);
-       }
-
-       if ((term = getenv("TERM")) == NULL)
-               term = "";
+               close(sock);
+               return;
+       }
+       if (stdin_null_flag) {
+               if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+                       fatal("open(/dev/null): %s", strerror(errno));
+               if (dup2(fd, STDIN_FILENO) == -1)
+                       fatal("dup2: %s", strerror(errno));
+               if (fd > STDERR_FILENO)
+                       close(fd);
+       }
+  
+       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");
@@ -1308,7 +1311,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));
 
@@ -1330,7 +1333,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);
@@ -1341,7 +1344,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);
 
index 3e7ca8f28223eb91c4c075e5e15a8a947351cd9d..40774297c13792ad6aef733b00332898f560ca12 100644 (file)
@@ -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.
This page took 0.064738 seconds and 5 git commands to generate.