X-Git-Url: https://defaria.com/gitweb/?a=blobdiff_plain;f=maps%2Fbin%2Fmaps;h=4a9b64edd29ca8dffe08b628ba7dbe349f39eaf8;hb=dd45f3430c6ce7ad0633e2a7989c120372ef0b6f;hp=fca158691e32c5b6738a57ad6f195a456046b8f3;hpb=020a4a5ea2be725b155cae3a2cadc9aba3911b9b;p=clearscm.git diff --git a/maps/bin/maps b/maps/bin/maps index fca1586..4a9b64e 100755 --- a/maps/bin/maps +++ b/maps/bin/maps @@ -38,18 +38,18 @@ $Date: 2013/06/12 14:05:47 $ =head1 SYNOPSIS - Usage maps: [-u|ser ] [-ve|rbose] [-deb|ug] [-e|xecute] Where: -u|ser : Set context to this username - + -v|erbose: Be verbose -de|bug: Output debug messages - - -[no]e|xecute: Set execute mode. -# (c) Copyright 2000-2006, Andrew@DeFaria.com, all rights reserved. + -[no]e|xecute: Set execute mode. + -f|ile : File to use as a test message + +# (c) Copyright 2000-2021, Andrew@DeFaria.com, all rights reserved. =cut @@ -57,29 +57,34 @@ use strict; use warnings; use Getopt::Long; +use Pod::Usage; +use Email::Valid; use FindBin; use File::Temp qw (tempfile); use Net::Domain qw (hostdomain); -use lib $FindBin::Bin, '/opt/clearscm/lib'; +use lib "$FindBin::Bin/../lib"; +use lib "$FindBin::Bin/../../lib"; use MAPS; use MAPSLog; use Display; +use Logger; use Utils; -my $verbose = 0; -my $execute = 1; -my $userid = $ENV{USER}; +my %opts = ( + execute => 1, +); -my $logpath = "$FindBin::Bin/../log"; -my $logfile = "$logpath/debug.log"; +my $userid = $ENV{USER}; + +my $log; # For some reason I'm not parsing messages correctly but it only seems to # happen when the message is piped in from the MTA. This routine will # temporarily save the messages in a file. -sub SaveStdin () { +sub SaveStdin() { # Generate tempfile my $msgfile = tempfile (); @@ -95,28 +100,13 @@ sub SaveStdin () { return $msgfile; } # SaveStdin -sub save_msg { - my ($sender, $sender_long, $reply_to, $subject, $data) = @_; - - open SAVED_MSG, ">>$logpath/$sender" - or die "Unable to open $logpath/$sender - $!\n"; - - print SAVED_MSG "Sender = $sender\n"; - print SAVED_MSG "Sender long = $sender\n"; - print SAVED_MSG "reply_to = $reply_to\n"; - print SAVED_MSG "subject = $subject\n"; - print SAVED_MSG "data:\n\n"; - print SAVED_MSG $data; - print SAVED_MSG "*** END OF DATA***\n"; -} # save_msg - -sub ValidDomainUser ($) { +sub ValidDomainUser($) { my ($sender) = @_; my ($username, $domainname); if ($sender =~ /(.*)\@(.*)/) { - $username = $1; + $username = $1; $domainname = $2; } else { return 1; @@ -132,93 +122,149 @@ sub ValidDomainUser ($) { return defined $uid ? 1 : 0; } # ValidDomainUser +sub formatRule($) { + my ($rec) = @_; + + return "$rec->{pattern}\@$rec->{domain}:$rec->{sequence}/$rec->{hit_count}"; +} # formatRule + sub ProcessMsgs ($$$) { my ($msgfile, $username, $user_email) = @_; - return - unless $execute; + return unless $opts{execute}; + + while (!eof $msgfile) { + my %msgInfo = ReadMsg $msgfile; + + my ($onlist, $rec, $sequence, $hit_count); + + # Algorithm change: We now first check to see if the sender is not found + # in the message and skip it if so. Then we handle if we are the sender + # and that the from address is formatted properly. Spammers often use + # the senders email address (i.e. andrew@defaria.com) as their from address + # so we check "Andrew DeFaria ", which they have never + # forged. This catches a lot of spam actually. + # + # Next we check to see if the sender is on our whitelist. If so then we let + # them in. This allows us to say whitelist josephrosenberg@hotmail.com while + # still nulllisting all of the other hotmail.com spammers. + # + # Next we process blacklisted people as they are also of high priority. + # + # Then we process nulllist people. + # + # Finally, we handle return processing + + # Discard any email with an invalid email address + next unless Email::Valid->address($msgInfo{sender}); + + if ($msgInfo{sender} eq $user_email and + (lc ($msgInfo{sender_long}) !~ lc ("\"$username\" <$user_email>") and + lc ($msgInfo{sender_long}) !~ lc ("$username <$user_email>"))) { + $log->msg("Nulllisting message from sender ($msgInfo{sender_long}) pretending to be $user_email"); - while (!eof *$msgfile) { - my ($sender, $sender_long, $reply_to, $subject, $data) = ReadMsg (*$msgfile); + next; + } # if - my ($onlist, $rule, $sequence, $hit_count); + # Discard messges coming from andrew@clearscm.com because I don't send from + # that email address + if (lc $msgInfo{to} eq 'andrew@clearscm.com') { + $log->msg("Nullisting message from Andrew\@ClearSCM.com since I don't send from that email address"); - if ($sender eq "" or $sender eq "@" or $sender =~ /.*\@$/) { - verbose "Sender not found in message"; - next; - } elsif ($sender eq $user_email and - (lc ($sender_long) !~ lc ("\"$username\" <$user_email>") and - lc ($sender_long) !~ lc ("$username <$user_email>"))) { - verbose "Nulllisting message from sender ($sender_long) pretending to be $user_email"; - Nulllist $sender; next; } # if - ($onlist, $rule, $sequence, $hit_count) = OnNulllist $sender; + # Check whitelist: + ($onlist, $rec) = OnWhitelist $msgInfo{sender}; if ($onlist) { - verbose "Nulllisting $sender"; - Nulllist $sender, $sequence, $hit_count; + if (ValidDomainUser $msgInfo{sender}) { + $log->msg("Whitelisting $msgInfo{sender} - Rule: " . formatRule($rec)); + + Whitelist $msgInfo{sender}, $msgInfo{data}, $rec->{sequence}, $rec->{hit_count}; + } else { + $log->msg("Sender ($msgInfo{sender}) from this domain but user not found"); + + Nulllist $msgInfo{sender}; + } # if + next; } # if - ($onlist, $rule, $sequence, $hit_count) = OnBlacklist $sender; + # Check blacklist: + ($onlist, $rec) = OnBlacklist $msgInfo{sender}; if ($onlist) { - verbose "Blacklisting $sender"; - my @msg = split /\n/, $data; + $log->msg("Blacklisting $msgInfo{sender} - Rule: " . formatRule($rec)); + + Blacklist( + userid => $userid, + sender => $msgInfo{sender}, + sequence => $rec->{sequence}, + hit_count => $rec->{hit_count}, + data => $msgInfo{data}, + ); - Blacklist $sender, $sequence, $hit_count, @msg; next; } # if - ($onlist, $rule, $sequence, $hit_count) = OnWhitelist $sender; + # Check nulllist: + ($onlist, $rec) = OnNulllist $msgInfo{sender}; if ($onlist) { - if (ValidDomainUser $sender) { - verbose "Whitelisting $sender"; - Whitelist $sender, $data, $sequence, $hit_count; - } else { - verbose "Sender from this domain but user not found"; - Nulllist $sender; - } # if - } else { - if ($sender !~ /\@/) { - verbose "Sender ($sender) does not appear to be a valid email address"; - } else { - verbose "Returning message from $sender"; - ReturnMsg $sender, $reply_to, $subject, $data; - } # if + $log->msg("Nulllisting $msgInfo{sender} - Rule: " . formatRule($rec)); + + Nulllist $msgInfo{sender}, $rec->{sequence}, $rec->{hit_count}; + + next; } # if + + # Return processing: + $log->msg("Returning message from $msgInfo{sender}"); + + ReturnMsg( + userid => $userid, + sender => $msgInfo{sender}, + reply_to => $msgInfo{reply_to}, + subject => $msgInfo{subject}, + data => $msgInfo{data}, + ); } # while } # ProcessMsgs # Main -GetOptions ( - 'user=s' => \$userid, - 'verbose' => sub { set_verbose }, - 'debug' => sub { set_debug }, - 'execute!' => \$execute, -) || Usage; +GetOptions( + \%opts, + 'user=s', + 'verbose', + 'debug', + 'execute!', +) or pod2usage; + +$log = Logger->new( + path => '/var/local/log', + timestamped => 'yes', + append => 'yes', +); my $msgfile; -if ($ARGV[0] and $ARGV[0] ne "") { - open $msgfile, $ARGV[0]; +if ($ARGV[0] and $ARGV[0] ne '') { + open $msgfile, '<', $ARGV[0]; - if (!$msgfile) { - Error "Unable to open file ($ARGV[0]): $!\n"; + unless ($msgfile) { + $log->err("Unable to open file ($ARGV[0]): $!"); exit 1; } # if } else { $msgfile = SaveStdin; } # if -verbose "Starting MAPS...."; +# Get user +FindUser(userid => $userid); -my ($username, $user_email) = SetContext $userid - or die "$userid is not a registered MAPS user\n"; +my $user = GetUser; -ProcessMsgs $msgfile, $username, $user_email; +ProcessMsgs $msgfile, $user->{name}, lc $user->{email}; exit 0;