libxcb uses FamilyLocal authorization if the host name or IP in the
display string is from the loopback device. This patch adds the same
behavior to xauth.
This fixes a long standing problem that for ssh tunneled connections
a display variable of the form: localhost:<N>.<M> leads to correct
authorization when an X client is started but "xauth list $DISPLAY"
returns nothing.

Signed-off-by: Egbert Eich <[email protected]>
---
 gethost.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/gethost.c b/gethost.c
index 10f6078..7c4b600 100644
--- a/gethost.c
+++ b/gethost.c
@@ -224,16 +224,36 @@ struct addrlist *get_address_info (
        for (ai = firstai; ai != NULL; ai = ai->ai_next) {
            struct addrlist *duplicate;
 
+           len = 0;
            if (ai->ai_family == AF_INET) {
                struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
                src = &(sin->sin_addr);
-               len = sizeof(sin->sin_addr);
-               family = FamilyInternet;
+               if (*(in_addr_t *) src == htonl(INADDR_LOOPBACK)) {
+                   family = FamilyLocal;
+                   if (get_local_hostname (buf, sizeof buf)) {
+                       src = buf;
+                       len = strlen (buf);
+                   } else
+                       src = NULL;
+               } else {
+                   len = sizeof(sin->sin_addr);
+                   family = FamilyInternet;
+               }
            } else if (ai->ai_family == AF_INET6) {
                struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
                src = &(sin6->sin6_addr);
-               len = sizeof(sin6->sin6_addr);
-               family = FamilyInternet6;
+               if (IN6_IS_ADDR_V4MAPPED((struct sockaddr_in6 *)src)
+                   || IN6_IS_ADDR_LOOPBACK((struct sockaddr_in6 *)src)) {
+                   family = FamilyLocal;
+                   if (get_local_hostname (buf, sizeof buf)) {
+                       src = buf;
+                       len = strlen (buf);
+                   } else
+                       src = NULL;
+               } else {
+                   len = sizeof(sin6->sin6_addr);
+                   family = FamilyInternet6;
+               }
            }
 
            for(duplicate = retval; duplicate != NULL; duplicate = 
duplicate->next) {
@@ -272,7 +292,17 @@ struct addrlist *get_address_info (
 #else
        if (!get_inet_address (host, &hostinetaddr)) return NULL;
        src = (char *) &hostinetaddr;
-       len = 4; /* sizeof inaddr.sin_addr, would fail on Cray */
+       if (*(in_addr_t *) src == htonl(INADDR_LOOPBACK)) {
+           family = FamilyLocal;
+           if (get_local_hostname (buf, sizeof buf)) {
+               src = buf;
+               len = strlen (buf);
+           } else {
+               len = 0;
+               src = NULL;
+           }
+       } else
+           len = 4; /* sizeof inaddr.sin_addr, would fail on Cray */
        break;
 #endif /* IPv6 */
 #else
-- 
1.8.1.4

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to