changeset 160:b3ed72ee6564

allow manual updates to auto whitelist files
author carl
date Tue, 10 Jul 2007 11:20:23 -0700
parents ea7c57a4a2d1
children d384df37491f
files ChangeLog NEWS configure.in src/context.cpp src/context.h xml/dnsbl.in
diffstat 6 files changed, 63 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Jul 08 11:57:51 2007 -0700
+++ b/ChangeLog	Tue Jul 10 11:20:23 2007 -0700
@@ -1,5 +1,10 @@
     $Id$
 
+6.02 2007-07-10
+    Allow manual updates to the auto whitelisting files, mainly for
+    scp or rsync synchronization between primary and backup mx
+    systems.
+
 6.01 2007-07-07
     GPL3. Block mail to recipients that cannot reply. Start auto
     whitelisting.
--- a/NEWS	Sun Jul 08 11:57:51 2007 -0700
+++ b/NEWS	Tue Jul 10 11:20:23 2007 -0700
@@ -1,5 +1,6 @@
     $Id$
 
+6.02 2007-07-10 Allow manual updates to the auto whitelisting files.
 6.01 2007-07-07 GPL3. Block mail to recipients that cannot reply. Start auto whitelisting.
 5.30 2007-06-09 Selinux fixes
 5.29 2007-03-27 Limit dns resolver to two retries five seconds apart.
--- a/configure.in	Sun Jul 08 11:57:51 2007 -0700
+++ b/configure.in	Tue Jul 10 11:20:23 2007 -0700
@@ -1,6 +1,6 @@
 
 AC_PREREQ(2.59)
-AC_INIT(dnsbl,6.01,carl@five-ten-sg.com)
+AC_INIT(dnsbl,6.02,carl@five-ten-sg.com)
 AC_CONFIG_SRCDIR([config.h.in])
 AC_CONFIG_HEADER([config.h])
 
--- a/src/context.cpp	Sun Jul 08 11:57:51 2007 -0700
+++ b/src/context.cpp	Tue Jul 10 11:20:23 2007 -0700
@@ -8,16 +8,16 @@
 
 #include "includes.h"
 
-// needed for socket io
-#include <unistd.h>
-#include <sys/ioctl.h>
+#include <arpa/inet.h>
 #include <net/if.h>
-#include <arpa/inet.h>
+#include <netdb.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
-#include <netdb.h>
+#include <sys/ioctl.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <sys/un.h>
+#include <unistd.h>
 
 static char* context_version="$Id$";
 
@@ -425,6 +425,13 @@
 	days	 = d;
 	pthread_mutex_init(&mutex, 0);
 	need	 = false;
+	loaded	 = time(NULL);
+	merge();
+}
+
+
+void WHITELISTER::merge() {
+	time_t now = time(NULL);
 	ifstream ifs;
 	ifs.open(fn);
 	if (!ifs.fail()) {
@@ -435,11 +442,19 @@
 			if (p) {
 				*p = '\0';
 				char *who = strdup(buf);
-				int  when = atoi(p+1);
+				time_t when = atoi(p+1);
+				if ((when == 0) || (when > now)) when = now;
+				autowhite_sent::iterator i = rcpts.find(who);
+				if (i != rcpts.end()) {
+					time_t wh = (*i).second;
+					if (when > wh) rcpts[who] = when;
+				}
+				else {
 				rcpts[who] = when;
 			}
 		}
 	}
+	}
 	ifs.close();
 }
 
@@ -447,6 +462,17 @@
 void WHITELISTER::writer() {
 	pthread_mutex_lock(&mutex);
 		time_t limit = time(NULL) - days*86400;
+
+		// check for manually modified autowhitelist file
+		struct stat st;
+		if (stat(fn, &st)) need = true; // file has disappeared
+		else if (st.st_mtime > loaded) {
+			// file has been manually updated, merge new entries
+			merge();
+			need = true;
+		}
+
+		// purge old entries
 		for (autowhite_sent::iterator i=rcpts.begin(); i!=rcpts.end();) {
 			time_t when = (*i).second;
 			if (when < limit) {
@@ -473,6 +499,7 @@
 			}
 			ofs.close();
 			need = false;
+			loaded = time(NULL);	// update load time
 		}
 	pthread_mutex_unlock(&mutex);
 }
