Date: Wed, 23 Jan 2002 08:55:49 +0900 From: Hajimu UMEMOTO <ume@mahoroba.org> To: Mark Murray <mark@grondar.za> Cc: Hajimu UMEMOTO <ume@mahoroba.org>, Dag-Erling Smorgrav <des@ofug.org>, Ruslan Ermilov <ru@FreeBSD.org>, Mark Murray <markm@FreeBSD.org>, cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org Subject: Re: cvs commit: src/share/mk bsd.libnames.mk Message-ID: <ygeelkivt2y.wl@mille.mahoroba.org> In-Reply-To: <200201222007.g0MK7At61082@grimreaper.grondar.org> References: <ygeg04yw3xp.wl@mille.mahoroba.org>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
>>>>> On Tue, 22 Jan 2002 20:07:10 +0000
>>>>> Mark Murray <mark@grondar.za> said:
> des> I've tested a statically linked login(1) with the patch I committed,
> des> and have been able to log in using my SSH passphrase. But I see from
> des> your patch that there are issues with IPv6 which I hadn't considered.
> des> I'll back out my patch if you commit yours shortly after.
>
> I'm planning to support IPv6 for opieaccess. But, around here is hot
> issue, now. So, I'll start my work after this issue is calm down. :-)
mark> Submitting patches is a great idea. Things are cool right now! :-)
Okay. I just wrote the patch.
There is an issue. This patch changes api of rdnets() and obsoletes
isaddr(). I believe these functions are only for internal use within
accessfile.c, and never used in opie itself anymore. But, these
functions are still global. Should I leave these function as is, and
provide new rnets_sa()?
[-- Attachment #2 --]
Index: contrib/opie/opie.h
===================================================================
RCS file: /home/ncvs/src/contrib/opie/opie.h,v
retrieving revision 1.7
diff -u -r1.7 opie.h
--- contrib/opie/opie.h 15 May 2000 04:20:54 -0000 1.7
+++ contrib/opie/opie.h 22 Jan 2002 23:37:04 -0000
@@ -77,11 +77,12 @@
#define OPIE_PRINCIPAL_MAX 32
#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/socket.h>
__BEGIN_DECLS
int opieaccessfile __P((char *));
-int rdnets __P((long));
-int isaddr __P((register char *));
+int rdnets __P((struct sockaddr *));
int opiealways __P((char *));
char *opieatob8 __P((char *,char *));
void opiebackspace __P((char *));
Index: contrib/opie/libopie/accessfile.c
===================================================================
RCS file: /home/ncvs/src/contrib/opie/libopie/accessfile.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 accessfile.c
--- contrib/opie/libopie/accessfile.c 10 Apr 2000 11:09:34 -0000 1.1.1.3
+++ contrib/opie/libopie/accessfile.c 22 Jan 2002 23:37:04 -0000
@@ -49,16 +49,38 @@
#include "opie.h"
+/* 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);
+}
+
int opieaccessfile FUNCTION((host), char *host)
{
#ifdef PATH_ACCESS_FILE
/* Turn host into an IP address and then look it up in the authorization
* database to determine if ordinary password logins are OK
*/
- long n;
- struct hostent *hp;
- FILE *fp;
- char buf[128], **lp;
+ struct addrinfo hints, *res0, *res;
#ifdef DEBUG
syslog(LOG_DEBUG, "accessfile: host=%s", host);
@@ -66,29 +88,34 @@
if (!host[0])
/* Local login, okay */
return (1);
- if (isaddr(host)) {
- n = inet_addr(host);
- return rdnets(n);
- } else {
- hp = gethostbyname(host);
- if (!hp) {
- printf("Unknown host %s\n", host);
- return 0;
- }
- for (lp = hp->h_addr_list; *lp; lp++) {
- memcpy((char *) &n, *lp, sizeof(n));
- if (rdnets(n))
- return (1);
- }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ if (getaddrinfo(host, NULL, &hints, &res0) != 0) {
+ printf("Unknown host %s\n", host);
return (0);
}
+ for (res = res0; res; res = res->ai_next) {
+ ai_unmapped(res);
+ if (rdnets(res->ai_addr)) {
+ freeaddrinfo(res0);
+ return (1);
+ }
+ }
+ freeaddrinfo(res0);
+ return (0);
}
-int rdnets FUNCTION((host), long host)
+int rdnets FUNCTION((host), struct sockaddr *host)
{
FILE *fp;
char buf[128], *cp;
- long pattern, mask;
+ struct addrinfo hints, *res;
+ struct sockaddr_storage pattern, mask;
+ struct sockaddr_in *host4, *pattern4, *mask4;
+ struct sockaddr_in6 *host6, *pattern6, *mask6;
+ int i, match;
int permit_it;
if (!(fp = fopen(PATH_ACCESS_FILE, "r")))
@@ -111,38 +138,66 @@
}
if (!(cp = strtok(NULL, " \t")))
continue; /* Invalid line */
- pattern = inet_addr(cp);
- if (!(cp = strtok(NULL, " \t")))
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = host->sa_family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+ if (getaddrinfo(cp, NULL, &hints, &res) != 0)
+ continue;
+ memcpy(&pattern, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ if (!(cp = strtok(NULL, " \t\n")))
continue; /* Invalid line */
- mask = inet_addr(cp);
+ if (getaddrinfo(cp, NULL, &hints, &res) != 0)
+ continue;
+ memcpy(&mask, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ if (pattern.ss_family != mask.ss_family)
+ continue;
+ if (host->sa_family != pattern.ss_family)
+ continue;
+
+ switch (host->sa_family) {
+ case AF_INET:
+ host4 = (struct sockaddr_in *)host;
+ mask4 = (struct sockaddr_in *)&mask;
+ pattern4 = (struct sockaddr_in *)&pattern;
#ifdef DEBUG
- syslog(LOG_DEBUG, "accessfile: %08x & %08x == %08x (%s)", host, mask, pattern, ((host & mask) == pattern) ? "true" : "false");
+ syslog(LOG_DEBUG, "accessfile: %08x & %08x == %08x (%s)",
+ host4->sin_addr.s_addr, mask4->sin_addr.s_addr,
+ pattern4->sin_addr.s_addr,
+ ((host4->sin_addr.s_addr & mask4->sin_addr.s_addr) == pattern4->sin_addr.s_addr) ? "true" : "false");
#endif /* DEBUG */
- if ((host & mask) == pattern) {
- fclose(fp);
- return permit_it;
+ if ((host4->sin_addr.s_addr & mask4->sin_addr.s_addr) == pattern4->sin_addr.s_addr) {
+ fclose(fp);
+ return permit_it;
+ }
+ break;
+ case AF_INET6:
+ host6 = (struct sockaddr_in6 *)host;
+ mask6 = (struct sockaddr_in6 *)&mask;
+ pattern6 = (struct sockaddr_in6 *)&pattern;
+ if (pattern6->sin6_scope_id != 0 &&
+ host6->sin6_scope_id != pattern6->sin6_scope_id)
+ continue;
+ match = 1;
+ for (i = 0; i < 16; ++i) {
+ if ((host6->sin6_addr.s6_addr[i] & mask6->sin6_addr.s6_addr[i]) != pattern6->sin6_addr.s6_addr[i]) {
+ match = 0;
+ break;
+ }
+ }
+ if (match) {
+ fclose(fp);
+ return permit_it;
+ }
+ break;
+ default:
+ break;
}
}
fclose(fp);
return 0;
-}
-
-
-/* Return TRUE if string appears to be an IP address in dotted decimal;
- * return FALSE otherwise (i.e., if string is a domain name)
- */
-int isaddr FUNCTION((s), register char *s)
-{
- char c;
-
- if (!s)
- return 1; /* Can't happen */
-
- while ((c = *s++) != '\0') {
- if (c != '[' && c != ']' && !isdigit(c) && c != '.')
- return 0;
- }
- return 1;
#else /* PATH_ACCESS_FILE */
return !host[0];
#endif /* PATH_ACCESS_FILE */
[-- Attachment #3 --]
--
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/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ygeelkivt2y.wl>
