From 29403793e155c69571170fb84a26b2948670d0a4 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Wed, 17 Jun 2015 00:00:00 -0500 Subject: [PATCH] postfix-3.1-20150617-nonprod --- postfix/HISTORY | 8 +++++ postfix/src/global/mail_version.h | 2 +- postfix/src/postscreen/postscreen_dnsbl.c | 43 +++++++++++++++-------- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/postfix/HISTORY b/postfix/HISTORY index 5bbac2a8b..06efd52a1 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -21782,3 +21782,11 @@ Apologies for any names omitted. Files: global/mail_params.h, postscreen/postscreen.c, postscreen/postscreen_early.c, mantools/postlink, proto/postconf.proto. + +20150616 + + Refinement: the postscreen daemon now combines the TTLs from + DNS replies that agree whether a remote SMTP client should be + blocked or not. This more conservative than simply combining + all the TTLs from all the "found" and "not found" DNSBL and + DNSWL responses. File: postscreen/postscreen_dnsbl.c. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index ad6afd18f..25ef400e0 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20150615" +#define MAIL_RELEASE_DATE "20150617" #define MAIL_VERSION_NUMBER "3.1" #ifdef SNAPSHOT diff --git a/postfix/src/postscreen/postscreen_dnsbl.c b/postfix/src/postscreen/postscreen_dnsbl.c index d56dca2df..4d2106ff8 100644 --- a/postfix/src/postscreen/postscreen_dnsbl.c +++ b/postfix/src/postscreen/postscreen_dnsbl.c @@ -144,8 +144,9 @@ typedef struct { typedef struct { const char *dnsbl_name; /* DNSBL with largest contribution */ int dnsbl_weight; /* weight of largest contribution */ - int total; /* combined blocklist score */ - int dnsbl_ttl; /* DNS reply ttl */ + int total; /* combined white+blocklist score */ + int fail_ttl; /* combined reply TTL */ + int pass_ttl; /* combined reply TTL */ int refcount; /* score reference count */ int pending_lookups; /* nr of DNS requests in flight */ int request_id; /* duplicate suppression */ @@ -334,7 +335,7 @@ int psc_dnsbl_retrieve(const char *client_addr, const char **dnsbl_name, */ result_score = score->total; *dnsbl_name = score->dnsbl_name; - *dnsbl_ttl = score->dnsbl_ttl; + *dnsbl_ttl = (result_score > 0) ? score->fail_ttl : score->pass_ttl; score->refcount -= 1; if (score->refcount < 1) { if (msg_verbose > 1) @@ -398,10 +399,10 @@ static void psc_dnsbl_receive(int event, void *context) msg_info("%s: client=\"%s\" score=%d domain=\"%s\" reply=\"%d %s\"", myname, STR(reply_client), score->total, STR(reply_dnsbl), dnsbl_ttl, STR(reply_addr)); + head = (PSC_DNSBL_HEAD *) + htable_find(dnsbl_site_cache, STR(reply_dnsbl)); + site = (head ? head->first : (PSC_DNSBL_SITE *) 0); if (*STR(reply_addr) != 0) { - head = (PSC_DNSBL_HEAD *) - htable_find(dnsbl_site_cache, STR(reply_dnsbl)); - site = (head ? head->first : (PSC_DNSBL_SITE *) 0); for (reply_argv = 0; site != 0; site = site->next) { if (site->byte_codes == 0 || psc_dnsbl_match(site->byte_codes, reply_argv ? reply_argv : @@ -416,20 +417,31 @@ static void psc_dnsbl_receive(int event, void *context) msg_info("%s: filter=\"%s\" weight=%d score=%d", myname, site->filter ? site->filter : "null", site->weight, score->total); + /* Combine TTLs from sites that agree. */ + if (site->weight > 0) { + if (score->fail_ttl > dnsbl_ttl) + score->fail_ttl = dnsbl_ttl; + } else { + if (score->pass_ttl > dnsbl_ttl) + score->pass_ttl = dnsbl_ttl; + } } } if (reply_argv != 0) argv_free(reply_argv); + } else { + for (/* void */; site != 0; site = site->next) { + /* Combine TTLs from sites that agree. */ + if (site->weight > 0) { + if (score->pass_ttl > dnsbl_ttl) + score->pass_ttl = dnsbl_ttl; + } else { + if (score->fail_ttl > dnsbl_ttl) + score->fail_ttl = dnsbl_ttl; + } + } } - /* - * For now, don't try to be clever, and play safe: use the smallest - * TTL even if that particular DNS reply would not change the final - * decision. - */ - if (score->dnsbl_ttl > dnsbl_ttl) - score->dnsbl_ttl = dnsbl_ttl; - /* * Notify the requestor(s) that the result is ready to be picked up. * If this call isn't made, clients have to sit out the entire @@ -501,7 +513,8 @@ int psc_dnsbl_request(const char *client_addr, score->request_id = request_count++; score->dnsbl_name = 0; score->dnsbl_weight = 0; - score->dnsbl_ttl = INT_MAX; + score->pass_ttl = INT_MAX; + score->fail_ttl = INT_MAX; score->total = 0; score->refcount = 1; score->pending_lookups = 0; -- 2.47.3