Mercurial > dnsbl
diff src/dnsbl.cpp @ 27:43a4f6b3e668 stable-2-3
add configurable host name limit and bad html tag limits.
author | carl |
---|---|
date | Sat, 22 May 2004 22:30:45 -0700 |
parents | fdae7ab30cfc |
children | 33e1e3910506 |
line wrap: on
line diff
--- a/src/dnsbl.cpp Fri May 21 21:55:38 2004 -0700 +++ b/src/dnsbl.cpp Sat May 22 22:30:45 2004 -0700 @@ -71,7 +71,9 @@ enum status {oksofar, // not rejected yet white, // whitelisted by envelope from black, // blacklisted by envelope from or to - reject}; // rejected by a dns list + reject, // rejected by a dns list + reject_tag, // too many bad html tags + reject_host}; // too many hosts/urls in body using namespace std; @@ -125,8 +127,10 @@ string_map env_to_chkfrom; // map recipient to a named from map char * content_suffix; // for sbl url body filtering char * content_message; // "" - char * limit_message; // error message for excessive bad html tags - int bad_tag_limit; // limit on bad html tags + char * host_limit_message; // error message for excessive host names + int host_limit; // limit on host names + char * tag_limit_message; // error message for excessive bad html tags + int tag_limit; // limit on bad html tags string_set html_tags; // set of valid html tags CONFIG(); ~CONFIG(); @@ -136,8 +140,10 @@ load_time = 0; content_suffix = NULL; content_message = NULL; - limit_message = NULL; - bad_tag_limit = 0; + host_limit_message = NULL; + host_limit = 0; + tag_limit_message = NULL; + tag_limit = 0; } CONFIG::~CONFIG() { for (dnsblp_map::iterator i=dnsbls.begin(); i!=dnsbls.end(); i++) { @@ -483,7 +489,8 @@ int count = 0; for (string_set::iterator i=priv.memory->hosts.begin(); i!=priv.memory->hosts.end(); i++) { count++; - if (count > 20) return oksofar; // silly to check too many hosts + int lim = priv.pc->host_limit; + if ((count > lim) && (lim > 0)) return reject_host; host = *i; if (debug_syslog) { char buf[200]; @@ -492,14 +499,14 @@ } ip = protected_dns_interface(host, true); if (ip) { - if (debug_syslog) { - char adr[sizeof "255.255.255.255"]; - adr[0] = '\0'; - inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); - char buf[200]; - snprintf(buf, sizeof(buf), "found host %s at %s", host, adr); - my_syslog(buf); - } + // if (debug_syslog) { + // char adr[sizeof "255.255.255.255"]; + // adr[0] = '\0'; + // inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); + // char buf[200]; + // snprintf(buf, sizeof(buf), "found host %s at %s", host, adr); + // my_syslog(buf); + // } status st = check_single(ip, dc.content_suffix); if (st == reject) return st; } @@ -507,9 +514,9 @@ host = NULL; int bin = priv.memory->binary_tags; int bad = priv.memory->bad_html_tags; - int lim = priv.pc->bad_tag_limit; + int lim = priv.pc->tag_limit; if (bin > bad) return oksofar; // probably .zip or .tar.gz with random content - if ((bad > lim) && (lim > 0)) return reject; + if ((bad > lim) && (lim > 0)) return reject_tag; return oksofar; } @@ -618,17 +625,22 @@ mlfiPriv &priv = *MLFIPRIV; char *host = NULL; int ip; + status st; // process end of message if (priv.authenticated || priv.only_whites || - (check_hosts(priv, host, ip) == oksofar)) rc = SMFIS_CONTINUE; + ((st=check_hosts(priv, host, ip)) == oksofar)) rc = SMFIS_CONTINUE; else { if (!priv.have_whites) { // can reject the entire message char buf[2000]; - if (!host) { - // must be rejected due to excessive bad html tags - snprintf(buf, sizeof(buf), priv.pc->limit_message); + if (st == reject_tag) { + // rejected due to excessive bad html tags + snprintf(buf, sizeof(buf), priv.pc->tag_limit_message); + } + else if (st == reject_host) { + // rejected due to excessive unique host/urls + snprintf(buf, sizeof(buf), priv.pc->host_limit_message); } else { char adr[sizeof "255.255.255.255"]; @@ -730,8 +742,11 @@ if (dc.content_suffix) { fprintf(stdout, "\ncontent filtering enabled with %s %s\n", dc.content_suffix, dc.content_message); } - if (dc.bad_tag_limit) { - fprintf(stdout, "\ncontent filtering for excessive html tags enabled with limit %d %s\n", dc.bad_tag_limit, dc.limit_message); + if (dc.host_limit) { + fprintf(stdout, "\ncontent filtering for host names enabled with limit %d %s\n", dc.host_limit, dc.host_limit_message); + } + if (dc.tag_limit) { + fprintf(stdout, "\ncontent filtering for excessive html tags enabled with limit %d %s\n", dc.tag_limit, dc.tag_limit_message); } fprintf(stdout, "\nfiles\n"); for (string_list::iterator i=dc.config_files.begin(); i!=dc.config_files.end(); i++) { @@ -830,8 +845,9 @@ static void load_conf(CONFIG &dc, char *fn) { dc.config_files.push_back(fn); map<char*, int, ltstr> commands; - enum {dummy, content, htmllimit, htmltag, dnsbl, dnsbll, envfrom, envto, include, includedcc}; + enum {dummy, content, hostlimit, htmllimit, htmltag, dnsbl, dnsbll, envfrom, envto, include, includedcc}; commands["content" ] = content; + commands["host_limit" ] = hostlimit; commands["html_limit" ] = htmllimit; commands["html_tag" ] = htmltag; commands["dnsbl" ] = dnsbl; @@ -875,6 +891,23 @@ processed = true; } break; + case hostlimit: { + char *limit = strtok(NULL, delim); + if (!limit) break; // no integer limit + char *msg = limit + strlen(limit); + if ((msg - line) >= strlen(orig)) break; // line ended with the limit + msg = strchr(msg+1, '\''); + if (!msg) break; // no reply message template + msg++; // move over the leading ' + if ((msg - line) >= strlen(orig)) break; // line ended with the leading quote + char *last = strchr(msg, '\''); + if (!last) break; // no trailing quote + *last = '\0'; // make it a null terminator + dc.host_limit = atoi(limit); + dc.host_limit_message = register_string(msg); + processed = true; + } break; + case htmllimit: { char *limit = strtok(NULL, delim); if (!limit) break; // no integer limit @@ -887,18 +920,20 @@ char *last = strchr(msg, '\''); if (!last) break; // no trailing quote *last = '\0'; // make it a null terminator - dc.bad_tag_limit = atoi(limit); - dc.limit_message = register_string(msg); + dc.tag_limit = atoi(limit); + dc.tag_limit_message = register_string(msg); processed = true; } break; case htmltag: { char *tag = next_token(delim); if (!tag) break; // no html tag value + dc.html_tags.insert(tag); // base version char buf[200]; snprintf(buf, sizeof(buf), "/%s", tag); - dc.html_tags.insert(tag); - dc.html_tags.insert(register_string(buf)); + dc.html_tags.insert(register_string(buf)); // leading / + snprintf(buf, sizeof(buf), "%s/", tag); + dc.html_tags.insert(register_string(buf)); // trailing / processed = true; } break;