diff options
author | John Denker <jsd@av8n.com> | 2012-11-24 19:40:13 -0800 |
---|---|---|
committer | John Denker <jsd@av8n.com> | 2012-11-24 19:40:13 -0800 |
commit | f7de8573f5521263449fd80a2d5cdf3901b96087 (patch) | |
tree | 565829f500e520428cdb099bbc44a3351986f1dc /tools | |
parent | a80d71e7dc3b46980b9f91c9238599fee26cc1b2 (diff) |
Now can check to see if hostnames map to observed IP
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libltgrey.c | 5 | ||||
-rw-r--r-- | tools/libskrewt.c | 93 | ||||
-rw-r--r-- | tools/sepofra.c | 5 |
3 files changed, 90 insertions, 13 deletions
diff --git a/tools/libltgrey.c b/tools/libltgrey.c index eb6d904..0538d5c 100644 --- a/tools/libltgrey.c +++ b/tools/libltgrey.c @@ -306,10 +306,9 @@ int whatsit::check_dns_sub(const char* ipvar, const char* namevar, if (error == EAI_NONAME) return ex_badDNS; if (error) { cerr << progid + << " getaddrinfo for " << ipvar << " error " << error - << " compare " << EAI_NONAME - << " in getaddrinfo for " << ipvar - << " :: " << gai_strerror(error) << endl; + << " i.e. " << gai_strerror(error) << endl; return ex_dns_fail; } diff --git a/tools/libskrewt.c b/tools/libskrewt.c index 3c820f1..d93a9e1 100644 --- a/tools/libskrewt.c +++ b/tools/libskrewt.c @@ -214,12 +214,7 @@ int skrewt::dump_bigbuf(std::ostream& xout){ return 0; } -void check_name(name_tester& fqdn, const string ip) { - if (ip == "") { - cerr << "SPF: should never happen: email with no IP?" <<endl; - fqdn.spf = fqdn.map2ip = neutral; - return; - } +void check_spf(name_tester& fqdn, const string ip) { sepofra my_spf; try { my_spf.check(ip, @@ -238,6 +233,88 @@ void check_name(name_tester& fqdn, const string ip) { } } +void check_map2ip(name_tester& fqdn, const string ipstr) { + if (ipstr.length() == 0) { + cerr << progid << " check_map2ip: no addr specified." << endl; + fqdn.map2ip = fail; + return; + } + +// convert address-as-string to address-as-bits. +// also get information about family + struct addrinfo *ipresult; + struct addrinfo *result; + addrinfo hints; + int error; + + memset(&hints, 0, sizeof(struct addrinfo)); + // restrict to TCP only; otherwise we get N records per address + hints.ai_protocol = IPPROTO_TCP; + + error = getaddrinfo(ipstr.c_str(), NULL, &hints, &ipresult); + // EAI_NONAME covers the case of malformed IP address + // e.g. 1.2.3.4.5 + if (error == EAI_NONAME) { + fqdn.map2ip = fail; + return; + } + if (error) { // some unexpected error + cerr << progid + << " odd error " << error + << " in getaddrinfo for " << ipstr + << " : " << gai_strerror(error) << endl; + fqdn.map2ip = fail; + return; + } + if (!ipresult) { + cerr << progid + <<" ??? should never happen (ipstr with no ipbits?)" << endl; + fqdn.map2ip = fail; + return; + } + + error = getaddrinfo(fqdn.name.c_str(), NULL, &hints, &result); + if (error == EAI_NONAME) { + // malformed name, or no address for name + fqdn.map2ip = fail; + return; + } + if (error) { + cerr << progid + << " getaddrinfo for " << fqdn.name + << " error " << error + << " i.e. " << gai_strerror(error) << endl; + fqdn.map2ip = fail; + return; + } + +// loop over all returned results and check for a match. + for (struct addrinfo *res = result; res != NULL; res = res->ai_next){ + if (memcmp(res->ai_addr, ipresult->ai_addr, res->ai_addrlen) == 0) { + // match! + goto done; + } + } + // here if no match + fqdn.map2ip = fail; + return; +done: + fqdn.map2ip = pass; + return; +} + +void check_name_ip(name_tester& fqdn, const string ip) { + if (ip == "") { + cerr << "check_nane_ip: should never happen: email with no IP?" <<endl; + fqdn.spf = fqdn.map2ip = neutral; + return; + } + check_spf(fqdn, ip); + check_map2ip(fqdn, ip); +} + + + int skrewt::interstage(){ if (saw_blank_line) {/* ignore */} // Note that the headers are in reverse-chronological order. @@ -253,8 +330,8 @@ int skrewt::interstage(){ if (rslt) return rslt; if (proximta_AuthUser == "") { // FIXME: also check return-path aka envelope-from - check_name(proximta_HELO, proximta_IP); - check_name(proximta_rDNS, proximta_IP); + check_name_ip(proximta_HELO, proximta_IP); + check_name_ip(proximta_rDNS, proximta_IP); } cerr << progid << " === rDNS: " << proximta_rDNS.name diff --git a/tools/sepofra.c b/tools/sepofra.c index 56d02a9..41cc784 100644 --- a/tools/sepofra.c +++ b/tools/sepofra.c @@ -87,13 +87,14 @@ void sepofra::check( spf_request = SPF_request_new(spf_server); if (spf_request == NULL) { - cerr << "SPF_request_new failed" << endl; + cerr << "sepofra::check SPF_request_new failed" << endl; break; } if ( SPF_request_set_ipv4_str( spf_request, opt_ip.c_str() ) && SPF_request_set_ipv6_str( spf_request, opt_ip.c_str() ) ) { - cerr << "Invalid IP address: " << opt_ip << endl; + cerr << "sepofra::check: Invalid IP address: '" + << opt_ip << "'" << endl; break; } |