Package: greylistd Version: 0.8.3.2 Severity: normal Tags: patch I'm using greylisting very successfully, and have included a quick enhancement.
My original setup under exim4 was: 1. accept MAIL FROM and RCPT TO 2. perform greylist check and store result 3. accept DATA 4. perform spam check to get a spam score 5. if spam check > maxgrey then reject 6. if spam check > mingrey and <= maxgrey and is on greylist then defer This was working great... bot spam would only try once, or possibly again 15-20 minutes later, but had always given up after an hour. Relayed spam would try a few times, but after an hour was (almost) always on a blacklist and so was rejectedthen. What I found though, is that because I only want to greylist emails that look like they might be spam, I accept the whole DATA session multiple times, which was bloating my smtp traffic by a factor of 5-10 on the primary server, and 100-200 on the secondary (only spammers use the secondary unless the primary is down, so almost everything is spam!). Then I decided to add a step between 2 and 3, which says if the triplet is already on the greylist, then defer it then, rather than re-checking the DATA, on the basis that the spam score won't have changed. Unfortunately greylistd always treats an unseen triplet as 'grey', with no option to specify otherwise. The attached patch adds a '--falseifnotseen' option which can only be used with 'check --grey', and causes greylistd to return false unless the triplet is actually in the database as greylisted. Another way of doing it would be to add a new 'seen --grey' command, which only returns true if the triplet is in the database as greylisted. Please check my code carefully, I have never written a line of python code before in my life! James (hoping that reportbug is going to ask me to attach the actual patch when I save this) -- System Information: Debian Release: 4.0 APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.18-3-xen-686 Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Versions of packages greylistd depends on: ii adduser 3.102 Add and remove users and groups ii debconf [debconf-2.0] 1.5.11 Debian configuration management sy ii python 2.4.4-2 An interactive high-level object-o Versions of packages greylistd recommends: ii exim4 4.63-17 metapackage to ease exim MTA (v4) -- debconf information: greylistd/autoconfig_notdone: greylistd/restartexim: true * greylistd/autoconfig_notdone_exim4:
--- greylistd.old 2007-02-14 14:36:40.000000000 +1100 +++ greylistd.new 2007-02-14 14:49:08.000000000 +1100 @@ -78,6 +78,8 @@ ### Lists/states (WHITE, GREY, BLACK) = ("white", "grey", "black") +(FALSEIFNOTSEEN) = ("falseifnotseen") + ### Additional data file sections/items (STATS, START, LASTSAVE) = ("statistics", "start", "lastsave") @@ -448,18 +450,28 @@ def do_check (options, key, update=False): - if options: - truthtest = options[0] - if not truthtest in datatypes: - raise CommandError, "'%s' is not a known state"%truthtest - else: - truthtest = None - + truthtest = None + falseifnotseen = False + for option in options: + if option in datatypes: + if truthtest: + raise CommandError, "already set type" + truthtest = option + elif option == FALSEIFNOTSEEN: + falseifnotseen = True + else: + raise CommandError, "Invalid option '%s'"%option + if falseifnotseen and truthtest != GREY: + raise CommandError, "Option 'falseifnotseen' only valid with 'grey'" + + now = int(time()) expireKeys(now) state = listStatus(key) if state is None: + if truthtest == GREY and falseifnotseen: + return "false"; state = GREY elif ((state == GREY) and