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....@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....@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 via email to