| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
=head1 NAME |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
Authen::Passphrase - hashed passwords/passphrases as objects |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use Authen::Passphrase; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
$ppr = Authen::Passphrase->from_crypt($passwd); |
|
10
|
|
|
|
|
|
|
$ppr = Authen::Passphrase->from_rfc2307($userPassword); |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
if($ppr->match($passphrase)) { ... |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
$passphrase = $ppr->passphrase; |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
$crypt = $ppr->as_crypt; |
|
17
|
|
|
|
|
|
|
$userPassword = $ppr->as_rfc2307; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
This is the base class for a system of objects that encapsulate |
|
22
|
|
|
|
|
|
|
passphrases. An object of this type is a passphrase recogniser: its |
|
23
|
|
|
|
|
|
|
job is to recognise whether an offered passphrase is the right one. |
|
24
|
|
|
|
|
|
|
For security, such passphrase recognisers usually do not themselves know |
|
25
|
|
|
|
|
|
|
the passphrase they are looking for; they can merely recognise it when |
|
26
|
|
|
|
|
|
|
they see it. There are many schemes in use to achieve this effect, |
|
27
|
|
|
|
|
|
|
and the intent of this class is to provide a consistent interface to |
|
28
|
|
|
|
|
|
|
them all, hiding the details. |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
The CPAN package Authen-Passphrase contains implementations of several |
|
31
|
|
|
|
|
|
|
specific passphrase schemes in addition to the base class. See the |
|
32
|
|
|
|
|
|
|
specific classes for notes on the security properties of each scheme. |
|
33
|
|
|
|
|
|
|
In new systems, if there is a choice of which passphrase algorithm to |
|
34
|
|
|
|
|
|
|
use, it is recommended to use L or |
|
35
|
|
|
|
|
|
|
L. Most other schemes are too weak |
|
36
|
|
|
|
|
|
|
for new applications, and should be used only for backward compatibility. |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head2 Side-channel cryptanalysis |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Both the Authen-Passphrase framework and most of the underlying |
|
41
|
|
|
|
|
|
|
cryptographic algorithm implementations are vulnerable to side-channel |
|
42
|
|
|
|
|
|
|
cryptanalytic attacks. However, the impact of this is quite limited. |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
Unlike the case of symmetric encryption, where a side-channel attack can |
|
45
|
|
|
|
|
|
|
extract the plaintext directly, the cryptographic operations involved in |
|
46
|
|
|
|
|
|
|
passphrase recognition don't directly process the correct passphrase. |
|
47
|
|
|
|
|
|
|
A sophisticated side-channel attack, applied when offering incorrect |
|
48
|
|
|
|
|
|
|
passphrases for checking, could potentially extract salt (from the |
|
49
|
|
|
|
|
|
|
operation of the hashing algorithm) and the target hash value (from |
|
50
|
|
|
|
|
|
|
the comparison of hash values). This would enable a cryptanalytic or |
|
51
|
|
|
|
|
|
|
brute-force attack on the passphrase recogniser to be performed offline. |
|
52
|
|
|
|
|
|
|
This is not a disaster; the very intent of storing only a hash of |
|
53
|
|
|
|
|
|
|
the correct passphrase is that leakage of these stored values doesn't |
|
54
|
|
|
|
|
|
|
compromise the passphrase. |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
In a typical usage scenario for this framework, the side-channel attacks |
|
57
|
|
|
|
|
|
|
that can be mounted are very restricted. If authenticating network |
|
58
|
|
|
|
|
|
|
users, typically an attacker has no access at all to power consumption, |
|
59
|
|
|
|
|
|
|
electromagnetic emanation, and other such side channels. The only |
|
60
|
|
|
|
|
|
|
side channel that is readily available is timing, and the precision of |
|
61
|
|
|
|
|
|
|
timing measurements is significantly blunted by the normal processes of |
|
62
|
|
|
|
|
|
|
network communication. For example, it would not normally be feasible |
|
63
|
|
|
|
|
|
|
to mount a timing attack against hash value comparison (to see how far |
|
64
|
|
|
|
|
|
|
through the values the first mismatch was). |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
Perl as a whole has not been built as a platform for |
|
67
|
|
|
|
|
|
|
side-channel-resistant cryptography, so hardening Authen-Passphrase and |
|
68
|
|
|
|
|
|
|
its underlying algorithms is not feasible. In any serious use of Perl |
|
69
|
|
|
|
|
|
|
for cryptography, including for authentication using Authen-Passphrase, |
|
70
|
|
|
|
|
|
|
an analysis should be made of the exposure to side-channel attacks, |
|
71
|
|
|
|
|
|
|
and if necessary efforts made to further blunt the timing channel. |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
One timing attack that is very obviously feasible over the network is to |
|
74
|
|
|
|
|
|
|
determine which of several passphrase hashing algorithms is being used. |
|
75
|
|
|
|
|
|
|
This can potentially distinguish between classes of user accounts, |
|
76
|
|
|
|
|
|
|
or distinguish between existing and non-existing user accounts when an |
|
77
|
|
|
|
|
|
|
attacker is guessing usernames. To obscure this information requires |
|
78
|
|
|
|
|
|
|
an extreme restriction of the timing channel, most likely by explicitly |
|
79
|
|
|
|
|
|
|
pausing to standardise the amount of time spent on authentication. |
|
80
|
|
|
|
|
|
|
This defence also rules out essentially all other timing attacks. |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head1 PASSPHRASE ENCODINGS |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Because hashed passphrases frequently need to be stored, various encodings |
|
85
|
|
|
|
|
|
|
of them have been devised. This class has constructors and methods to |
|
86
|
|
|
|
|
|
|
support these. |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head2 crypt encoding |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
The Unix crypt() function, which performs passphrase hashing, returns |
|
91
|
|
|
|
|
|
|
hashes in a textual format intended to be stored in a text file. |
|
92
|
|
|
|
|
|
|
In particular, such hashes are stored in /etc/passwd (and now /etc/shadow) |
|
93
|
|
|
|
|
|
|
to control access to Unix user accounts. The same textual format has |
|
94
|
|
|
|
|
|
|
been adopted and extended by other passphrase-handling software such as |
|
95
|
|
|
|
|
|
|
password crackers. |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
For historical reasons, there are several different syntaxes used in this |
|
98
|
|
|
|
|
|
|
format. The original DES-based password scheme represents its hashes |
|
99
|
|
|
|
|
|
|
simply as a string of thirteen base 64 digits. An extended variant of |
|
100
|
|
|
|
|
|
|
this scheme uses nineteen base 64 digits, preceded by an "B<_>" marker. |
|
101
|
|
|
|
|
|
|
A more general syntax was developed later, which starts the string with |
|
102
|
|
|
|
|
|
|
"B<$>", an alphanumeric scheme identifier, and another "B<$>". |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
In addition to actual passphrase hashes, the crypt format can also |
|
105
|
|
|
|
|
|
|
represent a couple of special cases. The empty string indicates that |
|
106
|
|
|
|
|
|
|
there is no access control; it is possible to login without giving a |
|
107
|
|
|
|
|
|
|
passphrase. Finally, any string that is not a possible output of crypt() |
|
108
|
|
|
|
|
|
|
may be used to prevent login completely; "B<*>" is the usual choice, |
|
109
|
|
|
|
|
|
|
but other strings are used too. |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
crypt strings are intended to be used in text files that use colon and |
|
112
|
|
|
|
|
|
|
newline characters as delimiters. This module treats the crypt string |
|
113
|
|
|
|
|
|
|
syntax as being limited to ASCII graphic characters excluding colon. |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=head2 RFC 2307 encoding |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
RFC 2307 describes an encoding system for passphrase hashes, to be used |
|
118
|
|
|
|
|
|
|
in the "B" attribute in LDAP databases. It encodes hashes |
|
119
|
|
|
|
|
|
|
as ASCII text, and supports several passphrase schemes in an extensible |
|
120
|
|
|
|
|
|
|
way by starting the encoding with an alphanumeric scheme identifier |
|
121
|
|
|
|
|
|
|
enclosed in braces. There are several standard scheme identifiers. |
|
122
|
|
|
|
|
|
|
The "B<{CRYPT}>" scheme allows the use of any crypt encoding. |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
This module treats the RFC 2307 string syntax as being limited to ASCII |
|
125
|
|
|
|
|
|
|
graphic characters. |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
The RFC 2307 encoding is a good one, and is recommended for storage and |
|
128
|
|
|
|
|
|
|
exchange of passphrase hashes. |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=cut |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
package Authen::Passphrase; |
|
133
|
|
|
|
|
|
|
|
|
134
|
22
|
|
|
22
|
|
408
|
{ use 5.006; } |
|
|
22
|
|
|
|
|
82
|
|
|
|
22
|
|
|
|
|
1541
|
|
|
135
|
22
|
|
|
22
|
|
150
|
use warnings; |
|
|
22
|
|
|
|
|
42
|
|
|
|
22
|
|
|
|
|
1694
|
|
|
136
|
22
|
|
|
22
|
|
120
|
use strict; |
|
|
22
|
|
|
|
|
40
|
|
|
|
22
|
|
|
|
|
1728
|
|
|
137
|
|
|
|
|
|
|
|
|
138
|
22
|
|
|
22
|
|
185
|
use Carp qw(croak); |
|
|
22
|
|
|
|
|
47
|
|
|
|
22
|
|
|
|
|
2492
|
|
|
139
|
22
|
|
|
22
|
|
29335
|
use MIME::Base64 2.21 qw(decode_base64); |
|
|
22
|
|
|
|
|
38761
|
|
|
|
22
|
|
|
|
|
2081
|
|
|
140
|
22
|
|
|
22
|
|
36356
|
use Module::Runtime 0.011 qw(use_module); |
|
|
22
|
|
|
|
|
60681
|
|
|
|
22
|
|
|
|
|
429
|
|
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
our $VERSION = "0.008"; |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=head1 CONSTRUCTORS |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=over |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=item Authen::Passphrase->from_crypt(PASSWD) |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Returns a passphrase recogniser object matching the supplied crypt |
|
151
|
|
|
|
|
|
|
encoding. This constructor may only be called on the base class, not |
|
152
|
|
|
|
|
|
|
any subclass. |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
The specific passphrase recogniser class is loaded at runtime, so |
|
155
|
|
|
|
|
|
|
successfully loading C does not guarantee that |
|
156
|
|
|
|
|
|
|
it will be possible to use a specific type of passphrase recogniser. |
|
157
|
|
|
|
|
|
|
If necessary, check separately for presence and loadability of the |
|
158
|
|
|
|
|
|
|
recogniser class. |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
Known scheme identifiers: |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=over |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=item B<$1$> |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
A baroque passphrase scheme based on MD5, designed by |
|
167
|
|
|
|
|
|
|
Poul-Henning Kamp and originally implemented in FreeBSD. See |
|
168
|
|
|
|
|
|
|
L. |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=item B<$2$> |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=item B<$2a$> |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Two versions of a passphrase scheme based on Blowfish, |
|
175
|
|
|
|
|
|
|
designed by Niels Provos and David Mazieres for OpenBSD. See |
|
176
|
|
|
|
|
|
|
L. |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=item B<$3$> |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
The NT-Hash scheme, which stores the MD4 hash of the passphrase expressed |
|
181
|
|
|
|
|
|
|
in Unicode. See L. |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=item B<$IPB2$> |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Invision Power Board 2.x salted MD5 |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=item B<$K4$> |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Kerberos AFS DES |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item B<$LM$> |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Half of the Microsoft LAN Manager hash scheme. The two |
|
194
|
|
|
|
|
|
|
halves of a LAN Manager hash can be separated and manipulated |
|
195
|
|
|
|
|
|
|
independently; this represents such an isolated half. See |
|
196
|
|
|
|
|
|
|
L. |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=item B<$NT$> |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
The NT-Hash scheme, which stores the MD4 hash of the passphrase expressed |
|
201
|
|
|
|
|
|
|
in Unicode. See L. |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
The B<$3$> identifier refers to the same hash algorithm, but has a |
|
204
|
|
|
|
|
|
|
slightly different textual format (an extra "B<$>"). |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=item B<$P$> |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
Portable PHP password hash (phpass), based on MD5. See |
|
209
|
|
|
|
|
|
|
L. |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=item B<$VMS1$> |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=item B<$VMS2$> |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=item B<$VMS3$> |
|
216
|
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
Three variants of the Purdy polynomial system used in VMS. |
|
218
|
|
|
|
|
|
|
See L. |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=item B<$af$> |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
Kerberos v4 TGT |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=item B<$apr1$> |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
A variant of the B<$1$> scheme, used by Apache. |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
=item B<$krb5$> |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
Kerberos v5 TGT |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=back |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
The historical formats supported are: |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=over |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
=item "I" |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
("I" represents a base 64 digit.) The original DES-based Unix password |
|
241
|
|
|
|
|
|
|
hash scheme. See L. |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=item "B<_>I" |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
("I" represents a base 64 digit.) Extended DES-based passphrase hash |
|
246
|
|
|
|
|
|
|
scheme from BSDi. See L. |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=item "" |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
Accept any passphrase. See L. |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=item "B<*>" |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
To handle historical practice, anything non-empty but shorter than 13 |
|
255
|
|
|
|
|
|
|
characters and not starting with "B<$>" is treated as deliberately |
|
256
|
|
|
|
|
|
|
rejecting all passphrases. (See L.) |
|
257
|
|
|
|
|
|
|
Anything 13 characters or longer, or starting with "B<$>", that is not |
|
258
|
|
|
|
|
|
|
recognised as a hash is treated as an error. |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=back |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
There are also two different passphrase schemes that use a crypt string |
|
263
|
|
|
|
|
|
|
consisting of 24 base 64 digits. One is named "bigcrypt" and appears in |
|
264
|
|
|
|
|
|
|
HP-UX, Digital Unix, and OSF/1 (see L). |
|
265
|
|
|
|
|
|
|
The other is named "crypt16" and appears in Ultrix and Tru64 (see |
|
266
|
|
|
|
|
|
|
L). These schemes conflict. Neither of |
|
267
|
|
|
|
|
|
|
them is accepted as a crypt string by this constructor; such strings |
|
268
|
|
|
|
|
|
|
are regarded as invalid encodings. |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=cut |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
my %crypt_scheme_handler = ( |
|
273
|
|
|
|
|
|
|
"1" => [ "Authen::Passphrase::MD5Crypt", 0.003 ], |
|
274
|
|
|
|
|
|
|
"2" => [ "Authen::Passphrase::BlowfishCrypt", 0.007 ], |
|
275
|
|
|
|
|
|
|
"2a" => [ "Authen::Passphrase::BlowfishCrypt", 0.007 ], |
|
276
|
|
|
|
|
|
|
"3" => [ "Authen::Passphrase::NTHash", 0.003 ], |
|
277
|
|
|
|
|
|
|
"IPB2" => sub($) { croak '$IPB2$ is unimplemented' }, |
|
278
|
|
|
|
|
|
|
"K4" => sub($) { croak '$K4$ is unimplemented' }, |
|
279
|
|
|
|
|
|
|
"LM" => [ "Authen::Passphrase::LANManagerHalf", 0.003 ], |
|
280
|
|
|
|
|
|
|
"NT" => [ "Authen::Passphrase::NTHash", 0.003 ], |
|
281
|
|
|
|
|
|
|
"P" => [ "Authen::Passphrase::PHPass", 0.003 ], |
|
282
|
|
|
|
|
|
|
"VMS1" => [ "Authen::Passphrase::VMSPurdy", 0.006 ], |
|
283
|
|
|
|
|
|
|
"VMS2" => [ "Authen::Passphrase::VMSPurdy", 0.006 ], |
|
284
|
|
|
|
|
|
|
"VMS3" => [ "Authen::Passphrase::VMSPurdy", 0.006 ], |
|
285
|
|
|
|
|
|
|
"af" => sub($) { croak '$af$ is unimplemented' }, |
|
286
|
|
|
|
|
|
|
"apr1" => sub($) { croak '$apr1$ is unimplemented' }, |
|
287
|
|
|
|
|
|
|
"krb5" => sub($) { croak '$krb5$ is unimplemented' }, |
|
288
|
|
|
|
|
|
|
); |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub from_crypt { |
|
291
|
5
|
|
|
5
|
1
|
11
|
my($class, $passwd) = @_; |
|
292
|
5
|
50
|
|
|
|
1043
|
croak "crypt string \"$passwd\" not supported for $class" |
|
293
|
|
|
|
|
|
|
unless $class eq __PACKAGE__; |
|
294
|
0
|
|
|
|
|
0
|
my $handler; |
|
295
|
0
|
0
|
|
|
|
0
|
if($passwd =~ /\A\$([0-9A-Za-z]+)\$/) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
296
|
0
|
|
|
|
|
0
|
my $scheme = $1; |
|
297
|
0
|
|
|
|
|
0
|
$handler = $crypt_scheme_handler{$scheme}; |
|
298
|
0
|
0
|
|
|
|
0
|
croak "unrecognised crypt scheme \$$scheme\$" |
|
299
|
|
|
|
|
|
|
unless defined $handler; |
|
300
|
|
|
|
|
|
|
} elsif($passwd =~ m#\A(?:[^\$].{12}|_.{19})\z#s) { |
|
301
|
0
|
|
|
|
|
0
|
$handler = [ "Authen::Passphrase::DESCrypt", 0.006 ]; |
|
302
|
|
|
|
|
|
|
} elsif($passwd eq "") { |
|
303
|
0
|
|
|
|
|
0
|
$handler = [ "Authen::Passphrase::AcceptAll", 0.003 ]; |
|
304
|
|
|
|
|
|
|
} elsif($passwd =~ /\A[^\$].{0,11}\z/s) { |
|
305
|
0
|
|
|
|
|
0
|
$handler = [ "Authen::Passphrase::RejectAll", 0.003 ]; |
|
306
|
|
|
|
|
|
|
} else { |
|
307
|
0
|
|
|
|
|
0
|
croak "bad crypt syntax in \"$passwd\""; |
|
308
|
|
|
|
|
|
|
} |
|
309
|
0
|
0
|
|
|
|
0
|
if(ref($handler) eq "CODE") { |
|
310
|
0
|
|
|
|
|
0
|
return $handler->($passwd); |
|
311
|
|
|
|
|
|
|
} else { |
|
312
|
0
|
|
|
|
|
0
|
my($modname, $modver) = @$handler; |
|
313
|
0
|
|
|
|
|
0
|
return use_module($modname, $modver)->from_crypt($passwd); |
|
314
|
|
|
|
|
|
|
} |
|
315
|
|
|
|
|
|
|
} |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=item Authen::Passphrase->from_rfc2307(USERPASSWORD) |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Returns a passphrase recogniser object matching the supplied RFC 2307 |
|
320
|
|
|
|
|
|
|
encoding. This constructor may only be called on the base class, not |
|
321
|
|
|
|
|
|
|
any subclass. |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
The specific passphrase recogniser class is loaded at runtime. See the |
|
324
|
|
|
|
|
|
|
note about this for the L constructor above. |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Known scheme identifiers: |
|
327
|
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=over |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=item B<{CLEARTEXT}> |
|
331
|
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
Passphrase stored in cleartext. See L. |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=item B<{CRYPT}> |
|
335
|
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
The scheme identifier is followed by a crypt string. |
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=item B<{CRYPT16}> |
|
339
|
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
Used ambiguously by Exim, to refer to either crypt16 |
|
341
|
|
|
|
|
|
|
(see L) or bigcrypt (see |
|
342
|
|
|
|
|
|
|
L) depending on compilation options. |
|
343
|
|
|
|
|
|
|
This is a bug, resulting from a confusion between the two algorithms. |
|
344
|
|
|
|
|
|
|
This module does not support any meaning for this scheme identifier. |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=item B<{K5KEY}> |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
Not a real passphrase scheme, but a placeholder to indicate that a |
|
349
|
|
|
|
|
|
|
Kerberos key stored separately should be checked against. No data |
|
350
|
|
|
|
|
|
|
follows the scheme identifier. |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=item B<{KERBEROS}> |
|
353
|
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
Not a real passphrase scheme, but a placeholder to indicate that |
|
355
|
|
|
|
|
|
|
Kerberos should be invoked to check against a user's passphrase. |
|
356
|
|
|
|
|
|
|
The scheme identifier is followed by the user's username, in the form |
|
357
|
|
|
|
|
|
|
"IB<@>I". |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=item B<{LANM}> |
|
360
|
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Synonym for B<{LANMAN}>, used by CommuniGate Pro. |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=item B<{LANMAN}> |
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
The Microsoft LAN Manager hash scheme. See |
|
366
|
|
|
|
|
|
|
L. |
|
367
|
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=item B<{MD4}> |
|
369
|
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
The MD4 digest of the passphrase is stored. See |
|
371
|
|
|
|
|
|
|
L. |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=item B<{MD5}> |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
The MD5 digest of the passphrase is stored. See |
|
376
|
|
|
|
|
|
|
L. |
|
377
|
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=item B<{MSNT}> |
|
379
|
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
The NT-Hash scheme, which stores the MD4 hash of the passphrase expressed |
|
381
|
|
|
|
|
|
|
in Unicode. See L. |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=item B<{NS-MTA-MD5}> |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
An MD5-based scheme used by Netscape Mail Server. See |
|
386
|
|
|
|
|
|
|
L. |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=item B<{RMD160}> |
|
389
|
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
The RIPEMD-160 digest of the passphrase is stored. See |
|
391
|
|
|
|
|
|
|
L. |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=item B<{SASL}> |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
Not a real passphrase scheme, but a placeholder to indicate that SASL |
|
396
|
|
|
|
|
|
|
should be invoked to check against a user's passphrase. The scheme |
|
397
|
|
|
|
|
|
|
identifier is followed by the user's username. |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=item B<{SHA}> |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
The SHA-1 digest of the passphrase is stored. See |
|
402
|
|
|
|
|
|
|
L. |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=item B<{SMD5}> |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
The MD5 digest of the passphrase plus a salt is stored. See |
|
407
|
|
|
|
|
|
|
L. |
|
408
|
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=item B<{SSHA}> |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
The SHA-1 digest of the passphrase plus a salt is stored. |
|
412
|
|
|
|
|
|
|
See L. |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=item B<{UNIX}> |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
Not a real passphrase scheme, but a placeholder to indicate that Unix |
|
417
|
|
|
|
|
|
|
mechanisms should be used to check against a Unix user's login passphrase. |
|
418
|
|
|
|
|
|
|
The scheme identifier is followed by the user's username. |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=item B<{WM-CRY}> |
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
Synonym for B<{CRYPT}>, used by CommuniGate Pro. |
|
423
|
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
=back |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=cut |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
my %rfc2307_scheme_handler = ( |
|
429
|
|
|
|
|
|
|
"CLEARTEXT" => [ "Authen::Passphrase::Clear", 0.003 ], |
|
430
|
|
|
|
|
|
|
# "CRYPT" is handled specially |
|
431
|
|
|
|
|
|
|
"CRYPT16" => sub($) { croak "{CRYPT16} is ambiguous" }, |
|
432
|
|
|
|
|
|
|
"K5KEY" => sub($) { croak "{K5KEY} is a placeholder" }, |
|
433
|
|
|
|
|
|
|
"KERBEROS" => sub($) { croak "{KERBEROS} is a placeholder" }, |
|
434
|
|
|
|
|
|
|
"LANM" => [ "Authen::Passphrase::LANManager", 0.003 ], |
|
435
|
|
|
|
|
|
|
"LANMAN" => [ "Authen::Passphrase::LANManager", 0.003 ], |
|
436
|
|
|
|
|
|
|
"MD4" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], |
|
437
|
|
|
|
|
|
|
"MD5" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], |
|
438
|
|
|
|
|
|
|
"MSNT" => [ "Authen::Passphrase::NTHash", 0.003 ], |
|
439
|
|
|
|
|
|
|
"NS-MTA-MD5" => [ "Authen::Passphrase::NetscapeMail", 0.003 ], |
|
440
|
|
|
|
|
|
|
"RMD160" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], |
|
441
|
|
|
|
|
|
|
"SASL" => sub($) { croak "{SASL} is a placeholder" }, |
|
442
|
|
|
|
|
|
|
"SHA" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], |
|
443
|
|
|
|
|
|
|
"SMD5" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], |
|
444
|
|
|
|
|
|
|
"SSHA" => [ "Authen::Passphrase::SaltedDigest", 0.008 ], |
|
445
|
|
|
|
|
|
|
"UNIX" => sub($) { croak "{UNIX} is a placeholder" }, |
|
446
|
|
|
|
|
|
|
# "WM-CRY" is handled specially |
|
447
|
|
|
|
|
|
|
); |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
sub from_rfc2307 { |
|
450
|
11
|
|
|
11
|
1
|
2555
|
my($class, $userpassword) = @_; |
|
451
|
11
|
50
|
|
|
|
186
|
if($userpassword =~ m#\A\{(?i:crypt|wm-cry)\}(.*)\z#s) { |
|
452
|
11
|
|
|
|
|
34
|
my $passwd = $1; |
|
453
|
11
|
|
|
|
|
53
|
return $class->from_crypt($passwd); |
|
454
|
|
|
|
|
|
|
} |
|
455
|
0
|
0
|
|
|
|
0
|
croak "RFC 2307 string \"$userpassword\" not supported for $class" |
|
456
|
|
|
|
|
|
|
unless $class eq __PACKAGE__; |
|
457
|
0
|
0
|
|
|
|
0
|
$userpassword =~ /\A\{([-0-9a-z]+)\}/i |
|
458
|
|
|
|
|
|
|
or croak "bad RFC 2307 syntax in \"$userpassword\""; |
|
459
|
0
|
|
|
|
|
0
|
my $scheme = uc($1); |
|
460
|
0
|
|
|
|
|
0
|
my $handler = $rfc2307_scheme_handler{$scheme}; |
|
461
|
0
|
0
|
|
|
|
0
|
croak "unrecognised RFC 2307 scheme {$scheme}" unless defined $handler; |
|
462
|
0
|
0
|
|
|
|
0
|
if(ref($handler) eq "CODE") { |
|
463
|
0
|
|
|
|
|
0
|
return $handler->($userpassword); |
|
464
|
|
|
|
|
|
|
} else { |
|
465
|
0
|
|
|
|
|
0
|
my($modname, $modver) = @$handler; |
|
466
|
0
|
|
|
|
|
0
|
return use_module($modname, $modver) |
|
467
|
|
|
|
|
|
|
->from_rfc2307($userpassword); |
|
468
|
|
|
|
|
|
|
} |
|
469
|
|
|
|
|
|
|
} |
|
470
|
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
=back |
|
472
|
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
=head1 METHODS |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
=over |
|
476
|
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
=item $ppr->match(PASSPHRASE) |
|
478
|
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
Checks whether the supplied passphrase is correct. Returns a truth value. |
|
480
|
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
=item $ppr->passphrase |
|
482
|
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
If a matching passphrase can be easily determined by the passphrase |
|
484
|
|
|
|
|
|
|
recogniser then this method will return it. This is only feasible for |
|
485
|
|
|
|
|
|
|
very weak passphrase schemes. The method Cs if it is infeasible. |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=item $ppr->as_crypt |
|
488
|
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Encodes the passphrase recogniser in crypt format and returns the encoded |
|
490
|
|
|
|
|
|
|
result. Cs if the passphrase recogniser cannot be represented in |
|
491
|
|
|
|
|
|
|
this form. |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=item $ppr->as_rfc2307 |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
Encodes the passphrase recogniser in RFC 2307 format and returns |
|
496
|
|
|
|
|
|
|
the encoded result. Cs if the passphrase recogniser cannot be |
|
497
|
|
|
|
|
|
|
represented in this form. |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=cut |
|
500
|
|
|
|
|
|
|
|
|
501
|
73
|
|
|
73
|
1
|
5718
|
sub as_rfc2307 { "{CRYPT}".$_[0]->as_crypt } |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=back |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
=head1 SUBCLASSING |
|
506
|
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
This class is designed to be subclassed, and cannot be instantiated alone. |
|
508
|
|
|
|
|
|
|
Any subclass must implement the L method. That is the minimum |
|
509
|
|
|
|
|
|
|
required. |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
Subclasses should implement the L and L methods |
|
512
|
|
|
|
|
|
|
and the L and L constructors wherever |
|
513
|
|
|
|
|
|
|
appropriate, with the following exception. If a passphrase scheme has |
|
514
|
|
|
|
|
|
|
a crypt encoding but no native RFC 2307 encoding, so it can be RFC 2307 |
|
515
|
|
|
|
|
|
|
encoded only by using the "B<{CRYPT}>" scheme, then L and |
|
516
|
|
|
|
|
|
|
L should I be implemented by the class. There is a |
|
517
|
|
|
|
|
|
|
default implementation of the L method that uses "B<{CRYPT}>" |
|
518
|
|
|
|
|
|
|
and L, and a default implementation of the L |
|
519
|
|
|
|
|
|
|
method that recognises "B<{CRYPT}>" and passes the embedded crypt string |
|
520
|
|
|
|
|
|
|
to the L constructor. |
|
521
|
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
Implementation of the L method is entirely optional. |
|
523
|
|
|
|
|
|
|
It should be attempted only for schemes that are so ludicrously weak as |
|
524
|
|
|
|
|
|
|
to allow passphrases to be cracked reliably in a short time. Dictionary |
|
525
|
|
|
|
|
|
|
attacks are not appropriate implementations. |
|
526
|
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
L, |
|
530
|
|
|
|
|
|
|
L, |
|
531
|
|
|
|
|
|
|
RFC 2307 |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
=head1 AUTHOR |
|
534
|
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
Andrew Main (Zefram) |
|
536
|
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
538
|
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
Copyright (C) 2006, 2007, 2009, 2010, 2012 |
|
540
|
|
|
|
|
|
|
Andrew Main (Zefram) |
|
541
|
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=head1 LICENSE |
|
543
|
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or modify it |
|
545
|
|
|
|
|
|
|
under the same terms as Perl itself. |
|
546
|
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
=cut |
|
548
|
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
1; |