File Coverage

blib/lib/Mail/SpamAssassin/Message/Metadata.pm
Criterion Covered Total %
statement 44 44 100.0
branch 11 12 91.6
condition 7 12 58.3
subroutine 11 11 100.0
pod 1 3 33.3
total 74 82 90.2


line stmt bran cond sub pod time 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              
20             Mail::SpamAssassin::Message::Metadata - extract metadata from a message
21              
22             =head1 DESCRIPTION
23              
24             This class is tasked with extracting "metadata" from messages for use as
25             Bayes tokens, fodder for eval tests, or other rules. Metadata is
26             supplemental data inferred from the message, like the examples below.
27              
28             It is held in two forms:
29              
30             1. as name-value pairs of strings, presented in mail header format. For
31             example, "X-Languages" => "en". This is the general form for simple
32             metadata that's useful as Bayes tokens, can be added to marked-up
33             messages using "add_header", etc., such as the trusted-relay inference
34             and language detection.
35              
36             2. as more complex data structures on the $msg->{metadata} object. This
37             is the form used for metadata like the HTML parse data, which is stored
38             there for access by eval rule code. Because it's not simple strings,
39             it's not added as a Bayes token by default (Bayes needs simple strings).
40              
41             =head1 PUBLIC METHODS
42              
43             =over 4
44              
45             =cut
46              
47             package Mail::SpamAssassin::Message::Metadata;
48              
49 40     40   297 use strict;
  40         94  
  40         1445  
50 40     40   240 use warnings;
  40         142  
  40         1427  
51             # use bytes;
52 40     40   251 use re 'taint';
  40         79  
  40         1620  
53              
54 40     40   255 use Mail::SpamAssassin;
  40         97  
  40         1174  
55 40     40   246 use Mail::SpamAssassin::Constants qw(:sa);
  40         76  
  40         6730  
56 40     40   302 use Mail::SpamAssassin::Util qw(reverse_ip_address);
  40         94  
  40         2172  
57 40     40   14121 use Mail::SpamAssassin::Message::Metadata::Received;
  40         276  
  40         3698  
58 40     40   411 use Mail::SpamAssassin::Logger;
  40         179  
  40         15677  
59              
60             =item new()
61              
62             =back
63              
64             =cut
65              
66             sub new {
67 149     149 1 496 my ($class, $msg) = @_;
68 149   33     882 $class = ref($class) || $class;
69              
70 149         818 my $self = {
71             msg => $msg,
72             strings => { }
73             };
74              
75 149         495 bless($self,$class);
76 149         594 $self;
77             }
78              
79             sub extract {
80 102     102 0 345 my ($self, $msg, $permsgstatus) = @_;
81              
82             # pre-chew Received headers
83 102         844 $self->parse_received_headers ($permsgstatus, $msg);
84              
85 102         1097 foreach my $tuple (
86             [$self->{relays_trusted}, 'RELAYSTRUSTEDREVIP' ],
87             [$self->{relays_untrusted}, 'RELAYSUNTRUSTEDREVIP'],
88             [$self->{relays_internal}, 'RELAYSINTERNALREVIP' ],
89             [$self->{relays_external}, 'RELAYSEXTERNALREVIP' ])
90 408         855 { my($rly, $tag) = @$tuple;
91 408         588 my @revips;
92             @revips = map {
93 408 50       945 my($ip,$revip);
  130         228  
94 130 100 66     747 $ip = $_->{ip} if ref $_ && !$_->{ip_private};
95 130 100 66     1029 $revip = reverse_ip_address($ip) if defined $ip && $ip ne '';
96 130 100 66     956 defined $revip && $revip ne '' ? $revip : ();
97             } @$rly if $rly;
98 408 100       1374 $permsgstatus->set_tag($tag,
    100          
99             @revips == 1 ? $revips[0] : \@revips) if @revips;
100             }
101              
102             $permsgstatus->{main}->call_plugins("extract_metadata",
103             { msg => $msg, permsgstatus => $permsgstatus,
104 102         1192 conf => $permsgstatus->{main}->{conf} });
105             }
106              
107             sub finish {
108 128     128 0 410 my ($self) = @_;
109 128         253 %{$self} = ();
  128         967  
110             }
111              
112             1;