From 9277ba4cf19854c02be339daa460598b7ee7de94 Mon Sep 17 00:00:00 2001 From: John Denker Date: Sat, 21 Jul 2012 09:47:14 -0700 Subject: adding some code to check DNS consistency --- tools/greylist.c | 113 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 25 deletions(-) (limited to 'tools/greylist.c') diff --git a/tools/greylist.c b/tools/greylist.c index d76ba08..b64636e 100644 --- a/tools/greylist.c +++ b/tools/greylist.c @@ -3,7 +3,7 @@ #include #include -#include /* for stat() */ +#include /* for stat(), getaddrinfo() */ #include /* for stat() */ #include /* for stat() */ #include /* for perror */ @@ -17,6 +17,10 @@ // requires apt-get install libboost-filesystem-dev: #include +#include /* for getaddrinfo() */ +#include /* for getaddrinfo() */ +#include /* for memset() */ + using namespace std; const int minute(60); @@ -84,6 +88,8 @@ public: string progname; pid_t mypid; timeval now; + char* ipvar; + char* hostvar; string ipbase; string ipname; string hostname; @@ -104,7 +110,8 @@ public: // access comes after modification: void update(const string msg, const timeval new_mod, const timeval new_ac, const int penalty=0); - void bind(); + int setup(); + int check_dns(); }; string basename(const string path){ @@ -113,11 +120,24 @@ string basename(const string path){ return path; } -void whatsit::bind(){ +int whatsit::setup(){ stringstream foo; - foo << basename(progname) << suffix + foo << basename(progname) << suffix << "[" << mypid << "]"; progid = foo.str(); + + ipvar = getenv("TCPREMOTEIP"); + if (!ipvar) { + cerr << progid + << " TCPREMOTEIP not set???" << endl; + // should never happen + // although you can make it happen using a weird test-harness + return(ex_syserr); + } + ipbase = ipvar; + hostvar = getenv("TCPREMOTEHOST"); + if (hostvar) hostname = hostvar; + return 0; } string time_out(const int _ttt){ @@ -218,6 +238,7 @@ void whatsit::update(const string msg, const timeval new_mod, utimes(ipname.c_str(), upd); } + int main(int _argc, char** _argv){ mypid = getpid(); int argc(_argc); @@ -256,7 +277,7 @@ int main(int _argc, char** _argv){ exeunt(ex_syserr); } } - foo.bind(); + if (foo.setup()) return ex_syserr; if (scanmode) { scan(foo.progid, dirname, copies); @@ -269,31 +290,15 @@ int main(int _argc, char** _argv){ // check mode ... perform some extra checks. // Probably a better design would be to -// a) make more thorough DNS checks, and -// b) move all the DNS checking to a separate module +// (a) make more thorough DNS checks, and +// (b) move all the DNS checking to a separate module - char* hostvar = getenv("TCPREMOTEHOST"); - if (!hostvar) { - cerr << foo.progid - << " from " << foo.ipbase - << " ... TCPREMOTEHOST not set???" << endl; - exeunt(ex_spam); - } + int dns = foo.check_dns(); + if (dns == ex_syserr) return dns; exeunt(sts); } int whatsit::doit(const int penalty){ - char* ipvar = getenv("TCPREMOTEIP"); - if (!ipvar) { - cerr << progid - << " TCPREMOTEIP not set???" << endl; - // should never happen - // although you can make it happen using a weird test-harness - return(ex_syserr); - } - ipbase = ipvar; - char* hostvar = getenv("TCPREMOTEHOST"); - if (hostvar) hostname = hostvar; // see if our directory exists: struct stat dirstat; @@ -365,3 +370,61 @@ int whatsit::doit(const int penalty){ update("returning customer", mod_orig, now, penalty); return 0; } + +int whatsit::check_dns(){ + char* hostvar = getenv("TCPREMOTEHOST"); + if (!hostvar) { + cerr << progid + << " from " << ipbase + << " ... TCPREMOTEHOST not set???" << endl; + exeunt(ex_spam); + } + + struct addrinfo *result; + struct addrinfo *ipresult; + struct addrinfo *res; + addrinfo hints; + int error; + + /* resolve the domain name into a list of addresses */ + memset(&hints, 0, sizeof(struct addrinfo)); +#if 1 + // restrict to TCP only; otherwise we get N records per address + hints.ai_protocol = IPPROTO_TCP; +#endif + error = getaddrinfo(hostvar, NULL, &hints, &result); + if (error) { + cerr << "error in getaddrinfo for " << hostvar + << " : " << gai_strerror(error) << endl; + return ex_syserr; + } + + error = getaddrinfo(ipvar, NULL, &hints, &ipresult); + if (error) { + cerr << "error in getaddrinfo for " << ipvar + << " : " << gai_strerror(error) << endl; + return ex_syserr; + } + +// loop over all returned results and check for a match. + for (res = result; res != NULL; res = res->ai_next){ + void *numericAddress; + + sa_family_t fam = ((sockaddr *)res->ai_addr)->sa_family; + int addrsize; + switch (fam) { + case AF_INET: + numericAddress = &(((sockaddr_in *)res->ai_addr)->sin_addr.s_addr); + addrsize = sizeof(in_addr); + break; + case AF_INET6: + numericAddress = &(((sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr); + addrsize = sizeof(in6_addr); + break; + default: + cerr << "?Unknown address family " << fam << endl; + return(ex_syserr); + } + } + return 0; +} -- cgit v1.2.3