From b95f5ec1d83519c603f6e2145865c14932c4a813 Mon Sep 17 00:00:00 2001 From: John Denker Date: Tue, 31 Jul 2012 19:23:01 -0700 Subject: smarter about top-level domains, smarter about avoiding duplicate checks --- tools/sepofra.c | 32 ++++++++++++++++++++++---------- 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 #include +#include # include /* inet_ functions / structs */ # include /* inet_ functions / structs */ # include /* in_addr struct */ @@ -15,10 +16,13 @@ extern "C" { #include #include "bad_thing.h" +typedef std::map MSI; + class sepofra{ public: SPF_result_t result; std::list authorities; + MSI seen; std::string ip; std::string mailfrom; std::string helo; -- cgit v1.2.3