[Mimedefang] Greylisting

David F. Skoll dfs at roaringpenguin.com
Fri Sep 5 16:07:00 EDT 2003


Hi,

Many of you may have heard about greylisting:

	http://projects.puremagic.com/greylisting/

We've had a version of greylisting in CanIt for a while.  I decided to
see how little code is required to do a simplified version of
greylisting.

The following filter tempfails sender/recipient pairs the very first time
they are encountered.  This simple rule stops an unbelievable amount of
spam.  (30+% on my machine.)

Obvious enhancements left for the reader:

1) Comment the code. :-)
2) Implement the full greylisting spec.
3) Expire old greylist data.

Have fun!

--
David.

# Partial implementation of Greylisting
use DB_File;
use Fcntl ':flock';

$DBFilename = "/var/spool/MIMEDefang/greylist.db";

sub lock_db () {
    open(LOCKFILE, ">>$DBFilename.lock") or return 0;
    flock(LOCKFILE, LOCK_EX);
    return 1;
}

sub unlock_db () {
    flock(LOCKFILE, LOCK_UN);
    close(LOCKFILE);
    unlink("$DBFilename.lock");
    return 1;
}

sub canonicalize_email ($) {
    my($email) = @_;
    # Remove angle-brackets; convert to lower-case
    $email =~ s/^<//;
    $email =~ s/>$//;
    $email = lc($email);
}

sub should_greylist ($$) {
    my($sender, $recip) = @_;
    my %hash;

    $sender = canonicalize_email($sender);
    $recip  = canonicalize_email($recip);
    my $key = "<$sender><$recip>";

    lock_db();
    tie %hash, 'DB_File', $DBFilename;
    my $ret = ++$hash{$key};
    untie %hash;
    unlock_db();
    return ($ret == 1);
}

sub filter_recipient ($$$$$$$$$) {
    my($recip, $sender, $rest_of_the_junk) = @_;
    if (should_greylist($sender, $recip)) {
	return("TEMPFAIL", "Tempfailed as anti-spam measure.  Please try again.");
    }
    return ("CONTINUE", "");
}

1;



More information about the MIMEDefang mailing list