summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2012-11-24 19:40:13 -0800
committerJohn Denker <jsd@av8n.com>2012-11-24 19:40:13 -0800
commitf7de8573f5521263449fd80a2d5cdf3901b96087 (patch)
tree565829f500e520428cdb099bbc44a3351986f1dc
parenta80d71e7dc3b46980b9f91c9238599fee26cc1b2 (diff)
Now can check to see if hostnames map to observed IP
-rw-r--r--tools/libltgrey.c5
-rw-r--r--tools/libskrewt.c93
-rw-r--r--tools/sepofra.c5
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;
}