File Coverage

blib/lib/Crypt/PWSafe3.pm
Criterion Covered Total %
statement 28 30 93.3
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 38 40 95.0


line stmt bran cond sub pod time code
1             #
2             # Copyright (c) 2011-2015 T.v.Dein .
3             #
4             # Licensed under the terms of the Artistic License 2.0
5             # see: http://www.perlfoundation.org/artistic_license_2_0
6             #
7             # Implements:
8             # http://passwordsafe.svn.sourceforge.net/viewvc/passwordsafe/trunk/pwsafe/pwsafe/docs/formatV3.txt?revision=2139
9              
10             package Crypt::PWSafe3;
11              
12 1     1   35876 use strict;
  1         1  
  1         38  
13              
14 1     1   3 use Config;
  1         2  
  1         35  
15              
16 1     1   460 use Carp::Heavy;
  1         99  
  1         23  
17 1     1   4 use Carp;
  1         1  
  1         67  
18              
19 1     1   562 use Crypt::CBC;
  1         3456  
  1         26  
20 1     1   518 use Crypt::ECB;
  1         2293  
  1         61  
21 1     1   474 use Crypt::Twofish;
  1         839  
  1         27  
22 1     1   448 use Digest::HMAC;
  1         437  
  1         38  
23 1     1   563 use Digest::SHA;
  1         2791  
  1         49  
24 1     1   211 use Crypt::Random qw( makerandom );
  0            
  0            
