diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2002-06-07 03:32:05 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2002-06-07 03:32:05 +0000 |
commit | 7ab586a39aaba2282184b2e377a64b5c3d16ace5 (patch) | |
tree | 435bf7f430d17a473dd290ade0e70f3bd43c3148 /libexec | |
parent | e06010752854f5ea2eeb25c2b5694b82be59c2ea (diff) |
support scoped IPv6 address.
no visible API change, old config files work just fine.
now you can use expressions like "ALL: [fe80::%lo0/64]". theo ok
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/tcpd/tcpdchk/scaffold.c | 163 | ||||
-rw-r--r-- | libexec/tcpd/tcpdchk/scaffold.h | 4 | ||||
-rw-r--r-- | libexec/tcpd/tcpdchk/tcpdchk.c | 57 | ||||
-rw-r--r-- | libexec/tcpd/tcpdmatch/tcpdmatch.c | 100 |
4 files changed, 102 insertions, 222 deletions
diff --git a/libexec/tcpd/tcpdchk/scaffold.c b/libexec/tcpd/tcpdchk/scaffold.c index 46a4797e1e4..582cea1d173 100644 --- a/libexec/tcpd/tcpdchk/scaffold.c +++ b/libexec/tcpd/tcpdchk/scaffold.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scaffold.c,v 1.5 2002/05/07 23:01:07 deraadt Exp $ */ +/* $OpenBSD: scaffold.c,v 1.6 2002/06/07 03:32:04 itojun Exp $ */ /* * Routines for testing only. Not really industrial strength. @@ -10,7 +10,7 @@ #if 0 static char sccs_id[] = "@(#) scaffold.c 1.5 95/01/03 09:13:48"; #else -static char rcsid[] = "$OpenBSD: scaffold.c,v 1.5 2002/05/07 23:01:07 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: scaffold.c,v 1.6 2002/06/07 03:32:04 itojun Exp $"; #endif #endif @@ -43,119 +43,31 @@ static char rcsid[] = "$OpenBSD: scaffold.c,v 1.5 2002/05/07 23:01:07 deraadt Ex */ int allow_severity = SEVERITY; int deny_severity = LOG_WARNING; -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); -} +int rfc931_timeout = RFC931_TIMEOUT; /* 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; - struct hostent *hp; - static struct hostent h; - static char *addr_list[2]; -#ifdef INET6 - static struct in6_addr in6; -#endif - - /* - * Host address: translate it to internal form. - */ - if (dot_quad_addr_new(host, &addr.s_addr)) { - 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)); - } -#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); + struct addrinfo hints, *res; + int error; + + 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); } - 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)", 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 */ @@ -164,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 in_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 @@ -205,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/libexec/tcpd/tcpdchk/scaffold.h b/libexec/tcpd/tcpdchk/scaffold.h index 2450d24ca10..7bb69bc18a2 100644 --- a/libexec/tcpd/tcpdchk/scaffold.h +++ b/libexec/tcpd/tcpdchk/scaffold.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scaffold.h,v 1.2 2002/02/16 21:27:31 millert Exp $ */ +/* $OpenBSD: scaffold.h,v 1.3 2002/06/07 03:32:04 itojun Exp $ */ /* * @(#) scaffold.h 1.3 94/12/31 18:19:19 @@ -9,7 +9,7 @@ #include <sys/cdefs.h> __BEGIN_DECLS -extern struct hostent *find_inet_addr(char *); +extern struct addrinfo *find_inet_addr(char *, int); extern int check_dns(char *); extern int check_path(char *, struct stat *); __END_DECLS diff --git a/libexec/tcpd/tcpdchk/tcpdchk.c b/libexec/tcpd/tcpdchk/tcpdchk.c index ec605da57da..ebe74dafcc7 100644 --- a/libexec/tcpd/tcpdchk/tcpdchk.c +++ b/libexec/tcpd/tcpdchk/tcpdchk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcpdchk.c,v 1.5 2001/07/08 21:18:13 deraadt Exp $ */ +/* $OpenBSD: tcpdchk.c,v 1.6 2002/06/07 03:32:04 itojun Exp $ */ /* * tcpdchk - examine all tcpd access control rules and inetd.conf entries @@ -20,7 +20,7 @@ #if 0 static char sccsid[] = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25"; #else -static char rcsid[] = "$OpenBSD: tcpdchk.c,v 1.5 2001/07/08 21:18:13 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: tcpdchk.c,v 1.6 2002/06/07 03:32:04 itojun Exp $"; #endif #endif @@ -28,9 +28,6 @@ static char rcsid[] = "$OpenBSD: tcpdchk.c,v 1.5 2001/07/08 21:18:13 deraadt Exp #include <sys/types.h> #include <sys/stat.h> -#ifdef INET6 -#include <sys/socket.h> -#endif #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> @@ -76,15 +73,18 @@ extern jmp_buf tcpd_buf; /* * Local stuff. */ -static void usage(); -static void parse_table(); -static void print_list(); -static void check_daemon_list(); -static void check_client_list(); -static void check_daemon(); -static void check_user(); -static int check_host(); -static int reserved_name(); +static void usage(void); +static void parse_table(char *, struct request_info *); +static void print_list(char *, char *); +static void check_daemon_list(char *); +static void check_client_list(char *); +static void check_daemon(char *); +static void check_user(char *); +#ifdef INET6 +static int check_inet_addr(char *); +#endif +static int check_host(char *); +static int reserved_name(char *); #define PERMIT 1 #define DENY 0 @@ -419,8 +419,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; { @@ -446,18 +460,15 @@ 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_new(pat, NULL) - && dot_quad_addr_new(mask, NULL)) + if (dot_quad_addr_new(pat, NULL) && dot_quad_addr_new(mask, NULL)) ; /*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/libexec/tcpd/tcpdmatch/tcpdmatch.c b/libexec/tcpd/tcpdmatch/tcpdmatch.c index f9de6575da6..de15e410663 100644 --- a/libexec/tcpd/tcpdmatch/tcpdmatch.c +++ b/libexec/tcpd/tcpdmatch/tcpdmatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcpdmatch.c,v 1.5 2000/10/14 00:56:15 itojun Exp $ */ +/* $OpenBSD: tcpdmatch.c,v 1.6 2002/06/07 03:32:04 itojun Exp $ */ /* * tcpdmatch - explain what tcpd would do in a specific case @@ -19,7 +19,7 @@ #if 0 static char sccsid[] = "@(#) tcpdmatch.c 1.5 96/02/11 17:01:36"; #else -static char rcsid[] = "$OpenBSD: tcpdmatch.c,v 1.5 2000/10/14 00:56:15 itojun Exp $"; +static char rcsid[] = "$OpenBSD: tcpdmatch.c,v 1.6 2002/06/07 03:32:04 itojun Exp $"; #endif #endif @@ -53,8 +53,9 @@ static char rcsid[] = "$OpenBSD: tcpdmatch.c,v 1.5 2000/10/14 00:56:15 itojun Ex #include "inetcf.h" #include "scaffold.h" -static void usage(); -static void tcpdmatch(); +static void usage(char *); +static void expand(char *, char *, struct request_info *); +static void tcpdmatch(struct request_info *); /* The main program */ @@ -62,25 +63,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. @@ -180,28 +175,17 @@ char **argv; * address and name conversion results. */ if (NOT_INADDR(server) == 0 || HOSTNAME_KNOWN(server)) { - if ((hp = find_inet_addr(server)) == 0) - 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: + if ((res0 = find_inet_addr(server, 0)) == NULL) 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 @@ -217,7 +201,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); } @@ -226,18 +210,15 @@ char **argv; * If a client address is specified, we simulate the effect of client * hostname lookup failure. */ - if (dot_quad_addr_new(client, NULL)) { - request_set(&request, RQ_CLIENT_ADDR, client, 0); - tcpdmatch(&request); - exit(0); - } -#ifdef INET6 - if (inet_pton(AF_INET6, client, &in6) == 1) { - 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); } -#endif + if (res0) + freeaddrinfo(res0); /* * Perhaps they are testing special client hostname patterns that aren't @@ -257,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) - 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: + if ((res0 = find_inet_addr(client, 0)) == NULL) 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 @@ -289,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); } |