#!/usr/bin/perl $version='$Id: ef.pl,v 1.4 2002/03/25 11:43:50 torh Exp torh $ '; ## exim blacklist generator ## ## you need this in your exim_filter: ## ## ## (c) th@bogus.net 2002 / 03 / 20 ## ## (this is probably not a good idea, but seems to work (tm)) ## $DEBUG=1; $SIG{'INT'} = "CleanExit"; $SIG{'QUIT'} = "CleanExit"; $ENV{'PATH'} = "/bin:/usr/bin"; # /bin/mv, /usr/bin/head $HOME=$ENV{'HOME'}; $TMPDIR="/var/tmp"; $CONFIG="/etc/exim/.spamtraps"; $SPAMMERS="/etc/exim/.spammers"; $LOGFILE="/var/spool/exim/log/mainlog"; ## read spamtraps (text file w/single mail address entries) ## open(ST,"$CONFIG") || die "Cannot open config file: \$\n"; while() { chop($_); if(/\@/) { $traps{$_}=1; } } close(ST); if($DEBUG) { foreach (keys %traps) { print "added: $_\n"; } } ProcessLog($LOGFILE); exit(1); ## CleanExit ## sub CleanExit { print "Shutting down...\n"; close(LOGFILE); close(OUT); dbmclose(%spam); exit(0); } ## ProcessLog ## sub ProcessLog { my($file) = @_; $FIRSTLINE=`head -1 $file`; open(LOGFILE,$file) || die "Can't open $file: $!\n"; seek(LOGFILE,0,2); $timethen=time(); while(1) { if(!-r $file) { print STDERR "Fatal: cannot open \'$file\': $!\n"; exit(0); } $FIRST = `head -1 $file`; if($FIRSTLINE ne $FIRST) { if(*LOGFILE) { close(LOGFILE); } open(LOGFILE,$file) || die "Can't open $file: $!\n"; $FIRSTLINE=`head -1 $file`; if($DEBUG) {print "DEBUG: reopened $file\n";} } ## the big sausage, look for "verify failed" ## while() { if(/.* verify failed .* recipient (\S+) from <(\S+)>.*/) { $rcpt=$1; $from=$2; if($DEBUG) {print "DEBUG: recipient: $rcpt sender: $from\n";} if(SpamTrap($rcpt,$from)) { if($DEBUG) {print "DEBUG: caught $from sending to spamtrap $rcpt\n";} } } } ## check every 10 minutes if we can take someone off our shitlist ## if(($timethen+600)$tmp") || die "Could not open temp file '$tmp': !$\n"; if($DEBUG) {print "DEBUG: created temp file $tmp\n";} if($DEBUG) {print "DEBUG: creating blacklist..";} foreach $key (keys %spam) { if($spam{$key}>0 || ($spam{$key}==-666)) { print OUT "$key:black\n"; } } close(OUT); ## safe enough? system("mv $tmp /etc/exim/blacklist"); if($DEBUG) {print "done.\n";} } dbmclose(%spam); return(1); } return(0); } ## TmpFile; create a temporary file (input is dir, returns filename); ## sub TmpFile { my($dir,$url)=@_; my($adr) = "ef"; ## generate random string and append to main part ## my($tfile)=$adr."_".RandChars(); ## make sure the filename doesn't exist ## $tfile=$adr."_".RandChars() while(-e "$dir/$tfile"); open(OUT,">$dir/$tfile");close(OUT); if($DEBUG>2) {print "DEBUG: tempdir is \'$dir\' , file is $tfile\n";} return($dir."/".$tfile); } ## RandChars; generates a string of 10 pseudorandom characters ## sub RandChars { my($a,$c,$i); for($i=0;$i<10;$i++) { if(rand(100)<50) {$a=65;} else {$a=97;} $c .= chr(rand(26)+$a); } return($c); }