From 858f0a2960123d6d2cbced1bb18e4e5e524df21e Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 11 Feb 2014 00:36:06 +0000 Subject: move pre-spamc checks to PublicInbox->precheck We may add more checks before we go to spamc. --- lib/PublicInbox.pm | 10 +++++++- public-inbox-mda | 6 +---- t/precheck.t | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ t/recipient.t | 59 ------------------------------------------- 4 files changed, 84 insertions(+), 65 deletions(-) create mode 100644 t/precheck.t delete mode 100644 t/recipient.t diff --git a/lib/PublicInbox.pm b/lib/PublicInbox.pm index b51c000f..899027be 100644 --- a/lib/PublicInbox.pm +++ b/lib/PublicInbox.pm @@ -4,6 +4,7 @@ package PublicInbox; use strict; use warnings; use Email::Address; +use constant MAX_SIZE => 1024 * 500; # same as spamc default # drop plus addressing for matching sub __drop_plus { @@ -13,8 +14,15 @@ sub __drop_plus { } # do not allow Bcc, only Cc and To if ORIGINAL_RECIPIENT (postfix) env is set -sub recipient_specified { +sub precheck { my ($klass, $filter) = @_; + return 0 unless defined($filter->from); + return 0 if length($filter->simple->as_string) > MAX_SIZE; + recipient_specified($filter); +} + +sub recipient_specified { + my ($filter) = @_; my $or = $ENV{ORIGINAL_RECIPIENT}; defined($or) or return 1; # for imports my @or = Email::Address->parse($or); diff --git a/public-inbox-mda b/public-inbox-mda index 62d5b7fc..291b5574 100755 --- a/public-inbox-mda +++ b/public-inbox-mda @@ -11,13 +11,9 @@ my $usage = "public-inbox-mda main_repo fail_repo < rfc2822_message"; my $filter = Email::Filter->new(emergency => "~/emergency.mbox"); my $main_repo = shift @ARGV or die "Usage: $usage\n"; my $fail_repo = shift @ARGV or die "Usage: $usage\n"; -my $max = 1024 * 500; # same as spamc my $filtered; -if ($filter->simple->header("From") - && length($filter->simple->as_string) <= $max - && PublicInbox->recipient_specified($filter) - && do_spamc($filter->simple, \$filtered)) { +if (PublicInbox->precheck($filter) && do_spamc($filter->simple, \$filtered)) { # update our message with SA headers (in case our filter rejects it) my $simple = Email::Simple->new($filtered); $filtered = undef; diff --git a/t/precheck.t b/t/precheck.t new file mode 100644 index 00000000..6deead98 --- /dev/null +++ b/t/precheck.t @@ -0,0 +1,74 @@ +# Copyright (C) 2014, Eric Wong and all contributors +# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt) +use strict; +use warnings; +use Test::More; +use Email::Simple; +use Email::Filter; +use PublicInbox; + +sub do_checks { + my ($s) = @_; + + my $f = Email::Filter->new(data => $s->as_string); + local %ENV; + delete $ENV{ORIGINAL_RECIPIENT}; + + ok(PublicInbox->precheck($f), + "ORIGINAL_RECIPIENT unset is OK"); + + $ENV{ORIGINAL_RECIPIENT} = 'foo@example.com'; + ok(!PublicInbox->precheck($f), + "wrong ORIGINAL_RECIPIENT rejected"); + + $ENV{ORIGINAL_RECIPIENT} = 'b@example.com'; + ok(PublicInbox->precheck($f), + "ORIGINAL_RECIPIENT in To: is OK"); + + $ENV{ORIGINAL_RECIPIENT} = 'c@example.com'; + ok(PublicInbox->precheck($f), + "ORIGINAL_RECIPIENT in Cc: is OK"); +} + +{ + do_checks(Email::Simple->create( + header => [ + From => 'a@example.com', + To => 'b@example.com', + Cc => 'c@example.com', + 'Content-Type' => 'text/plain', + Subject => 'this is a subject', + ], + body => "hello world\n", + )); +} + +{ + do_checks(Email::Simple->create( + header => [ + From => 'a@example.com', + To => 'b+plus@example.com', + Cc => 'John Doe ', + 'Content-Type' => 'text/plain', + Subject => 'this is a subject', + ], + body => "hello world\n", + )); +} + +{ + $ENV{ORIGINAL_RECIPIENT} = 'b@example.com'; + my $s = Email::Simple->create( + header => [ + To => 'b@example.com', + Cc => 'c@example.com', + 'Content-Type' => 'text/plain', + Subject => 'this is a subject', + ], + body => "hello world\n", + ); + my $f = Email::Filter->new(data => $s->as_string); + ok(!PublicInbox->precheck($f), "missing From: is rejected"); +} + +done_testing(); diff --git a/t/recipient.t b/t/recipient.t deleted file mode 100644 index 9cb1969e..00000000 --- a/t/recipient.t +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2014, Eric Wong and all contributors -# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt) -use strict; -use warnings; -use Test::More; -use Email::Simple; -use Email::Filter; -use PublicInbox; - -sub do_checks { - my ($s) = @_; - - my $f = Email::Filter->new(data => $s->as_string); - local %ENV; - delete $ENV{ORIGINAL_RECIPIENT}; - - ok(PublicInbox->recipient_specified($f), - "ORIGINAL_RECIPIENT unset is OK"); - - $ENV{ORIGINAL_RECIPIENT} = 'foo@example.com'; - ok(!PublicInbox->recipient_specified($f), - "wrong ORIGINAL_RECIPIENT rejected"); - - $ENV{ORIGINAL_RECIPIENT} = 'b@example.com'; - ok(PublicInbox->recipient_specified($f), - "ORIGINAL_RECIPIENT in To: is OK"); - - $ENV{ORIGINAL_RECIPIENT} = 'c@example.com'; - ok(PublicInbox->recipient_specified($f), - "ORIGINAL_RECIPIENT in Cc: is OK"); -} - -{ - do_checks(Email::Simple->create( - header => [ - From => 'a@example.com', - To => 'b@example.com', - Cc => 'c@example.com', - 'Content-Type' => 'text/plain', - Subject => 'this is a subject', - ], - body => "hello world\n", - )); -} - -{ - do_checks(Email::Simple->create( - header => [ - From => 'a@example.com', - To => 'b+plus@example.com', - Cc => 'John Doe ', - 'Content-Type' => 'text/plain', - Subject => 'this is a subject', - ], - body => "hello world\n", - )); -} - -done_testing(); -- cgit v1.2.3-24-ge0c7