From 010db437f35e831d170a726aad88bcc305c7b668 Mon Sep 17 00:00:00 2001 From: John Denker Date: Sun, 22 Jul 2012 19:10:38 -0700 Subject: implement "-stain" feature; the "-penalty" feature was a baaaad idea --- tools/filters.conf | 2 +- tools/greylist.c | 57 +++++++++++++++++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/filters.conf b/tools/filters.conf index 7768e6a..bd8eb33 100644 --- a/tools/filters.conf +++ b/tools/filters.conf @@ -5,4 +5,4 @@ sa /usr/local/bin/spamc -Y 0 -s 1000000 -x qq /var/qmail/bin/qmail-queue # postspam /var/qmail/bin/greylist -suffix (post) -penalize 86400 -v -postspam /var/qmail/bin/greylist -suffix (post) -penalize 1 -v +postspam /var/qmail/bin/greylist -suffix (post) -stain 1 -v diff --git a/tools/greylist.c b/tools/greylist.c index fd5ac4f..92e638f 100644 --- a/tools/greylist.c +++ b/tools/greylist.c @@ -113,10 +113,10 @@ public: { gettimeofday(&now, NULL); } - int doit(const int penalty=0); + int doit(const int penalty, const int stain); // access comes after modification: void update(const string msg, const timeval new_mod, - const timeval new_ac, const int penalty=0); + const timeval new_ac, const int penalty, const int stain); int setup(); int check_dns(); int check_dns_sub(string &addr, string &host, vector &checked); @@ -216,27 +216,37 @@ void scan(const string progid, const string p, const int copies=1){ } void whatsit::update(const string msg, const timeval new_mod, - const timeval new_ac, const int penalty){ + const timeval new_ac, const int penalty, const int stain){ if (verbosity){ cerr << progid << ": "; - if (penalty) cerr << " penalty+"; - cerr << msg << ": " << ipbase; - if (hostname.length()) cerr << " " << hostname; - cerr << " mod_age: " << time_out(mod_age) - << " ac_age: " << time_out(ac_age) - << endl; + if (penalty) cerr << " penalty " << penalty; + if (stain) cerr << " stain " << stain; + if (verbosity > 1) { + if (penalty || stain) cerr << "+"; // separation, punctuation + cerr << msg << ": " << ipbase; + if (hostname.length()) cerr << " " << hostname; + cerr << " mod_age: " << time_out(mod_age) + << " ac_age: " << time_out(ac_age); + } + cerr << endl; } timeval pen_mod(new_mod); + timeval stain_ac(new_ac); if (penalty) { pen_mod = now; pen_mod.tv_sec += penalty; } + if (stain) { + stain_ac = now; + stain_ac.tv_sec -= stain; + } timeval upd[2] = { // beware: access illogically comes *before* modification here: - new_ac, + stain_ac, pen_mod }; - utimes(ipname.c_str(), upd); + if (utimes(ipname.c_str(), upd)) + cerr << "oops" << endl; } @@ -249,6 +259,7 @@ int main(int _argc, char** _argv){ int scanmode(0); int copies(1); int penalty(0); + int stain(0); int check(0); while (argc > 0) { string arg = argv[0]; argc--; argv++; @@ -267,6 +278,12 @@ int main(int _argc, char** _argv){ exeunt(ex_syserr); } penalty = atoi(*argv++); argc--; + } else if (prefix(arg, "-stain")) { + if (!argc){ + cerr << "Option '" << arg << "' requires an argument" << endl; + exeunt(ex_syserr); + } + stain = atoi(*argv++); argc--; } else if (prefix(arg, "-suffix")) { if (!argc){ cerr << "Option '" << arg << "' requires an argument" << endl; @@ -285,7 +302,7 @@ int main(int _argc, char** _argv){ return 0; } - int sts = foo.doit(penalty); + int sts = foo.doit(penalty, stain); if (sts == ex_syserr) return sts; if (!check) return ex_good; @@ -299,7 +316,7 @@ int main(int _argc, char** _argv){ exeunt(sts); } -int whatsit::doit(const int penalty){ +int whatsit::doit(const int penalty, const int stain){ if (!ipvar) { cerr << progid @@ -346,7 +363,7 @@ int whatsit::doit(const int penalty){ perror(0); } close(fd); - update("new customer", now, now, penalty); + update("new customer", now, now, penalty, stain); return(ex_greylisting); } @@ -355,29 +372,29 @@ int whatsit::doit(const int penalty){ ac_age = now.tv_sec - ipstat.st_atime; timeval mod_orig = {ipstat.st_mtime, 0}; if (mod_age < 0) { - update("penalty box", mod_orig, now, penalty); + update("penalty box", mod_orig, now, penalty, stain); return(ex_penaltybox); } if (mod_age < ac_age){ // when he comes out on parole, he starts over with no reputation: - update("paroled spammer", now, now, penalty); + update("paroled spammer", now, now, penalty, stain); return(ex_greylisting); } if (mod_age < minimum_age) { - update("early bird", mod_orig, now, penalty); + update("early bird", mod_orig, now, penalty, stain); return(ex_greylisting); } if (mod_age - ac_age < minimum_age // early bird, or completely unused && mod_age > probation) { // did not diligently resubmit - update("disprobation", now, now, penalty); + update("disprobation", now, now, penalty, stain); return(ex_greylisting); } if (ac_age > maximum_age) { - update("too old, starting over", now, now, penalty); + update("too old, starting over", now, now, penalty, stain); return(ex_greylisting); } // if all checks are passed, must be OK: - update("returning customer", mod_orig, now, penalty); + update("returning customer", mod_orig, now, penalty, stain); return 0; } -- cgit v1.2.3