Mercurial > dnsbl
diff src/dnsbl.cpp @ 382:c378e9d03f37
start parsing spf txt records
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Mon, 06 Mar 2017 12:21:05 -0800 |
parents | 879a470c6ac3 |
children | 7b7066a51c33 |
line wrap: on
line diff
--- a/src/dnsbl.cpp Tue Feb 28 17:02:07 2017 -0800 +++ b/src/dnsbl.cpp Mon Mar 06 12:21:05 2017 -0800 @@ -123,14 +123,6 @@ auth_addresses auth_daily_addresses; // protected with rate_mutex -struct ns_map { - // all the strings are owned by the keys/values in the ns_host string map - string_map ns_host; // nameserver name -> host name that uses this name server - ns_mapper ns_ip; // nameserver name -> ipv4 address of the name server - ~ns_map(); - void add(const char *name, const char *refer); -}; - ns_map::~ns_map() { for (string_map::iterator i=ns_host.begin(); i!=ns_host.end(); i++) { @@ -195,18 +187,18 @@ } -void add_auth_address(const char *user, int &hourly, int &daily, int32_t ip); -void add_auth_address(const char *user, int &hourly, int &daily, int32_t ip) { +void add_auth_address(const char *user, int &hourly, int &daily, uint32_t ip); +void add_auth_address(const char *user, int &hourly, int &daily, uint32_t ip) { pthread_mutex_lock(&rate_mutex); auth_addresses::iterator i = auth_hourly_addresses.find(user); if (i == auth_hourly_addresses.end()) { user = strdup(user); - auth_hourly_addresses[user] = new int32_t_set; + auth_hourly_addresses[user] = new uint32_t_set; auth_hourly_addresses[user]->insert(ip); hourly = 1; } else { - int32_t_set::iterator k = ((*i).second)->find(ip); + uint32_t_set::iterator k = ((*i).second)->find(ip); if (k == ((*i).second)->end()) ((*i).second)->insert(ip); hourly = ((*i).second)->size(); } @@ -214,12 +206,12 @@ auth_addresses::iterator j = auth_daily_addresses.find(user); if (j == auth_daily_addresses.end()) { user = strdup(user); - auth_daily_addresses[user] = new int32_t_set; + auth_daily_addresses[user] = new uint32_t_set; auth_daily_addresses[user]->insert(ip); daily = 1; } else { - int32_t_set::iterator k = ((*j).second)->find(ip); + uint32_t_set::iterator k = ((*j).second)->find(ip); if (k == ((*j).second)->end()) ((*j).second)->insert(ip); daily = ((*j).second)->size(); } @@ -307,10 +299,13 @@ // If we cannot get an answer, we just accept the mail. // If the qtype is ns_t_txt, the answer is placed in txt_answer which // must be non-null, and the return value can be ignored. +// A null string is returned in txt_answer in the case of errors. // If the qtype is ns_t_a, the ip address is returned in network byte order. +// IP address 0 is returned in case of errors. // -uint32_t dns_interface(mlfiPriv &priv, const char *question, int qtype, bool maybe_ip = false, ns_map *nameservers = NULL, char *txt_answer = NULL, size_t txt_size = 0); uint32_t dns_interface(mlfiPriv &priv, const char *question, int qtype, bool maybe_ip, ns_map *nameservers, char *txt_answer, size_t txt_size) { + if (txt_answer) txt_answer[0] = '\0'; // return null string if there are no txt answers + // tell sendmail we are still working #if _FFR_SMFI_PROGRESS if (priv.eom) smfi_progress(priv.ctx); @@ -419,9 +414,9 @@ } } } - if ((qtype == ns_t_txt) && (txt_answer) && (txt_size > 5)) { + if ((qtype == ns_t_txt) && (txt_answer) && (txt_size > 7)) { + txt_answer[0] = '\0'; // return null string if there are no txt answers txt_size--; // allow room for terminating null; - txt_answer[0] = '\0'; // return null string if there are no answers while (ns_parserr(&handle, ns_s_an, rrnum++, &rr) == 0) { size_t offset = 0; if (ns_rr_type(rr) == qtype) { @@ -439,7 +434,10 @@ } } txt_answer[offset] = '\0'; // trailing null - if (strcasecmp(txt_answer, "v=spf1 ") == 0) break; + if (strncasecmp(txt_answer, "v=spf1 ", 7) == 0) break; + } + if (strncasecmp(txt_answer, "v=spf1 ", 7) != 0) { + txt_answer[0] = '\0'; // return null string if there are no spf1 txt answers } } } @@ -891,10 +889,16 @@ #else glom.length = sizeof(glom.answer); glom.answer = 0; + int t = int8_t(question[0]); + if (t != ns_t_a) { + glom.length = 0; + } + else { struct hostent *host = gethostbyname(question+1); if (host && (host->h_addrtype == AF_INET)) { memcpy(&glom.answer, host->h_addr, sizeof(glom.answer)); } + } #endif // write the answer @@ -927,8 +931,8 @@ //////////////////////////////////////////////// // check a single dns list, return ip address in network byte order // -uint32_t check_single(mlfiPriv &priv, int32_t ip, const char *suffix); -uint32_t check_single(mlfiPriv &priv, int32_t ip, const char *suffix) { +uint32_t check_single(mlfiPriv &priv, uint32_t ip, const char *suffix); +uint32_t check_single(mlfiPriv &priv, uint32_t ip, const char *suffix) { // make a dns question const u_char *src = (const u_char *)&ip; if (src[0] == 127) return 0; // don't do dns lookups on localhost @@ -949,8 +953,8 @@ //////////////////////////////////////////////// // check a single dnsbl // -bool check_single(mlfiPriv &priv, int32_t ip, DNSBL &bl); -bool check_single(mlfiPriv &priv, int32_t ip, DNSBL &bl) { +bool check_single(mlfiPriv &priv, uint32_t ip, DNSBL &bl); +bool check_single(mlfiPriv &priv, uint32_t ip, DNSBL &bl) { return check_single(priv, ip, bl.suffix); } @@ -958,8 +962,8 @@ //////////////////////////////////////////////// // check a single dnswl // -bool check_single(mlfiPriv &priv, int32_t ip, DNSWL &wl); -bool check_single(mlfiPriv &priv, int32_t ip, DNSWL &wl) { +bool check_single(mlfiPriv &priv, uint32_t ip, DNSWL &wl); +bool check_single(mlfiPriv &priv, uint32_t ip, DNSWL &wl) { uint32_t r = ntohl(check_single(priv, ip, wl.suffix)); uint32_t v = (uint32_t)0x7f000000; uint32_t m = (uint32_t)0xffff0000; @@ -1026,8 +1030,8 @@ // check the hosts from the body against the content filter and uribl dnsbls // // -bool check_hosts(mlfiPriv &priv, bool random, int limit, const char *&msg, const char *&host, int32_t &ip, const char *&found); -bool check_hosts(mlfiPriv &priv, bool random, int limit, const char *&msg, const char *&host, int32_t &ip, const char *&found) { +bool check_hosts(mlfiPriv &priv, bool random, int limit, const char *&msg, const char *&host, uint32_t &ip, const char *&found); +bool check_hosts(mlfiPriv &priv, bool random, int limit, const char *&msg, const char *&host, uint32_t &ip, const char *&found) { found = NULL; // normally ip address style if (!priv.content_suffix && !priv.uribl_suffix) return false; // nothing to check string_set &hosts = priv.memory->get_hosts(); @@ -1035,7 +1039,7 @@ int count = 0; int cnt = hosts.size(); // number of hosts we could look at - int32_t_set ips; + uint32_t_set ips; ns_map nameservers; for (string_set::iterator i=hosts.begin(); i!=hosts.end(); i++) { host = *i; // a reference into hosts, which will live until this smtp transaction is closed @@ -1072,7 +1076,7 @@ my_syslog(&priv, buf); } if (ip) { - int32_t_set::iterator i = ips.find(ip); + uint32_t_set::iterator i = ips.find(ip); if (i == ips.end()) { // we haven't looked this up yet ips.insert(ip); @@ -1110,7 +1114,7 @@ my_syslog(&priv, buf); } if (ip) { - int32_t_set::iterator i = ips.find(ip); + uint32_t_set::iterator i = ips.find(ip); if (i == ips.end()) { ips.insert(ip); if (check_single(priv, ip, priv.content_suffix)) { @@ -1649,7 +1653,7 @@ sfsistat rc; mlfiPriv &priv = *MLFIPRIV; const char *host = NULL; - int32_t ip; + uint32_t ip; // process end of message priv.eom = true; if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE; @@ -1847,7 +1851,7 @@ } for (auth_addresses::iterator j=auth_hourly_addresses.begin(); j!=auth_hourly_addresses.end(); j++) { delete (*j).second; - (*j).second = new int32_t_set; + (*j).second = new uint32_t_set; } pthread_mutex_unlock(&rate_mutex); loop1 = 0; @@ -1861,7 +1865,7 @@ } for (auth_addresses::iterator j=auth_daily_addresses.begin(); j!=auth_daily_addresses.end(); j++) { delete (*j).second; - (*j).second = new int32_t_set; + (*j).second = new uint32_t_set; } pthread_mutex_unlock(&rate_mutex); loop2 = 0;