#! /usr/bin/perl -w ######################### # BEWARE: # # The most dangerous criminals routinely forge email from-addresses. # Therefore blacklisting addresses only works for senders # who have bad manners but are otherwise quasi-legitimate. # # Overuse of blacklisting will punish innocent parties # whose domain-names look nice to forgers. ## hint: mail-scan +from * | iconv -c \... ## | sed 's/.*@//;s/>$//' | sort | uniq -c | sort -nr > some-junk.from-count use strict; use Symbol; main: { my $baremode = 0; my @argv = @ARGV; @ARGV = (); while (@argv){ my $arg = shift @argv; if ($arg eq '-bare') { $baremode++; } else { die "Unrecognized verbiage '$arg'\n"; } } my $file = '/etc/mail/spamassassin/local.cf'; my $inch = Symbol::gensym; my $mainpart = ''; my %blacklist = (); my $verb = 'blacklist_from'; open($inch, '<', $file) || die "Could not open input file '$file'\n"; while (my $line = <$inch>) { chomp $line; my @stuff = split(' ', $line, 2); if (0+@stuff == 2 && $stuff[0] eq $verb) { my $key = lc($stuff[1]); $blacklist{$stuff[1]} ++; } else { $mainpart .= $line . "\n"; } } close $inch; my $unchanged = 0; my $new = 0; liner: while (my $line=<>){ chomp $line; my $domain = ''; if ($baremode) { my @stuff = split(' ', $line); $domain = $stuff[$#stuff]; } else { if ($line =~ m'<.*@(.*)>$') { $domain = $1; } else { print STDERR "no ''; ignoring line ...\n"; print STDERR "... '$line'\n"; next liner; } } if ($domain ne '') { my $key = "*@" . lc($domain); if (exists $blacklist{$key}) { $unchanged++; } else { $new++; } $blacklist{$key} ++; } } my $ouch = Symbol::gensym; open($ouch, '>', $file) || die "Could not open output file '$file'\n"; print $ouch $mainpart; for my $baddy (sort keys %blacklist){ print $ouch "$verb $baddy\n"; } close $ouch; my $updated = $unchanged + $new; my $total = 0+(keys %blacklist); print "$new new + $unchanged unchanged = $updated updated; $total new total\n"; }