File Coverage

blib/lib/Apache2/Authen/Passphrase.pm
Criterion Covered Total %
statement 54 65 83.0
branch 6 12 50.0
condition 2 2 100.0
subroutine 15 16 93.7
pod 4 4 100.0
total 81 99 81.8


line stmt bran cond sub pod time code
1             package Apache2::Authen::Passphrase;
2              
3             our $VERSION = 0.002001;
4              
5 1     1   60979 use 5.014000;
  1         4  
  1         27  
6 1     1   6 use strict;
  1         2  
  1         28  
7 1     1   4 use warnings;
  1         6  
  1         33  
8 1     1   4 use parent qw/Exporter/;
  1         2  
  1         7  
9 1     1   906 use subs qw/OK HTTP_UNAUTHORIZED/;
  1         17  
  1         3  
10              
11             use constant +{
12 1         96 USER_REGEX => qr/^\w{2,20}$/pa,
13             PASSPHRASE_VERSION => 1,
14             INVALID_USER => "invalid-user\n",
15             BAD_PASSWORD => "bad-password\n",
16 1     1   84 };
  1         2  
17              
18 1     1   1019 use if $ENV{MOD_PERL}, 'Apache2::RequestRec';
  1         11  
  1         8  
19 1     1   40 use if $ENV{MOD_PERL}, 'Apache2::Access';
  1         3  
  1         4  
20 1     1   33 use if $ENV{MOD_PERL}, 'Apache2::Const' => qw/OK HTTP_UNAUTHORIZED/;
  1         1  
  1         4  
21 1     1   890 use Authen::Passphrase;
  1         6189  
  1         38  
22 1     1   1106 use Authen::Passphrase::BlowfishCrypt;
  1         28669  
  1         39  
23 1     1   856 use YAML::Any qw/LoadFile DumpFile/;
  1         969  
  1         5  
24              
25             our @EXPORT_OK = qw/pwset pwcheck pwhash USER_REGEX PASSPHRASE_VERSION INVALID_USER BAD_PASSWORD/;
26              
27             ##################################################
28              
29             our $rootdir //= $ENV{AAP_ROOTDIR};
30              
31             sub pwhash{
32 2     2 1 5 my ($pass)=@_;
33              
34 2         24 my $ppr=Authen::Passphrase::BlowfishCrypt->new(
35             cost => 10,
36             passphrase => $pass,
37             salt_random => 1,
38             );
39              
40 2         260762 $ppr->as_rfc2307
41             }
42              
43             sub pwset{
44 2     2 1 140312 my ($user, $pass)=@_;
45              
46 2         9 my $file = "$rootdir/$user.yml";
47 2   100     4 my $conf = eval { LoadFile $file } // undef;
  2         17  
48 2         7564 $conf->{passphrase}=pwhash $pass;
49 2         153 $conf->{passphrase_version}=PASSPHRASE_VERSION;
50 2         19 DumpFile $file, $conf;
51              
52 2         22130 chmod 0660, $file;
53             }
54              
55             sub pwcheck{
56 6     6 1 3186 my ($user, $pass)=@_;
57 6 100       59 die INVALID_USER unless $user =~ USER_REGEX;
58 3         12 $user=${^MATCH};# Make taint shut up
59 3         22 my $conf=LoadFile "$rootdir/$user.yml";
60              
61 3 50       22181 die BAD_PASSWORD unless keys $conf;# Empty hash means no such user
62 3 100       37 die BAD_PASSWORD unless Authen::Passphrase->from_rfc2307($conf->{passphrase})->match($pass);
63 2 50       256145 pwset $user, $pass if $conf->{passphrase_version} < PASSPHRASE_VERSION
64             }
65              
66             sub handler{
67 0     0 1   my $r=shift;
68 0           local $rootdir = $r->dir_config('AuthenPassphraseRootdir');
69              
70 0           my ($rc, $pass) = $r->get_basic_auth_pw;
71 0 0         return $rc unless $rc == OK;
72              
73 0           my $user=$r->user;
74 0 0         unless (eval { pwcheck $user, $pass; 1 }) {
  0            
  0            
75 0           $r->note_basic_auth_failure;
76 0           return HTTP_UNAUTHORIZED
77             }
78              
79             OK
80 0           }
81              
82             1;
83             __END__