File Coverage

blib/lib/Mail/DKIM/Canonicalization/DkimCommon.pm
Criterion Covered Total %
statement 46 55 83.6
branch 9 16 56.2
condition n/a
subroutine 10 12 83.3
pod 2 8 25.0
total 67 91 73.6


line stmt bran cond sub pod time code
1             package Mail::DKIM::Canonicalization::DkimCommon;
2 14     14   113 use strict;
  14         33  
  14         399  
3 14     14   77 use warnings;
  14         32  
  14         593  
4             our $VERSION = '1.20230212'; # VERSION
5             # ABSTRACT: common canonicalization
6              
7             # Copyright 2005-2007 Messiah College. All rights reserved.
8             # Jason Long
9              
10             # Copyright (c) 2004 Anthony D. Urso. All rights reserved.
11             # This program is free software; you can redistribute it and/or
12             # modify it under the same terms as Perl itself.
13              
14 14     14   89 use base 'Mail::DKIM::Canonicalization::Base';
  14         38  
  14         6733  
15 14     14   103 use Carp;
  14         39  
  14         8609  
16              
17             sub init {
18 905     905 0 1415 my $self = shift;
19 905         2263 $self->SUPER::init;
20              
21 905         1617 $self->{body_count} = 0;
22 905         1470 $self->{body_truncated} = 0;
23              
24             # these canonicalization methods require signature to use
25             $self->{Signature}
26 905 50       2607 or croak 'no signature specified';
27             }
28              
29             # similar to code in DkCommon.pm
30       5848 0   sub add_header {
31              
32             #Note: canonicalization of headers is performed
33             #in finish_header()
34             }
35              
36             sub finish_header {
37 253     253 1 464 my $self = shift;
38 253         702 my %args = @_;
39              
40             # Headers are canonicalized in the order specified by the h= tag.
41             # However, in the case of multiple instances of the same header name,
42             # the headers will be canonicalized in reverse order (i.e. "from
43             # the bottom of the header field block to the top").
44             #
45             # This is described in 5.4 of RFC4871.
46              
47             # Since the bottom-most headers are to get precedence, we reverse
48             # the headers here... (now the first header matching a particular
49             # name is the header to insert)
50 253         418 my @mess_headers = reverse @{ $args{Headers} };
  253         1123  
51              
52             # presence of a h= tag is mandatory...
53 253 50       864 unless ( defined $self->{Signature}->headerlist ) {
54 0         0 die "Error: h= tag is required for this canonicalization\n";
55             }
56              
57             # iterate through the header field names specified in the signature
58 253         691 my @sig_headers = $self->{Signature}->headerlist;
59 253         611 foreach my $hdr_name (@sig_headers) {
60 1402         2667 $hdr_name = lc $hdr_name;
61              
62             # find the specified header in the message
63             inner_loop:
64 1402         3339 for ( my $i = 0 ; $i < @mess_headers ; $i++ ) {
65 5544         8668 my $hdr = $mess_headers[$i];
66              
67 5544 100       16836 if ( $hdr =~ /^([^\s:]+)\s*:/ ) {
68 5542         10859 my $key = lc $1;
69 5542 100       13412 if ( $key eq $hdr_name ) {
70              
71             # found it
72              
73             # remove it from our list, so if it occurs more than
74             # once, we'll get the next header in line
75 1392         2557 splice @mess_headers, $i, 1;
76              
77 1392         4498 $hdr =~ s/\015\012\z//s;
78 1392         3980 $self->output(
79             $self->canonicalize_header($hdr) . "\015\012" );
80 1392         4399 last inner_loop;
81             }
82             }
83             }
84             }
85             }
86              
87             sub add_body {
88 252     252 1 456 my $self = shift;
89 252         696 my ($multiline) = @_;
90              
91 252         746 $multiline = $self->canonicalize_body($multiline);
92 252 50       657 if ( $self->{Signature} ) {
93 252 50       820 if ( my $limit = $self->{Signature}->body_count ) {
94 0         0 my $remaining = $limit - $self->{body_count};
95 0 0       0 if ( length($multiline) > $remaining ) {
96 0         0 $self->{body_truncated} += length($multiline) - $remaining;
97 0         0 $multiline = substr( $multiline, 0, $remaining );
98             }
99             }
100             }
101              
102 252         574 $self->{body_count} += length($multiline);
103 252         734 $self->output($multiline);
104             }
105              
106       411 0   sub finish_body {
107             }
108              
109             sub finish_message {
110 1     1 0 8 my $self = shift;
111              
112 1 50       4 if ( $self->{Signature} ) {
113 1         4 $self->output("\015\012");
114              
115             # append the DKIM-Signature (without data)
116 1         6 my $line = $self->{Signature}->as_string_without_data;
117              
118             # signature is subject to same canonicalization as headers
119 1         7 $self->output( $self->canonicalize_header($line) );
120             }
121             }
122              
123             sub body_count {
124 0     0 0   my $self = shift;
125 0           return $self->{body_count};
126             }
127              
128             sub body_truncated {
129 0     0 0   my $self = shift;
130 0           return $self->{body_truncated};
131             }
132              
133             1;
134              
135             __END__