File Coverage

blib/lib/Mail/SRS/DB.pm
Criterion Covered Total %
statement 26 48 54.1
branch 2 12 16.6
condition n/a
subroutine 8 10 80.0
pod 3 3 100.0
total 39 73 53.4


line stmt bran cond sub pod time code
1             package Mail::SRS::DB;
2              
3 1     1   28483 use strict;
  1         1  
  1         33  
4 1     1   4 use warnings;
  1         2  
  1         31  
5 1     1   4 use vars qw(@ISA);
  1         2  
  1         50  
6 1     1   4 use Carp;
  1         1  
  1         91  
7 1     1   935 use MLDBM qw(DB_File Storable);
  1         3851  
  1         6  
8 1     1   30 use Fcntl;
  1         2  
  1         297  
9 1     1   1274 use Mail::SRS qw(:all);
  1         3  
  1         578  
10              
11             @ISA = qw(Mail::SRS);
12              
13             =head1 NAME
14              
15             Mail::SRS::DB - A MLDBM based Sender Rewriting Scheme
16              
17             =head1 SYNOPSIS
18              
19             use Mail::SRS::DB;
20             my $srs = new Mail::SRS::DB(
21             Database => '/var/run/srs.db',
22             ...
23             );
24              
25             =head1 DESCRIPTION
26              
27             See Mail::SRS for details of the standard SRS subclass interface.
28             This module provides the methods compile() and parse().
29              
30             This module requires one extra parameter to the constructor, a filename
31             for a Berkeley DB_File database.
32              
33             =head1 BUGS
34              
35             This code relies on not getting collisions in the cryptographic
36             hash. This can and should be fixed.
37              
38             The database is not garbage collected.
39              
40             =head1 SEE ALSO
41              
42             L
43              
44             =cut
45              
46             sub new {
47 1     1 1 15 my $class = shift;
48 1         12 my $self = $class->SUPER::new(@_);
49 1 50       14 die "No database specified for Mail::SRS::DB"
50             unless $self->{Database};
51 1         2 my %data;
52 1 50       11 my $dbm = tie %data, 'MLDBM',
53             $self->{Database}, O_CREAT|O_RDWR, 0640
54             or die "Cannot open $self->{Database}: $!";
55 0           $self->{Data} = \%data;
56 0           return $self;
57             }
58              
59             sub compile {
60 0     0 1   my ($self, $sendhost, $senduser) = @_;
61              
62 0           my $time = time();
63              
64 0           my $data = {
65             Time => $time,
66             SendHost => $sendhost,
67             SendUser => $senduser,
68             };
69              
70             # We rely on not getting collisions in this hash.
71 0           my $hash = $self->hash_create($sendhost, $senduser);
72              
73 0           $self->{Data}->{$hash} = $data;
74              
75             # Note that there are 4 fields here and that sendhost may
76             # not contain a + sign. Therefore, we do not need to escape
77             # + signs anywhere in order to reverse this transformation.
78 0           return $SRS0TAG . $self->separator . $hash;
79             }
80              
81             sub parse {
82 0     0 1   my ($self, $user) = @_;
83              
84 0 0         unless ($user =~ s/$SRS0RE//oi) {
85 0           die "Reverse address does not match $SRS0RE.";
86             }
87              
88 0           my $hash = $user;
89 0           my $data;
90              
91 0 0         unless ($data = $self->{Data}->{$hash}) {
92 0           die "No data found";
93             }
94              
95 0           my $sendhost = $data->{SendHost};
96 0           my $senduser = $data->{SendUser};
97              
98 0 0         unless ($self->hash_verify($hash, $sendhost, $senduser)) {
99 0           die "Invalid hash";
100             }
101              
102 0 0         unless ($self->time_check($data->{Time})) {
103 0           die "Invalid timestamp";
104             }
105              
106 0           return ($sendhost, $senduser);
107             }
108              
109             1;