summaryrefslogtreecommitdiff
path: root/tools/libskrewt.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libskrewt.c')
-rw-r--r--tools/libskrewt.c93
1 files changed, 85 insertions, 8 deletions
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