From owner-freebsd-audit Thu Mar 15 8:10:48 2001 Delivered-To: freebsd-audit@freebsd.org Received: from khavrinen.lcs.mit.edu (khavrinen.lcs.mit.edu [18.24.4.193]) by hub.freebsd.org (Postfix) with ESMTP id B5B4837B718; Thu, 15 Mar 2001 08:10:43 -0800 (PST) (envelope-from wollman@khavrinen.lcs.mit.edu) Received: (from wollman@localhost) by khavrinen.lcs.mit.edu (8.9.3/8.9.3) id LAA46410; Thu, 15 Mar 2001 11:10:42 -0500 (EST) (envelope-from wollman) Date: Thu, 15 Mar 2001 11:10:42 -0500 (EST) From: Garrett Wollman Message-Id: <200103151610.LAA46410@khavrinen.lcs.mit.edu> To: freebsd-standards@bostonradio.org, audit@freebsd.org, current@freebsd.org Subject: Latest version of mega header file POSIX update Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG I have finally produced another version of the big header file patch for people to look at. I'm still running an older (January) kernel and world based on these changes. I have verified that these still build on i386-architecture systems. I'm looking for some people to do the following: 1) Look at the changes to machine-dependent i386 headers and make analogous changes, or verify the changes I've made, in the Alpha and IA64 code. 2) Test it. I'm interested not only in whether it runs -- I'm fairly confident of that -- but also in what external software it breaks, if any. I'm expecting to make a third pass over the header files once Austin Group draft 6 is issued. (Draft 7 is expected to be the final text.) However, I really, really want to get this checked in so that we can all have a framework on which to work. The patch has now gotten too large for some e-mail systems, so I'm making it available via the Web at . -GAWollman To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu Mar 15 14:33:29 2001 Delivered-To: freebsd-audit@freebsd.org Received: from meow.osd.bsdi.com (meow.osd.bsdi.com [204.216.28.88]) by hub.freebsd.org (Postfix) with ESMTP id 37D7537B718; Thu, 15 Mar 2001 14:33:26 -0800 (PST) (envelope-from jhb@FreeBSD.org) Received: from laptop.baldwin.cx (john@jhb-laptop.osd.bsdi.com [204.216.28.241]) by meow.osd.bsdi.com (8.11.2/8.11.2) with ESMTP id f2FMWOG24836; Thu, 15 Mar 2001 14:32:25 -0800 (PST) (envelope-from jhb@FreeBSD.org) Message-ID: X-Mailer: XFMail 1.4.0 on FreeBSD X-Priority: 3 (Normal) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit MIME-Version: 1.0 In-Reply-To: <200103151610.LAA46410@khavrinen.lcs.mit.edu> Date: Thu, 15 Mar 2001 14:32:20 -0800 (PST) From: John Baldwin To: Garrett Wollman Subject: RE: Latest version of mega header file POSIX update Cc: current@FreeBSD.org, audit@FreeBSD.org, freebsd-standards@bostonradio.org Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On 15-Mar-01 Garrett Wollman wrote: > The patch has now gotten too large for some e-mail systems, so I'm > making it available via the Web at > . I don't think the sys/conf/Makefile.i386 change is needed. :) Nothing else jumped out at me while I glanced over it however, and it seems fine at first glance. -- John Baldwin -- http://www.FreeBSD.org/~jhb/ PGP Key: http://www.baldwin.cx/~john/pgpkey.asc "Power Users Use the Power to Serve!" - http://www.FreeBSD.org/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Fri Mar 16 8: 0:53 2001 Delivered-To: freebsd-audit@freebsd.org Received: from khavrinen.lcs.mit.edu (khavrinen.lcs.mit.edu [18.24.4.193]) by hub.freebsd.org (Postfix) with ESMTP id DF69D37B719; Fri, 16 Mar 2001 08:00:49 -0800 (PST) (envelope-from wollman@khavrinen.lcs.mit.edu) Received: (from wollman@localhost) by khavrinen.lcs.mit.edu (8.9.3/8.9.3) id LAA59683; Fri, 16 Mar 2001 11:00:46 -0500 (EST) (envelope-from wollman) Date: Fri, 16 Mar 2001 11:00:46 -0500 (EST) From: Garrett Wollman Message-Id: <200103161600.LAA59683@khavrinen.lcs.mit.edu> To: John Baldwin Cc: current@FreeBSD.org, audit@FreeBSD.org, freebsd-standards@bostonradio.org Subject: RE: Latest version of mega header file POSIX update In-Reply-To: References: <200103151610.LAA46410@khavrinen.lcs.mit.edu> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG < said: > I don't think the sys/conf/Makefile.i386 change is needed. :) Oops. Sorry, that one leaked out.... > Nothing else jumped out at me while I glanced over it however, and > it seems fine at first glance. But did you *test* it? I know it compiles. -GAWollman To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Fri Mar 16 11:39: 8 2001 Delivered-To: freebsd-audit@freebsd.org Received: from meow.osd.bsdi.com (meow.osd.bsdi.com [204.216.28.88]) by hub.freebsd.org (Postfix) with ESMTP id 1A98437B71A; Fri, 16 Mar 2001 11:39:04 -0800 (PST) (envelope-from jhb@FreeBSD.org) Received: from laptop.baldwin.cx (john@jhb-laptop.osd.bsdi.com [204.216.28.241]) by meow.osd.bsdi.com (8.11.2/8.11.2) with ESMTP id f2GJbqG60203; Fri, 16 Mar 2001 11:37:52 -0800 (PST) (envelope-from jhb@FreeBSD.org) Message-ID: X-Mailer: XFMail 1.4.0 on FreeBSD X-Priority: 3 (Normal) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit MIME-Version: 1.0 In-Reply-To: <200103161600.LAA59683@khavrinen.lcs.mit.edu> Date: Fri, 16 Mar 2001 11:38:03 -0800 (PST) From: John Baldwin To: Garrett Wollman Subject: RE: Latest version of mega header file POSIX update Cc: freebsd-standards@bostonradio.org, audit@FreeBSD.org, current@FreeBSD.org Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On 16-Mar-01 Garrett Wollman wrote: > < > said: > >> Nothing else jumped out at me while I glanced over it however, and >> it seems fine at first glance. > > But did you *test* it? I know it compiles. No, not yet. I can try it out on my SMP and alpha testboxes here, though my the witness_exit panic deadlocks my alpha under heavy load. :-P > -GAWollman -- John Baldwin -- http://www.FreeBSD.org/~jhb/ PGP Key: http://www.baldwin.cx/~john/pgpkey.asc "Power Users Use the Power to Serve!" - http://www.FreeBSD.org/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Fri Mar 16 14: 1: 4 2001 Delivered-To: freebsd-audit@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 1E6BB37B71A; Fri, 16 Mar 2001 14:01:01 -0800 (PST) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id JAA11786; Sat, 17 Mar 2001 09:00:33 +1100 Date: Sat, 17 Mar 2001 09:00:16 +1100 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Garrett Wollman Cc: freebsd-standards@bostonradio.org, audit@FreeBSD.ORG, current@FreeBSD.ORG Subject: Re: Latest version of mega header file POSIX update In-Reply-To: <200103151610.LAA46410@khavrinen.lcs.mit.edu> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Thu, 15 Mar 2001, Garrett Wollman wrote: > The patch has now gotten too large for some e-mail systems, so I'm > making it available via the Web at > . Please include it in the mail anyway so that it is easier to see and reply if the e-mail system actually works. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat Mar 17 6:41:49 2001 Delivered-To: freebsd-audit@freebsd.org Received: from peace.mahoroba.org (peace.calm.imasy.or.jp [202.227.26.34]) by hub.freebsd.org (Postfix) with ESMTP id 919B437B71A; Sat, 17 Mar 2001 06:41:22 -0800 (PST) (envelope-from ume@FreeBSD.org) Received: from localhost (IDENT:WJXqsQemxu+a/yZiE2qXmkBE3bNU35d4dLIM4cGPDO8qQDnDmzsh1EhBuVcaAW/R@localhost [::1]) (authenticated as ume with CRAM-MD5) by peace.mahoroba.org (8.11.3/8.11.3/peace) with ESMTP/inet6 id f2HEbwR83437; Sat, 17 Mar 2001 23:38:00 +0900 (JST) (envelope-from ume@FreeBSD.org) Date: Sat, 17 Mar 2001 23:37:58 +0900 (JST) Message-Id: <20010317.233758.21880242.ume@FreeBSD.org> To: audit@FreeBSD.org, net@FreeBSD.org Subject: [CFR] IPv6 support for skeyaccess(3) From: Hajimu UMEMOTO X-Mailer: Mew version 1.95b97 on Emacs 20.7 / Mule 4.0 =?iso-2022-jp?B?KBskQjJWMWMbKEIp?= X-PGP-Public-Key: http://www.imasy.org/~ume/publickey.asc X-PGP-Fingerprint: 6B 0C 53 FC 5D D0 37 91 05 D0 B3 EF 36 9B 6A BC X-URL: http://www.imasy.org/~ume/ X-OS: FreeBSD 5.0-CURRENT Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Hi, I wish to support IPv6 for skeyaccess(3). With this patch, you can specify IPv6 address using `internet' keyword into /etc/skey.access. Please review it. Index: lib/libskey/skeyaccess.c diff -u lib/libskey/skeyaccess.c.orig lib/libskey/skeyaccess.c --- lib/libskey/skeyaccess.c.orig Mon Oct 26 20:54:36 1998 +++ lib/libskey/skeyaccess.c Fri Mar 16 03:04:48 2001 @@ -63,8 +63,8 @@ static int match_group __P((struct login_info *)); static int match_token __P((char *)); static int is_internet_addr __P((char *)); -static struct in_addr *convert_internet_addr __P((char *)); -static struct in_addr *lookup_internet_addr __P((char *)); +static struct addrinfo *convert_internet_addr __P((char *)); +static struct addrinfo *lookup_internet_addr __P((char *)); #define MAX_ADDR 32 #define PERMIT 1 @@ -79,7 +79,7 @@ struct login_info { char *host_name; /* host name */ - struct in_addr *internet_addr; /* null terminated list */ + struct addrinfo *internet_addr; /* addrinfo chain */ char *user; /* user name */ char *port; /* login port */ }; @@ -120,22 +120,22 @@ login_info.user = user; login_info.port = port; - if (host != 0 && !is_internet_addr(host)) { + if (host != NULL && !is_internet_addr(host)) { login_info.host_name = host; } else { - login_info.host_name = 0; + login_info.host_name = NULL; } - if (addr != 0 && is_internet_addr(addr)) { + if (addr != NULL && is_internet_addr(addr)) { login_info.internet_addr = convert_internet_addr(addr); - } else if (host != 0) { + } else if (host != NULL) { if (is_internet_addr(host)) { login_info.internet_addr = convert_internet_addr(host); } else { login_info.internet_addr = lookup_internet_addr(host); } } else { - login_info.internet_addr = 0; + login_info.internet_addr = NULL; } /* @@ -146,19 +146,23 @@ printf("user: %s\n", login_info.user); printf("host: %s\n", login_info.host_name ? login_info.host_name : "none"); printf("addr: "); - if (login_info.internet_addr == 0) { + if (login_info.internet_addr == NULL) { printf("none\n"); } else { - int i; + struct addrinfo *res; + char haddr[NI_MAXHOST]; - for (i = 0; login_info.internet_addr[i].s_addr; i++) - printf("%s%s", login_info.internet_addr[i].s_addr == -1 ? - "(see error log)" : inet_ntoa(login_info.internet_addr[i]), - login_info.internet_addr[i + 1].s_addr ? " " : "\n"); + for (res = login_info.internet_addr; res; res = res->ai_next) { + getnameinfo(res->ai_addr, res->ai_addrlen, haddr, sizeof(haddr), + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); + printf("%s%s", haddr, res->ai_next ? " " : "\n"); + } } #endif result = _skeyaccess(fp, &login_info); fclose(fp); + if (login_info.internet_addr) + freeaddrinfo(login_info.internet_addr); return (result); } @@ -226,33 +230,99 @@ return (match ? permission : DENY); } +/* translate IPv4 mapped IPv6 address to IPv4 address */ + +static void +ai_unmapped(struct addrinfo *ai) +{ + struct sockaddr_in6 *sin6; + struct sockaddr_in *sin4; + u_int32_t addr; + int port; + + if (ai->ai_family != AF_INET6) + return; + sin6 = (struct sockaddr_in6 *)ai->ai_addr; + if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) + return; + sin4 = (struct sockaddr_in *)ai->ai_addr; + addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; + port = sin6->sin6_port; + memset(sin4, 0, sizeof(struct sockaddr_in)); + sin4->sin_addr.s_addr = addr; + sin4->sin_port = port; + sin4->sin_family = AF_INET; + sin4->sin_len = sizeof(struct sockaddr_in); + ai->ai_family = AF_INET; + ai->ai_addrlen = sizeof(struct sockaddr_in); +} + /* match_internet_addr - match internet network address */ static int match_internet_addr(login_info) struct login_info *login_info; { - char * tok; - u_int32_t pattern; - u_int32_t mask; - struct in_addr *addrp; + char *tok; + struct addrinfo *res; + struct sockaddr_storage pattern, mask; + struct sockaddr_in *addr4, *pattern4, *mask4; + struct sockaddr_in6 *addr6, *pattern6, *mask6; + int i, match; - if (login_info->internet_addr == 0) + if (login_info->internet_addr == NULL) return (0); if ((tok = need_internet_addr()) == 0) return (0); - pattern = inet_addr(tok); + if ((res = convert_internet_addr(tok)) == NULL) + return (0); + memcpy(&pattern, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); if ((tok = need_internet_addr()) == 0) return (0); - mask = inet_addr(tok); + if ((res = convert_internet_addr(tok)) == NULL) + return (0); + memcpy(&mask, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + if (pattern.ss_family != mask.ss_family) + return (0); + mask4 = (struct sockaddr_in *)&mask; + pattern4 = (struct sockaddr_in *)&pattern; + mask6 = (struct sockaddr_in6 *)&mask; + pattern6 = (struct sockaddr_in6 *)&pattern; /* * See if any of the addresses matches a pattern in the control file. We * have already tried to drop addresses that belong to someone else. */ - for (addrp = login_info->internet_addr; addrp->s_addr; addrp++) - if (addrp->s_addr != INADDR_NONE && (addrp->s_addr & mask) == pattern) - return (1); + for (res = login_info->internet_addr; res; res = res->ai_next) { + ai_unmapped(res); + if (res->ai_family != pattern.ss_family) + continue; + switch (res->ai_family) { + case AF_INET: + addr4 = (struct sockaddr_in *)res->ai_addr; + if (addr4->sin_addr.s_addr != INADDR_NONE && + (addr4->sin_addr.s_addr & mask4->sin_addr.s_addr) == pattern4->sin_addr.s_addr) + return (1); + break; + case AF_INET6: + addr6 = (struct sockaddr_in6 *)res->ai_addr; + if (pattern6->sin6_scope_id != 0 && + addr6->sin6_scope_id != pattern6->sin6_scope_id) + break; + match = 1; + for (i = 0; i < 16; ++i) { + if ((addr6->sin6_addr.s6_addr[i] & mask6->sin6_addr.s6_addr[i]) != pattern6->sin6_addr.s6_addr[i]) { + match = 0; + break; + } + } + if (match) + return (1); + break; + } + } return (0); } @@ -369,53 +439,49 @@ static int is_internet_addr(str) char *str; { - int in_run = 0; - int runs = 0; + struct addrinfo *res; - /* Count the number of runs of characters between the dots. */ - - while (*str) { - if (*str == '.') { - in_run = 0; - } else { - if (!isdigit(*str)) - return (0); - if (in_run == 0) { - in_run = 1; - runs++; - } - } - str++; + if ((res = convert_internet_addr(str)) != NULL) + freeaddrinfo(res); + return (res != NULL); +} + +/* + * Nuke addrinfo entry from list. + * XXX: Depending on the implementation of KAME's getaddrinfo(3). + */ +static void nuke_ai(rp, res) +struct addrinfo **rp, *res; +{ + *rp = res->ai_next; + if (res->ai_canonname) { + if (res->ai_next && !res->ai_next->ai_canonname) + res->ai_next->ai_canonname = res->ai_canonname; + else + free(res->ai_canonname); } - return (runs == 4); + free(res); } /* lookup_internet_addr - look up internet addresses with extreme prejudice */ -static struct in_addr *lookup_internet_addr(host) +static struct addrinfo *lookup_internet_addr(host) char *host; { - struct hostent *hp; - static struct in_addr list[MAX_ADDR + 1]; - char buf[MAXHOSTNAMELEN + 1]; - int length; - int i; - - if ((hp = gethostbyname(host)) == 0 || hp->h_addrtype != AF_INET) - return (0); - - /* - * Save a copy of the results before gethostbyaddr() clobbers them. - */ - - for (i = 0; i < MAX_ADDR && hp->h_addr_list[i]; i++) - memcpy((char *) &list[i], - hp->h_addr_list[i], (size_t)hp->h_length); - list[i].s_addr = 0; - - strncpy(buf, hp->h_name, MAXHOSTNAMELEN); - buf[MAXHOSTNAMELEN] = 0; - length = hp->h_length; + struct addrinfo hints, *res0, *res, **rp; + char hname[NI_MAXHOST], haddr[NI_MAXHOST]; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_CANONNAME; + if (getaddrinfo(host, NULL, &hints, &res0) != 0) + return (NULL); + if (res0->ai_canonname == NULL) { + freeaddrinfo(res0); + return (NULL); + } /* * Wipe addresses that appear to belong to someone else. We will get @@ -425,31 +491,51 @@ #define NEQ(x,y) (strcasecmp((x),(y)) != 0) #define NEQ3(x,y,n) (strncasecmp((x),(y), (n)) != 0) - while (--i >= 0) { - if ((hp = gethostbyaddr((char *) &list[i], length, AF_INET)) == 0) { + rp = &res0; + for (res = res0; res; res = res->ai_next) { + if (res->ai_family != AF_INET && res->ai_family != AF_INET6) { + nuke_ai(rp, res); + continue; + } + error = getnameinfo(res->ai_addr, res->ai_addrlen, + hname, sizeof(hname), + NULL, 0, NI_NAMEREQD | NI_WITHSCOPEID); + if (error) { + getnameinfo(res->ai_addr, res->ai_addrlen, haddr, sizeof(haddr), + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); syslog(LOG_ERR, "address %s not registered for host %s", - inet_ntoa(list[i]), buf); - list[i].s_addr = (u_int32_t) -1; + haddr, res0->ai_canonname); + nuke_ai(rp, res); + continue; } - if (NEQ(buf, hp->h_name) && NEQ3(buf, "localhost.", 10)) { + if (NEQ(res0->ai_canonname, hname) && + NEQ3(res0->ai_canonname, "localhost.", 10)) { + getnameinfo(res->ai_addr, res->ai_addrlen, haddr, sizeof(haddr), + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); syslog(LOG_ERR, "address %s registered for host %s and %s", - inet_ntoa(list[i]), hp->h_name, buf); - list[i].s_addr = (u_int32_t) -1; + haddr, hname, res0->ai_canonname); + nuke_ai(rp, res); + continue; } + rp = &res->ai_next; } - return (list); + return (res0); } /* convert_internet_addr - convert string to internet address */ -static struct in_addr *convert_internet_addr(string) +static struct addrinfo *convert_internet_addr(string) char *string; { - static struct in_addr list[2]; + struct addrinfo hints, *res; - list[0].s_addr = inet_addr(string); - list[1].s_addr = 0; - return (list); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + if (getaddrinfo(string, NULL, &hints, &res) != 0) + return (NULL); + return (res); } #ifdef TEST @@ -458,7 +544,7 @@ int argc; char **argv; { - struct hostent *hp; + struct addrinfo hints, *res; char host[MAXHOSTNAMELEN + 1]; int verdict; char *user; @@ -475,8 +561,18 @@ user = argv[1]; port = argv[2]; if (argv[3]) { - strncpy(host, (hp = gethostbyname(argv[3])) ? - hp->h_name : argv[3], MAXHOSTNAMELEN); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_CANONNAME; + if (getaddrinfo(argv[3], NULL, &hints, &res) == 0) { + if (res->ai_canonname == NULL) + strncpy(host, argv[3], MAXHOSTNAMELEN); + else + strncpy(host, res->ai_canonname, MAXHOSTNAMELEN); + freeaddrinfo(res); + } else + strncpy(host, argv[3], MAXHOSTNAMELEN); host[MAXHOSTNAMELEN] = 0; } verdict = skeyaccess(user, port, argv[3] ? host : (char *) 0, (char *) 0); -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@bisd.hitachi.co.jp ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat Mar 17 9:53:50 2001 Delivered-To: freebsd-audit@freebsd.org Received: from peace.mahoroba.org (peace.calm.imasy.or.jp [202.227.26.34]) by hub.freebsd.org (Postfix) with ESMTP id 6136B37B71A; Sat, 17 Mar 2001 09:53:19 -0800 (PST) (envelope-from ume@FreeBSD.org) Received: from localhost (IDENT:p8jkn3SzUJMbNWSKDclLcxnFnqs/dngHjSJCJ8hHEcbtOVG4LNOk5AaJzarYmRE6@localhost [::1]) (authenticated as ume with CRAM-MD5) by peace.mahoroba.org (8.11.3/8.11.3/peace) with ESMTP/inet6 id f2HHnvR45766; Sun, 18 Mar 2001 02:49:58 +0900 (JST) (envelope-from ume@FreeBSD.org) Date: Sun, 18 Mar 2001 02:49:57 +0900 (JST) Message-Id: <20010318.024957.70172896.ume@FreeBSD.org> To: audit@FreeBSD.org, net@FreeBSD.org Subject: Re: [CFR] IPv6 support for skeyaccess(3) From: Hajimu UMEMOTO In-Reply-To: <20010317.233758.21880242.ume@FreeBSD.org> References: <20010317.233758.21880242.ume@FreeBSD.org> X-Mailer: xcite1.38> Mew version 1.95b97 on Emacs 20.7 / Mule 4.0 =?iso-2022-jp?B?KBskQjJWMWMbKEIp?= X-PGP-Public-Key: http://www.imasy.org/~ume/publickey.asc X-PGP-Fingerprint: 6B 0C 53 FC 5D D0 37 91 05 D0 B3 EF 36 9B 6A BC X-URL: http://www.imasy.org/~ume/ X-OS: FreeBSD 5.0-CURRENT Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG >>>>> On Sat, 17 Mar 2001 23:37:58 +0900 (JST) >>>>> Hajimu UMEMOTO said: ume> I wish to support IPv6 for skeyaccess(3). With this patch, you can ume> specify IPv6 address using `internet' keyword into /etc/skey.access. ume> Please review it. Oops, previous patch touched the memory already freed. This is corrected version. Sorry for my inconvenience. Index: lib/libskey/skeyaccess.c diff -u lib/libskey/skeyaccess.c.orig lib/libskey/skeyaccess.c --- lib/libskey/skeyaccess.c.orig Mon Oct 26 20:54:36 1998 +++ lib/libskey/skeyaccess.c Sun Mar 18 01:29:48 2001 @@ -63,8 +63,8 @@ static int match_group __P((struct login_info *)); static int match_token __P((char *)); static int is_internet_addr __P((char *)); -static struct in_addr *convert_internet_addr __P((char *)); -static struct in_addr *lookup_internet_addr __P((char *)); +static struct addrinfo *convert_internet_addr __P((char *)); +static struct addrinfo *lookup_internet_addr __P((char *)); #define MAX_ADDR 32 #define PERMIT 1 @@ -79,7 +79,7 @@ struct login_info { char *host_name; /* host name */ - struct in_addr *internet_addr; /* null terminated list */ + struct addrinfo *internet_addr; /* addrinfo chain */ char *user; /* user name */ char *port; /* login port */ }; @@ -120,22 +120,22 @@ login_info.user = user; login_info.port = port; - if (host != 0 && !is_internet_addr(host)) { + if (host != NULL && !is_internet_addr(host)) { login_info.host_name = host; } else { - login_info.host_name = 0; + login_info.host_name = NULL; } - if (addr != 0 && is_internet_addr(addr)) { + if (addr != NULL && is_internet_addr(addr)) { login_info.internet_addr = convert_internet_addr(addr); - } else if (host != 0) { + } else if (host != NULL) { if (is_internet_addr(host)) { login_info.internet_addr = convert_internet_addr(host); } else { login_info.internet_addr = lookup_internet_addr(host); } } else { - login_info.internet_addr = 0; + login_info.internet_addr = NULL; } /* @@ -146,19 +146,23 @@ printf("user: %s\n", login_info.user); printf("host: %s\n", login_info.host_name ? login_info.host_name : "none"); printf("addr: "); - if (login_info.internet_addr == 0) { + if (login_info.internet_addr == NULL) { printf("none\n"); } else { - int i; + struct addrinfo *res; + char haddr[NI_MAXHOST]; - for (i = 0; login_info.internet_addr[i].s_addr; i++) - printf("%s%s", login_info.internet_addr[i].s_addr == -1 ? - "(see error log)" : inet_ntoa(login_info.internet_addr[i]), - login_info.internet_addr[i + 1].s_addr ? " " : "\n"); + for (res = login_info.internet_addr; res; res = res->ai_next) { + getnameinfo(res->ai_addr, res->ai_addrlen, haddr, sizeof(haddr), + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); + printf("%s%s", haddr, res->ai_next ? " " : "\n"); + } } #endif result = _skeyaccess(fp, &login_info); fclose(fp); + if (login_info.internet_addr) + freeaddrinfo(login_info.internet_addr); return (result); } @@ -226,33 +230,99 @@ return (match ? permission : DENY); } +/* translate IPv4 mapped IPv6 address to IPv4 address */ + +static void +ai_unmapped(struct addrinfo *ai) +{ + struct sockaddr_in6 *sin6; + struct sockaddr_in *sin4; + u_int32_t addr; + int port; + + if (ai->ai_family != AF_INET6) + return; + sin6 = (struct sockaddr_in6 *)ai->ai_addr; + if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) + return; + sin4 = (struct sockaddr_in *)ai->ai_addr; + addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; + port = sin6->sin6_port; + memset(sin4, 0, sizeof(struct sockaddr_in)); + sin4->sin_addr.s_addr = addr; + sin4->sin_port = port; + sin4->sin_family = AF_INET; + sin4->sin_len = sizeof(struct sockaddr_in); + ai->ai_family = AF_INET; + ai->ai_addrlen = sizeof(struct sockaddr_in); +} + /* match_internet_addr - match internet network address */ static int match_internet_addr(login_info) struct login_info *login_info; { - char * tok; - u_int32_t pattern; - u_int32_t mask; - struct in_addr *addrp; + char *tok; + struct addrinfo *res; + struct sockaddr_storage pattern, mask; + struct sockaddr_in *addr4, *pattern4, *mask4; + struct sockaddr_in6 *addr6, *pattern6, *mask6; + int i, match; - if (login_info->internet_addr == 0) + if (login_info->internet_addr == NULL) return (0); if ((tok = need_internet_addr()) == 0) return (0); - pattern = inet_addr(tok); + if ((res = convert_internet_addr(tok)) == NULL) + return (0); + memcpy(&pattern, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); if ((tok = need_internet_addr()) == 0) return (0); - mask = inet_addr(tok); + if ((res = convert_internet_addr(tok)) == NULL) + return (0); + memcpy(&mask, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + if (pattern.ss_family != mask.ss_family) + return (0); + mask4 = (struct sockaddr_in *)&mask; + pattern4 = (struct sockaddr_in *)&pattern; + mask6 = (struct sockaddr_in6 *)&mask; + pattern6 = (struct sockaddr_in6 *)&pattern; /* * See if any of the addresses matches a pattern in the control file. We * have already tried to drop addresses that belong to someone else. */ - for (addrp = login_info->internet_addr; addrp->s_addr; addrp++) - if (addrp->s_addr != INADDR_NONE && (addrp->s_addr & mask) == pattern) - return (1); + for (res = login_info->internet_addr; res; res = res->ai_next) { + ai_unmapped(res); + if (res->ai_family != pattern.ss_family) + continue; + switch (res->ai_family) { + case AF_INET: + addr4 = (struct sockaddr_in *)res->ai_addr; + if (addr4->sin_addr.s_addr != INADDR_NONE && + (addr4->sin_addr.s_addr & mask4->sin_addr.s_addr) == pattern4->sin_addr.s_addr) + return (1); + break; + case AF_INET6: + addr6 = (struct sockaddr_in6 *)res->ai_addr; + if (pattern6->sin6_scope_id != 0 && + addr6->sin6_scope_id != pattern6->sin6_scope_id) + break; + match = 1; + for (i = 0; i < 16; ++i) { + if ((addr6->sin6_addr.s6_addr[i] & mask6->sin6_addr.s6_addr[i]) != pattern6->sin6_addr.s6_addr[i]) { + match = 0; + break; + } + } + if (match) + return (1); + break; + } + } return (0); } @@ -369,53 +439,50 @@ static int is_internet_addr(str) char *str; { - int in_run = 0; - int runs = 0; + struct addrinfo *res; - /* Count the number of runs of characters between the dots. */ - - while (*str) { - if (*str == '.') { - in_run = 0; - } else { - if (!isdigit(*str)) - return (0); - if (in_run == 0) { - in_run = 1; - runs++; - } - } - str++; + if ((res = convert_internet_addr(str)) != NULL) + freeaddrinfo(res); + return (res != NULL); +} + +/* + * Nuke addrinfo entry from list. + * XXX: Depending on the implementation of KAME's getaddrinfo(3). + */ +static struct addrinfo *nuke_ai(rp, res) +struct addrinfo **rp, *res; +{ + *rp = res->ai_next; + if (res->ai_canonname) { + if (res->ai_next && !res->ai_next->ai_canonname) + res->ai_next->ai_canonname = res->ai_canonname; + else + free(res->ai_canonname); } - return (runs == 4); + free(res); + return (*rp); } /* lookup_internet_addr - look up internet addresses with extreme prejudice */ -static struct in_addr *lookup_internet_addr(host) +static struct addrinfo *lookup_internet_addr(host) char *host; { - struct hostent *hp; - static struct in_addr list[MAX_ADDR + 1]; - char buf[MAXHOSTNAMELEN + 1]; - int length; - int i; - - if ((hp = gethostbyname(host)) == 0 || hp->h_addrtype != AF_INET) - return (0); - - /* - * Save a copy of the results before gethostbyaddr() clobbers them. - */ - - for (i = 0; i < MAX_ADDR && hp->h_addr_list[i]; i++) - memcpy((char *) &list[i], - hp->h_addr_list[i], (size_t)hp->h_length); - list[i].s_addr = 0; - - strncpy(buf, hp->h_name, MAXHOSTNAMELEN); - buf[MAXHOSTNAMELEN] = 0; - length = hp->h_length; + struct addrinfo hints, *res0, *res, **rp; + char hname[NI_MAXHOST], haddr[NI_MAXHOST]; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_CANONNAME; + if (getaddrinfo(host, NULL, &hints, &res0) != 0) + return (NULL); + if (res0->ai_canonname == NULL) { + freeaddrinfo(res0); + return (NULL); + } /* * Wipe addresses that appear to belong to someone else. We will get @@ -425,31 +492,53 @@ #define NEQ(x,y) (strcasecmp((x),(y)) != 0) #define NEQ3(x,y,n) (strncasecmp((x),(y), (n)) != 0) - while (--i >= 0) { - if ((hp = gethostbyaddr((char *) &list[i], length, AF_INET)) == 0) { + res = res0; + rp = &res0; + while (res) { + if (res->ai_family != AF_INET && res->ai_family != AF_INET6) { + res = nuke_ai(rp, res); + continue; + } + error = getnameinfo(res->ai_addr, res->ai_addrlen, + hname, sizeof(hname), + NULL, 0, NI_NAMEREQD | NI_WITHSCOPEID); + if (error) { + getnameinfo(res->ai_addr, res->ai_addrlen, haddr, sizeof(haddr), + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); syslog(LOG_ERR, "address %s not registered for host %s", - inet_ntoa(list[i]), buf); - list[i].s_addr = (u_int32_t) -1; + haddr, res0->ai_canonname); + res = nuke_ai(rp, res); + continue; } - if (NEQ(buf, hp->h_name) && NEQ3(buf, "localhost.", 10)) { + if (NEQ(res0->ai_canonname, hname) && + NEQ3(res0->ai_canonname, "localhost.", 10)) { + getnameinfo(res->ai_addr, res->ai_addrlen, haddr, sizeof(haddr), + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); syslog(LOG_ERR, "address %s registered for host %s and %s", - inet_ntoa(list[i]), hp->h_name, buf); - list[i].s_addr = (u_int32_t) -1; + haddr, hname, res0->ai_canonname); + res = nuke_ai(rp, res); + continue; } + res = res->ai_next; + rp = &res->ai_next; } - return (list); + return (res0); } /* convert_internet_addr - convert string to internet address */ -static struct in_addr *convert_internet_addr(string) +static struct addrinfo *convert_internet_addr(string) char *string; { - static struct in_addr list[2]; + struct addrinfo hints, *res; - list[0].s_addr = inet_addr(string); - list[1].s_addr = 0; - return (list); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + if (getaddrinfo(string, NULL, &hints, &res) != 0) + return (NULL); + return (res); } #ifdef TEST @@ -458,7 +547,7 @@ int argc; char **argv; { - struct hostent *hp; + struct addrinfo hints, *res; char host[MAXHOSTNAMELEN + 1]; int verdict; char *user; @@ -475,8 +564,18 @@ user = argv[1]; port = argv[2]; if (argv[3]) { - strncpy(host, (hp = gethostbyname(argv[3])) ? - hp->h_name : argv[3], MAXHOSTNAMELEN); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_CANONNAME; + if (getaddrinfo(argv[3], NULL, &hints, &res) == 0) { + if (res->ai_canonname == NULL) + strncpy(host, argv[3], MAXHOSTNAMELEN); + else + strncpy(host, res->ai_canonname, MAXHOSTNAMELEN); + freeaddrinfo(res); + } else + strncpy(host, argv[3], MAXHOSTNAMELEN); host[MAXHOSTNAMELEN] = 0; } verdict = skeyaccess(user, port, argv[3] ? host : (char *) 0, (char *) 0); -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@bisd.hitachi.co.jp ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message