comparison src/dnsbl.cpp @ 178:d6531c702be3

embedded dcc filtering
author carl
date Thu, 04 Oct 2007 22:45:21 -0700
parents a4d313c2460b
children 8b86a894514d
comparison
equal deleted inserted replaced
177:a4d313c2460b 178:d6531c702be3
253 authenticated = NULL; 253 authenticated = NULL;
254 client_name = NULL; 254 client_name = NULL;
255 have_whites = false; 255 have_whites = false;
256 only_whites = true; 256 only_whites = true;
257 want_spamassassin = false; 257 want_spamassassin = false;
258 want_dccgrey = false;
259 want_dccbulk = false;
260 content_context = NULL;
258 memory = NULL; 261 memory = NULL;
259 scanner = NULL; 262 scanner = NULL;
260 assassin = NULL;
261 content_suffix = NULL; 263 content_suffix = NULL;
262 content_message = NULL; 264 content_message = NULL;
263 uribl_suffix = NULL; 265 uribl_suffix = NULL;
264 uribl_message = NULL; 266 uribl_message = NULL;
265 content_host_ignore = NULL; 267 content_host_ignore = NULL;
268 assassin = NULL;
269 dccifd = NULL;
266 } 270 }
267 271
268 mlfiPriv::~mlfiPriv() { 272 mlfiPriv::~mlfiPriv() {
269 return_fd(); 273 return_fd();
270 pthread_mutex_lock(&config_mutex); 274 pthread_mutex_lock(&config_mutex);
283 if (client_name) free(client_name); 287 if (client_name) free(client_name);
284 discard(env_to); 288 discard(env_to);
285 if (memory) delete memory; 289 if (memory) delete memory;
286 if (scanner) delete scanner; 290 if (scanner) delete scanner;
287 if (assassin) delete assassin; 291 if (assassin) delete assassin;
292 if (dccifd) delete dccifd;
288 if (!final) { 293 if (!final) {
289 mailaddr = NULL; 294 mailaddr = NULL;
290 queueid = NULL; 295 queueid = NULL;
291 authenticated = NULL; 296 authenticated = NULL;
292 client_name = NULL; 297 client_name = NULL;
293 have_whites = false; 298 have_whites = false;
294 only_whites = true; 299 only_whites = true;
295 want_spamassassin = false; 300 want_spamassassin = false;
301 want_dccgrey = false;
302 want_dccbulk = false;
303 content_context = NULL;
296 memory = NULL; 304 memory = NULL;
297 scanner = NULL; 305 scanner = NULL;
298 assassin = NULL;
299 content_suffix = NULL; 306 content_suffix = NULL;
300 content_message = NULL; 307 content_message = NULL;
301 uribl_suffix = NULL; 308 uribl_suffix = NULL;
302 uribl_message = NULL; 309 uribl_message = NULL;
303 content_host_ignore = NULL; 310 content_host_ignore = NULL;
311 assassin = NULL;
312 dccifd = NULL;
304 } 313 }
305 } 314 }
306 315
307 void mlfiPriv::get_fd() { 316 void mlfiPriv::get_fd() {
308 err = true; 317 err = true;
402 } 411 }
403 412
404 void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) { 413 void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) {
405 register_string(env_to, rcpt, &con); 414 register_string(env_to, rcpt, &con);
406 if (!memory) { 415 if (!memory) {
407 // first recipient that needs content filtering sets all 416 // first recipient that needs content filtering sets
408 // the content filtering parameters 417 // some of the content filtering parameters
409 memory = new recorder(this, con.get_html_tags(), con.get_content_tlds(), con.get_content_cctlds()); 418 memory = new recorder(this, con.get_html_tags(), con.get_content_tlds(), con.get_content_cctlds());
410 scanner = new url_scanner(memory); 419 scanner = new url_scanner(memory);
411 content_suffix = con.get_content_suffix(); 420 content_suffix = con.get_content_suffix();
412 content_message = con.get_content_message(); 421 content_message = con.get_content_message();
413 uribl_suffix = con.get_uribl_suffix(); 422 uribl_suffix = con.get_uribl_suffix();
716 725
717 //////////////////////////////////////////////// 726 ////////////////////////////////////////////////
718 // lookup the domain name part of a hostname on the uribl 727 // lookup the domain name part of a hostname on the uribl
719 // 728 //
720 // if we find part of the hostname on the uribl, return 729 // if we find part of the hostname on the uribl, return
721 // true and point found to the part of the hostname that we found. 730 // true and point found to the part of the hostname that we found
731 // as a string registered in hosts.
722 // otherwise, return false and preserve the value of found. 732 // otherwise, return false and preserve the value of found.
723 // 733 //
724 bool uriblookup(mlfiPriv &priv ,char *hostname, char *top, char *&found) ; 734 bool uriblookup(mlfiPriv &priv, string_set &hosts, char *hostname, char *top, char *&found) ;
725 bool uriblookup(mlfiPriv &priv, char *hostname, char *top, char *&found) { 735 bool uriblookup(mlfiPriv &priv, string_set &hosts, char *hostname, char *top, char *&found) {
726 // top is pointer to '.' char at end of base domain, or null for ip address form 736 // top is pointer to '.' char at end of base domain, or null for ip address form
727 // so for hostname of www.fred.mydomain.co.uk 737 // so for hostname of www.fred.mydomain.co.uk
728 // top points to-----------------------^ 738 // top points to-----------------------^
729 // and we end up looking at only mydomain.co.uk, ignoring the www.fred stuff 739 // and we end up looking at only mydomain.co.uk, ignoring the www.fred stuff
730 char buf[maxlen]; 740 char buf[maxlen];
740 if (debug_syslog > 2) { 750 if (debug_syslog > 2) {
741 char tmp[maxlen]; 751 char tmp[maxlen];
742 snprintf(tmp, sizeof(tmp), "found %s on %s", hostname, priv.uribl_suffix); 752 snprintf(tmp, sizeof(tmp), "found %s on %s", hostname, priv.uribl_suffix);
743 my_syslog(tmp); 753 my_syslog(tmp);
744 } 754 }
745 found = hostname; 755 found = register_string(hosts, hostname);
746 return true; 756 return true;
747 } 757 }
748 return false; 758 return false;
749 } 759 }
750 760
755 // hostname MUST not have a trailing dot 765 // hostname MUST not have a trailing dot
756 // If tld, two level lookup. 766 // If tld, two level lookup.
757 // Else, look up three level domain. 767 // Else, look up three level domain.
758 // 768 //
759 // if we find part of the hostname on the uribl, return 769 // if we find part of the hostname on the uribl, return
760 // true and point found to the part of the hostname that we found. 770 // true and point found to the part of the hostname that we found
771 // as a string registered in hosts.
761 // otherwise, return false and preserve the value of found. 772 // otherwise, return false and preserve the value of found.
762 // 773 //
763 bool check_uribl(mlfiPriv &priv, char *hostname, char *&found) ; 774 bool check_uribl(mlfiPriv &priv, string_set &hosts, char *hostname, char *&found) ;
764 bool check_uribl(mlfiPriv &priv, char *hostname, char *&found) { 775 bool check_uribl(mlfiPriv &priv, string_set &hosts, char *hostname, char *&found) {
765 in_addr ip; 776 in_addr ip;
766 if (inet_aton(hostname, &ip)) { 777 if (inet_aton(hostname, &ip)) {
767 const u_char *src = (const u_char *)&ip.s_addr; 778 const u_char *src = (const u_char *)&ip.s_addr;
768 if (src[0] == 127) return false; // don't do dns lookups on localhost 779 if (src[0] == 127) return false; // don't do dns lookups on localhost
769 if (src[0] == 10) return false; // don't do dns lookups on rfc1918 space 780 if (src[0] == 10) return false; // don't do dns lookups on rfc1918 space
770 if ((src[0] == 192) && (src[1] == 168)) return false; 781 if ((src[0] == 192) && (src[1] == 168)) return false;
771 if ((src[0] == 172) && (16 <= src[1]) && (src[1] <= 31)) return false; 782 if ((src[0] == 172) && (16 <= src[1]) && (src[1] <= 31)) return false;
772 static char adr[sizeof "255.255.255.255"]; 783 char adr[sizeof "255.255.255.255 "];
773 snprintf(adr, sizeof(adr), "%u.%u.%u.%u", src[3], src[2], src[1], src[0]); 784 snprintf(adr, sizeof(adr), "%u.%u.%u.%u", src[3], src[2], src[1], src[0]);
774 return (uriblookup(priv, adr, NULL, found)); 785 return (uriblookup(priv, hosts, adr, NULL, found));
775 } 786 }
776 787
777 char *top, *top2, *top3; 788 char *top, *top2, *top3;
778 top = strrchr(hostname, '.'); 789 top = strrchr(hostname, '.');
779 if (top) { 790 if (top) {
783 794
784 if (top2) { 795 if (top2) {
785 string_set::iterator i = priv.memory->get_cctlds()->find(top2+1); 796 string_set::iterator i = priv.memory->get_cctlds()->find(top2+1);
786 string_set::iterator x = priv.memory->get_cctlds()->end(); 797 string_set::iterator x = priv.memory->get_cctlds()->end();
787 // if we have a 2-level-cctld, just look at top three levels of the name 798 // if we have a 2-level-cctld, just look at top three levels of the name
788 if (i != x) return uriblookup(priv, hostname, top2, found); 799 if (i != x) return uriblookup(priv, hosts, hostname, top2, found);
789 800
790 *top2 = '\0'; 801 *top2 = '\0';
791 top3 = strrchr(hostname, '.'); 802 top3 = strrchr(hostname, '.');
792 *top2 = '.'; 803 *top2 = '.';
793 804
794 // if we have more than 3 levels in the name, look at the top three levels of the name 805 // if we have more than 3 levels in the name, look at the top three levels of the name
795 if (top3 && uriblookup(priv, hostname, top2, found)) return true; 806 if (top3 && uriblookup(priv, hosts, hostname, top2, found)) return true;
796 // if that was not found, fall thru to looking at the top two levels 807 // if that was not found, fall thru to looking at the top two levels
797 } 808 }
798 // look at the top two levels of the name 809 // look at the top two levels of the name
799 return uriblookup(priv, hostname, top, found); 810 return uriblookup(priv, hosts, hostname, top, found);
800 } 811 }
801 return false; 812 return false;
802 } 813 }
803 814
804 815
840 count++; 851 count++;
841 ip = dns_interface(priv, host, true, &nameservers); 852 ip = dns_interface(priv, host, true, &nameservers);
842 if (debug_syslog > 2) { 853 if (debug_syslog > 2) {
843 char buf[maxlen]; 854 char buf[maxlen];
844 if (ip) { 855 if (ip) {
845 char adr[sizeof "255.255.255.255"]; 856 char adr[sizeof "255.255.255.255 "];
846 adr[0] = '\0'; 857 adr[0] = '\0';
847 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); 858 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr));
848 snprintf(buf, sizeof(buf), "host %s found at %s", host, adr); 859 snprintf(buf, sizeof(buf), "host %s found at %s", host, adr);
849 } 860 }
850 else { 861 else {
861 if (priv.content_suffix && check_single(priv, ip, priv.content_suffix)) { 872 if (priv.content_suffix && check_single(priv, ip, priv.content_suffix)) {
862 msg = priv.content_message; 873 msg = priv.content_message;
863 return true; 874 return true;
864 } 875 }
865 // Check uribl & surbl style list 876 // Check uribl & surbl style list
866 if (priv.uribl_suffix && check_uribl(priv, host, found)) { 877 if (priv.uribl_suffix && check_uribl(priv, hosts, host, found)) {
867 msg = priv.uribl_message; 878 msg = priv.uribl_message;
868 return true; 879 return true;
869 } 880 }
870 } 881 }
871 } 882 }
878 ip = (*i).second; 889 ip = (*i).second;
879 if (!ip) ip = dns_interface(priv, host, false, NULL); 890 if (!ip) ip = dns_interface(priv, host, false, NULL);
880 if (debug_syslog > 2) { 891 if (debug_syslog > 2) {
881 char buf[maxlen]; 892 char buf[maxlen];
882 if (ip) { 893 if (ip) {
883 char adr[sizeof "255.255.255.255"]; 894 char adr[sizeof "255.255.255.255 "];
884 adr[0] = '\0'; 895 adr[0] = '\0';
885 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); 896 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr));
886 snprintf(buf, sizeof(buf), "ns %s found at %s", host, adr); 897 snprintf(buf, sizeof(buf), "ns %s found at %s", host, adr);
887 } 898 }
888 else { 899 else {
974 if (priv.authenticated) priv.authenticated = strdup(priv.authenticated); 985 if (priv.authenticated) priv.authenticated = strdup(priv.authenticated);
975 if (priv.client_name) priv.client_name = strdup(priv.client_name); 986 if (priv.client_name) priv.client_name = strdup(priv.client_name);
976 if (spamc != spamc_empty) { 987 if (spamc != spamc_empty) {
977 priv.assassin = new SpamAssassin(&priv, priv.ip, priv.helo, priv.mailaddr, priv.queueid); 988 priv.assassin = new SpamAssassin(&priv, priv.ip, priv.helo, priv.mailaddr, priv.queueid);
978 } 989 }
990 if (dccifd_port) {
991 priv.dccifd = new DccInterface(dccifd_port, &priv, priv.ip, priv.helo, priv.mailaddr, priv.queueid);
992 }
979 return SMFIS_CONTINUE; 993 return SMFIS_CONTINUE;
980 } 994 }
981 995
982 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt) 996 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt)
983 { 997 {
992 smfi_setreply(ctx, "550", "5.7.1", "bogus recipient"); 1006 smfi_setreply(ctx, "550", "5.7.1", "bogus recipient");
993 return SMFIS_REJECT; 1007 return SMFIS_REJECT;
994 } 1008 }
995 1009
996 if (priv.assassin) priv.assassin->mlfi_envrcpt(ctx, loto); 1010 if (priv.assassin) priv.assassin->mlfi_envrcpt(ctx, loto);
1011 if (priv.dccifd) priv.dccifd->mlfi_envrcpt(loto);
997 // priv.mailaddr sending original message to loto 1012 // priv.mailaddr sending original message to loto
998 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr)); 1013 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr));
999 VERIFYP ver = con.find_verify(loto); 1014 VERIFYP ver = con.find_verify(loto);
1000 char *fromvalue = con.find_from(priv.mailaddr, true); 1015 char *fromvalue = con.find_from(priv.mailaddr, true);
1001 // loto sending a reply back to priv.mailaddr 1016 // loto sending a reply back to priv.mailaddr
1038 // check the dns based lists 1053 // check the dns based lists
1039 st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? reject : oksofar; 1054 st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? reject : oksofar;
1040 } 1055 }
1041 if (st == reject) { 1056 if (st == reject) {
1042 // reject the recipient based on some dnsbl 1057 // reject the recipient based on some dnsbl
1043 char adr[sizeof "255.255.255.255"]; 1058 char adr[sizeof "255.255.255.255 "];
1044 adr[0] = '\0'; 1059 adr[0] = '\0';
1045 inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr)); 1060 inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr));
1046 char buf[maxlen]; 1061 char buf[maxlen];
1047 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr); 1062 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr);
1048 smfi_setreply(ctx, "550", "5.7.1", buf); 1063 smfi_setreply(ctx, "550", "5.7.1", buf);
1087 w->sent(loto); // don't free it, the whitelister takes ownership of the string 1102 w->sent(loto); // don't free it, the whitelister takes ownership of the string
1088 } 1103 }
1089 else { 1104 else {
1090 free(loto); 1105 free(loto);
1091 } 1106 }
1107 // remember first content filtering context
1108 if (con.get_content_filtering()) {
1109 if (!priv.content_context) priv.content_context = &con;
1110 else if (con.get_require() && (priv.content_context != &con)) {
1111 smfi_setreply(ctx, "452", "4.2.1", "incompatible filtering contexts");
1112 return SMFIS_TEMPFAIL;
1113 }
1114 }
1092 // accept the recipient 1115 // accept the recipient
1093 if (!con.get_content_filtering()) st = white; 1116 if (!con.get_content_filtering()) st = white;
1094 if (st == oksofar) { 1117 if (st == oksofar) {
1095 // but remember the non-whites 1118 // but remember the non-whites
1096 priv.need_content_filter(rcptaddr, con); 1119 priv.need_content_filter(rcptaddr, con);
1097 priv.only_whites = false; 1120 priv.only_whites = false;
1098 priv.want_spamassassin |= (priv.assassin) && // have spam assassin available and 1121 priv.want_spamassassin |= (priv.assassin) && // have spam assassin available and
1099 (con.get_spamassassin_limit() != 0); // want to use it with a non-zero score 1122 (con.get_spamassassin_limit() != 0); // want to use it with a non-zero score
1123 priv.want_dccgrey |= (priv.dccifd) && // have dcc interface and
1124 (con.get_grey()); // want to use it for greylisting
1125 priv.want_dccbulk |= (priv.dccifd) && // have dcc interface and
1126 (con.get_bulk() != 0); // want to use it for bulk detection
1100 } 1127 }
1101 if (st == white) { 1128 if (st == white) {
1102 priv.have_whites = true; 1129 priv.have_whites = true;
1103 } 1130 }
1104 return SMFIS_CONTINUE; 1131 return SMFIS_CONTINUE;
1108 { 1135 {
1109 mlfiPriv &priv = *MLFIPRIV; 1136 mlfiPriv &priv = *MLFIPRIV;
1110 if (priv.authenticated) return SMFIS_CONTINUE; 1137 if (priv.authenticated) return SMFIS_CONTINUE;
1111 if (priv.only_whites) return SMFIS_CONTINUE; 1138 if (priv.only_whites) return SMFIS_CONTINUE;
1112 if (priv.want_spamassassin) priv.assassin->mlfi_header(headerf, headerv); 1139 if (priv.want_spamassassin) priv.assassin->mlfi_header(headerf, headerv);
1140 if (priv.want_dccgrey || priv.want_dccbulk) priv.dccifd->mlfi_header(ctx, headerf, headerv);
1113 return SMFIS_CONTINUE; 1141 return SMFIS_CONTINUE;
1114 } 1142 }
1115 1143
1116 sfsistat mlfi_eoh(SMFICTX* ctx) 1144 sfsistat mlfi_eoh(SMFICTX* ctx)
1117 { 1145 {
1118 mlfiPriv &priv = *MLFIPRIV; 1146 mlfiPriv &priv = *MLFIPRIV;
1119 if (priv.authenticated) return SMFIS_CONTINUE; 1147 if (priv.authenticated) return SMFIS_CONTINUE;
1120 if (priv.only_whites) return SMFIS_CONTINUE; 1148 if (priv.only_whites) return SMFIS_CONTINUE;
1121 if (priv.want_spamassassin) priv.assassin->mlfi_eoh(); 1149 if (priv.want_spamassassin) priv.assassin->mlfi_eoh();
1150 if (priv.want_dccgrey || priv.want_dccbulk) priv.dccifd->mlfi_eoh();
1122 return SMFIS_CONTINUE; 1151 return SMFIS_CONTINUE;
1123 } 1152 }
1124 1153
1125 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) 1154 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len)
1126 { 1155 {
1127 mlfiPriv &priv = *MLFIPRIV; 1156 mlfiPriv &priv = *MLFIPRIV;
1128 if (priv.authenticated) return SMFIS_CONTINUE; 1157 if (priv.authenticated) return SMFIS_CONTINUE;
1129 if (priv.only_whites) return SMFIS_CONTINUE; 1158 if (priv.only_whites) return SMFIS_CONTINUE;
1130 if (priv.want_spamassassin) priv.assassin->mlfi_body(data, len); 1159 if (priv.want_spamassassin) priv.assassin->mlfi_body(data, len);
1160 if (priv.want_dccgrey || priv.want_dccbulk) priv.dccifd->mlfi_body(data, len);
1131 priv.scanner->scan(data, len); 1161 priv.scanner->scan(data, len);
1132 return SMFIS_CONTINUE; 1162 return SMFIS_CONTINUE;
1133 } 1163 }
1134 1164
1135 sfsistat mlfi_eom(SMFICTX *ctx) 1165 sfsistat mlfi_eom(SMFICTX *ctx)
1141 int ip; 1171 int ip;
1142 status st; 1172 status st;
1143 // process end of message 1173 // process end of message
1144 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE; 1174 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE;
1145 else { 1175 else {
1176 // assert env_to not empty, it contains the
1177 // non-whitelisted folks that want content filtering
1146 int score = (priv.want_spamassassin) ? priv.assassin->mlfi_eom() : 0; 1178 int score = (priv.want_spamassassin) ? priv.assassin->mlfi_eom() : 0;
1147 // assert env_to not empty 1179 bool greylist = false;
1148 char buf[maxlen]; 1180 int dccbulk = 0;
1149 string msg; 1181 if (priv.want_dccgrey || priv.want_dccbulk) priv.dccifd->mlfi_eom(greylist, dccbulk);
1150 string_set alive; 1182
1151 bool random = false; 1183 if (priv.want_dccgrey && greylist) {
1152 int limit = 0; 1184 smfi_setreply(ctx, "452", "4.2.1", "temporary greylist embargoed");
1153 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) { 1185 rc = SMFIS_TEMPFAIL;
1154 char *rcpt = (*i).first; 1186 }
1155 CONTEXT &con = *((*i).second); 1187 else {
1156 if (!con.acceptable_content(*priv.memory, score, msg)) { 1188 char buf[maxlen];
1157 // bad html tags or excessive hosts or high spam assassin score 1189 string msg;
1158 smfi_delrcpt(ctx, rcpt); 1190 string_set alive;
1191 bool random = false;
1192 int limit = 0;
1193 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) {
1194 char *rcpt = (*i).first;
1195 CONTEXT &con = *((*i).second);
1196 if (!con.acceptable_content(*priv.memory, score, dccbulk, msg)) {
1197 // bad html tags or excessive hosts or
1198 // high spam assassin score or dcc bulk threshold exceedeed
1199 smfi_delrcpt(ctx, rcpt);
1200 }
1201 else {
1202 alive.insert(rcpt);
1203 random |= con.get_host_random();
1204 limit = max(limit, con.get_host_limit());
1205 }
1206 }
1207 bool rejecting = alive.empty(); // if alive is empty, we must have set msg above in acceptable_content()
1208 if (!rejecting) {
1209 char *fmt, *found;
1210 if (check_hosts(priv, random, limit, fmt, host, ip, found)) {
1211 if (found) {
1212 // uribl style
1213 snprintf(buf, sizeof(buf), fmt, host, found);
1214 }
1215 else {
1216 // dnsbl style
1217 char adr[sizeof "255.255.255.255 "];
1218 adr[0] = '\0';
1219 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr));
1220 snprintf(buf, sizeof(buf), fmt, host, adr);
1221 }
1222 msg = string(buf);
1223 rejecting = true;
1224 }
1225 }
1226 if (!rejecting) {
1227 rc = SMFIS_CONTINUE;
1228 }
1229 else if (!priv.have_whites) {
1230 // can reject the entire message
1231 snprintf(buf, sizeof(buf), "%s", msg.c_str());
1232 smfi_setreply(ctx, "550", "5.7.1", buf);
1233 rc = SMFIS_REJECT;
1159 } 1234 }
1160 else { 1235 else {
1161 alive.insert(rcpt); 1236 // need to accept it but remove the recipients that don't want it
1162 random |= con.get_host_random(); 1237 for (string_set::iterator i=alive.begin(); i!=alive.end(); i++) {
1163 limit = max(limit, con.get_host_limit()); 1238 char *rcpt = *i;
1164 } 1239 smfi_delrcpt(ctx, rcpt);
1165 } 1240 }
1166 bool rejecting = alive.empty(); // if alive is empty, we must have set msg above in acceptable_content() 1241 rc = SMFIS_CONTINUE;
1167 if (!rejecting) { 1242 }
1168 char *fmt, *found;
1169 if (check_hosts(priv, random, limit, fmt, host, ip, found)) {
1170 if (found) {
1171 // uribl style
1172 snprintf(buf, sizeof(buf), fmt, host, found);
1173 }
1174 else {
1175 // dnsbl style
1176 char adr[sizeof "255.255.255.255"];
1177 adr[0] = '\0';
1178 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr));
1179 snprintf(buf, sizeof(buf), fmt, host, adr);
1180 }
1181 msg = string(buf);
1182 rejecting = true;
1183 }
1184 }
1185 if (!rejecting) {
1186 rc = SMFIS_CONTINUE;
1187 }
1188 else if (!priv.have_whites) {
1189 // can reject the entire message
1190 snprintf(buf, sizeof(buf), "%s", msg.c_str());
1191 smfi_setreply(ctx, "550", "5.7.1", buf);
1192 rc = SMFIS_REJECT;
1193 }
1194 else {
1195 // need to accept it but remove the recipients that don't want it
1196 for (string_set::iterator i=alive.begin(); i!=alive.end(); i++) {
1197 char *rcpt = *i;
1198 smfi_delrcpt(ctx, rcpt);
1199 }
1200 rc = SMFIS_CONTINUE;
1201 } 1243 }
1202 } 1244 }
1203 // reset for a new message on the same connection 1245 // reset for a new message on the same connection
1204 mlfi_abort(ctx); 1246 mlfi_abort(ctx);
1205 return rc; 1247 return rc;