Initial commit
[clearscm.git] / maps / bin / maps
1 #!/usr/bin/perl
2
3 =pod
4
5 =head1 NAME $RCSfile: maps,v $
6
7 This script filters mail based on the files nulllist, blacklist and whitelist. 
8 Input is an email message. This script extracts the From line and then parses 
9 the email address. If the email is from a sender who should be /dev/null'ed 
10 (e.g. bounce messages from mail daemons) the message will be discarded. If the
11 sender is on the blacklist then a message is sent back informing the sender that
12 he's been blacklisted. If the sender is on the white list then the email is 
13 appended to the mail drop file. Otherwise a message is sent back informing the
14 sender that in order to successfully send email the sender must register for the
15 permission to do so, along with a URL that allows the sender to sign up.
16
17 =head1 VERSION
18
19 =over
20
21 =item Author
22
23 Andrew DeFaria <Andrew@DeFaria.com>
24
25 =item Revision
26
27 $Revision: 1.1 $
28
29 =item Created:
30
31 Fri Nov 29 14:17:21  2002
32
33 =item Modified:
34
35 $Date: 2013/06/12 14:05:47 $
36
37 =back
38
39 =head1 SYNOPSIS
40
41  
42  Usage maps: [-u|ser <username>] [-ve|rbose] [-deb|ug] [-e|xecute]
43
44  Where:
45    -u|ser <username>: Set context to this username
46  
47    -v|erbose:         Be verbose
48    -de|bug:           Output debug messages
49    
50    -[no]e|xecute:     Set execute mode.         
51
52 # (c) Copyright 2000-2006, Andrew@DeFaria.com, all rights reserved.
53
54 =cut 
55
56 use strict;
57 use warnings;
58
59 use Getopt::Long;
60 use FindBin;
61 use File::Temp qw (tempfile);
62 use Net::Domain qw (hostdomain);
63
64 use lib $FindBin::Bin, '/opt/clearscm/lib';
65
66 use MAPS;
67 use MAPSLog;
68
69 use Display;
70 use Utils;
71
72 my $verbose     = 0;
73 my $execute     = 1;
74 my $userid       = $ENV{USER};
75
76 my $logpath     = "$FindBin::Bin/../log";
77 my $logfile     = "$logpath/debug.log";
78
79 # For some reason I'm not parsing messages correctly but it only seems to
80 # happen when the message is piped in from the MTA. This routine will
81 # temporarily save the messages in a file.
82 sub SaveStdin () {
83   # Generate tempfile
84   my $msgfile = tempfile ();
85
86   # Read STDIN and write it out to the tempfile
87   while (<STDIN>) {
88     print $msgfile $_;
89   } # while
90
91   # Seek to the start of the file (Note if we closed it, it would be deleted)
92   seek $msgfile, 0, 0;
93
94   # Return the filehandle
95   return $msgfile;
96 } # SaveStdin
97
98 sub save_msg {
99   my ($sender, $sender_long, $reply_to, $subject, $data) = @_;
100
101   open SAVED_MSG, ">>$logpath/$sender"
102     or die "Unable to open $logpath/$sender - $!\n";
103
104   print SAVED_MSG "Sender       = $sender\n";
105   print SAVED_MSG "Sender long  = $sender\n";
106   print SAVED_MSG "reply_to     = $reply_to\n";
107   print SAVED_MSG "subject      = $subject\n";
108   print SAVED_MSG "data:\n\n";
109   print SAVED_MSG $data;
110   print SAVED_MSG "*** END OF DATA***\n";
111 } # save_msg
112
113 sub ValidDomainUser ($) {
114   my ($sender) = @_;
115
116   my ($username, $domainname);
117
118   if ($sender =~ /(.*)\@(.*)/) {
119     $username   = $1;
120     $domainname = $2;
121   } else {
122     return 1;
123   } # if
124
125   return 1 if $domainname ne hostdomain;
126
127   # Let BICE email come through
128   return 1 if $username eq "bice";
129
130   my $uid = getpwnam $username;
131
132   return defined $uid ? 1 : 0;
133 } # ValidDomainUser
134
135 sub ProcessMsgs ($$$) {
136   my ($msgfile, $username, $user_email) = @_;
137
138   return
139     unless $execute;
140
141   while (!eof *$msgfile) {
142     my ($sender, $sender_long, $reply_to, $subject, $data) = ReadMsg (*$msgfile);
143
144     my ($onlist, $rule, $sequence, $hit_count);
145
146     if ($sender eq "" or $sender eq "@" or $sender =~ /.*\@$/) {
147       verbose "Sender not found in message";
148       next;
149     } elsif ($sender eq $user_email and
150             (lc ($sender_long) !~ lc ("\"$username\" <$user_email>") and
151              lc ($sender_long) !~ lc ("$username <$user_email>"))) {
152       verbose "Nulllisting message from sender ($sender_long) pretending to be $user_email";
153       Nulllist $sender;
154       next;
155     } # if
156
157     ($onlist, $rule, $sequence, $hit_count) = OnNulllist $sender;
158
159     if ($onlist) {
160       verbose "Nulllisting $sender";
161       Nulllist $sender, $sequence, $hit_count;
162       next;
163     } # if
164
165     ($onlist, $rule, $sequence, $hit_count) = OnBlacklist $sender;
166
167     if ($onlist) {
168       verbose "Blacklisting $sender";
169       my @msg = split /\n/, $data;
170
171       Blacklist $sender, $sequence, $hit_count, @msg;
172       next;
173     } # if 
174
175     ($onlist, $rule, $sequence, $hit_count) = OnWhitelist $sender;
176
177     if ($onlist) {
178       if (ValidDomainUser $sender) {
179         verbose "Whitelisting $sender";
180         Whitelist $sender, $data, $sequence, $hit_count;
181       } else {
182         verbose "Sender from this domain but user not found";
183         Nulllist $sender;
184       } # if
185     } else {
186       if ($sender !~ /\@/) {
187         verbose "Sender ($sender) does not appear to be a valid email address";
188       } else {
189         verbose "Returning message from $sender";
190         ReturnMsg $sender, $reply_to, $subject, $data;
191       } # if
192     } # if
193   } # while
194 } # ProcessMsgs
195
196 # Main
197 GetOptions (
198   'user=s'       => \$userid,
199   'verbose'      => sub { set_verbose },
200   'debug'          => sub { set_debug },
201   'execute!' => \$execute,
202 ) || Usage;
203
204 my $msgfile;
205
206 if ($ARGV[0] and $ARGV[0] ne "") {
207   open $msgfile, $ARGV[0];
208
209   if (!$msgfile) {
210     Error "Unable to open file ($ARGV[0]): $!\n";
211     exit 1;
212   } # if
213 } else {
214   $msgfile = SaveStdin;
215 } # if 
216
217 verbose "Starting MAPS....";
218
219 my ($username, $user_email) = SetContext $userid
220   or die "$userid is not a registered MAPS user\n";
221
222 ProcessMsgs $msgfile, $username, $user_email;
223
224 exit 0;