--- a/src/context.h	Sun Jul 08 11:57:51 2007 -0700
+++ b/src/context.h	Tue Jul 10 11:20:23 2007 -0700
@@ -39,7 +39,7 @@
 typedef map<char *, CONTEXTP, ltstr>	  context_map;
 typedef map<char *, int, ltstr> 		  ns_mapper;
 typedef map<char *, int, ltstr> 		  rcpt_rates;
-typedef map<char *, int, ltstr> 		  autowhite_sent;
+typedef map<char *, time_t,  ltstr> 	  autowhite_sent;
 typedef map<char *, VERIFYP, ltstr> 	  verify_map;
 typedef map<char *, WHITELISTERP, ltstr>  whitelister_map;
 
@@ -95,10 +95,12 @@
 	char			*fn;		// file to use
 	int 			days;		// how long do we keep entries
 	pthread_mutex_t mutex;		// protect the flag and map
+	time_t			loaded; 	// when we loaded this file
 	bool			need;		// force writing on new entries
 	autowhite_sent	rcpts;		// recipient map to remember when we sent them mail
 public:
 	WHITELISTER(char *f, int d);
+	void	merge();
 	void	writer();			// dump any changes back to the file
 	void	sent(char *to);
 	bool	is_white(char *from);	// should we white list this sender (did we send them anything recently)
--- a/xml/dnsbl.in	Sun Jul 08 11:57:51 2007 -0700
+++ b/xml/dnsbl.in	Tue Jul 10 11:20:23 2007 -0700
@@ -180,10 +180,9 @@
                 If that message is not blocked, then we might eventually see a reply
                 message from B to A. If the filtering context for A includes an
                 autowhite entry, then this milter will add an entry in that file to
-                whitelist such replies.  Note that manually editing such autowhite files
-                is not supported. Also, such autowhite files need to be writeable by the
-                dnsbl user, where all the other dnsbl configuration files only need
-                to be readable by the dnsbl user.
+                whitelist such replies for a configurable time period.  Such autowhite
+                files need to be writeable by the dnsbl user, where all the other dnsbl
+                configuration files only need to be readable by the dnsbl user.
             </para>
             <para>
                 The DNSBL milter reads a text configuration file (dnsbl.conf) on
@@ -264,11 +263,13 @@
             <para>
                 The SMTP envelope 'from' and 'to' values are used in various checks.
                 The first check is to see if a reply message (swapping the env_from and
-                env_to values) would be blocked.  That check is similar to the main
-                check described below, but there is no body content to be scanned, and
-                there is no client connection ip address to be checked against DNSBLs.
-                This prevents folks from sending mail to recipients that are unable to
-                reply.
+                env_to values) would be unconditionally blocked (just based on the
+                envelope from address).  That check is similar to the main check
+                described below, but there is no body content to be scanned, and there
+                is no client connection ip address to be checked against DNSBLs.  If
+                such a reply message would be blocked, we also block the original
+                outgoing message.  This prevents folks from sending mail to recipients
+                that are unable to reply.
             </para>
             <para>
                 If the client has authenticated with sendmail, the rate limits are
@@ -345,6 +346,12 @@
                 </para></listitem>
             </orderedlist>
             <para>
+                For each recipient that was accepted, we search for an autowhite entry
+                starting in the reply filtering context. If an autowhite entry is found,
+                we add the recipient to that auto whitelist file. This will prevent reply
+                messages from being blocked by the dnsbl or content filtering.
+            </para>
+            <para>
                 If content filtering is enabled for this body, the mail text is decoded
                 (uuencode, base64, mime, html entity, url encodings), and scanned for HTTP
                 and HTTPS URLs or bare host names.  Hostnames must be either ip address
@@ -493,7 +500,7 @@
             <para>
                 This program is free software; you can redistribute it and/or modify it
                 under the terms of the GNU General Public License as published by the
-                Free Software Foundation; either version 2, or (at your option) any
+                Free Software Foundation; either version 3, or (at your option) any
                 later version.
             </para>
             <para>