summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-07 03:32:05 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-07 03:32:05 +0000
commit7ab586a39aaba2282184b2e377a64b5c3d16ace5 (patch)
tree435bf7f430d17a473dd290ade0e70f3bd43c3148 /libexec
parente06010752854f5ea2eeb25c2b5694b82be59c2ea (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.c163
-rw-r--r--libexec/tcpd/tcpdchk/scaffold.h4
-rw-r--r--libexec/tcpd/tcpdchk/tcpdchk.c57
-rw-r--r--libexec/tcpd/tcpdmatch/tcpdmatch.c100
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);
}