SF.net SVN: postfixadmin:[453] trunk/VIRTUAL_VACATION
Brought to you by:
christian_boltz,
gingerdog
|
From: <Gin...@us...> - 2008-08-31 20:17:18
|
Revision: 453
http://postfixadmin.svn.sourceforge.net/postfixadmin/?rev=453&view=rev
Author: GingerDog
Date: 2008-08-31 20:17:23 +0000 (Sun, 31 Aug 2008)
Log Message:
-----------
vacation.pl: plenty of refactoring; I think this addresses all hte points at https://sourceforge.net/forum/message.php?msg_id=5205584
Modified Paths:
--------------
trunk/VIRTUAL_VACATION/tests/asterisk-email.txt
trunk/VIRTUAL_VACATION/tests/test-email.txt
trunk/VIRTUAL_VACATION/tests/test.sh
trunk/VIRTUAL_VACATION/vacation.pl
Modified: trunk/VIRTUAL_VACATION/tests/asterisk-email.txt
===================================================================
--- trunk/VIRTUAL_VACATION/tests/asterisk-email.txt 2008-08-31 14:15:48 UTC (rev 452)
+++ trunk/VIRTUAL_VACATION/tests/asterisk-email.txt 2008-08-31 20:17:23 UTC (rev 453)
@@ -3,7 +3,7 @@
Delivered-To: da...@ex...
Received: by mail.palepurple.co.uk (Postfix, from userid 33)
id 1942F894CF9; Fri, 1 Aug 2008 11:23:45 +0100 (BST)
-To: <da...@ex...>
+To: "" <da...@ex...>
Subject: New Phone call - annotate it!
X-PHP-Script: admin.palepurple.co.uk/contacts/dispatch.php for 78.105.97.55
From: "ast...@ex..." <ast...@ex...>
Modified: trunk/VIRTUAL_VACATION/tests/test-email.txt
===================================================================
--- trunk/VIRTUAL_VACATION/tests/test-email.txt 2008-08-31 14:15:48 UTC (rev 452)
+++ trunk/VIRTUAL_VACATION/tests/test-email.txt 2008-08-31 20:17:23 UTC (rev 453)
@@ -22,7 +22,8 @@
id 8869450146; Tue, 5 Aug 2008 20:15:50 +0100 (BST)
Date: Tue, 5 Aug 2008 20:15:50 +0100
From: David Goodwin <da...@ex...>
-To: da...@ex...
+To: "DG" <da...@ex...>, "Fred@Work" <fr...@ex...>, "Barney Rubble"
+ <ba...@ex...>, "Rover Dog" <ro...@ex...>, ro...@ex...
Subject: test email
Message-ID: <200...@co...>
MIME-Version: 1.0
Modified: trunk/VIRTUAL_VACATION/tests/test.sh
===================================================================
--- trunk/VIRTUAL_VACATION/tests/test.sh 2008-08-31 14:15:48 UTC (rev 452)
+++ trunk/VIRTUAL_VACATION/tests/test.sh 2008-08-31 20:17:23 UTC (rev 453)
@@ -18,25 +18,32 @@
# First time around, there should be no vacation record for da...@ex..., so these should all not cause mail to be sent.
# some will trip up spam/mailing list protection etc though
-
+echo
echo "NONE OF THESE SHOULD RESULT IN MAIL BEING SENT"
+echo
cat mailing-list.txt | perl ../vacation.pl -t yes -f fw-...@li... -- da...@ex...
cat test-email.txt | perl ../vacation.pl -t yes -f da...@ex... -- da...@ex...
cat spam.txt | perl ../vacation.pl -t yes -f ma...@cc... -- da...@ex...
cat asterisk-email.txt | perl ../vacation.pl -t yes -f www...@pa... -- da...@ex...
cat facebook.txt | perl ../vacation.pl -t yes -f not...@fa... -- da...@ex...
+cat mail-myself.txt | perl ../vacation.pl -t yes -f da...@ex... -- da...@ex...
echo "INSERT INTO vacation (email, subject, body, created, active, domain) VALUES ('da...@ex...', 'I am on holiday', 'Yeah, that is right', NOW(), true, 'example.org')" | psql
-
+echo
echo "VACATION TURNED ON "
+echo
echo "Still ignore mailing list"
cat mailing-list.txt | perl ../vacation.pl -t yes -f fw-...@li... -- da...@ex...
-echo "* Should send vacation message for this"
+echo " * Should send vacation message for this *"
cat test-email.txt | perl ../vacation.pl -t yes -f da...@ex... -- da...@ex...
-echo "* Spam - no vacation message for this"
+echo " * Spam - no vacation message for this"
cat spam.txt | perl ../vacation.pl -t yes -f ma...@xx... -- da...@ex...
-echo "* OK - should send vacation message for this"
+echo " * OK - should send vacation message for this"
cat asterisk-email.txt | perl ../vacation.pl -t yes -f www...@pa... -- da...@ex...
-echo "* Facebook - should not send vacation message for"
+echo " * Facebook - should not send vacation message for"
cat facebook.txt | perl ../vacation.pl -t yes -f not...@fa... -- da...@ex...
+echo " * Mailing myself - should not send vacation message"
+cat mail-myself.txt | perl ../vacation.pl -t yes -f da...@ex... -- da...@ex...
+echo
+echo
Modified: trunk/VIRTUAL_VACATION/vacation.pl
===================================================================
--- trunk/VIRTUAL_VACATION/vacation.pl 2008-08-31 14:15:48 UTC (rev 452)
+++ trunk/VIRTUAL_VACATION/vacation.pl 2008-08-31 20:17:23 UTC (rev 453)
@@ -99,8 +99,8 @@
my $db_host = '';
# connection details
-my $db_username = 'your_username';
-my $db_password = 'your_password';
+my $db_username = 'dg';
+my $db_password = 'gingerdog';
my $db_name = 'postfix';
# smtp server used to send vacation e-mails
@@ -139,17 +139,19 @@
use Getopt::Std;
use Log::Log4perl qw(get_logger :levels);
-my ($from, $to, $cc, ,$bcc , $subject, $messageid, $lastheader, $smtp_sender, $smtp_recipient, %opts, $sndrhdr, $spam, $test_mode, $logger);
+my ($from, $to, $cc, $replyto , $subject, $messageid, $lastheader, $smtp_sender, $smtp_recipient, %opts, $spam, $test_mode, $logger);
$subject='';
# Setup a logger...
#
-getopts('f:t:', \%opts) or die "Usage: $0 [-t yes] [-f sender] [-- [recipient]]\n -t for testing only\n";
+getopts('f:t:', \%opts) or die "Usage: $0 [-t yes] -f sender -- recipient\n -t for testing only\n";
$opts{f} and $smtp_sender = $opts{f};
$test_mode = 0;
$opts{t} and $test_mode = 1;
+$smtp_recipient = shift || $smtp_recipient || $ENV{"USER"} || "";
+
my $log_layout = Log::Log4perl::Layout::PatternLayout->new("%d %p> %F:%L %M - %m%n");
if($test_mode == 1) {
@@ -388,15 +390,24 @@
}
}
+# Remove textual stuff from a (list of) email address(es)
+# e.g. convert: "aardvark" <a@b.com>, "Danger Mouse" <c@d.com>, e@f.com to
+# a@b.com, c@d.com, e@f.com
sub strip_address {
my ($arg) = @_;
if(!$arg) {
return '';
}
- if($arg =~ /([\w\-.%]+\@[\w.-]+)/) {
- return lc($1);
+ my @ok;
+ $logger = get_logger();
+ for (split(/,\s*/, lc($arg))) {
+ my $temp = Email::Valid->address($_);
+ if($temp) {
+ push(@ok, $temp);
+ }
}
- return '';
+ my $result = join(", ", @ok);
+ return $result;
}
sub panic_prepare {
@@ -412,34 +423,52 @@
$logger->error("Could not execute sql statement - '$arg' with parameters '$param'");
exit(0);
}
+
+# Make sure the email wasn't sent by someone who could be a mailing list etc; if it was,
+# then we abort after appropriate logging.
+sub check_and_clean_from_address {
+ my ($address) = @_;
+ my $logger = get_logger();
+
+ if($address =~ /^(noreply|postmaster|mailer-daemon|listserv|majordomo|owner-|request-|bounces-)/i ||
+ $address =~ /-(owner|request|bounces)\@/i ) {
+ $logger->debug("sender $address contains $1 - will not send vacation message");
+ exit(0);
+ }
+ $address = strip_address($address);
+ if($address eq "") {
+ $logger->error("Address $address is not valid; exiting");
+ exit(0);
+ }
+ #$logger->debug("Address cleaned up to $address");
+ return $address;
+}
########################### main #################################
# Take headers apart
-#
+$cc = '';
+$replyto = '';
+
while (<STDIN>) {
last if (/^$/);
- if (/^\s+(.*)/ and $lastheader) { $$lastheader .= " $1"; }
- elsif (/^Return-Path:\s+(.*)\n$/i) { $smtp_sender = $1; $lastheader = \$smtp_sender; }
- elsif (/^Delivered-To:\s+(.*)\n$/i) { $smtp_recipient = $1; $lastheader = \$smtp_recipient; }
- elsif (/^from:\s+(.*)\n$/i) { $from = $1; $lastheader = \$from; }
- elsif (/^to:\s+(.*)\n$/i) { $to = $1; $lastheader = \$to; }
- elsif (/^cc:\s+(.*)\n$/i) { $cc = $1; $lastheader = \$cc; }
- elsif (/^bcc:\s+(.*)\n$/i) { $bcc = $1; $lastheader = \$bcc; }
- elsif (/^subject:\s+(.*)\n$/i) { $subject = $1; $lastheader = \$subject; }
- elsif (/^message-id:\s+(.*)\n$/i) { $messageid = $1; $lastheader = \$messageid; }
+ if (/^\s+(.*)/ and $lastheader) { $$lastheader .= " $1"; next; }
+ elsif (/^from:\s*(.*)\s*\n$/i) { $from = $1; $lastheader = \$from; }
+ elsif (/^to:\s*(.*)\s*\n$/i) { $to = $1; $lastheader = \$to; }
+ elsif (/^cc:\s*(.*)\s*\n$/i) { $cc = $1; $lastheader = \$cc; }
+ elsif (/^Reply-to:\s*(.*)\s*\n$/i) { $replyto = $1; $lastheader = \$replyto; }
+ elsif (/^subject:\s*(.*)\s*\n$/i) { $subject = $1; $lastheader = \$subject; }
+ elsif (/^message-id:\s*(.*)\s*\n$/i) { $messageid = $1; $lastheader = \$messageid; }
elsif (/^x-spam-(flag|status):\s+yes/i) { $logger->debug("x-spam-$1: yes found; exiting"); exit (0); }
elsif (/^x-facebook-notify:/i) { $logger->debug('Mail from facebook, ignoring'); exit(0); }
elsif (/^precedence:\s+(bulk|list|junk)/i) { $logger->debug("precedence: $1 found; exiting"); exit (0); }
elsif (/^x-loop:\s+postfix\ admin\ virtual\ vacation/i) { $logger->debug("x-loop: postfix admin virtual vacation found; exiting"); exit (0); }
- elsif (/^Auto-Submitted:\s+no/i) { next; }
+ elsif (/^Auto-Submitted:\s*no\s*/i) { next; }
elsif (/^Auto-Submitted:/i) { $logger->debug("Auto-Submitted: something found; exiting"); exit (0); }
elsif (/^List-(Id|Post):/i) { $logger->debug("List-$1: found; exiting"); exit (0); }
- elsif (/^Sender:\s+(.*)/i) { $sndrhdr = $1; $lastheader = \$sndrhdr; }
else {$lastheader = "" ; }
}
-$smtp_recipient = shift || $smtp_recipient || $ENV{"USER"} || "";
# If either From: or To: are not set, exit
if(!$from || !$to || !$messageid || !$smtp_sender || !$smtp_recipient) {
@@ -447,15 +476,16 @@
exit(0);
}
-if($smtp_sender =~ /^(mailer-daemon|listserv|majordomo|owner-|request-|bounces-)/i ||
- $smtp_sender =~ /-(owner|request|bounces)\@/i ) {
- $logger->debug("sender $smtp_sender contains $1 - will not send vacation message");
- exit(0);
+$to = strip_address($to);
+$from = lc ($from);
+$from = check_and_clean_from_address($from);
+if($replyto ne "") {
+ # if reply-to is invalid, or looks like a mailing list, then we probably don't want to send a reply.
+ $replyto = check_and_clean_from_address($replyto);
}
+$smtp_sender = check_and_clean_from_address($smtp_sender);
+$smtp_recipient = check_and_clean_from_address($smtp_recipient);
-$smtp_sender = strip_address($smtp_sender);
-$smtp_recipient = strip_address($smtp_recipient);
-$sndrhdr = strip_address($sndrhdr);
if ($smtp_sender eq $smtp_recipient) {
$logger->debug("smtp sender $smtp_sender and recipient $smtp_recipient are the same; aborting");
@@ -463,39 +493,28 @@
}
my $recipfound = 0;
-for (split(/,\s*/, lc($to)), split(/,\s*/, lc($cc)), split(/,\s*/, lc($bcc))) {
+for (split(/,\s*/, lc($to)), split(/,\s*/, lc($cc))) {
my $destinatario = strip_address($_);
- if ($sndrhdr eq $destinatario) {
- $logger->debug("sender header $sndrhdr contains recipient $destinatario (mailing myself?)");
+ if ($smtp_sender eq $destinatario) {
+ $logger->debug("sender header $smtp_sender contains recipient $destinatario (mailing myself?)");
exit(0);
}
if ($smtp_recipient eq $destinatario) { $recipfound++; }
}
if (!$recipfound) {
- $logger->debug("smtp envelope recipient $smtp_recipient not found in the header recipients (therefore they were bcc'ed, so won't send vacation message)");
+ $logger->debug("smtp envelope recipient $smtp_recipient not found in the header recipients ($to & $cc) (therefore they were bcc'ed, so won't send vacation message)");
exit (0);
}
-$from = lc ($from);
-if (!Email::Valid->address($from,-mxcheck => 1)) { $logger->debug("Invalid from email address: $from; exiting."); exit(0); }
-if (!Email::Valid->address($smtp_sender,-mxcheck => 1)) { $logger->debug("Invalid sender email address: $smtp_sender; exiting."); exit(0); }
-if ($from =~ /([\w\-.%]+\@[\w.-]+)/) { $from = $1; }
-# Does the $from address look like a mailing list etc?
-if ($from eq "" ||
- $from =~ /^(owner-|-(?:request|owner)\@|^(?:mailer-daemon|postmaster)\@)/i) {
- $logger->debug("from $from contains $1"); exit (0);
-}
-
my ($rv, $email) = find_real_address($smtp_recipient);
-$logger->debug("find_email_address gave: rv:$rv, email:$email");
if ($rv == 1) {
$logger->debug("Attempting to send vacation response for: $messageid to: $smtp_sender, $smtp_recipient, $email (test_mode = $test_mode)");
send_vacation_email($email, $smtp_sender, $smtp_recipient, $messageid, $test_mode);
}
else {
- $logger->debug("SMTP recipient $smtp_recipient which resolves to $email does not have an active vacation");
+ $logger->debug("SMTP recipient $smtp_recipient which resolves to $email does not have an active vacation (rv: $rv, email: $email)");
}
0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|