summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEgbert Eich <eich@freedesktop.org>2013-08-14 17:08:27 +0200
committerDr. Tilmann Bubeck <t.bubeck@reinform.de>2013-09-24 14:49:49 +0200
commit345c7bf0d09f26183cfde9ad1c812c8de71869a5 (patch)
tree3230c571962aac236fe9577ecddff2d823c74a70
parent289ca779f73840cb5c9d69b919413079d1be3fc2 (diff)
downloadxorg-app-xauth-345c7bf0d09f26183cfde9ad1c812c8de71869a5.tar.gz
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:<N>.<M> leads to correct authorization when an X client is started but "xauth list $DISPLAY" returns nothing. Signed-off-by: Egbert Eich <eich@freedesktop.org>
-rw-r--r--gethost.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/gethost.c b/gethost.c
index 8f77c80..8f282c7 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 (*(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) {
@@ -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 (*(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