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

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.16.1/src/xcb_auth.c
===================================================================
--- libxcb-1.16.1.orig/src/xcb_auth.c
+++ libxcb-1.16.1/src/xcb_auth.c
@@ -110,7 +110,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;
@@ -120,6 +120,8 @@ static Xauth *get_authptr(struct sockadd
     int dispbuflen;
     Xauth *authptr = NULL;
 
+    if (*stage == 2)
+        return NULL;
     family = FamilyLocal; /* 256 */
     switch(sockname->sa_family)
     {
@@ -163,18 +165,23 @@ static Xauth *get_authptr(struct sockadd
         addrlen = strlen(addr);
     }
 
-    authptr = XauGetBestAuthByAddr (family,
-                                 (unsigned short) addrlen, addr,
-                                 (unsigned short) dispbuflen, dispbuf,
-                                 N_AUTH_PROTOS, (char **)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, (char **)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, (char **) authnames, authnameslen);
+                                            (unsigned short) strlen(addr), addr,
+                                            (unsigned short) dispbuflen, dispbuf,
+                                            N_AUTH_PROTOS, (char **) authnames, authnameslen);
         }
+        *stage = 2;
+        return authptr;
     }
     return authptr;
 }
@@ -329,7 +336,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 */
@@ -354,7 +361,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.16.1/src/xcbint.h
===================================================================
--- libxcb-1.16.1.orig/src/xcbint.h
+++ libxcb-1.16.1/src/xcbint.h
@@ -232,7 +232,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.16.1/src/xcb_util.c
===================================================================
--- libxcb-1.16.1.orig/src/xcb_util.c
+++ libxcb-1.16.1/src/xcb_util.c
@@ -516,6 +516,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);
 
@@ -532,6 +533,7 @@ xcb_connection_t *xcb_connect_to_display
     }
 #endif
 
+    retry:
     fd = _xcb_open(host, protocol, display);
 
     if(fd == -1) {
@@ -545,7 +547,7 @@ xcb_connection_t *xcb_connect_to_display
     if(auth) {
         c = xcb_connect_to_fd(fd, auth);
     }
-    else if(_xcb_get_auth_info(fd, &ourauth, display))
+    else if(_xcb_get_auth_info(fd, &ourauth, display, &stage))
     {
         c = xcb_connect_to_fd(fd, &ourauth);
         free(ourauth.name);
@@ -554,8 +556,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)) {
openSUSE Build Service is sponsored by