diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | channels.c | 10 | ||||
-rw-r--r-- | channels.h | 5 | ||||
-rw-r--r-- | clientloop.c | 105 | ||||
-rw-r--r-- | clientloop.h | 4 | ||||
-rw-r--r-- | ssh.c | 126 |
6 files changed, 138 insertions, 122 deletions
@@ -1,3 +1,11 @@ | |||
1 | 20050617 | ||
2 | - (djm) OpenBSD CVS Sync | ||
3 | - djm@cvs.openbsd.org 2005/06/16 03:38:36 | ||
4 | [channels.c channels.h clientloop.c clientloop.h ssh.c] | ||
5 | move x11_get_proto from ssh.c to clientloop.c, to make muliplexed xfwd | ||
6 | easier later; ok deraadt@ | ||
7 | |||
8 | |||
1 | 20050616 | 9 | 20050616 |
2 | - (djm) OpenBSD CVS Sync | 10 | - (djm) OpenBSD CVS Sync |
3 | - jaredy@cvs.openbsd.org 2005/06/07 13:25:23 | 11 | - jaredy@cvs.openbsd.org 2005/06/07 13:25:23 |
@@ -2714,4 +2722,4 @@ | |||
2714 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2722 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2715 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2723 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2716 | 2724 | ||
2717 | $Id: ChangeLog,v 1.3820 2005/06/16 03:21:17 djm Exp $ | 2725 | $Id: ChangeLog,v 1.3821 2005/06/17 02:54:33 djm Exp $ |
diff --git a/channels.c b/channels.c index 3f6db60c6..440043b9c 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.214 2005/03/14 11:46:56 markus Exp $"); | 42 | RCSID("$OpenBSD: channels.c,v 1.215 2005/06/16 03:38:36 djm Exp $"); |
43 | 43 | ||
44 | #include "ssh.h" | 44 | #include "ssh.h" |
45 | #include "ssh1.h" | 45 | #include "ssh1.h" |
@@ -2952,7 +2952,7 @@ deny_input_open(int type, u_int32_t seq, void *ctxt) | |||
2952 | * This should be called in the client only. | 2952 | * This should be called in the client only. |
2953 | */ | 2953 | */ |
2954 | void | 2954 | void |
2955 | x11_request_forwarding_with_spoofing(int client_session_id, | 2955 | x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, |
2956 | const char *proto, const char *data) | 2956 | const char *proto, const char *data) |
2957 | { | 2957 | { |
2958 | u_int data_len = (u_int) strlen(data) / 2; | 2958 | u_int data_len = (u_int) strlen(data) / 2; |
@@ -2962,9 +2962,9 @@ x11_request_forwarding_with_spoofing(int client_session_id, | |||
2962 | const char *cp; | 2962 | const char *cp; |
2963 | u_int32_t rnd = 0; | 2963 | u_int32_t rnd = 0; |
2964 | 2964 | ||
2965 | cp = getenv("DISPLAY"); | 2965 | cp = disp; |
2966 | if (cp) | 2966 | if (disp) |
2967 | cp = strchr(cp, ':'); | 2967 | cp = strchr(disp, ':'); |
2968 | if (cp) | 2968 | if (cp) |
2969 | cp = strchr(cp, '.'); | 2969 | cp = strchr(cp, '.'); |
2970 | if (cp) | 2970 | if (cp) |
diff --git a/channels.h b/channels.h index fc20fb2c3..f87db6afb 100644 --- a/channels.h +++ b/channels.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.h,v 1.76 2005/03/01 10:09:52 djm Exp $ */ | 1 | /* $OpenBSD: channels.h,v 1.77 2005/06/16 03:38:36 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -216,7 +216,8 @@ int channel_cancel_rport_listener(const char *, u_short); | |||
216 | int x11_connect_display(void); | 216 | int x11_connect_display(void); |
217 | int x11_create_display_inet(int, int, int, u_int *); | 217 | int x11_create_display_inet(int, int, int, u_int *); |
218 | void x11_input_open(int, u_int32_t, void *); | 218 | void x11_input_open(int, u_int32_t, void *); |
219 | void x11_request_forwarding_with_spoofing(int, const char *, const char *); | 219 | void x11_request_forwarding_with_spoofing(int, const char *, const char *, |
220 | const char *); | ||
220 | void deny_input_open(int, u_int32_t, void *); | 221 | void deny_input_open(int, u_int32_t, void *); |
221 | 222 | ||
222 | /* agent forwarding */ | 223 | /* agent forwarding */ |
diff --git a/clientloop.c b/clientloop.c index ae4dce820..ee36cc9e5 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.137 2005/06/08 11:25:09 djm Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.138 2005/06/16 03:38:36 djm Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -208,6 +208,109 @@ get_current_time(void) | |||
208 | return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; | 208 | return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; |
209 | } | 209 | } |
210 | 210 | ||
211 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" | ||
212 | void | ||
213 | client_x11_get_proto(const char *display, const char *xauth_path, | ||
214 | u_int trusted, char **_proto, char **_data) | ||
215 | { | ||
216 | char cmd[1024]; | ||
217 | char line[512]; | ||
218 | char xdisplay[512]; | ||
219 | static char proto[512], data[512]; | ||
220 | FILE *f; | ||
221 | int got_data = 0, generated = 0, do_unlink = 0, i; | ||
222 | char *xauthdir, *xauthfile; | ||
223 | struct stat st; | ||
224 | |||
225 | xauthdir = xauthfile = NULL; | ||
226 | *_proto = proto; | ||
227 | *_data = data; | ||
228 | proto[0] = data[0] = '\0'; | ||
229 | |||
230 | if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { | ||
231 | debug("No xauth program."); | ||
232 | } else { | ||
233 | if (display == NULL) { | ||
234 | debug("x11_get_proto: DISPLAY not set"); | ||
235 | return; | ||
236 | } | ||
237 | /* | ||
238 | * Handle FamilyLocal case where $DISPLAY does | ||
239 | * not match an authorization entry. For this we | ||
240 | * just try "xauth list unix:displaynum.screennum". | ||
241 | * XXX: "localhost" match to determine FamilyLocal | ||
242 | * is not perfect. | ||
243 | */ | ||
244 | if (strncmp(display, "localhost:", 10) == 0) { | ||
245 | snprintf(xdisplay, sizeof(xdisplay), "unix:%s", | ||
246 | display + 10); | ||
247 | display = xdisplay; | ||
248 | } | ||
249 | if (trusted == 0) { | ||
250 | xauthdir = xmalloc(MAXPATHLEN); | ||
251 | xauthfile = xmalloc(MAXPATHLEN); | ||
252 | strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); | ||
253 | if (mkdtemp(xauthdir) != NULL) { | ||
254 | do_unlink = 1; | ||
255 | snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", | ||
256 | xauthdir); | ||
257 | snprintf(cmd, sizeof(cmd), | ||
258 | "%s -f %s generate %s " SSH_X11_PROTO | ||
259 | " untrusted timeout 1200 2>" _PATH_DEVNULL, | ||
260 | xauth_path, xauthfile, display); | ||
261 | debug2("x11_get_proto: %s", cmd); | ||
262 | if (system(cmd) == 0) | ||
263 | generated = 1; | ||
264 | } | ||
265 | } | ||
266 | snprintf(cmd, sizeof(cmd), | ||
267 | "%s %s%s list %s . 2>" _PATH_DEVNULL, | ||
268 | xauth_path, | ||
269 | generated ? "-f " : "" , | ||
270 | generated ? xauthfile : "", | ||
271 | display); | ||
272 | debug2("x11_get_proto: %s", cmd); | ||
273 | f = popen(cmd, "r"); | ||
274 | if (f && fgets(line, sizeof(line), f) && | ||
275 | sscanf(line, "%*s %511s %511s", proto, data) == 2) | ||
276 | got_data = 1; | ||
277 | if (f) | ||
278 | pclose(f); | ||
279 | } | ||
280 | |||
281 | if (do_unlink) { | ||
282 | unlink(xauthfile); | ||
283 | rmdir(xauthdir); | ||
284 | } | ||
285 | if (xauthdir) | ||
286 | xfree(xauthdir); | ||
287 | if (xauthfile) | ||
288 | xfree(xauthfile); | ||
289 | |||
290 | /* | ||
291 | * If we didn't get authentication data, just make up some | ||
292 | * data. The forwarding code will check the validity of the | ||
293 | * response anyway, and substitute this data. The X11 | ||
294 | * server, however, will ignore this fake data and use | ||
295 | * whatever authentication mechanisms it was using otherwise | ||
296 | * for the local connection. | ||
297 | */ | ||
298 | if (!got_data) { | ||
299 | u_int32_t rnd = 0; | ||
300 | |||
301 | logit("Warning: No xauth data; " | ||
302 | "using fake authentication data for X11 forwarding."); | ||
303 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); | ||
304 | for (i = 0; i < 16; i++) { | ||
305 | if (i % 4 == 0) | ||
306 | rnd = arc4random(); | ||
307 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", | ||
308 | rnd & 0xff); | ||
309 | rnd >>= 8; | ||
310 | } | ||
311 | } | ||
312 | } | ||
313 | |||
211 | /* | 314 | /* |
212 | * This is called when the interactive is entered. This checks if there is | 315 | * This is called when the interactive is entered. This checks if there is |
213 | * an EOF coming on stdin. We must check this explicitly, as select() does | 316 | * an EOF coming on stdin. We must check this explicitly, as select() does |
diff --git a/clientloop.h b/clientloop.h index b23c111cb..71c61b5d2 100644 --- a/clientloop.h +++ b/clientloop.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.h,v 1.12 2004/11/07 00:01:46 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.h,v 1.13 2005/06/16 03:38:36 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | /* Client side main loop for the interactive session. */ | 38 | /* Client side main loop for the interactive session. */ |
39 | int client_loop(int, int, int); | 39 | int client_loop(int, int, int); |
40 | void client_x11_get_proto(const char *, const char *, u_int, | ||
41 | char **, char **); | ||
40 | void client_global_request_reply_fwd(int, u_int32_t, void *); | 42 | void client_global_request_reply_fwd(int, u_int32_t, void *); |
41 | void client_session2_setup(int, int, int, const char *, struct termios *, | 43 | void client_session2_setup(int, int, int, const char *, struct termios *, |
42 | int, Buffer *, char **, dispatch_fn *); | 44 | int, Buffer *, char **, dispatch_fn *); |
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.242 2005/06/08 11:25:09 djm Exp $"); | 43 | RCSID("$OpenBSD: ssh.c,v 1.243 2005/06/16 03:38:36 djm Exp $"); |
44 | 44 | ||
45 | #include <openssl/evp.h> | 45 | #include <openssl/evp.h> |
46 | #include <openssl/err.h> | 46 | #include <openssl/err.h> |
@@ -750,110 +750,6 @@ again: | |||
750 | return exit_status; | 750 | return exit_status; |
751 | } | 751 | } |
752 | 752 | ||
753 | #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" | ||
754 | |||
755 | static void | ||
756 | x11_get_proto(char **_proto, char **_data) | ||
757 | { | ||
758 | char cmd[1024]; | ||
759 | char line[512]; | ||
760 | char xdisplay[512]; | ||
761 | static char proto[512], data[512]; | ||
762 | FILE *f; | ||
763 | int got_data = 0, generated = 0, do_unlink = 0, i; | ||
764 | char *display, *xauthdir, *xauthfile; | ||
765 | struct stat st; | ||
766 | |||
767 | xauthdir = xauthfile = NULL; | ||
768 | *_proto = proto; | ||
769 | *_data = data; | ||
770 | proto[0] = data[0] = '\0'; | ||
771 | |||
772 | if (!options.xauth_location || | ||
773 | (stat(options.xauth_location, &st) == -1)) { | ||
774 | debug("No xauth program."); | ||
775 | } else { | ||
776 | if ((display = getenv("DISPLAY")) == NULL) { | ||
777 | debug("x11_get_proto: DISPLAY not set"); | ||
778 | return; | ||
779 | } | ||
780 | /* | ||
781 | * Handle FamilyLocal case where $DISPLAY does | ||
782 | * not match an authorization entry. For this we | ||
783 | * just try "xauth list unix:displaynum.screennum". | ||
784 | * XXX: "localhost" match to determine FamilyLocal | ||
785 | * is not perfect. | ||
786 | */ | ||
787 | if (strncmp(display, "localhost:", 10) == 0) { | ||
788 | snprintf(xdisplay, sizeof(xdisplay), "unix:%s", | ||
789 | display + 10); | ||
790 | display = xdisplay; | ||
791 | } | ||
792 | if (options.forward_x11_trusted == 0) { | ||
793 | xauthdir = xmalloc(MAXPATHLEN); | ||
794 | xauthfile = xmalloc(MAXPATHLEN); | ||
795 | strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); | ||
796 | if (mkdtemp(xauthdir) != NULL) { | ||
797 | do_unlink = 1; | ||
798 | snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", | ||
799 | xauthdir); | ||
800 | snprintf(cmd, sizeof(cmd), | ||
801 | "%s -f %s generate %s " SSH_X11_PROTO | ||
802 | " untrusted timeout 1200 2>" _PATH_DEVNULL, | ||
803 | options.xauth_location, xauthfile, display); | ||
804 | debug2("x11_get_proto: %s", cmd); | ||
805 | if (system(cmd) == 0) | ||
806 | generated = 1; | ||
807 | } | ||
808 | } | ||
809 | snprintf(cmd, sizeof(cmd), | ||
810 | "%s %s%s list %s . 2>" _PATH_DEVNULL, | ||
811 | options.xauth_location, | ||
812 | generated ? "-f " : "" , | ||
813 | generated ? xauthfile : "", | ||
814 | display); | ||
815 | debug2("x11_get_proto: %s", cmd); | ||
816 | f = popen(cmd, "r"); | ||
817 | if (f && fgets(line, sizeof(line), f) && | ||
818 | sscanf(line, "%*s %511s %511s", proto, data) == 2) | ||
819 | got_data = 1; | ||
820 | if (f) | ||
821 | pclose(f); | ||
822 | } | ||
823 | |||
824 | if (do_unlink) { | ||
825 | unlink(xauthfile); | ||
826 | rmdir(xauthdir); | ||
827 | } | ||
828 | if (xauthdir) | ||
829 | xfree(xauthdir); | ||
830 | if (xauthfile) | ||
831 | xfree(xauthfile); | ||
832 | |||
833 | /* | ||
834 | * If we didn't get authentication data, just make up some | ||
835 | * data. The forwarding code will check the validity of the | ||
836 | * response anyway, and substitute this data. The X11 | ||
837 | * server, however, will ignore this fake data and use | ||
838 | * whatever authentication mechanisms it was using otherwise | ||
839 | * for the local connection. | ||
840 | */ | ||
841 | if (!got_data) { | ||
842 | u_int32_t rnd = 0; | ||
843 | |||
844 | logit("Warning: No xauth data; " | ||
845 | "using fake authentication data for X11 forwarding."); | ||
846 | strlcpy(proto, SSH_X11_PROTO, sizeof proto); | ||
847 | for (i = 0; i < 16; i++) { | ||
848 | if (i % 4 == 0) | ||
849 | rnd = arc4random(); | ||
850 | snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", | ||
851 | rnd & 0xff); | ||
852 | rnd >>= 8; | ||
853 | } | ||
854 | } | ||
855 | } | ||
856 | |||
857 | static void | 753 | static void |
858 | ssh_init_forwarding(void) | 754 | ssh_init_forwarding(void) |
859 | { | 755 | { |
@@ -916,6 +812,7 @@ ssh_session(void) | |||
916 | int have_tty = 0; | 812 | int have_tty = 0; |
917 | struct winsize ws; | 813 | struct winsize ws; |
918 | char *cp; | 814 | char *cp; |
815 | const char *display; | ||
919 | 816 | ||
920 | /* Enable compression if requested. */ | 817 | /* Enable compression if requested. */ |
921 | if (options.compression) { | 818 | if (options.compression) { |
@@ -977,13 +874,15 @@ ssh_session(void) | |||
977 | packet_disconnect("Protocol error waiting for pty request response."); | 874 | packet_disconnect("Protocol error waiting for pty request response."); |
978 | } | 875 | } |
979 | /* Request X11 forwarding if enabled and DISPLAY is set. */ | 876 | /* Request X11 forwarding if enabled and DISPLAY is set. */ |
980 | if (options.forward_x11 && getenv("DISPLAY") != NULL) { | 877 | display = getenv("DISPLAY"); |
878 | if (options.forward_x11 && display != NULL) { | ||
981 | char *proto, *data; | 879 | char *proto, *data; |
982 | /* Get reasonable local authentication information. */ | 880 | /* Get reasonable local authentication information. */ |
983 | x11_get_proto(&proto, &data); | 881 | client_x11_get_proto(display, options.xauth_location, |
882 | options.forward_x11_trusted, &proto, &data); | ||
984 | /* Request forwarding with authentication spoofing. */ | 883 | /* Request forwarding with authentication spoofing. */ |
985 | debug("Requesting X11 forwarding with authentication spoofing."); | 884 | debug("Requesting X11 forwarding with authentication spoofing."); |
986 | x11_request_forwarding_with_spoofing(0, proto, data); | 885 | x11_request_forwarding_with_spoofing(0, display, proto, data); |
987 | 886 | ||
988 | /* Read response from the server. */ | 887 | /* Read response from the server. */ |
989 | type = packet_read(); | 888 | type = packet_read(); |
@@ -1125,15 +1024,18 @@ static void | |||
1125 | ssh_session2_setup(int id, void *arg) | 1024 | ssh_session2_setup(int id, void *arg) |
1126 | { | 1025 | { |
1127 | extern char **environ; | 1026 | extern char **environ; |
1128 | 1027 | const char *display; | |
1129 | int interactive = tty_flag; | 1028 | int interactive = tty_flag; |
1130 | if (options.forward_x11 && getenv("DISPLAY") != NULL) { | 1029 | |
1030 | display = getenv("DISPLAY"); | ||
1031 | if (options.forward_x11 && display != NULL) { | ||
1131 | char *proto, *data; | 1032 | char *proto, *data; |
1132 | /* Get reasonable local authentication information. */ | 1033 | /* Get reasonable local authentication information. */ |
1133 | x11_get_proto(&proto, &data); | 1034 | client_x11_get_proto(display, options.xauth_location, |
1035 | options.forward_x11_trusted, &proto, &data); | ||
1134 | /* Request forwarding with authentication spoofing. */ | 1036 | /* Request forwarding with authentication spoofing. */ |
1135 | debug("Requesting X11 forwarding with authentication spoofing."); | 1037 | debug("Requesting X11 forwarding with authentication spoofing."); |
1136 | x11_request_forwarding_with_spoofing(id, proto, data); | 1038 | x11_request_forwarding_with_spoofing(id, display, proto, data); |
1137 | interactive = 1; | 1039 | interactive = 1; |
1138 | /* XXX wait for reply */ | 1040 | /* XXX wait for reply */ |
1139 | } | 1041 | } |