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-Language" => "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   311 use strict;
  40         103  
  40         1327  
50 40     40   244 use warnings;
  40         140  
  40         1586  
51             # use bytes;
52 40     40   287 use re 'taint';
  40         96  
  40         1641  
53              
54 40     40   257 use Mail::SpamAssassin;
  40         97  
  40         1123  
55 40     40   274 use Mail::SpamAssassin::Constants qw(:sa);
  40         99  
  40         5984  
56 40     40   294 use Mail::SpamAssassin::Util qw(reverse_ip_address);
  40         101  
  40         2067  
57 40     40   13326 use Mail::SpamAssassin::Message::Metadata::Received;
  40         344  
  40         3809  
58 40     40   417 use Mail::SpamAssassin::Logger;
  40         176  
  40         15927  
59              
60             =item new()
61              
62             =back
63              
64             =cut
65              
66             sub new {
67 137     137 1 477 my ($class, $msg) = @_;
68 137   33     896 $class = ref($class) || $class;
69              
70 137         939 my $self = {
71             msg => $msg,
72             strings => { }
73             };
74              
75 137         473 bless($self,$class);
76 137         639 $self;
77             }
78              
79             sub extract {
80 102     102 0 353 my ($self, $msg, $permsgstatus) = @_;
81              
82             # pre-chew Received headers
83 102         952 $self->parse_received_headers ($permsgstatus, $msg);
84              
85 102         1245 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         848 { my($rly, $tag) = @$tuple;
91 408         567 my @revips;
92             @revips = map {
93 408 50       956 my($ip,$revip);
  130         211  
94 130 100 66     639 $ip = $_->{ip} if ref $_ && !$_->{ip_private};
95 130 100 66     698 $revip = reverse_ip_address($ip) if defined $ip && $ip ne '';
96 130 100 66     619 defined $revip && $revip ne '' ? $revip : ();
97             } @$rly if $rly;
98 408 100       1289 $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         1158 conf => $permsgstatus->{main}->{conf} });
105             }
106              
107             sub finish {
108 116     116 0 275 my ($self) = @_;
109 116         258 %{$self} = ();
  116         902  
110             }
111              
112             1;