From 17e7ed0e754577ae61cdd5e3f03b33fba2a09337 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 17 Jun 2005 12:54:33 +1000 Subject: - (djm) OpenBSD CVS Sync - djm@cvs.openbsd.org 2005/06/16 03:38:36 [channels.c channels.h clientloop.c clientloop.h ssh.c] move x11_get_proto from ssh.c to clientloop.c, to make muliplexed xfwd easier later; ok deraadt@ --- clientloop.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'clientloop.c') diff --git a/clientloop.c b/clientloop.c index ae4dce82..ee36cc9e 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.137 2005/06/08 11:25:09 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.138 2005/06/16 03:38:36 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -208,6 +208,109 @@ get_current_time(void) return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; } +#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" +void +client_x11_get_proto(const char *display, const char *xauth_path, + u_int trusted, char **_proto, char **_data) +{ + char cmd[1024]; + char line[512]; + char xdisplay[512]; + static char proto[512], data[512]; + FILE *f; + int got_data = 0, generated = 0, do_unlink = 0, i; + char *xauthdir, *xauthfile; + struct stat st; + + xauthdir = xauthfile = NULL; + *_proto = proto; + *_data = data; + proto[0] = data[0] = '\0'; + + if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { + debug("No xauth program."); + } else { + if (display == NULL) { + debug("x11_get_proto: DISPLAY not set"); + return; + } + /* + * Handle FamilyLocal case where $DISPLAY does + * not match an authorization entry. For this we + * just try "xauth list unix:displaynum.screennum". + * XXX: "localhost" match to determine FamilyLocal + * is not perfect. + */ + if (strncmp(display, "localhost:", 10) == 0) { + snprintf(xdisplay, sizeof(xdisplay), "unix:%s", + display + 10); + display = xdisplay; + } + if (trusted == 0) { + xauthdir = xmalloc(MAXPATHLEN); + xauthfile = xmalloc(MAXPATHLEN); + strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); + if (mkdtemp(xauthdir) != NULL) { + do_unlink = 1; + snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", + xauthdir); + snprintf(cmd, sizeof(cmd), + "%s -f %s generate %s " SSH_X11_PROTO + " untrusted timeout 1200 2>" _PATH_DEVNULL, + xauth_path, xauthfile, display); + debug2("x11_get_proto: %s", cmd); + if (system(cmd) == 0) + generated = 1; + } + } + snprintf(cmd, sizeof(cmd), + "%s %s%s list %s . 2>" _PATH_DEVNULL, + xauth_path, + generated ? "-f " : "" , + generated ? xauthfile : "", + display); + debug2("x11_get_proto: %s", cmd); + f = popen(cmd, "r"); + if (f && fgets(line, sizeof(line), f) && + sscanf(line, "%*s %511s %511s", proto, data) == 2) + got_data = 1; + if (f) + pclose(f); + } + + if (do_unlink) { + unlink(xauthfile); + rmdir(xauthdir); + } + if (xauthdir) + xfree(xauthdir); + if (xauthfile) + xfree(xauthfile); + + /* + * 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 rnd = 0; + + logit("Warning: No xauth data; " + "using fake authentication data for X11 forwarding."); + strlcpy(proto, SSH_X11_PROTO, sizeof proto); + for (i = 0; i < 16; i++) { + if (i % 4 == 0) + rnd = arc4random(); + snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", + rnd & 0xff); + rnd >>= 8; + } + } +} + /* * This is called when the interactive is entered. This checks if there is * an EOF coming on stdin. We must check this explicitly, as select() does -- cgit v1.2.3