# HG changeset patch # User carl # Date 1082785510 25200 # Node ID 6ac6d6b822cef73542ca55aa8a704234e6999a6a # Parent 2c206836b4ccf06af5c285bbb4decfd3d496d818 fix memory leak with duplicate url host names, document differences from sendmail.mc feature diff -r 2c206836b4cc -r 6ac6d6b822ce sendmail.st Binary file sendmail.st has changed diff -r 2c206836b4cc -r 6ac6d6b822ce src/dnsbl.cpp --- a/src/dnsbl.cpp Thu Apr 22 20:19:01 2004 -0700 +++ b/src/dnsbl.cpp Fri Apr 23 22:45:10 2004 -0700 @@ -146,11 +146,6 @@ static pthread_mutex_t resolve_mutex; - -// include the content scanner -#include "scanner.cpp" - - //////////////////////////////////////////////// // helper to discard the strings held by a string_set // @@ -162,6 +157,22 @@ s.clear(); } +//////////////////////////////////////////////// +// helper to register a string in a string set +// +static char* register_string(string_set &s, char *name); +static char* register_string(string_set &s, char *name) { + string_set::iterator i = s.find(name); + if (i != s.end()) return *i; + char *x = strdup(name); + s.insert(x); + return x; +} + +// include the content scanner +#include "scanner.cpp" + + //////////////////////////////////////////////// // mail filter private data, held for us by sendmail @@ -179,7 +190,7 @@ bool only_whites; // every recipient is whitelisted? url_scanner *scanner; // object to handle body scanning string_set non_whites; // remember the non-whitelisted recipients so we can remove them if need be - string_set urls; // remember the urls that we have checked + string_set hosts; // remember the hosts that we have checked mlfiPriv(); ~mlfiPriv(); void reset(bool final = false); // for a new message @@ -194,7 +205,7 @@ authenticated = false; have_whites = false; only_whites = true; - scanner = new url_scanner(&urls); + scanner = new url_scanner(&hosts); } mlfiPriv::~mlfiPriv() { pthread_mutex_lock(&config_mutex); @@ -206,13 +217,13 @@ if (mailaddr) free(mailaddr); delete scanner; discard(non_whites); - discard(urls); + discard(hosts); if (!final) { mailaddr = NULL; authenticated = false; have_whites = false; only_whites = true; - scanner = new url_scanner(&urls); + scanner = new url_scanner(&hosts); } } @@ -237,11 +248,7 @@ // static char* register_string(char *name); static char* register_string(char *name) { - string_set::iterator i = all_strings.find(name); - if (i != all_strings.end()) return *i; - char *x = strdup(name); - all_strings.insert(x); - return x; + return register_string(all_strings, name); } @@ -425,14 +432,14 @@ //////////////////////////////////////////////// // check the dnsbls specified for this recipient // -static status check_urls(mlfiPriv &priv, char *&url, int &ip); -static status check_urls(mlfiPriv &priv, char *&url, int &ip) { +static status check_hosts(mlfiPriv &priv, char *&url, int &ip); +static status check_hosts(mlfiPriv &priv, char *&url, int &ip) { CONFIG &dc = *priv.pc; if (!dc.content_suffix) return oksofar; int count = 0; - for (string_set::iterator i=priv.urls.begin(); i!=priv.urls.end(); i++) { + for (string_set::iterator i=priv.hosts.begin(); i!=priv.hosts.end(); i++) { count++; - if (count > 20) return oksofar; // silly to check too many urls + if (count > 20) return oksofar; // silly to check too many hosts url = *i; char buf[200]; snprintf(buf, sizeof(buf), "looking for url %s", url); @@ -526,7 +533,7 @@ // accept the recipient if (st == oksofar) { // but remember the non-whites - priv.non_whites.insert(strdup(rcptaddr)); + register_string(priv.non_whites, rcptaddr); priv.only_whites = false; } if (st == white) { @@ -554,7 +561,7 @@ // process end of message if (priv.authenticated || priv.only_whites || - (check_urls(priv, url, ip) == oksofar)) rc = SMFIS_CONTINUE; + (check_hosts(priv, url, ip) == oksofar)) rc = SMFIS_CONTINUE; else { if (!priv.have_whites) { // can reject the entire message diff -r 2c206836b4cc -r 6ac6d6b822ce src/scanner.cpp --- a/src/scanner.cpp Thu Apr 22 20:19:01 2004 -0700 +++ b/src/scanner.cpp Fri Apr 23 22:45:10 2004 -0700 @@ -825,18 +825,18 @@ state st; state init; fsa* next; - string_set *urls; + string_set *hosts; - fsa(state init, fsa* next_, string_set *urls_); + fsa(state init, fsa* next_, string_set *hosts_); void push(u_char *buf, int len); }; -fsa::fsa(state init_, fsa *next_, string_set *urls_) { +fsa::fsa(state init_, fsa *next_, string_set *hosts_) { count = 0; st = init_; init = init_; next = next_; - urls = urls_; + hosts = hosts_; } void fsa::push(u_char *buf, int len) { @@ -866,7 +866,7 @@ pending[count-1] = 0; if (strncasecmp((const char *)pending, "http://", 7) == 0) { char *p = (char *)pending + 7; - if (strchr(p, '.')) urls->insert(strdup(p)); // require at least one . in a dns name + if (strchr(p, '.')) register_string(*hosts, p); // require at least one . in a dns name } } } // fall thru @@ -969,13 +969,13 @@ fsa *mime_parser; fsa *b64_parser; - url_scanner(string_set *urls); + url_scanner(string_set *hosts); ~url_scanner(); void scan(u_char *buffer, size_t length); }; -url_scanner::url_scanner(string_set *urls) { - urls_parser = new fsa(u_init, NULL, urls); +url_scanner::url_scanner(string_set *hosts) { + urls_parser = new fsa(u_init, NULL, hosts); html_parser = new fsa(e_init, urls_parser, NULL); mime_parser = new fsa(m_init, html_parser, NULL); b64_parser = new fsa(b_init, mime_parser, NULL); diff -r 2c206836b4cc -r 6ac6d6b822ce xml/dnsbl.in --- a/xml/dnsbl.in Thu Apr 22 20:19:01 2004 -0700 +++ b/xml/dnsbl.in Fri Apr 23 22:45:10 2004 -0700 @@ -5,15 +5,16 @@ DNSBL Sendmail milter +
Introduction

