--- xorg-server-1.8.0/os/access.c 2009-12-17 05:58:44.000000000 +0000 +++ xorg-server-1.8.0-20100708/os/access.c 2010-07-08 13:55:08.000000000 +0000 @@ -800,18 +800,6 @@ ) continue; - /* - * ignore 'localhost' entries as they're not useful - * on the other end of the wire - */ - if (ifr->ifa_flags & IFF_LOOPBACK) - continue; - - if (family == FamilyInternet && - addr[0] == 127 && addr[1] == 0 && - addr[2] == 0 && addr[3] == 1) - continue; - /* * Ignore '0.0.0.0' entries as they are * returned by some OSes for unconfigured NICs but they are @@ -821,11 +809,6 @@ addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0) continue; -#if defined(IPv6) && defined(AF_INET6) - else if (family == FamilyInternet6 && - IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)) - continue; -#endif XdmcpRegisterConnection(family, (char *)addr, len); #if defined(IPv6) && defined(AF_INET6) if (family == FamilyInternet6) --- xorg-server-1.8.0/os/xdmcp.c 2009-11-04 16:25:50.000000000 +0000 +++ xorg-server-1.8.0-20100708/os/xdmcp.c 2010-07-08 13:56:36.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include #endif @@ -209,6 +210,50 @@ static ARRAY8 ManufacturerDisplayID; + + +static int is_loopback(int type, void *a) +{ + char *addr = a; + int ret = 0; + int gairet; + struct sockaddr_storage s; + struct sockaddr_in *s4 = (struct sockaddr_in *)&s; + struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)&s; + char host[NI_MAXHOST]; + + memset(&s, 0, sizeof(s)); + if (type == FamilyInternet) { + s4->sin_family = AF_INET; + s4->sin_addr.s_addr = *((in_addr_t*)a); + if (addr[0] == 127) { + /* IPv4 loopback /8 net */ + ret = 1; + } + } else if (type == FamilyInternet6) { + s6->sin6_family = AF_INET6; + memcpy(&(s6->sin6_addr), a, sizeof(struct in6_addr)); + if (IN6_IS_ADDR_LOOPBACK(addr)) { + /* IPv6 loopback address */ + ret = 1; + } else if (IN6_IS_ADDR_V4MAPPED(addr) && + ((struct in6_addr*)addr)->s6_addr[12] == 127) { + /* IPv4 mapped loopback address */ + ret = 1; + } + } else { + return 0; + } + gairet = getnameinfo((struct sockaddr*)&s, sizeof(struct sockaddr_storage), + host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + if (gairet != 0) { + ErrorF(" => %s\n", gai_strerror(gairet)); + } else { + ErrorF("is_loopback(%s) = %d\n", host, ret); + } + return ret; +} + static void XdmcpRegisterManufacturerDisplayID (char *name, int length) { @@ -438,8 +483,8 @@ * Register the host address for the display */ -static ARRAY16 ConnectionTypes; -static ARRAYofARRAY8 ConnectionAddresses; +static ARRAY16 ConnectionTypes[2]; +static ARRAYofARRAY8 ConnectionAddresses[2]; static long xdmcpGeneration; void @@ -451,12 +496,21 @@ int i; CARD8 *newAddress; + /* + * Index for ConnectionTypes and ConnectionAddresses: + * 1 for loopback address, 0 for remote addresses. + */ + int l; + if (xdmcpGeneration != serverGeneration) { - XdmcpDisposeARRAY16 (&ConnectionTypes); - XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses); + XdmcpDisposeARRAY16 (&ConnectionTypes[0]); + XdmcpDisposeARRAY16 (&ConnectionTypes[1]); + XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses[0]); + XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses[1]); xdmcpGeneration = serverGeneration; } + l = is_loopback(type, address); if (xdm_from != NULL) { /* Only register the requested address */ const void *regAddr = address; const void *fromAddr = NULL; @@ -490,27 +544,27 @@ return; } } - if (ConnectionAddresses.length + 1 == 256) + if (ConnectionAddresses[l].length + 1 == 256) return; newAddress = xalloc (addrlen * sizeof (CARD8)); if (!newAddress) return; - if (!XdmcpReallocARRAY16 (&ConnectionTypes, ConnectionTypes.length + 1)) + if (!XdmcpReallocARRAY16 (&ConnectionTypes[l], ConnectionTypes[l].length + 1)) { xfree (newAddress); return; } - if (!XdmcpReallocARRAYofARRAY8 (&ConnectionAddresses, - ConnectionAddresses.length + 1)) + if (!XdmcpReallocARRAYofARRAY8 (&ConnectionAddresses[l], + ConnectionAddresses[l].length + 1)) { xfree (newAddress); return; } - ConnectionTypes.data[ConnectionTypes.length - 1] = (CARD16) type; + ConnectionTypes[l].data[ConnectionTypes[l].length - 1] = (CARD16) type; for (i = 0; i < addrlen; i++) newAddress[i] = address[i]; - ConnectionAddresses.data[ConnectionAddresses.length-1].data = newAddress; - ConnectionAddresses.data[ConnectionAddresses.length-1].length = addrlen; + ConnectionAddresses[l].data[ConnectionAddresses[l].length-1].data = newAddress; + ConnectionAddresses[l].data[ConnectionAddresses[l].length-1].length = addrlen; } /* @@ -1176,12 +1230,19 @@ CARD16 XdmcpConnectionType; ARRAY8 authenticationData; int socketfd = xdmcpSocket; + int l; switch (SOCKADDR_FAMILY(ManagerAddress)) { - case AF_INET: XdmcpConnectionType=FamilyInternet; break; + case AF_INET: + XdmcpConnectionType=FamilyInternet; + l = is_loopback(XdmcpConnectionType, &(((struct sockaddr_in*)&ManagerAddress)->sin_addr.s_addr)); + break; #if defined(IPv6) && defined(AF_INET6) - case AF_INET6: XdmcpConnectionType=FamilyInternet6; break; + case AF_INET6: + XdmcpConnectionType=FamilyInternet6; + l = is_loopback(XdmcpConnectionType, ((struct sockaddr_in6*)&ManagerAddress)->sin6_addr.s6_addr); + break; #endif default: XdmcpConnectionType=0xffff; break; } @@ -1190,10 +1251,10 @@ header.opcode = (CARD16) REQUEST; length = 2; /* display number */ - length += 1 + 2 * ConnectionTypes.length; /* connection types */ + length += 1 + 2 * ConnectionTypes[l].length; /* connection types */ length += 1; /* connection addresses */ - for (i = 0; i < ConnectionAddresses.length; i++) - length += 2 + ConnectionAddresses.data[i].length; + for (i = 0; i < ConnectionAddresses[l].length; i++) + length += 2 + ConnectionAddresses[l].data[i].length; authenticationData.length = 0; authenticationData.data = 0; if (AuthenticationFuncs) @@ -1216,27 +1277,27 @@ return; } XdmcpWriteCARD16 (&buffer, DisplayNumber); - XdmcpWriteCARD8 (&buffer, ConnectionTypes.length); + XdmcpWriteCARD8 (&buffer, ConnectionTypes[l].length); /* The connection array is send reordered, so that connections of */ /* the same address type as the XDMCP manager connection are send */ /* first. This works around a bug in xdm. mario@klebsch.de */ - for (i = 0; i < (int)ConnectionTypes.length; i++) - if (ConnectionTypes.data[i]==XdmcpConnectionType) - XdmcpWriteCARD16 (&buffer, ConnectionTypes.data[i]); - for (i = 0; i < (int)ConnectionTypes.length; i++) - if (ConnectionTypes.data[i]!=XdmcpConnectionType) - XdmcpWriteCARD16 (&buffer, ConnectionTypes.data[i]); - - XdmcpWriteCARD8 (&buffer, ConnectionAddresses.length); - for (i = 0; i < (int)ConnectionAddresses.length; i++) - if ( (i=ConnectionTypes.length) || - (ConnectionTypes.data[i]!=XdmcpConnectionType) ) - XdmcpWriteARRAY8 (&buffer, &ConnectionAddresses.data[i]); + for (i = 0; i < (int)ConnectionTypes[l].length; i++) + if (ConnectionTypes[l].data[i]==XdmcpConnectionType) + XdmcpWriteCARD16 (&buffer, ConnectionTypes[l].data[i]); + for (i = 0; i < (int)ConnectionTypes[l].length; i++) + if (ConnectionTypes[l].data[i]!=XdmcpConnectionType) + XdmcpWriteCARD16 (&buffer, ConnectionTypes[l].data[i]); + + XdmcpWriteCARD8 (&buffer, ConnectionAddresses[l].length); + for (i = 0; i < (int)ConnectionAddresses[l].length; i++) + if ( (i=ConnectionTypes[l].length) || + (ConnectionTypes[l].data[i]!=XdmcpConnectionType) ) + XdmcpWriteARRAY8 (&buffer, &ConnectionAddresses[l].data[i]); XdmcpWriteARRAY8 (&buffer, AuthenticationName); XdmcpWriteARRAY8 (&buffer, &authenticationData);