comparison 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
comparison
equal deleted inserted replaced
248:b0738685bf51 249:15bf4f68a0b2
817 817
818 818
819 //////////////////////////////////////////////// 819 ////////////////////////////////////////////////
820 // check a single dnsbl 820 // check a single dnsbl
821 // 821 //
822 bool check_single(mlfiPriv &priv, int32_t ip, const char *suffix); 822 int32_t check_single(mlfiPriv &priv, int32_t ip, const char *suffix);
823 bool check_single(mlfiPriv &priv, int32_t ip, const char *suffix) { 823 int32_t check_single(mlfiPriv &priv, int32_t ip, const char *suffix) {
824 // make a dns question 824 // make a dns question
825 const u_char *src = (const u_char *)&ip; 825 const u_char *src = (const u_char *)&ip;
826 if (src[0] == 127) return false; // don't do dns lookups on localhost 826 if (src[0] == 127) return 0; // don't do dns lookups on localhost
827 if (src[0] == 10) return false; // don't do dns lookups on rfc1918 space 827 if (src[0] == 10) return 0; // don't do dns lookups on rfc1918 space
828 if ((src[0] == 192) && (src[1] == 168)) return false; 828 if ((src[0] == 192) && (src[1] == 168)) return 0;
829 if ((src[0] == 172) && (16 <= src[1]) && (src[1] <= 31)) return false; 829 if ((src[0] == 172) && (16 <= src[1]) && (src[1] <= 31)) return 0;
830 #ifdef NS_MAXDNAME 830 #ifdef NS_MAXDNAME
831 char question[NS_MAXDNAME]; 831 char question[NS_MAXDNAME];
832 #else 832 #else
833 char question[1000]; 833 char question[1000];
834 #endif 834 #endif
846 return check_single(priv, ip, bl.suffix); 846 return check_single(priv, ip, bl.suffix);
847 } 847 }
848 848
849 849
850 //////////////////////////////////////////////// 850 ////////////////////////////////////////////////
851 // check a single dnswl
852 //
853 bool check_single(mlfiPriv &priv, int32_t ip, DNSWL &wl);
854 bool check_single(mlfiPriv &priv, int32_t ip, DNSWL &wl) {
855 int32_t r = check_single(priv, ip, wl.suffix);
856 int32_t v = (int32_t)0x7f000000;
857 int32_t m = (int32_t)0xffff0000;
858 int32_t m2 = (int32_t)0x000000ff;
859 if ((r & m) == v) {
860 int32_t l = r & m2;
861 if (l >= wl.level) return true;
862 }
863 return false;
864 }
865
866
867 ////////////////////////////////////////////////
851 // check the dnsbls specified for this recipient 868 // check the dnsbls specified for this recipient
852 // 869 //
853 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist); 870 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist);
854 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist) { 871 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist) {
855 for (dnsblp_list::iterator i=dnsbll.begin(); i!=dnsbll.end(); i++) { 872 for (dnsblp_list::iterator i=dnsbll.begin(); i!=dnsbll.end(); i++) {
856 DNSBLP dp = *i; // non null by construction 873 DNSBLP dp = *i; // non null by construction
857 bool st; 874 bool st;
858 map<DNSBLP, bool>::iterator f = priv.checked.find(dp); 875 map<DNSBLP, bool>::iterator f = priv.checked_black.find(dp);
859 if (f == priv.checked.end()) { 876 if (f == priv.checked_black.end()) {
860 // have not checked this list yet 877 // have not checked this list yet
861 st = check_single(priv, priv.ip, *dp); 878 st = check_single(priv, priv.ip, *dp);
862 rejectlist = dp; 879 rejectlist = dp;
863 priv.checked[dp] = st; 880 priv.checked_black[dp] = st;
864 } 881 }
865 else { 882 else {
866 st = (*f).second; 883 st = (*f).second;
867 rejectlist = (*f).first; 884 rejectlist = (*f).first;
885 }
886 if (st) return st;
887 }
888 return false;
889 }
890
891
892 ////////////////////////////////////////////////
893 // check the dnswls specified for this recipient
894 //
895 bool check_dnswl(mlfiPriv &priv, dnswlp_list &dnswll, DNSWLP &acceptlist);
896 bool check_dnswl(mlfiPriv &priv, dnswlp_list &dnswll, DNSWLP &acceptlist) {
897 for (dnswlp_list::iterator i=dnswll.begin(); i!=dnswll.end(); i++) {
898 DNSWLP dp = *i; // non null by construction
899 bool st;
900 map<DNSWLP, bool>::iterator f = priv.checked_white.find(dp);
901 if (f == priv.checked_white.end()) {
902 // have not checked this list yet
903 st = check_single(priv, priv.ip, *dp);
904 acceptlist = dp;
905 priv.checked_white[dp] = st;
906 }
907 else {
908 st = (*f).second;
909 acceptlist = (*f).first;
868 } 910 }
869 if (st) return st; 911 if (st) return st;
870 } 912 }
871 return false; 913 return false;
872 } 914 }
1115 // loto sending a reply back to priv.mailaddr 1157 // loto sending a reply back to priv.mailaddr
1116 CONTEXT &con2 = *(dc.find_context(priv.mailaddr)->find_context(loto)); 1158 CONTEXT &con2 = *(dc.find_context(priv.mailaddr)->find_context(loto));
1117 const char *replyvalue = con2.find_from(loto); 1159 const char *replyvalue = con2.find_from(loto);
1118 if (debug_syslog > 1) { 1160 if (debug_syslog > 1) {
1119 char buf[maxlen]; 1161 char buf[maxlen];
1162 char buf2[maxlen];
1120 char msg[maxlen]; 1163 char msg[maxlen];
1121 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); 1164 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);
1122 my_syslog(&priv, msg); 1165 my_syslog(&priv, msg);
1123 } 1166 }
1124 free((void*)loto); 1167 free((void*)loto);
1125 status st; 1168 status st;
1126 if (replyvalue == token_black) { 1169 if (replyvalue == token_black) {
1146 } 1189 }
1147 else if ((fromvalue == token_white) && !self) { 1190 else if ((fromvalue == token_white) && !self) {
1148 st = white; 1191 st = white;
1149 } 1192 }
1150 else { 1193 else {
1151 // check the dns based lists 1194 // check the dns based lists, whitelist first
1152 st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? reject : oksofar; 1195 DNSWLP acceptlist = NULL; // list that caused the whitelisting
1196 if (check_dnswl(priv, con.get_dnswl_list(), acceptlist)) {
1197 st = white;
1198 if (debug_syslog > 1) {
1199 char msg[maxlen];
1200 snprintf(msg, sizeof(msg), "whitelisted by %s", acceptlist->name);
1201 my_syslog(&priv, msg);
1202 }
1203 }
1204 else if (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) {
1205 st = reject;
1206 }
1207 else {
1208 st = oksofar;
1209 }
1153 } 1210 }
1154 if (st == reject) { 1211 if (st == reject) {
1155 // reject the recipient based on some dnsbl 1212 // reject the recipient based on some dnsbl
1156 char adr[sizeof "255.255.255.255 "]; 1213 char adr[sizeof "255.255.255.255 "];
1157 adr[0] = '\0'; 1214 adr[0] = '\0';