File Coverage

blib/lib/Mail/SRS/Guarded.pm
Criterion Covered Total %
statement 37 39 94.8
branch 12 14 85.7
condition 1 3 33.3
subroutine 8 8 100.0
pod 2 2 100.0
total 60 66 90.9


line stmt bran cond sub pod time code
1             package Mail::SRS::Guarded;
2              
3 6     6   7602 use strict;
  6         12  
  6         205  
4 6     6   27 use warnings;
  6         10  
  6         360  
5 6     6   31 use vars qw(@ISA);
  6         9  
  6         250  
6 6     6   29 use Carp;
  6         11  
  6         439  
7 6     6   28 use Mail::SRS qw(:all);
  6         10  
  6         1241  
8 6     6   3192 use Mail::SRS::Shortcut;
  6         13  
  6         2580  
9              
10             @ISA = qw(Mail::SRS::Shortcut);
11              
12             =head1 NAME
13              
14             Mail::SRS::Guarded - A guarded Sender Rewriting Scheme (recommended)
15              
16             =head1 SYNOPSIS
17              
18             use Mail::SRS::Guarded;
19             my $srs = new Mail::SRS::Guarded(...);
20              
21             =head1 DESCRIPTION
22              
23             This is the default subclass of Mail::SRS. An instance of this subclass
24             is actually constructed when "new Mail::SRS" is called.
25              
26             Note that allowing variable separators after the SRS\d token means that
27             we must preserve this separator in the address for a possible reversal.
28             SRS1 does not need to understand the SRS0 address, just preserve it,
29             on the assumption that it is valid and that the host doing the final
30             reversal will perform cryptographic tests. It may therefore strip just
31             the string SRS0 and not the separator. This explains the appearance
32             of a double separator in SRS1=.
33              
34             See Mail::SRS for details of the standard SRS subclass interface.
35             This module provides the methods compile() and parse(). It operates
36             without store, and guards against gaming the shortcut system.
37              
38             =head1 SEE ALSO
39              
40             L
41              
42             =cut
43              
44             sub compile {
45 75     75 1 125 my ($self, $sendhost, $senduser) = @_;
46              
47 75 100       465 if ($senduser =~ s/$SRS1RE//io) {
    100          
48              
49             # We could do a sanity check. After all, it might NOT be
50             # an SRS address, unlikely though that is. We are in the
51             # presence of malicious agents. However, since we don't need
52             # to interpret it, it doesn't matter if it isn't an SRS
53             # address. Our malicious SRS0 party gets back the garbage
54             # he spat out.
55              
56             # Actually, it turns out that we can simplify this
57             # function considerably, although it should be borne in mind
58             # that this address is not opaque to us, even though we didn't
59             # actually process or generate it.
60              
61             # hash, srshost, srsuser
62 5         44 my (undef, $srshost, $srsuser) =
63             split(qr/\Q$SRSSEP\E/, $senduser, 3);
64              
65 5         22 my $hash = $self->hash_create($srshost, $srsuser);
66              
67 5         83 return $SRS1TAG . $self->separator .
68             join($SRSSEP, $hash, $srshost, $srsuser);
69             }
70             elsif ($senduser =~ s/$SRS0RE/$1/io) {
71 37         113 my $hash = $self->hash_create($sendhost, $senduser);
72 37         389 return $SRS1TAG . $self->separator .
73             join($SRSSEP, $hash, $sendhost, $senduser);
74             }
75              
76 33         125 return $self->SUPER::compile($sendhost, $senduser);
77             }
78              
79             sub parse {
80 77     77 1 107 my ($self, $user) = @_;
81              
82 77 100       277 if ($user =~ s/$SRS1RE//oi) {
83 40         298 my ($hash, $srshost, $srsuser) =
84             split(qr/\Q$SRSSEP\E/, $user, 3);
85              
86 40 100       188 if ($hash =~ /\Q.\E/) {
87 2 100       12 die "Hashless SRS1 address received when " .
88             "AllowUnsafeSrs is not set"
89             unless $self->{AllowUnsafeSrs};
90             # Reconstruct the parameters as they were in the old format.
91 1         3 $srsuser = $srshost . $SRSSEP . $srsuser;
92 1         2 $srshost = $hash;
93             }
94             else {
95 38 50       112 unless ($self->hash_verify($hash, $srshost, $srsuser)) {
96 0         0 die "Invalid hash";
97             }
98             }
99              
100 39 50 33     435 unless (defined $srshost and defined $srsuser) {
101 0         0 die "Invalid SRS1 address";
102             }
103 39         234 return ($srshost, $SRS0TAG . $srsuser);
104             }
105              
106 37         116 return $self->SUPER::parse($user);
107             }
108              
109             1;