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 )