diff src/dnsbl.cpp @ 249:15bf4f68a0b2

Add dnswl support
author Carl Byington <carl@five-ten-sg.com>
date Sun, 08 Apr 2012 11:42:59 -0700
parents b0738685bf51
children 836b7f2357f9
line wrap: on
line diff
--- a/src/dnsbl.cpp	Fri Jan 06 22:07:45 2012 -0800
+++ b/src/dnsbl.cpp	Sun Apr 08 11:42:59 2012 -0700
@@ -819,14 +819,14 @@
 ////////////////////////////////////////////////
 //  check a single dnsbl
 //
-bool check_single(mlfiPriv &priv, int32_t ip, const char *suffix);
-bool check_single(mlfiPriv &priv, int32_t ip, const char *suffix) {
+int32_t check_single(mlfiPriv &priv, int32_t ip, const char *suffix);
+int32_t check_single(mlfiPriv &priv, int32_t ip, const char *suffix) {
     // make a dns question
     const u_char *src = (const u_char *)&ip;
-    if (src[0] == 127) return false;    // don't do dns lookups on localhost
-    if (src[0] == 10)  return false;    // don't do dns lookups on rfc1918 space
-    if ((src[0] == 192) && (src[1] == 168)) return false;
-    if ((src[0] == 172) && (16 <= src[1]) && (src[1] <= 31)) return false;
+    if (src[0] == 127) return 0;    // don't do dns lookups on localhost
+    if (src[0] == 10)  return 0;    // don't do dns lookups on rfc1918 space
+    if ((src[0] == 192) && (src[1] == 168)) return 0;
+    if ((src[0] == 172) && (16 <= src[1]) && (src[1] <= 31)) return 0;
 #ifdef NS_MAXDNAME
     char question[NS_MAXDNAME];
 #else
@@ -848,6 +848,23 @@
 
 
 ////////////////////////////////////////////////
+//  check a single dnswl
+//
+bool check_single(mlfiPriv &priv, int32_t ip, DNSWL &wl);
+bool check_single(mlfiPriv &priv, int32_t ip, DNSWL &wl) {
+    int32_t r = check_single(priv, ip, wl.suffix);
+    int32_t v = (int32_t)0x7f000000;
+    int32_t m = (int32_t)0xffff0000;
+    int32_t m2 = (int32_t)0x000000ff;
+    if ((r & m) == v) {
+        int32_t l = r & m2;
+        if (l >= wl.level) return true;
+    }
+    return false;
+}
+
+
+////////////////////////////////////////////////
 //  check the dnsbls specified for this recipient
 //
 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist);
@@ -855,12 +872,12 @@
     for (dnsblp_list::iterator i=dnsbll.begin(); i!=dnsbll.end(); i++) {
         DNSBLP dp = *i;     // non null by construction
         bool st;
-        map<DNSBLP, bool>::iterator f = priv.checked.find(dp);
-        if (f == priv.checked.end()) {
+        map<DNSBLP, bool>::iterator f = priv.checked_black.find(dp);
+        if (f == priv.checked_black.end()) {
             // have not checked this list yet
             st = check_single(priv, priv.ip, *dp);
             rejectlist = dp;
-            priv.checked[dp] = st;
+            priv.checked_black[dp] = st;
         }
         else {
             st = (*f).second;
@@ -873,6 +890,31 @@
 
 
 ////////////////////////////////////////////////
+//  check the dnswls specified for this recipient
+//
+bool check_dnswl(mlfiPriv &priv, dnswlp_list &dnswll, DNSWLP &acceptlist);
+bool check_dnswl(mlfiPriv &priv, dnswlp_list &dnswll, DNSWLP &acceptlist) {
+    for (dnswlp_list::iterator i=dnswll.begin(); i!=dnswll.end(); i++) {
+        DNSWLP dp = *i;     // non null by construction
+        bool st;
+        map<DNSWLP, bool>::iterator f = priv.checked_white.find(dp);
+        if (f == priv.checked_white.end()) {
+            // have not checked this list yet
+            st = check_single(priv, priv.ip, *dp);
+            acceptlist = dp;
+            priv.checked_white[dp] = st;
+        }
+        else {
+            st = (*f).second;
+            acceptlist = (*f).first;
+        }
+        if (st) return st;
+    }
+    return false;
+}
+
+
+////////////////////////////////////////////////
 //  check the hosts from the body against the content filter and uribl dnsbls
 //
 //
@@ -1117,8 +1159,9 @@
     const char *replyvalue = con2.find_from(loto);
     if (debug_syslog > 1) {
         char buf[maxlen];
+        char buf2[maxlen];
         char msg[maxlen];
-        snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s state %s reply state %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen), fromvalue, replyvalue);
+        snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s state %s reply context %s state %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen), fromvalue, con2.get_full_name(buf2,maxlen), replyvalue);
         my_syslog(&priv, msg);
     }
     free((void*)loto);
@@ -1148,8 +1191,22 @@
         st = white;
     }
     else {
-        // check the dns based lists
-        st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? reject : oksofar;
+        // check the dns based lists, whitelist first
+        DNSWLP acceptlist = NULL;   // list that caused the whitelisting
+        if (check_dnswl(priv, con.get_dnswl_list(), acceptlist)) {
+            st = white;
+            if (debug_syslog > 1) {
+                char msg[maxlen];
+                snprintf(msg, sizeof(msg), "whitelisted by %s", acceptlist->name);
+                my_syslog(&priv, msg);
+            }
+        }
+        else if (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) {
+            st = reject;
+        }
+        else {
+            st = oksofar;
+        }
     }
     if (st == reject) {
         // reject the recipient based on some dnsbl