#!/usr/bin/perl ##FIXME : REMOVE THE -w above when the code is fixed ! # #This is headers_filter.pl v0.2a # #Changelog #Dec 03 : v0.2a Fix a bug when email address contains a "&" # The fix is dirty, and requires more thinking # But it works. # #Filters emails (send it headers+body) in order to hide your network mail hops from the outside world. # # #Author : Vincent Deffontaines #Copyright : Vincent Deffontaines, KDX (www.kdx.fr), Council of Europe (www.coe.int) (c) 2002 # #Please send me contributions/ modifications/ comments that could be useful to this script! # #This program is free software; you can redistribute it and/or #modify it under the terms of the GNU General Public License #as published by the Free Software Foundation; version 2 #of the License. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # #For DEBUG ONLY, not on prod #use Data::Dumper; #Maybe this one could be commented too for performance use strict; my $sendmail = "/usr/lib/sendmail"; my %filtered_patterns = (); #Data is in this part of the script, so it loads faster. #Have a look at your email headers and set this up #If you see # ######################### #Received: from foo.bar.com [whatever stuff here] # by foobar.bar.com blah blah # for user@bar.com # id ########################## #you will set up this : push @{$filtered_patterns{'Received: from foo.bar.com'}}, "\\s+by\\s+"; push @{$filtered_patterns{'Received: from foo.bar.com'}}, "\\s+for\\s+"; push @{$filtered_patterns{'Received: from foo.bar.com'}}, "\\s+id\\s+"; # The code below will interpret it as : # Line with "Received: from foo.bar.com" is filtered, and lines just below it that start with \s+{by/for/id} # will be filtered too. #you can setup several "sections" to filter, eg: push @{$filtered_patterns{'Received: by foo.bar.com'}}, "\\s+id\\s+"; #Which is a common one too. #This optimises filtering : whenever one line starts with one of these elements, script stops #looking at lines and just outputs the input as it received it. #By default only the header is filtered, NEVER the body, so this is just to make things faster. my @stop_filtering_patterns = ( "Message-ID:", "From:", "To:", "Subject:", "Date:", "Mime-Version:", "X-Mailer:", "Content-Type" ); my $end_filtering = 0; my $filter = 0; my $patt = ""; #We quote "&" else they will be damned interpreted when we run sendmail #Probably more thinking must be performed here, and probably more things need to be filtered or quoted. foreach my $argument(@ARGV) { $argument =~ s/&/\\&/; } open (SENDMAIL, "|$sendmail @ARGV") or die "Couldn't fork: $!\n"; while (not $end_filtering){ my $line = ; my $filter_this_line =0; $line =~ /^$/ and $end_filtering = 1; foreach my $pattern (@stop_filtering_patterns) { $line =~/^$pattern/ and $end_filtering =1; } if ($end_filtering) { print SENDMAIL $line; next; } foreach my $pattern (keys %filtered_patterns) { if ($line =~/^$pattern/) { $filter_this_line = 1; $filter = 1; $patt = $pattern; last; } } if ($filter) { # print STDERR "DEBUG : ".Dumper($filtered_patterns{$patt})."\n"; foreach my $subpattern(@{$filtered_patterns{$patt}}) { if ($line =~ /^$subpattern/) { $filter_this_line = 1; last; } } unless ($filter_this_line) { $filter = 0; } } unless ($filter_this_line) { print SENDMAIL $line; } } while (){print SENDMAIL $_;} print SENDMAIL ".\n"; close SENDMAIL;