TCP Wrapper Blacklist Extension

The patch below adds a new host pattern to the TCP Wrapper access
control language. Instead of a host name or address pattern, you
can specify an external /file/name with host name or address
patterns.   The feature can be used recursively.

The /file/name extension makes it easy to blacklist bad sites, for
example, to block unwanted electronic mail when libwrap is linked
into sendmail.  Adding hosts to a simple text file is much easier
than having to edit a more complex hosts.allow/deny file.

I developed this a year or so ago as a substitute for NIS netgroups.
At that time, I did not consider it of sufficient interest for
inclusion in the TCP Wrapper distribution. How times have changed.

The patch is relative to TCP Wrappers version 7.6. The main archive
site is ftp://ftp.win.tue.nl/pub/security/tcp_wrappers_7.6.tar.gz

Thanks to the Debian LINUX folks for expressing their interest in
this patch.

	Wietse


[diff updated by Md]


Gbp-Pq: Name 11_tcpd_blacklist
This commit is contained in:
Wietse Venema 1997-09-08 18:53:13 -04:00 committed by openKylinBot
parent c3046c5d6e
commit 12196d4614
3 changed files with 53 additions and 0 deletions

View File

@ -97,6 +97,13 @@ 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
A string that begins with a `/\' character is treated as a file
name. A host name or address is matched if it matches any host name
or address pattern listed in the named file. The file format is
zero or more lines with zero or more host name or address patterns
separated by whitespace. A file name pattern can be used anywhere
a host name or address pattern can be used.
.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 `.\'.

View File

@ -254,6 +254,26 @@ struct request_info *request;
}
}
/* hostfile_match - look up host patterns from file */
static int hostfile_match(path, host)
char *path;
struct hosts_info *host;
{
char tok[BUFSIZ];
int match = NO;
FILE *fp;
if ((fp = fopen(path, "r")) != 0) {
while (fscanf(fp, "%s", tok) == 1 && !(match = host_match(tok, host)))
/* void */ ;
fclose(fp);
} else if (errno != ENOENT) {
tcpd_warn("open %s: %m", path);
}
return (match);
}
/* host_match - match host name and/or address against pattern */
static int host_match(tok, host)
@ -281,6 +301,8 @@ struct host_info *host;
tcpd_warn("netgroup support is disabled"); /* not tcpd_jump() */
return (NO);
#endif
} else if (tok[0] == '/') { /* /file hack */
return (hostfile_match(tok, host));
} else if (STR_EQ(tok, "KNOWN")) { /* check address and name */
char *name = eval_hostname(host);
return (STR_NE(eval_hostaddr(host), unknown) && HOSTNAME_KNOWN(name));

View File

@ -353,6 +353,8 @@ char *pat;
{
if (pat[0] == '@') {
tcpd_warn("%s: daemon name begins with \"@\"", pat);
} else if (pat[0] == '/') {
tcpd_warn("%s: daemon name begins with \"/\"", pat);
} else if (pat[0] == '.') {
tcpd_warn("%s: daemon name begins with dot", pat);
} else if (pat[strlen(pat) - 1] == '.') {
@ -385,6 +387,8 @@ char *pat;
{
if (pat[0] == '@') { /* @netgroup */
tcpd_warn("%s: user name begins with \"@\"", pat);
} else if (pat[0] == '/') {
tcpd_warn("%s: user name begins with \"/\"", pat);
} else if (pat[0] == '.') {
tcpd_warn("%s: user name begins with dot", pat);
} else if (pat[strlen(pat) - 1] == '.') {
@ -430,8 +434,13 @@ static int is_inet6_addr(pat)
static int check_host(pat)
char *pat;
{
char buf[BUFSIZ];
char *mask;
int addr_count = 1;
FILE *fp;
struct tcpd_context saved_context;
char *cp;
char *wsp = " \t\r\n";
if (pat[0] == '@') { /* @netgroup */
#ifdef NO_NETGRENT
@ -450,6 +459,21 @@ char *pat;
tcpd_warn("netgroup support disabled");
#endif
#endif
} else if (pat[0] == '/') { /* /path/name */
if ((fp = fopen(pat, "r")) != 0) {
saved_context = tcpd_context;
tcpd_context.file = pat;
tcpd_context.line = 0;
while (fgets(buf, sizeof(buf), fp)) {
tcpd_context.line++;
for (cp = strtok(buf, wsp); cp; cp = strtok((char *) 0, wsp))
check_host(cp);
}
tcpd_context = saved_context;
fclose(fp);
} else if (errno != ENOENT) {
tcpd_warn("open %s: %m", pat);
}
} else if (mask = split_at(pat, '/')) { /* network/netmask */
#ifdef INET6
int mask_len;