support scoped IPv6 address properly. PR 16810.
This commit is contained in:
parent
8dbe673a81
commit
2f7d82e63d
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: hosts_access.c,v 1.14 2002/05/24 05:38:20 itojun Exp $ */
|
/* $NetBSD: hosts_access.c,v 1.15 2002/06/06 21:28:49 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This module implements a simple access control language that is based on
|
* This module implements a simple access control language that is based on
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#) hosts_access.c 1.21 97/02/12 02:13:22";
|
static char sccsid[] = "@(#) hosts_access.c 1.21 97/02/12 02:13:22";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: hosts_access.c,v 1.14 2002/05/24 05:38:20 itojun Exp $");
|
__RCSID("$NetBSD: hosts_access.c,v 1.15 2002/06/06 21:28:49 itojun Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -372,9 +372,14 @@ char *string;
|
||||||
#ifndef INET6
|
#ifndef INET6
|
||||||
return masked_match4(net_tok, mask_tok, string);
|
return masked_match4(net_tok, mask_tok, string);
|
||||||
#else
|
#else
|
||||||
if (dot_quad_addr(net_tok, NULL) != INADDR_NONE
|
/*
|
||||||
&& dot_quad_addr(mask_tok, NULL) != INADDR_NONE
|
* masked_match4() is kept just for supporting shortened IPv4 address form.
|
||||||
&& dot_quad_addr(string, NULL) != INADDR_NONE) {
|
* If we could get rid of shortened IPv4 form, we could just always use
|
||||||
|
* masked_match6().
|
||||||
|
*/
|
||||||
|
if (dot_quad_addr(net_tok, NULL) != INADDR_NONE &&
|
||||||
|
dot_quad_addr(mask_tok, NULL) != INADDR_NONE &&
|
||||||
|
dot_quad_addr(string, NULL) != INADDR_NONE) {
|
||||||
return masked_match4(net_tok, mask_tok, string);
|
return masked_match4(net_tok, mask_tok, string);
|
||||||
} else
|
} else
|
||||||
return masked_match6(net_tok, mask_tok, string);
|
return masked_match6(net_tok, mask_tok, string);
|
||||||
|
@ -398,8 +403,8 @@ char *string;
|
||||||
|
|
||||||
if (dot_quad_addr(string, &addr) != 0)
|
if (dot_quad_addr(string, &addr) != 0)
|
||||||
return (NO);
|
return (NO);
|
||||||
if (dot_quad_addr(net_tok, &net) != 0
|
if (dot_quad_addr(net_tok, &net) != 0 ||
|
||||||
|| dot_quad_addr(mask_tok, &mask) != 0) {
|
dot_quad_addr(mask_tok, &mask) != 0) {
|
||||||
tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
|
tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
|
||||||
return (NO); /* not tcpd_jump() */
|
return (NO); /* not tcpd_jump() */
|
||||||
}
|
}
|
||||||
|
@ -411,75 +416,140 @@ char *string;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
/* Ugly because it covers IPv4 mapped address. I hate mapped addresses. */
|
|
||||||
static int masked_match6(net_tok, mask_tok, string)
|
static int masked_match6(net_tok, mask_tok, string)
|
||||||
char *net_tok;
|
char *net_tok;
|
||||||
char *mask_tok;
|
char *mask_tok;
|
||||||
char *string;
|
char *string;
|
||||||
{
|
{
|
||||||
struct in6_addr net;
|
union {
|
||||||
struct in6_addr mask;
|
struct sockaddr sa;
|
||||||
struct in6_addr addr;
|
struct sockaddr_in sin;
|
||||||
int masklen;
|
struct sockaddr_in6 sin6;
|
||||||
int fail;
|
} net, mask, addr;
|
||||||
|
struct addrinfo hints, *res;
|
||||||
|
unsigned long masklen;
|
||||||
|
char *ep;
|
||||||
int i;
|
int i;
|
||||||
int maskoff;
|
char *np, *mp, *ap;
|
||||||
int netaf;
|
int alen;
|
||||||
int dirty;
|
|
||||||
const int sizoff64 = sizeof(struct in6_addr) - sizeof(struct in_addr);
|
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&hints, 0, sizeof(hints));
|
||||||
if (inet_pton(AF_INET6, string, &addr) == 1)
|
hints.ai_family = PF_UNSPEC;
|
||||||
; /* okay */
|
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||||
else if (inet_pton(AF_INET, string, &addr.s6_addr[sizoff64]) == 1)
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
addr.s6_addr[10] = addr.s6_addr[11] = 0xff;
|
if (getaddrinfo(net_tok, "0", &hints, &res) == 0) {
|
||||||
else
|
if (res->ai_addrlen > sizeof(net) || res->ai_next) {
|
||||||
|
freeaddrinfo(res);
|
||||||
return NO;
|
return NO;
|
||||||
|
}
|
||||||
memset(&net, 0, sizeof(net));
|
memcpy(&net, res->ai_addr, res->ai_addrlen);
|
||||||
if (inet_pton(AF_INET6, net_tok, &net) == 1) {
|
freeaddrinfo(res);
|
||||||
netaf = AF_INET6;
|
|
||||||
maskoff = 0;
|
|
||||||
} else if (inet_pton(AF_INET, net_tok, &net.s6_addr[sizoff64]) == 1) {
|
|
||||||
netaf = AF_INET;
|
|
||||||
maskoff = sizoff64;
|
|
||||||
net.s6_addr[10] = net.s6_addr[11] = 0xff;
|
|
||||||
} else
|
} else
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
fail = 0;
|
memset(&hints, 0, sizeof(hints));
|
||||||
if (mask_tok[strspn(mask_tok, "0123456789")] == '\0') {
|
hints.ai_family = net.sa.sa_family;
|
||||||
masklen = atoi(mask_tok) + maskoff * 8;
|
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||||
if (0 <= masklen && masklen <= 128) {
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
ep = NULL;
|
||||||
|
if (getaddrinfo(mask_tok, "0", &hints, &res) == 0) {
|
||||||
|
if (res->ai_family == AF_INET6 &&
|
||||||
|
((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) {
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
if (res->ai_addrlen > sizeof(mask) || res->ai_next) {
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
memcpy(&mask, res->ai_addr, res->ai_addrlen);
|
||||||
|
freeaddrinfo(res);
|
||||||
|
} else {
|
||||||
|
ep = NULL;
|
||||||
|
masklen = strtoul(mask_tok, &ep, 10);
|
||||||
|
if (ep && !*ep) {
|
||||||
memset(&mask, 0, sizeof(mask));
|
memset(&mask, 0, sizeof(mask));
|
||||||
memset(&mask, 0xff, masklen / 8);
|
mask.sa.sa_family = net.sa.sa_family;
|
||||||
if (masklen % 8) {
|
mask.sa.sa_len = net.sa.sa_len;
|
||||||
((u_char *)&mask)[masklen / 8] =
|
switch (mask.sa.sa_family) {
|
||||||
(0xff00 >> (masklen % 8)) & 0xff;
|
case AF_INET:
|
||||||
|
mp = (char *)&mask.sin.sin_addr;
|
||||||
|
alen = sizeof(mask.sin.sin_addr);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
mp = (char *)&mask.sin6.sin6_addr;
|
||||||
|
alen = sizeof(mask.sin6.sin6_addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
if (masklen / 8 > alen)
|
||||||
|
return NO;
|
||||||
|
memset(mp, 0xff, masklen / 8);
|
||||||
|
if (masklen % 8)
|
||||||
|
mp[masklen / 8] = 0xff00 >> (masklen % 8);
|
||||||
} else
|
} else
|
||||||
fail++;
|
return NO;
|
||||||
} else if (netaf == AF_INET6 && inet_pton(AF_INET6, mask_tok, &mask) == 1)
|
|
||||||
; /* okay */
|
|
||||||
else if (netaf == AF_INET
|
|
||||||
&& inet_pton(AF_INET, mask_tok, &mask.s6_addr[12]) == 1) {
|
|
||||||
memset(&mask, 0xff, sizoff64);
|
|
||||||
} else
|
|
||||||
fail++;
|
|
||||||
if (fail) {
|
|
||||||
tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
|
|
||||||
return (NO); /* not tcpd_jump() */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dirty = 0;
|
memset(&hints, 0, sizeof(hints));
|
||||||
for (i = 0; i < sizeof(addr); i++) {
|
hints.ai_family = PF_UNSPEC;
|
||||||
addr.s6_addr[i] &= mask.s6_addr[i];
|
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||||
dirty |= (net.s6_addr[i] & ~mask.s6_addr[i]);
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
if (getaddrinfo(string, "0", &hints, &res) == 0) {
|
||||||
|
if (res->ai_addrlen > sizeof(addr) || res->ai_next) {
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
/* special case - IPv4 mapped address */
|
||||||
|
if (net.sa.sa_family == AF_INET && res->ai_family == AF_INET6 &&
|
||||||
|
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)) {
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sa.sa_family = net.sa.sa_family;
|
||||||
|
addr.sa.sa_len = net.sa.sa_len;
|
||||||
|
memcpy(&addr.sin.sin_addr,
|
||||||
|
&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr[12],
|
||||||
|
sizeof(addr.sin.sin_addr));
|
||||||
|
} else
|
||||||
|
memcpy(&addr, res->ai_addr, res->ai_addrlen);
|
||||||
|
freeaddrinfo(res);
|
||||||
|
} else
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
if (net.sa.sa_family != mask.sa.sa_family ||
|
||||||
|
net.sa.sa_family != addr.sa.sa_family) {
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty)
|
switch (net.sa.sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
np = (char *)&net.sin.sin_addr;
|
||||||
|
mp = (char *)&mask.sin.sin_addr;
|
||||||
|
ap = (char *)&addr.sin.sin_addr;
|
||||||
|
alen = sizeof(net.sin.sin_addr);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
np = (char *)&net.sin6.sin6_addr;
|
||||||
|
mp = (char *)&mask.sin6.sin6_addr;
|
||||||
|
ap = (char *)&addr.sin6.sin6_addr;
|
||||||
|
alen = sizeof(net.sin6.sin6_addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < alen; i++)
|
||||||
|
if (np[i] & ~mp[i]) {
|
||||||
tcpd_warn("host bits not all zero in %s/%s", net_tok, mask_tok);
|
tcpd_warn("host bits not all zero in %s/%s", net_tok, mask_tok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return (memcmp(&addr, &net, sizeof(addr)) == 0);
|
for (i = 0; i < alen; i++)
|
||||||
|
ap[i] &= mp[i];
|
||||||
|
|
||||||
|
if (addr.sa.sa_family == AF_INET6 && addr.sin6.sin6_scope_id &&
|
||||||
|
addr.sin6.sin6_scope_id != net.sin6.sin6_scope_id)
|
||||||
|
return NO;
|
||||||
|
return (memcmp(ap, np, alen) == 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: socket.c,v 1.10 2002/05/24 05:38:20 itojun Exp $ */
|
/* $NetBSD: socket.c,v 1.11 2002/06/06 21:28:50 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This module determines the type of socket (datagram, stream), the client
|
* This module determines the type of socket (datagram, stream), the client
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#) socket.c 1.15 97/03/21 19:27:24";
|
static char sccsid[] = "@(#) socket.c 1.15 97/03/21 19:27:24";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: socket.c,v 1.10 2002/05/24 05:38:20 itojun Exp $");
|
__RCSID("$NetBSD: socket.c,v 1.11 2002/06/06 21:28:50 itojun Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -105,27 +105,12 @@ void sock_hostaddr(host)
|
||||||
struct host_info *host;
|
struct host_info *host;
|
||||||
{
|
{
|
||||||
struct sockaddr *sa = host->sin;
|
struct sockaddr *sa = host->sin;
|
||||||
int alen, af;
|
|
||||||
char *ap;
|
|
||||||
|
|
||||||
if (!sa)
|
if (!sa)
|
||||||
return;
|
return;
|
||||||
switch (af = sa->sa_family) {
|
|
||||||
case AF_INET:
|
|
||||||
ap = (char *)&((struct sockaddr_in *)sa)->sin_addr;
|
|
||||||
alen = sizeof(struct in_addr);
|
|
||||||
break;
|
|
||||||
#ifdef INET6
|
|
||||||
case AF_INET6:
|
|
||||||
ap = (char *)&((struct sockaddr_in6 *)sa)->sin6_addr;
|
|
||||||
alen = sizeof(struct in6_addr);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
host->addr[0] = '\0';
|
host->addr[0] = '\0';
|
||||||
inet_ntop(af, ap, host->addr, sizeof(host->addr));
|
getnameinfo(sa, sa->sa_len, host->addr, sizeof(host->addr),
|
||||||
|
NULL, 0, NI_NUMERICHOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sock_hostname - map endpoint address to host name */
|
/* sock_hostname - map endpoint address to host name */
|
||||||
|
@ -133,95 +118,84 @@ struct host_info *host;
|
||||||
void sock_hostname(host)
|
void sock_hostname(host)
|
||||||
struct host_info *host;
|
struct host_info *host;
|
||||||
{
|
{
|
||||||
struct sockaddr *sinp = host->sin;
|
struct sockaddr *sa = host->sin;
|
||||||
struct hostent *hp;
|
char h1[NI_MAXHOST], h2[NI_MAXHOST];
|
||||||
int i;
|
struct addrinfo hints, *res, *res0;
|
||||||
int af, alen;
|
|
||||||
char *ap;
|
|
||||||
char hbuf[MAXHOSTNAMELEN];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* On some systems, for example Solaris 2.3, gethostbyaddr(0.0.0.0) does
|
|
||||||
* not fail. Instead it returns "INADDR_ANY". Unfortunately, this does
|
|
||||||
* not work the other way around: gethostbyname("INADDR_ANY") fails. We
|
|
||||||
* have to special-case 0.0.0.0, in order to avoid false alerts from the
|
|
||||||
* host name/address checking code below.
|
|
||||||
*/
|
|
||||||
if (!sinp)
|
|
||||||
return;
|
|
||||||
switch (af = sinp->sa_family) {
|
|
||||||
case AF_INET:
|
|
||||||
if (((struct sockaddr_in *)sinp)->sin_addr.s_addr == 0)
|
|
||||||
return;
|
|
||||||
ap = (char *)&((struct sockaddr_in *)sinp)->sin_addr;
|
|
||||||
alen = sizeof(struct in_addr);
|
|
||||||
break;
|
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
case AF_INET6:
|
struct sockaddr_in tmp;
|
||||||
ap = (char *)&((struct sockaddr_in6 *)sinp)->sin6_addr;
|
|
||||||
alen = sizeof(struct in6_addr);
|
|
||||||
/* special case on reverse lookup: mapped addr. I hate it */
|
|
||||||
if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
|
|
||||||
af = AF_INET;
|
|
||||||
ap += (sizeof(struct in6_addr) - sizeof(struct in_addr));
|
|
||||||
alen = sizeof(struct in_addr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
|
||||||
|
if (!sa)
|
||||||
|
return;
|
||||||
|
#ifdef INET6
|
||||||
|
/* special case on reverse lookup: mapped addr. I hate it */
|
||||||
|
if (sa->sa_family == AF_INET6 &&
|
||||||
|
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
|
||||||
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
|
tmp.sin_family = AF_INET;
|
||||||
|
tmp.sin_len = sizeof(struct sockaddr_in);
|
||||||
|
memcpy(&tmp.sin_addr,
|
||||||
|
&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12], 4);
|
||||||
|
sa = (struct sockaddr *)&tmp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (getnameinfo(sa, sa->sa_len, h1, sizeof(h1), NULL, 0,
|
||||||
|
NI_NUMERICHOST) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((hp = gethostbyaddr(ap, alen, af)) != 0) {
|
if (getnameinfo(sa, sa->sa_len, host->name, sizeof(host->name), NULL, 0,
|
||||||
|
NI_NAMEREQD) == 0) {
|
||||||
STRN_CPY(host->name, hp->h_name, sizeof(host->name));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify that the address is a member of the address list returned
|
* Verify that the address is a member of the address list returned
|
||||||
* by gethostbyname(hostname).
|
* by getaddrinfo(hostname).
|
||||||
*
|
*
|
||||||
* Verify also that gethostbyaddr() and gethostbyname() return the same
|
* Verify also that getnameinfo() and getaddrinfo() return the same
|
||||||
* hostname, or rshd and rlogind may still end up being spoofed.
|
* hostname, or rshd and rlogind may still end up being spoofed.
|
||||||
*
|
*
|
||||||
* On some sites, gethostbyname("localhost") returns "localhost.domain".
|
* On some sites, getaddrinfo("localhost") returns "localhost.domain".
|
||||||
* This is a DNS artefact. We treat it as a special case. When we
|
* This is a DNS artefact. We treat it as a special case. When we
|
||||||
* can't believe the address list from gethostbyname("localhost")
|
* can't believe the address list from getaddrinfo("localhost")
|
||||||
* we're in big trouble anyway.
|
* we're in big trouble anyway.
|
||||||
*/
|
*/
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
if ((hp = gethostbyname2(host->name, af)) == 0) {
|
hints.ai_family = sa->sa_family;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
if (getaddrinfo(host->name, "0", &hints, &res0) != 0) {
|
||||||
/*
|
/*
|
||||||
* Unable to verify that the host name matches the address. This
|
* Unable to verify that the host name matches the address. This
|
||||||
* may be a transient problem or a botched name server setup.
|
* may be a transient problem or a botched name server setup.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tcpd_warn("can't verify hostname: gethostbyname2(%s, %d) failed",
|
tcpd_warn("can't verify hostname: getaddrinfo(%s, %d) failed",
|
||||||
host->name, af);
|
host->name, hints.ai_family);
|
||||||
|
} else if (res0->ai_canonname &&
|
||||||
} else if (STR_NE(host->name, hp->h_name)
|
STR_NE(host->name, res0->ai_canonname) &&
|
||||||
&& STR_NE(host->name, "localhost")) {
|
STR_NE(host->name, "localhost")) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The gethostbyaddr() and gethostbyname() calls did not return
|
* The getnameinfo() and getaddrinfo() calls did not return
|
||||||
* the same hostname. This could be a nameserver configuration
|
* the same hostname. This could be a nameserver configuration
|
||||||
* problem. It could also be that someone is trying to spoof us.
|
* problem. It could also be that someone is trying to spoof us.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tcpd_warn("host name/name mismatch: %s != %.*s",
|
tcpd_warn("host name/name mismatch: %s != %s",
|
||||||
host->name, STRING_LENGTH, hp->h_name);
|
host->name, res0->ai_canonname);
|
||||||
|
freeaddrinfo(res0);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The address should be a member of the address list returned by
|
* The address should be a member of the address list returned by
|
||||||
* gethostbyname(). We should first verify that the h_addrtype
|
* getaddrinfo().
|
||||||
* field is AF_INET, but this program has already caused too much
|
|
||||||
* grief on systems with broken library code.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; hp->h_addr_list[i]; i++) {
|
for (res = res0; res; res = res->ai_next) {
|
||||||
if (memcmp(hp->h_addr_list[i], (char *) ap, alen) == 0)
|
if (getnameinfo(res->ai_addr, res->ai_addrlen, h2, sizeof(h2),
|
||||||
return; /* name is good, keep it */
|
NULL, 0, NI_NUMERICHOST) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (STR_EQ(h1, h2)) {
|
||||||
|
freeaddrinfo(res0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -230,9 +204,10 @@ struct host_info *host;
|
||||||
* server.
|
* server.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tcpd_warn("host name/address mismatch: %s != %.*s",
|
tcpd_warn("host name/address mismatch: %s != %s", h1,
|
||||||
inet_ntop(af, ap, hbuf, sizeof(hbuf)),
|
res0->ai_canonname ? res0->ai_canonname : "?");
|
||||||
STRING_LENGTH, hp->h_name);
|
|
||||||
|
freeaddrinfo(res0);
|
||||||
}
|
}
|
||||||
/* name is bad, clobber it */
|
/* name is bad, clobber it */
|
||||||
(void)strncpy(host->name, paranoid, sizeof(host->name) - 1);
|
(void)strncpy(host->name, paranoid, sizeof(host->name) - 1);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: scaffold.c,v 1.7 1999/08/31 13:58:58 itojun Exp $ */
|
/* $NetBSD: scaffold.c,v 1.8 2002/06/06 21:28:50 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routines for testing only. Not really industrial strength.
|
* Routines for testing only. Not really industrial strength.
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccs_id[] = "@(#) scaffold.c 1.6 97/03/21 19:27:24";
|
static char sccs_id[] = "@(#) scaffold.c 1.6 97/03/21 19:27:24";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: scaffold.c,v 1.7 1999/08/31 13:58:58 itojun Exp $");
|
__RCSID("$NetBSD: scaffold.c,v 1.8 2002/06/06 21:28:50 itojun Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -38,8 +38,6 @@ __RCSID("$NetBSD: scaffold.c,v 1.7 1999/08/31 13:58:58 itojun Exp $");
|
||||||
#include "tcpd.h"
|
#include "tcpd.h"
|
||||||
#include "scaffold.h"
|
#include "scaffold.h"
|
||||||
|
|
||||||
static struct hostent *dup_hostent __P((struct hostent *));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are referenced by the options module and by rfc931.c.
|
* These are referenced by the options module and by rfc931.c.
|
||||||
*/
|
*/
|
||||||
|
@ -47,119 +45,29 @@ int allow_severity = SEVERITY;
|
||||||
int deny_severity = LOG_WARNING;
|
int deny_severity = LOG_WARNING;
|
||||||
extern int rfc931_timeout; /* = RFC931_TIMEOUT; */
|
extern int rfc931_timeout; /* = RFC931_TIMEOUT; */
|
||||||
|
|
||||||
/* dup_hostent - create hostent in one memory block */
|
|
||||||
|
|
||||||
static struct hostent *dup_hostent(hp)
|
|
||||||
struct hostent *hp;
|
|
||||||
{
|
|
||||||
struct hostent_block {
|
|
||||||
struct hostent host;
|
|
||||||
char *addr_list[1];
|
|
||||||
};
|
|
||||||
struct hostent_block *hb;
|
|
||||||
int count;
|
|
||||||
char *data;
|
|
||||||
char *addr;
|
|
||||||
|
|
||||||
for (count = 0; hp->h_addr_list[count] != 0; count++)
|
|
||||||
/* void */ ;
|
|
||||||
|
|
||||||
if ((hb = (struct hostent_block *) malloc(sizeof(struct hostent_block)
|
|
||||||
+ (hp->h_length + sizeof(char *)) * count)) == 0) {
|
|
||||||
fprintf(stderr, "Sorry, out of memory\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memset((char *) &hb->host, 0, sizeof(hb->host));
|
|
||||||
hb->host.h_addrtype = hp->h_addrtype;
|
|
||||||
hb->host.h_length = hp->h_length;
|
|
||||||
hb->host.h_addr_list = hb->addr_list;
|
|
||||||
hb->host.h_addr_list[count] = 0;
|
|
||||||
data = (char *) (hb->host.h_addr_list + count + 1);
|
|
||||||
|
|
||||||
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
|
|
||||||
hb->host.h_addr_list[count] = data + hp->h_length * count;
|
|
||||||
memcpy(hb->host.h_addr_list[count], addr, hp->h_length);
|
|
||||||
}
|
|
||||||
return (&hb->host);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find_inet_addr - find all addresses for this host, result to free() */
|
/* find_inet_addr - find all addresses for this host, result to free() */
|
||||||
|
|
||||||
struct hostent *find_inet_addr(host)
|
struct addrinfo *find_inet_addr(host, flags)
|
||||||
char *host;
|
char *host;
|
||||||
|
int flags;
|
||||||
{
|
{
|
||||||
struct in_addr addr;
|
struct addrinfo hints, *res;
|
||||||
unsigned long addr_num;
|
int error;
|
||||||
struct hostent *hp;
|
|
||||||
static struct hostent h;
|
|
||||||
static char *addr_list[2];
|
|
||||||
#ifdef INET6
|
|
||||||
static struct in6_addr in6;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
memset(&hints, 0, sizeof(hints));
|
||||||
* Host address: translate it to internal form.
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
*/
|
hints.ai_flags = AI_CANONNAME | flags;
|
||||||
if (dot_quad_addr(host, &addr_num) == 0) {
|
error = getaddrinfo(host, "0", &hints, &res);
|
||||||
addr.s_addr = (addr_num & 0xffffffff);
|
if (error) {
|
||||||
h.h_addr_list = addr_list;
|
tcpd_warn("%s: %s", host, gai_strerror(error));
|
||||||
h.h_addr_list[0] = (char *) &addr;
|
return (0);
|
||||||
h.h_length = sizeof(addr);
|
|
||||||
h.h_addrtype = AF_INET;
|
|
||||||
return (dup_hostent(&h));
|
|
||||||
}
|
}
|
||||||
#ifdef INET6
|
|
||||||
if (inet_pton(AF_INET6, host, &in6) == 1) {
|
|
||||||
h.h_addr_list = addr_list;
|
|
||||||
h.h_addr_list[0] = (char *) &in6;
|
|
||||||
h.h_length = sizeof(in6);
|
|
||||||
h.h_addrtype = AF_INET6;
|
|
||||||
return (dup_hostent(&h));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
if (res->ai_canonname && STR_NE(host, res->ai_canonname)) {
|
||||||
* Map host name to a series of addresses. Watch out for non-internet
|
|
||||||
* forms or aliases. The NOT_INADDR() is here in case gethostbyname() has
|
|
||||||
* been "enhanced" to accept numeric addresses. Make a copy of the
|
|
||||||
* address list so that later gethostbyXXX() calls will not clobber it.
|
|
||||||
*/
|
|
||||||
#ifdef INET6
|
|
||||||
if (NOT_INADDR(host) == 0 && inet_pton(AF_INET6, host, &in6) == 1)
|
|
||||||
#else
|
|
||||||
if (NOT_INADDR(host) == 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
tcpd_warn("%s: not an internet address", host);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#ifdef INET6
|
|
||||||
/*
|
|
||||||
* XXX this behavior may, or may not be desirable.
|
|
||||||
* - we may better use getipnodebyname() to addresses of get both AFs,
|
|
||||||
* however, getipnodebyname() is not widely implemented.
|
|
||||||
* - it may be better to have a way to specify the AF to use.
|
|
||||||
*/
|
|
||||||
if ((hp = gethostbyname2(host, AF_INET)) == 0
|
|
||||||
&& (hp = gethostbyname2(host, AF_INET6)) == 0) {
|
|
||||||
tcpd_warn("%s: host not found", host);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ((hp = gethostbyname(host)) == 0) {
|
|
||||||
tcpd_warn("%s: host not found", host);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (hp->h_addrtype != AF_INET) {
|
|
||||||
tcpd_warn("%d: not an internet host", hp->h_addrtype);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (STR_NE(host, hp->h_name)) {
|
|
||||||
tcpd_warn("%s: hostname alias", host);
|
tcpd_warn("%s: hostname alias", host);
|
||||||
tcpd_warn("(official name: %.*s)", STRING_LENGTH, hp->h_name);
|
tcpd_warn("(official name: %.*s)", STRING_LENGTH, res->ai_canonname);
|
||||||
}
|
}
|
||||||
return (dup_hostent(hp));
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check_dns - give each address thorough workout, return address count */
|
/* check_dns - give each address thorough workout, return address count */
|
||||||
|
@ -168,36 +76,22 @@ int check_dns(host)
|
||||||
char *host;
|
char *host;
|
||||||
{
|
{
|
||||||
struct request_info request;
|
struct request_info request;
|
||||||
struct sockaddr_storage sin;
|
struct sockaddr_storage ss;
|
||||||
struct hostent *hp;
|
struct addrinfo *res0, *res;
|
||||||
int count;
|
int count;
|
||||||
char *addr;
|
|
||||||
char *ap;
|
|
||||||
int alen;
|
|
||||||
|
|
||||||
if ((hp = find_inet_addr(host)) == 0)
|
if ((res0 = find_inet_addr(host, 0)) == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
request_init(&request, RQ_CLIENT_SIN, &sin, 0);
|
memset(&ss, 0, sizeof(ss));
|
||||||
|
request_init(&request, RQ_CLIENT_SIN, &ss, 0);
|
||||||
sock_methods(&request);
|
sock_methods(&request);
|
||||||
memset((char *) &sin, 0, sizeof(sin));
|
|
||||||
sin.ss_family = hp->h_addrtype;
|
|
||||||
switch (hp->h_addrtype) {
|
|
||||||
case AF_INET:
|
|
||||||
ap = (char *)&((struct sockaddr_in *)&sin)->sin_addr;
|
|
||||||
alen = sizeof(struct in6_addr);
|
|
||||||
break;
|
|
||||||
#ifdef INET6
|
|
||||||
case AF_INET6:
|
|
||||||
ap = (char *)&((struct sockaddr_in6 *)&sin)->sin6_addr;
|
|
||||||
alen = sizeof(struct in6_addr);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
|
count = 0;
|
||||||
memcpy(ap, addr, alen);
|
for (res = res0; res; res = res->ai_next) {
|
||||||
|
count++;
|
||||||
|
if (res->ai_addrlen > sizeof(ss))
|
||||||
|
continue;
|
||||||
|
memcpy(&ss, res->ai_addr, res->ai_addrlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force host name and address conversions. Use the request structure
|
* Force host name and address conversions. Use the request structure
|
||||||
|
@ -209,8 +103,9 @@ char *host;
|
||||||
if (STR_EQ(eval_hostname(request.client), unknown))
|
if (STR_EQ(eval_hostname(request.client), unknown))
|
||||||
tcpd_warn("host address %s->name lookup failed",
|
tcpd_warn("host address %s->name lookup failed",
|
||||||
eval_hostaddr(request.client));
|
eval_hostaddr(request.client));
|
||||||
|
tcpd_warn("%s %s", eval_hostname(request.client), unknown);
|
||||||
}
|
}
|
||||||
free((char *) hp);
|
freeaddrinfo(res0);
|
||||||
return (count);
|
return (count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: scaffold.h,v 1.3 1998/01/09 08:11:48 perry Exp $ */
|
/* $NetBSD: scaffold.h,v 1.4 2002/06/06 21:28:50 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @(#) scaffold.h 1.3 94/12/31 18:19:19
|
* @(#) scaffold.h 1.3 94/12/31 18:19:19
|
||||||
|
@ -6,7 +6,7 @@
|
||||||
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct hostent *find_inet_addr __P((char *));
|
struct addrinfo *find_inet_addr __P((char *, int));
|
||||||
int check_dns __P((char *));
|
int check_dns __P((char *));
|
||||||
void shell_cmd __P((char *));
|
void shell_cmd __P((char *));
|
||||||
void clean_exit __P((struct request_info *));
|
void clean_exit __P((struct request_info *));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: tcpdchk.c,v 1.9 1999/08/31 13:58:58 itojun Exp $ */
|
/* $NetBSD: tcpdchk.c,v 1.10 2002/06/06 21:28:51 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tcpdchk - examine all tcpd access control rules and inetd.conf entries
|
* tcpdchk - examine all tcpd access control rules and inetd.conf entries
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25";
|
static char sccsid[] = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: tcpdchk.c,v 1.9 1999/08/31 13:58:58 itojun Exp $");
|
__RCSID("$NetBSD: tcpdchk.c,v 1.10 2002/06/06 21:28:51 itojun Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -29,9 +29,6 @@ __RCSID("$NetBSD: tcpdchk.c,v 1.9 1999/08/31 13:58:58 itojun Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef INET6
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -88,6 +85,9 @@ static void check_daemon_list __P((char *));
|
||||||
static void check_client_list __P((char *));
|
static void check_client_list __P((char *));
|
||||||
static void check_daemon __P((char *));
|
static void check_daemon __P((char *));
|
||||||
static void check_user __P((char *));
|
static void check_user __P((char *));
|
||||||
|
#ifdef INET6
|
||||||
|
static int check_inet_addr __P((char *));
|
||||||
|
#endif
|
||||||
static int check_host __P((char *));
|
static int check_host __P((char *));
|
||||||
static int reserved_name __P((char *));
|
static int reserved_name __P((char *));
|
||||||
|
|
||||||
|
@ -428,8 +428,22 @@ char *pat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check_host - criticize host pattern */
|
#ifdef INET6
|
||||||
|
static int check_inet_addr(pat)
|
||||||
|
char *pat;
|
||||||
|
{
|
||||||
|
struct addrinfo *res;
|
||||||
|
|
||||||
|
res = find_inet_addr(pat, AI_NUMERICHOST);
|
||||||
|
if (res) {
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check_host - criticize host pattern */
|
||||||
static int check_host(pat)
|
static int check_host(pat)
|
||||||
char *pat;
|
char *pat;
|
||||||
{
|
{
|
||||||
|
@ -455,18 +469,16 @@ char *pat;
|
||||||
#endif
|
#endif
|
||||||
} else if ((mask = split_at(pat, '/')) != NULL) { /* network/netmask */
|
} else if ((mask = split_at(pat, '/')) != NULL) { /* network/netmask */
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
struct in6_addr in6;
|
char *ep;
|
||||||
#endif
|
#endif
|
||||||
if (dot_quad_addr(pat, NULL) != INADDR_NONE
|
if (dot_quad_addr(pat, NULL) != INADDR_NONE
|
||||||
|| dot_quad_addr(mask, NULL) != INADDR_NONE)
|
|| dot_quad_addr(mask, NULL) != INADDR_NONE)
|
||||||
; /*okay*/
|
; /*okay*/
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
else if (inet_pton(AF_INET6, pat, &in6) == 1
|
else if (check_inet_addr(pat) && check_inet_addr(mask))
|
||||||
&& inet_pton(AF_INET6, mask, &in6) == 1)
|
|
||||||
; /*okay*/
|
; /*okay*/
|
||||||
else if (inet_pton(AF_INET6, pat, &in6) == 1
|
else if (check_inet_addr(pat) &&
|
||||||
&& strchr(mask, ':') == NULL
|
(ep = NULL, strtoul(mask, &ep, 10), ep && !*ep))
|
||||||
&& 0 <= atoi(mask) && atoi(mask) <= 128)
|
|
||||||
; /*okay*/
|
; /*okay*/
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: tcpdmatch.c,v 1.6 1999/08/31 13:58:58 itojun Exp $ */
|
/* $NetBSD: tcpdmatch.c,v 1.7 2002/06/06 21:28:50 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tcpdmatch - explain what tcpd would do in a specific case
|
* tcpdmatch - explain what tcpd would do in a specific case
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#) tcpdmatch.c 1.5 96/02/11 17:01:36";
|
static char sccsid[] = "@(#) tcpdmatch.c 1.5 96/02/11 17:01:36";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: tcpdmatch.c,v 1.6 1999/08/31 13:58:58 itojun Exp $");
|
__RCSID("$NetBSD: tcpdmatch.c,v 1.7 2002/06/06 21:28:50 itojun Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -64,25 +64,19 @@ int main(argc, argv)
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
{
|
{
|
||||||
struct hostent *hp;
|
struct addrinfo *res, *res0;
|
||||||
char *myname = argv[0];
|
char *myname = argv[0];
|
||||||
char *client;
|
char *client;
|
||||||
char *server;
|
char *server;
|
||||||
char *addr;
|
|
||||||
char *user;
|
char *user;
|
||||||
char *daemon;
|
char *daemon;
|
||||||
struct request_info request;
|
struct request_info request;
|
||||||
int ch;
|
int ch;
|
||||||
char *inetcf = 0;
|
char *inetcf = 0;
|
||||||
int count;
|
int count;
|
||||||
struct sockaddr_storage server_sin;
|
struct sockaddr_storage server_ss;
|
||||||
struct sockaddr_storage client_sin;
|
struct sockaddr_storage client_ss;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *ap;
|
|
||||||
int alen;
|
|
||||||
#ifdef INET6
|
|
||||||
struct sockaddr_in6 in6;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show what rule actually matched.
|
* Show what rule actually matched.
|
||||||
|
@ -182,28 +176,17 @@ char **argv;
|
||||||
* address and name conversion results.
|
* address and name conversion results.
|
||||||
*/
|
*/
|
||||||
if (NOT_INADDR(server) == 0 || HOSTNAME_KNOWN(server)) {
|
if (NOT_INADDR(server) == 0 || HOSTNAME_KNOWN(server)) {
|
||||||
if ((hp = find_inet_addr(server)) == 0)
|
if ((res0 = find_inet_addr(server, 0)) == NULL)
|
||||||
exit(1);
|
exit(1);
|
||||||
memset((char *) &server_sin, 0, sizeof(server_sin));
|
memset((char *) &server_ss, 0, sizeof(server_ss));
|
||||||
server_sin.ss_family = hp->h_addrtype;
|
request_set(&request, RQ_SERVER_SIN, &server_ss, 0);
|
||||||
switch (hp->h_addrtype) {
|
|
||||||
case AF_INET:
|
|
||||||
ap = (char *)&((struct sockaddr_in *)&server_sin)->sin_addr;
|
|
||||||
alen = sizeof(struct in_addr);
|
|
||||||
break;
|
|
||||||
#ifdef INET6
|
|
||||||
case AF_INET6:
|
|
||||||
ap = (char *)&((struct sockaddr_in6 *)&server_sin)->sin6_addr;
|
|
||||||
alen = sizeof(struct in6_addr);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
request_set(&request, RQ_SERVER_SIN, &server_sin, 0);
|
|
||||||
|
|
||||||
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
|
count = 0;
|
||||||
memcpy(ap, addr, alen);
|
for (res = res0; res; res = res->ai_next) {
|
||||||
|
count++;
|
||||||
|
if (res->ai_addrlen > sizeof(server_ss))
|
||||||
|
continue;
|
||||||
|
memcpy(&server_ss, res->ai_addr, res->ai_addrlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force evaluation of server host name and address. Host name
|
* Force evaluation of server host name and address. Host name
|
||||||
|
@ -219,7 +202,7 @@ char **argv;
|
||||||
fprintf(stderr, "Please specify an address instead\n");
|
fprintf(stderr, "Please specify an address instead\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
free((char *) hp);
|
freeaddrinfo(res0);
|
||||||
} else {
|
} else {
|
||||||
request_set(&request, RQ_SERVER_NAME, server, 0);
|
request_set(&request, RQ_SERVER_NAME, server, 0);
|
||||||
}
|
}
|
||||||
|
@ -228,18 +211,14 @@ char **argv;
|
||||||
* If a client address is specified, we simulate the effect of client
|
* If a client address is specified, we simulate the effect of client
|
||||||
* hostname lookup failure.
|
* hostname lookup failure.
|
||||||
*/
|
*/
|
||||||
if (dot_quad_addr(client, NULL) == 0) {
|
res0 = find_inet_addr(client, AI_NUMERICHOST);
|
||||||
request_set(&request, RQ_CLIENT_ADDR, client, 0);
|
if (res0 && !res0->ai_next) {
|
||||||
|
request_set(&request, RQ_CLIENT_SIN, res0->ai_addr);
|
||||||
tcpdmatch(&request);
|
tcpdmatch(&request);
|
||||||
|
freeaddrinfo(res0);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
#ifdef INET6
|
freeaddrinfo(res0);
|
||||||
if (inet_pton(AF_INET6, client, &in6) == 1) {
|
|
||||||
request_set(&request, RQ_CLIENT_ADDR, client, 0);
|
|
||||||
tcpdmatch(&request);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perhaps they are testing special client hostname patterns that aren't
|
* Perhaps they are testing special client hostname patterns that aren't
|
||||||
|
@ -259,28 +238,17 @@ char **argv;
|
||||||
* using the request.client structure as a cache for host name and
|
* using the request.client structure as a cache for host name and
|
||||||
* address conversion results.
|
* address conversion results.
|
||||||
*/
|
*/
|
||||||
if ((hp = find_inet_addr(client)) == 0)
|
if ((res0 = find_inet_addr(client, 0)) == NULL)
|
||||||
exit(1);
|
exit(1);
|
||||||
memset((char *) &client_sin, 0, sizeof(client_sin));
|
memset((char *) &client_ss, 0, sizeof(client_ss));
|
||||||
client_sin.ss_family = hp->h_addrtype;
|
request_set(&request, RQ_CLIENT_SIN, &client_ss, 0);
|
||||||
switch (hp->h_addrtype) {
|
|
||||||
case AF_INET:
|
|
||||||
ap = (char *)&((struct sockaddr_in *)&client_sin)->sin_addr;
|
|
||||||
alen = sizeof(struct in_addr);
|
|
||||||
break;
|
|
||||||
#ifdef INET6
|
|
||||||
case AF_INET6:
|
|
||||||
ap = (char *)&((struct sockaddr_in6 *)&client_sin)->sin6_addr;
|
|
||||||
alen = sizeof(struct in6_addr);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
request_set(&request, RQ_CLIENT_SIN, &client_sin, 0);
|
|
||||||
|
|
||||||
for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) {
|
count = 0;
|
||||||
memcpy(ap, addr, alen);
|
for (res = res0; res; res = res->ai_next) {
|
||||||
|
count++;
|
||||||
|
if (res->ai_addrlen > sizeof(client_ss))
|
||||||
|
continue;
|
||||||
|
memcpy(&client_ss, res->ai_addr, res->ai_addrlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force evaluation of client host name and address. Host name
|
* Force evaluation of client host name and address. Host name
|
||||||
|
@ -291,10 +259,10 @@ char **argv;
|
||||||
tcpd_warn("host address %s->name lookup failed",
|
tcpd_warn("host address %s->name lookup failed",
|
||||||
eval_hostaddr(request.client));
|
eval_hostaddr(request.client));
|
||||||
tcpdmatch(&request);
|
tcpdmatch(&request);
|
||||||
if (hp->h_addr_list[count + 1])
|
if (res->ai_next)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
free((char *) hp);
|
freeaddrinfo(res0);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue