Mercurial > dnsbl
diff src/dnsbl.cpp @ 76:81f1e400e8ab
start coding on new config syntax
author | carl |
---|---|
date | Sat, 16 Jul 2005 13:47:19 -0700 |
parents | 1142e46be550 |
children | 8487650c98ee |
line wrap: on
line diff
--- a/src/dnsbl.cpp Wed Jul 13 23:04:14 2005 -0700 +++ b/src/dnsbl.cpp Sat Jul 16 13:47:19 2005 -0700 @@ -12,23 +12,15 @@ -t sec The timeout value. -c Check the config, and print a copy to stdout. Don't start the milter or do anything with the socket. +-s Stress test by loading and deleting the current config in a loop. -d Add debug syslog entries +-e f|t Print the results of looking up from address f and to address + t in the current config TODO: -1) Add config for max_recipients for each mail domain. Recipients in -excess of that limit will be rejected, and the entire data will be -rejected if it is sent. -2) Add config for poison addresses. If any recipient is poison, all -recipients are rejected even if they would be whitelisted, and the -data is rejected if sent. - -3) Add option to only allow one recipient if the return path is empty. - -4) Check if the envelope from domain name primary MX points 127.0.0.0/8 - -5) Add option for using smtp connections to verify addresses from backup +1) Add option for using smtp connections to verify addresses from backup mx machines. This allows the backup mx to learn the valid addresses on the primary machine. @@ -95,6 +87,7 @@ bool loader_run = true; // used to stop the config loader thread CONFIG * config = NULL; // protected by the config_mutex int generation = 0; // protected by the config_mutex +const int maxlen = 1000; // used for snprintf buffers pthread_mutex_t config_mutex; pthread_mutex_t syslog_mutex; @@ -163,6 +156,7 @@ char *x = (*i).first; free(x); } + cm.clear(); } @@ -241,8 +235,11 @@ authenticated = false; have_whites = false; only_whites = true; - memory = new recorder(this, pc->get_html_tags(), pc->get_content_tlds()); - scanner = new url_scanner(memory); + memory = NULL; + scanner = NULL; + content_suffix = NULL; + content_message = NULL; + content_host_ignore = NULL; } mlfiPriv::~mlfiPriv() { @@ -254,20 +251,25 @@ } void mlfiPriv::reset(bool final) { + if (debug_syslog) my_syslog(this, "mlfiPriv::reset"); if (mailaddr) free(mailaddr); if (queueid) free(queueid); discard(env_to); - delete memory; - delete scanner; + if (memory) delete memory; + if (scanner) delete scanner; if (!final) { mailaddr = NULL; queueid = NULL; authenticated = false; have_whites = false; only_whites = true; - memory = new recorder(this, pc->get_html_tags(), pc->get_content_tlds()); - scanner = new url_scanner(memory); + memory = NULL; + scanner = NULL; + content_suffix = NULL; + content_message = NULL; + content_host_ignore = NULL; } + if (debug_syslog) my_syslog("mlfiPriv::reset exit"); } void mlfiPriv::get_fd() { @@ -368,7 +370,18 @@ } void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) { + if (debug_syslog) my_syslog(this, "need_content_filter"); register_string(env_to, rcpt, &con); + if (!memory) { + // first recipient that needs content filtering sets all + // the content filtering parameters + memory = new recorder(this, con.get_html_tags(), con.get_content_tlds()); + scanner = new url_scanner(memory); + content_suffix = con.get_content_suffix(); + content_message = con.get_content_message(); + content_host_ignore = &con.get_content_host_ignore(); + } + if (debug_syslog) my_syslog(this, "need_content_filter exit"); } #define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) @@ -378,7 +391,7 @@ // syslog a message // void my_syslog(mlfiPriv *priv, char *text) { - char buf[1000]; + char buf[maxlen]; if (priv) { snprintf(buf, sizeof(buf), "%s: %s", priv->queueid, text); text = buf; @@ -390,6 +403,8 @@ syslog_opened = true; } syslog(LOG_NOTICE, "%s", text); + closelog(); + syslog_opened = false; pthread_mutex_unlock(&syslog_mutex); } else { @@ -644,8 +659,8 @@ bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip) { CONFIG &dc = *priv.pc; string_set &hosts = priv.memory->get_hosts(); - string_set &ignore = dc.get_content_host_ignore(); - char *suffix = dc.get_content_suffix(); + string_set &ignore = *priv.content_host_ignore; + char *suffix = priv.content_suffix; int count = 0; int cnt = hosts.size(); // number of hosts we could look at @@ -662,7 +677,7 @@ if ((cnt > limit) && (limit > 0) && random) { int r = rand() % cnt; if (r >= limit) { - char buf[1000]; + char buf[maxlen]; snprintf(buf, sizeof(buf), "host %s skipped", host); my_syslog(&priv, buf); continue; @@ -671,7 +686,7 @@ count++; ip = dns_interface(priv, host, true, &nameservers); if (debug_syslog) { - char buf[1000]; + char buf[maxlen]; if (ip) { char adr[sizeof "255.255.255.255"]; adr[0] = '\0'; @@ -704,7 +719,7 @@ ip = (*i).second; if (!ip) ip = dns_interface(priv, host, false, NULL); if (debug_syslog) { - char buf[200]; + char buf[maxlen]; if (ip) { char adr[sizeof "255.255.255.255"]; adr[0] = '\0'; @@ -724,7 +739,7 @@ string_map::iterator j = nameservers.ns_host.find(host); if (j != nameservers.ns_host.end()) { char *refer = (*j).second; - char buf[1000]; + char buf[maxlen]; snprintf(buf, sizeof(buf), "%s with nameserver %s", refer, host); host = register_string(hosts, buf); // put a copy into hosts, and return that reference } @@ -762,6 +777,7 @@ // sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) { + if (debug_syslog) my_syslog("mlfi_connect"); // allocate some private memory mlfiPriv *priv = new mlfiPriv; if (hostaddr->sa_family == AF_INET) { @@ -778,6 +794,7 @@ sfsistat mlfi_envfrom(SMFICTX *ctx, char **from) { mlfiPriv &priv = *MLFIPRIV; + if (debug_syslog) my_syslog(&priv, "mlfi_envfrom"); priv.mailaddr = to_lower_string(from[0]); priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL); return SMFIS_CONTINUE; @@ -787,11 +804,20 @@ { DNSBLP rejectlist = NULL; // list that caused the reject mlfiPriv &priv = *MLFIPRIV; + if (debug_syslog) my_syslog(&priv, "mlfi_envrcpt"); CONFIG &dc = *priv.pc; if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i")); char *rcptaddr = rcpt[0]; char *loto = to_lower_string(rcptaddr); - CONTEXT con = *(dc.find_context(loto)->find_context(priv.mailaddr)); + if (debug_syslog) my_syslog(&priv, "finding context"); + CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr)); + if (debug_syslog) { + char buf[maxlen]; + char msg[maxlen]; + snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen)); + my_syslog(&priv, msg); + } + if (debug_syslog) my_syslog(&priv, "finding from value"); char *fromvalue = con.find_from(priv.mailaddr); free(loto); status st; @@ -803,6 +829,7 @@ } else { // check the dns based lists + if (debug_syslog) my_syslog(&priv, "checking dns lists"); st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? black : oksofar; } if (st == reject) { @@ -810,7 +837,7 @@ char adr[sizeof "255.255.255.255"]; adr[0] = '\0'; inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr)); - char buf[2000]; + char buf[maxlen]; snprintf(buf, sizeof(buf), rejectlist->message, adr, adr); smfi_setreply(ctx, "550", "5.7.1", buf); return SMFIS_REJECT; @@ -822,6 +849,7 @@ } else { // accept the recipient + if (debug_syslog) my_syslog(&priv, "checking content filtering"); if (!con.get_content_filtering()) st = white; if (st == oksofar) { // but remember the non-whites @@ -838,6 +866,7 @@ sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) { mlfiPriv &priv = *MLFIPRIV; + if (debug_syslog) my_syslog(&priv, "mlfi_body"); if (priv.authenticated) return SMFIS_CONTINUE; if (priv.only_whites) return SMFIS_CONTINUE; priv.scanner->scan(data, len); @@ -846,8 +875,10 @@ sfsistat mlfi_eom(SMFICTX *ctx) { + if (debug_syslog) my_syslog("mlfi_eom"); sfsistat rc; mlfiPriv &priv = *MLFIPRIV; + if (debug_syslog) my_syslog(&priv, "mlfi_eom"); CONFIG &dc = *priv.pc; char *host = NULL; int ip; @@ -855,6 +886,8 @@ // process end of message if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE; else { + // assert env_to not empty + char buf[maxlen]; char *msg = NULL; string_set alive; bool random = false; @@ -872,22 +905,21 @@ limit = max(limit, con.get_host_limit()); } } - bool rejecting = alive.empty(); + bool rejecting = alive.empty(); // if alive is empty, we must have set msg above in acceptable_content() if (!rejecting) { - rejecting = check_hosts(priv, random, limit, host, ip); - if (rejecting) { - static char buf[2000]; + if (check_hosts(priv, random, limit, host, ip)) { char adr[sizeof "255.255.255.255"]; adr[0] = '\0'; inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); - snprintf(buf, sizeof(buf), dc.get_content_message(), host, adr); + snprintf(buf, sizeof(buf), priv.content_message, host, adr); msg = buf; + rejecting = true; } } if (!rejecting) { rc = SMFIS_CONTINUE; } - else if (!priv.have_whites && alive.empty()) { + else if (!priv.have_whites) { // can reject the entire message smfi_setreply(ctx, "550", "5.7.1", msg); rc = SMFIS_REJECT; @@ -909,6 +941,7 @@ sfsistat mlfi_abort(SMFICTX *ctx) { mlfiPriv &priv = *MLFIPRIV; + if (debug_syslog) my_syslog(&priv, "mlfi_abort"); priv.reset(); return SMFIS_CONTINUE; } @@ -916,6 +949,7 @@ sfsistat mlfi_close(SMFICTX *ctx) { mlfiPriv *priv = MLFIPRIV; + if (debug_syslog) my_syslog(priv, "mlfi_close"); if (!priv) return SMFIS_CONTINUE; delete priv; smfi_setpriv(ctx, NULL); @@ -949,7 +983,7 @@ pthread_mutex_lock(&config_mutex); newc->generation = generation++; pthread_mutex_unlock(&config_mutex); - char buf[200]; + char buf[maxlen]; snprintf(buf, sizeof(buf), "loading configuration generation %d", newc->generation); my_syslog(buf); if (load_conf(*newc, "dnsbl.conf")) { @@ -996,7 +1030,7 @@ for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) { CONFIG *old = *i; if (!old->reference_count) { - char buf[200]; + char buf[maxlen]; snprintf(buf, sizeof(buf), "freeing memory for old configuration generation %d", old->generation); my_syslog(buf); delete old; // destructor does all the work @@ -1133,6 +1167,7 @@ if (check) { use_syslog = false; + debug_syslog = true; CONFIG *conf = new_conf(); if (conf) { conf->dump(); @@ -1167,7 +1202,6 @@ CONFIG *conf = new_conf(); if (conf) { CONTEXTP con = conf->find_context(to); - const int maxlen = 1000; char buf[maxlen]; fprintf(stdout, "envelope to <%s> finds context %s\n", to, con->get_full_name(buf,maxlen)); CONTEXTP fc = con->find_context(from);