comparison src/dnsbl.cpp @ 163:97d7da45fe2a

spamassassin changes
author carl
date Sun, 26 Aug 2007 19:03:17 -0700
parents c4bce911c276
children 5809bcdc325b
comparison
equal deleted inserted replaced
162:c4bce911c276 163:97d7da45fe2a
11 -p port The port through which the MTA will connect to this milter. 11 -p port The port through which the MTA will connect to this milter.
12 -t sec The timeout value. 12 -t sec The timeout value.
13 -c Check the config, and print a copy to stdout. Don't start the 13 -c Check the config, and print a copy to stdout. Don't start the
14 milter or do anything with the socket. 14 milter or do anything with the socket.
15 -s Stress test by loading and deleting the current config in a loop. 15 -s Stress test by loading and deleting the current config in a loop.
16 -d increase debug level 16 -d level set the debug level
17 -e f|t Print the results of looking up from address f and to address 17 -e f|t Print the results of looking up from address f and to address
18 t in the current config 18 t in the current config
19 19
20 */ 20 */
21 21
63 63
64 64
65 extern "C" { 65 extern "C" {
66 #include <libmilter/mfapi.h> 66 #include <libmilter/mfapi.h>
67 sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr); 67 sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr);
68 sfsistat mlfi_helo(SMFICTX * ctx, char *helohost);
68 sfsistat mlfi_envfrom(SMFICTX *ctx, char **argv); 69 sfsistat mlfi_envfrom(SMFICTX *ctx, char **argv);
69 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **argv); 70 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **argv);
71 sfsistat mlfi_header(SMFICTX* ctx, char* headerf, char* headerv);
70 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len); 72 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len);
71 sfsistat mlfi_eom(SMFICTX *ctx); 73 sfsistat mlfi_eom(SMFICTX *ctx);
72 sfsistat mlfi_abort(SMFICTX *ctx); 74 sfsistat mlfi_abort(SMFICTX *ctx);
73 sfsistat mlfi_close(SMFICTX *ctx); 75 sfsistat mlfi_close(SMFICTX *ctx);
74 void sig_chld(int signo); 76 void sig_chld(int signo);
241 pc = config; 243 pc = config;
242 pc->reference_count++; 244 pc->reference_count++;
243 pthread_mutex_unlock(&config_mutex); 245 pthread_mutex_unlock(&config_mutex);
244 get_fd(); 246 get_fd();
245 ip = 0; 247 ip = 0;
248 helo = NULL;
246 mailaddr = NULL; 249 mailaddr = NULL;
247 queueid = NULL; 250 queueid = NULL;
248 authenticated = NULL; 251 authenticated = NULL;
249 have_whites = false; 252 have_whites = false;
250 only_whites = true; 253 only_whites = true;
262 pthread_mutex_lock(&config_mutex); 265 pthread_mutex_lock(&config_mutex);
263 pc->reference_count--; 266 pc->reference_count--;
264 bool last = (!pc->reference_count) && (pc != config); 267 bool last = (!pc->reference_count) && (pc != config);
265 pthread_mutex_unlock(&config_mutex); 268 pthread_mutex_unlock(&config_mutex);
266 if (last) delete pc; // free this config, since we were the last reference to it 269 if (last) delete pc; // free this config, since we were the last reference to it
270 if (helo) free(helo);
267 reset(true); 271 reset(true);
268 } 272 }
269 273
270 void mlfiPriv::reset(bool final) { 274 void mlfiPriv::reset(bool final) {
271 if (mailaddr) free(mailaddr); 275 if (mailaddr) free(mailaddr);
272 if (queueid) free(queueid); 276 if (queueid) free(queueid);
273 if (authenticated) free(authenticated); 277 if (authenticated) free(authenticated);
274 discard(env_to); 278 discard(env_to);
275 if (memory) delete memory; 279 if (memory) delete memory;
276 if (scanner) delete scanner; 280 if (scanner) delete scanner;
281 if (assassin) delete assassin;
277 if (!final) { 282 if (!final) {
278 mailaddr = NULL; 283 mailaddr = NULL;
279 queueid = NULL; 284 queueid = NULL;
280 authenticated = NULL; 285 authenticated = NULL;
281 have_whites = false; 286 have_whites = false;
282 only_whites = true; 287 only_whites = true;
283 memory = NULL; 288 memory = NULL;
284 scanner = NULL; 289 scanner = NULL;
290 assassin = NULL;
285 content_suffix = NULL; 291 content_suffix = NULL;
286 content_message = NULL; 292 content_message = NULL;
287 uribl_suffix = NULL; 293 uribl_suffix = NULL;
288 uribl_message = NULL; 294 uribl_message = NULL;
289 content_host_ignore = NULL; 295 content_host_ignore = NULL;
423 syslog(LOG_NOTICE, "%s", text); 429 syslog(LOG_NOTICE, "%s", text);
424 pthread_mutex_unlock(&syslog_mutex); 430 pthread_mutex_unlock(&syslog_mutex);
425 } 431 }
426 else { 432 else {
427 printf("%s \n", text); 433 printf("%s \n", text);
434 }
435 }
436
437 void my_syslog(mlfiPriv *priv, string text) {
438 if (debug_syslog > 3) {
439 char buf[maxlen];
440 strncpy(buf, text.c_str(), sizeof(buf));
441 buf[maxlen-1] = '\0'; // ensure null termination
442 my_syslog(priv, buf);
428 } 443 }
429 } 444 }
430 445
431 void my_syslog(char *text) { 446 void my_syslog(char *text) {
432 my_syslog(NULL, text); 447 my_syslog(NULL, text);
925 // allocate some private memory 940 // allocate some private memory
926 mlfiPriv *priv = new mlfiPriv; 941 mlfiPriv *priv = new mlfiPriv;
927 if (hostaddr->sa_family == AF_INET) { 942 if (hostaddr->sa_family == AF_INET) {
928 priv->ip = ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr; 943 priv->ip = ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr;
929 } 944 }
930
931 // save the private data 945 // save the private data
932 smfi_setpriv(ctx, (void*)priv); 946 smfi_setpriv(ctx, (void*)priv);
933 947
934 // continue processing 948 // continue processing
949 return SMFIS_CONTINUE;
950 }
951
952 sfsistat mlfi_helo(SMFICTX * ctx, char *helohost)
953 {
954 mlfiPriv &priv = *MLFIPRIV;
955 priv.helo = strdup(helohost);
935 return SMFIS_CONTINUE; 956 return SMFIS_CONTINUE;
936 } 957 }
937 958
938 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from) 959 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from)
939 { 960 {
940 mlfiPriv &priv = *MLFIPRIV; 961 mlfiPriv &priv = *MLFIPRIV;
941 priv.mailaddr = to_lower_string(from[0]); 962 priv.mailaddr = to_lower_string(from[0]);
963 priv.queueid = strdup(smfi_getsymval(ctx, "i"));
942 priv.authenticated = smfi_getsymval(ctx, "{auth_authen}"); 964 priv.authenticated = smfi_getsymval(ctx, "{auth_authen}");
943 if (priv.authenticated) priv.authenticated = strdup(priv.authenticated); 965 if (priv.authenticated) priv.authenticated = strdup(priv.authenticated);
966 priv.assassin = new SpamAssassin;
967 priv.assassin->mlfi_connect(&priv, priv.ip);
968 priv.assassin->mlfi_helo(priv.helo);
969 priv.assassin->mlfi_envfrom(priv.mailaddr, priv.queueid);
944 return SMFIS_CONTINUE; 970 return SMFIS_CONTINUE;
945 } 971 }
946 972
947 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt) 973 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt)
948 { 974 {
949 DNSBLP rejectlist = NULL; // list that caused the reject 975 DNSBLP rejectlist = NULL; // list that caused the reject
950 mlfiPriv &priv = *MLFIPRIV; 976 mlfiPriv &priv = *MLFIPRIV;
951 CONFIG &dc = *priv.pc; 977 CONFIG &dc = *priv.pc;
952 if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i"));
953 char *rcptaddr = rcpt[0]; 978 char *rcptaddr = rcpt[0];
954 char *loto = to_lower_string(rcptaddr); 979 char *loto = to_lower_string(rcptaddr);
980 priv.assassin->mlfi_envrcpt(ctx, loto);
955 // priv.mailaddr sending original message to loto 981 // priv.mailaddr sending original message to loto
956 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr)); 982 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr));
957 VERIFYP ver = con.find_verify(loto); 983 VERIFYP ver = con.find_verify(loto);
958 char *fromvalue = con.find_from(priv.mailaddr); 984 char *fromvalue = con.find_from(priv.mailaddr);
959 // loto sending a reply back to priv.mailaddr 985 // loto sending a reply back to priv.mailaddr
1048 priv.have_whites = true; 1074 priv.have_whites = true;
1049 } 1075 }
1050 return SMFIS_CONTINUE; 1076 return SMFIS_CONTINUE;
1051 } 1077 }
1052 1078
1079 sfsistat mlfi_header(SMFICTX* ctx, char* headerf, char* headerv)
1080 {
1081 mlfiPriv &priv = *MLFIPRIV;
1082 if (priv.authenticated) return SMFIS_CONTINUE;
1083 if (priv.only_whites) return SMFIS_CONTINUE;
1084 priv.assassin->mlfi_header(headerf, headerv);
1085 return SMFIS_CONTINUE;
1086 }
1087
1088 sfsistat mlfi_eoh(SMFICTX* ctx)
1089 {
1090 mlfiPriv &priv = *MLFIPRIV;
1091 if (priv.authenticated) return SMFIS_CONTINUE;
1092 if (priv.only_whites) return SMFIS_CONTINUE;
1093 priv.assassin->mlfi_eoh();
1094 return SMFIS_CONTINUE;
1095 }
1096
1053 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) 1097 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len)
1054 { 1098 {
1055 mlfiPriv &priv = *MLFIPRIV; 1099 mlfiPriv &priv = *MLFIPRIV;
1056 if (priv.authenticated) return SMFIS_CONTINUE; 1100 if (priv.authenticated) return SMFIS_CONTINUE;
1057 if (priv.only_whites) return SMFIS_CONTINUE; 1101 if (priv.only_whites) return SMFIS_CONTINUE;
1102 priv.assassin->mlfi_body(data, len);
1058 priv.scanner->scan(data, len); 1103 priv.scanner->scan(data, len);
1059 return SMFIS_CONTINUE; 1104 return SMFIS_CONTINUE;
1060 } 1105 }
1061 1106
1062 sfsistat mlfi_eom(SMFICTX *ctx) 1107 sfsistat mlfi_eom(SMFICTX *ctx)
1068 int ip; 1113 int ip;
1069 status st; 1114 status st;
1070 // process end of message 1115 // process end of message
1071 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE; 1116 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE;
1072 else { 1117 else {
1118 int score = priv.assassin->mlfi_eom();
1073 // assert env_to not empty 1119 // assert env_to not empty
1074 char buf[maxlen]; 1120 char buf[maxlen];
1075 char *msg = NULL; 1121 char *msg = NULL;
1076 string_set alive; 1122 string_set alive;
1077 bool random = false; 1123 bool random = false;
1078 int limit = 0; 1124 int limit = 0;
1079 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) { 1125 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) {
1080 char *rcpt = (*i).first; 1126 char *rcpt = (*i).first;
1081 CONTEXT &con = *((*i).second); 1127 CONTEXT &con = *((*i).second);
1082 if (!con.acceptable_content(*priv.memory, msg)) { 1128 if (!con.acceptable_content(*priv.memory, score, msg)) {
1083 // bad html tags or excessive hosts 1129 // bad html tags or excessive hosts or high spam assassin score
1084 smfi_delrcpt(ctx, rcpt); 1130 smfi_delrcpt(ctx, rcpt);
1085 } 1131 }
1086 else { 1132 else {
1087 alive.insert(rcpt); 1133 alive.insert(rcpt);
1088 random |= con.get_host_random(); 1134 random |= con.get_host_random();
1150 { 1196 {
1151 "DNSBL", // filter name 1197 "DNSBL", // filter name
1152 SMFI_VERSION, // version code -- do not change 1198 SMFI_VERSION, // version code -- do not change
1153 SMFIF_DELRCPT, // flags 1199 SMFIF_DELRCPT, // flags
1154 mlfi_connect, // connection info filter 1200 mlfi_connect, // connection info filter
1155 NULL, // SMTP HELO command filter 1201 mlfi_helo, // SMTP HELO command filter
1156 mlfi_envfrom, // envelope sender filter 1202 mlfi_envfrom, // envelope sender filter
1157 mlfi_envrcpt, // envelope recipient filter 1203 mlfi_envrcpt, // envelope recipient filter
1158 NULL, // header filter 1204 mlfi_header, // header filter
1159 NULL, // end of header 1205 mlfi_eoh, // end of header
1160 mlfi_body, // body block filter 1206 mlfi_body, // body block filter
1161 mlfi_eom, // end of message 1207 mlfi_eom, // end of message
1162 mlfi_abort, // message aborted 1208 mlfi_abort, // message aborted
1163 mlfi_close, // connection cleanup 1209 mlfi_close, // connection cleanup
1164 }; 1210 };
1190 //////////////////////////////////////////////// 1236 ////////////////////////////////////////////////
1191 // thread to watch the old config files for changes 1237 // thread to watch the old config files for changes
1192 // and reload when needed. 1238 // and reload when needed.
1193 // we also clear the SMTP AUTH recipient counts hourly 1239 // we also clear the SMTP AUTH recipient counts hourly
1194 // 1240 //
1195 void* config_loader(void *arg); 1241 extern "C" {void* config_loader(void *arg);}
1196 void* config_loader(void *arg) { 1242 void* config_loader(void *arg) {
1197 int loop = 0; 1243 int loop = 0;
1198 typedef set<CONFIG *> configp_set;
1199 while (loader_run) { 1244 while (loader_run) {
1200 sleep(180); // look for modifications every 3 minutes 1245 sleep(180); // look for modifications every 3 minutes
1201 if (!loader_run) break; 1246 if (!loader_run) break;
1202 loop++; 1247 loop++;
1203 if (loop == 20) { 1248 if (loop == 20) {
1227 pthread_mutex_lock(&config_mutex); 1272 pthread_mutex_lock(&config_mutex);
1228 CONFIG *pc = config; 1273 CONFIG *pc = config;
1229 bool last = pc && (!pc->reference_count); 1274 bool last = pc && (!pc->reference_count);
1230 config = newc; 1275 config = newc;
1231 pthread_mutex_unlock(&config_mutex); 1276 pthread_mutex_unlock(&config_mutex);
1232 if (last) delete pc; // there were no references to this config 1277 if (last) delete pc; // there were no references to this config
1233 } 1278 }
1234 else { 1279 else {
1235 // failed to load new config 1280 // failed to load new config
1236 my_syslog("failed to load new configuration"); 1281 my_syslog("failed to load new configuration");
1237 system("echo 'failed to load new dnsbl configuration from /etc/dnsbl' | mail -s 'error in /etc/dnsbl configuration' root"); 1282 system("echo 'failed to load new dnsbl configuration from /etc/dnsbl' | mail -s 'error in /etc/dnsbl configuration' root");
1266 1311
1267 1312
1268 void setup_socket(char *sock); 1313 void setup_socket(char *sock);
1269 void setup_socket(char *sock) { 1314 void setup_socket(char *sock) {
1270 unlink(sock); 1315 unlink(sock);
1271 // sockaddr_un addr;
1272 // memset(&addr, '\0', sizeof addr);
1273 // addr.sun_family = AF_UNIX;
1274 // strncpy(addr.sun_path, sock, sizeof(addr.sun_path)-1);
1275 // int s = socket(AF_UNIX, SOCK_STREAM, 0);
1276 // bind(s, (sockaddr*)&addr, sizeof(addr));
1277 // close(s);
1278 } 1316 }
1279 1317
1280 1318
1281 /* 1319 /*
1282 * The signal handler function -- only gets called when a SIGCHLD 1320 * The signal handler function -- only gets called when a SIGCHLD