Support authentication for IPv6 connections
Support AF_INET6 in get_authptr, and refactor to use common code for IPv4 and v4-mapped IPv6 addresses. Commit by Jamey Sharp and Josh Triplett.
This commit is contained in:
parent
48776ce233
commit
907f8c8c49
|
@ -77,11 +77,19 @@ static int authname_match(enum auth_protos kind, char *name, int namelen)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *_xcb_memrchr(const void *s, int c, size_t n)
|
||||||
|
{
|
||||||
|
for(s = (char *) s + n - 1; n--; s = (char *) s - 1)
|
||||||
|
if(*(char *)s == (char)c)
|
||||||
|
return (void *) s;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen)
|
static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen)
|
||||||
{
|
{
|
||||||
char *addr = 0;
|
char *addr = 0;
|
||||||
int addrlen = 0;
|
int addrlen = 0;
|
||||||
unsigned short family;
|
unsigned short family, port = 0;
|
||||||
char hostnamebuf[256]; /* big enough for max hostname */
|
char hostnamebuf[256]; /* big enough for max hostname */
|
||||||
char dispbuf[40]; /* big enough to hold more than 2^64 base 10 */
|
char dispbuf[40]; /* big enough to hold more than 2^64 base 10 */
|
||||||
char *display;
|
char *display;
|
||||||
|
@ -89,34 +97,47 @@ static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
family = FamilyLocal; /* 256 */
|
family = FamilyLocal; /* 256 */
|
||||||
switch (sockname->sa_family) {
|
switch(sockname->sa_family)
|
||||||
case AF_INET:
|
{
|
||||||
/*block*/ {
|
case AF_INET6:
|
||||||
struct sockaddr_in *si = (struct sockaddr_in *) sockname;
|
addr = (char *) &((struct sockaddr_in6 *)sockname)->sin6_addr;
|
||||||
assert(sizeof(*si) == socknamelen);
|
addrlen = sizeof(((struct sockaddr_in6 *)sockname)->sin6_addr);
|
||||||
addr = (char *) &si->sin_addr;
|
port = ((struct sockaddr_in6 *)sockname)->sin6_port;
|
||||||
addrlen = 4;
|
if(!IN6_IS_ADDR_V4MAPPED(addr))
|
||||||
if (ntohl(si->sin_addr.s_addr) != 0x7f000001)
|
{
|
||||||
family = XCB_FAMILY_INTERNET;
|
if(!IN6_IS_ADDR_LOOPBACK(addr))
|
||||||
snprintf(dispbuf, sizeof(dispbuf), "%d", ntohs(si->sin_port) - X_TCP_PORT);
|
family = XCB_FAMILY_INTERNET_6;
|
||||||
display = dispbuf;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
addr += 12;
|
||||||
|
/* if v4-mapped, fall through. */
|
||||||
|
case AF_INET:
|
||||||
|
if(!addr)
|
||||||
|
{
|
||||||
|
addr = (char *) &((struct sockaddr_in *)sockname)->sin_addr;
|
||||||
|
port = ((struct sockaddr_in *)sockname)->sin_port;
|
||||||
|
}
|
||||||
|
addrlen = sizeof(((struct sockaddr_in *)sockname)->sin_addr);
|
||||||
|
if(*(in_addr_t *) addr != htonl(INADDR_LOOPBACK))
|
||||||
|
family = XCB_FAMILY_INTERNET;
|
||||||
|
break;
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
/*block*/ {
|
display = _xcb_memrchr(((struct sockaddr_un *) sockname)->sun_path, 'X',
|
||||||
struct sockaddr_un *su = (struct sockaddr_un *) sockname;
|
socknamelen);
|
||||||
char *sockbuf = (char *) sockname;
|
if(!display)
|
||||||
assert(sizeof(*su) >= socknamelen);
|
return 0; /* sockname is mangled somehow */
|
||||||
sockbuf[socknamelen] = 0; /* null-terminate path */
|
display++;
|
||||||
display = strrchr(su->sun_path, 'X');
|
break;
|
||||||
if (display == 0)
|
|
||||||
return 0; /* sockname is mangled somehow */
|
|
||||||
display++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return 0; /* cannot authenticate this family */
|
return 0; /* cannot authenticate this family */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(port)
|
||||||
|
{
|
||||||
|
snprintf(dispbuf, sizeof(dispbuf), "%hu", ntohs(port) - X_TCP_PORT);
|
||||||
|
display = dispbuf;
|
||||||
|
}
|
||||||
|
|
||||||
if (family == FamilyLocal) {
|
if (family == FamilyLocal) {
|
||||||
if (gethostname(hostnamebuf, sizeof(hostnamebuf)) == -1)
|
if (gethostname(hostnamebuf, sizeof(hostnamebuf)) == -1)
|
||||||
return 0; /* do not know own hostname */
|
return 0; /* do not know own hostname */
|
||||||
|
|
Loading…
Reference in New Issue