Hi,
I just wrote greylisting support for SA (to use at SMTP time with SA-Exim,
http://marc.merlins.org/linux/exim/sa.html)
(patched attached if you're interested)
I call my rule as such:
header GREYLIST_ISWHITE eval:greylisting('/var/spool/sa-exim/tuplets', "dir",
"1800", "X-SA-Exim-Connect-IP", "X-SA-Exim-Mail-From", "X-SA-Exim-Rcpt-To")
describe GREYLIST_ISWHITE The incoming server has been whitelisted for this
receipient
score GREYLIST_ISWHITE -6
I would however like the following thing:
How do I run this rule close to last, and only if 5 < current score < 10
Is there a way to do this cleanly without patching SA some more?
Thanks
Marc
PS: Here's the patch:
--- EvalTests.pm.orig Tue Dec 30 11:48:38 2003
+++ EvalTests.pm Sun Feb 15 11:22:22 2004
@@ -1863,6 +1863,142 @@
return 0;
}
+
+# This was originally written to implement greylisting in SA-Exim, although
+# I have tried to make it more general and allow for reuse in other MTAs
+# (although they will need to
+# 1) be running SA at SMTP time
+# 2) Provide the list of rcpt to and env from in some headers for SA to read
+# 3) Provide the IP of the connecting host )
+#
+# This rule should get a negative score so that if we've already seen the
+# greylisting tuplet before, we lower the score, which hopefully brings us from
+# a tempreject to an accept (at least that's how sa-exim does it)
+# -- Marc <[EMAIL PROTECTED]> 2004/01/19
+
+sub greylisting {
+ # db/file/dir / pointer type / how many secs to greylist after 1st connection
+ my ($self, $dirorfileordb, $method, $greylisttime,
+ $connectiphdr, $envfromhdr, $rcpttohdr) = @_;
+ my $dirorfile = shift @_;
+
+ my $connectip;
+ my $envfrom;
+ my $rcptto;
+ my @rcptto;
+ my $iswhitelisted=0;
+
+ if (not $connectip = $self->get($connectiphdr))
+ {
+ warn "Couldn't get Connecting IP header $connectiphdr, skipping
greylisting call\n";
+ return 0;
+ }
+ chomp($connectip);
+ # Clean up input (for security, if you use files/dirs)
+ $connectip =~ s#/#-#g;
+
+ if (not $envfrom = $self->get($envfromhdr))
+ {
+ warn "Couldn't get Envelope From header $envfromhdr, skipping greylisting
call\n";
+ return 0;
+ }
+ chomp($envfrom);
+ # Clean up input (for security, if you use files/dirs)
+ $envfrom =~ s#/#-#g;
+
+ if (not $rcptto = $self->get($rcpttohdr))
+ {
+ warn "Couldn't get Rcpt To header $rcpttohdr, skipping greylisting call\n";
+ return 0;
+ }
+ chomp($rcptto);
+ # Clean up input (for security, if you use files/dirs)
+ $rcptto =~ s#/#-#g;
+ @rcptto = split(/, /, $rcptto);
+
+ foreach $rcptto (@rcptto)
+ {
+ my $ipdir = "$dirorfileordb/$connectip";
+ my $tupletdir = "$ipdir/$envfrom";
+ my $tuplet = "$tupletdir/$rcptto";
+
+ # The dir method is easy to fiddle with and expire records in (with
+ # a find | rm) but it's probably more I/O extensive than a real DB
+ # and suffers from directory size problems if a specific IP is sending
+ # generating tens of thousands of tuplets. -- Marc
+ if ($method eq "dir")
+ {
+ # make directory whether it's there or not (faster than test and set)
+ mkdir $ipdir;
+ mkdir $tupletdir;
+
+ if (not -e $tuplet)
+ {
+ # If the tuplets aren't there, that's a rule failure, we touch them
+ # and continue in case there are other ones
+ umask 0770;
+ open (TUPLET, ">$tuplet") or warn "Can't create $tuplet: $!";
+ print TUPLET time."\n";
+ print TUPLET "Status: Greylisted\n";
+ print TUPLET "Whitelisted Count: 0\n";
+ print TUPLET "Query Count: 1\n";
+ close TUPLET or warn "Can't create $tuplet: $!";;
+ }
+ else
+ {
+ my $time;
+ my $status;
+ my $whitelistcount;
+ my $querycount;
+
+ # Take into account race condition of expiring deletes and us running
+ open (TUPLET, "<$tuplet") or goto diskerror;
+ $time=<TUPLET> or goto diskerror;
+ $status=<TUPLET> or goto diskerror;
+ $whitelistcount=<TUPLET> or goto diskerror;
+ $whitelistcount=~s/.*: //;
+ $querycount=<TUPLET> or goto diskerror;
+ $querycount=~s/.*: //;
+ close (TUPLET);
+
+ $querycount++;
+ if (($time - time) > $greylisttime)
+ {
+ $status="Whitelisted";
+ $whitelistcount++;
+ }
+
+ umask 0770;
+ open (TUPLET, ">$tuplet") or warn "Can't recreate $tuplet: $!";
+ print TUPLET "$time\n";
+ print TUPLET "Status: $status\n";
+ print TUPLET "Whitelisted Count: $whitelistcount\n";
+ print TUPLET "Query Count: $querycount\n";
+ close TUPLET or warn "Can't recreate $tuplet: $!";;
+
+ # We continue processing the other receipients, to setup or
+ # update their counters
+ if ($status="Whitelisted")
+ {
+ $iswhitelisted=1;
+ }
+ }
+ }
+ elsif ($method eq "file")
+ {
+ warn "codeme\n";
+ }
+ elsif ($method eq "db")
+ {
+ warn "codeme\n";
+ }
+ }
+
+ diskerror:
+ return $iswhitelisted;
+}
+
+
###########################################################################
# BODY TESTS:
###########################################################################
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems & security ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/ | Finger [EMAIL PROTECTED] for PGP key