This milter is released under the GPL license version 2 included in the LICENSE file in the distribution, and also available at http://www.gnu.org/licenses/gpl.html -

Consider the case of a mail server that is acting as secondary MX -for a collection of clients, each of which has a collection of mail -domains. Each client may use their own collection of DNSBLs on their -primary mail server. We present here a mechanism whereby the backup -mail server can use the correct set of DNSBLs for each message. As a +

Consider the case of a mail server that is acting as secondary MX for +a collection of clients, each of which has a collection of mail domains. +Each client may use their own collection of DNSBLs on their primary mail +server. We present here a mechanism whereby the backup mail server can +use the correct set of DNSBLs for each recipient for each message. As a side-effect, it gives us the ability to customize the set of DNSBLs on a per-recipient basis, so that fred@example.com could use SPEWS and the SBL, where all other users @example.com use only the SBL. @@ -27,6 +28,8 @@ startup, and whenever the config file (or any of the referenced include files) is changed. The entire configuration file is case insensitive. +


+
DCC Issues

If you are also using the DCC milter, there are a few considerations. You may need to whitelist senders from the DCC @@ -61,8 +64,8 @@ appropriately tagged and used only for the domains controlled by each of those clients. -

Definitions: - +


+
Definitions

DNSBL - a named DNS based blocking list is defined by a dns suffix (e.g. sbl-xbl.spamhaus.org) and a message string that is used to generate the "550 5.7.1" smtp error return code. The names of these @@ -110,7 +113,30 @@ +


+
Sendmail access vs. DNSBL
+

With the standard sendmail.mc dnsbl FEATURE, the dnsbl checks may be +suppressed by entries in the /etc/mail/access database. For example, +suppose you control a /18 of address space, and have allocated some /24s +to some clients. You have access entries like +

+192.168.4   OK
+192.168.17  OK
+
+ +

to allow those clients to smarthost thru your mail server. Now if +one of those clients happens get infected with a virus that turns into +an open proxy, and their 192.168.4.45 lands on the SBL-XBL, you will +still wind up allowing that infected machine to smarthost thru your mail +servers. + +

With this DNSBL milter, the sendmail access database cannot override +the dnsbl checks, so that machine won't be able to send mail to or thru +your smarthost machine. + +


+
Installation and configuration

Usage: Note that this has ONLY been tested on Linux, specifically RedHat Linux. Your mileage will vary. In particular, this milter makes no attempt to understand IPv6.