summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2012-07-31 19:23:01 -0700
committerJohn Denker <jsd@av8n.com>2012-07-31 19:23:01 -0700
commitb95f5ec1d83519c603f6e2145865c14932c4a813 (patch)
tree2c67a4626712344168672e935b89322309e78f2c
parentcff5a7b49c4151fdc55e085b150385259d0dc781 (diff)
smarter about top-level domains, smarter about avoiding duplicate checks
-rw-r--r--tools/sepofra.c32
-rw-r--r--tools/sepofra.h4
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;