← Index
NYTProf Performance Profile   « line view »
For /usr/local/bin/sa-learn
  Run on Tue Nov 7 05:38:10 2017
Reported on Tue Nov 7 06:16:05 2017

Filename/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/VBounce.pm
StatementsExecuted 25 statements in 1.86ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11191µs321µsMail::SpamAssassin::Plugin::VBounce::::newMail::SpamAssassin::Plugin::VBounce::new
11152µs52µsMail::SpamAssassin::Plugin::VBounce::::BEGIN@30Mail::SpamAssassin::Plugin::VBounce::BEGIN@30
11131µs133µsMail::SpamAssassin::Plugin::VBounce::::set_configMail::SpamAssassin::Plugin::VBounce::set_config
11128µs41µsMail::SpamAssassin::Plugin::VBounce::::BEGIN@32Mail::SpamAssassin::Plugin::VBounce::BEGIN@32
11127µs255µsMail::SpamAssassin::Plugin::VBounce::::BEGIN@31Mail::SpamAssassin::Plugin::VBounce::BEGIN@31
11121µs54µsMail::SpamAssassin::Plugin::VBounce::::BEGIN@33Mail::SpamAssassin::Plugin::VBounce::BEGIN@33
11120µs106µsMail::SpamAssassin::Plugin::VBounce::::BEGIN@34Mail::SpamAssassin::Plugin::VBounce::BEGIN@34
0000s0sMail::SpamAssassin::Plugin::VBounce::::_relay_is_in_listMail::SpamAssassin::Plugin::VBounce::_relay_is_in_list
0000s0sMail::SpamAssassin::Plugin::VBounce::::_relay_is_in_whitelist_bounce_relaysMail::SpamAssassin::Plugin::VBounce::_relay_is_in_whitelist_bounce_relays
0000s0sMail::SpamAssassin::Plugin::VBounce::::check_whitelist_bounce_relaysMail::SpamAssassin::Plugin::VBounce::check_whitelist_bounce_relays
0000s0sMail::SpamAssassin::Plugin::VBounce::::have_any_bounce_relaysMail::SpamAssassin::Plugin::VBounce::have_any_bounce_relays
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# <@LICENSE>
2# Licensed to the Apache Software Foundation (ASF) under one or more
3# contributor license agreements. See the NOTICE file distributed with
4# this work for additional information regarding copyright ownership.
5# The ASF licenses this file to you under the Apache License, Version 2.0
6# (the "License"); you may not use this file except in compliance with
7# the License. You may obtain a copy of the License at:
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# </@LICENSE>
17
18=head1 NAME
19
20Mail::SpamAssassin::Plugin::VBounce - aid in rescuing genuine bounces
21
22=head1 SYNOPSIS
23
24 loadplugin Mail::SpamAssassin::Plugin::VBounce [/path/to/VBounce.pm]
25
26=cut
27
28package Mail::SpamAssassin::Plugin::VBounce;
29
30272µs152µs
# spent 52µs within Mail::SpamAssassin::Plugin::VBounce::BEGIN@30 which was called: # once (52µs+0s) by Mail::SpamAssassin::PluginHandler::load_plugin at line 30
use Mail::SpamAssassin::Plugin;
# spent 52µs making 1 call to Mail::SpamAssassin::Plugin::VBounce::BEGIN@30
31279µs2484µs
# spent 255µs (27+228) within Mail::SpamAssassin::Plugin::VBounce::BEGIN@31 which was called: # once (27µs+228µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 31
use Mail::SpamAssassin::Logger;
# spent 255µs making 1 call to Mail::SpamAssassin::Plugin::VBounce::BEGIN@31 # spent 228µs making 1 call to Exporter::import
32297µs254µs
# spent 41µs (28+13) within Mail::SpamAssassin::Plugin::VBounce::BEGIN@32 which was called: # once (28µs+13µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 32
use strict;
# spent 41µs making 1 call to Mail::SpamAssassin::Plugin::VBounce::BEGIN@32 # spent 13µs making 1 call to strict::import
332100µs287µs
# spent 54µs (21+33) within Mail::SpamAssassin::Plugin::VBounce::BEGIN@33 which was called: # once (21µs+33µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 33
use warnings;
# spent 54µs making 1 call to Mail::SpamAssassin::Plugin::VBounce::BEGIN@33 # spent 33µs making 1 call to warnings::import
3421.39ms2192µs
# spent 106µs (20+86) within Mail::SpamAssassin::Plugin::VBounce::BEGIN@34 which was called: # once (20µs+86µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 34
use re 'taint';
# spent 106µs making 1 call to Mail::SpamAssassin::Plugin::VBounce::BEGIN@34 # spent 86µs making 1 call to re::import
35
36112µsour @ISA = qw(Mail::SpamAssassin::Plugin);
37
38
# spent 321µs (91+230) within Mail::SpamAssassin::Plugin::VBounce::new which was called: # once (91µs+230µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 1 of (eval 107)[Mail/SpamAssassin/PluginHandler.pm:129]
sub new {
3912µs my $class = shift;
4012µs my $mailsaobject = shift;
41
4212µs $class = ref($class) || $class;
4319µs128µs my $self = $class->SUPER::new($mailsaobject);
# spent 28µs making 1 call to Mail::SpamAssassin::Plugin::new
4412µs bless ($self, $class);
45
46120µs140µs $self->register_eval_rule("have_any_bounce_relays");
# spent 40µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule
4716µs129µs $self->register_eval_rule("check_whitelist_bounce_relays");
# spent 29µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule
48
49115µs1133µs $self->set_config($mailsaobject->{conf});
# spent 133µs making 1 call to Mail::SpamAssassin::Plugin::VBounce::set_config
50
5119µs return $self;
52}
53
54
# spent 133µs (31+102) within Mail::SpamAssassin::Plugin::VBounce::set_config which was called: # once (31µs+102µs) by Mail::SpamAssassin::Plugin::VBounce::new at line 49
sub set_config {
5512µs my($self, $conf) = @_;
5612µs my @cmds;
57
58=head1 USER PREFERENCES
59
60The following options can be used in both site-wide (C<local.cf>) and
61user-specific (C<user_prefs>) configuration files to customize how
62SpamAssassin handles incoming email messages.
63
64=over 4
65
66=item whitelist_bounce_relays hostname [hostname2 ...]
67
68This is used to 'rescue' legitimate bounce messages that were generated in
69response to mail you really *did* send. List the MTA relays that your outbound
70mail is delivered through. If a bounce message is found, and it contains one
71of these hostnames in a 'Received' header, it will not be marked as a blowback
72virus-bounce.
73
74The hostnames can be file-glob-style patterns, so C<relay*.isp.com> will work.
75Specifically, C<*> and C<?> are allowed, but all other metacharacters are not.
76Regular expressions are not used for security reasons.
77
78Multiple addresses per line, separated by spaces, is OK. Multiple
79C<whitelist_bounce_relays> lines are also OK.
80
81=back
82
83=cut
84
8514µs push (@cmds, {
86 setting => 'whitelist_bounce_relays',
87 type => $Mail::SpamAssassin::Conf::CONF_TYPE_ADDRLIST
88 });
89
90117µs1102µs $conf->{parser}->register_commands(\@cmds);
91}
92
93sub have_any_bounce_relays {
94 my ($self, $pms) = @_;
95 return $pms->{conf}->{whitelist_bounce_relays} &&
96 %{$pms->{conf}->{whitelist_bounce_relays}} ? 1 : 0;
97}
98
99sub check_whitelist_bounce_relays {
100 my ($self, $pms) = @_;
101
102 return 0 if !$self->have_any_bounce_relays($pms);
103
104 my $body = $pms->get_decoded_stripped_body_text_array();
105 my $res;
106
107 # catch lines like:
108 # Received: by dogma.boxhost.net (Postfix, from userid 1007)
109
110 # check the plain-text body, first
111 foreach my $line (@{$body}) {
112 next unless ($line =~ /^[> ]*Received:/i);
113 while ($line =~ / (\S+\.\S+) /g) {
114 return 1 if $self->_relay_is_in_whitelist_bounce_relays($pms, $1);
115 }
116 }
117
118 # now check any "message/anything" attachment MIME parts, too.
119 # don't use the more efficient find_parts() method until bug 5331 is
120 # fixed, otherwise we'll miss some messages due to their MIME structure
121
122 my $pristine = $pms->{msg}->get_pristine_body();
123
124 # triage, avoids expensive loop through large mail with attachments
125 return 0 if $pristine !~ /Received:/i;
126
127 my $found_received = 0;
128 my $fullhdr = '';
129 foreach my $line ($pristine =~ /^(.*)$/gm) {
130 if (!defined $line) { return 0; }
131
132 # don't bother until we see a line with "Received:" in it
133 if (!$found_received) {
134 next unless ($line =~ /^[> ]*Received:/i);
135 $found_received = 1;
136 }
137
138 if ($line =~ /^\s/) { # bug 5912, deal with multiline
139 $fullhdr .= $line;
140 } else {
141 $fullhdr = $line;
142 }
143
144 next unless ($fullhdr =~ /^[> ]*Received:/i);
145 while ($fullhdr =~ /\s(\S+\.\S+)\s/gs) {
146 return 1 if $self->_relay_is_in_whitelist_bounce_relays($pms, $1);
147 }
148 }
149
150 return 0;
151}
152
153sub _relay_is_in_whitelist_bounce_relays {
154 my ($self, $pms, $relay) = @_;
155 return 1 if $self->_relay_is_in_list(
156 $pms->{conf}->{whitelist_bounce_relays}, $pms, $relay);
157 dbg("rules: relay $relay doesn't match any whitelist");
158
159 return 0;
160}
161
162sub _relay_is_in_list {
163 my ($self, $list, $pms, $relay) = @_;
164 $relay = lc $relay;
165
166 if (defined $list->{$relay}) { return 1; }
167
168 foreach my $regexp (values %{$list}) {
169 if ($relay =~ qr/$regexp/i) {
170 dbg("rules: relay $relay matches regexp: $regexp");
171 return 1;
172 }
173 }
174
175 return 0;
176}
177
178113µs1;