[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#691844: xauth: Failed X11 forwarding when using GDM via XDMCP



Package: xauth
Version: 1:1.0.4-1
Severity: normal
Tags: upstream patch


When using GDM via XDMCP, for examle when accessing GDM via
vncserver->XDMCP->localhost, ssh is no longer able to forward X11.

	Invalid MIT-MAGIC-COOKIE-1 keyxterm Xt error: Can't open display:
	localhost:10.0

The problem is, that xauth is unable to deal with the Family "FamilyWild" which
is used by GDM in XDMCP to store the MIT-MAGIC-COOKIE-1 for the user.

Attached are two patches, one for 1.0.4-1 and one for 1.0.7-1. The original
Patch is by Dr. Tilmann Bubeck.

Upstream Bug is at

	https://bugs.freedesktop.org/show_bug.cgi?id=43425

FWIW, Redhat also has a bug for this:

	https://bugzilla.redhat.com/show_bug.cgi?id=505545

-- System Information:
Debian Release: 6.0.6
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.32-5-xen-686 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages xauth depends on:
ii  libc6                         2.11.3-4   Embedded GNU C Library: Shared lib
ii  libx11-6                      2:1.3.3-4  X11 client-side library
ii  libxau6                       1:1.0.6-1  X11 authorisation library
ii  libxext6                      2:1.1.2-1  X11 miscellaneous extension librar
ii  libxmuu1                      2:1.0.5-2  X11 miscellaneous micro-utility li

xauth recommends no packages.

xauth suggests no packages.

-- no debconf information
>From 5da21eaf6ec6537c3aab23adbebd617050e0c2c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20V=C3=B6lkel?= <stefan.volkel.ext@nsn.com>
Date: Wed, 8 Aug 2012 14:13:08 +0200
Subject: [PATCH] improve to handle FamilyWild necessary for GDM/XDMCP/SSH #43425

---
 process.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/process.c b/process.c
index 893b51d..5a3984c 100644
--- a/process.c
+++ b/process.c
@@ -465,8 +465,11 @@ read_auth_entries(FILE *fp, Bool numeric, AuthList **headp, AuthList **tailp)
     return n;
 }
 
-static Bool 
-get_displayname_auth(char *displayname, AuthList **authl)
+/**
+ * Parse the given displayname and build a corresponding AuthList.
+ */
+static Bool
+get_displayname_auth(const char *displayname, AuthList **authl)
 {
     int family;
     char *host = NULL, *rest = NULL;
@@ -997,6 +1000,9 @@ dump_entry(char *inputfilename, int lineno, Xauth *auth, char *data)
 	    fwrite (auth->address, sizeof (char), auth->address_length, fp);
 	    fprintf (fp, "/unix");
 	    break;
+	  case FamilyWild:
+	    fwrite (auth->address, sizeof (char), auth->address_length, fp);
+	    break;
 	  case FamilyInternet:
 #if defined(IPv6) && defined(AF_INET6)
 	  case FamilyInternet6:
@@ -1079,6 +1085,49 @@ match_auth_dpy(register Xauth *a, register Xauth *b)
 	     memcmp(a->number, b->number, a->number_length) == 0) ? 1 : 0);
 }
 
+static int
+match_authwild_dpy(register Xauth *a, const char *displayname)
+{
+    int family;
+    char *host = NULL, *rest = NULL;
+    int dpynum, scrnum;
+    char dpynumbuf[40];			/* want to hold largest display num */
+
+    if ( a->family != FamilyWild )
+	return False;
+
+    if (!parse_displayname (displayname,
+			    &family, &host, &dpynum, &scrnum, &rest)) {
+	free(host);
+	free(rest);
+
+	return False;
+    }
+
+    dpynumbuf[0] = '\0';
+    sprintf (dpynumbuf, "%d", dpynum);
+
+    if (a->address_length != strlen(host) || a->number_length != strlen(dpynumbuf)) {
+	free(host);
+	free(rest);
+
+        return False;
+    }
+
+    if (memcmp(a->address, host, a->address_length) == 0 &&
+        memcmp(a->number, dpynumbuf, a->number_length) == 0) {
+	free(host);
+	free(rest);
+
+        return True;
+    } else {
+	free(host);
+	free(rest);
+
+        return False;
+   }
+}
+
 /* return non-zero iff display and authorization type are the same */
 
 static int 
