Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | Upstream-Status: Backport |
| 2 | |
| 3 | Path: news.porcupine.org!news.porcupine.org!not-for-mail |
| 4 | From: Wietse Venema <wietse@((no)(spam)(please))wzv.win.tue.nl> |
| 5 | Newsgroups: comp.mail.sendmail,comp.security.unix |
| 6 | Subject: TCP Wrapper Blacklist Extension |
| 7 | Followup-To: poster |
| 8 | Date: 8 Sep 1997 18:53:13 -0400 |
| 9 | Organization: Wietse's hangout while on sabattical in the USA |
| 10 | Lines: 147 |
| 11 | Sender: wietse@spike.porcupine.org |
| 12 | Message-ID: <5v1vkp$h4f$1@spike.porcupine.org> |
| 13 | NNTP-Posting-Host: spike.porcupine.org |
| 14 | Xref: news.porcupine.org comp.mail.sendmail:3541 comp.security.unix:7158 |
| 15 | |
| 16 | The patch below adds a new host pattern to the TCP Wrapper access |
| 17 | control language. Instead of a host name or address pattern, you |
| 18 | can specify an external /file/name with host name or address |
| 19 | patterns. The feature can be used recursively. |
| 20 | |
| 21 | The /file/name extension makes it easy to blacklist bad sites, for |
| 22 | example, to block unwanted electronic mail when libwrap is linked |
| 23 | into sendmail. Adding hosts to a simple text file is much easier |
| 24 | than having to edit a more complex hosts.allow/deny file. |
| 25 | |
| 26 | I developed this a year or so ago as a substitute for NIS netgroups. |
| 27 | At that time, I did not consider it of sufficient interest for |
| 28 | inclusion in the TCP Wrapper distribution. How times have changed. |
| 29 | |
| 30 | The patch is relative to TCP Wrappers version 7.6. The main archive |
| 31 | site is ftp://ftp.win.tue.nl/pub/security/tcp_wrappers_7.6.tar.gz |
| 32 | |
| 33 | Thanks to the Debian LINUX folks for expressing their interest in |
| 34 | this patch. |
| 35 | |
| 36 | Wietse |
| 37 | |
| 38 | |
| 39 | [diff updated by Md] |
| 40 | |
| 41 | diff -ruN tcp_wrappers_7.6.orig/hosts_access.5 tcp_wrappers_7.6/hosts_access.5 |
| 42 | --- tcp_wrappers_7.6.orig/hosts_access.5 2004-04-10 19:28:09.000000000 +0200 |
| 43 | +++ tcp_wrappers_7.6/hosts_access.5 2004-04-10 19:28:01.000000000 +0200 |
| 44 | @@ -97,6 +97,13 @@ |
| 45 | `[3ffe:505:2:1::]/64\' matches every address in the range |
| 46 | `3ffe:505:2:1::\' through `3ffe:505:2:1:ffff:ffff:ffff:ffff\'. |
| 47 | .IP \(bu |
| 48 | +A string that begins with a `/\' character is treated as a file |
| 49 | +name. A host name or address is matched if it matches any host name |
| 50 | +or address pattern listed in the named file. The file format is |
| 51 | +zero or more lines with zero or more host name or address patterns |
| 52 | +separated by whitespace. A file name pattern can be used anywhere |
| 53 | +a host name or address pattern can be used. |
| 54 | +.IP \(bu |
| 55 | Wildcards `*\' and `?\' can be used to match hostnames or IP addresses. This |
| 56 | method of matching cannot be used in conjunction with `net/mask\' matching, |
| 57 | hostname matching beginning with `.\' or IP address matching ending with `.\'. |
| 58 | diff -ruN tcp_wrappers_7.6.orig/hosts_access.c tcp_wrappers_7.6/hosts_access.c |
| 59 | --- tcp_wrappers_7.6.orig/hosts_access.c 2004-04-10 19:28:09.000000000 +0200 |
| 60 | +++ tcp_wrappers_7.6/hosts_access.c 2004-04-10 19:27:05.000000000 +0200 |
| 61 | @@ -253,6 +253,26 @@ |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | +/* hostfile_match - look up host patterns from file */ |
| 66 | + |
| 67 | +static int hostfile_match(path, host) |
| 68 | +char *path; |
| 69 | +struct hosts_info *host; |
| 70 | +{ |
| 71 | + char tok[BUFSIZ]; |
| 72 | + int match = NO; |
| 73 | + FILE *fp; |
| 74 | + |
| 75 | + if ((fp = fopen(path, "r")) != 0) { |
| 76 | + while (fscanf(fp, "%s", tok) == 1 && !(match = host_match(tok, host))) |
| 77 | + /* void */ ; |
| 78 | + fclose(fp); |
| 79 | + } else if (errno != ENOENT) { |
| 80 | + tcpd_warn("open %s: %m", path); |
| 81 | + } |
| 82 | + return (match); |
| 83 | +} |
| 84 | + |
| 85 | /* host_match - match host name and/or address against pattern */ |
| 86 | |
| 87 | static int host_match(tok, host) |
| 88 | @@ -280,6 +300,8 @@ |
| 89 | tcpd_warn("netgroup support is disabled"); /* not tcpd_jump() */ |
| 90 | return (NO); |
| 91 | #endif |
| 92 | + } else if (tok[0] == '/') { /* /file hack */ |
| 93 | + return (hostfile_match(tok, host)); |
| 94 | } else if (STR_EQ(tok, "KNOWN")) { /* check address and name */ |
| 95 | char *name = eval_hostname(host); |
| 96 | return (STR_NE(eval_hostaddr(host), unknown) && HOSTNAME_KNOWN(name)); |
| 97 | diff -ruN tcp_wrappers_7.6.orig/tcpdchk.c tcp_wrappers_7.6/tcpdchk.c |
| 98 | --- tcp_wrappers_7.6.orig/tcpdchk.c 2004-04-10 19:28:09.000000000 +0200 |
| 99 | +++ tcp_wrappers_7.6/tcpdchk.c 2004-04-10 19:27:05.000000000 +0200 |
| 100 | @@ -353,6 +353,8 @@ |
| 101 | { |
| 102 | if (pat[0] == '@') { |
| 103 | tcpd_warn("%s: daemon name begins with \"@\"", pat); |
| 104 | + } else if (pat[0] == '/') { |
| 105 | + tcpd_warn("%s: daemon name begins with \"/\"", pat); |
| 106 | } else if (pat[0] == '.') { |
| 107 | tcpd_warn("%s: daemon name begins with dot", pat); |
| 108 | } else if (pat[strlen(pat) - 1] == '.') { |
| 109 | @@ -385,6 +387,8 @@ |
| 110 | { |
| 111 | if (pat[0] == '@') { /* @netgroup */ |
| 112 | tcpd_warn("%s: user name begins with \"@\"", pat); |
| 113 | + } else if (pat[0] == '/') { |
| 114 | + tcpd_warn("%s: user name begins with \"/\"", pat); |
| 115 | } else if (pat[0] == '.') { |
| 116 | tcpd_warn("%s: user name begins with dot", pat); |
| 117 | } else if (pat[strlen(pat) - 1] == '.') { |
| 118 | @@ -430,8 +434,13 @@ |
| 119 | static int check_host(pat) |
| 120 | char *pat; |
| 121 | { |
| 122 | + char buf[BUFSIZ]; |
| 123 | char *mask; |
| 124 | int addr_count = 1; |
| 125 | + FILE *fp; |
| 126 | + struct tcpd_context saved_context; |
| 127 | + char *cp; |
| 128 | + char *wsp = " \t\r\n"; |
| 129 | |
| 130 | if (pat[0] == '@') { /* @netgroup */ |
| 131 | #ifdef NO_NETGRENT |
| 132 | @@ -450,6 +459,21 @@ |
| 133 | tcpd_warn("netgroup support disabled"); |
| 134 | #endif |
| 135 | #endif |
| 136 | + } else if (pat[0] == '/') { /* /path/name */ |
| 137 | + if ((fp = fopen(pat, "r")) != 0) { |
| 138 | + saved_context = tcpd_context; |
| 139 | + tcpd_context.file = pat; |
| 140 | + tcpd_context.line = 0; |
| 141 | + while (fgets(buf, sizeof(buf), fp)) { |
| 142 | + tcpd_context.line++; |
| 143 | + for (cp = strtok(buf, wsp); cp; cp = strtok((char *) 0, wsp)) |
| 144 | + check_host(cp); |
| 145 | + } |
| 146 | + tcpd_context = saved_context; |
| 147 | + fclose(fp); |
| 148 | + } else if (errno != ENOENT) { |
| 149 | + tcpd_warn("open %s: %m", pat); |
| 150 | + } |
| 151 | } else if (mask = split_at(pat, '/')) { /* network/netmask */ |
| 152 | #ifdef INET6 |
| 153 | int mask_len; |