File n_If-auth-with-credentials-for-hostname-fails-retry-with-XAUTHLOCALHOSTNAME.patch of Package libxcb.8586

From: Egbert Eich <eich@suse.de>
Date: Thu Dec 24 00:11:43 2015 +0100
Subject: [PATCH]If auth with credentials for hostname fails retry with XAUTHLOCALHOSTNAME
Patch-mainline: never

References: boo#906622
Signed-off-by: Egbert Eich <eich@suse.com>

Signed-off-by: Egbert Eich <eich@suse.de>
---
 src/xcb_auth.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

Index: libxcb-1.12/src/xcb_auth.c
===================================================================
--- libxcb-1.12.orig/src/xcb_auth.c
+++ libxcb-1.12/src/xcb_auth.c
@@ -109,7 +109,7 @@ static int authname_match(enum auth_prot
 
 #define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr)
 
-static Xauth *get_authptr(struct sockaddr *sockname, int display)
+static Xauth *get_authptr(struct sockaddr *sockname, int display, int *stage)
 {
     char *addr = 0;
     int addrlen = 0;
@@ -119,6 +119,8 @@ static Xauth *get_authptr(struct sockadd
     int dispbuflen;
     Xauth *authptr = NULL;
 
+    if (*stage == 2)
+        return NULL;
     family = FamilyLocal; /* 256 */
     switch(sockname->sa_family)
     {
@@ -161,18 +163,23 @@ static Xauth *get_authptr(struct sockadd
         addrlen = strlen(addr);
     }
 
-    authptr = XauGetBestAuthByAddr (family,
-                                 (unsigned short) addrlen, addr,
-                                 (unsigned short) dispbuflen, dispbuf,
-                                 N_AUTH_PROTOS, authnames, authnameslen);
-    // && !phostname
-    if ((!authptr || !authptr->data_length) && family == FamilyLocal) {
-        if ( (addr = getenv("XAUTHLOCALHOSTNAME")) ) {
+    if (*stage == 0) {
+        authptr = XauGetBestAuthByAddr (family,
+                                       (unsigned short) addrlen, addr,
+                                       (unsigned short) dispbuflen, dispbuf,
+                                       N_AUTH_PROTOS, authnames, authnameslen);
+        *stage = 1;
+        return authptr;
+    }
+    if (*stage == 1) {
+        if ((!authptr || !authptr->data_length) && family == FamilyLocal && (addr = getenv("XAUTHLOCALHOSTNAME"))) {
             authptr = XauGetBestAuthByAddr (family,
                                            (unsigned short) strlen(addr), addr,
                                            (unsigned short) dispbuflen, dispbuf,
                                            N_AUTH_PROTOS, authnames, authnameslen);
         }
+        *stage = 2;
+        return authptr;
     }
     return authptr;
 }
@@ -320,7 +327,7 @@ static struct sockaddr *get_peer_sock_na
     return NULL;
 }
 
-int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
+int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display, int *stage)
 {
     /* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c,
        xtrans/Xtransutils.c */
@@ -345,7 +352,7 @@ int _xcb_get_auth_info(int fd, xcb_auth_
         gotsockname = 1;
     }
 
-    authptr = get_authptr(sockname, display);
+    authptr = get_authptr(sockname, display, stage);
     if (authptr == 0)
     {
         free(sockname);
Index: libxcb-1.12/src/xcbint.h
===================================================================
--- libxcb-1.12.orig/src/xcbint.h
+++ libxcb-1.12/src/xcbint.h
@@ -219,7 +219,7 @@ int _xcb_conn_wait(xcb_connection_t *c,
 
 /* xcb_auth.c */
 
-int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display);
+int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display, int *stage);
 
 #ifdef GCC_HAS_VISIBILITY
 #pragma GCC visibility pop
Index: libxcb-1.12/src/xcb_util.c
===================================================================
--- libxcb-1.12.orig/src/xcb_util.c
+++ libxcb-1.12/src/xcb_util.c
@@ -494,6 +494,7 @@ xcb_connection_t *xcb_connect_to_display
     char *protocol = NULL;
     xcb_auth_info_t ourauth;
     xcb_connection_t *c;
+    int stage = 0;
 
     int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp);
 
@@ -510,6 +511,7 @@ xcb_connection_t *xcb_connect_to_display
     }
 #endif
 
+    retry:
     fd = _xcb_open(host, protocol, display);
 
     if(fd == -1) {
@@ -525,7 +527,7 @@ xcb_connection_t *xcb_connect_to_display
         goto out;
     }
 
-    if(_xcb_get_auth_info(fd, &ourauth, display))
+    if(_xcb_get_auth_info(fd, &ourauth, display, &stage))
     {
         c = xcb_connect_to_fd(fd, &ourauth);
         free(ourauth.name);
@@ -534,8 +536,11 @@ xcb_connection_t *xcb_connect_to_display
     else
         c = xcb_connect_to_fd(fd, 0);
 
-    if(c->has_error)
+    if(c->has_error) {
+        if (stage < 2)
+            goto retry;
         goto out;
+    }
 
     /* Make sure requested screen number is in bounds for this server */
     if((screenp != NULL) && (*screenp >= (int) c->setup->roots_len)) {