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; |