From 58140dbbd39389ad6af58e201e055f3d4b92d368 Mon Sep 17 00:00:00 2001 From: Egbert Eich Date: Sun, 29 Sep 2013 08:25:14 -0700 Subject: Look for FamilyLocal if inet or inet6 address is loopback 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:. leads to correct authorization when an X client is started but "xauth list $DISPLAY" returns nothing. Signed-off-by: Egbert Eich Signed-off-by: Jeremy Huddleston Sequoia Reviewed-by: Jeremy Huddleston Sequoia --- gethost.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'gethost.c') diff --git a/gethost.c b/gethost.c index 8f77c80..48977bb 100644 --- a/gethost.c +++ b/gethost.c @@ -227,16 +227,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 (*(const 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((const struct in6_addr *)src) + || IN6_IS_ADDR_LOOPBACK((const struct in6_addr *)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) { @@ -275,7 +295,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 (*(const 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 -- cgit v1.2.1