App-OATH
view release on metacpan or search on metacpan
lib/App/OATH.pm view on Meta::CPAN
$tm >>= 8;
}
my $challenge;
{
no warnings;
$challenge = pack('C*',@chal);
}
my $secret = decode_base32($key);
my $hashtxt = hmac_sha1($challenge,$secret);
my @hash = unpack("C*",$hashtxt);
my $offset = $hash[$#hash]& 0xf ;
my $truncatedHash=0;
for (my $i=0;$i<4;$i++) {
$truncatedHash <<=8;
$truncatedHash |= $hash[$offset+$i];
}
$truncatedHash &=0x7fffffff;
$truncatedHash %= 1000000;
$truncatedHash = substr( '0'x6 . $truncatedHash, -6 );
return $truncatedHash;
}
sub set_filename {
my ( $self, $filename ) = @_;
$self->drop_lock() if $self->{'filename'} ne $filename;
$self->{'filename'} = $filename;
return;
}
sub get_filename {
my ( $self ) = @_;
return $self->{'filename'};
}
sub get_lockfilename {
my ( $self ) = @_;
my $filename = $self->get_filename();
my $lockfilename = $filename . '.lock';
return $lockfilename;
}
sub drop_lock {
my ( $self ) = @_;
delete $self->{'lockhandle'};
return;
}
sub get_lock {
my ( $self ) = @_;
my $lockh;
my $lockfilename = $self->get_lockfilename();
if ( ! -e $lockfilename ) {
open $lockh, '>', $lockfilename;
close $lockh;
chmod( 0600, $lockfilename );
}
open $lockh, '<', $lockfilename;
if ( !flock( $lockh, LOCK_EX | LOCK_NB ) ) {
return 0;
}
$self->{'lockhandle'} = $lockh;
return 1;
}
sub load_data {
my ( $self ) = @_;
my $json = JSON->new();
my $filename = $self->get_filename();
open( my $file, '<', $filename ) || die "cannot open file $!";
my @content = <$file>;
close $file;
my $data = $json->decode( join( "\n", @content ) );
$self->{'data_encrypted'} = $data;
return;
}
sub save_data {
my ( $self ) = @_;
my $data = $self->get_encrypted();
my $json = JSON->new->canonical->pretty;
my $content = $json->encode( $data );
my $filename = $self->get_filename();
open( my $file, '>', $filename ) || die "cannot open file $!";
print $file $content;
close $file;
chmod( 0600, $filename );
return;
}
sub encrypt_data {
my ( $self ) = @_;
my $newpass = $self->{newpass};
my $data = $self->get_plaintext();
$self->drop_password() if $newpass;
my $crypt = App::OATH::Crypt->new( $self->get_password() );
my $edata = {};
foreach my $k ( keys %$data ) {
$edata->{$k} = $crypt->encrypt( $data->{$k} );
}
$self->{'data_encrypted'} = $edata;
return;
}
sub decrypt_data {
my ( $self ) = @_;
my $data = $self->get_encrypted();
my $crypt = App::OATH::Crypt->new( $self->get_password() );
my $ddata = {};
foreach my $k ( keys %$data ) {
my $d = $crypt->decrypt( $data->{$k} );
if ( ! $d ) {
print "Invalid password\n";
exit 1;
}
$ddata->{$k} = $d;
}
$self->{'data_plaintext'} = $ddata;
return;
}
sub get_plaintext {
my ( $self ) = @_;
$self->decrypt_data() if ! exists $self->{'data_plaintext'};
return $self->{'data_plaintext'};
}
sub get_encrypted {
my ( $self ) = @_;
$self->load_data() if ! exists $self->{'data_encrypted'};
return $self->{'data_encrypted'};
}
sub set_newpass {
my ( $self ) = @_;
$self->{'newpass'} = 1;
return;
}
sub drop_password {
my ( $self ) = @_;
delete $self->{'password'};
return;
}
sub _read_password_stdin {
# uncoverable subroutine
( run in 1.426 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )