From 225d233deb08e4006d8cabd0a6572f76d729f90d Mon Sep 17 00:00:00 2001 From: shin Date: Thu, 3 Feb 2000 10:27:03 +0000 Subject: Missing tcp_wrapper IPv6 support seemed to be a bug, so commit it. Now when tcp_wrapper is enabled by inetd -wW, several accesses which should be permitted are refused only for IPv6, if hostname is used to decide the host to be allowed. IPv6 users will be just upset. About security related concern. -All extensions are wrapped by #ifdef INET6, so people can completely disable the extension by recompile libwrap without INET6 option. -Access via IPv6 is not enabled by default. People need to enable IPv6 access by changing /etc/inetd.conf at first, by adding tcp6 and/or tcp46 entries. -The base of patches are from KAME package and are actually daily used for more than a year in several Japanese IPv6 environments. -Patches are reviewed by markm. Approved by: jkh Submitted by: Hajimu UMEMOTO Reviewed by: markm Obtained from: KAME project --- contrib/tcp_wrappers/tcpdchk.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'contrib/tcp_wrappers/tcpdchk.c') diff --git a/contrib/tcp_wrappers/tcpdchk.c b/contrib/tcp_wrappers/tcpdchk.c index 6a317d9..a2804a2 100644 --- a/contrib/tcp_wrappers/tcpdchk.c +++ b/contrib/tcp_wrappers/tcpdchk.c @@ -24,6 +24,9 @@ static char sccsid[] = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25"; #include #include +#ifdef INET6 +#include +#endif #include #include #include @@ -403,6 +406,26 @@ char *pat; } } +#ifdef INET6 +static int is_inet6_addr(pat) + char *pat; +{ + struct in6_addr addr; + int len, ret; + char ch; + + if (*pat != '[') + return (0); + len = strlen(pat); + if ((ch = pat[len - 1]) != ']') + return (0); + pat[len - 1] = '\0'; + ret = inet_pton(AF_INET6, pat + 1, &addr); + pat[len - 1] = ch; + return (ret == 1); +} +#endif + /* check_host - criticize host pattern */ static int check_host(pat) @@ -449,14 +472,27 @@ char *pat; tcpd_warn("open %s: %m", pat); } } else if (mask = split_at(pat, '/')) { /* network/netmask */ +#ifdef INET6 + int mask_len; + + if ((dot_quad_addr(pat) == INADDR_NONE + || dot_quad_addr(mask) == INADDR_NONE) + && (!is_inet6_addr(pat) + || ((mask_len = atoi(mask)) < 0 || mask_len > 128))) +#else if (dot_quad_addr(pat) == INADDR_NONE || dot_quad_addr(mask) == INADDR_NONE) +#endif tcpd_warn("%s/%s: bad net/mask pattern", pat, mask); } else if (STR_EQ(pat, "FAIL")) { /* obsolete */ tcpd_warn("FAIL is no longer recognized"); tcpd_warn("(use EXCEPT or DENY instead)"); } else if (reserved_name(pat)) { /* other reserved */ /* void */ ; +#ifdef INET6 + } else if (is_inet6_addr(pat)) { /* IPv6 address */ + addr_count = 1; +#endif } else if (NOT_INADDR(pat)) { /* internet name */ if (pat[strlen(pat) - 1] == '.') { tcpd_warn("%s: domain or host name ends in dot", pat); -- cgit v1.1