root/trunk/hldfilter/hldfilter

Revision 32, 25.7 KB (checked in by wombat, 9 years ago)

Fixed checkuser bug

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl
2###########################################################################
3#
4#      Copyright Dan Cardamore <wombat@hld.ca> 2000 - 2001
5#      This program is licensed under the GNU GPL.  Since this is free
6#      software, the author assumes no liability for it and the damages
7#      that it may cause.
8#
9#      Please read the README file.
10#      http://www.hld.ca/opensource/hldfilter
11#
12###########################################################################
13#       $rcs = ' $Id: hldfilter,v 3.1 2001/06/01 17:35:32 wombat Exp $ ' ;
14###########################################################################
15
16use strict;
17use Mail::Audit;      # this is for filtering mail
18use Date::Manip;      # this is for logging the date
19use Mail::Address;    # For extracting email addresses out
20use Mail::RBL;        # Real Time black hole list
21use Mail::CheckUser;  # Checks if the email address is valid
22use MIME::Lite;       # For sending mail
23use Getopt::Long;     # for getting command line options
24
25############################################################################
26
27use vars (
28            '$VERSION',
29            '$home',
30            '$now',
31            '$msg',
32            '$from',
33            '$to',
34            '$subject',
35            '$cc',
36            '$configDir',
37            '$logfile',
38            '%rc',
39            '%mailback',
40            '%rules',
41            '%subjectrules',
42            '%forwardrules',
43            '@reject',
44            '@rejectspam',
45            '@ignore',
46            '$opt_reject',
47            '$opt_forward',
48            '$opt_rejectspam',
49            '$opt_ignore',
50            '$opt_version',       
51            '$opt_spamcop',
52            '$opt_addrule',
53            '$opt_addsubjectrule',
54            '$opt_extractfrom',
55            '$opt_extractto',
56            '$opt_extractsubject',
57            '$opt_extractcc',
58            '$opt_from',
59            '$opt_to',
60            '$opt_subject',
61            '$opt_cc',
62            '$opt_folder',
63            '$opt_help',
64            '$opt_about',
65            '$opt_init'
66         );
67
68$VERSION = "2.4";
69my $uid = $>;
70my $home = (getpwuid ($uid))[7];
71my $configDir = $home . "/.hldfilter";
72my $logfile = $configDir . "/log";
73
74sub usage {
75    print <<USAGE;
76hldfilter --option value -option2 value
77   Copyright Dan Cardamore 2000-2001. <wombat\@hld.ca>
78   http://www.hld.ca/opensource/hldfilter
79Options:
80  --reject:\t\tAdd sender to reject list
81  --forward:\t\tForward this message
82  --ignore:\t\tAdd sender to ignore list
83  --rejectspam:\t\tAdd sender to rejectspam list
84  --init:\t\tInitialize configuration files for HLDFilter
85  --about:\t\tInformation about this program
86  --version:\t\tDisplay version number
87  --addsubjectrule:\tCreate a subject rule.  A prompt for the subject
88    \t\t\twill be given.
89  --extractfrom\t\tWhen a piped message is given, the "From: " field will
90    \t\t\tbe extracted.
91  --extractsubject\tWhen a piped message is given, the "Subject: " field
92    \t\t\twill be extracted.
93  --extractto\t\tWhen a piped message is given, the "To: " field will
94    \t\t\tbe extracted.
95  --extractcc\t\tWhen a piped message is given, the "Cc: " field will
96    \t\t\tbe extracted.
97  --from\t\tSpecify the "From: " field.
98  --to\t\t\tSpecify the "To: " field.
99  --cc\t\t\tSpecify the "Cc: " field.
100  --subject\t\tSpecify the "Subject: " field.
101  --folder\t\tSpecify the "Folder: " field.
102USAGE
103    exit;
104}
105
106sub commandLine {
107    &GetOptions(
108        "reject", \$opt_reject,
109        "forward", \$opt_forward,
110        "ignore", \$opt_ignore,
111        "about", \$opt_about,
112        "version", \$opt_version,
113        "init", \$opt_init,
114        "rejectspam", \$opt_rejectspam,
115        "spamcop", \$opt_spamcop,
116        "addrule", \$opt_addrule,
117        "addsubjectrule", \$opt_addsubjectrule,
118        "extractfrom", \$opt_extractfrom,
119        "extractcc", \$opt_extractcc,
120        "extractto", \$opt_extractto,
121        "extractsubject", \$opt_extractsubject,
122        "from=s", \$opt_from,
123        "to=s", \$opt_to,
124        "cc=s", \$opt_cc,
125        "subject=s", \$opt_subject,
126        "folder=s", \$opt_folder,
127        "help", \$opt_help,
128        "<>", \&usage
129    );
130
131    if (defined $opt_help) {
132        &usage;
133    }
134
135    if (defined $opt_version) {
136      print "hldfilter version $VERSION\n";
137      exit;
138    }
139
140    # check if we got any parameters or not
141    unless (defined $opt_reject or defined $opt_forward or defined $opt_ignore
142                or defined $opt_rejectspam or defined $opt_spamcop or
143                    defined $opt_addrule or defined $opt_addsubjectrule or
144                    defined $opt_about or defined $opt_init) {
145        return;
146    }
147
148    if (defined $opt_about) {
149        print <<ABOUT;
150   Copyright Dan Cardamore 2000-2001. <wombat\@hld.ca>
151   http://www.hld.ca/opensource/hldfilter
152
153HLDFilter is an email filtering program which can do many things including
154web based statistics of this filtering, auto responder, and auto spam
155complaints.
156
157This program is released under the GNU GPL.  It is important to note that
158no warranty of any kind is offered or implied with this software.
159
160Please email me at wombat\@hld.ca for any bugs.  General discussions should be
161directed to the mailing list at hldfilter\@hld.ca.
162
163ABOUT
164
165        exit;
166    }
167
168    # Initialize the users configuration
169    if (defined $opt_init) {
170        print "Your config dir is: $configDir\n";
171       
172        if (-e $configDir) {
173            print "$configDir exists.  Please delete it before running init\n";
174            exit(1);
175        }
176
177        if (-e "$home/.forward") {
178            print "$home/.forward exists.  " .
179                "Please delete it before running init\n";
180            exit 1;
181        }
182
183        print "What is your mail folder directory (not spool): ";
184        my $maildir = <STDIN>;
185        chop $maildir;
186        $maildir =~ s/\/$//;  # remove end / if any
187       
188
189        print "Where do you want your stats directory?\n";
190        print "  Note: This can be web accessible if you want, but does\n";
191        print "        not need to be.\n";
192        print "Stats Directory: ";
193        my $statsdir = <STDIN>;
194        chop $statsdir;
195        $statsdir =~ s/\/$//;  # remove end / if any
196 
197
198        print "Your email address: ";
199        my $email = <STDIN>;
200        chop $email;
201
202        if (not defined $email or not defined $statsdir or not defined $maildir)
203        {
204            print "You must specify all the previous options!\n";
205            exit 1;
206        }
207
208        mkdir $configDir, 0700 or die print $!;
209        open (FILE, ">$configDir/hldfilter.rc");
210        flock (FILE, 2);
211        print FILE <<HLDFILTERRCFILE;
212# HLDFilter Config File.  Anything following a '#' will be ignored.
213
214maildir=$maildir   # the directorying containing mail folders
215statsdir=$statsdir  # the stats direcotory
216
217loglevel=1    # set to 0 if you don't want logs
218statslevel=1  # set to 0 if you don't want stats
219
220email=$email  # your email address
221smtpserver=localhost         # your outgoing mailserver
222rejectmsg=Message Not Accepted   # message to reject with
223
224CheckSenderValidity=no      # check how valid the sender's email address is
225tidyMessages=yes             # clean up messages?  (not tested thorougly)
226replyInvalidUser=no          # should we reply to invalid users?
227RejectedSpamBounceISP=no    # send mail to abuse\@theirISP.com?
228IgnoreSpamBounceISP=no       # do the same when we ignore
229InvalidUserBounceISP=no     # again, but with invalid email addresses
230
231Stats_HideSpammersEmail=no   # hide the spammers email addresses
232Stats_HideAcceptedEmail=yes   # hide the accepted email addresses
233TopSpammersCount=10          # 0 is all.  This is the max number shown
234TopAcceptedCount=10          # 0 is all.
235
236HLDFILTERRCFILE
237        flock (FILE, 8);
238        close (FILE);
239
240
241        open (FILE, ">$configDir/forwardrules") or die ($!);
242        flock (FILE, 2);
243        flock (FILE, 8);
244        close (FILE);
245
246        open (FILE, ">$configDir/ignore") or die ($!);
247        flock (FILE, 2);
248        flock (FILE, 8);
249        close (FILE);
250
251        open (FILE, ">$configDir/reject") or die ($!);
252        flock (FILE, 2);
253        flock (FILE, 8);
254        close (FILE);
255
256        open (FILE, ">$configDir/log") or die ($!);
257        flock (FILE, 2);
258        flock (FILE, 8);
259        close (FILE);
260
261        open (FILE, ">$configDir/mailback") or die ($!);
262        flock (FILE, 2);
263        flock (FILE, 8);
264        close (FILE);
265
266        open (FILE, ">$configDir/rules") or die ($!);
267        flock (FILE, 2);
268        flock (FILE, 8);
269        close (FILE);
270
271        open (FILE, ">$configDir/rejectspam") or die ($!);
272        flock (FILE, 2);
273        flock (FILE, 8);
274        close (FILE);
275
276        open (FILE, ">$configDir/stats.ignore") or die ($!);
277        flock (FILE, 2);
278        flock (FILE, 8);
279        close (FILE);
280
281        open (FILE, ">$configDir/subjectrules") or die ($!);
282        flock (FILE, 2);
283        flock (FILE, 8);
284        close (FILE);
285
286        # stats
287        mkdir "$statsdir", 0755 or die print $!;
288        open (FILE, ">$statsdir/footer.shtml") or die ($!);
289        flock (FILE, 2);
290        print FILE "</body>\n</html>\n";
291        flock (FILE, 8);
292        close (FILE);
293
294        open (FILE, ">$statsdir/header.shtml") or die ($!);
295        flock (FILE, 2);
296        print FILE "<html>\n<head><META HTTP-EQUIV=\"expires\" CONTENT=\"0\">".
297            "</head>\n<body bgcolor=white>\n\n";
298        flock (FILE, 8);
299        close (FILE);
300
301        open (FILE, ">$statsdir/index.shtml") or die ($!);
302        flock (FILE, 2);
303        print FILE "<!--#include virtual=\"header.shtml\"-->\n";
304        print FILE "<!--#include virtual=\"stats.shtml\"-->\n";
305        print FILE "<!--#include virtual=\"footer.shtml\"-->\n";
306        flock (FILE, 8);
307        close (FILE);
308
309        open (FILE, ">$statsdir/stats.shtml") or die ($!);
310        flock (FILE, 2);
311        print FILE "<b>Please run statsgen.pl to update this</b>\n";
312        flock (FILE, 8);
313        close (FILE);
314
315        open (FILE, ">$statsdir/stats.dat") or die ($!);
316        flock (FILE, 2);
317        flock (FILE, 8);
318        close (FILE);
319
320        # Update .forward file
321        open (FILE, ">$home/.forward") or die ($!);
322        print FILE "\"|/usr/local/bin/hldfilter\"\n";
323        close FILE;
324
325
326        print <<ENDINIT;
327HLDFilter has been configured for your use now.  Please test it by sending
328yourself an email.  If you receive it, and the $configDir/log shows
329no errors than things should be working well. 
330
331Please edit $configDir/hldfilter.rc to customize your install.
332
333If you would like to have your stats updated automatically, you can
334easily do so using cron.  Type 'crontab -e' at the command line
335and then add the following line to that file and save it:
33630 1 * * * /usr/local/bin/statsgen.pl
337
338Please email me \@ wombat\@hld.ca if you find any bugs.
339
340ENDINIT
341       
342        exit;
343    }
344
345    # check if we need to extract anything
346    if (defined $opt_extractfrom or defined $opt_extractcc or
347            defined $opt_extractto or defined $opt_extractsubject) {
348            # extract information out of the email
349
350        $msg = Mail::Audit->new;
351        $from = $msg->from() if defined $opt_extractfrom;
352        $cc = $msg->cc() if defined $opt_extractcc;
353        $to = $msg->to() if defined $opt_extractto;
354        $subject = $msg->subject() if defined $opt_extractsubject;
355    }
356
357    # override any extracted info from the message with our own commandline
358    # args.
359
360    $from = $opt_from if defined $opt_from;
361    $to = $opt_to if defined $opt_to;
362    $cc = $opt_cc if defined $opt_cc;
363    $subject = $opt_subject if defined $opt_subject;
364
365    # perform actions
366    if (defined $opt_reject or defined $opt_rejectspam or defined $opt_ignore) {
367        my $pMsg;
368
369        # Handle Cases where they are running more than one at a time
370        if (defined $opt_reject and defined $opt_rejectspam) {
371            print "Can't reject, and rejectspam\n";
372            exit(1);
373        }
374        if (defined $opt_reject and defined $opt_ignore) {
375            print "Can't reject, and ignore\n";
376            exit(1);
377        }
378        if (defined $opt_rejectspam and defined $opt_ignore) {
379            print "Can't rejectspam, and ignore\n";
380            exit(1);
381        }
382
383        if (defined $opt_reject) {
384            open (FILE, ">>$configDir/reject") or &error($!);
385            $pMsg = "Rejecting";
386        }
387        elsif (defined $opt_rejectspam) {
388            open (FILE, ">>$configDir/rejectspam") or &error($!);
389            $pMsg = "Rejecting spam";
390        }
391        elsif (defined $opt_ignore) {
392            open (FILE, ">>$configDir/ignore") or &error($!);
393            $pMsg = "Ignoring";
394        }
395 
396        flock (FILE, 2);
397        if (defined $from) {
398            print FILE "$from\n";
399            print "$pMsg mail from $from\n";
400        }
401        if (defined $to) {
402            print FILE "$to\n";
403            print "$pMsg mail to $to\n";
404        }
405        if (defined $cc) {
406            print FILE "$cc\n";
407            print "$pMsg mail carbon-copied to $cc\n";
408        }
409        flock (FILE, 8);
410        close (FILE);
411
412        unless (defined $from or defined $to or defined $cc) {
413            print "from, to, or cc were not specified.  ABORTING\n";
414            exit (1);
415        }
416     }
417   
418    elsif (defined $opt_forward) {
419        print "Reading Message to forward\n";
420        if (not defined $to) {
421            print "To field not specified.  ABORTING\n";
422            exit (1);
423        }
424        $subject ||= "";
425        my $data = <STDIN>;
426        my $sendmail = MIME::Lite->new(
427                From     => $rc{'email'},
428                To       => $to,
429                Subject  => $subject,
430                Type     => "text/plain",
431                Encoding => '7bit',
432                Data     => $data
433            );
434        MIME::Lite->send('smtp', 'localhost', Timeout => 60);
435        $sendmail->send;
436        die;
437    }
438
439    elsif (defined $opt_spamcop) {
440        print "Missing feature, next release\n";
441        exit (1);
442    }
443
444    elsif (defined $opt_addrule) {
445        print "Missing feature, next release\n";
446        exit (1);
447    }
448
449    elsif (defined $opt_addsubjectrule) {
450        if (not defined $subject or not defined $opt_folder) {
451            print "folder or subject not specified.  ABORTING\n";
452            exit (1);
453        }
454        open (FILE, ">>$configDir/subjectrules") or &error($1);
455        flock (FILE, 2);
456        print FILE "$subject~:~$opt_folder\n";
457        flock (FILE, 8);
458        close (FILE);
459    }
460    exit;
461}
462
463sub writelog {
464        my $entry = shift;
465        if ($rc{'loglevel'} < 1) { return; }  # no logging, return
466
467        my $date = UnixDate($now, "%l");
468        open (LOG, ">>$logfile") or die "Cannot open log file";
469        flock (LOG, 2);
470        print LOG "$date~:~$entry\n";
471        flock (LOG, 8);
472        close (LOG);
473        return 1;
474}
475
476sub error {
477        my $error = shift;
478
479    # Build the message
480        my $sendmail = MIME::Lite->new(
481                    From     => $rc{'email'},
482                    To       => $rc{'email'},
483                    Subject  => "[HLDFilter] Error.  Please look at log file",
484                    Type     => "text/plain",
485                    Encoding => '7bit',
486                    Data     => $error
487                );
488        MIME::Lite->send('smtp', 'localhost', Timeout => 60);
489        $sendmail->send;
490
491        $error = "ERROR: $error";
492        &writelog($error);
493        $msg->accept;  #  we're about to die so save the message
494        confess ($error);
495}
496
497sub warn {
498        my $error = shift;
499
500    # Build the message
501        my $sendmail = MIME::Lite->new(
502                    From     => $rc{'email'},
503                    To       => $rc{'email'},
504                    Subject  => "[HLDFilter] Error.  Please look at log file",
505                    Type     => "text/plain",
506                    Encoding => '7bit',
507                    Data     => $error
508                );
509        MIME::Lite->send('smtp', 'localhost', Timeout => 60);
510        $sendmail->send;
511
512        $error = "ERROR: $error";
513        &writelog($error);
514}
515
516sub rblCheck {
517        my @addresses = Mail::Address->parse($from);
518        my $host = $addresses[0]->host();
519
520        my $checkRBL = new Mail::RBL('list.org');
521        if ($checkRBL->check($host)) {
522        # the host is in the RBL
523        my $logmsg = "SPAM(REJECTED_RBL)-> \n" .
524                "   From: $from\n" .
525                "   Subject: $subject\n" .
526                "   To: $to\n" .
527                "   Cc: $cc";
528        &writelog($logmsg);
529        &stats("rbl");
530        $msg->reject("You are in the real-time black hole list. REJECTED");
531        return undef;  # failure
532        }
533        return 1;
534}
535
536sub checkUser {
537    unless ($rc{'CheckSenderValidity'} eq "yes") {
538        return;
539    }
540
541    my @addresses = Mail::Address->parse($from);
542    my $emailAddress = $addresses[0]->address();
543
544    my $res = Mail::CheckUser::check_email($emailAddress);
545
546    if ($res) {
547        return 1;  # passed test
548    }
549    else {
550        my $logmsg;
551        &stats("checkuser");
552        if ($rc{'replyInvalidUser'} eq "yes") {
553            $logmsg = "SPAM(REJECTED_INVALID_USER)-> \n" .
554                    "   From: $from\n" .
555                    "   Subject: $subject\n" .
556                    "   To: $to\n" .
557                    "   Cc: $cc";
558            &writelog($logmsg);
559            replyAbuseISP() if ($rc{'InvalidUserBounceISP'} eq "yes");
560            $msg->reject("Your email address or your mailserver are invalid");
561        }
562        else {
563            $logmsg = "SPAM(IGNORED_INVALID_USER)-> \n" .
564                    "   From: $from\n" .
565                    "   Subject: $subject\n" .
566                    "   To: $to\n" .
567                    "   Cc: $cc";
568            &writelog($logmsg);
569            replyAbuseISP() if ($rc{'InvalidUserBounceISP'} eq "yes");
570            $msg->ignore;
571        }
572        return undef;
573    }
574}
575
576sub stats {
577        my $type = shift;
578        if ($rc{'statslevel'} < 1) { return; }
579
580        my @addresses = Mail::Address->parse($from);
581        my $onlyemail = $addresses[0]->address();
582
583    unless ( open (FILE, ">>$rc{'statsdir'}/stats.dat") ) {
584        warn($!);
585        return;
586    }
587        flock (FILE, 2);
588        print FILE "$onlyemail~:~$now~:~$type\n";
589        flock (FILE, 8);
590        close (FILE);
591    return;
592}
593
594sub getConfig {
595        open (RC, "<$configDir/hldfilter.rc") or &error($!);
596        flock (RC, 2);
597        while (<RC>) {
598                chomp;
599                s/\s*#.*//;             # no comments
600                s/^\s+//;               # no leading white
601                s/\s+$//;               # no trailing white
602                next unless length;     # anything left?
603        m/=/;
604        $rc{$`} = $';           # $key = $value
605        }
606        flock (*RC, 8);
607        close(*RC);
608        return 1;  # sucess
609}
610
611sub getRules {
612        open (RULES, "<$configDir/rules") or &error($!);
613        flock (RULES, 2);
614        my @ruleset = <RULES>;
615        flock (RULES, 8);
616        close (RULES);
617        chomp @ruleset;
618
619        foreach my $line (@ruleset) {
620    if ($line eq "") { next; }
621        my ($key, $folder) = split /~:~/, $line;
622        $rules{$key} = $folder;
623    }
624
625        open (SUBJECTRULES, "<$configDir/subjectrules") or &error($!);
626        flock (SUBJECTRULES, 2);
627        @ruleset = <SUBJECTRULES>;
628        flock (SUBJECTRULES, 8);
629        close (SUBJECTRULES);
630        chomp @ruleset;
631
632        foreach my $line (@ruleset) {
633    if ($line eq "") { next; }
634        my ($key, $folder) = split /~:~/, $line;
635        $subjectrules{$key} = $folder;
636    }
637
638        open (FORWARDRULES, "<$configDir/forwardrules") or &error($!);
639        flock (FORWARDRULES, 2);
640        @ruleset = <FORWARDRULES>;
641        flock (FORWARDRULES, 8);
642        close (FORWARDRULES);
643        chomp @ruleset;
644
645        foreach my $line (@ruleset) {
646    if ($line eq "") { next; }
647                my ($key, $address) = split /~:~/, $line;
648                $forwardrules{$key} = $address;
649        }
650
651        open (REJECT, "<$configDir/reject") or &error($!);
652        flock (REJECT, 2);
653        @reject = <REJECT>;
654        flock (REJECT, 8);
655        close (REJECT);
656        chomp @reject;
657
658    for (my $i = 0; $i <= $#reject; $i++){
659        if ($reject[$i] eq "") { splice @reject, $i, 1; }
660    }
661
662        open (REJECTSPAM, "<$configDir/rejectspam") or &error($!);
663        flock (REJECTSPAM, 2);
664        @rejectspam = <REJECTSPAM>;
665        flock (REJECTSPAM, 8);
666        close (REJECTSPAM);
667        chomp @rejectspam;
668
669    for (my $i = 0; $i <= $#rejectspam; $i++){
670        if ($rejectspam[$i] eq "") { splice @rejectspam, $i, 1; }
671    }
672
673
674        open (IGNORE, "<$configDir/ignore") or &error($!);
675        flock (IGNORE, 2);
676        @ignore = <IGNORE>;
677        flock (IGNORE, 8);
678        close (IGNORE);
679        chomp @ignore;
680
681    for (my $i = 0; $i <= $#ignore; $i++){
682        if ($ignore[$i] eq "") { splice @ignore, $i, 1; }
683    }
684
685        open (MAIL, "<$configDir/mailback") or &error($!);
686        flock (MAIL, 2);
687        @ruleset = <MAIL>;
688        flock (MAIL, 8);
689        close (MAIL);
690        chomp @ruleset;
691
692        foreach my $line (@ruleset) {
693    if ($line eq "") { next; }
694                my ($key, $type, $input, $body) = split /~:~/, $line;
695                $mailback{$key} = $type . "~:~" . $input . "~:~" . $body;
696        }
697        return 1;
698}
699
700sub replyAbuseISP {
701    my @addresses = Mail::Address->parse($from);
702    my $ISPdomain = $addresses[0]->host();
703
704    $msg->resend("abuse\@$ISPdomain");
705    return;
706}
707
708               ###########
709               #         #
710               #  Start  #
711               #         #
712               ###########
713
714
715&commandLine;
716
717&getConfig;
718&getRules;
719
720$now = DateCalc("today");
721$msg = Mail::Audit->new unless defined $msg;
722$msg->tidy if ($rc{'tidyMessages'} eq "yes");
723
724$from = $msg->from();
725$to   = $msg->to();
726$cc   = $msg->cc();
727$subject = $msg->subject();
728chomp ($from, $to, $subject, $cc);
729
730
731&rblCheck();   # we already rejected them at this point
732&checkUser();  # we already rejected them at this point
733
734for my $pattern (keys %forwardrules) {
735  if ( ($subject =~ /$pattern/) ) {
736    my $logmsg = "Forward ($forwardrules{$pattern})-> \n" .
737              "   From: $from\n" .
738              "   Subject: $subject\n" .
739              "   To: $to\n" .
740              "   Cc: $cc";
741                &writelog($logmsg);
742                &stats("forward~:~$forwardrules{$pattern}");
743
744    $msg->resend($forwardrules{$pattern});  #forward the message
745    $msg->ignore;
746  }
747}
748
749##  Mailing lists
750for my $pattern (keys %rules) {
751  if ( ($from =~ /$pattern/i) or
752    ($to =~ /$pattern/i) or ($cc =~ /$pattern/i) ) {
753                my $logmsg = "$rules{$pattern}-> \n" .
754              "   From: $from\n" .
755              "   Subject: $subject\n" .
756              "   To: $to\n" .
757              "   Cc: $cc";
758                &writelog($logmsg);
759                &stats("normal~:~$rules{$pattern}");
760
761    $msg->accept($rc{'maildir'}."/".$rules{$pattern})
762  }
763}
764for my $pattern (keys %subjectrules) {
765  if ( ($subject =~ /$pattern/) ) {
766    my $logmsg = "$subjectrules{$pattern}-> \n" .
767              "   From: $from\n" .
768              "   Subject: $subject\n" .
769              "   To: $to\n" .
770              "   Cc: $cc";
771    &writelog($logmsg);
772    &stats("normal~:~$subjectrules{$pattern}");
773
774    $msg->accept($rc{'maildir'}."/".$subjectrules{$pattern})
775  }
776}
777
778## Mail backs
779for my $pattern (keys %mailback) {
780    if ($subject =~ /$pattern/) {
781        my ($type, $input, $body) = split /~:~/, $mailback{$pattern};
782        my $logmsg = "Mail Back ($pattern)-> \n" .
783                    "   From: $from\n" .
784                    "   Subject: $subject\n" .
785                    "   To: $to\n" .
786                    "   Cc: $cc";
787        &writelog($logmsg);
788        &stats("normal~:~mailback");
789
790        if ($type =~ /file/i) {
791            # Build the message
792            my $sendmail = MIME::Lite->new(
793                                 From     => $rc{'email'},
794                                 To       => $from,
795                                 Subject  => "[AutoReply] $input",
796                                 Type     => "text/plain",
797                                 Encoding => '7bit',
798                                 Data     => $body
799                            );
800            # Add the attachment
801            $sendmail->attach(
802                                Encoding => "base64",
803                                Path => $input
804                             );
805            MIME::Lite->send('smtp', 'localhost', Timeout => 60);
806            $sendmail->send;
807        }
808        elsif ($type =~ /command/i) {
809            my @outputA = `$input`;
810            my $output;
811            foreach my $i (@outputA) {
812                $output .= "$i\n";
813            }
814            # Build the message
815            my $sendmail = MIME::Lite->new(
816                                 From     => $rc{'email'},
817                                 To       => $from,
818                                 Subject  => "[AutoReply] $input",
819                                 Type     => "text/plain",
820                                 Encoding => '7bit',
821                                 Data     => $output
822                            );
823            MIME::Lite->send('smtp', 'localhost', Timeout => 60);
824            $sendmail->send;
825        }
826        else {
827            &writelog("Error in config file mailback.  Unknown type: $type");
828        }
829        $msg->accept
830    }
831}
832
833#Now catch spam.. this is the fun part!
834foreach my $test (@rejectspam) {
835  if ( ($from =~ /$test/i) or ($to =~ /$test/i) ) {
836    my $logmsg = "SPAM(REJECTED)-> \n" .
837              "   From: $from\n" .
838              "   Subject: $subject\n" .
839              "   To: $to\n" .
840              "   Cc: $cc";
841    &writelog($logmsg);
842    &stats("spam");
843    replyAbuseISP() if ($rc{'RejectedSpamBounceISP'} eq "yes");
844    $msg->reject("$rc{'rejectmsg'}\n");
845  }
846}
847
848foreach my $test (@reject) {
849  if ( ($from =~ /$test/i) or ($to =~ /$test/i) ) {
850    my $logmsg = "BLACKLIST(REJECTED)-> \n" .
851              "   From: $from\n" .
852              "   Subject: $subject\n" .
853              "   To: $to\n" .
854              "   Cc: $cc";
855    &writelog($logmsg);
856    &stats("spam");
857    replyAbuseISP() if ($rc{'RejectedBounceISP'} eq "yes");
858    $msg->reject("$rc{'rejectmsg'}\n");
859  }
860}
861
862foreach my $test (@ignore) {
863  if ( ($from =~ /$test/i) or ($to =~ /$test/i) ) {
864    my $logmsg = "SPAM(IGNORED)-> \n" .
865              "   From: $from\n" .
866              "   Subject: $subject\n" .
867              "   To: $to\n" .
868              "   Cc: $cc";
869    &writelog($logmsg);
870    &stats("spam");
871    replyAbuseISP() if ($rc{'IgnoreSpamBounceISP'} eq "yes");
872    $msg->ignore;
873  }
874}
875
876
877### The message passed all the filters.  Accept it into the inbox
878my $logmsg = "INBOX-> \n" .
879        "   From: $from\n" .
880        "   Subject: $subject\n" .
881        "   To: $to\n" .
882        "   Cc: $cc";
883&writelog($logmsg);
884&stats("normal~:~INBOX");
885
886$msg->accept;    # make sure to accept it if no other rules take it out.
887
888
889__END__
Note: See TracBrowser for help on using the browser.