Hi, I've been using OpenBSD spamd for a while now and I find it really great.
One feature I wanted to try was the ability to trap and whitelist hosts for different periods of time, depending on the host's behaviour. As you well know, there are some really bad guys out there. So I wrote this little patch that allows the user to specify how many hours the keys should be trapped or whitelisted. I've being using it for some time, and I thought someone else might have the same need. Regards, Emilio Lucena --- spamdb.c.orig Sat May 17 07:48:06 2008 +++ spamdb.c Mon Jul 18 08:04:29 2011 @@ -39,10 +39,10 @@ #define SPAMTRAP 2 int dblist(DB *); -int dbupdate(DB *, char *, int, int); +int dbupdate(DB *, char *, int, int, time_t); int -dbupdate(DB *db, char *ip, int add, int type) +dbupdate(DB *db, char *ip, int add, int type, time_t exp) { DBT dbk, dbd; struct gdata gd; @@ -97,10 +97,10 @@ switch (type) { case WHITE: gd.pass = now; - gd.expire = now + WHITEEXP; + gd.expire = now + exp; break; case TRAPHIT: - gd.expire = now + TRAPEXP; + gd.expire = now + exp; gd.pcount = -1; break; case SPAMTRAP: @@ -139,10 +139,10 @@ switch (type) { case WHITE: gd.pass = now; - gd.expire = now + WHITEEXP; + gd.expire = now + exp; break; case TRAPHIT: - gd.expire = now + TRAPEXP; + gd.expire = now + exp; gd.pcount = -1; break; case SPAMTRAP: @@ -261,7 +261,7 @@ static int usage(void) { - fprintf(stderr, "usage: %s [[-Tt] -a keys] [[-Tt] -d keys]\n", __progname); + fprintf(stderr, "usage: %s [[-Tt] -x hours -a keys] [[-Tt] -d keys]\n", __progname); exit(1); /* NOTREACHED */ } @@ -270,10 +270,12 @@ main(int argc, char **argv) { int i, ch, action = 0, type = WHITE, r = 0, c = 0; + time_t exp = 0; HASHINFO hashinfo; DB *db; + const char *errstr; - while ((ch = getopt(argc, argv, "adtT")) != -1) { + while ((ch = getopt(argc, argv, "adtTx:")) != -1) { switch (ch) { case 'a': action = 1; @@ -287,6 +289,14 @@ case 'T': type = SPAMTRAP; break; + case 'x': + /* limit exp to 2160 hours (90 days) */ + exp = strtonum(optarg, 1, (24 * 90),&errstr); + if (errstr) + usage(); + /* convert to seconds from hours */ + exp *= (60 * 60); + break; default: usage(); break; @@ -294,7 +304,7 @@ } argc -= optind; argv += optind; - if (action == 0&& type != WHITE) + if ((action == 0&& type != WHITE) || (action != 1&& exp != 0)) usage(); memset(&hashinfo, 0, sizeof(hashinfo)); @@ -314,10 +324,12 @@ case 0: return dblist(db); case 1: + if (exp == 0) + exp = type ? TRAPEXP : WHITEEXP; for (i=0; i<argc; i++) if (argv[i][0] != '\0') { c++; - r += dbupdate(db, argv[i], 1, type); + r += dbupdate(db, argv[i], 1, type, exp); } if (c == 0) errx(2, "no addresses specified"); @@ -326,7 +338,7 @@ for (i=0; i<argc; i++) if (argv[i][0] != '\0') { c++; - r += dbupdate(db, argv[i], 0, type); + r += dbupdate(db, argv[i], 0, type, exp); } if (c == 0) errx(2, "no addresses specified");