# HG changeset patch # User carl # Date 1089384782 25200 # Node ID 6b79046b18c2f3ef05b3d4f05303ad14778128ad # Parent acbe44bbba22d078e58e4c4a7aecc01caba9b417 changes for 3.2 diff -r acbe44bbba22 -r 6b79046b18c2 ChangeLog --- a/ChangeLog Mon Jul 05 22:24:22 2004 -0700 +++ b/ChangeLog Fri Jul 09 07:53:02 2004 -0700 @@ -11,7 +11,7 @@ subsystem that were tripping the html tag detector. Help with changes required to allow dnsbl to drop root - priviledges. + priviledges. Move the socket to /var/run/dnsbl/dnsbl.sock Change parser to handle &#xnnn; obfuscated urls with charaters specified in hex. @@ -20,3 +20,16 @@ positives in .zip or .tar.gz file attachments. Add sendmail queueid to the dnsbl syslog messages. + + Fix one place where host names were not forced to lower case. + Discovered by Nigel Horne + + Remove duplicate dns queries within the same smtp transaction from + the body content filtering. This helps if the mail server does not + have a nearby caching dns server. + + Add host_soft_limit config keyword. Use only one of host_limit or + host_soft_limit, since the last one wins. The host_limit is a hard + upper limit on the number of host names in a message. The + host_soft_limit allows unlimited host names, but only checks a + random sample of them against the dnsbl. diff -r acbe44bbba22 -r 6b79046b18c2 dnsbl.conf --- a/dnsbl.conf Mon Jul 05 22:24:22 2004 -0700 +++ b/dnsbl.conf Fri Jul 09 07:53:02 2004 -0700 @@ -2,7 +2,8 @@ # content scanning parameters # content sbl-xbl.spamhaus.org 'Mail containing %s rejected - sbl; see http://www.spamhaus.org/query/bl?ip=%s' -host_limit 20 'Mail containing too many host names rejected' +#host_limit 20 'Mail containing too many host names rejected' +host_soft_limit 20 html_limit 20 'Mail containing excessive bad html tags rejected' include html-tags.conf include tld.conf diff -r acbe44bbba22 -r 6b79046b18c2 dnsbl.rc --- a/dnsbl.rc Mon Jul 05 22:24:22 2004 -0700 +++ b/dnsbl.rc Fri Jul 09 07:53:02 2004 -0700 @@ -22,8 +22,7 @@ echo -n "Starting dnsbl-milter: " if [ ! -f /var/lock/subsys/dnsbl ]; then cd /etc/dnsbl # conf file is here - #su -l dnsbl -s /bin/sh -c "/usr/sbin/dnsbl -d -p local:/var/run/dnsbl.sock " - /usr/sbin/dnsbl -d -p local:/var/run/dnsbl.sock + /usr/sbin/dnsbl -d -p local:/var/run/dnsbl/dnsbl.sock RETVAL=$? pid=`pidof -s /usr/sbin/dnsbl` if [ $pid ] diff -r acbe44bbba22 -r 6b79046b18c2 sendmail.st Binary file sendmail.st has changed diff -r acbe44bbba22 -r 6b79046b18c2 src/dnsbl.cpp --- a/src/dnsbl.cpp Mon Jul 05 22:24:22 2004 -0700 +++ b/src/dnsbl.cpp Fri Jul 09 07:53:02 2004 -0700 @@ -116,6 +116,7 @@ typedef map dnsblp_map; typedef map dnsbllp_map; typedef set string_set; +typedef set int_set; typedef list string_list; typedef map ns_map; @@ -135,6 +136,7 @@ char * content_message; // "" char * host_limit_message; // error message for excessive host names int host_limit; // limit on host names + bool host_random; // pick a random selection of host names rather than error for excessive hosts char * tag_limit_message; // error message for excessive bad html tags int tag_limit; // limit on bad html tags string_set html_tags; // set of valid html tags @@ -150,6 +152,7 @@ content_message = NULL; host_limit_message = NULL; host_limit = 0; + host_random = false; tag_limit_message = NULL; tag_limit = 0; } @@ -586,17 +589,30 @@ if (!dc.content_suffix) return oksofar; int count = 0; ns_map nameservers; - int lim = priv.pc->host_limit; + bool ran = priv.pc->host_random; + int lim = priv.pc->host_limit; // we should not look at more than this many hosts + int cnt = priv.memory->hosts.size(); // number of hosts we could look at + int_set ips; // remove duplicate ip addresses for (string_set::iterator i=priv.memory->hosts.begin(); i!=priv.memory->hosts.end(); i++) { + host = *i; // a reference into priv.memory->hosts, which will live until this smtp transaction is closed + if ((cnt > lim) && (lim > 0) && ran) { + // try to only look at lim/cnt fraction of the available cnt host names + int r = rand() % cnt; + if (r >= lim) { + char buf[1000]; + snprintf(buf, sizeof(buf), "host %s skipped", host); + my_syslog(&priv, buf); + continue; + } + } count++; - if ((count > lim) && (lim > 0)) { + if ((count > lim) && (lim > 0) && (!ran)) { discard(nameservers); return reject_host; } - host = *i; // a reference into priv.memory->hosts, which will live until this smtp transaction is closed ip = protected_dns_interface(host, true, &nameservers); if (debug_syslog) { - char buf[200]; + char buf[1000]; if (ip) { char adr[sizeof "255.255.255.255"]; adr[0] = '\0'; @@ -609,6 +625,9 @@ my_syslog(&priv, buf); } if (ip) { + int_set::iterator i = ips.find(ip); + if (i == ips.end()) { + ips.insert(ip); status st = check_single(ip, dc.content_suffix); if (st == reject) { discard(nameservers); @@ -616,10 +635,12 @@ } } } + } lim *= 4; // allow average of 3 ns per host name for (ns_map::iterator i=nameservers.begin(); i!=nameservers.end(); i++) { count++; if ((count > lim) && (lim > 0)) { + if (ran) continue; // don't complain discard(nameservers); return reject_host; } @@ -640,6 +661,9 @@ my_syslog(&priv, buf); } if (ip) { + int_set::iterator i = ips.find(ip); + if (i == ips.end()) { + ips.insert(ip); status st = check_single(ip, dc.content_suffix); if (st == reject) { host = register_string(priv.memory->hosts, host); // put a copy into priv.memory->hosts, and return that reference @@ -648,6 +672,7 @@ } } } + } discard(nameservers); host = NULL; int bin = priv.memory->binary_tags; @@ -884,6 +909,9 @@ if (dc.host_limit) { fprintf(stdout, "\ncontent filtering for host names enabled with limit %d %s\n", dc.host_limit, dc.host_limit_message); } + if (dc.host_random) { + fprintf(stdout, "\nrandom selection of host names, host limit message is not used\n"); + } if (dc.tag_limit) { fprintf(stdout, "\ncontent filtering for excessive html tags enabled with limit %d %s\n", dc.tag_limit, dc.tag_limit_message); } @@ -996,10 +1024,11 @@ } dc.config_files.push_back(fn); map commands; - enum {dummy, tld, content, hostlimit, htmllimit, htmltag, dnsbl, dnsbll, envfrom, envto, include, includedcc}; + enum {dummy, tld, content, hostlimit, hostrandom, htmllimit, htmltag, dnsbl, dnsbll, envfrom, envto, include, includedcc}; commands["tld" ] = tld; commands["content" ] = content; commands["host_limit" ] = hostlimit; + commands["host_random"] = hostrandom; commands["html_limit" ] = htmllimit; commands["html_tag" ] = htmltag; commands["dnsbl" ] = dnsbl; @@ -1065,6 +1094,11 @@ processed = true; } break; + case hostrandom: { + dc.host_random = true; + processed = true; + } break; + case htmllimit: { char *limit = strtok(NULL, delim); if (!limit) break; // no integer limit diff -r acbe44bbba22 -r 6b79046b18c2 src/scanner.cpp --- a/src/scanner.cpp Mon Jul 05 22:24:22 2004 -0700 +++ b/src/scanner.cpp Fri Jul 09 07:53:02 2004 -0700 @@ -959,7 +959,7 @@ char *p2 = strrchr((const char *)pending, '.'); if (p1 && (p1 != p2)) { // have two periods, so three components - for (int i=1; itlds->find(p2+1); if (i != memory->tlds->end()) memory->new_url((char*)pending); @@ -1013,7 +1013,11 @@ if (p && // have a leading / strchr(p, '.') && // require at least one . in a dns name (strncasecmp((const char *)pending, "http", 4) == 0)) { // must start with protocol - memory->new_url(++p); // we seem to have a host name, skip the last / + // we seem to have a host name + p++; // skip the last / + int c = strlen(p); + for (int i=0; inew_url(p); // record it } } st = u_init; diff -r acbe44bbba22 -r 6b79046b18c2 xml/dnsbl.in --- a/xml/dnsbl.in Mon Jul 05 22:24:22 2004 -0700 +++ b/xml/dnsbl.in Fri Jul 09 07:53:02 2004 -0700 @@ -171,18 +171,18 @@ line in your sendmail.mc and rebuild the .cf file
-INPUT_MAIL_FILTER(`dnsbl', `S=local:/var/run/dnsbl.sock, F=T, T=C:30s;S:2m;R:2m;E:5m')
+INPUT_MAIL_FILTER(`dnsbl', `S=local:/var/run/dnsbl/dnsbl.sock, F=T, T=C:30s;S:2m;R:2m;E:5m')
 
Read the sample var/dnsbl/dnsbl.conf +href="http://www.five-ten-sg.com/dnsbl.conf">/etc/dnsbl/dnsbl.conf file and modify it to fit your configuration. You can test your configuration files, and see a readable internal dump of them on stdout with
-cd /var/dnsbl
-./dnsbl -c
+cd /etc/dnsbl
+/usr/sbin/dnsbl -c
 
diff -r acbe44bbba22 -r 6b79046b18c2 xml/sample.conf
--- a/xml/sample.conf	Mon Jul 05 22:24:22 2004 -0700
+++ b/xml/sample.conf	Fri Jul 09 07:53:02 2004 -0700
@@ -17,11 +17,19 @@
 # host_limit:
 #   second token is the integer count of the number of host names
 #       or urls that are allowed in any one mail body. Zero is
-#       unlimited.
+#       unlimited. If the actual number of host names in the message
+#       is larger than this limit, the message is rejected.
 #   third  token? is a string enclosed in single quotes, so it
 #       is not really a token. This is the error message supplied
 #       to the smtp client.
 #
+# host_soft_limit:
+#   second token is the integer count of the number of host names
+#       or urls that are checked in any one mail body. Zero is
+#       unlimited. If the actual number of host names in the message
+#       is larger than this limit, only a random selection of them
+#       are checked against the dnsbl.
+#
 # html_limit:
 #   second token is the integer count of the number of bad html tags
 #       that are allowed in any one mail body. Zero is unlimited.
@@ -103,6 +111,7 @@
 #
 content         sbl-xbl.spamhaus.org        'Mail containing %s rejected - sbl; see http://www.spamhaus.org/query/bl?ip=%s'
 host_limit      20                          'Mail containing too many host names rejected'
+host_soft_limit 20
 html_limit      20                          'Mail containing excessive bad html tags rejected'
 include html-tags.conf
 include tld.conf