summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/filters.conf3
-rw-r--r--tools/greylist.c93
-rw-r--r--tools/skrewt.c33
3 files changed, 83 insertions, 46 deletions
diff --git a/tools/filters.conf b/tools/filters.conf
index f5b35f5..7768e6a 100644
--- a/tools/filters.conf
+++ b/tools/filters.conf
@@ -4,4 +4,5 @@ stub /var/qmail/bin/greylist -check -v
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 86400 -v
+postspam /var/qmail/bin/greylist -suffix (post) -penalize 1 -v
diff --git a/tools/greylist.c b/tools/greylist.c
index 063c3d0..fd5ac4f 100644
--- a/tools/greylist.c
+++ b/tools/greylist.c
@@ -38,6 +38,7 @@ const int probation(4*hour);
#define bar foo(good, 0) ;\
foo(spam, 21) ;\
foo(penaltybox, 22) ;\
+foo(badDNS, 23) ;\
foo(greylisting, 70) ;\
foo(syserr, 71) ;\
foo(comerr, 74) ;
@@ -118,6 +119,7 @@ public:
const timeval new_ac, const int penalty=0);
int setup();
int check_dns();
+ int check_dns_sub(string &addr, string &host, vector<string> &checked);
};
string basename(const string path){
@@ -133,14 +135,7 @@ int whatsit::setup(){
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;
+ if (ipvar) ipbase = ipvar;
hostvar = getenv("TCPREMOTEHOST");
if (hostvar) hostname = hostvar;
return 0;
@@ -306,6 +301,14 @@ int main(int _argc, char** _argv){
int whatsit::doit(const int penalty){
+ 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);
+ }
+
// see if our directory exists:
struct stat dirstat;
int rslt = stat(dirname.c_str(), &dirstat);
@@ -356,6 +359,7 @@ int whatsit::doit(const int penalty){
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);
return(ex_greylisting);
}
@@ -427,23 +431,35 @@ int diff(const VU aaa, const VU bbb){
}
int whatsit::check_dns(){
- char* hostvar = getenv("TCPREMOTEHOST");
- if (!hostvar) {
- cerr << progid
- << " from " << ipbase
- << " ... TCPREMOTEHOST not set???" << endl;
- exeunt(ex_spam);
- }
+ 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
+#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;
+
+ return sts;
+}
+
+int whatsit::check_dns_sub(string &addr, string &host, vector<string> &checked){
struct addrinfo *result;
struct addrinfo *ipresult;
struct addrinfo *res;
addrinfo hints;
int error;
- int ex_dnserr(ex_syserr);
- ex_dnserr = 0; // temporarily just a warning
- /* 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
@@ -451,43 +467,46 @@ int whatsit::check_dns(){
#endif
error = getaddrinfo(ipvar, NULL, &hints, &ipresult);
- if (error) {
- cerr << "error in getaddrinfo for " << ipvar
+ if (error == EAI_NONAME) return ex_badDNS;
+ if (error) { // some unexpected error
+ cerr << progid
+ << " odd error " << error
+ << " in getaddrinfo for " << ipvar
<< " : " << gai_strerror(error) << endl;
- return ex_dnserr;
+ return ex_syserr;
}
if (!ipresult) {
cerr << "should never happen (addr with no addrs?)" << endl;
- return ex_dnserr;
+ return ex_syserr;
}
-
VUx ipAddr = parse_sockaddr(ipresult->ai_addr);
+ addr = ipAddr.str();
+
+ char* hostvar = getenv("TCPREMOTEHOST");
+ if (hostvar) host = hostvar;
+ else return(ex_badDNS);
+
error = getaddrinfo(hostvar, NULL, &hints, &result);
+ if (error == EAI_NONAME) return ex_badDNS;
if (error) {
- cerr << "error in getaddrinfo for " << hostvar
- << " : " << gai_strerror(error) << endl;
- return ex_dnserr;
+ cerr << progid
+ << " error " << error
+ << " compare " << EAI_NONAME
+ << " in getaddrinfo for " << ipvar
+ << " :: " << gai_strerror(error) << endl;
+ return ex_syserr;
}
// loop over all returned results and check for a match.
- vector<string> checked_hosts;
for (res = result; res != NULL; res = res->ai_next){
VUx hostAddr = parse_sockaddr(res->ai_addr);
-
+ checked.push_back(hostAddr.str());
if (!diff(hostAddr.addr, ipAddr.addr)) {
///// cerr << "match! " << ipAddr.addr.size() << endl;
goto done;
}
}
- if (!ex_dnserr) cerr << "(warning) ";
- cerr << "DNS inconsistency: "
- << ipAddr.str() << " --> "
- << hostvar << " ==>";
- for (res = result; res != NULL; res = res->ai_next){
- cerr << " " << parse_sockaddr(res->ai_addr).str();
- }
- cerr << endl;
- return ex_dnserr;
+ return ex_badDNS;
done:
return 0;
diff --git a/tools/skrewt.c b/tools/skrewt.c
index 44e885b..6de3dd9 100644
--- a/tools/skrewt.c
+++ b/tools/skrewt.c
@@ -11,6 +11,7 @@
#include <signal.h>
#include <stdio.h> /* perror */
+#include <sstream>
using namespace std;
@@ -134,6 +135,15 @@ void exeunt(const int sts){
exit(sts);
}
+string basename(const string path){
+ size_t where = path.rfind("/");
+ if (where != string::npos) return path.substr(1+where);
+ return path;
+}
+
+string progname, progid;
+int mypid;
+
////////////////////////////////////////////////////////////
int main(int _argc, const char** _argv){
//// pid_t pid = getpid();
@@ -141,7 +151,14 @@ int main(int _argc, const char** _argv){
//// cout << getpgid(pid) << endl;
int argc(_argc);
const char **argv(_argv);
- string progname(*argv); argv++; argc--;
+ {
+ progname = *argv++; argc--;
+ mypid = getpid();
+ stringstream binder;
+ binder << basename(progname) << "[" << mypid << "]";
+ progid = binder.str();
+ }
+
int maxsize(1000000);
@@ -183,7 +200,7 @@ int main(int _argc, const char** _argv){
if (getline(cin, header).fail()) continue;
msgsize += header.length()+1;
if (msgsize > maxsize) {
- cerr << "skrewt rejection: bigger than " << maxsize << endl;
+ cerr << progid << " rejection: bigger than " << maxsize << endl;
exeunt(ex_spam);
}
for (;;) {
@@ -197,7 +214,7 @@ int main(int _argc, const char** _argv){
if (getline(cin, line).fail()) continue;
msgsize += line.length()+1;
if (msgsize > maxsize) {
- cerr << "skrewt rejection: bigger than " << maxsize << endl;
+ cerr << progid << " rejection: bigger than " << maxsize << endl;
exeunt(ex_spam);
}
header += "\n" + line;
@@ -206,7 +223,7 @@ int main(int _argc, const char** _argv){
if (len && header[len-1] == '\r') len--; // reduced length, not counting <cr>
if (len == 0) {
if (!gotdate) {
- cerr << "skrewt rejection: no date" << endl;
+ cerr << progid << " rejection: no date" << endl;
exeunt(ex_spam); // disallow mail with no date
}
inheads = 0;
@@ -256,7 +273,7 @@ int main(int _argc, const char** _argv){
gotdate++;
} else if (headword == "subject") {
if (rest.find("-please-bounce-this-") != string::npos) {
- cerr << "skrewt rejection: by request" << endl;
+ cerr << progid << " rejection: by request" << endl;
exeunt(ex_spam);
}
}
@@ -268,7 +285,7 @@ int main(int _argc, const char** _argv){
if (!getline(cin, line).fail()) {
msgsize += line.length()+1;
if (msgsize > maxsize) {
- cerr << "skrewt rejection: bigger than " << maxsize << endl;
+ cerr << progid << " rejection: bigger than " << maxsize << endl;
exeunt(ex_spam);
}
if (line == "--" + boundary) {
@@ -284,9 +301,9 @@ int main(int _argc, const char** _argv){
}
if (0) cerr << "textlines: " << textlines << endl;
if (!textlines) {
- cerr << "skrewt rejection: no text" << endl;
+ cerr << progid << " rejection: no text" << endl;
exeunt(ex_spam);
}
- cerr << "skrewt normal completion" << endl;
+ cerr << progid << " normal completion" << endl;
exit(ex_good);
}