summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/libltgrey.c136
-rw-r--r--tools/libltgrey.h23
-rw-r--r--tools/ltgrey.c43
3 files changed, 132 insertions, 70 deletions
diff --git a/tools/libltgrey.c b/tools/libltgrey.c
index d4ec0da..1bf7e9f 100644
--- a/tools/libltgrey.c
+++ b/tools/libltgrey.c
@@ -73,6 +73,15 @@ void exeunt(const int sts){
#include "utils.h"
#include "qq_exit_codes.h"
+// constructor
+whatsit::whatsit(const std::string name, const std::string _parent_dir)
+: parent_dir(_parent_dir), progname(name), mypid(getpid()),
+ mod_age(0), ac_age(0),
+ verbosity(0)
+{
+ gettimeofday(&now, NULL);
+}
+
void whatsit::dump(const string var){
char* str = getenv(var.c_str());
cerr << progname
@@ -88,13 +97,14 @@ int whatsit::setup(){
<< "[" << mypid << "]";
progid = foo.str();
- ipvar = getenv("TCPREMOTEIP");
- if (ipvar) ipbase = ipvar;
- hostvar = getenv("TCPREMOTEHOST");
- if (hostvar) hostname = hostvar;
return 0;
}
+#if 1
+void whatsit::update(const string msg, const timeval new_mod,
+ const timeval new_ac, const int penalty, const int stain){
+}
+#else
void whatsit::update(const string msg, const timeval new_mod,
const timeval new_ac, const int penalty, const int stain){
if (verbosity){
@@ -128,36 +138,51 @@ void whatsit::update(const string msg, const timeval new_mod,
if (utimes(ipname.c_str(), upd))
cerr << "oops" << endl;
}
+#endif
-int whatsit::doit(const int penalty, const int stain){
-
- 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);
- }
-
+int whatsit::maybe_mkdir(const string somedir, const string msg){
// see if our directory exists:
struct stat dirstat;
- int rslt = stat(dirname.c_str(), &dirstat);
+ int rslt = stat(somedir.c_str(), &dirstat);
if (rslt != 0){
if (errno != ENOENT) {
- cerr << progid << ": stat failed for '"
- << dirname << "' : ";
+ cerr << progid << " stat failed for "
+ << msg
+ << " '" << somedir << "' : ";
perror(0);
}
- rslt = mkdir(dirname.c_str(), 0755);
+ rslt = mkdir(somedir.c_str(), 0755);
if (rslt != 0) {
cerr << progid
<< "uid " << getuid()
- << ": mkdir failed for '"
- << dirname << "' : ";
+ << " mkdir failed for "
+ << msg
+ << "' " << somedir << "' : ";
perror(0);
return(ex_syserr);
}
}
+ return 0;
+}
+
+#if 1
+int whatsit::doit(const int penalty, const int stain){
+ return ex_syserr;
+}
+
+#else
+int whatsit::doit(const int penalty, const int stain){
+ 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);
+ }
+
+ maybe_mkdir(parent_dir, "parent dir");
+ maybe_mkdir(parent_dir + "/quarante", "quarantine dir");
+ maybe_mkdir(parent_dir + "/repute", "reputation dir");
ipname = dirname + "/" + ipbase;
struct stat ipstat;
@@ -210,6 +235,7 @@ int whatsit::doit(const int penalty, const int stain){
update("returning customer", mod_orig, now, penalty, stain);
return 0;
}
+#endif
typedef vector<unsigned char> VU;
@@ -260,29 +286,35 @@ int diff(const VU aaa, const VU bbb){
return 0;
}
-int whatsit::check_dns(){
+int whatsit::check_dns(const char* ipvar, const char* namevar){
+ if (!ipvar) {
+ cerr << progid << " check_dns: no addr specified." << endl;
+ return ex_syserr;
+ }
string addr("()"), host("()");
vector<string> checked;
- int sts = check_dns_sub(addr, host, checked);
- if (sts == 0) return sts;
- if (sts != ex_badDNS) return sts; // possible ex_syserr
+ int rslt = check_dns_sub(ipvar, namevar, addr, host, checked);
+ int sts = rslt;
#if 1
sts = 0; // demote badDNS to just a warning
#endif
- cerr << progid;
- if (!sts) cerr << " (warning)";
- cerr << " DNS inconsistency: "
- << addr << " --> "
- << host << " ==>";
- if (!checked.size()) cerr << " ()";
- else for (vector<string>::const_iterator chk = checked.begin();
- chk != checked.end(); chk++) cerr << " " << *chk;
- cerr << endl;
-
+ if (rslt || verbosity) {
+ cerr << progid;
+ if (rslt && !sts) cerr << " (warning)";
+ if (rslt) cerr << " DNS inconsistency: ";
+ else cerr << " DNS OK: ";
+ cerr << addr << " --> "
+ << host << " ==>";
+ if (!checked.size()) cerr << " ()";
+ else for (vector<string>::const_iterator chk = checked.begin();
+ chk != checked.end(); chk++) cerr << " " << *chk;
+ cerr << endl;
+ }
return sts;
}
-int whatsit::check_dns_sub(string &addr, string &host, vector<string> &checked){
+int whatsit::check_dns_sub(const char* ipvar, const char* namevar,
+ string &addr, string &host, vector<string> &checked){
struct addrinfo *result;
struct addrinfo *ipresult;
@@ -296,6 +328,8 @@ int whatsit::check_dns_sub(string &addr, string &host, vector<string> &checked){
hints.ai_protocol = IPPROTO_TCP;
#endif
+// convert address-as-string to address-as-bits.
+// also get information about family
error = getaddrinfo(ipvar, NULL, &hints, &ipresult);
if (error == EAI_NONAME) return ex_badDNS;
if (error) { // some unexpected error
@@ -309,14 +343,38 @@ int whatsit::check_dns_sub(string &addr, string &host, vector<string> &checked){
cerr << "should never happen (addr with no addrs?)" << endl;
return ex_syserr;
}
+
+// reconvert from bits to string + family info
VUx ipAddr = parse_sockaddr(ipresult->ai_addr);
addr = ipAddr.str();
- char* hostvar = getenv("TCPREMOTEHOST");
- if (hostvar) host = hostvar;
- else return(ex_badDNS);
+ if (namevar) {
+ // inverse lookup already done
+ host = namevar;
+ } else {
+ // namevar not specified; do inverse lookup on our own
+
+ char hostname[NI_MAXHOST] = "";
+ char service[NI_MAXHOST] = "";
+
+#ifdef convert_bits_to_string
+ const char* rslt = inet_ntop(ipAddr.fam, &ipAddr.addr[0],
+ msgbuf, sizeof(msgbuf));
+ if (rslt) fprintf(stdout, "%s addrsize: %2d --> ",
+ msgbuf, addrsize);
+#endif
+ error = getnameinfo(ipresult->ai_addr, ipresult->ai_addrlen,
+ hostname, NI_MAXHOST, service, NI_MAXHOST, 0);
+ if (error != 0) {
+ cerr << progid << " reverse DNS lookup failed: "
+ << gai_strerror(error) << endl;
+ return (ex_badDNS);
+ }
+ namevar = hostname; // a char*, used below
+ host = hostname; // a string, returned to caller
+ }
- error = getaddrinfo(hostvar, NULL, &hints, &result);
+ error = getaddrinfo(namevar, NULL, &hints, &result);
if (error == EAI_NONAME) return ex_badDNS;
if (error) {
cerr << progid
diff --git a/tools/libltgrey.h b/tools/libltgrey.h
index 585ec01..6f516b4 100644
--- a/tools/libltgrey.h
+++ b/tools/libltgrey.h
@@ -4,35 +4,26 @@
class whatsit{
public:
- std::string dirname;
+ std::string parent_dir;
std::string progname;
pid_t mypid;
timeval now;
- char* ipvar;
- char* hostvar;
- std::string ipbase;
- std::string ipname;
- std::string hostname;
int mod_age;
int ac_age;
std::string suffix;
std::string progid;
int verbosity;
- whatsit(const std::string name, const std::string _dirname)
- : dirname(_dirname), progname(name), mypid(getpid()),
- mod_age(0), ac_age(0),
- verbosity(0)
- {
- gettimeofday(&now, NULL);
- }
+ whatsit(const std::string name, const std::string _parent_dir);
int doit(const int penalty, const int stain);
// access comes after modification:
void update(const std::string msg, const timeval new_mod,
const timeval new_ac, const int penalty, const int stain);
int setup();
- int check_dns();
- int check_dns_sub(std::string &addr, std::string &host,
- std::vector<std::string> &checked);
+ int check_dns(const char* ipvar, const char* namevar);
+ int check_dns_sub(const char* ipvar, const char* namevar,
+ std::string &addr, std::string &host,
+ std::vector<std::string> &checked);
void dump(const std::string var);
+ int maybe_mkdir(const std::string somedir, const std::string msg);
};
diff --git a/tools/ltgrey.c b/tools/ltgrey.c
index afdb4c1..c9f384f 100644
--- a/tools/ltgrey.c
+++ b/tools/ltgrey.c
@@ -14,17 +14,24 @@ string progname;
// forward reference:
void scan(const string progid, const string p, const int copies=1);
+
int main(int _argc, char** _argv){
+ char* namevar;
+ std::string hostname;
+ char* ipvar;
+ std::string ipbase;
+ std::string ipname;
+
mypid = getpid();
int argc(_argc);
char** argv(_argv);
- const string dirname("/var/qmail/greylist");
- whatsit foo(argv[0], dirname); argc--; argv++;
+ const string parent_dir("/var/qmail/ltgrey");
+ whatsit foo(argv[0], parent_dir); argc--; argv++;
int scanmode(0);
int copies(1);
int penalty(0);
int stain(0);
- int check(0);
+ int dnscheck(0);
while (argc > 0) {
string arg = argv[0]; argc--; argv++;
if (prefix(arg, "-scan")) {
@@ -33,8 +40,8 @@ int main(int _argc, char** _argv){
copies++;
} else if (prefix(arg, "-verbose")) {
foo.verbosity++;
- } else if (prefix(arg, "-check")) {
- check++;
+ } else if (prefix(arg, "-dnscheck")) {
+ dnscheck++;
} else if (prefix(arg, "-penalize")
|| prefix(arg, "-penalty")) {
if (!argc){
@@ -61,23 +68,29 @@ int main(int _argc, char** _argv){
}
if (foo.setup()) return ex_syserr;
+// dnscheck mode ...
+// Probably a better design would be to
+// (a) make more thorough DNS checks, and
+// (b) move all the DNS checking to a separate module
+
+ ipvar = getenv("TCPREMOTEIP");
+ if (ipvar) ipbase = ipvar;
+ namevar = getenv("TCPREMOTEHOST");
+ if (namevar) hostname = namevar;
+
+ if (dnscheck) {
+ exeunt(foo.check_dns(ipvar, namevar));
+ }
+
if (scanmode) {
+ string dirname = parent_dir + "/quarante";
scan(foo.progid, dirname, copies);
return 0;
}
int sts = foo.doit(penalty, stain);
- if (sts == ex_syserr) return sts;
- if (!check) return ex_good;
-
-// 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
+ return sts;
- int dns = foo.check_dns();
- if (dns == ex_syserr || dns == ex_spam) return dns;
- exeunt(sts);
}
//////////////////////////////////////////////////////////////////////