Mercurial > dnsbl
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