Commit 6786f311 authored by Khem Raj's avatar Khem Raj

tcp-wrappers: Use the recipe from oe-core

Signed-off-by: default avatarKhem Raj <raj.khem@gmail.com>
parent ae4ea40e
diff -ruN tcp_wrappers_7.6.orig/hosts_access.5 tcp_wrappers_7.6/hosts_access.5
--- tcp_wrappers_7.6.orig/hosts_access.5 1995-01-30 19:51:47.000000000 +0100
+++ tcp_wrappers_7.6/hosts_access.5 2004-04-09 16:59:45.000000000 +0200
@@ -173,7 +173,7 @@
Patterns like these can be used when the machine has different internet
addresses with different internet hostnames. Service providers can use
this facility to offer FTP, GOPHER or WWW archives with internet names
-that may even belong to different organizations. See also the `twist'
+that may even belong to different organizations. See also the `twist\'
option in the hosts_options(5) document. Some systems (Solaris,
FreeBSD) can have more than one internet address on one physical
interface; with other systems you may have to resort to SLIP or PPP
@@ -236,10 +236,10 @@
Before accepting a client request, the wrappers can use the IDENT
service to find out that the client did not send the request at all.
When the client host provides IDENT service, a negative IDENT lookup
-result (the client matches `UNKNOWN@host') is strong evidence of a host
+result (the client matches `UNKNOWN@host\') is strong evidence of a host
spoofing attack.
.PP
-A positive IDENT lookup result (the client matches `KNOWN@host') is
+A positive IDENT lookup result (the client matches `KNOWN@host\') is
less trustworthy. It is possible for an intruder to spoof both the
client connection and the IDENT lookup, although doing so is much
harder than spoofing just a client connection. It may also be that
diff -ruN tcp_wrappers_7.6.orig/hosts_options.5 tcp_wrappers_7.6/hosts_options.5
--- tcp_wrappers_7.6.orig/hosts_options.5 1994-12-28 17:42:29.000000000 +0100
+++ tcp_wrappers_7.6/hosts_options.5 2004-04-09 16:59:49.000000000 +0200
@@ -124,7 +124,7 @@
value is taken.
.SH MISCELLANEOUS
.IP "banners /some/directory"
-Look for a file in `/some/directory' with the same name as the daemon
+Look for a file in `/some/directory\' with the same name as the daemon
process (for example in.telnetd for the telnet service), and copy its
contents to the client. Newline characters are replaced by
carriage-return newline, and %<letter> sequences are expanded (see
diff -ruN tcp_wrappers_7.6.orig/tcpdmatch.8 tcp_wrappers_7.6/tcpdmatch.8
--- tcp_wrappers_7.6.orig/tcpdmatch.8 1996-02-11 17:01:36.000000000 +0100
+++ tcp_wrappers_7.6/tcpdmatch.8 2004-04-09 17:00:49.000000000 +0200
@@ -26,7 +26,7 @@
A daemon process name. Typically, the last component of a daemon
executable pathname.
.IP client
-A host name or network address, or one of the `unknown' or `paranoid'
+A host name or network address, or one of the `unknown\' or `paranoid\'
wildcard patterns.
.sp
When a client host name is specified, \fItcpdmatch\fR gives a
@@ -37,13 +37,13 @@
.PP
Optional information specified with the \fIdaemon@server\fR form:
.IP server
-A host name or network address, or one of the `unknown' or `paranoid'
-wildcard patterns. The default server name is `unknown'.
+A host name or network address, or one of the `unknown\' or `paranoid\'
+wildcard patterns. The default server name is `unknown\'.
.PP
Optional information specified with the \fIuser@client\fR form:
.IP user
A client user identifier. Typically, a login name or a numeric userid.
-The default user name is `unknown'.
+The default user name is `unknown\'.
.SH OPTIONS
.IP -d
Examine \fIhosts.allow\fR and \fIhosts.deny\fR files in the current
@@ -70,7 +70,7 @@
.ti +5
tcpdmatch in.telnetd paranoid
.PP
-On some systems, daemon names have no `in.' prefix, or \fItcpdmatch\fR
+On some systems, daemon names have no `in.\' prefix, or \fItcpdmatch\fR
may need some help to locate the inetd configuration file.
.SH FILES
.PP
diff -ruNp tcp_wrappers_7.6.orig/hosts_access.3 tcp_wrappers_7.6/hosts_access.3
--- tcp_wrappers_7.6.orig/hosts_access.3 2005-03-09 18:30:25.000000000 +0100
+++ tcp_wrappers_7.6/hosts_access.3 2005-03-09 18:27:03.000000000 +0100
@@ -3,7 +3,7 @@
hosts_access, hosts_ctl, request_init, request_set \- access control library
.SH SYNOPSIS
.nf
-#include "tcpd.h"
+#include <tcpd.h>
extern int allow_severity;
extern int deny_severity;
diff -ruNp tcp_wrappers_7.6.orig/hosts_access.5 tcp_wrappers_7.6/hosts_access.5
--- tcp_wrappers_7.6.orig/hosts_access.5 2005-03-09 18:30:25.000000000 +0100
+++ tcp_wrappers_7.6/hosts_access.5 2005-03-09 18:30:18.000000000 +0100
@@ -8,9 +8,9 @@ name, host name/address) patterns. Exam
impatient reader is encouraged to skip to the EXAMPLES section for a
quick introduction.
.PP
-An extended version of the access control language is described in the
-\fIhosts_options\fR(5) document. The extensions are turned on at
-program build time by building with -DPROCESS_OPTIONS.
+The extended version of the access control language is described in the
+\fIhosts_options\fR(5) document. \fBNote that this language supersedes
+the meaning of \fIshell_command\fB as documented below.\fR
.PP
In the following text, \fIdaemon\fR is the the process name of a
network daemon process, and \fIclient\fR is the name and/or address of
@@ -346,8 +346,8 @@ in.tftpd: LOCAL, .my.domain
/etc/hosts.deny:
.in +3
.nf
-in.tftpd: ALL: (/some/where/safe_finger -l @%h | \\
- /usr/ucb/mail -s %d-%h root) &
+in.tftpd: ALL: (/usr/sbin/safe_finger -l @%h | \\
+ /usr/bin/mail -s %d-%h root) &
.fi
.PP
The safe_finger command comes with the tcpd wrapper and should be
@@ -383,6 +383,7 @@ that shouldn\'t. All problems are repor
.fi
.SH SEE ALSO
.nf
+hosts_options(5) extended syntax.
tcpd(8) tcp/ip daemon wrapper program.
tcpdchk(8), tcpdmatch(8), test programs.
.SH BUGS
diff -ruNp tcp_wrappers_7.6.orig/hosts_options.5 tcp_wrappers_7.6/hosts_options.5
--- tcp_wrappers_7.6.orig/hosts_options.5 2005-03-09 18:30:24.000000000 +0100
+++ tcp_wrappers_7.6/hosts_options.5 2005-03-09 18:27:03.000000000 +0100
@@ -2,10 +2,8 @@
.SH NAME
hosts_options \- host access control language extensions
.SH DESCRIPTION
-This document describes optional extensions to the language described
-in the hosts_access(5) document. The extensions are enabled at program
-build time. For example, by editing the Makefile and turning on the
-PROCESS_OPTIONS compile-time option.
+This document describes extensions to the language described
+in the hosts_access(5) document.
.PP
The extensible language uses the following format:
.sp
@@ -58,12 +56,12 @@ Notice the leading dot on the domain nam
Execute, in a child process, the specified shell command, after
performing the %<letter> expansions described in the hosts_access(5)
manual page. The command is executed with stdin, stdout and stderr
-connected to the null device, so that it won\'t mess up the
+connected to the null device, so that it won't mess up the
conversation with the client host. Example:
.sp
.nf
.ti +3
-spawn (/some/where/safe_finger -l @%h | /usr/ucb/mail root) &
+spawn (/usr/sbin/safe_finger -l @%h | /usr/bin/mail root) &
.fi
.sp
executes, in a background child process, the shell command "safe_finger
diff -ruNp tcp_wrappers_7.6.orig/inetcf.c tcp_wrappers_7.6/inetcf.c
--- tcp_wrappers_7.6.orig/inetcf.c 1997-02-12 02:13:24.000000000 +0100
+++ tcp_wrappers_7.6/inetcf.c 2005-03-09 18:27:03.000000000 +0100
@@ -26,13 +26,17 @@ extern void exit();
* guesses. Shorter names follow longer ones.
*/
char *inet_files[] = {
+#if 0
"/private/etc/inetd.conf", /* NEXT */
"/etc/inet/inetd.conf", /* SYSV4 */
"/usr/etc/inetd.conf", /* IRIX?? */
+#endif
"/etc/inetd.conf", /* BSD */
+#if 0
"/etc/net/tlid.conf", /* SYSV4?? */
"/etc/saf/tlid.conf", /* SYSV4?? */
"/etc/tlid.conf", /* SYSV4?? */
+#endif
0,
};
diff -ruNp tcp_wrappers_7.6.orig/tcpd.8 tcp_wrappers_7.6/tcpd.8
--- tcp_wrappers_7.6.orig/tcpd.8 1996-02-21 16:39:16.000000000 +0100
+++ tcp_wrappers_7.6/tcpd.8 2005-03-09 18:27:03.000000000 +0100
@@ -12,7 +12,11 @@ The program supports both 4.3BSD-style s
TLI. Functionality may be limited when the protocol underneath TLI is
not an internet protocol.
.PP
-Operation is as follows: whenever a request for service arrives, the
+There are two possible modes of operation: execution of \fItcpd\fP
+before a service started by \fIinetd\fP, or linking a daemon with
+the \fIlibwrap\fP shared library as documented in the \fIhosts_access\fR(3)
+manual page. Operation when started by \fIinetd\fP
+is as follows: whenever a request for service arrives, the
\fIinetd\fP daemon is tricked into running the \fItcpd\fP program
instead of the desired server. \fItcpd\fP logs the request and does
some additional checks. When all is well, \fItcpd\fP runs the
@@ -88,11 +92,11 @@ configuration files.
.sp
.in +5
# mkdir /other/place
-# mv /usr/etc/in.fingerd /other/place
-# cp tcpd /usr/etc/in.fingerd
+# mv /usr/sbin/in.fingerd /other/place
+# cp tcpd /usr/sbin/in.fingerd
.fi
.PP
-The example assumes that the network daemons live in /usr/etc. On some
+The example assumes that the network daemons live in /usr/sbin. On some
systems, network daemons live in /usr/sbin or in /usr/libexec, or have
no `in.\' prefix to their name.
.SH EXAMPLE 2
@@ -101,35 +105,34 @@ are left in their original place.
.PP
In order to monitor access to the \fIfinger\fR service, perform the
following edits on the \fIinetd\fR configuration file (usually
-\fI/etc/inetd.conf\fR or \fI/etc/inet/inetd.conf\fR):
+\fI/etc/inetd.conf\fR):
.nf
.sp
.ti +5
-finger stream tcp nowait nobody /usr/etc/in.fingerd in.fingerd
+finger stream tcp nowait nobody /usr/sbin/in.fingerd in.fingerd
.sp
becomes:
.sp
.ti +5
-finger stream tcp nowait nobody /some/where/tcpd in.fingerd
+finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd
.sp
.fi
.PP
-The example assumes that the network daemons live in /usr/etc. On some
+The example assumes that the network daemons live in /usr/sbin. On some
systems, network daemons live in /usr/sbin or in /usr/libexec, the
daemons have no `in.\' prefix to their name, or there is no userid
field in the inetd configuration file.
.PP
Similar changes will be needed for the other services that are to be
covered by \fItcpd\fR. Send a `kill -HUP\' to the \fIinetd\fR(8)
-process to make the changes effective. AIX users may also have to
-execute the `inetimp\' command.
+process to make the changes effective.
.SH EXAMPLE 3
In the case of daemons that do not live in a common directory ("secret"
or otherwise), edit the \fIinetd\fR configuration file so that it
specifies an absolute path name for the process name field. For example:
.nf
.sp
- ntalk dgram udp wait root /some/where/tcpd /usr/local/lib/ntalkd
+ ntalk dgram udp wait root /usr/sbin/tcpd /usr/local/lib/ntalkd
.sp
.fi
.PP
@@ -164,6 +167,7 @@ The default locations of the host access
.SH SEE ALSO
.na
.nf
+hosts_access(3), functions provided by the libwrap library.
hosts_access(5), format of the tcpd access control tables.
syslog.conf(5), format of the syslogd control file.
inetd.conf(5), format of the inetd control file.
diff -ruNp tcp_wrappers_7.6.orig/tcpdchk.8 tcp_wrappers_7.6/tcpdchk.8
--- tcp_wrappers_7.6.orig/tcpdchk.8 1995-01-08 17:00:31.000000000 +0100
+++ tcp_wrappers_7.6/tcpdchk.8 2005-03-09 18:27:03.000000000 +0100
@@ -9,8 +9,8 @@ tcpdchk [-a] [-d] [-i inet_conf] [-v]
potential and real problems it can find. The program examines the
\fItcpd\fR access control files (by default, these are
\fI/etc/hosts.allow\fR and \fI/etc/hosts.deny\fR), and compares the
-entries in these files against entries in the \fIinetd\fR or \fItlid\fR
-network configuration files.
+entries in these files against entries in the \fIinetd\fR
+network configuration file.
.PP
\fItcpdchk\fR reports problems such as non-existent pathnames; services
that appear in \fItcpd\fR access control rules, but are not controlled
@@ -26,14 +26,13 @@ problem.
.SH OPTIONS
.IP -a
Report access control rules that permit access without an explicit
-ALLOW keyword. This applies only when the extended access control
-language is enabled (build with -DPROCESS_OPTIONS).
+ALLOW keyword.
.IP -d
Examine \fIhosts.allow\fR and \fIhosts.deny\fR files in the current
directory instead of the default ones.
.IP "-i inet_conf"
Specify this option when \fItcpdchk\fR is unable to find your
-\fIinetd.conf\fR or \fItlid.conf\fR network configuration file, or when
+\fIinetd.conf\fR network configuration file, or when
you suspect that the program uses the wrong one.
.IP -v
Display the contents of each access control rule. Daemon lists, client
@@ -54,7 +53,6 @@ tcpdmatch(8), explain what tcpd would do
hosts_access(5), format of the tcpd access control tables.
hosts_options(5), format of the language extensions.
inetd.conf(5), format of the inetd control file.
-tlid.conf(5), format of the tlid control file.
.SH AUTHORS
.na
.nf
diff -ruNp tcp_wrappers_7.6.orig/tcpdmatch.8 tcp_wrappers_7.6/tcpdmatch.8
--- tcp_wrappers_7.6.orig/tcpdmatch.8 2005-03-09 18:30:24.000000000 +0100
+++ tcp_wrappers_7.6/tcpdmatch.8 2005-03-09 18:27:03.000000000 +0100
@@ -13,7 +13,7 @@ request for service. Examples are given
The program examines the \fItcpd\fR access control tables (default
\fI/etc/hosts.allow\fR and \fI/etc/hosts.deny\fR) and prints its
conclusion. For maximal accuracy, it extracts additional information
-from your \fIinetd\fR or \fItlid\fR network configuration file.
+from your \fIinetd\fR network configuration file.
.PP
When \fItcpdmatch\fR finds a match in the access control tables, it
identifies the matched rule. In addition, it displays the optional
@@ -50,7 +50,7 @@ Examine \fIhosts.allow\fR and \fIhosts.d
directory instead of the default ones.
.IP "-i inet_conf"
Specify this option when \fItcpdmatch\fR is unable to find your
-\fIinetd.conf\fR or \fItlid.conf\fR network configuration file, or when
+\fIinetd.conf\fR network configuration file, or when
you suspect that the program uses the wrong one.
.SH EXAMPLES
To predict how \fItcpd\fR would handle a telnet request from the local
@@ -86,7 +86,6 @@ tcpdchk(8), tcpd configuration checker
hosts_access(5), format of the tcpd access control tables.
hosts_options(5), format of the language extensions.
inetd.conf(5), format of the inetd control file.
-tlid.conf(5), format of the tlid control file.
.SH AUTHORS
.na
.nf
See https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=17847
diff -ruN tcp_wrappers_7.6.orig/hosts_access.5 tcp_wrappers_7.6/hosts_access.5
--- tcp_wrappers_7.6.orig/hosts_access.5 2004-04-10 18:54:33.000000000 +0200
+++ tcp_wrappers_7.6/hosts_access.5 2004-04-10 18:54:27.000000000 +0200
@@ -89,6 +89,10 @@
bitwise AND of the address and the `mask\'. For example, the net/mask
pattern `131.155.72.0/255.255.254.0\' matches every address in the
range `131.155.72.0\' through `131.155.73.255\'.
+.IP \(bu
+Wildcards `*\' and `?\' can be used to match hostnames or IP addresses. This
+method of matching cannot be used in conjunction with `net/mask\' matching,
+hostname matching beginning with `.\' or IP address matching ending with `.\'.
.SH WILDCARDS
The access control language supports explicit wildcards:
.IP ALL
diff -ruN tcp_wrappers_7.6.orig/hosts_access.c tcp_wrappers_7.6/hosts_access.c
--- tcp_wrappers_7.6.orig/hosts_access.c 1997-02-12 02:13:23.000000000 +0100
+++ tcp_wrappers_7.6/hosts_access.c 2004-04-10 18:52:21.000000000 +0200
@@ -289,6 +289,11 @@
{
int n;
+#ifndef DISABLE_WILDCARD_MATCHING
+ if (strchr(tok, '*') || strchr(tok,'?')) { /* contains '*' or '?' */
+ return (match_pattern_ylo(string,tok));
+ } else
+#endif
if (tok[0] == '.') { /* suffix */
n = strlen(string) - strlen(tok);
return (n > 0 && STR_EQ(tok, string + n));
@@ -329,3 +334,71 @@
}
return ((addr & mask) == net);
}
+
+#ifndef DISABLE_WILDCARD_MATCHING
+/* Note: this feature has been adapted in a pretty straightforward way
+ from Tatu Ylonen's last SSH version under free license by
+ Pekka Savola <pekkas@netcore.fi>.
+
+ Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+*/
+
+/* Returns true if the given string matches the pattern (which may contain
+ ? and * as wildcards), and zero if it does not match. */
+
+int match_pattern_ylo(const char *s, const char *pattern)
+{
+ while (1)
+ {
+ /* If at end of pattern, accept if also at end of string. */
+ if (!*pattern)
+ return !*s;
+
+ /* Process '*'. */
+ if (*pattern == '*')
+ {
+ /* Skip the asterisk. */
+ pattern++;
+
+ /* If at end of pattern, accept immediately. */
+ if (!*pattern)
+ return 1;
+
+ /* If next character in pattern is known, optimize. */
+ if (*pattern != '?' && *pattern != '*')
+ {
+ /* Look instances of the next character in pattern, and try
+ to match starting from those. */
+ for (; *s; s++)
+ if (*s == *pattern &&
+ match_pattern_ylo(s + 1, pattern + 1))
+ return 1;
+ /* Failed. */
+ return 0;
+ }
+
+ /* Move ahead one character at a time and try to match at each
+ position. */
+ for (; *s; s++)
+ if (match_pattern_ylo(s, pattern))
+ return 1;
+ /* Failed. */
+ return 0;
+ }
+
+ /* There must be at least one more character in the string. If we are
+ at the end, fail. */
+ if (!*s)
+ return 0;
+
+ /* Check if the next character of the string is acceptable. */
+ if (*pattern != '?' && *pattern != *s)
+ return 0;
+
+ /* Move to the next character, both in string and in pattern. */
+ s++;
+ pattern++;
+ }
+ /*NOTREACHED*/
+}
+#endif /* DISABLE_WILDCARD_MATCHING */
* Mon Feb 5 2001 Preston Brown <pbrown@redhat.com>
- fix gethostbyname to work better with dot "." notation (#16949)
--- tcp_wrappers_7.6/socket.c.fixgethostbyname Fri Mar 21 13:27:25 1997
+++ tcp_wrappers_7.6/socket.c Mon Feb 5 14:09:40 2001
@@ -52,7 +52,8 @@
char *name;
{
char dot_name[MAXHOSTNAMELEN + 1];
-
+ struct hostent *hp;
+
/*
* Don't append dots to unqualified names. Such names are likely to come
* from local hosts files or from NIS.
@@ -61,8 +62,12 @@
if (strchr(name, '.') == 0 || strlen(name) >= MAXHOSTNAMELEN - 1) {
return (gethostbyname(name));
} else {
- sprintf(dot_name, "%s.", name);
- return (gethostbyname(dot_name));
+ sprintf(dot_name, "%s.", name);
+ hp = gethostbyname(dot_name);
+ if (hp)
+ return hp;
+ else
+ return (gethostbyname(name));
}
}
diff -ruN tcp_wrappers_7.6.orig/fix_options.c tcp_wrappers_7.6/fix_options.c
--- tcp_wrappers_7.6.orig/fix_options.c 1997-04-08 02:29:19.000000000 +0200
+++ tcp_wrappers_7.6/fix_options.c 2004-04-10 19:07:43.000000000 +0200
@@ -11,6 +11,9 @@
#include <sys/types.h>
#include <sys/param.h>
+#ifdef INET6
+#include <sys/socket.h>
+#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@@ -41,6 +44,22 @@
unsigned int opt;
int optlen;
struct in_addr dummy;
+#ifdef INET6
+ struct sockaddr_storage ss;
+ int sslen;
+
+ /*
+ * check if this is AF_INET socket
+ * XXX IPv6 support?
+ */
+ sslen = sizeof(ss);
+ if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ clean_exit(request);
+ }
+ if (ss.ss_family != AF_INET)
+ return;
+#endif
if ((ip = getprotobyname("ip")) != 0)
ipproto = ip->p_proto;
diff -ruN tcp_wrappers_7.6.orig/hosts_access.5 tcp_wrappers_7.6/hosts_access.5
--- tcp_wrappers_7.6.orig/hosts_access.5 2004-04-10 19:22:58.000000000 +0200
+++ tcp_wrappers_7.6/hosts_access.5 2004-04-10 19:07:43.000000000 +0200
@@ -85,11 +85,18 @@
for daemon process names or for client user names.
.IP \(bu
An expression of the form `n.n.n.n/m.m.m.m\' is interpreted as a
-`net/mask\' pair. A host address is matched if `net\' is equal to the
+`net/mask\' pair. An IPv4 host address is matched if `net\' is equal to the
bitwise AND of the address and the `mask\'. For example, the net/mask
pattern `131.155.72.0/255.255.254.0\' matches every address in the
range `131.155.72.0\' through `131.155.73.255\'.
.IP \(bu
+An expression of the form `[n:n:n:n:n:n:n:n]/m\' is interpreted as a
+`[net]/prefixlen\' pair. An IPv6 host address is matched if
+`prefixlen\' bits of `net\' is equal to the `prefixlen\' bits of the
+address. For example, the [net]/prefixlen pattern
+`[3ffe:505:2:1::]/64\' matches every address in the range
+`3ffe:505:2:1::\' through `3ffe:505:2:1:ffff:ffff:ffff:ffff\'.
+.IP \(bu
Wildcards `*\' and `?\' can be used to match hostnames or IP addresses. This
method of matching cannot be used in conjunction with `net/mask\' matching,
hostname matching beginning with `.\' or IP address matching ending with `.\'.
diff -ruN tcp_wrappers_7.6.orig/hosts_access.c tcp_wrappers_7.6/hosts_access.c
--- tcp_wrappers_7.6.orig/hosts_access.c 2004-04-10 19:22:58.000000000 +0200
+++ tcp_wrappers_7.6/hosts_access.c 2004-04-10 19:07:43.000000000 +0200
@@ -24,7 +24,13 @@
/* System libraries. */
#include <sys/types.h>
+#ifdef INT32_T
+ typedef uint32_t u_int32_t;
+#endif
#include <sys/param.h>
+#ifdef INET6
+#include <sys/socket.h>
+#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
@@ -33,6 +39,9 @@
#include <errno.h>
#include <setjmp.h>
#include <string.h>
+#ifdef INET6
+#include <netdb.h>
+#endif
extern char *fgets();
extern int errno;
@@ -82,6 +91,10 @@
static int host_match();
static int string_match();
static int masked_match();
+#ifdef INET6
+static int masked_match4();
+static int masked_match6();
+#endif
/* Size of logical line buffer. */
@@ -289,6 +302,13 @@
{
int n;
+#ifdef INET6
+ /* convert IPv4 mapped IPv6 address to IPv4 address */
+ if (STRN_EQ(string, "::ffff:", 7)
+ && dot_quad_addr(string + 7) != INADDR_NONE) {
+ string += 7;
+ }
+#endif
#ifndef DISABLE_WILDCARD_MATCHING
if (strchr(tok, '*') || strchr(tok,'?')) { /* contains '*' or '?' */
return (match_pattern_ylo(string,tok));
@@ -304,20 +324,72 @@
} else if (tok[(n = strlen(tok)) - 1] == '.') { /* prefix */
return (STRN_EQ(tok, string, n));
} else { /* exact match */
+#ifdef INET6
+ struct addrinfo hints, *res;
+ struct sockaddr_in6 pat, addr;
+ int len, ret;
+ char ch;
+
+ len = strlen(tok);
+ if (*tok == '[' && tok[len - 1] == ']') {
+ ch = tok[len - 1];
+ tok[len - 1] = '\0';
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+ if ((ret = getaddrinfo(tok + 1, NULL, &hints, &res)) == 0) {
+ memcpy(&pat, res->ai_addr, sizeof(pat));
+ freeaddrinfo(res);
+ }
+ tok[len - 1] = ch;
+ if (ret != 0 || getaddrinfo(string, NULL, &hints, &res) != 0)
+ return NO;
+ memcpy(&addr, res->ai_addr, sizeof(addr));
+ freeaddrinfo(res);
+#ifdef NI_WITHSCOPEID
+ if (pat.sin6_scope_id != 0 &&
+ addr.sin6_scope_id != pat.sin6_scope_id)
+ return NO;
+#endif
+ return (!memcmp(&pat.sin6_addr, &addr.sin6_addr,
+ sizeof(struct in6_addr)));
+ return (ret);
+ }
+#endif
return (STR_EQ(tok, string));
}
}
/* masked_match - match address against netnumber/netmask */
+#ifdef INET6
static int masked_match(net_tok, mask_tok, string)
char *net_tok;
char *mask_tok;
char *string;
{
+ return (masked_match4(net_tok, mask_tok, string) ||
+ masked_match6(net_tok, mask_tok, string));
+}
+
+static int masked_match4(net_tok, mask_tok, string)
+#else
+static int masked_match(net_tok, mask_tok, string)
+#endif
+char *net_tok;
+char *mask_tok;
+char *string;
+{
+#ifdef INET6
+ u_int32_t net;
+ u_int32_t mask;
+ u_int32_t addr;
+#else
unsigned long net;
unsigned long mask;
unsigned long addr;
+#endif
/*
* Disallow forms other than dotted quad: the treatment that inet_addr()
@@ -329,12 +401,78 @@
return (NO);
if ((net = dot_quad_addr(net_tok)) == INADDR_NONE
|| (mask = dot_quad_addr(mask_tok)) == INADDR_NONE) {
+#ifndef INET6
tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
+#endif
return (NO); /* not tcpd_jump() */
}
return ((addr & mask) == net);
}
+#ifdef INET6
+static int masked_match6(net_tok, mask_tok, string)
+char *net_tok;
+char *mask_tok;
+char *string;
+{
+ struct addrinfo hints, *res;
+ struct sockaddr_in6 net, addr;
+ u_int32_t mask;
+ int len, mask_len, i = 0;
+ char ch;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+ if (getaddrinfo(string, NULL, &hints, &res) != 0)
+ return NO;
+ memcpy(&addr, res->ai_addr, sizeof(addr));
+ freeaddrinfo(res);
+
+ if (IN6_IS_ADDR_V4MAPPED(&addr.sin6_addr)) {
+ if ((*(u_int32_t *)&net.sin6_addr.s6_addr[12] = dot_quad_addr(net_tok)) == INADDR_NONE
+ || (mask = dot_quad_addr(mask_tok)) == INADDR_NONE)
+ return (NO);
+ return ((*(u_int32_t *)&addr.sin6_addr.s6_addr[12] & mask) == *(u_int32_t *)&net.sin6_addr.s6_addr[12]);
+ }
+
+ /* match IPv6 address against netnumber/prefixlen */
+ len = strlen(net_tok);
+ if (*net_tok != '[' || net_tok[len - 1] != ']')
+ return NO;
+ ch = net_tok[len - 1];
+ net_tok[len - 1] = '\0';
+ if (getaddrinfo(net_tok + 1, NULL, &hints, &res) != 0) {
+ net_tok[len - 1] = ch;
+ return NO;