# HG changeset patch # User carl # Date 1184091623 25200 # Node ID b3ed72ee656431ebc399a048af1fcc98222530b9 # Parent ea7c57a4a2d1a33b9f972fa7db0725643f3a9cda allow manual updates to auto whitelist files diff -r ea7c57a4a2d1 -r b3ed72ee6564 ChangeLog --- 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. diff -r ea7c57a4a2d1 -r b3ed72ee6564 NEWS --- 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. diff -r ea7c57a4a2d1 -r b3ed72ee6564 configure.in --- 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]) diff -r ea7c57a4a2d1 -r b3ed72ee6564 src/context.cpp --- 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 -#include +#include #include -#include +#include #include #include -#include +#include #include +#include #include +#include 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); } diff -r ea7c57a4a2d1 -r b3ed72ee6564 src/context.h --- 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 context_map; typedef map ns_mapper; typedef map rcpt_rates; -typedef map autowhite_sent; +typedef map autowhite_sent; typedef map verify_map; typedef map 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) diff -r ea7c57a4a2d1 -r b3ed72ee6564 xml/dnsbl.in --- 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. The DNSBL milter reads a text configuration file (dnsbl.conf) on @@ -264,11 +263,13 @@ 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. If the client has authenticated with sendmail, the rate limits are @@ -345,6 +346,12 @@ + 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. + + 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 @@ 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.