diff options
author | John Denker <jsd@av8n.com> | 2012-07-31 19:23:01 -0700 |
---|---|---|
committer | John Denker <jsd@av8n.com> | 2012-07-31 19:23:01 -0700 |
commit | b95f5ec1d83519c603f6e2145865c14932c4a813 (patch) | |
tree | 2c67a4626712344168672e935b89322309e78f2c | |
parent | cff5a7b49c4151fdc55e085b150385259d0dc781 (diff) |
smarter about top-level domains, smarter about avoiding duplicate checks
-rw-r--r-- | tools/sepofra.c | 32 | ||||
-rw-r--r-- | tools/sepofra.h | 4 |
2 files changed, 26 insertions, 10 deletions
diff --git a/tools/sepofra.c b/tools/sepofra.c index d41e5ad..69575c4 100644 --- a/tools/sepofra.c +++ b/tools/sepofra.c @@ -22,12 +22,19 @@ string domain_part(const string ema){ return ema; } -string subdomain(const string ema){ - size_t where = ema.find('.'); - if (where != ema.npos){ - return ema.substr(1+where); - } - return ema; +// strips off one level of domain name, +// provided that at least two levels remain. +// foo.bar.com --> bar.com +// bar.com --> bar.com +// ..foo.bar.com --> bar.com +string subdomain2plus(const string ema){ + string sub(ema); + while (sub[0] == '.') sub = sub.substr(1); + size_t where = sub.find('.'); + if (where == string::npos) return ema; + sub = sub.substr(1+where); + if (sub.find(".") == string::npos) return ema; + return sub; } SPF_result_t sepofra::check1(const string _host, @@ -38,6 +45,11 @@ SPF_result_t sepofra::check1(const string _host, host = host.substr(1+where); } if (!host.length()) return SPF_RESULT_INVALID; + if (seen.find(host) != seen.end()) { + // already checked this one + return SPF_RESULT_SOFTFAIL; + } + seen[host] = 1; authorities.push_back(host); if (SPF_request_set_env_from( spf_request, @@ -62,8 +74,8 @@ void sepofra::check( SPF_server_t* spf_server = NULL; sepofra rslt; ip = opt_ip; - helo = opt_helo; - mailfrom = trim(opt_mailfrom, " \t\r\n<>"); + helo = trim(opt_helo, " \t\r\n<.>"); + mailfrom = trim(opt_mailfrom, " \t\r\n<.>"); string mailfrom_domain = domain_part(opt_mailfrom); do { @@ -92,11 +104,11 @@ void sepofra::check( if (result == SPF_RESULT_PASS) break; if (result == SPF_RESULT_FAIL) break; - result = check1(subdomain(opt_helo), "HELO subdomain", opt_debug); + result = check1(subdomain2plus(opt_helo), "HELO subdomain", opt_debug); if (result == SPF_RESULT_PASS) break; if (result == SPF_RESULT_FAIL) break; - result = check1(subdomain(mailfrom), "MAILFROM domain", opt_debug); + result = check1(subdomain2plus(mailfrom), "MAILFROM domain", opt_debug); if (result == SPF_RESULT_PASS) break; if (result == SPF_RESULT_FAIL) break; diff --git a/tools/sepofra.h b/tools/sepofra.h index 2e4b831..60a404f 100644 --- a/tools/sepofra.h +++ b/tools/sepofra.h @@ -1,5 +1,6 @@ #include <string> #include <list> +#include <map> # include <sys/socket.h> /* inet_ functions / structs */ # include <netinet/in.h> /* inet_ functions / structs */ # include <arpa/inet.h> /* in_addr struct */ @@ -15,10 +16,13 @@ extern "C" { #include <string.h> #include "bad_thing.h" +typedef std::map<std::string,int> MSI; + class sepofra{ public: SPF_result_t result; std::list<std::string> authorities; + MSI seen; std::string ip; std::string mailfrom; std::string helo; |