"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/Mail/SpamAssassin/Message/Metadata/Received.pm" between
Mail-SpamAssassin-3.4.4.tar.bz2 and Mail-SpamAssassin-3.4.5.tar.bz2

About: SpamAssassin is a mail filter that uses a wide range of heuristic tests on mail headers and body text to identify "spam" (also known as unsolicited commercial email) incl. Bayesian (statistical) spam filter and several internet-based realtime blacklists.

Received.pm  (Mail-SpamAssassin-3.4.4.tar.bz2):Received.pm  (Mail-SpamAssassin-3.4.5.tar.bz2)
skipping to change at line 56 skipping to change at line 56
# use bytes; # use bytes;
use re 'taint'; use re 'taint';
use Mail::SpamAssassin::Dns; use Mail::SpamAssassin::Dns;
use Mail::SpamAssassin::PerMsgStatus; use Mail::SpamAssassin::PerMsgStatus;
use Mail::SpamAssassin::Constants qw(:ip); use Mail::SpamAssassin::Constants qw(:ip);
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
sub parse_received_headers { sub parse_received_headers {
my ($self, $permsgstatus, $msg) = @_; my ($self, $pms, $msg) = @_;
my $suppl_attrib = $msg->{suppl_attrib}; # out-of-band info from a caller
# a caller may assert that a message is coming from inside or from an # a caller may assert that a message is coming from inside or from an
# authenticated roaming users; this info may not be available in mail # authenticated roaming users; this info may not be available in mail
# header section, e.g. in case of nonstandard authentication mechanisms # header section, e.g. in case of nonstandard authentication mechanisms
my $originating; # boolean my $originating; # boolean
$originating = $suppl_attrib->{originating} if ref $suppl_attrib; if (exists $msg->{suppl_attrib}->{originating}) {
$originating = $msg->{suppl_attrib}->{originating} || 0;
dbg("metadata: set originating from suppl_attrib: %s", $originating);
}
$self->{relays_trusted} = [ ]; $self->{relays_trusted} = [ ];
$self->{num_relays_trusted} = 0; $self->{num_relays_trusted} = 0;
$self->{relays_trusted_str} = ''; $self->{relays_trusted_str} = '';
$self->{relays_untrusted} = [ ]; $self->{relays_untrusted} = [ ];
$self->{num_relays_untrusted} = 0; $self->{num_relays_untrusted} = 0;
$self->{relays_untrusted_str} = ''; $self->{relays_untrusted_str} = '';
$self->{relays_internal} = [ ]; $self->{relays_internal} = [ ];
skipping to change at line 90 skipping to change at line 91
$self->{relays_external_str} = ''; $self->{relays_external_str} = '';
$self->{num_relays_unparseable} = 0; $self->{num_relays_unparseable} = 0;
$self->{last_trusted_relay_index} = -1; # last counting from the top, $self->{last_trusted_relay_index} = -1; # last counting from the top,
$self->{last_internal_relay_index} = -1; # first in time $self->{last_internal_relay_index} = -1; # first in time
$self->{allow_mailfetch_markers} = 1; # This needs to be set for the $self->{allow_mailfetch_markers} = 1; # This needs to be set for the
# first Received: header # first Received: header
# now figure out what relays are trusted... # now figure out what relays are trusted...
my $trusted = $permsgstatus->{main}->{conf}->{trusted_networks}; my $trusted = $pms->{main}->{conf}->{trusted_networks};
my $internal = $permsgstatus->{main}->{conf}->{internal_networks}; my $internal = $pms->{main}->{conf}->{internal_networks};
my $msa = $permsgstatus->{main}->{conf}->{msa_networks}; my $msa = $pms->{main}->{conf}->{msa_networks};
my $did_user_specify_trust = $permsgstatus->{main}->{conf}->{trusted_networks_ my $did_user_specify_trust = $pms->{main}->{conf}->{trusted_networks_configure
configured}; d};
my $did_user_specify_internal = $permsgstatus->{main}->{conf}->{internal_netwo my $did_user_specify_internal = $pms->{main}->{conf}->{internal_networks_confi
rks_configured}; gured};
my $in_trusted = 1; my $in_trusted = 1;
my $in_internal = 1; my $in_internal = 1;
my $found_msa = 0; my $found_msa = 0;
unless ($did_user_specify_trust && $did_user_specify_internal) { unless ($did_user_specify_trust && $did_user_specify_internal) {
if (!$did_user_specify_trust && !$did_user_specify_internal) { if (!$did_user_specify_trust && !$did_user_specify_internal) {
dbg('config: trusted_networks are not configured; it is recommended '. dbg('config: trusted_networks are not configured; it is recommended '.
'that you configure trusted_networks manually'); 'that you configure trusted_networks manually');
} elsif (!$did_user_specify_internal) { } elsif (!$did_user_specify_internal) {
# use 'trusted' for 'internal'; compatibility with SpamAssassin 2.60 # use 'trusted' for 'internal'; compatibility with SpamAssassin 2.60
skipping to change at line 128 skipping to change at line 129
my $IP_ADDRESS = IP_ADDRESS; my $IP_ADDRESS = IP_ADDRESS;
my $IP_PRIVATE = IP_PRIVATE; my $IP_PRIVATE = IP_PRIVATE;
my $LOCALHOST = LOCALHOST; my $LOCALHOST = LOCALHOST;
my @hdrs = $msg->get_header('Received'); my @hdrs = $msg->get_header('Received');
# Now add the single line headers like X-Originating-IP. (bug 5680) # Now add the single line headers like X-Originating-IP. (bug 5680)
# we convert them into synthetic "Received" headers so we can share # we convert them into synthetic "Received" headers so we can share
# code below. # code below.
for my $header (@{$permsgstatus->{main}->{conf}->{originating_ip_headers}}) foreach my $header (@{$pms->{main}->{conf}->{originating_ip_headers}}) {
{
my $str = $msg->get_header($header); my $str = $msg->get_header($header);
next unless ($str && $str =~ m/($IP_ADDRESS)/); next unless ($str && $str =~ m/($IP_ADDRESS)/);
push @hdrs, "from X-Originating-IP: $1\n"; push @hdrs, "from X-Originating-IP: $1\n";
} }
foreach my $line ( @hdrs ) { foreach my $line ( @hdrs ) {
# qmail-scanner support hack: we may have had one of these set from the # qmail-scanner support hack: we may have had one of these set from the
# previous (read: more recent) Received header. if so, add it on to this # previous (read: more recent) Received header. if so, add it on to this
# header's set, since that's the handover it was describing. # header's set, since that's the handover it was describing.
skipping to change at line 337 skipping to change at line 337
# get rid of invalid semicolon at the end of the header # get rid of invalid semicolon at the end of the header
1 while s/\s?;$//; 1 while s/\s?;$//;
my $ip = ''; my $ip = '';
my $helo = ''; my $helo = '';
my $rdns = ''; my $rdns = '';
my $by = ''; my $by = '';
my $id = ''; my $id = '';
my $ident = ''; my $ident = '';
my $envfrom = ''; my $envfrom = undef;
my $mta_looked_up_dns = 0; my $mta_looked_up_dns = 0;
my $IP_ADDRESS = IP_ADDRESS; my $IP_ADDRESS = IP_ADDRESS;
my $IP_PRIVATE = IP_PRIVATE; my $IP_PRIVATE = IP_PRIVATE;
my $LOCALHOST = LOCALHOST; my $LOCALHOST = LOCALHOST;
my $auth = ''; my $auth = '';
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# We care about lines starting with from. all of the others are ignorable: # We care about lines starting with from. all of the others are ignorable:
# Bug 4943: give /^(from/ a chance to be parsed # Bug 4943: give /^(from/ a chance to be parsed
skipping to change at line 1212 skipping to change at line 1212
# outside the firewall. We can only ignore the handover since we don't have # outside the firewall. We can only ignore the handover since we don't have
# enough info in those headers; however, from googling, it appears that # enough info in those headers; however, from googling, it appears that
# all samples are cases where the handover is safely ignored. # all samples are cases where the handover is safely ignored.
if (/^no\.name\.available by \S+ via smtpd \(for /) { return 0; } if (/^no\.name\.available by \S+ via smtpd \(for /) { return 0; }
# from 156.56.111.196 by blazing.arsecandle.org (envelope-from <gentoo-annou nce-return-530-rod=arsecandle.org@lists.gentoo.org>, uid 502) with qmail-scanner -1.24 (clamdscan: 0.80/594. f-prot: 4.4.2/3.14.11. Clear:RC:0(156.56.111.196):. Processed in 0.288806 secs); 06 Feb 2005 21:11:38 -0000 # from 156.56.111.196 by blazing.arsecandle.org (envelope-from <gentoo-annou nce-return-530-rod=arsecandle.org@lists.gentoo.org>, uid 502) with qmail-scanner -1.24 (clamdscan: 0.80/594. f-prot: 4.4.2/3.14.11. Clear:RC:0(156.56.111.196):. Processed in 0.288806 secs); 06 Feb 2005 21:11:38 -0000
# these are safe to ignore. the previous handover line has the full # these are safe to ignore. the previous handover line has the full
# details of the handover described here, it's just qmail-scanner # details of the handover described here, it's just qmail-scanner
# logging a little more. # logging a little more.
if (/^\S+ by \S+ \(.{0,100}\) with qmail-scanner/) { if (/^\S+ by \S+ \(.{0,100}\) with qmail-scanner/) {
$envfrom =~ s/^\s*<*//gs; $envfrom =~ s/>*\s*$//gs; if (defined $envfrom) {
$envfrom =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs; $envfrom =~ s/^\s*<*//gs;
$envfrom =~ s/>*\s*$//gs;
$envfrom =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs;
}
$self->{qmail_scanner_env_from} = $envfrom; # hack! $self->{qmail_scanner_env_from} = $envfrom; # hack!
return 0; return 0;
} }
# Received: from mmail by argon.connect.org.uk with local (connectmail/exim) # Received: from mmail by argon.connect.org.uk with local (connectmail/exim)
# id 18tOsg-0008FX-00; Thu, 13 Mar 2003 09:20:06 +0000 # id 18tOsg-0008FX-00; Thu, 13 Mar 2003 09:20:06 +0000
if (/^\S+ by \S+ with local/) { return 0; } if (/^\S+ by \S+ with local/) { return 0; }
# Local unix socket handover from Cyrus, tested with v2.3.14 # Local unix socket handover from Cyrus, tested with v2.3.14
# Received: from testintranator.net.vm ([unix socket])_ by testintranator.ne t.vm (Cyrus v2.3.14) with LMTPA;_ Tue, 21 Jul 2009 14:34:14 +0200 # Received: from testintranator.net.vm ([unix socket])_ by testintranator.ne t.vm (Cyrus v2.3.14) with LMTPA;_ Tue, 21 Jul 2009 14:34:14 +0200
skipping to change at line 1242 skipping to change at line 1245
# Received: from CATHY.IJS.SI by CATHY.IJS.SI (PMDF V4.3-10 #8779) id <01KTS SR50NSW001MXN@CATHY.IJS.SI>; Fri, 21 Mar 2003 20:50:56 +0100 # Received: from CATHY.IJS.SI by CATHY.IJS.SI (PMDF V4.3-10 #8779) id <01KTS SR50NSW001MXN@CATHY.IJS.SI>; Fri, 21 Mar 2003 20:50:56 +0100
# Received: from MATT_LINUX by hippo.star.co.uk via smtpd (for mail.webnote. net [193.120.211.219]) with SMTP; 3 Jul 2002 15:43:50 UT # Received: from MATT_LINUX by hippo.star.co.uk via smtpd (for mail.webnote. net [193.120.211.219]) with SMTP; 3 Jul 2002 15:43:50 UT
# Received: from cp-its-ieg01.mail.saic.com by cpmx.mail.saic.com for me@jma son.org; Tue, 23 Jul 2002 14:09:10 -0700 # Received: from cp-its-ieg01.mail.saic.com by cpmx.mail.saic.com for me@jma son.org; Tue, 23 Jul 2002 14:09:10 -0700
if (/^\S+ by \S+ (?:with|via|for|\()/) { return 0; } if (/^\S+ by \S+ (?:with|via|for|\()/) { return 0; }
# from senmail2.senate.gov with LMTP by senmail2 (3.0.2/sieved-3-0-build-942 ) for <example@vandinter.org>; Fri, 30 Jun 2006 10:58:41 -0400 # from senmail2.senate.gov with LMTP by senmail2 (3.0.2/sieved-3-0-build-942 ) for <example@vandinter.org>; Fri, 30 Jun 2006 10:58:41 -0400
# from zimbramail.artsit.org.uk (unverified) by MAILSWEEP.birminghamartsit.o rg.uk (Clearswift SMTPRS 5.1.7) with ESMTP id <T78926b35f2c0a80003da8@MAILSWEEP. birminghamartsit.org.uk> for <discuss@lists.surbl.org>; Tue, 30 May 2006 15:56:1 5 +0100 # from zimbramail.artsit.org.uk (unverified) by MAILSWEEP.birminghamartsit.o rg.uk (Clearswift SMTPRS 5.1.7) with ESMTP id <T78926b35f2c0a80003da8@MAILSWEEP. birminghamartsit.org.uk> for <discuss@lists.surbl.org>; Tue, 30 May 2006 15:56:1 5 +0100
if (/^\S+ (?:(?:with|via|for) \S+|\(unverified\)) by\b/) { return 0; } if (/^\S+ (?:(?:with|via|for) \S+|\(unverified\)) by\b/) { return 0; }
# from MjA3NDc4Mg (unknown) by ismtpd0001p1lon1.sendgrid.net (SG) with HTTP
id aqHKNX2kSp-HiqspAa-uvw for <email@e.example.com>; Thu, 02 Apr 2020 07:53:55.5
16 +0000 (UTC)
if (/^\S+ \(unknown\) by \S+ \(SG\) with \b/) { return 0; }
# from localhost (example.com [local]) by example.com (OpenSMTPD) with ESMTP
A id 5db34e0d for <email@example.com>; Tue, 7 Apr 2020 01:38:29 -0600 (MDT)
if (/^\S+ \(\S+ \[local\]\) by \S+ \(OpenSMTPD\) with \b/) { return 0; }
# from DL1GSPMX02 (dl1gspmx02.gamestop.com) by email.ebgames.com (LSMTP for Windows NT v1.1b) with SMTP id <21.000575A0@email.ebgames.com>; Tue, 12 Sep 2006 21:06:43 -0500 # from DL1GSPMX02 (dl1gspmx02.gamestop.com) by email.ebgames.com (LSMTP for Windows NT v1.1b) with SMTP id <21.000575A0@email.ebgames.com>; Tue, 12 Sep 2006 21:06:43 -0500
if (/\(LSMTP for/) { return 0; } if (/\(LSMTP for/) { return 0; }
# from ([127.0.0.1]) with MailEnable ESMTP; Wed, 10 Jul 2019 10:29:59 +0300 # from ([127.0.0.1]) with MailEnable ESMTP; Wed, 10 Jul 2019 10:29:59 +0300
if (/^\(\[${LOCALHOST}\]\) with MailEnable /) { return 0; } if (/^\(\[${LOCALHOST}\]\) with MailEnable /) { return 0; }
# from facebook.com (RrlQsUbrndsQ6/zbJaSzSPcmy3GwqE5h6IukkE5GGBIJgonAFnoQE3L +9tv2TU3e 2401:db00:1110:50e8:face:0000:002f:0000) # from facebook.com (RrlQsUbrndsQ6/zbJaSzSPcmy3GwqE5h6IukkE5GGBIJgonAFnoQE3L +9tv2TU3e 2401:db00:1110:50e8:face:0000:002f:0000)
# by facebook.com with Thrift id 423753524b5011e9a83e248a0796a3b2-169bd530; Wed, 20 Mar 2019 13:39:29 -0700 # by facebook.com with Thrift id 423753524b5011e9a83e248a0796a3b2-169bd530; Wed, 20 Mar 2019 13:39:29 -0700
if (/^facebook\.com \([^\)]+\) by facebook\.com with Thrift id \S+$/) { retu rn 0; } if (/^facebook\.com \([^\)]+\) by facebook\.com with Thrift id \S+$/) { retu rn 0; }
skipping to change at line 1347 skipping to change at line 1356
# will be recorded, but we won't have the relays handover recorded # will be recorded, but we won't have the relays handover recorded
# for that SMTP transaction, so we wind up checking the wrong IP # for that SMTP transaction, so we wind up checking the wrong IP
# for the addr. # for the addr.
if (0) { if (0) {
if ($ip eq '127.0.0.1') { if ($ip eq '127.0.0.1') {
dbg("received-header: ignoring localhost handover"); dbg("received-header: ignoring localhost handover");
return 0; # ignore localhost handovers return 0; # ignore localhost handovers
} }
} }
# Strip ending dot, Bug 7810
$rdns =~ s/\.+\z//;
if ($rdns =~ /^unknown$/i || $rdns =~ /^\[/) { if ($rdns =~ /^unknown$/i || $rdns =~ /^\[/) {
$rdns = ''; # some MTAs seem to do this $rdns = ''; # some MTAs seem to do this
} }
$ip =~ s/^ipv6://i; # remove "IPv6:" prefix $ip =~ s/^ipv6://i; # remove "IPv6:" prefix
$ip =~ s/^\[//; $ip =~ s/\]\z//; $ip =~ s/^\[//; $ip =~ s/\]\z//;
# IPv6 Scoped Address (RFC 4007, RFC 6874, RFC 3986 "unreserved" charset) # IPv6 Scoped Address (RFC 4007, RFC 6874, RFC 3986 "unreserved" charset)
$ip =~ s/%[A-Z0-9._~-]*\z//si; # scoped address? remove <zone_id> $ip =~ s/%[A-Z0-9._~-]*\z//si; # scoped address? remove <zone_id>
# remove "::ffff:" prefix from IPv4-mapped-in-IPv6 addresses, # remove "::ffff:" prefix from IPv4-mapped-in-IPv6 addresses,
# so we can treat them simply as IPv4 addresses # so we can treat them simply as IPv4 addresses
# (only handles 'alternative form', not 'preferred form' - to be improved) # (only handles 'alternative form', not 'preferred form' - to be improved)
$ip =~ s/^0*:0*:(?:0*:)*ffff:(\d+\.\d+\.\d+\.\d+)$/$1/i; $ip =~ s/^0*:0*:(?:0*:)*ffff:(\d+\.\d+\.\d+\.\d+)$/$1/i;
$envfrom =~ s/^\s*<*//gs; $envfrom =~ s/>*\s*$//gs;
$by =~ s/\;$//; $by =~ s/\;$//;
# ensure invalid chars are stripped. Replace with '!' to flag their # ensure invalid chars are stripped. Replace with '!' to flag their
# presence, though. NOTE: this means "[1.2.3.4]" IP addr HELO # presence, though. NOTE: this means "[1.2.3.4]" IP addr HELO
# strings, which are legit by RFC-2821, look like "!1.2.3.4!". # strings, which are legit by RFC-2821, look like "!1.2.3.4!".
# still useful though. # still useful though.
$ip =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs; my $strip_chars = qr/[\s\000\#\[\]\(\)\<\>\|]/;
$rdns =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs; $ip =~ s/$strip_chars/!/gs;
$helo =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs; $rdns =~ s/$strip_chars/!/gs;
$by =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs; $helo =~ s/$strip_chars/!/gs;
$ident =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs; $by =~ s/$strip_chars/!/gs;
$envfrom =~ s/[\s\000\#\[\]\(\)\<\>\|]/!/gs; $ident =~ s/$strip_chars/!/gs;
if (defined $envfrom) {
$envfrom =~ s/^\s*<*//gs;
$envfrom =~ s/>*\s*$//gs;
$envfrom =~ s/$strip_chars/!/gs;
}
my $relay = { my $relay = {
ip => $ip, ip => $ip,
by => $by, by => $by,
helo => $helo, helo => $helo,
id => $id, id => $id,
ident => $ident, ident => $ident,
envfrom => $envfrom, envfrom => $envfrom,
lc_by => (lc $by), lc_by => (lc $by),
lc_helo => (lc $helo), lc_helo => (lc $helo),
skipping to change at line 1421 skipping to change at line 1437
sub make_relay_as_string { sub make_relay_as_string {
my ($self, $relay) = @_; my ($self, $relay) = @_;
# as-string rep. use spaces so things like Bayes can tokenize them easily. # as-string rep. use spaces so things like Bayes can tokenize them easily.
# NOTE: when tokenizing or matching, be sure to note that new # NOTE: when tokenizing or matching, be sure to note that new
# entries may be added to this string later. However, the *order* # entries may be added to this string later. However, the *order*
# of entries must be preserved, so that regexps that assume that # of entries must be preserved, so that regexps that assume that
# e.g. "ip" comes before "helo" will still work. # e.g. "ip" comes before "helo" will still work.
# #
my $asstr = "[ ip=$relay->{ip} rdns=$relay->{rdns} helo=$relay->{helo} by=$rel
ay->{by} ident=$relay->{ident} envfrom=$relay->{envfrom} intl=0 id=$relay->{id} # we could mark envfrom as "undef" if missing? dunno if needed?
auth=$relay->{auth} msa=0 ]"; my $envfrom = $relay->{envfrom} || '';
my $asstr = "[ ip=$relay->{ip} rdns=$relay->{rdns} helo=$relay->{helo} by=$rel
ay->{by} ident=$relay->{ident} envfrom=$envfrom intl=0 id=$relay->{id} auth=$rel
ay->{auth} msa=0 ]";
dbg("received-header: parsed as $asstr"); dbg("received-header: parsed as $asstr");
$relay->{as_string} = $asstr; $relay->{as_string} = $asstr;
} }
# restart the parse if we find a fetchmail marker or similar. # restart the parse if we find a fetchmail marker or similar.
# spamcop does this, and it's a great idea ;) # spamcop does this, and it's a great idea ;)
sub found_pop_fetcher_sig { sub found_pop_fetcher_sig {
my ($self) = @_; my ($self) = @_;
if ($self->{allow_mailfetch_markers}) { if ($self->{allow_mailfetch_markers}) {
dbg("received-header: found mail fetcher marker, restarting parse"); dbg("received-header: found mail fetcher marker, restarting parse");
 End of changes. 11 change blocks. 
26 lines changed or deleted 48 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)