line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mail::SRS::Shortcut; |
2
|
|
|
|
|
|
|
|
3
|
8
|
|
|
8
|
|
20625
|
use strict; |
|
8
|
|
|
|
|
15
|
|
|
8
|
|
|
|
|
231
|
|
4
|
8
|
|
|
8
|
|
39
|
use warnings; |
|
8
|
|
|
|
|
11
|
|
|
8
|
|
|
|
|
196
|
|
5
|
8
|
|
|
8
|
|
36
|
use vars qw(@ISA); |
|
8
|
|
|
|
|
19
|
|
|
8
|
|
|
|
|
277
|
|
6
|
8
|
|
|
8
|
|
38
|
use Carp; |
|
8
|
|
|
|
|
13
|
|
|
8
|
|
|
|
|
478
|
|
7
|
8
|
|
|
8
|
|
595
|
use Mail::SRS qw(:all); |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
4070
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
@ISA = qw(Mail::SRS); |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 NAME |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Mail::SRS::Shortcut - A shortcutting Sender Rewriting Scheme |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 SYNOPSIS |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
use Mail::SRS::Shortcut; |
18
|
|
|
|
|
|
|
my $srs = new Mail::SRS::Shortcut(...); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
WARNING: Using the simple Shortcut strategy is a very bad idea. Use the |
23
|
|
|
|
|
|
|
Guarded strategy instead. The weakness in the Shortcut strategy is |
24
|
|
|
|
|
|
|
documented at http://www.anarres.org/projects/srs/ |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
See Mail::SRS for details of the standard SRS subclass interface. |
27
|
|
|
|
|
|
|
This module provides the methods compile() and parse(). It operates |
28
|
|
|
|
|
|
|
without store, and shortcuts around all middleman resenders. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 SEE ALSO |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
L |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=cut |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub compile { |
37
|
64
|
|
|
64
|
1
|
116
|
my ($self, $sendhost, $senduser) = @_; |
38
|
|
|
|
|
|
|
|
39
|
64
|
100
|
|
|
|
394
|
if ($senduser =~ s/^$SRS0RE//io) { |
|
|
50
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# This duplicates effort in Guarded.pm but makes this file work |
41
|
|
|
|
|
|
|
# standalone. |
42
|
|
|
|
|
|
|
# We just do the split because this was hashed with someone |
43
|
|
|
|
|
|
|
# else's secret key and we can't check it. |
44
|
|
|
|
|
|
|
# hash, timestamp, host, user |
45
|
16
|
|
|
|
|
161
|
(undef, undef, $sendhost, $senduser) = |
46
|
|
|
|
|
|
|
split(qr/\Q$SRSSEP\E/, $senduser, 4); |
47
|
|
|
|
|
|
|
# We should do a sanity check. After all, it might NOT be |
48
|
|
|
|
|
|
|
# an SRS address, unlikely though that is. We are in the |
49
|
|
|
|
|
|
|
# presence of malicious agents. However, this code is |
50
|
|
|
|
|
|
|
# never reached if the Guarded subclass is used. |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
elsif ($senduser =~ s/$SRS1RE//io) { |
53
|
|
|
|
|
|
|
# This should never be hit in practice. It would be bad. |
54
|
|
|
|
|
|
|
# Introduce compatibility with the guarded format? |
55
|
|
|
|
|
|
|
# SRSHOST, hash, timestamp, host, user |
56
|
0
|
|
|
|
|
0
|
(undef, undef, undef, $sendhost, $senduser) = |
57
|
|
|
|
|
|
|
split(qr/\Q$SRSSEP\E/, $senduser, 6); |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
64
|
|
|
|
|
240
|
my $timestamp = $self->timestamp_create(); |
61
|
|
|
|
|
|
|
|
62
|
64
|
|
|
|
|
200
|
my $hash = $self->hash_create($timestamp, $sendhost, $senduser); |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# Note that there are 5 fields here and that sendhost may |
65
|
|
|
|
|
|
|
# not contain a valid separator. Therefore, we do not need to |
66
|
|
|
|
|
|
|
# escape separators anywhere in order to reverse this |
67
|
|
|
|
|
|
|
# transformation. |
68
|
64
|
|
|
|
|
701
|
return $SRS0TAG . $self->separator . |
69
|
|
|
|
|
|
|
join($SRSSEP, $hash, $timestamp, $sendhost, $senduser); |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub parse { |
73
|
95
|
|
|
95
|
1
|
144
|
my ($self, $user) = @_; |
74
|
|
|
|
|
|
|
|
75
|
95
|
50
|
|
|
|
425
|
unless ($user =~ s/$SRS0RE//oi) { |
76
|
|
|
|
|
|
|
# We should deal with SRS1 addresses here, just in case? |
77
|
0
|
|
|
|
|
0
|
die "Reverse address does not match $SRS0RE."; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# The 4 here matches the number of fields we encoded above. If |
81
|
|
|
|
|
|
|
# there are more separators, then they belong in senduser anyway. |
82
|
95
|
|
|
|
|
739
|
my ($hash, $timestamp, $sendhost, $senduser) = |
83
|
|
|
|
|
|
|
split(qr/\Q$SRSSEP\E/, $user, 4); |
84
|
|
|
|
|
|
|
# Again, this must match as above. |
85
|
95
|
50
|
|
|
|
385
|
unless ($self->hash_verify($hash,$timestamp,$sendhost,$senduser)) { |
86
|
0
|
|
|
|
|
0
|
die "Invalid hash"; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
95
|
50
|
|
|
|
916
|
unless ($self->timestamp_check($timestamp)) { |
90
|
0
|
|
|
|
|
0
|
die "Invalid timestamp"; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
95
|
|
|
|
|
333
|
return ($sendhost, $senduser); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
1; |