changeset 12:6ac6d6b822ce stable-2-0

fix memory leak with duplicate url host names, document differences from sendmail.mc feature
author carl
date Fri, 23 Apr 2004 22:45:10 -0700
parents 2c206836b4cc
children 2752e512fd32
files sendmail.st src/dnsbl.cpp src/scanner.cpp xml/dnsbl.in
diffstat 4 files changed, 73 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
Binary file sendmail.st has changed
--- 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
--- 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);
--- 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 @@
 <title>DNSBL Sendmail milter</title>
 </head>
 
+<center>Introduction</center>
 <p>This milter is released under the GPL license version 2 included in
 the LICENSE file in the distribution, and also available at
 <a href="http://www.gnu.org/licenses/gpl.html">http://www.gnu.org/licenses/gpl.html</a>
 
-<p>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
+<p>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.
 
+<hr>
+<center>DCC Issues</center>
 <p>If you are also using the <a
 href="http://www.rhyolite.com/anti-spam/dcc/">DCC</a> 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.
 
-<p>Definitions:
-
+<hr>
+<center>Definitions</center>
 <p>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 @@
 
 </ol>
 
+<hr>
+<center>Sendmail access vs. DNSBL</center>
+<p>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
 
+<pre>
+192.168.4   OK
+192.168.17  OK
+</pre>
+
+<p>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.
+
+<p>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.
+
+<hr>
+<center>Installation and configuration</center>
 <p>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.