mirror of
https://codeberg.org/scip/Crypt--PWSafe3.git
synced 2025-12-16 20:21:01 +01:00
enhanced unittests, added pod for addrecord and newrecord, using ->new() everywhere, new parameter "create"
This commit is contained in:
15
CHANGELOG
15
CHANGELOG
@@ -1,6 +1,21 @@
|
||||
NEXT:
|
||||
added license to META
|
||||
|
||||
open tmpfiles with O_EXLOCK disabled (cpantesters)
|
||||
|
||||
added new parameter 'create', enabled by default,
|
||||
which creates a new vault if enabled and dies otherwise.
|
||||
|
||||
enhanced unit tests to report if read/write of files fails.
|
||||
|
||||
added unit test to create a new vault
|
||||
|
||||
added POD for newrecord() and addrecord(), previously
|
||||
missing.
|
||||
|
||||
replaced "new $perl::$object" with $perl::$object->new()
|
||||
everywhere.
|
||||
|
||||
1.16
|
||||
re-licensed from artistic1 to artistic2 in order to be
|
||||
compatible to fedora packaging. no code changes otherwise
|
||||
|
||||
@@ -29,7 +29,7 @@ use Data::Dumper;
|
||||
use Exporter ();
|
||||
use vars qw(@ISA @EXPORT);
|
||||
|
||||
$Crypt::PWSafe3::VERSION = '1.16';
|
||||
$Crypt::PWSafe3::VERSION = '1.17';
|
||||
|
||||
use Crypt::PWSafe3::Field;
|
||||
use Crypt::PWSafe3::HeaderField;
|
||||
@@ -92,7 +92,7 @@ sub new {
|
||||
# new vault object
|
||||
my($this, %param) = @_;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = \%param; # file, password, whoami, program
|
||||
my $self = \%param; # file, password, whoami, program, create
|
||||
bless($self, $class);
|
||||
|
||||
# sanity checks
|
||||
@@ -108,14 +108,23 @@ sub new {
|
||||
croak 'Parameter password is required';
|
||||
}
|
||||
|
||||
if (! exists $self->{create}) {
|
||||
$self->{create} = 1;
|
||||
}
|
||||
|
||||
if (! exists $self->{file}) {
|
||||
$self->{file} = '';
|
||||
$self->create();
|
||||
}
|
||||
else {
|
||||
if (! -s $self->{file}) {
|
||||
if (! -s $self->{file} || ! -r $self->{file}) {
|
||||
if ($self->{create}) {
|
||||
$self->create();
|
||||
}
|
||||
else {
|
||||
croak "PWSafe3 file $self->{file} does not exist or is not readable";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->read();
|
||||
}
|
||||
@@ -133,7 +142,7 @@ sub stretchpw {
|
||||
# algorithm is described here:
|
||||
# [KEYSTRETCH Section 4.1] http://www.schneier.com/paper-low-entropy.pdf
|
||||
my ($this, $passwd) = @_;
|
||||
my $sha = new Digest::SHA('SHA-256');
|
||||
my $sha = Digest::SHA->new('SHA-256');
|
||||
$sha->reset();
|
||||
$sha->add( ( $passwd, $this->salt) );
|
||||
my $stretched = $sha->digest();
|
||||
@@ -160,7 +169,7 @@ sub create {
|
||||
$this->strechedpw($this->stretchpw($this->password()));
|
||||
|
||||
# generate hash of the streched pw
|
||||
my $sha = new Digest::SHA('SHA-256');
|
||||
my $sha = Digest::SHA->new('SHA-256');
|
||||
$sha->reset();
|
||||
$sha->add( ( $this->strechedpw() ) );
|
||||
$this->shaps( $sha->digest() );
|
||||
@@ -183,8 +192,8 @@ sub create {
|
||||
$this->iv( $this->random(16) );
|
||||
|
||||
# create hmac'er and cipher for actual encryption
|
||||
$this->{hmacer} = new Digest::HMAC($this->keyl, "Crypt::PWSafe3::SHA256");
|
||||
$this->{cipher} = new Crypt::CBC(
|
||||
$this->{hmacer} = Digest::HMAC->new($this->keyl, "Crypt::PWSafe3::SHA256");
|
||||
$this->{cipher} = Crypt::CBC->new(
|
||||
-key => $this->keyk,
|
||||
-iv => $this->iv,
|
||||
-cipher => 'Twofish',
|
||||
@@ -204,7 +213,7 @@ sub read {
|
||||
# read and decrypt an existing vault file
|
||||
my($this) = @_;
|
||||
|
||||
my $fd = new FileHandle($this->file, 'r');
|
||||
my $fd = FileHandle->new($this->file, 'r');
|
||||
$fd->binmode();
|
||||
$this->{fd} = $fd;
|
||||
|
||||
@@ -218,13 +227,12 @@ sub read {
|
||||
|
||||
$this->strechedpw($this->stretchpw($this->password()));
|
||||
|
||||
my $sha = new Digest::SHA(256);
|
||||
my $sha = Digest::SHA->new(256);
|
||||
$sha->reset();
|
||||
$sha->add( ( $this->strechedpw() ) );
|
||||
$this->shaps( $sha->digest() );
|
||||
|
||||
my $fileshaps = $this->readbytes(32);
|
||||
#print "sha1: <" . unpack('H*', $fileshaps) . ">\nsha2: <" . unpack('H*', $this->shaps) . ">\n";
|
||||
if ($fileshaps ne $this->shaps) {
|
||||
croak "Wrong password!";
|
||||
}
|
||||
@@ -241,14 +249,11 @@ sub read {
|
||||
$this->keyk($crypt->decrypt($this->b1) . $crypt->decrypt($this->b2));
|
||||
$this->keyl($crypt->decrypt($this->b3) . $crypt->decrypt($this->b4));
|
||||
|
||||
#print "keyk:<" . unpack('H*', $this->keyk) . ">\n";
|
||||
|
||||
$this->iv( $this->readbytes(16) );
|
||||
|
||||
# create hmac'er and cipher for actual encryption
|
||||
$this->{hmacer} = new Digest::HMAC($this->keyl, "Crypt::PWSafe3::SHA256");
|
||||
#print "keyk len: " . length($this->keyk) . "\n";
|
||||
$this->{cipher} = new Crypt::CBC(
|
||||
$this->{hmacer} = Digest::HMAC->new($this->keyl, "Crypt::PWSafe3::SHA256");
|
||||
$this->{cipher} = Crypt::CBC->new(
|
||||
-key => $this->keyk,
|
||||
-iv => $this->iv,
|
||||
-cipher => 'Twofish',
|
||||
@@ -274,7 +279,7 @@ sub read {
|
||||
}
|
||||
|
||||
# read db records
|
||||
my $record = new Crypt::PWSafe3::Record();
|
||||
my $record = Crypt::PWSafe3::Record->new();
|
||||
$this->{record} = {};
|
||||
while (1) {
|
||||
my $field = $this->readfield();
|
||||
@@ -283,8 +288,7 @@ sub read {
|
||||
}
|
||||
if ($field->type == 0xff) {
|
||||
$this->addrecord($record);
|
||||
#print "--- record added (uuid:" . $record->uuid . ")\n";
|
||||
$record = new Crypt::PWSafe3::Record();
|
||||
$record = Crypt::PWSafe3::Record->new();
|
||||
}
|
||||
else {
|
||||
$record->addfield($field);
|
||||
@@ -338,14 +342,14 @@ sub save {
|
||||
return;
|
||||
}
|
||||
|
||||
my $lastsave = new Crypt::PWSafe3::HeaderField(type => 0x04, value => time);
|
||||
my $whatsaved = new Crypt::PWSafe3::HeaderField(type => 0x06, value => $this->{program});
|
||||
my $whosaved = new Crypt::PWSafe3::HeaderField(type => 0x05, value => $this->{whoami});
|
||||
my $lastsave = Crypt::PWSafe3::HeaderField->new(type => 0x04, value => time);
|
||||
my $whatsaved = Crypt::PWSafe3::HeaderField->new(type => 0x06, value => $this->{program});
|
||||
my $whosaved = Crypt::PWSafe3::HeaderField->new(type => 0x05, value => $this->{whoami});
|
||||
$this->addheader($lastsave);
|
||||
$this->addheader($whatsaved);
|
||||
$this->addheader($whosaved);
|
||||
|
||||
my $fd = File::Temp->new(TEMPLATE => '.vaultXXXXXXXX', TMPDIR => 1) or croak "Could not open tmpfile: $!\n";
|
||||
my $fd = File::Temp->new(TEMPLATE => '.vaultXXXXXXXX', TMPDIR => 1, EXLOCK => 0) or croak "Could not open tmpfile: $!\n";
|
||||
my $tmpfile = "$fd";
|
||||
|
||||
$this->{fd} = $fd;
|
||||
@@ -357,7 +361,7 @@ sub save {
|
||||
$this->strechedpw($this->stretchpw($passwd));
|
||||
|
||||
# line 472
|
||||
my $sha = new Digest::SHA(256);
|
||||
my $sha = Digest::SHA->new(256);
|
||||
$sha->reset();
|
||||
$sha->add( ( $this->strechedpw() ) );
|
||||
$this->shaps( $sha->digest() );
|
||||
@@ -377,8 +381,8 @@ sub save {
|
||||
|
||||
$this->writebytes($this->iv);
|
||||
|
||||
$this->{hmacer} = new Digest::HMAC($this->keyl, "Crypt::PWSafe3::SHA256");
|
||||
$this->{cipher} = new Crypt::CBC(
|
||||
$this->{hmacer} = Digest::HMAC->new($this->keyl, "Crypt::PWSafe3::SHA256");
|
||||
$this->{cipher} = Crypt::CBC->new(
|
||||
-key => $this->keyk,
|
||||
-iv => $this->iv,
|
||||
-cipher => 'Twofish',
|
||||
@@ -389,7 +393,7 @@ sub save {
|
||||
-blocksize => 16
|
||||
);
|
||||
|
||||
my $eof = new Crypt::PWSafe3::HeaderField(type => 0xff, value => '');
|
||||
my $eof = Crypt::PWSafe3::HeaderField->new(type => 0xff, value => '');
|
||||
|
||||
foreach my $type (keys %{$this->{header}}) {
|
||||
$this->writefield($this->{header}->{$type});
|
||||
@@ -398,7 +402,7 @@ sub save {
|
||||
$this->writefield($eof);
|
||||
$this->hmacer($eof->{raw});
|
||||
|
||||
$eof = new Crypt::PWSafe3::Field(type => 0xff, value => '');
|
||||
$eof = Crypt::PWSafe3::Field->new(type => 0xff, value => '');
|
||||
|
||||
foreach my $uuid (keys %{$this->{record}}) {
|
||||
my $record = $this->{record}->{$uuid};
|
||||
@@ -410,7 +414,7 @@ sub save {
|
||||
$this->hmacer($eof->{raw});
|
||||
}
|
||||
|
||||
$this->writefield(new Crypt::PWSafe3::Field(type => 'none', raw => 0));
|
||||
$this->writefield(Crypt::PWSafe3::Field->new(type => 'none', raw => 0));
|
||||
|
||||
$this->hmac( $this->{hmacer}->digest() );
|
||||
$this->writebytes($this->hmac);
|
||||
@@ -419,7 +423,7 @@ sub save {
|
||||
# now try to read it in again to check if it
|
||||
# is valid what we created
|
||||
eval {
|
||||
my $vault = new Crypt::PWSafe3(file => $tmpfile, password => $passwd);
|
||||
my $vault = Crypt::PWSafe3->new(file => $tmpfile, create => 0, password => $passwd);
|
||||
};
|
||||
if ($@) {
|
||||
unlink $tmpfile;
|
||||
@@ -436,8 +440,6 @@ sub writefield {
|
||||
# write a field to vault file
|
||||
my($this, $field) = @_;
|
||||
|
||||
#print "write field " . $field->name . "\n";
|
||||
|
||||
if ($field->type eq 'none') {
|
||||
$this->writebytes("PWS3-EOFPWS3-EOF");
|
||||
return;
|
||||
@@ -459,19 +461,15 @@ sub writefield {
|
||||
if (length($data) > 16) {
|
||||
my $crypt;
|
||||
while (1) {
|
||||
#print "processing part\n";
|
||||
my $part = substr($data, 0, 16);
|
||||
$crypt .= $this->encrypt($part);
|
||||
if (length($data) <= 16) {
|
||||
#print " this was the last one\n";
|
||||
last;
|
||||
}
|
||||
else {
|
||||
#print " getting next\n";
|
||||
$data = substr($data, 16);
|
||||
}
|
||||
}
|
||||
#print " len: " . length($crypt) . "\n";
|
||||
$this->writebytes($crypt);
|
||||
}
|
||||
else {
|
||||
@@ -525,7 +523,6 @@ sub modifyrecord {
|
||||
sub deleterecord {
|
||||
#
|
||||
# delete a record identified by the given uuid, if present
|
||||
#
|
||||
# returns 1 if record was actually removed, 0 if it was not present
|
||||
my($this, $uuid) = @_;
|
||||
|
||||
@@ -546,11 +543,11 @@ sub markmodified {
|
||||
#
|
||||
# mark the vault as modified by setting the appropriate header fields
|
||||
my($this) = @_;
|
||||
my $lastmod = new Crypt::PWSafe3::HeaderField(
|
||||
my $lastmod = Crypt::PWSafe3::HeaderField->new(
|
||||
name => "lastsavetime",
|
||||
value => time
|
||||
);
|
||||
my $who = new Crypt::PWSafe3::HeaderField(
|
||||
my $who = Crypt::PWSafe3::HeaderField->new(
|
||||
name => "wholastsaved",
|
||||
value => $this->{whoami}
|
||||
);
|
||||
@@ -563,7 +560,7 @@ sub newrecord {
|
||||
#
|
||||
# add a new record to an existing vault
|
||||
my($this, %fields) = @_;
|
||||
my $record = new Crypt::PWSafe3::Record();
|
||||
my $record = Crypt::PWSafe3::Record->new();
|
||||
foreach my $field (keys %fields) {
|
||||
$record->modifyfield($field, $fields{$field});
|
||||
}
|
||||
@@ -599,18 +596,12 @@ sub readfield {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#print "\n raw: <" . unpack('H*', $data) . ">\n";
|
||||
|
||||
$data = $this->decrypt($data);
|
||||
|
||||
#print "clear: <" . unpack('H*', $data) . ">\n";
|
||||
|
||||
my $len = unpack("L<", substr($data, 0, 4));
|
||||
my $type = unpack("C", substr($data, 4, 1));
|
||||
my $raw = substr($data, 5);
|
||||
|
||||
#print "readfield: len: $len, type: $type\n";
|
||||
|
||||
if ($len > 11) {
|
||||
my $step = int(($len+4) / 16);
|
||||
for (1 .. $step) {
|
||||
@@ -623,10 +614,10 @@ sub readfield {
|
||||
}
|
||||
$raw = substr($raw, 0, $len);
|
||||
if ($header) {
|
||||
return new Crypt::PWSafe3::HeaderField(type => $type, raw => $raw);
|
||||
return Crypt::PWSafe3::HeaderField->new(type => $type, raw => $raw);
|
||||
}
|
||||
else {
|
||||
return new Crypt::PWSafe3::Field(type => $type, raw => $raw);
|
||||
return Crypt::PWSafe3::Field->new(type => $type, raw => $raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,7 +637,7 @@ sub encrypt {
|
||||
my $raw = $this->{cipher}->encrypt($data);
|
||||
if (length($raw) > 16) {
|
||||
# we use only the last 16byte block as next iv
|
||||
# if data is more than 1 blocks than Crypt::CBC
|
||||
# if data is more than 1 blocks then Crypt::CBC
|
||||
# has already updated the iv for the inner blocks
|
||||
$raw = substr($raw, -16, 16);
|
||||
}
|
||||
@@ -672,7 +663,6 @@ sub readbytes {
|
||||
my $got = $this->{fd}->sysread($buffer, $size);
|
||||
if ($got == $size) {
|
||||
$this->{sum} += $got;
|
||||
#print "Got $got bytes (read so far: $this->{sum} bytes) $package line $line\n";
|
||||
return $buffer;
|
||||
}
|
||||
else {
|
||||
@@ -698,7 +688,6 @@ sub getheader {
|
||||
#
|
||||
# return a header object
|
||||
my($this, $name) = @_;
|
||||
# $this->{header}->{ $field->name } = $field;
|
||||
if (exists $this->{header}->{$name}) {
|
||||
return $this->{header}->{$name};
|
||||
}
|
||||
@@ -717,7 +706,7 @@ Crypt::PWSafe3 - Read and write Passwordsafe v3 files
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Crypt::PWSafe3;
|
||||
my $vault = new Crypt::PWSafe3(file => 'filename.psafe3', password => 'somesecret');
|
||||
my $vault = Crypt::PWSafe3->new(file => 'filename.psafe3', password => 'somesecret');
|
||||
|
||||
# fetch all database records
|
||||
my @records = $vault->getrecords();
|
||||
@@ -764,7 +753,7 @@ Crypt::PWSafe3 - Read and write Passwordsafe v3 files
|
||||
print scalar localtime($vault->getheader('lastsavetime')->value());
|
||||
|
||||
# add/replace a database header
|
||||
my $h = new Crypt::PWSafe3::HeaderField(name => 'savedonhost', value => 'localhost');
|
||||
my $h = Crypt::PWSafe3::HeaderField->new(name => 'savedonhost', value => 'localhost');
|
||||
$vault->addheader($h);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@@ -780,11 +769,12 @@ http://passwordsafe.sf.net.
|
||||
The new() method creates a new Crypt::PWSafe3 object. Any parameters
|
||||
must be given as hash parameters.
|
||||
|
||||
my $vault = new Crypt::PWSafe3(
|
||||
my $vault = Crypt::PWSafe3->new(
|
||||
file => 'vault.psafe3',
|
||||
password => 'secret',
|
||||
whoami => 'user1',
|
||||
program => 'mypwtool v1'
|
||||
program => 'mypwtool v1',
|
||||
create => 0, # or 1
|
||||
);
|
||||
|
||||
Mandatory parameters:
|
||||
@@ -820,6 +810,11 @@ If omitted, the content of the perl variable $0 will
|
||||
be used, which contains the name of the current running
|
||||
script.
|
||||
|
||||
=item B<create>
|
||||
|
||||
If set to 0, B<new()> will fail if the file doesn't exist,
|
||||
otherwise it will try to create it. Enabled by default.
|
||||
|
||||
=back
|
||||
|
||||
The optional parameters will become header fields of
|
||||
@@ -882,6 +877,16 @@ The parameter hash may contain any valid record field
|
||||
type with according values. Refer to L<Crypt::PWSafe3::Record>
|
||||
for details about available fields.
|
||||
|
||||
=head2 B<newrecord(parameter-hash)>
|
||||
|
||||
Create a new record. The UUID of the record will be generated
|
||||
automatically. Refer to L<Crypt::PWSafe3::Record>
|
||||
for details about available fields.
|
||||
|
||||
=head2 B<addrecord(Crypt::PWSafe3::Record object)>
|
||||
|
||||
Add a record to the vault. The record must be an
|
||||
L<Crypt::PWSafe3::Record> object.
|
||||
|
||||
=head2 B<deleterecord(uuid)>
|
||||
|
||||
@@ -970,7 +975,7 @@ License 2.0, see: L<http://www.perlfoundation.org/artistic_license_2_0>
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Crypt::PWSafe3 Version 1.16.
|
||||
Crypt::PWSafe3 Version 1.17.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ use Exporter ();
|
||||
use vars qw(@ISA @EXPORT);
|
||||
use utf8;
|
||||
|
||||
$Crypt::PWSafe3::Field::VERSION = '1.05';
|
||||
$Crypt::PWSafe3::Field::VERSION = '1.06';
|
||||
|
||||
%Crypt::PWSafe3::Field::map2type = (
|
||||
uuid => 0x01,
|
||||
@@ -120,9 +120,6 @@ sub new {
|
||||
$self->{name} = $self->{type};
|
||||
}
|
||||
|
||||
#print "New Field of type $self->{name}\n";
|
||||
#print "Field Value: $self->{value}\n";
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
@@ -151,7 +148,7 @@ raw implementation and you normally don't have to cope with it.
|
||||
|
||||
However, if you ever do, you can do it this way:
|
||||
|
||||
my $field = new Crypt::PWSafe3::Field(
|
||||
my $field = Crypt::PWSafe3::Field->new(
|
||||
value => 'testing',
|
||||
name => 'title
|
||||
);
|
||||
|
||||
@@ -13,7 +13,7 @@ use Exporter ();
|
||||
use vars qw(@ISA @EXPORT);
|
||||
use utf8;
|
||||
|
||||
$Crypt::PWSafe3::HeaderField::VERSION = '1.04';
|
||||
$Crypt::PWSafe3::HeaderField::VERSION = '1.05';
|
||||
|
||||
%Crypt::PWSafe3::HeaderField::map2name = (
|
||||
0x00 => "version",
|
||||
@@ -135,7 +135,7 @@ Crypt::PWSafe3::HeaderField - represent a passwordsafe v3 header field.
|
||||
my $who = $vault->getheader('wholastsaved');
|
||||
print $who->value;
|
||||
|
||||
my $h = new Crypt::PWSafe3::HeaderField(name => 'savedonhost',
|
||||
my $h = Crypt::PWSafe3::HeaderField->new(name => 'savedonhost',
|
||||
value => 'localhost');
|
||||
$vault->addheader($h);
|
||||
|
||||
@@ -147,7 +147,7 @@ raw implementation and you normally don't have to cope with it.
|
||||
However, if you ever do, you can add/replace any field type
|
||||
this way:
|
||||
|
||||
my $field = new Crypt::PWSafe3::HeaderField(
|
||||
my $field = Crypt::PWSafe3::HeaderField->new(
|
||||
value => 'localhost',
|
||||
name => 'savedonhost'
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ my %map2type = %Crypt::PWSafe3::Field::map2type;
|
||||
|
||||
my %map2name = %Crypt::PWSafe3::Field::map2name;
|
||||
|
||||
$Crypt::PWSafe3::Record::VERSION = '1.08';
|
||||
$Crypt::PWSafe3::Record::VERSION = '1.09';
|
||||
|
||||
foreach my $field (keys %map2type ) {
|
||||
eval qq(
|
||||
@@ -46,47 +46,47 @@ sub new {
|
||||
|
||||
my $time = time;
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'uuid',
|
||||
raw => $newuuid,
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'ctime',
|
||||
value => $time,
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'mtime',
|
||||
value => $time
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'lastmod',
|
||||
value => $time
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'passwd',
|
||||
value => ''
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'user',
|
||||
value => ''
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'title',
|
||||
value => ''
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'notes',
|
||||
value => ''
|
||||
));
|
||||
|
||||
$self->addfield(new Crypt::PWSafe3::Field(
|
||||
$self->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'group',
|
||||
value => ''
|
||||
));
|
||||
@@ -100,7 +100,7 @@ sub modifyfield {
|
||||
my($this, $name, $value) = @_;
|
||||
if (exists $map2type{$name}) {
|
||||
my $type = $map2type{$name};
|
||||
my $field = new Crypt::PWSafe3::Field(
|
||||
my $field = Crypt::PWSafe3::Field->new(
|
||||
type => $type,
|
||||
value => $value
|
||||
);
|
||||
@@ -114,12 +114,12 @@ sub modifyfield {
|
||||
$this->addfield($field);
|
||||
|
||||
# mark the field as modified if it's passwd field
|
||||
$this->addfield(new Crypt::PWSafe3::Field(
|
||||
$this->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => 'mtime',
|
||||
value => $time
|
||||
)) if $name eq 'passwd';
|
||||
|
||||
$this->addfield(new Crypt::PWSafe3::Field(
|
||||
$this->addfield(Crypt::PWSafe3::Field->new(
|
||||
name => "lastmod",
|
||||
value => $time
|
||||
));
|
||||
@@ -134,7 +134,7 @@ sub genuuid {
|
||||
#
|
||||
# generate a v4 uuid string
|
||||
my($this) = @_;
|
||||
my $ug = new Data::UUID;
|
||||
my $ug = Data::UUID->new();
|
||||
my $uuid = $ug->create();
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
package Crypt::PWSafe3::SHA256;
|
||||
|
||||
$Crypt::PWSafe3::SHA256::VERSION = '1.02';
|
||||
$Crypt::PWSafe3::SHA256::VERSION = '1.03';
|
||||
|
||||
use Digest::SHA;
|
||||
|
||||
@@ -17,7 +17,7 @@ sub new {
|
||||
my $class = ref($this) || $this;
|
||||
my $self = { };
|
||||
bless($self, $class);
|
||||
my $sha = new Digest::SHA('SHA-256');
|
||||
my $sha = Digest::SHA->new('SHA-256');
|
||||
return $sha;
|
||||
}
|
||||
|
||||
|
||||
81
t/run.t
81
t/run.t
@@ -12,9 +12,24 @@
|
||||
#
|
||||
|
||||
use Data::Dumper;
|
||||
#use Test::More tests => 57;
|
||||
use Test::More qw(no_plan);
|
||||
use Test::More tests => 11;
|
||||
#use Test::More qw(no_plan);
|
||||
|
||||
my %params = (create => 0, password => 'tom');
|
||||
|
||||
my %record = (
|
||||
user => 'u3',
|
||||
passwd => 'p3',
|
||||
group => 'g3',
|
||||
title => 't3',
|
||||
notes => 'n3'
|
||||
);
|
||||
|
||||
sub rdpw {
|
||||
my $file = shift;
|
||||
my $vault = Crypt::PWSafe3->new(file => $file, %params) or die "$!";
|
||||
return $vault;
|
||||
}
|
||||
|
||||
### 1
|
||||
# load module
|
||||
@@ -24,7 +39,7 @@ require_ok( 'Crypt::PWSafe3' );
|
||||
### 2
|
||||
# open vault and read in all records
|
||||
eval {
|
||||
my $vault = new Crypt::PWSafe3(file => 't/tom.psafe3', password => 'tom');
|
||||
my $vault = &rdpw('t/tom.psafe3');
|
||||
my @r = $vault->getrecords;
|
||||
my $got = 0;
|
||||
foreach my $rec (@r) {
|
||||
@@ -36,45 +51,65 @@ eval {
|
||||
die "No records found in test database";
|
||||
}
|
||||
};
|
||||
ok(!$@, "open a pwsafe3 database");
|
||||
ok(!$@, "open a pwsafe3 database ($@)");
|
||||
|
||||
|
||||
### 1a
|
||||
# create a new vault
|
||||
my %rdata1a;
|
||||
my $fd = File::Temp->new(TEMPLATE => '.myvaultXXXXXXXX', TMPDIR => 1, EXLOCK => 0) or die "Could not open tmpfile: $!\n";
|
||||
my $tmpfile = "$fd";
|
||||
close($fd);
|
||||
|
||||
eval {
|
||||
my $vault = Crypt::PWSafe3->new(file => $tmpfile, password => 'tom') or die "$!";
|
||||
$vault->newrecord(%record);
|
||||
$vault->save();
|
||||
};
|
||||
ok(!$@, "create a new pwsafe3 database ($@)");
|
||||
|
||||
eval {
|
||||
my $rvault1a = &rdpw($tmpfile);
|
||||
my $rec1a = ($rvault1a->getrecords())[0];
|
||||
foreach my $name (keys %record) {
|
||||
$rdata1a{$name} = $rec1a->$name();
|
||||
}
|
||||
};
|
||||
ok(!$@, "read created new pwsafe3 database ($@)");
|
||||
is_deeply(\%record, \%rdata1a, "Write record to a new pwsafe3 database");
|
||||
unlink($tmpfile);
|
||||
|
||||
### 3
|
||||
# modify an existing record
|
||||
my $uuid3;
|
||||
my %rdata3;
|
||||
my $rec3;
|
||||
my %data3 = (
|
||||
user => 'u3',
|
||||
passwd => 'p3',
|
||||
group => 'g3',
|
||||
title => 't3',
|
||||
notes => 'n3'
|
||||
);
|
||||
|
||||
eval {
|
||||
my $vault3 = new Crypt::PWSafe3(file => 't/tom.psafe3', password => 'tom');
|
||||
my $vault3 = &rdpw('t/tom.psafe3');
|
||||
foreach my $uuid ($vault3->looprecord) {
|
||||
$uuid3 = $uuid;
|
||||
$vault3->modifyrecord($uuid3, %data3);
|
||||
$vault3->modifyrecord($uuid3, %record);
|
||||
last;
|
||||
}
|
||||
$vault3->save(file=>'t/3.out');
|
||||
|
||||
my $rvault3 = new Crypt::PWSafe3(file => 't/3.out', password => 'tom');
|
||||
my $rvault3 = &rdpw('t/3.out');
|
||||
$rec3 = $rvault3->getrecord($uuid3);
|
||||
|
||||
foreach my $name (keys %data3) {
|
||||
foreach my $name (keys %record) {
|
||||
$rdata3{$name} = $rec3->$name();
|
||||
}
|
||||
};
|
||||
ok(!$@, "read a pwsafe3 database and change a record ($@)");
|
||||
is_deeply(\%data3, \%rdata3, "Change a record an check if changes persist after saving");
|
||||
is_deeply(\%record, \%rdata3, "Change a record an check if changes persist after saving");
|
||||
|
||||
|
||||
### 4
|
||||
# re-use $rec3 and change it the oop way
|
||||
my $rec4;
|
||||
eval {
|
||||
my $vault4 = new Crypt::PWSafe3(file => 't/3.out', password => 'tom');
|
||||
my $vault4 = &rdpw('t/tom.psafe3');
|
||||
$rec4 = $vault4->getrecord($uuid3);
|
||||
|
||||
$rec4->user("u4");
|
||||
@@ -84,7 +119,7 @@ eval {
|
||||
$vault4->markmodified();
|
||||
$vault4->save(file=>'t/4.out');
|
||||
|
||||
my $rvault4 = new Crypt::PWSafe3(file => 't/4.out', password => 'tom');
|
||||
my $rvault4 = &rdpw('t/4.out');
|
||||
$rec4 = $rvault4->getrecord($uuid3);
|
||||
if ($rec4->user ne 'u4') {
|
||||
die "oop way record change failed";
|
||||
@@ -95,7 +130,7 @@ ok(!$@, "re-use record and change it the oop way\n" . $@ . "\n");
|
||||
|
||||
### 5 modify some header fields
|
||||
eval {
|
||||
my $vault5 = new Crypt::PWSafe3(file => 't/tom.psafe3', password => 'tom');
|
||||
my $vault5 = &rdpw('t/tom.psafe3');
|
||||
|
||||
my $h3 = new Crypt::PWSafe3::HeaderField(name => 'savedonhost', value => 'localhost');
|
||||
|
||||
@@ -103,7 +138,7 @@ eval {
|
||||
$vault5->markmodified();
|
||||
$vault5->save(file=>'t/5.out');
|
||||
|
||||
my $rvault5 = new Crypt::PWSafe3(file => 't/5.out', password => 'tom');
|
||||
my $rvault5 = &rdpw('t/5.out');
|
||||
|
||||
if ($rvault5->getheader('savedonhost')->value() ne 'localhost') {
|
||||
die "header savedonhost not correct";
|
||||
@@ -113,11 +148,11 @@ ok(!$@, "modify some header fields ($@)");
|
||||
|
||||
### 6 delete
|
||||
eval {
|
||||
my $vault6 = new Crypt::PWSafe3(file => 't/3.out', password => 'tom');
|
||||
my $vault6 = &rdpw('t/3.out');
|
||||
my $uuid = $vault6->newrecord(user => 'xxx', passwd => 'y');
|
||||
$vault6->save(file=>'t/6.out');
|
||||
|
||||
my $rvault6 = new Crypt::PWSafe3(file => 't/6.out', password => 'tom');
|
||||
my $rvault6 = &rdpw('t/6.out');
|
||||
my $rec = $rvault6->getrecord($uuid);
|
||||
if ($rec->user ne 'xxx') {
|
||||
die "oop way record change failed";
|
||||
@@ -128,7 +163,7 @@ eval {
|
||||
}
|
||||
$vault6->save(file=>'t/6a.out');
|
||||
|
||||
my $rvault6a = new Crypt::PWSafe3(file => 't/6a.out', password => 'tom');
|
||||
my $rvault6a = &rdpw('t/6a.out');
|
||||
if ($rvault6->getrecord($uuid)) {
|
||||
die "deleted record reappears after save and reload";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user