bea2bca35a2fb3e1728ac4cc4a4c2c5e1f9ffc49
[apache2-authen-passphrase.git] / lib / Apache2 / Authen / Passphrase.pm
1 package Apache2::Authen::Passphrase;
2
3 our $VERSION = 0.002;
4
5 use 5.014000;
6 use strict;
7 use warnings;
8 use parent qw/Exporter/;
9
10 use constant +{
11 USER_REGEX => qr/^\w{2,20}$/pa,
12 PASSPHRASE_VERSION => 1,
13 INVALID_USER => "invalid-user\n",
14 BAD_PASSWORD => "bad-password\n",
15 };
16
17 use Apache2::RequestRec;
18 use Apache2::Access;
19 use Apache2::Const qw/OK HTTP_UNAUTHORIZED/;
20 use Authen::Passphrase;
21 use Authen::Passphrase::BlowfishCrypt;
22 use YAML::Any qw/LoadFile DumpFile/;
23
24 our @EXPORT_OK = qw/pwset pwcheck pwhash USER_REGEX PASSPHRASE_VERSION INVALID_USER BAD_PASSWORD/;
25
26 ##################################################
27
28 our $rootdir //= $ENV{AAP_ROOTDIR};
29
30 sub pwhash{
31 my ($pass)=@_;
32
33 my $ppr=Authen::Passphrase::BlowfishCrypt->new(
34 cost => 10,
35 passphrase => $pass,
36 salt_random => 1,
37 );
38
39 $ppr->as_rfc2307
40 }
41
42 sub pwset{
43 my ($user, $pass)=@_;
44
45 my $file = "$rootdir/$user.yml";
46 my $conf = eval { LoadFile $file } // undef;
47 $conf->{passphrase}=pwhash $pass;
48 $conf->{passphrase_version}=PASSPHRASE_VERSION;
49 DumpFile $file, $conf;
50
51 chmod 0660, $file;
52 }
53
54 sub pwcheck{
55 my ($user, $pass)=@_;
56 die INVALID_USER unless $user =~ USER_REGEX;
57 $user=${^MATCH};# Make taint shut up
58 my $conf=LoadFile "$rootdir/$user.yml";
59
60 die BAD_PASSWORD unless keys $conf;# Empty hash means no such user
61 die BAD_PASSWORD unless Authen::Passphrase->from_rfc2307($conf->{passphrase})->match($pass);
62 pwset $user, $pass if $conf->{passphrase_version} < PASSPHRASE_VERSION
63 }
64
65 sub handler{
66 my $r=shift;
67 local $rootdir = $r->dir_config('AuthenPassphraseRootdir');
68
69 my ($rc, $pass) = $r->get_basic_auth_pw;
70 return $rc unless $rc == OK;
71
72 my $user=$r->user;
73 unless (eval { pwcheck $user, $pass; 1 }) {
74 $r->note_basic_auth_failure;
75 return HTTP_UNAUTHORIZED
76 }
77
78 OK
79 }
80
81 1;
82 __END__
83
84 =head1 NAME
85
86 Apache2::Authen::Passphrase - basic authentication with Authen::Passphrase
87
88 =head1 SYNOPSIS
89
90 use Apache2::Authen::Passphrase qw/pwcheck pwset pwhash/;
91 $Apache2::Authen::Passphrase::rootdir = "/path/to/user/directory"
92 my $hash = pwhash $username, $password;
93 pwset $username, "pass123";
94 eval { pwcheck $username, "pass123" };
95
96 # In Apache2 config
97 <Location /secret>
98 PerlAuthenHandler Apache2::Authen::Passphrase
99 PerlSetVar AuthenPassphraseRootdir /path/to/user/directory
100 AuthName MyAuth
101 Require valid-user
102 </Location>
103
104 =head1 DESCRIPTION
105
106 Apache2::Authen::Passphrase is a perl module which provides easy-to-use Apache2 authentication. It exports some utility functions and it contains a PerlAuthenHandler.
107
108 The password hashes are stored in YAML files in an directory (called the C<rootdir>), one file per user.
109
110 Set the C<rootdir> like this:
111
112 $Apache2::Authen::Passphrase::rootdir = '/path/to/rootdir';
113
114 or by setting the C<AAP_ROOTDIR> enviroment variable to the desired value.
115
116 =head1 FUNCTIONS
117
118 =over
119
120 =item B<pwhash>()
121
122 Takes the password as a single argument and returns the password hash.
123
124 =item B<pwset>(I<$username>, I<$password>)
125
126 Sets the password of $username to $password.
127
128 =item B<pwcheck>(I<$username>, I<$password>)
129
130 Checks the given username and password, throwing an exception if the username is invalid or the password is incorrect.
131
132 =item B<handler>
133
134 The PerlAuthenHandler for use in apache2. It uses Basic Access Authentication.
135
136 =item B<USER_REGEX>
137
138 A regex that matches valid usernames. Usernames must be at least 2 characters, at most 20 characters, and they may only contain word characters (C<[A-Za-z0-9_]>).
139
140 =item B<INVALID_USER>
141
142 Exception thrown if the username does not match C<USER_REGEX>.
143
144 =item B<BAD_PASSWORD>
145
146 Exception thrown if the password is different from the one stored in the user's yml file.
147
148 =item B<PASSPHRASE_VERSION>
149
150 The version of the passphrase. It is incremented each time the passphrase hashing scheme is changed. Versions so far:
151
152 =over
153
154 =item Version 1 B<(current)>
155
156 Uses C<Authen::Passphrase::BlowfishCrypt> with a cost factor of 10
157
158 =back
159
160 =back
161
162 =head1 ENVIRONMENT
163
164 =over
165
166 =item AAP_ROOTDIR
167
168 If the C<rootdir> is not explicitly set, it is taken from this environment variable.
169
170 =back
171
172 =head1 AUTHOR
173
174 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
175
176 =head1 COPYRIGHT AND LICENSE
177
178 Copyright (C) 2013 by Marius Gavrilescu
179
180 This library is free software; you can redistribute it and/or modify
181 it under the same terms as Perl itself, either Perl version 5.14.2 or,
182 at your option, any later version of Perl 5 you may have available.
183
184
185 =cut
This page took 0.028157 seconds and 3 git commands to generate.