11_tcpd_blacklist 5.4 KB

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