Authen-Passphrase
view release on metacpan or search on metacpan
lib/Authen/Passphrase/NetscapeMail.pm view on Meta::CPAN
my $attr = shift;
my $value = shift;
if($attr eq "salt") {
croak "salt specified redundantly"
if exists $self->{salt};
$value =~ m#\A[\x00-\xff]{32}\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} = unpack("H*", random_bytes(16));
} elsif($attr eq "hash") {
croak "hash specified redundantly"
if exists($self->{hash}) ||
defined($passphrase);
$value =~ m#\A[\x00-\xff]{16}\z#
or croak "not a valid MD5 hash";
$self->{hash} = "$value";
} elsif($attr eq "hash_hex") {
croak "hash specified redundantly"
if exists($self->{hash}) ||
defined($passphrase);
$value =~ m#\A[0-9A-Fa-f]{32}\z#
or croak "\"$value\" is not a valid ".
"hex MD5 hash";
$self->{hash} = pack("H*", $value);
} elsif($attr eq "passphrase") {
croak "passphrase specified redundantly"
if exists($self->{hash}) ||
defined($passphrase);
$passphrase = $value;
} else {
croak "unrecognised attribute `$attr'";
}
}
croak "salt not specified" unless exists $self->{salt};
$self->{hash} = $self->_hash_of($passphrase) if defined $passphrase;
croak "hash not specified" unless exists $self->{hash};
return $self;
}
=item Authen::Passphrase::NetscapeMail->from_rfc2307(USERPASSWORD)
Generates a new Netscape Mail Server passphrase recogniser object from
an RFC 2307 string. The string must consist of "B<{NS-MTA-MD5}>" (case
insensitive) followed by the hash in case-insensitive hexadecimal and
then the salt. The salt must be exactly 32 characters long, and cannot
contain any character that cannot appear in an RFC 2307 string.
=cut
sub from_rfc2307 {
my($class, $userpassword) = @_;
if($userpassword =~ /\A\{(?i:ns-mta-md5)\}/) {
$userpassword =~ /\A\{.*?\}([0-9a-fA-F]{32})([!-~]{32})\z/
or croak "malformed {NS-MTA-MD5} data";
my($hash, $salt) = ($1, $2);
return $class->new(salt => $salt, hash_hex => $hash);
}
return $class->SUPER::from_rfc2307($userpassword);
}
=back
=head1 METHODS
=over
=item $ppr->salt
Returns the salt value, as a string of 32 bytes.
=cut
sub salt {
my($self) = @_;
return $self->{salt};
}
=item $ppr->hash
Returns the hash value, as a string of 16 bytes.
=cut
sub hash {
my($self) = @_;
return $self->{hash};
}
=item $ppr->hash_hex
Returns the hash value, as a string of 32 hexadecimal digits.
=cut
sub hash_hex {
my($self) = @_;
return unpack("H*", $self->{hash});
}
=item $ppr->match(PASSPHRASE)
=item $ppr->as_rfc2307
These methods are part of the standard L<Authen::Passphrase> interface.
=cut
sub _hash_of {
my($self, $passphrase) = @_;
my $ctx = Digest::MD5->new;
$ctx->add($self->{salt});
$ctx->add("\x59");
$ctx->add($passphrase);
$ctx->add("\xf7");
$ctx->add($self->{salt});
return $ctx->digest;
}
( run in 0.950 second using v1.01-cache-2.11-cpan-364913b4093 )