diff options
author | Damien Miller <djm@mindrot.org> | 2005-07-06 09:44:19 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-07-06 09:44:19 +1000 |
commit | 1339002e8b05d89b10767849d9ee9be55e460f4c (patch) | |
tree | 58e307b74579313f31732dfdf21f756d6a051ce9 | |
parent | a7270309fc5e95b29c91d0190b13ef5a9b1df339 (diff) |
- 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@
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | channels.c | 61 | ||||
-rw-r--r-- | clientloop.c | 35 | ||||
-rw-r--r-- | clientloop.h | 7 | ||||
-rw-r--r-- | misc.c | 19 | ||||
-rw-r--r-- | misc.h | 3 | ||||
-rw-r--r-- | ssh.c | 45 | ||||
-rw-r--r-- | ssh_config.5 | 8 |
8 files changed, 128 insertions, 59 deletions
@@ -3,6 +3,13 @@ | |||
3 | - markus@cvs.openbsd.org 2005/07/01 13:19:47 | 3 | - markus@cvs.openbsd.org 2005/07/01 13:19:47 |
4 | [channels.c] | 4 | [channels.c] |
5 | don't free() if getaddrinfo() fails; report mpech@ | 5 | don't free() if getaddrinfo() fails; report mpech@ |
6 | - djm@cvs.openbsd.org 2005/07/04 00:58:43 | ||
7 | [channels.c clientloop.c clientloop.h misc.c misc.h ssh.c ssh_config.5] | ||
8 | implement support for X11 and agent forwarding over multiplex slave | ||
9 | connections. Because of protocol limitations, the slave connections inherit | ||
10 | the master's DISPLAY and SSH_AUTH_SOCK rather than distinctly forwarding | ||
11 | their own. | ||
12 | ok dtucker@ "put it in" deraadt@ | ||
6 | 13 | ||
7 | 20050626 | 14 | 20050626 |
8 | - (djm) OpenBSD CVS Sync | 15 | - (djm) OpenBSD CVS Sync |
@@ -2769,4 +2776,4 @@ | |||
2769 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2776 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2770 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2777 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2771 | 2778 | ||
2772 | $Id: ChangeLog,v 1.3832 2005/07/05 23:36:05 djm Exp $ | 2779 | $Id: ChangeLog,v 1.3833 2005/07/05 23:44:19 djm Exp $ |
diff --git a/channels.c b/channels.c index b58902328..14ff166ae 100644 --- a/channels.c +++ b/channels.c | |||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: channels.c,v 1.218 2005/07/01 13:19:47 markus Exp $"); | 42 | RCSID("$OpenBSD: channels.c,v 1.219 2005/07/04 00:58:42 djm Exp $"); |
43 | 43 | ||
44 | #include "ssh.h" | 44 | #include "ssh.h" |
45 | #include "ssh1.h" | 45 | #include "ssh1.h" |
@@ -111,6 +111,9 @@ static int all_opens_permitted = 0; | |||
111 | /* Maximum number of fake X11 displays to try. */ | 111 | /* Maximum number of fake X11 displays to try. */ |
112 | #define MAX_DISPLAYS 1000 | 112 | #define MAX_DISPLAYS 1000 |
113 | 113 | ||
114 | /* Saved X11 local (client) display. */ | ||
115 | static char *x11_saved_display = NULL; | ||
116 | |||
114 | /* Saved X11 authentication protocol name. */ | 117 | /* Saved X11 authentication protocol name. */ |
115 | static char *x11_saved_proto = NULL; | 118 | static char *x11_saved_proto = NULL; |
116 | 119 | ||
@@ -2955,12 +2958,18 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, | |||
2955 | const char *proto, const char *data) | 2958 | const char *proto, const char *data) |
2956 | { | 2959 | { |
2957 | u_int data_len = (u_int) strlen(data) / 2; | 2960 | u_int data_len = (u_int) strlen(data) / 2; |
2958 | u_int i, value, len; | 2961 | u_int i, value; |
2959 | char *new_data; | 2962 | char *new_data; |
2960 | int screen_number; | 2963 | int screen_number; |
2961 | const char *cp; | 2964 | const char *cp; |
2962 | u_int32_t rnd = 0; | 2965 | u_int32_t rnd = 0; |
2963 | 2966 | ||
2967 | if (x11_saved_display && strcmp(disp, x11_saved_display) != 0) { | ||
2968 | error("x11_request_forwarding_with_spoofing: different " | ||
2969 | "$DISPLAY already forwarded"); | ||
2970 | return; | ||
2971 | } | ||
2972 | |||
2964 | cp = disp; | 2973 | cp = disp; |
2965 | if (disp) | 2974 | if (disp) |
2966 | cp = strchr(disp, ':'); | 2975 | cp = strchr(disp, ':'); |
@@ -2971,33 +2980,31 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, | |||
2971 | else | 2980 | else |
2972 | screen_number = 0; | 2981 | screen_number = 0; |
2973 | 2982 | ||
2974 | /* Save protocol name. */ | 2983 | if (x11_saved_proto == NULL) { |
2975 | x11_saved_proto = xstrdup(proto); | 2984 | /* Save protocol name. */ |
2976 | 2985 | x11_saved_proto = xstrdup(proto); | |
2977 | /* | 2986 | /* |
2978 | * Extract real authentication data and generate fake data of the | 2987 | * Extract real authentication data and generate fake data |
2979 | * same length. | 2988 | * of the same length. |
2980 | */ | 2989 | */ |
2981 | x11_saved_data = xmalloc(data_len); | 2990 | x11_saved_data = xmalloc(data_len); |
2982 | x11_fake_data = xmalloc(data_len); | 2991 | x11_fake_data = xmalloc(data_len); |
2983 | for (i = 0; i < data_len; i++) { | 2992 | for (i = 0; i < data_len; i++) { |
2984 | if (sscanf(data + 2 * i, "%2x", &value) != 1) | 2993 | if (sscanf(data + 2 * i, "%2x", &value) != 1) |
2985 | fatal("x11_request_forwarding: bad authentication data: %.100s", data); | 2994 | fatal("x11_request_forwarding: bad " |
2986 | if (i % 4 == 0) | 2995 | "authentication data: %.100s", data); |
2987 | rnd = arc4random(); | 2996 | if (i % 4 == 0) |
2988 | x11_saved_data[i] = value; | 2997 | rnd = arc4random(); |
2989 | x11_fake_data[i] = rnd & 0xff; | 2998 | x11_saved_data[i] = value; |
2990 | rnd >>= 8; | 2999 | x11_fake_data[i] = rnd & 0xff; |
2991 | } | 3000 | rnd >>= 8; |
2992 | x11_saved_data_len = data_len; | 3001 | } |
2993 | x11_fake_data_len = data_len; | 3002 | x11_saved_data_len = data_len; |
3003 | x11_fake_data_len = data_len; | ||
3004 | } | ||
2994 | 3005 | ||
2995 | /* Convert the fake data into hex. */ | 3006 | /* Convert the fake data into hex. */ |
2996 | len = 2 * data_len + 1; | 3007 | new_data = tohex(x11_fake_data, data_len); |
2997 | new_data = xmalloc(len); | ||
2998 | for (i = 0; i < data_len; i++) | ||
2999 | snprintf(new_data + 2 * i, len - 2 * i, | ||
3000 | "%02x", (u_char) x11_fake_data[i]); | ||
3001 | 3008 | ||
3002 | /* Send the request packet. */ | 3009 | /* Send the request packet. */ |
3003 | if (compat20) { | 3010 | if (compat20) { |
diff --git a/clientloop.c b/clientloop.c index a030cf6e4..9611a5e3e 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.139 2005/06/17 02:44:32 djm Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.140 2005/07/04 00:58:43 djm Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -140,6 +140,8 @@ int session_ident = -1; | |||
140 | struct confirm_ctx { | 140 | struct confirm_ctx { |
141 | int want_tty; | 141 | int want_tty; |
142 | int want_subsys; | 142 | int want_subsys; |
143 | int want_x_fwd; | ||
144 | int want_agent_fwd; | ||
143 | Buffer cmd; | 145 | Buffer cmd; |
144 | char *term; | 146 | char *term; |
145 | struct termios tio; | 147 | struct termios tio; |
@@ -631,6 +633,7 @@ static void | |||
631 | client_extra_session2_setup(int id, void *arg) | 633 | client_extra_session2_setup(int id, void *arg) |
632 | { | 634 | { |
633 | struct confirm_ctx *cctx = arg; | 635 | struct confirm_ctx *cctx = arg; |
636 | const char *display; | ||
634 | Channel *c; | 637 | Channel *c; |
635 | int i; | 638 | int i; |
636 | 639 | ||
@@ -639,6 +642,24 @@ client_extra_session2_setup(int id, void *arg) | |||
639 | if ((c = channel_lookup(id)) == NULL) | 642 | if ((c = channel_lookup(id)) == NULL) |
640 | fatal("%s: no channel for id %d", __func__, id); | 643 | fatal("%s: no channel for id %d", __func__, id); |
641 | 644 | ||
645 | display = getenv("DISPLAY"); | ||
646 | if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { | ||
647 | char *proto, *data; | ||
648 | /* Get reasonable local authentication information. */ | ||
649 | client_x11_get_proto(display, options.xauth_location, | ||
650 | options.forward_x11_trusted, &proto, &data); | ||
651 | /* Request forwarding with authentication spoofing. */ | ||
652 | debug("Requesting X11 forwarding with authentication spoofing."); | ||
653 | x11_request_forwarding_with_spoofing(id, display, proto, data); | ||
654 | /* XXX wait for reply */ | ||
655 | } | ||
656 | |||
657 | if (cctx->want_agent_fwd && options.forward_agent) { | ||
658 | debug("Requesting authentication agent forwarding."); | ||
659 | channel_request_start(id, "auth-agent-req@openssh.com", 0); | ||
660 | packet_send(); | ||
661 | } | ||
662 | |||
642 | client_session2_setup(id, cctx->want_tty, cctx->want_subsys, | 663 | client_session2_setup(id, cctx->want_tty, cctx->want_subsys, |
643 | cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env, | 664 | cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env, |
644 | client_subsystem_reply); | 665 | client_subsystem_reply); |
@@ -704,7 +725,7 @@ client_process_control(fd_set * readset) | |||
704 | buffer_free(&m); | 725 | buffer_free(&m); |
705 | return; | 726 | return; |
706 | } | 727 | } |
707 | if ((ver = buffer_get_char(&m)) != 1) { | 728 | if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { |
708 | error("%s: wrong client version %d", __func__, ver); | 729 | error("%s: wrong client version %d", __func__, ver); |
709 | buffer_free(&m); | 730 | buffer_free(&m); |
710 | close(client_fd); | 731 | close(client_fd); |
@@ -738,7 +759,7 @@ client_process_control(fd_set * readset) | |||
738 | buffer_clear(&m); | 759 | buffer_clear(&m); |
739 | buffer_put_int(&m, allowed); | 760 | buffer_put_int(&m, allowed); |
740 | buffer_put_int(&m, getpid()); | 761 | buffer_put_int(&m, getpid()); |
741 | if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { | 762 | if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { |
742 | error("%s: client msg_send failed", __func__); | 763 | error("%s: client msg_send failed", __func__); |
743 | close(client_fd); | 764 | close(client_fd); |
744 | buffer_free(&m); | 765 | buffer_free(&m); |
@@ -758,7 +779,7 @@ client_process_control(fd_set * readset) | |||
758 | buffer_clear(&m); | 779 | buffer_clear(&m); |
759 | buffer_put_int(&m, allowed); | 780 | buffer_put_int(&m, allowed); |
760 | buffer_put_int(&m, getpid()); | 781 | buffer_put_int(&m, getpid()); |
761 | if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { | 782 | if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { |
762 | error("%s: client msg_send failed", __func__); | 783 | error("%s: client msg_send failed", __func__); |
763 | close(client_fd); | 784 | close(client_fd); |
764 | buffer_free(&m); | 785 | buffer_free(&m); |
@@ -779,7 +800,7 @@ client_process_control(fd_set * readset) | |||
779 | buffer_free(&m); | 800 | buffer_free(&m); |
780 | return; | 801 | return; |
781 | } | 802 | } |
782 | if ((ver = buffer_get_char(&m)) != 1) { | 803 | if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { |
783 | error("%s: wrong client version %d", __func__, ver); | 804 | error("%s: wrong client version %d", __func__, ver); |
784 | buffer_free(&m); | 805 | buffer_free(&m); |
785 | close(client_fd); | 806 | close(client_fd); |
@@ -790,6 +811,8 @@ client_process_control(fd_set * readset) | |||
790 | memset(cctx, 0, sizeof(*cctx)); | 811 | memset(cctx, 0, sizeof(*cctx)); |
791 | cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; | 812 | cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; |
792 | cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; | 813 | cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; |
814 | cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; | ||
815 | cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; | ||
793 | cctx->term = buffer_get_string(&m, &len); | 816 | cctx->term = buffer_get_string(&m, &len); |
794 | 817 | ||
795 | cmd = buffer_get_string(&m, &len); | 818 | cmd = buffer_get_string(&m, &len); |
@@ -823,7 +846,7 @@ client_process_control(fd_set * readset) | |||
823 | 846 | ||
824 | /* This roundtrip is just for synchronisation of ttymodes */ | 847 | /* This roundtrip is just for synchronisation of ttymodes */ |
825 | buffer_clear(&m); | 848 | buffer_clear(&m); |
826 | if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { | 849 | if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { |
827 | error("%s: client msg_send failed", __func__); | 850 | error("%s: client msg_send failed", __func__); |
828 | close(client_fd); | 851 | close(client_fd); |
829 | close(new_fd[0]); | 852 | close(new_fd[0]); |
diff --git a/clientloop.h b/clientloop.h index 71c61b5d2..aed2d918b 100644 --- a/clientloop.h +++ b/clientloop.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.h,v 1.13 2005/06/16 03:38:36 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.h,v 1.14 2005/07/04 00:58:43 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -43,6 +43,9 @@ void client_global_request_reply_fwd(int, u_int32_t, void *); | |||
43 | void client_session2_setup(int, int, int, const char *, struct termios *, | 43 | void client_session2_setup(int, int, int, const char *, struct termios *, |
44 | int, Buffer *, char **, dispatch_fn *); | 44 | int, Buffer *, char **, dispatch_fn *); |
45 | 45 | ||
46 | /* Multiplexing protocol version */ | ||
47 | #define SSHMUX_VER 1 | ||
48 | |||
46 | /* Multiplexing control protocol flags */ | 49 | /* Multiplexing control protocol flags */ |
47 | #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ | 50 | #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ |
48 | #define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ | 51 | #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 *, | |||
50 | 53 | ||
51 | #define SSHMUX_FLAG_TTY (1) /* Request tty on open */ | 54 | #define SSHMUX_FLAG_TTY (1) /* Request tty on open */ |
52 | #define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ | 55 | #define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ |
56 | #define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */ | ||
57 | #define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */ | ||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "includes.h" | 26 | #include "includes.h" |
27 | RCSID("$OpenBSD: misc.c,v 1.32 2005/06/17 02:44:32 djm Exp $"); | 27 | RCSID("$OpenBSD: misc.c,v 1.33 2005/07/04 00:58:43 djm Exp $"); |
28 | 28 | ||
29 | #include "misc.h" | 29 | #include "misc.h" |
30 | #include "log.h" | 30 | #include "log.h" |
@@ -506,3 +506,20 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, | |||
506 | } | 506 | } |
507 | return -1; | 507 | return -1; |
508 | } | 508 | } |
509 | |||
510 | char * | ||
511 | tohex(const u_char *d, u_int l) | ||
512 | { | ||
513 | char b[3], *r; | ||
514 | u_int i, hl; | ||
515 | |||
516 | hl = l * 2 + 1; | ||
517 | r = xmalloc(hl); | ||
518 | *r = '\0'; | ||
519 | for (i = 0; i < l; i++) { | ||
520 | snprintf(b, sizeof(b), "%02x", d[i]); | ||
521 | strlcat(r, b, hl); | ||
522 | } | ||
523 | return (r); | ||
524 | } | ||
525 | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.h,v 1.23 2005/06/06 11:20:36 djm Exp $ */ | 1 | /* $OpenBSD: misc.h,v 1.24 2005/07/04 00:58:43 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -26,6 +26,7 @@ char *colon(char *); | |||
26 | long convtime(const char *); | 26 | long convtime(const char *); |
27 | char *tilde_expand_filename(const char *, uid_t); | 27 | char *tilde_expand_filename(const char *, uid_t); |
28 | char *percent_expand(const char *, ...) __attribute__((sentinel)); | 28 | char *percent_expand(const char *, ...) __attribute__((sentinel)); |
29 | char *tohex(const u_char *, u_int); | ||
29 | 30 | ||
30 | struct passwd *pwcopy(struct passwd *); | 31 | struct passwd *pwcopy(struct passwd *); |
31 | 32 | ||
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.246 2005/06/25 22:47:49 djm Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.247 2005/07/04 00:58:43 djm Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -1250,41 +1250,44 @@ control_client(const char *path) | |||
1250 | error("Control socket connect(%.100s): %s", path, | 1250 | error("Control socket connect(%.100s): %s", path, |
1251 | strerror(errno)); | 1251 | strerror(errno)); |
1252 | } | 1252 | } |
1253 | close(sock); | 1253 | close(sock); |
1254 | return; | 1254 | return; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | if (stdin_null_flag) { | 1257 | if (stdin_null_flag) { |
1258 | if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) | 1258 | if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) |
1259 | fatal("open(/dev/null): %s", strerror(errno)); | 1259 | fatal("open(/dev/null): %s", strerror(errno)); |
1260 | if (dup2(fd, STDIN_FILENO) == -1) | 1260 | if (dup2(fd, STDIN_FILENO) == -1) |
1261 | fatal("dup2: %s", strerror(errno)); | 1261 | fatal("dup2: %s", strerror(errno)); |
1262 | if (fd > STDERR_FILENO) | 1262 | if (fd > STDERR_FILENO) |
1263 | close(fd); | 1263 | close(fd); |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | if ((term = getenv("TERM")) == NULL) | 1266 | term = getenv("TERM"); |
1267 | term = ""; | ||
1268 | 1267 | ||
1269 | flags = 0; | 1268 | flags = 0; |
1270 | if (tty_flag) | 1269 | if (tty_flag) |
1271 | flags |= SSHMUX_FLAG_TTY; | 1270 | flags |= SSHMUX_FLAG_TTY; |
1272 | if (subsystem_flag) | 1271 | if (subsystem_flag) |
1273 | flags |= SSHMUX_FLAG_SUBSYS; | 1272 | flags |= SSHMUX_FLAG_SUBSYS; |
1273 | if (options.forward_x11) | ||
1274 | flags |= SSHMUX_FLAG_X11_FWD; | ||
1275 | if (options.forward_agent) | ||
1276 | flags |= SSHMUX_FLAG_AGENT_FWD; | ||
1274 | 1277 | ||
1275 | buffer_init(&m); | 1278 | buffer_init(&m); |
1276 | 1279 | ||
1277 | /* Send our command to server */ | 1280 | /* Send our command to server */ |
1278 | buffer_put_int(&m, mux_command); | 1281 | buffer_put_int(&m, mux_command); |
1279 | buffer_put_int(&m, flags); | 1282 | buffer_put_int(&m, flags); |
1280 | if (ssh_msg_send(sock, /* version */1, &m) == -1) | 1283 | if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) |
1281 | fatal("%s: msg_send", __func__); | 1284 | fatal("%s: msg_send", __func__); |
1282 | buffer_clear(&m); | 1285 | buffer_clear(&m); |
1283 | 1286 | ||
1284 | /* Get authorisation status and PID of controlee */ | 1287 | /* Get authorisation status and PID of controlee */ |
1285 | if (ssh_msg_recv(sock, &m) == -1) | 1288 | if (ssh_msg_recv(sock, &m) == -1) |
1286 | fatal("%s: msg_recv", __func__); | 1289 | fatal("%s: msg_recv", __func__); |
1287 | if (buffer_get_char(&m) != 1) | 1290 | if (buffer_get_char(&m) != SSHMUX_VER) |
1288 | fatal("%s: wrong version", __func__); | 1291 | fatal("%s: wrong version", __func__); |
1289 | if (buffer_get_int(&m) != 1) | 1292 | if (buffer_get_int(&m) != 1) |
1290 | fatal("Connection to master denied"); | 1293 | fatal("Connection to master denied"); |
@@ -1308,7 +1311,7 @@ control_client(const char *path) | |||
1308 | } | 1311 | } |
1309 | 1312 | ||
1310 | /* SSHMUX_COMMAND_OPEN */ | 1313 | /* SSHMUX_COMMAND_OPEN */ |
1311 | buffer_put_cstring(&m, term); | 1314 | buffer_put_cstring(&m, term ? term : ""); |
1312 | buffer_append(&command, "\0", 1); | 1315 | buffer_append(&command, "\0", 1); |
1313 | buffer_put_cstring(&m, buffer_ptr(&command)); | 1316 | buffer_put_cstring(&m, buffer_ptr(&command)); |
1314 | 1317 | ||
@@ -1330,7 +1333,7 @@ control_client(const char *path) | |||
1330 | } | 1333 | } |
1331 | } | 1334 | } |
1332 | 1335 | ||
1333 | if (ssh_msg_send(sock, /* version */1, &m) == -1) | 1336 | if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) |
1334 | fatal("%s: msg_send", __func__); | 1337 | fatal("%s: msg_send", __func__); |
1335 | 1338 | ||
1336 | mm_send_fd(sock, STDIN_FILENO); | 1339 | mm_send_fd(sock, STDIN_FILENO); |
@@ -1341,7 +1344,7 @@ control_client(const char *path) | |||
1341 | buffer_clear(&m); | 1344 | buffer_clear(&m); |
1342 | if (ssh_msg_recv(sock, &m) == -1) | 1345 | if (ssh_msg_recv(sock, &m) == -1) |
1343 | fatal("%s: msg_recv", __func__); | 1346 | fatal("%s: msg_recv", __func__); |
1344 | if (buffer_get_char(&m) != 1) | 1347 | if (buffer_get_char(&m) != SSHMUX_VER) |
1345 | fatal("%s: wrong version", __func__); | 1348 | fatal("%s: wrong version", __func__); |
1346 | buffer_free(&m); | 1349 | buffer_free(&m); |
1347 | 1350 | ||
diff --git a/ssh_config.5 b/ssh_config.5 index 3e7ca8f28..40774297c 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -34,7 +34,7 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .\" $OpenBSD: ssh_config.5,v 1.57 2005/06/18 04:30:36 djm Exp $ | 37 | .\" $OpenBSD: ssh_config.5,v 1.58 2005/07/04 00:58:43 djm Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSH_CONFIG 5 | 39 | .Dt SSH_CONFIG 5 |
40 | .Os | 40 | .Os |
@@ -279,6 +279,12 @@ can not be opened, | |||
279 | .Nm ssh | 279 | .Nm ssh |
280 | will continue without connecting to a master instance. | 280 | will continue without connecting to a master instance. |
281 | .Pp | 281 | .Pp |
282 | X11 and | ||
283 | .Xr ssh-agent 4 | ||
284 | forwarding is supported over these multiplexed connections, however the | ||
285 | display and agent fowarded will be the one belonging to the master | ||
286 | connection. I.e. it is not possible to forward multiple displays or agents. | ||
287 | .Pp | ||
282 | Two additional options allow for opportunistic multiplexing: try to use a | 288 | Two additional options allow for opportunistic multiplexing: try to use a |
283 | master connection but fall back to creating a new one if one does not already | 289 | master connection but fall back to creating a new one if one does not already |
284 | exist. | 290 | exist. |