Authen-Passphrase
view release on metacpan or search on metacpan
lib/Authen/Passphrase/MD5Crypt.pm view on Meta::CPAN
sub new {
my $class = shift;
my $self = bless({}, $class);
my $passphrase;
while(@_) {
my $attr = shift;
my $value = shift;
if($attr eq "salt") {
croak "salt specified redundantly"
if exists $self->{salt};
$value =~ m#\A[\x00-\xff]*\z#
or croak "not a valid salt";
$self->{salt} = "$value";
} elsif($attr eq "salt_random") {
croak "salt specified redundantly"
if exists $self->{salt};
$self->{salt} = encode_base64(random_bytes(6), '');
$self->{salt} =~ tr{A-Za-z0-9+/=}{./0-9A-Za-z}d;
} elsif($attr eq "hash_base64") {
croak "hash specified redundantly"
if exists($self->{hash_base64}) ||
defined($passphrase);
$value =~ m#\A[./0-9A-Za-z]{21}[./01]\z#
or croak "\"$value\" is not a valid ".
"MD5-based crypt() hash";
$self->{hash_base64} = "$value";
} elsif($attr eq "passphrase") {
croak "passphrase specified redundantly"
if exists($self->{hash_base64}) ||
defined($passphrase);
$passphrase = $value;
} else {
croak "unrecognised attribute `$attr'";
}
}
croak "salt not specified" unless exists $self->{salt};
$self->{hash_base64} = $self->_hash_base64_of($passphrase)
if defined $passphrase;
croak "hash not specified" unless exists $self->{hash_base64};
return $self;
}
=item Authen::Passphrase::MD5Crypt->from_crypt(PASSWD)
Generates a new passphrase recogniser object using the MD5-based crypt()
algorithm, from a crypt string. The crypt string must consist of
"B<$1$>", the salt, "B<$>", then 22 base 64 digits giving the hash.
The salt may be up to 8 characters long, and cannot contain "B<$>"
or any character that cannot appear in a crypt string.
=cut
sub from_crypt {
my($class, $passwd) = @_;
if($passwd =~ /\A\$1\$/) {
$passwd =~ m:\A\$1\$([!-#%-9;-~]{0,8})\$([./0-9A-Za-z]{22})\z:
or croak "malformed \$1\$ data";
my($salt, $hash) = ($1, $2);
return $class->new(salt => $salt, hash_base64 => $hash);
}
return $class->SUPER::from_crypt($passwd);
}
=item Authen::Passphrase::MD5Crypt->from_rfc2307(USERPASSWORD)
Generates a new passphrase recogniser object using the MD5-based
crypt() algorithm, from an RFC 2307 string. The string must consist of
"B<{CRYPT}>" (case insensitive) followed by an acceptable crypt string.
=back
=head1 METHODS
=over
=item $ppr->salt
Returns the salt, in raw form.
=cut
sub salt {
my($self) = @_;
return $self->{salt};
}
=item $ppr->hash_base64
Returns the hash value, as a string of 22 base 64 digits.
=cut
sub hash_base64 {
my($self) = @_;
return $self->{hash_base64};
}
=item $ppr->match(PASSPHRASE)
=item $ppr->as_crypt
=item $ppr->as_rfc2307
These methods are part of the standard L<Authen::Passphrase> interface.
Not every passphrase recogniser of this type can be represented as a
crypt string: the crypt format only allows the salt to be up to eight
bytes, and it cannot contain any NUL or "B<$>" characters.
=cut
sub _hash_base64_of {
my($self, $passphrase) = @_;
die "can't use a crypt-incompatible salt yet ".
"(need generalised Crypt::MD5Passwd)"
if $self->{salt} =~ /[^\!-\#\%-9\;-\~]/ ||
length($self->{salt}) > 8;
my $hash = unix_md5_crypt($passphrase, $self->{salt});
$hash =~ s/\A.*\$//;
return $hash;
}
( run in 1.478 second using v1.01-cache-2.11-cpan-364913b4093 )