@@ -1242,13 +1291,22 @@ iterdpy (char *inputfilename, int lineno, int start,
 	    /* l may be freed by remove_entry below. so save its contents */
 	    next = l->next;
 	    tmp_auth = copyAuth(l->auth);
-	    for (proto = proto_head; proto; proto = proto->next) {
-		if (match_auth_dpy (proto->auth, tmp_auth)) {
-		    matched = True;
-		    if (yfunc) {
-			status = (*yfunc) (inputfilename, lineno,
-					   tmp_auth, data);
-			if (status < 0) break;
+
+	    if ( match_authwild_dpy(tmp_auth, displayname) ) {
+	        matched = True;
+		if (yfunc) {
+		    status = (*yfunc) (inputfilename, lineno,
+				       tmp_auth, data);
+		}
+	    } else {
+	        for (proto = proto_head; proto; proto = proto->next) {
+		    if (match_auth_dpy (proto->auth, tmp_auth)) {
+		        matched = True;
+		        if (yfunc) {
+			    status = (*yfunc) (inputfilename, lineno,
+					       tmp_auth, data);
+			    if (status < 0) break;
+			}
 		    }
 		}
 	    }
-- 
1.7.2.5

>From 1c84f163fd3dcdcb8b1193cc2debe08addf38551 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20V=C3=B6lkel?= <stefan.volkel.ext@nsn.com>
Date: Wed, 8 Aug 2012 14:13:08 +0200
Subject: [PATCH] improve to handle FamilyWild necessary for GDM/XDMCP/SSH #43425

---
 process.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/process.c b/process.c
index 283b4a1..03ea366 100644
--- a/process.c
+++ b/process.c
@@ -462,6 +462,9 @@ read_auth_entries(FILE *fp, Bool numeric, AuthList **headp, AuthList **tailp)
     return n;
 }
 
+/**
+ * Parse the given displayname and build a corresponding AuthList.
+ */
 static Bool
 get_displayname_auth(const char *displayname, AuthList **authl)
 {
@@ -991,6 +994,9 @@ dump_entry(const char *inputfilename, int lineno, Xauth *auth, char *data)
 	    fwrite (auth->address, sizeof (char), auth->address_length, fp);
 	    fprintf (fp, "/unix");
 	    break;
+	  case FamilyWild:
+	    fwrite (auth->address, sizeof (char), auth->address_length, fp);
+	    break;
 	  case FamilyInternet:
 #if defined(IPv6) && defined(AF_INET6)
 	  case FamilyInternet6:
@@ -1073,6 +1079,49 @@ match_auth_dpy(register Xauth *a, register Xauth *b)
 	     memcmp(a->number, b->number, a->number_length) == 0) ? 1 : 0);
 }
 
+static int
+match_authwild_dpy(register Xauth *a, const char *displayname)
+{
+    int family;
+    char *host = NULL, *rest = NULL;
+    int dpynum, scrnum;
+    char dpynumbuf[40];			/* want to hold largest display num */
+
+    if ( a->family != FamilyWild )
+	return False;
+
+    if (!parse_displayname (displayname,
+			    &family, &host, &dpynum, &scrnum, &rest)) {
+	free(host);
+	free(rest);
+
+	return False;
+    }
+
+    dpynumbuf[0] = '\0';
+    sprintf (dpynumbuf, "%d", dpynum);
+
+    if (a->address_length != strlen(host) || a->number_length != strlen(dpynumbuf)) {
+	free(host);
+	free(rest);
+
+        return False;
+    }
+
+    if (memcmp(a->address, host, a->address_length) == 0 &&
+        memcmp(a->number, dpynumbuf, a->number_length) == 0) {
+	free(host);
+	free(rest);
+
+        return True;
+    } else {
+	free(host);
+	free(rest);
+
+        return False;
+   }
+}
+
 /* return non-zero iff display and authorization type are the same */
 
 static int
@@ -1236,13 +1285,22 @@ iterdpy (const char *inputfilename, int lineno, int start,
 	    /* l may be freed by remove_entry below. so save its contents */
 	    next = l->next;
 	    tmp_auth = copyAuth(l->auth);
-	    for (proto = proto_head; proto; proto = proto->next) {
-		if (match_auth_dpy (proto->auth, tmp_auth)) {
-		    matched = True;
-		    if (yfunc) {
-			status = (*yfunc) (inputfilename, lineno,
-					   tmp_auth, data);
-			if (status < 0) break;
+
+	    if ( match_authwild_dpy(tmp_auth, displayname) ) {
+	        matched = True;
+		if (yfunc) {
+		    status = (*yfunc) (inputfilename, lineno,
+				       tmp_auth, data);
+		}
+	    } else {
+	        for (proto = proto_head; proto; proto = proto->next) {
+		    if (match_auth_dpy (proto->auth, tmp_auth)) {
+		        matched = True;
+		        if (yfunc) {
+			    status = (*yfunc) (inputfilename, lineno,
+					       tmp_auth, data);
+			    if (status < 0) break;
+			}
 		    }
 		}
 	    }
-- 
1.7.2.5


Reply to: