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