diff --git a/lib/libwrap/hosts_access.c b/lib/libwrap/hosts_access.c index ce16c57bc1f8..eeb7b8528315 100644 --- a/lib/libwrap/hosts_access.c +++ b/lib/libwrap/hosts_access.c @@ -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 @@ -24,7 +24,7 @@ #if 0 static char sccsid[] = "@(#) hosts_access.c 1.21 97/02/12 02:13:22"; #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 @@ -372,9 +372,14 @@ char *string; #ifndef INET6 return masked_match4(net_tok, mask_tok, string); #else - if (dot_quad_addr(net_tok, NULL) != INADDR_NONE - && dot_quad_addr(mask_tok, NULL) != INADDR_NONE - && dot_quad_addr(string, NULL) != INADDR_NONE) { + /* + * masked_match4() is kept just for supporting shortened IPv4 address form. + * 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); } else return masked_match6(net_tok, mask_tok, string); @@ -398,8 +403,8 @@ char *string; if (dot_quad_addr(string, &addr) != 0) return (NO); - if (dot_quad_addr(net_tok, &net) != 0 - || dot_quad_addr(mask_tok, &mask) != 0) { + if (dot_quad_addr(net_tok, &net) != 0 || + dot_quad_addr(mask_tok, &mask) != 0) { tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok); return (NO); /* not tcpd_jump() */ } @@ -411,75 +416,140 @@ char *string; } #ifdef INET6 -/* Ugly because it covers IPv4 mapped address. I hate mapped addresses. */ static int masked_match6(net_tok, mask_tok, string) char *net_tok; char *mask_tok; char *string; { - struct in6_addr net; - struct in6_addr mask; - struct in6_addr addr; - int masklen; - int fail; + union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } net, mask, addr; + struct addrinfo hints, *res; + unsigned long masklen; + char *ep; int i; - int maskoff; - int netaf; - int dirty; - const int sizoff64 = sizeof(struct in6_addr) - sizeof(struct in_addr); + char *np, *mp, *ap; + int alen; - memset(&addr, 0, sizeof(addr)); - if (inet_pton(AF_INET6, string, &addr) == 1) - ; /* okay */ - else if (inet_pton(AF_INET, string, &addr.s6_addr[sizoff64]) == 1) - addr.s6_addr[10] = addr.s6_addr[11] = 0xff; - else - return NO; - - memset(&net, 0, sizeof(net)); - if (inet_pton(AF_INET6, net_tok, &net) == 1) { - 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; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(net_tok, "0", &hints, &res) == 0) { + if (res->ai_addrlen > sizeof(net) || res->ai_next) { + freeaddrinfo(res); + return NO; + } + memcpy(&net, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); } else return NO; - fail = 0; - if (mask_tok[strspn(mask_tok, "0123456789")] == '\0') { - masklen = atoi(mask_tok) + maskoff * 8; - if (0 <= masklen && masklen <= 128) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = net.sa.sa_family; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + 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, 0xff, masklen / 8); - if (masklen % 8) { - ((u_char *)&mask)[masklen / 8] = - (0xff00 >> (masklen % 8)) & 0xff; + mask.sa.sa_family = net.sa.sa_family; + mask.sa.sa_len = net.sa.sa_len; + switch (mask.sa.sa_family) { + 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 - fail++; - } 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); + return NO; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + 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 - fail++; - if (fail) { - tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok); - return (NO); /* not tcpd_jump() */ + return NO; + + if (net.sa.sa_family != mask.sa.sa_family || + net.sa.sa_family != addr.sa.sa_family) { + return NO; + } + + 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; } - dirty = 0; - for (i = 0; i < sizeof(addr); i++) { - addr.s6_addr[i] &= mask.s6_addr[i]; - dirty |= (net.s6_addr[i] & ~mask.s6_addr[i]); - } + 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); + break; + } - if (dirty) - tcpd_warn("host bits not all zero in %s/%s", net_tok, mask_tok); + for (i = 0; i < alen; i++) + ap[i] &= mp[i]; - return (memcmp(&addr, &net, sizeof(addr)) == 0); + 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 diff --git a/lib/libwrap/socket.c b/lib/libwrap/socket.c index 59b5b61ce3b3..70231ed0e952 100644 --- a/lib/libwrap/socket.c +++ b/lib/libwrap/socket.c @@ -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 @@ -22,7 +22,7 @@ #if 0 static char sccsid[] = "@(#) socket.c 1.15 97/03/21 19:27:24"; #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 @@ -105,27 +105,12 @@ void sock_hostaddr(host) struct host_info *host; { struct sockaddr *sa = host->sin; - int alen, af; - char *ap; if (!sa) 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'; - 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 */ @@ -133,95 +118,84 @@ struct host_info *host; void sock_hostname(host) struct host_info *host; { - struct sockaddr *sinp = host->sin; - struct hostent *hp; - int i; - 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; + struct sockaddr *sa = host->sin; + char h1[NI_MAXHOST], h2[NI_MAXHOST]; + struct addrinfo hints, *res, *res0; #ifdef INET6 - case AF_INET6: - 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; + struct sockaddr_in tmp; #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; } - if ((hp = gethostbyaddr(ap, alen, af)) != 0) { - - STRN_CPY(host->name, hp->h_name, sizeof(host->name)); - + if (getnameinfo(sa, sa->sa_len, host->name, sizeof(host->name), NULL, 0, + NI_NAMEREQD) == 0) { /* * 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. * - * 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 - * can't believe the address list from gethostbyname("localhost") + * can't believe the address list from getaddrinfo("localhost") * we're in big trouble anyway. */ - - if ((hp = gethostbyname2(host->name, af)) == 0) { - + memset(&hints, 0, sizeof(hints)); + 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 * may be a transient problem or a botched name server setup. */ - tcpd_warn("can't verify hostname: gethostbyname2(%s, %d) failed", - host->name, af); - - } else if (STR_NE(host->name, hp->h_name) - && STR_NE(host->name, "localhost")) { - + tcpd_warn("can't verify hostname: getaddrinfo(%s, %d) failed", + host->name, hints.ai_family); + } else if (res0->ai_canonname && + STR_NE(host->name, res0->ai_canonname) && + 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 * problem. It could also be that someone is trying to spoof us. */ - tcpd_warn("host name/name mismatch: %s != %.*s", - host->name, STRING_LENGTH, hp->h_name); - + tcpd_warn("host name/name mismatch: %s != %s", + host->name, res0->ai_canonname); + freeaddrinfo(res0); } else { - /* * The address should be a member of the address list returned by - * gethostbyname(). We should first verify that the h_addrtype - * field is AF_INET, but this program has already caused too much - * grief on systems with broken library code. + * getaddrinfo(). */ - for (i = 0; hp->h_addr_list[i]; i++) { - if (memcmp(hp->h_addr_list[i], (char *) ap, alen) == 0) - return; /* name is good, keep it */ + for (res = res0; res; res = res->ai_next) { + if (getnameinfo(res->ai_addr, res->ai_addrlen, h2, sizeof(h2), + NULL, 0, NI_NUMERICHOST) != 0) { + continue; + } + if (STR_EQ(h1, h2)) { + freeaddrinfo(res0); + return; + } } /* @@ -230,9 +204,10 @@ struct host_info *host; * server. */ - tcpd_warn("host name/address mismatch: %s != %.*s", - inet_ntop(af, ap, hbuf, sizeof(hbuf)), - STRING_LENGTH, hp->h_name); + tcpd_warn("host name/address mismatch: %s != %s", h1, + res0->ai_canonname ? res0->ai_canonname : "?"); + + freeaddrinfo(res0); } /* name is bad, clobber it */ (void)strncpy(host->name, paranoid, sizeof(host->name) - 1); diff --git a/usr.sbin/tcpdchk/scaffold.c b/usr.sbin/tcpdchk/scaffold.c index ebb3f05ea62d..a744a9627747 100644 --- a/usr.sbin/tcpdchk/scaffold.c +++ b/usr.sbin/tcpdchk/scaffold.c @@ -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. @@ -11,7 +11,7 @@ #if 0 static char sccs_id[] = "@(#) scaffold.c 1.6 97/03/21 19:27:24"; #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 @@ -38,8 +38,6 @@ __RCSID("$NetBSD: scaffold.c,v 1.7 1999/08/31 13:58:58 itojun Exp $"); #include "tcpd.h" #include "scaffold.h" -static struct hostent *dup_hostent __P((struct hostent *)); - /* * These are referenced by the options module and by rfc931.c. */ @@ -47,119 +45,29 @@ int allow_severity = SEVERITY; int deny_severity = LOG_WARNING; 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() */ -struct hostent *find_inet_addr(host) +struct addrinfo *find_inet_addr(host, flags) char *host; +int flags; { - struct in_addr addr; - unsigned long addr_num; - struct hostent *hp; - static struct hostent h; - static char *addr_list[2]; -#ifdef INET6 - static struct in6_addr in6; -#endif + struct addrinfo hints, *res; + int error; - /* - * Host address: translate it to internal form. - */ - if (dot_quad_addr(host, &addr_num) == 0) { - addr.s_addr = (addr_num & 0xffffffff); - h.h_addr_list = addr_list; - h.h_addr_list[0] = (char *) &addr; - h.h_length = sizeof(addr); - h.h_addrtype = AF_INET; - return (dup_hostent(&h)); + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_CANONNAME | flags; + error = getaddrinfo(host, "0", &hints, &res); + if (error) { + tcpd_warn("%s: %s", host, gai_strerror(error)); + return (0); } -#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 - /* - * 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)) { + if (res->ai_canonname && STR_NE(host, res->ai_canonname)) { 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 */ @@ -168,36 +76,22 @@ int check_dns(host) char *host; { struct request_info request; - struct sockaddr_storage sin; - struct hostent *hp; + struct sockaddr_storage ss; + struct addrinfo *res0, *res; 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); - request_init(&request, RQ_CLIENT_SIN, &sin, 0); + memset(&ss, 0, sizeof(ss)); + request_init(&request, RQ_CLIENT_SIN, &ss, 0); 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++) { - memcpy(ap, addr, alen); + count = 0; + 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 @@ -209,8 +103,9 @@ char *host; if (STR_EQ(eval_hostname(request.client), unknown)) tcpd_warn("host address %s->name lookup failed", eval_hostaddr(request.client)); + tcpd_warn("%s %s", eval_hostname(request.client), unknown); } - free((char *) hp); + freeaddrinfo(res0); return (count); } diff --git a/usr.sbin/tcpdchk/scaffold.h b/usr.sbin/tcpdchk/scaffold.h index 87419da127c5..43685c2318a2 100644 --- a/usr.sbin/tcpdchk/scaffold.h +++ b/usr.sbin/tcpdchk/scaffold.h @@ -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 @@ -6,7 +6,7 @@ * 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 *)); void shell_cmd __P((char *)); void clean_exit __P((struct request_info *)); diff --git a/usr.sbin/tcpdchk/tcpdchk.c b/usr.sbin/tcpdchk/tcpdchk.c index 4e8f3f323a84..a53c6ff58e03 100644 --- a/usr.sbin/tcpdchk/tcpdchk.c +++ b/usr.sbin/tcpdchk/tcpdchk.c @@ -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 @@ -21,7 +21,7 @@ #if 0 static char sccsid[] = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25"; #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 @@ -29,9 +29,6 @@ __RCSID("$NetBSD: tcpdchk.c,v 1.9 1999/08/31 13:58:58 itojun Exp $"); #include #include -#ifdef INET6 -#include -#endif #include #include #include @@ -88,6 +85,9 @@ static void check_daemon_list __P((char *)); static void check_client_list __P((char *)); static void check_daemon __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 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) char *pat; { @@ -455,18 +469,16 @@ char *pat; #endif } else if ((mask = split_at(pat, '/')) != NULL) { /* network/netmask */ #ifdef INET6 - struct in6_addr in6; + char *ep; #endif if (dot_quad_addr(pat, NULL) != INADDR_NONE || dot_quad_addr(mask, NULL) != INADDR_NONE) ; /*okay*/ #ifdef INET6 - else if (inet_pton(AF_INET6, pat, &in6) == 1 - && inet_pton(AF_INET6, mask, &in6) == 1) + else if (check_inet_addr(pat) && check_inet_addr(mask)) ; /*okay*/ - else if (inet_pton(AF_INET6, pat, &in6) == 1 - && strchr(mask, ':') == NULL - && 0 <= atoi(mask) && atoi(mask) <= 128) + else if (check_inet_addr(pat) && + (ep = NULL, strtoul(mask, &ep, 10), ep && !*ep)) ; /*okay*/ #endif else diff --git a/usr.sbin/tcpdmatch/tcpdmatch.c b/usr.sbin/tcpdmatch/tcpdmatch.c index 34c7ec9de05a..86d2dd2714fd 100644 --- a/usr.sbin/tcpdmatch/tcpdmatch.c +++ b/usr.sbin/tcpdmatch/tcpdmatch.c @@ -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 @@ -20,7 +20,7 @@ #if 0 static char sccsid[] = "@(#) tcpdmatch.c 1.5 96/02/11 17:01:36"; #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 @@ -64,25 +64,19 @@ int main(argc, argv) int argc; char **argv; { - struct hostent *hp; + struct addrinfo *res, *res0; char *myname = argv[0]; char *client; char *server; - char *addr; char *user; char *daemon; struct request_info request; int ch; char *inetcf = 0; int count; - struct sockaddr_storage server_sin; - struct sockaddr_storage client_sin; + struct sockaddr_storage server_ss; + struct sockaddr_storage client_ss; struct stat st; - char *ap; - int alen; -#ifdef INET6 - struct sockaddr_in6 in6; -#endif /* * Show what rule actually matched. @@ -182,28 +176,17 @@ char **argv; * address and name conversion results. */ 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); - memset((char *) &server_sin, 0, sizeof(server_sin)); - server_sin.ss_family = hp->h_addrtype; - 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); + memset((char *) &server_ss, 0, sizeof(server_ss)); + request_set(&request, RQ_SERVER_SIN, &server_ss, 0); - for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) { - memcpy(ap, addr, alen); + count = 0; + 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 @@ -219,7 +202,7 @@ char **argv; fprintf(stderr, "Please specify an address instead\n"); exit(1); } - free((char *) hp); + freeaddrinfo(res0); } else { 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 * hostname lookup failure. */ - if (dot_quad_addr(client, NULL) == 0) { - request_set(&request, RQ_CLIENT_ADDR, client, 0); + res0 = find_inet_addr(client, AI_NUMERICHOST); + if (res0 && !res0->ai_next) { + request_set(&request, RQ_CLIENT_SIN, res0->ai_addr); tcpdmatch(&request); + freeaddrinfo(res0); exit(0); } -#ifdef INET6 - if (inet_pton(AF_INET6, client, &in6) == 1) { - request_set(&request, RQ_CLIENT_ADDR, client, 0); - tcpdmatch(&request); - exit(0); - } -#endif + freeaddrinfo(res0); /* * 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 * address conversion results. */ - if ((hp = find_inet_addr(client)) == 0) + if ((res0 = find_inet_addr(client, 0)) == NULL) exit(1); - memset((char *) &client_sin, 0, sizeof(client_sin)); - client_sin.ss_family = hp->h_addrtype; - 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); + memset((char *) &client_ss, 0, sizeof(client_ss)); + request_set(&request, RQ_CLIENT_SIN, &client_ss, 0); - for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) { - memcpy(ap, addr, alen); + count = 0; + 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 @@ -291,10 +259,10 @@ char **argv; tcpd_warn("host address %s->name lookup failed", eval_hostaddr(request.client)); tcpdmatch(&request); - if (hp->h_addr_list[count + 1]) + if (res->ai_next) printf("\n"); } - free((char *) hp); + freeaddrinfo(res0); exit(0); }