25             use Data::UUID;
26             use File::Copy qw(copy move);
27             use File::Temp;
28             use File::Spec;
29             use FileHandle;
30             use Data::Dumper;
31             use Exporter ();
32             use vars qw(@ISA @EXPORT);
33              
34             $Crypt::PWSafe3::VERSION = '1.21';
35              
36             use Crypt::PWSafe3::Field;
37             use Crypt::PWSafe3::HeaderField;
38             use Crypt::PWSafe3::Record;
39             use Crypt::PWSafe3::SHA256;
40             use Crypt::PWSafe3::PasswordPolicy;
41              
42             require 5.10.0;
43              
44             #
45             # check which random source to use.
46             # install a wrapper closure around the
47             # one we found.
48             BEGIN {
49             eval {
50             require Bytes::Random::Secure;
51             Bytes::Random::Secure->import("random_bytes");
52             };
53             if ($@) {
54             # well, didn' work, use slow function
55             eval { require Crypt::Random; };# qw( makerandom ); };
56             if ($@) {
57             croak "Could not find either Crypt::Random or Bytes::Random::Secure. Install one of them and retry!";
58             }
59             else {
60             *Crypt::PWSafe3::random = sub {
61             my($this, $len) = @_;
62             my $bits = makerandom(Size => 256, Strength => 1);
63             return substr($bits, 0, $len);
64             };
65             }
66             }
67             else {
68             # good. use the faster one
69             *Crypt::PWSafe3::random = sub {
70             my($this, $len) = @_;
71             return random_bytes($len);
72             };
73             }
74             }
75              
76             my @fields = qw(tag salt iter shaps b1 b2 b3 b4 keyk file program
77             keyl iv hmac header strechedpw password whoami);
78             foreach my $field (@fields) {
79             eval qq(
80             *Crypt::PWSafe3::$field = sub {
81             my(\$this, \$arg) = \@_;
82             if (\$arg) {
83             return \$this->{$field} = \$arg;
84             }
85             else {
86             return \$this->{$field};
87             }
88             }
89             );
90             }
91              
92             sub new {
93             #
94             # new vault object
95             my($this, %param) = @_;
96             my $class = ref($this) || $this;
97             my $self = \%param; # file, password, whoami, program, create
98             bless($self, $class);
99              
100             # sanity checks
101             if (! exists $self->{whoami}) {
102             $self->{whoami} = $ENV{USER};
103             }
104              
105             if (! exists $self->{program}) {
106             $self->{program} = $0;
107             }
108              
109             if (! exists $self->{password}) {
110             croak 'Parameter password is required';
111             }
112              
113             if (! exists $self->{create}) {
114             $self->{create} = 1;
115             }
116              
117             if (! exists $self->{file}) {
118             $self->{file} = '';
119             $self->create();
120             }
121             else {
122             if (! -s $self->{file} || ! -r $self->{file}) {
123             if ($self->{create}) {
124             $self->create();
125             }
126             else {
127             croak "PWSafe3 file $self->{file} does not exist or is not readable";
128             }
129             }
130             else {
131             $self->read();
132             }
133             }
134              
135             $self->{modified} = 0;
136              
137             return $self;
138             }
139              
140             sub stretchpw {
141             #
142             # generate the streched password hash
143             #
144             # algorithm is described here:
145             # [KEYSTRETCH Section 4.1] http://www.schneier.com/paper-low-entropy.pdf
146             my ($this, $passwd) = @_;
147             my $sha = Digest::SHA->new('SHA-256');
148             $sha->reset();
149             $sha->add( ( $passwd, $this->salt) );
150             my $stretched = $sha->digest();
151             foreach (1 .. $this->iter) {
152             $sha->reset();
153             $sha->add( ( $stretched) );
154             $stretched = $sha->digest();
155             }
156             $passwd = $this->random(64);
157             return $stretched;
158             }
159              
160             sub create {
161             #
162             # create an empty vault without writing to disk
163             my($this) = @_;
164              
165             # default header fields
166             $this->tag('PWS3');
167             $this->salt($this->random(32));
168             $this->iter(2048);
169              
170             # the streched pw
171             $this->strechedpw($this->stretchpw($this->password()));
172              
173             # generate hash of the streched pw
174             my $sha = Digest::SHA->new('SHA-256');
175             $sha->reset();
176             $sha->add( ( $this->strechedpw() ) );
177             $this->shaps( $sha->digest() );
178              
179             # encrypt b1 .. b4
180             my $crypt = Crypt::ECB->new;
181             $crypt->cipher('Twofish');
182             $crypt->key( $this->strechedpw() );
183             $this->b1( $crypt->encrypt( $this->random(16) ) );
184             $this->b2( $crypt->encrypt( $this->random(16) ) );
185             $this->b3( $crypt->encrypt( $this->random(16) ) );
186             $this->b4( $crypt->encrypt( $this->random(16) ) );
187              
188             # create key k + l
189             $this->keyk( $crypt->decrypt( $this->b1() ) . $crypt->decrypt( $this->b2() ));
190             $this->keyl( $crypt->decrypt( $this->b3() ) . $crypt->decrypt( $this->b4() ));
191              
192             # create IV
193             $this->iv( $this->random(16) );
194              
195             # create hmac'er and cipher for actual encryption
196             $this->{hmacer} = Digest::HMAC->new($this->keyl, "Crypt::PWSafe3::SHA256");
197             $this->{cipher} = Crypt::CBC->new(
198             -key => $this->keyk,
199             -iv => $this->iv,
200             -cipher => 'Twofish',
201             -header => 'none',
202             -padding => 'null',
203             -literal_key => 1,
204             -keysize => 32,
205             -blocksize => 16
206             );
207              
208             # empty for now
209             $this->hmac( $this->{hmacer}->digest() );
210             }
211              
212             sub read {
213             #
214             # read and decrypt an existing vault file
215             my($this) = @_;
216              
217             my $file = $this->file();
218             my $fd = FileHandle->new($file, 'r') or croak "Could not open $file for reading: $!";
219             $fd->binmode();
220             $this->{fd} = $fd;
221              
222             $this->tag( $this->readbytes(4) );
223             if ($this->tag ne 'PWS3') {
224             croak "Not a PasswordSave V3 file!";
225             }
226              
227             $this->salt( $this->readbytes(32) );
228             $this->iter( unpack("L<", $this->readbytes(4) ) );
229              
230             $this->strechedpw($this->stretchpw($this->password()));
231              
232             my $sha = Digest::SHA->new(256);
233             $sha->reset();
234             $sha->add( ( $this->strechedpw() ) );
235             $this->shaps( $sha->digest() );
236              
237             my $fileshaps = $this->readbytes(32);
238             if ($fileshaps ne $this->shaps) {
239             croak "Wrong password!";
240             }
241              
242             $this->b1( $this->readbytes(16) );
243             $this->b2( $this->readbytes(16) );
244             $this->b3( $this->readbytes(16) );
245             $this->b4( $this->readbytes(16) );
246              
247             my $crypt = Crypt::ECB->new;
248             $crypt->cipher('Twofish') || die $crypt->errstring;
249             $crypt->key( $this->strechedpw() );
250              
251             $this->keyk($crypt->decrypt($this->b1) . $crypt->decrypt($this->b2));
252             $this->keyl($crypt->decrypt($this->b3) . $crypt->decrypt($this->b4));
253              
254             $this->iv( $this->readbytes(16) );
255              
256             # create hmac'er and cipher for actual encryption
257             $this->{hmacer} = Digest::HMAC->new($this->keyl, "Crypt::PWSafe3::SHA256");
258             $this->{cipher} = Crypt::CBC->new(
259             -key => $this->keyk,
260             -iv => $this->iv,
261             -cipher => 'Twofish',
262             -header => 'none',
263             -padding => 'null',
264             -literal_key => 1,
265             -keysize => 32,
266             -blocksize => 16
267             );
268              
269             # read db header fields
270             $this->{header} = {};
271             while (1) {
272             my $field = $this->readfield('header');
273             if (! $field) {
274             last;
275             }
276             if ($field->type == 0xff) {
277             last;
278             }
279             $this->addheader($field);
280             $this->hmacer($field->raw);
281             }
282              
283             # read db records
284             my $record = Crypt::PWSafe3::Record->new();
285             $this->{record} = {};
286             while (1) {
287             my $field = $this->readfield();
288             if (! $field) {
289             last;
290             }
291             if ($field->type == 0xff) {
292             $this->addrecord($record);
293             $record = Crypt::PWSafe3::Record->new();
294             }
295             else {
296             $record->addfield($field);
297             $this->hmacer($field->raw);
298             }
299             }
300              
301             # read and check file hmac
302             $this->hmac( $this->readbytes(32) );
303             my $calcmac = $this->{hmacer}->digest();
304             if ($calcmac ne $this->hmac) {
305             croak "File integrity check failed, invalid HMAC";
306             }
307              
308             $this->{fd}->close() or croak "Could not close $file: $!";
309             }
310              
311             sub untaint {
312             #
313             # untaint path's
314             my ($this, $path) = @_;
315             if($path =~ /([\w\-\/\\\.:]+\z)/) {
316             return $1;
317             }
318             else {
319             # fail, return unchanged
320             return $path;
321             }
322             }
323              
324             sub save {
325             #
326             # write data to the vault file
327             my($this, %param) = @_;
328             my($file, $passwd);
329              
330             if (! exists $param{file}) {
331             $file = $this->file;
332             }
333             else {
334             $file = $param{file}
335             }
336             if (! exists $param{passwd}) {
337             $passwd = $this->password;
338             }
339             else {
340             $passwd = $param{passwd}
341             }
342              
343             if (! $this->{modified}) {
344             return;
345             }
346              
347             my $lastsave = Crypt::PWSafe3::HeaderField->new(type => 0x04, value => time);
348             my $whatsaved = Crypt::PWSafe3::HeaderField->new(type => 0x06, value => $this->{program});
349             my $whosaved = Crypt::PWSafe3::HeaderField->new(type => 0x05, value => $this->{whoami});
350             $this->addheader($lastsave);
351             $this->addheader($whatsaved);
352             $this->addheader($whosaved);
353              
354             # open a temp vault file, first we try it in the same directory as the target vault file
355             my $tmpdir;
356             if (File::Spec->file_name_is_absolute($file)) {
357             my ($volume, $directories, undef) = File::Spec->splitpath($file);
358             $tmpdir = File::Spec->catdir($volume, $directories);
359             }
360             else {
361             my ($volume, $directories, undef) = File::Spec->splitpath(File::Spec->rel2abs($file));
362             $tmpdir = File::Spec->abs2rel(File::Spec->catdir($volume, $directories));
363             }
364              
365             my $fd;
366             if (-w $tmpdir) {
367             $fd = File::Temp->new(TEMPLATE => '.vaultXXXXXXXX', DIR => $tmpdir, EXLOCK => 0) or croak "Could not open tmpfile: $!\n";
368             }
369             else {
370             # well, then we'll use one in the tmp dir of the system
371             $fd = File::Temp->new(TEMPLATE => '.vaultXXXXXXXX', TMPDIR => 1, EXLOCK => 0) or croak "Could not open tmpfile: $!\n";
372             }
373             my $tmpfile = "$fd";
374              
375             $this->{fd} = $fd;
376              
377             $this->writebytes($this->tag);
378             $this->writebytes($this->salt);
379             $this->writebytes(pack("L<", $this->iter));
380              
381             $this->strechedpw($this->stretchpw($passwd));
382              
383             # line 472
384             my $sha = Digest::SHA->new(256);
385             $sha->reset();
386             $sha->add( ( $this->strechedpw() ) );
387             $this->shaps( $sha->digest() );
388              
389             $this->writebytes($this->shaps);
390             $this->writebytes($this->b1);
391             $this->writebytes($this->b2);
392             $this->writebytes($this->b3);
393             $this->writebytes($this->b4);
394              
395             my $crypt = Crypt::ECB->new;
396             $crypt->cipher('Twofish');
397             $crypt->key( $this->strechedpw() );
398              
399             $this->keyk($crypt->decrypt($this->b1) . $crypt->decrypt($this->b2));
400             $this->keyl($crypt->decrypt($this->b3) . $crypt->decrypt($this->b4));
401              
402             $this->writebytes($this->iv);
403              
404             $this->{hmacer} = Digest::HMAC->new($this->keyl, "Crypt::PWSafe3::SHA256");
405             $this->{cipher} = Crypt::CBC->new(
406             -key => $this->keyk,
407             -iv => $this->iv,
408             -cipher => 'Twofish',
409             -header => 'none',
410             -padding => 'null',
411             -literal_key => 1,
412             -keysize => 32,
413             -blocksize => 16
414             );
415              
416             my $eof = Crypt::PWSafe3::HeaderField->new(type => 0xff, value => '');
417              
418             foreach my $type (keys %{$this->{header}}) {
419             $this->writefield($this->{header}->{$type});
420             $this->hmacer($this->{header}->{$type}->{raw});
421             }
422             $this->writefield($eof);
423             $this->hmacer($eof->{raw});
424              
425             $eof = Crypt::PWSafe3::Field->new(type => 0xff, value => '');
426              
427             foreach my $uuid (keys %{$this->{record}}) {
428             my $record = $this->{record}->{$uuid};
429             foreach my $type (keys %{$record->{field}}) {
430             $this->writefield($record->{field}->{$type});
431             $this->hmacer($record->{field}->{$type}->{raw});
432             }
433             $this->writefield($eof);
434             $this->hmacer($eof->{raw});
435             }
436              
437             $this->writefield(Crypt::PWSafe3::Field->new(type => 'none', raw => 0));
438              
439             $this->hmac( $this->{hmacer}->digest() );
440             $this->writebytes($this->hmac);
441             if ($Config{d_fsync}) {
442             $this->{fd}->sync() or croak "Could not fsync: $!";
443             }
444             $this->{fd}->close() or croak "Could not close tmpfile: $!";
445              
446             # now try to read it in again to check if it
447             # is valid what we created
448             eval {
449             my $vault = Crypt::PWSafe3->new(file => $tmpfile, create => 0, password => $passwd);
450             };
451             if ($@) {
452             unlink $tmpfile;
453             croak "File integrity check failed ($@)";
454             }
455             else {
456             # well, seems to be ok :)
457             move($tmpfile, $file) or croak "Could not move $tmpfile to $file: $!";
458             }
459             }
460              
461             sub writefield {
462             #
463             # write a field to vault file
464             my($this, $field) = @_;
465              
466             if ($field->type eq 'none') {
467             $this->writebytes("PWS3-EOFPWS3-EOF");
468             return;
469             }
470              
471             my $len = pack("L<", $field->len);
472             my $type = pack("C", $field->type);
473             my $raw = $field->raw;
474              
475             # Assemble TLV block and pad to 16-byte boundary
476             my $data = $len . $type . $raw;
477              
478             if (length($data) % 16 != 0) {
479             # too small or too large, padding required
480             my $padcount = 16 - (length($data) % 16);
481             $data .= $this->random($padcount);
482             }
483              
484             if (length($data) > 16) {
485             my $crypt;
486             while (1) {
487             my $part = substr($data, 0, 16);
488             $crypt .= $this->encrypt($part);
489             if (length($data) <= 16) {
490             last;
491             }
492             else {
493             $data = substr($data, 16);
494             }
495             }
496             $this->writebytes($crypt);
497             }
498             else {
499             $this->writebytes($this->encrypt($data));
500             }
501             }
502              
503             sub getrecord {
504             #
505             # return the given record
506             my($this, $uuid) = @_;
507             if (exists $this->{record}->{$uuid}) {
508             return $this->{record}->{$uuid};
509             }
510             else {
511             return 0;
512             }
513             }
514              
515             sub getrecords {
516             #
517             # return all records we've got as a copy
518             my ($this) = @_;
519             return map { $this->{record}->{$_} } keys %{$this->{record}};
520             }
521              
522             sub looprecord {
523             #
524             # return a list of uuid's of all records
525             my ($this) = @_;
526             return keys %{$this->{record}};
527             }
528              
529             sub modifyrecord {
530             #
531             # modify a record identified by the given uuid
532             my($this, $uuid, %fields) = @_;
533              
534             if (! exists $this->{record}->{$uuid}) {
535             croak "No record with uuid $uuid found!";
536             }
537              
538             foreach my $field (keys %fields) {
539             $this->{record}->{$uuid}->modifyfield($field, $fields{$field});
540             }
541              
542             # mark vault as modified
543             $this->markmodified();
544             }
545              
546             sub deleterecord {
547             #
548             # delete a record identified by the given uuid, if present
549             # returns 1 if record was actually removed, 0 if it was not present
550             my($this, $uuid) = @_;
551              
552             if (! exists $this->{record}->{$uuid}) {
553             return 0;
554             }
555              
556             delete $this->{record}->{$uuid};
557              
558             # mark vault as modified
559             $this->markmodified();
560              
561             return 1;
562             }
563              
564              
565             sub markmodified {
566             #
567             # mark the vault as modified by setting the appropriate header fields
568             my($this) = @_;
569             my $lastmod = Crypt::PWSafe3::HeaderField->new(
570             name => "lastsavetime",
571             value => time
572             );
573             my $who = Crypt::PWSafe3::HeaderField->new(
574             name => "wholastsaved",
575             value => $this->{whoami}
576             );
577             $this->addheader($lastmod);
578             $this->addheader($who);
579             $this->{modified} = 1;
580             }
581              
582             sub newrecord {
583             #
584             # add a new record to an existing vault
585             my($this, %fields) = @_;
586             my $record = Crypt::PWSafe3::Record->new();
587             foreach my $field (keys %fields) {
588             $record->modifyfield($field, $fields{$field});
589             }
590             $this->markmodified();
591             $this->addrecord($record);
592             return $record->uuid;
593             }
594              
595             sub addrecord {
596             #
597             # add a record object to record hash
598             my($this, $record) = @_;
599             $this->{record}->{ $record->uuid } = $record;
600             }
601              
602             sub addheader {
603             #
604             # add a header field to header hash
605             my($this, $field) = @_;
606             $this->{header}->{ $field->name } = $field;
607             }
608              
609              
610             sub readfield {
611             #
612             # read and return a field object of the vault
613             my($this, $header) = @_;
614             my $data = $this->readbytes(16);
615             if (! $data or length($data) < 16) {
616             croak "EOF encountered when parsing record field";
617             }
618             if ($data eq "PWS3-EOFPWS3-EOF") {
619             return 0;
620             }
621              
622             $data = $this->decrypt($data);
623              
624             my $len = unpack("L<", substr($data, 0, 4));
625             my $type = unpack("C", substr($data, 4, 1));
626             my $raw = substr($data, 5);
627              
628             if ($len > 11) {
629             my $step = int(($len+4) / 16);
630             for (1 .. $step) {
631             my $data = $this->readbytes(16);
632             if (! $data or length($data) < 16) {
633             croak "EOF encountered when parsing record field";
634             }
635             $raw .= $this->decrypt($data);
636             }
637             }
638             $raw = substr($raw, 0, $len);
639             if ($header) {
640             return Crypt::PWSafe3::HeaderField->new(type => $type, raw => $raw);
641             }
642             else {
643             return Crypt::PWSafe3::Field->new(type => $type, raw => $raw);
644             }
645             }
646              
647             sub decrypt {
648             #
649             # helper, decrypt a string
650             my ($this, $data) = @_;
651             my $clear = $this->{cipher}->decrypt($data);
652             $this->{cipher}->iv($data);
653             return $clear;
654             }
655              
656             sub encrypt {
657             #
658             # helper, encrypt a string
659             my ($this, $data) = @_;
660             my $raw = $this->{cipher}->encrypt($data);
661             if (length($raw) > 16) {
662             # we use only the last 16byte block as next iv
663             # if data is more than 1 blocks then Crypt::CBC
664             # has already updated the iv for the inner blocks
665             $raw = substr($raw, -16, 16);
666             }
667             $this->{cipher}->iv($raw);
668             return $raw;
669             }
670              
671             sub hmacer {
672             #
673             # helper, hmac generator
674             my($this, $data) = @_;
675              
676             $this->{hmacer}->add($data);
677             }
678              
679             sub readbytes {
680             #
681             # helper, reads number of bytes
682             my ($this, $size) = @_;
683             my $buffer;
684             my ($package, $filename, $line) = caller;
685              
686             my $got = $this->{fd}->sysread($buffer, $size);
687             if ($got == $size) {
688             $this->{sum} += $got;
689             return $buffer;
690             }
691             else {
692             return 0;
693             }
694             }
695              
696             sub writebytes {
697             #
698             # helper, reads number of bytes
699             my ($this, $bytes) = @_;
700             my $got = $this->{fd}->syswrite($bytes);
701             if ($got) {
702             return $got;
703             }
704             else {
705             croak "Could not write to $this->{file}: $!";
706             }
707             }
708              
709              
710             sub getheader {
711             #
712             # return a header object
713             my($this, $name) = @_;
714             if (exists $this->{header}->{$name}) {
715             return $this->{header}->{$name};
716             }
717             else {
718             croak "Unknown header $name";
719             }
720             }
721              
722              
723              
724              
725             =head1 NAME
726              
727             Crypt::PWSafe3 - Read and write Passwordsafe v3 files
728              
729             =head1 SYNOPSIS
730              
731             use Crypt::PWSafe3;
732             my $vault = Crypt::PWSafe3->new(file => 'filename.psafe3', password => 'somesecret');
733            
734             # fetch all database records
735             my @records = $vault->getrecords();
736             foreach my $record (@records) {
737             print $record->uuid;
738             print $record->title;
739             print $record->passwd;
740             # see Crypt::PWSafe3::Record for more details on accessing records
741             }
742              
743             # same as above but don't detach records from vault
744             foreach my $uuid ($vault->looprecord) {
745             # either change a record
746             $vault->modifyrecord($uuid, passwd => 'p1');
747              
748             # or just access it directly
749             print $vault->{record}->{$uuid}->title;
750             }
751              
752             # add a new record
753             $vault->newrecord(user => 'u1', passwd => 'p1', title => 't1');
754              
755             # modify an existing record
756             $vault->modifyrecord($uuid, passwd => 'p1');
757              
758             # replace a record (aka edit it)
759             my $record = $vault->getrecord($uuid);
760             $record->title('t2');
761             $record->passwd('foobar');
762             $vault->addrecord($record);
763              
764             # mark the vault as modified (not required if
765             # changes were done with ::modifyrecord()
766             $vault->markmodified();
767              
768             # save the vault
769             $vault->save();
770              
771             # save it under another name using another password
772             $vault->save(file => 'another.pwsafe3', passwd => 'blah');
773              
774             # access database headers
775             print $vault->getheader('wholastsaved')->value();
776             print scalar localtime($vault->getheader('lastsavetime')->value());
777              
778             # add/replace a database header
779             my $h = Crypt::PWSafe3::HeaderField->new(name => 'savedonhost', value => 'localhost');
780             $vault->addheader($h);
781              
782             =head1 DESCRIPTION
783              
784             Crypt::PWSafe3 provides read and write access to password
785             database files created by Password Safe V3 (and up) available at
786             http://passwordsafe.sf.net.
787              
788             =head1 METHODS
789              
790             =head2 B
791              
792             The new() method creates a new Crypt::PWSafe3 object. Any parameters
793             must be given as hash parameters.
794              
795             my $vault = Crypt::PWSafe3->new(
796             file => 'vault.psafe3',
797             password => 'secret',
798             whoami => 'user1',
799             program => 'mypwtool v1',
800             create => 0, # or 1
801             );
802              
803             Mandatory parameters:
804              
805             =over
806              
807             =item B
808              
809             Specifies the password safe (v3) file. If it exists
810             it will be read in. Otherwise it will be created
811             if you call B.
812              
813             =item B
814              
815             The password required to decrypt the password safe file.
816              
817             =back
818              
819             Optional parameters:
820              
821             =over
822              
823             =item B
824              
825             Specifies the user who saves the password safe file.
826             If omitted the environment variable USER will be used
827             when calling B.
828              
829             =item B
830              
831             Specifies which program saved the password safe file.
832             If omitted, the content of the perl variable $0 will
833             be used, which contains the name of the current running
834             script.
835              
836             =item B
837              
838             If set to 0, B will fail if the file doesn't exist,
839             otherwise it will try to create it. Enabled by default.
840              
841             =back
842              
843             The optional parameters will become header fields of
844             the password safe file. You can manually set/override
845             more headers. See section L for
846             more details.
847              
848             =head2 B
849              
850             Returns a list of all records found in the password
851             safe file. Each element is an B
852             object.
853              
854             A record object is identified by its B value,
855             which is a unique identifier. You can access the uuid by:
856              
857             $record->uuid
858              
859             Accessing other record properties works the same. For
860             more details, refer to L.
861              
862             Please note that record objects accessed this way are
863             copies. If you change such a record object and save the
864             database, nothing will in fact change. In this case you
865             need to put the changed record back into the record
866             list of the Crypt::PWSafe3 object by:
867              
868             $vault->addrecord($record):
869              
870             See section L for more details on this.
871              
872              
873             =head2 B
874              
875             Returns a list of UUIDs of all known records. You can
876             use this list to iterate over the records without
877             copying them and optionally changing them in place.
878              
879             Example:
880              
881             foreach my $uuid ($vault->looprecord) {
882             # either change a record
883             $vault->modifyrecord($uuid, passwd => 'p1');
884              
885             # or just access it directly
886             print $vault->{record}->{$uuid}->title;
887             }
888              
889              
890             =head2 B
891              
892             Modifies the record identified by the given UUID using
893             the values of the supplied parameter hash.
894              
895             Example:
896              
897             $vault->modifyrecord($uuid, passwd => 'p1');
898              
899             The parameter hash may contain any valid record field
900             type with according values. Refer to L
901             for details about available fields.
902              
903             =head2 B
904              
905             Create a new record. The UUID of the record will be generated
906             automatically. Refer to L
907             for details about available fields.
908              
909             =head2 B
910              
911             Add a record to the vault. The record must be an
912             L object.
913              
914             =head2 B
915              
916             Delete the record identified by the given UUID.
917              
918             =head2 B
919              
920             Save the current password safe vault back to disk.
921              
922             If not otherwise specified, use the same file and
923             password as we used to open it initially. If the
924             file doesn't exist it will be created.
925              
926             You may specify another filename and password here
927             by using a parameter hash.
928              
929             Example:
930              
931             $vault->save(file => 'anotherfile.psafe3', passwd => 'foo');
932              
933             Please note, that the vault will be written to a
934             temporary file first, then this temporary file
935             will be read in and if that works, it will be
936             moved over the destination file. This way the original
937             file persists if the written database gets corrupted
938             by some unknown reason (a bug for instance).
939              
940              
941             =head2 B
942              
943             Returns a raw B object.
944             Refer to L for details
945             how to access it.
946              
947             =head2 B
948              
949             Adds a header field to the password safe database. The
950             object parameter must be an B
951             object.
952              
953             If the header already exists it will be replaced.
954              
955             Refer to L for details
956             how to create new ones
957             .
958              
959             =head1 AUTHOR
960              
961             T.v.Dein
962              
963             =head1 BUGS
964              
965             Report bugs to
966             http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Crypt-PWSafe3.
967              
968              
969             =head1 SEE ALSO
970              
971             Subclasses:
972              
973             L
974             L
975             L
976              
977             Password Safe Homepage:
978             L
979              
980             Another (read-only) perl module:
981             L
982              
983             A python port of Password Safe:
984             L
985             Many thanks to Christoph Sommer, his python library
986             inspired me a lot and in fact most of the concepts
987             in this module are his ideas ported to perl.
988              
989             =head1 COPYRIGHT
990              
991             Copyright (c) 2011-2015 by T.v.Dein .
992              
993             =head1 LICENSE
994              
995             This program is free software; you can redistribute it
996             and/or modify it under the same terms of the Artistic
997             License 2.0, see: L
998              
999             =head1 VERSION
1000              
1001             Crypt::PWSafe3 Version 1.21.
1002              
1003             =cut
1004              
1005              
1006              
1007              
1008             1;
1009