]> Dogcows Code - chaz/p5-File-KDBX/blob - lib/File/KDBX.pm
Change custom icons to an array
[chaz/p5-File-KDBX] / lib / File / KDBX.pm
1 package File::KDBX;
2 # ABSTRACT: Encrypted databases to store secret text and files
3
4 use warnings;
5 use strict;
6
7 use Crypt::PRNG qw(random_bytes);
8 use Devel::GlobalDestruction;
9 use File::KDBX::Constants qw(:all);
10 use File::KDBX::Error;
11 use File::KDBX::Safe;
12 use File::KDBX::Util qw(:class :coercion :empty :uuid :search erase simple_expression_query snakify);
13 use Hash::Util::FieldHash qw(fieldhashes);
14 use List::Util qw(any first);
15 use Ref::Util qw(is_ref is_arrayref is_plain_hashref);
16 use Scalar::Util qw(blessed);
17 use Time::Piece;
18 use boolean;
19 use namespace::clean;
20
21 our $VERSION = '999.999'; # VERSION
22 our $WARNINGS = 1;
23
24 fieldhashes \my (%SAFE, %KEYS);
25
26 =method new
27
28 $kdbx = File::KDBX->new(%attributes);
29 $kdbx = File::KDBX->new($kdbx); # copy constructor
30
31 Construct a new L<File::KDBX>.
32
33 =cut
34
35 sub new {
36 my $class = shift;
37
38 # copy constructor
39 return $_[0]->clone if @_ == 1 && blessed $_[0] && $_[0]->isa($class);
40
41 my $self = bless {}, $class;
42 $self->init(@_);
43 $self->_set_nonlazy_attributes if empty $self;
44 return $self;
45 }
46
47 sub DESTROY { local ($., $@, $!, $^E, $?); !in_global_destruction and $_[0]->reset }
48
49 =method init
50
51 $kdbx = $kdbx->init(%attributes);
52
53 Initialize a L<File::KDBX> with a new set of attributes. Returns itself to allow method chaining.
54
55 This is called by L</new>.
56
57 =cut
58
59 sub init {
60 my $self = shift;
61 my %args = @_;
62
63 @$self{keys %args} = values %args;
64
65 return $self;
66 }
67
68 =method reset
69
70 $kdbx = $kdbx->reset;
71
72 Set a L<File::KDBX> to an empty state, ready to load a KDBX file or build a new one. Returns itself to allow
73 method chaining.
74
75 =cut
76
77 sub reset {
78 my $self = shift;
79 erase $self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY};
80 erase $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY};
81 erase $self->{raw};
82 %$self = ();
83 $self->_remove_safe;
84 return $self;
85 }
86
87 =method clone
88
89 $kdbx_copy = $kdbx->clone;
90 $kdbx_copy = File::KDBX->new($kdbx);
91
92 Clone a L<File::KDBX>. The clone will be an exact copy and completely independent of the original.
93
94 =cut
95
96 sub clone {
97 my $self = shift;
98 require Storable;
99 return Storable::dclone($self);
100 }
101
102 sub STORABLE_freeze {
103 my $self = shift;
104 my $cloning = shift;
105
106 my $copy = {%$self};
107
108 return '', $copy, $KEYS{$self} // (), $SAFE{$self} // ();
109 }
110
111 sub STORABLE_thaw {
112 my $self = shift;
113 my $cloning = shift;
114 shift;
115 my $clone = shift;
116 my $key = shift;
117 my $safe = shift;
118
119 @$self{keys %$clone} = values %$clone;
120 $KEYS{$self} = $key;
121 $SAFE{$self} = $safe;
122
123 # Dualvars aren't cloned as dualvars, so coerce the compression flags.
124 $self->compression_flags($self->compression_flags);
125
126 for my $object (@{$self->all_groups}, @{$self->all_entries(history => 1)}) {
127 $object->kdbx($self);
128 }
129 }
130
131 ##############################################################################
132
133 =method load
134
135 =method load_string
136
137 =method load_file
138
139 =method load_handle
140
141 $kdbx = KDBX::File->load(\$string, $key);
142 $kdbx = KDBX::File->load(*IO, $key);
143 $kdbx = KDBX::File->load($filepath, $key);
144 $kdbx->load(...); # also instance method
145
146 $kdbx = File::KDBX->load_string($string, $key);
147 $kdbx = File::KDBX->load_string(\$string, $key);
148 $kdbx->load_string(...); # also instance method
149
150 $kdbx = File::KDBX->load_file($filepath, $key);
151 $kdbx->load_file(...); # also instance method
152
153 $kdbx = File::KDBX->load_handle($fh, $key);
154 $kdbx = File::KDBX->load_handle(*IO, $key);
155 $kdbx->load_handle(...); # also instance method
156
157 Load a KDBX file from a string buffer, IO handle or file from a filesystem.
158
159 L<File::KDBX::Loader> does the heavy lifting.
160
161 =cut
162
163 sub load { shift->_loader->load(@_) }
164 sub load_string { shift->_loader->load_string(@_) }
165 sub load_file { shift->_loader->load_file(@_) }
166 sub load_handle { shift->_loader->load_handle(@_) }
167
168 sub _loader {
169 my $self = shift;
170 $self = $self->new if !ref $self;
171 require File::KDBX::Loader;
172 File::KDBX::Loader->new(kdbx => $self);
173 }
174
175 =method dump
176
177 =method dump_string
178
179 =method dump_file
180
181 =method dump_handle
182
183 $kdbx->dump(\$string, $key);
184 $kdbx->dump(*IO, $key);
185 $kdbx->dump($filepath, $key);
186
187 $kdbx->dump_string(\$string, $key);
188 \$string = $kdbx->dump_string($key);
189
190 $kdbx->dump_file($filepath, $key);
191
192 $kdbx->dump_handle($fh, $key);
193 $kdbx->dump_handle(*IO, $key);
194
195 Dump a KDBX file to a string buffer, IO handle or file in a filesystem.
196
197 L<File::KDBX::Dumper> does the heavy lifting.
198
199 =cut
200
201 sub dump { shift->_dumper->dump(@_) }
202 sub dump_string { shift->_dumper->dump_string(@_) }
203 sub dump_file { shift->_dumper->dump_file(@_) }
204 sub dump_handle { shift->_dumper->dump_handle(@_) }
205
206 sub _dumper {
207 my $self = shift;
208 $self = $self->new if !ref $self;
209 require File::KDBX::Dumper;
210 File::KDBX::Dumper->new(kdbx => $self);
211 }
212
213 ##############################################################################
214
215 =method user_agent_string
216
217 $string = $kdbx->user_agent_string;
218
219 Get a text string identifying the database client software.
220
221 =cut
222
223 sub user_agent_string {
224 require Config;
225 sprintf('%s/%s (%s/%s; %s/%s; %s)',
226 __PACKAGE__, $VERSION, @Config::Config{qw(package version osname osvers archname)});
227 }
228
229 has sig1 => KDBX_SIG1, coerce => \&to_number;
230 has sig2 => KDBX_SIG2_2, coerce => \&to_number;
231 has version => KDBX_VERSION_3_1, coerce => \&to_number;
232 has headers => {};
233 has inner_headers => {};
234 has meta => {};
235 has binaries => {};
236 has deleted_objects => {};
237 has raw => coerce => \&to_string;
238
239 # HEADERS
240 has 'headers.comment' => '', coerce => \&to_string;
241 has 'headers.cipher_id' => CIPHER_UUID_CHACHA20, coerce => \&to_uuid;
242 has 'headers.compression_flags' => COMPRESSION_GZIP, coerce => \&to_compression_constant;
243 has 'headers.master_seed' => sub { random_bytes(32) }, coerce => \&to_string;
244 has 'headers.encryption_iv' => sub { random_bytes(16) }, coerce => \&to_string;
245 has 'headers.stream_start_bytes' => sub { random_bytes(32) }, coerce => \&to_string;
246 has 'headers.kdf_parameters' => sub {
247 +{
248 KDF_PARAM_UUID() => KDF_UUID_AES,
249 KDF_PARAM_AES_ROUNDS() => $_[0]->headers->{+HEADER_TRANSFORM_ROUNDS} // KDF_DEFAULT_AES_ROUNDS,
250 KDF_PARAM_AES_SEED() => $_[0]->headers->{+HEADER_TRANSFORM_SEED} // random_bytes(32),
251 };
252 };
253 # has 'headers.transform_seed' => sub { random_bytes(32) };
254 # has 'headers.transform_rounds' => 100_000;
255 # has 'headers.inner_random_stream_key' => sub { random_bytes(32) }; # 64 ?
256 # has 'headers.inner_random_stream_id' => STREAM_ID_CHACHA20;
257 # has 'headers.public_custom_data' => {};
258
259 # META
260 has 'meta.generator' => '', coerce => \&to_string;
261 has 'meta.header_hash' => '', coerce => \&to_string;
262 has 'meta.database_name' => '', coerce => \&to_string;
263 has 'meta.database_name_changed' => sub { gmtime }, coerce => \&to_time;
264 has 'meta.database_description' => '', coerce => \&to_string;
265 has 'meta.database_description_changed' => sub { gmtime }, coerce => \&to_time;
266 has 'meta.default_username' => '', coerce => \&to_string;
267 has 'meta.default_username_changed' => sub { gmtime }, coerce => \&to_time;
268 has 'meta.maintenance_history_days' => 0, coerce => \&to_number;
269 has 'meta.color' => '', coerce => \&to_string;
270 has 'meta.master_key_changed' => sub { gmtime }, coerce => \&to_time;
271 has 'meta.master_key_change_rec' => -1, coerce => \&to_number;
272 has 'meta.master_key_change_force' => -1, coerce => \&to_number;
273 # has 'meta.memory_protection' => {};
274 has 'meta.custom_icons' => [];
275 has 'meta.recycle_bin_enabled' => true, coerce => \&to_bool;
276 has 'meta.recycle_bin_uuid' => "\0" x 16, coerce => \&to_uuid;
277 has 'meta.recycle_bin_changed' => sub { gmtime }, coerce => \&to_time;
278 has 'meta.entry_templates_group' => "\0" x 16, coerce => \&to_uuid;
279 has 'meta.entry_templates_group_changed' => sub { gmtime }, coerce => \&to_time;
280 has 'meta.last_selected_group' => "\0" x 16, coerce => \&to_uuid;
281 has 'meta.last_top_visible_group' => "\0" x 16, coerce => \&to_uuid;
282 has 'meta.history_max_items' => HISTORY_DEFAULT_MAX_ITEMS, coerce => \&to_number;
283 has 'meta.history_max_size' => HISTORY_DEFAULT_MAX_SIZE, coerce => \&to_number;
284 has 'meta.settings_changed' => sub { gmtime }, coerce => \&to_time;
285 # has 'meta.binaries' => {};
286 # has 'meta.custom_data' => {};
287
288 has 'memory_protection.protect_title' => false, coerce => \&to_bool;
289 has 'memory_protection.protect_username' => false, coerce => \&to_bool;
290 has 'memory_protection.protect_password' => true, coerce => \&to_bool;
291 has 'memory_protection.protect_url' => false, coerce => \&to_bool;
292 has 'memory_protection.protect_notes' => false, coerce => \&to_bool;
293 # has 'memory_protection.auto_enable_visual_hiding' => false;
294
295 my @ATTRS = (
296 HEADER_TRANSFORM_SEED,
297 HEADER_TRANSFORM_ROUNDS,
298 HEADER_INNER_RANDOM_STREAM_KEY,
299 HEADER_INNER_RANDOM_STREAM_ID,
300 HEADER_PUBLIC_CUSTOM_DATA,
301 );
302 sub _set_nonlazy_attributes {
303 my $self = shift;
304 $self->$_ for list_attributes(ref $self), @ATTRS;
305 }
306
307 =method memory_protection
308
309 \%settings = $kdbx->memory_protection
310 $kdbx->memory_protection(\%settings);
311
312 $bool = $kdbx->memory_protection($string_key);
313 $kdbx->memory_protection($string_key => $bool);
314
315 Get or set memory protection settings. This globally (for the whole database) configures whether and which of
316 the standard strings should be memory-protected. The default setting is to memory-protect only I<Password>
317 strings.
318
319 Memory protection can be toggled individually for each entry string, and individual settings take precedence
320 over these global settings.
321
322 =cut
323
324 sub memory_protection {
325 my $self = shift;
326 $self->{meta}{memory_protection} = shift if @_ == 1 && is_plain_hashref($_[0]);
327 return $self->{meta}{memory_protection} //= {} if !@_;
328
329 my $string_key = shift;
330 my $key = 'protect_' . lc($string_key);
331
332 $self->meta->{memory_protection}{$key} = shift if @_;
333 $self->meta->{memory_protection}{$key};
334 }
335
336 =method minimum_version
337
338 $version = $kdbx->minimum_version;
339
340 Determine the minimum file version required to save a database losslessly. Using certain databases features
341 might increase this value. For example, setting the KDF to Argon2 will increase the minimum version to at
342 least C<KDBX_VERSION_4_0> (i.e. C<0x00040000>) because Argon2 was introduced with KDBX4.
343
344 This method never returns less than C<KDBX_VERSION_3_1> (i.e. C<0x00030001>). That file version is so
345 ubiquitious and well-supported, there are seldom reasons to dump in a lesser format nowadays.
346
347 B<WARNING:> If you dump a database with a minimum version higher than the current L</version>, the dumper will
348 typically issue a warning and automatically upgrade the database. This seems like the safest behavior in order
349 to avoid data loss, but lower versions have the benefit of being compatible with more software. It is possible
350 to prevent auto-upgrades by explicitly telling the dumper which version to use, but you do run the risk of
351 data loss. A database will never be automatically downgraded.
352
353 =cut
354
355 sub minimum_version {
356 my $self = shift;
357
358 return KDBX_VERSION_4_1 if any {
359 nonempty $_->{last_modification_time}
360 } values %{$self->custom_data};
361
362 return KDBX_VERSION_4_1 if any {
363 nonempty $_->{name} || nonempty $_->{last_modification_time}
364 } @{$self->custom_icons};
365
366 return KDBX_VERSION_4_1 if any {
367 nonempty $_->previous_parent_group || nonempty $_->tags ||
368 any { nonempty $_->{last_modification_time} } values %{$_->custom_data}
369 } @{$self->all_groups};
370
371 return KDBX_VERSION_4_1 if any {
372 nonempty $_->previous_parent_group || (defined $_->quality_check && !$_->quality_check) ||
373 any { nonempty $_->{last_modification_time} } values %{$_->custom_data}
374 } @{$self->all_entries(history => 1)};
375
376 return KDBX_VERSION_4_0 if $self->kdf->uuid ne KDF_UUID_AES;
377
378 return KDBX_VERSION_4_0 if nonempty $self->public_custom_data;
379
380 return KDBX_VERSION_4_0 if any {
381 nonempty $_->custom_data
382 } @{$self->all_groups}, @{$self->all_entries(history => 1)};
383
384 return KDBX_VERSION_3_1;
385 }
386
387 ##############################################################################
388
389 =method root
390
391 $group = $kdbx->root;
392 $kdbx->root($group);
393
394 Get or set a database's root group. You don't necessarily need to explicitly create or set a root group
395 because it autovivifies when adding entries and groups to the database.
396
397 Every database has only a single root group at a time. Some old KDB files might have multiple root groups.
398 When reading such files, a single implicit root group is created to contain the actual root groups. When
399 writing to such a format, if the root group looks like it was implicitly created then it won't be written and
400 the resulting file might have multiple root groups. This allows working with older files without changing
401 their written internal structure while still adhering to modern semantics while the database is opened.
402
403 The root group of a KDBX database contains all of the database's entries and other groups. If you replace the
404 root group, you are essentially replacing the entire database contents with something else.
405
406 =cut
407
408 sub root {
409 my $self = shift;
410 if (@_) {
411 $self->{root} = $self->_wrap_group(@_);
412 $self->{root}->kdbx($self);
413 }
414 $self->{root} //= $self->_implicit_root;
415 return $self->_wrap_group($self->{root});
416 }
417
418 sub _kpx_groups {
419 my $self = shift;
420 return [] if !$self->{root};
421 return $self->_has_implicit_root ? $self->root->groups : [$self->root];
422 }
423
424 sub _has_implicit_root {
425 my $self = shift;
426 my $root = $self->root;
427 my $temp = __PACKAGE__->_implicit_root;
428 # If an implicit root group has been changed in any significant way, it is no longer implicit.
429 return $root->name eq $temp->name &&
430 $root->is_expanded ^ $temp->is_expanded &&
431 $root->notes eq $temp->notes &&
432 !@{$root->entries} &&
433 !defined $root->custom_icon_uuid &&
434 !keys %{$root->custom_data} &&
435 $root->icon_id == $temp->icon_id &&
436 $root->expires ^ $temp->expires &&
437 $root->default_auto_type_sequence eq $temp->default_auto_type_sequence &&
438 !defined $root->enable_auto_type &&
439 !defined $root->enable_searching;
440 }
441
442 sub _implicit_root {
443 my $self = shift;
444 require File::KDBX::Group;
445 return File::KDBX::Group->new(
446 name => 'Root',
447 is_expanded => true,
448 notes => 'Added as an implicit root group by '.__PACKAGE__.'.',
449 ref $self ? (kdbx => $self) : (),
450 );
451 }
452
453 =method trace_lineage
454
455 \@lineage = $kdbx->trace_lineage($group);
456 \@lineage = $kdbx->trace_lineage($group, $base_group);
457 \@lineage = $kdbx->trace_lineage($entry);
458 \@lineage = $kdbx->trace_lineage($entry, $base_group);
459
460 Get the direct line of ancestors from C<$base_group> (default: the root group) to a group or entry. The
461 lineage includes the base group but I<not> the target group or entry. Returns C<undef> if the target is not in
462 the database structure.
463
464 =cut
465
466 sub trace_lineage {
467 my $self = shift;
468 my $object = shift;
469 return $object->lineage(@_);
470 }
471
472 sub _trace_lineage {
473 my $self = shift;
474 my $object = shift;
475 my @lineage = @_;
476
477 push @lineage, $self->root if !@lineage;
478 my $base = $lineage[-1] or return [];
479
480 my $uuid = $object->uuid;
481 return \@lineage if any { $_->uuid eq $uuid } @{$base->groups || []}, @{$base->entries || []};
482
483 for my $subgroup (@{$base->groups || []}) {
484 my $result = $self->_trace_lineage($object, @lineage, $subgroup);
485 return $result if $result;
486 }
487 }
488
489 ##############################################################################
490
491 =method add_group
492
493 $kdbx->add_group($group, %options);
494 $kdbx->add_group(%group_attributes, %options);
495
496 Add a group to a database. This is equivalent to identifying a parent group and calling
497 L<File::KDBX::Group/add_group> on the parent group, forwarding the arguments. Available options:
498
499 =for :list
500 * C<group> (aka C<parent>) - Group (object or group UUID) to add the group to (default: root group)
501
502 =cut
503
504 sub add_group {
505 my $self = shift;
506 my $group = @_ % 2 == 1 ? shift : undef;
507 my %args = @_;
508
509 # find the right group to add the group to
510 my $parent = delete $args{group} // delete $args{parent} // $self->root;
511 ($parent) = $self->find_groups({uuid => $parent}) if !ref $parent;
512 $parent or throw 'Invalid group';
513
514 return $parent->add_group(defined $group ? $group : (), %args, kdbx => $self);
515 }
516
517 sub _wrap_group {
518 my $self = shift;
519 my $group = shift;
520 require File::KDBX::Group;
521 return File::KDBX::Group->wrap($group, $self);
522 }
523
524 =method all_groups
525
526 \@groups = $kdbx->all_groups(%options);
527 \@groups = $kdbx->all_groups($base_group, %options);
528
529 Get all groups deeply in a database, or all groups within a specified base group, in a flat array. Supported
530 options:
531
532 =for :list
533 * C<base> - Only include groups within a base group (same as C<$base_group>) (default: root)
534 * C<include_base> - Include the base group in the results (default: true)
535
536 =cut
537
538 sub all_groups {
539 my $self = shift;
540 my %args = @_ % 2 == 0 ? @_ : (base => shift, @_);
541 my $base = $args{base} // $self->root;
542
543 my @groups = $args{include_base} // 1 ? $self->_wrap_group($base) : ();
544
545 for my $subgroup (@{$base->{groups} || []}) {
546 my $more = $self->all_groups($subgroup);
547 push @groups, @$more;
548 }
549
550 return \@groups;
551 }
552
553 =method find_groups
554
555 @groups = $kdbx->find_groups($query, %options);
556
557 Find all groups deeply that match to a query. Options are the same as for L</all_groups>.
558
559 See L</QUERY> for a description of what C<$query> can be.
560
561 =cut
562
563 sub find_groups {
564 my $self = shift;
565 my $query = shift or throw 'Must provide a query';
566 my %args = @_;
567 my %all_groups = (
568 base => $args{base},
569 include_base => $args{include_base},
570 );
571 return @{search($self->all_groups(%all_groups), is_arrayref($query) ? @$query : $query)};
572 }
573
574 ##############################################################################
575
576 =method add_entry
577
578 $kdbx->add_entry($entry, %options);
579 $kdbx->add_entry(%entry_attributes, %options);
580
581 Add a entry to a database. This is equivalent to identifying a parent group and calling
582 L<File::KDBX::Group/add_entry> on the parent group, forwarding the arguments. Available options:
583
584 =for :list
585 * C<group> (aka C<parent>) - Group (object or group UUID) to add the entry to (default: root group)
586
587 =cut
588
589 sub add_entry {
590 my $self = shift;
591 my $entry = @_ % 2 == 1 ? shift : undef;
592 my %args = @_;
593
594 # find the right group to add the entry to
595 my $parent = delete $args{group} // delete $args{parent} // $self->root;
596 ($parent) = $self->find_groups({uuid => $parent}) if !ref $parent;
597 $parent or throw 'Invalid group';
598
599 return $parent->add_entry(defined $entry ? $entry : (), %args, kdbx => $self);
600 }
601
602 sub _wrap_entry {
603 my $self = shift;
604 my $entry = shift;
605 require File::KDBX::Entry;
606 return File::KDBX::Entry->wrap($entry, $self);
607 }
608
609 =method all_entries
610
611 \@entries = $kdbx->all_entries(%options);
612 \@entries = $kdbx->all_entries($base_group, %options);
613
614 Get entries deeply in a database, in a flat array. Supported options:
615
616 =for :list
617 * C<base> - Only include entries within a base group (same as C<$base_group>) (default: root)
618 * C<auto_type> - Only include entries with auto-type enabled (default: false, include all)
619 * C<search> - Only include entries within groups with search enabled (default: false, include all)
620 * C<history> - Also include historical entries (default: false, include only active entries)
621
622 =cut
623
624 sub all_entries {
625 my $self = shift;
626 my %args = @_ % 2 == 0 ? @_ : (base => shift, @_);
627
628 my $base = $args{base} // $self->root;
629 my $history = $args{history};
630 my $search = $args{search};
631 my $auto_type = $args{auto_type};
632
633 my $enable_auto_type = $base->{enable_auto_type} // true;
634 my $enable_searching = $base->{enable_searching} // true;
635
636 my @entries;
637 if ((!$search || $enable_searching) && (!$auto_type || $enable_auto_type)) {
638 push @entries,
639 map { $self->_wrap_entry($_) }
640 grep { !$auto_type || $_->{auto_type}{enabled} }
641 map { $_, $history ? @{$_->{history} || []} : () }
642 @{$base->{entries} || []};
643 }
644
645 for my $subgroup (@{$base->{groups} || []}) {
646 my $more = $self->all_entries($subgroup,
647 auto_type => $auto_type,
648 search => $search,
649 history => $history,
650 );
651 push @entries, @$more;
652 }
653
654 return \@entries;
655 }
656
657 =method find_entries
658
659 =method find_entries_simple
660
661 @entries = $kdbx->find_entries($query, %options);
662
663 @entries = $kdbx->find_entries_simple($expression, \@fields, %options);
664 @entries = $kdbx->find_entries_simple($expression, $operator, \@fields, %options);
665
666 Find all entries deeply that match a query. Options are the same as for L</all_entries>.
667
668 See L</QUERY> for a description of what C<$query> can be.
669
670 =cut
671
672 sub find_entries {
673 my $self = shift;
674 my $query = shift or throw 'Must provide a query';
675 my %args = @_;
676 my %all_entries = (
677 base => $args{base},
678 auto_type => $args{auto_type},
679 search => $args{search},
680 history => $args{history},
681 );
682 my $limit = delete $args{limit};
683 if (defined $limit) {
684 return @{search_limited($self->all_entries(%all_entries), is_arrayref($query) ? @$query : $query, $limit)};
685 }
686 else {
687 return @{search($self->all_entries(%all_entries), is_arrayref($query) ? @$query : $query)};
688 }
689 }
690
691 sub find_entries_simple {
692 my $self = shift;
693 my $text = shift;
694 my $op = @_ && !is_ref($_[0]) ? shift : undef;
695 my $fields = shift;
696 is_arrayref($fields) or throw q{Usage: find_entries_simple($expression, [$op,] \@fields)};
697 return $self->find_entries([\$text, $op, $fields], @_);
698 }
699
700 ##############################################################################
701
702 =method custom_icon
703
704 \%icon = $kdbx->custom_icon($uuid);
705 $kdbx->custom_icon($uuid => \%icon);
706 $kdbx->custom_icon(%icon);
707 $kdbx->custom_icon(uuid => $value, %icon);
708
709 Get or set custom icons.
710
711 =cut
712
713 sub custom_icon {
714 my $self = shift;
715 my %args = @_ == 2 ? (uuid => shift, data => shift)
716 : @_ % 2 == 1 ? (uuid => shift, @_) : @_;
717
718 if (!$args{uuid} && !$args{data}) {
719 my %standard = (uuid => 1, data => 1, name => 1, last_modification_time => 1);
720 my @other_keys = grep { !$standard{$_} } keys %args;
721 if (@other_keys == 1) {
722 my $key = $args{key} = $other_keys[0];
723 $args{data} = delete $args{$key};
724 }
725 }
726
727 my $uuid = $args{uuid} or throw 'Must provide a custom icon UUID to access';
728 my $icon = (first { $_->{uuid} eq $uuid } @{$self->custom_icons}) // do {
729 push @{$self->custom_icons}, my $i = { uuid => $uuid };
730 $i;
731 };
732
733 my $fields = \%args;
734 $fields = $args{data} if is_plain_hashref($args{data});
735
736 while (my ($field, $value) = each %$fields) {
737 $icon->{$field} = $value;
738 }
739 return $icon;
740 }
741
742 =method custom_icon_data
743
744 $image_data = $kdbx->custom_icon_data($uuid);
745
746 Get a custom icon image data.
747
748 =cut
749
750 sub custom_icon_data {
751 my $self = shift;
752 my $uuid = shift // return;
753 my $icon = first { $_->{uuid} eq $uuid } @{$self->custom_icons} or return;
754 return $icon->{data};
755 }
756
757 =method add_custom_icon
758
759 $uuid = $kdbx->add_custom_icon($image_data, %attributes);
760
761 Add a custom icon and get its UUID. If not provided, a random UUID will be generated. Possible attributes:
762
763 =for :list
764 * C<uuid> - Icon UUID (default: autogenerated)
765 * C<name> - Name of the icon (text, KDBX4.1+)
766 * C<last_modification_time> - Just what it says (datetime, KDBX4.1+)
767
768 =cut
769
770 sub add_custom_icon {
771 my $self = shift;
772 my $img = shift or throw 'Must provide image data';
773 my %args = @_;
774
775 my $uuid = $args{uuid} // generate_uuid;
776 push @{$self->custom_icons}, {
777 @_,
778 uuid => $uuid,
779 data => $img,
780 };
781 return $uuid;
782 }
783
784 =method remove_custom_icon
785
786 $kdbx->remove_custom_icon($uuid);
787
788 Remove a custom icon.
789
790 =cut
791
792 sub remove_custom_icon {
793 my $self = shift;
794 my $uuid = shift;
795 my @deleted;
796 @{$self->custom_icons} = grep { $_->{uuid} eq $uuid ? do { push @deleted, $_; 0 } : 1 }
797 @{$self->custom_icons};
798 $self->add_deleted_object($uuid) if @deleted;
799 return @deleted;
800 }
801
802 ##############################################################################
803
804 =method custom_data
805
806 \%all_data = $kdbx->custom_data;
807 $kdbx->custom_data(\%all_data);
808
809 \%data = $kdbx->custom_data($key);
810 $kdbx->custom_data($key => \%data);
811 $kdbx->custom_data(%data);
812 $kdbx->custom_data(key => $value, %data);
813
814 Get and set custom data. Custom data is metadata associated with a database.
815
816 Each data item can have a few attributes associated with it.
817
818 =for :list
819 * C<key> - A unique text string identifier used to look up the data item (required)
820 * C<value> - A text string value (required)
821 * C<last_modification_time> (optional, KDBX4.1+)
822
823 =cut
824
825 sub custom_data {
826 my $self = shift;
827 $self->{meta}{custom_data} = shift if @_ == 1 && is_plain_hashref($_[0]);
828 return $self->{meta}{custom_data} //= {} if !@_;
829
830 my %args = @_ == 2 ? (key => shift, value => shift)
831 : @_ % 2 == 1 ? (key => shift, @_) : @_;
832
833 if (!$args{key} && !$args{value}) {
834 my %standard = (key => 1, value => 1, last_modification_time => 1);
835 my @other_keys = grep { !$standard{$_} } keys %args;
836 if (@other_keys == 1) {
837 my $key = $args{key} = $other_keys[0];
838 $args{value} = delete $args{$key};
839 }
840 }
841
842 my $key = $args{key} or throw 'Must provide a custom_data key to access';
843
844 return $self->{meta}{custom_data}{$key} = $args{value} if is_plain_hashref($args{value});
845
846 while (my ($field, $value) = each %args) {
847 $self->{meta}{custom_data}{$key}{$field} = $value;
848 }
849 return $self->{meta}{custom_data}{$key};
850 }
851
852 =method custom_data_value
853
854 $value = $kdbx->custom_data_value($key);
855
856 Exactly the same as L</custom_data> except returns just the custom data's value rather than a structure of
857 attributes. This is a shortcut for:
858
859 my $data = $kdbx->custom_data($key);
860 my $value = defined $data ? $data->{value} : undef;
861
862 =cut
863
864 sub custom_data_value {
865 my $self = shift;
866 my $data = $self->custom_data(@_) // return;
867 return $data->{value};
868 }
869
870 =method public_custom_data
871
872 \%all_data = $kdbx->public_custom_data;
873 $kdbx->public_custom_data(\%all_data);
874
875 $value = $kdbx->public_custom_data($key);
876 $kdbx->public_custom_data($key => $value);
877
878 Get and set public custom data. Public custom data is similar to custom data but different in some important
879 ways. Public custom data:
880
881 =for :list
882 * can store strings, booleans and up to 64-bit integer values (custom data can only store text values)
883 * is NOT encrypted within a KDBX file (hence the "public" part of the name)
884 * is a plain hash/dict of key-value pairs with no other associated fields (like modification times)
885
886 =cut
887
888 sub public_custom_data {
889 my $self = shift;
890 $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA} = shift if @_ == 1 && is_plain_hashref($_[0]);
891 return $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA} //= {} if !@_;
892
893 my $key = shift or throw 'Must provide a public_custom_data key to access';
894 $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA}{$key} = shift if @_;
895 return $self->{headers}{+HEADER_PUBLIC_CUSTOM_DATA}{$key};
896 }
897
898 ##############################################################################
899
900 # TODO
901
902 # sub merge_to {
903 # my $self = shift;
904 # my $other = shift;
905 # my %options = @_; # prefer_old / prefer_new
906 # $other->merge_from($self);
907 # }
908
909 # sub merge_from {
910 # my $self = shift;
911 # my $other = shift;
912
913 # die 'Not implemented';
914 # }
915
916 =method add_deleted_object
917
918 $kdbx->add_deleted_object($uuid);
919
920 Add a UUID to the deleted objects list. This list is used to support automatic database merging.
921
922 You typically do not need to call this yourself because the list will be populated automatically as objects
923 are removed.
924
925 =cut
926
927 sub add_deleted_object {
928 my $self = shift;
929 my $uuid = shift;
930 $self->deleted_objects->{$uuid} = {
931 uuid => $uuid,
932 deletion_time => scalar gmtime,
933 };
934 }
935
936 ##############################################################################
937
938 =method resolve_reference
939
940 $string = $kdbx->resolve_reference($reference);
941 $string = $kdbx->resolve_reference($wanted, $search_in, $expression);
942
943 Resolve a L<field reference|https://keepass.info/help/base/fieldrefs.html>. A field reference is a kind of
944 string placeholder. You can use a field reference to refer directly to a standard field within an entry. Field
945 references are resolved automatically while expanding entry strings (i.e. replacing placeholders), but you can
946 use this method to resolve on-the-fly references that aren't part of any actual string in the database.
947
948 If the reference does not resolve to any field, C<undef> is returned. If the reference resolves to multiple
949 fields, only the first one is returned (in the same order as L</all_entries>). To avoid ambiguity, you can
950 refer to a specific entry by its UUID.
951
952 The syntax of a reference is: C<< {REF:<WantedField>@<SearchIn>:<Text>} >>. C<Text> is a
953 L</"Simple Expression">. C<WantedField> and C<SearchIn> are both single character codes representing a field:
954
955 =for :list
956 * C<T> - Title
957 * C<U> - UserName
958 * C<P> - Password
959 * C<A> - URL
960 * C<N> - Notes
961 * C<I> - UUID
962 * C<O> - Other custom strings
963
964 Since C<O> does not represent any specific field, it cannot be used as the C<WantedField>.
965
966 Examples:
967
968 To get the value of the I<UserName> string of the first entry with "My Bank" in the title:
969
970 my $username = $kdbx->resolve_reference('{REF:U@T:"My Bank"}');
971 # OR the {REF:...} wrapper is optional
972 my $username = $kdbx->resolve_reference('U@T:"My Bank"');
973 # OR separate the arguments
974 my $username = $kdbx->resolve_reference(U => T => '"My Bank"');
975
976 Note how the text is a L</"Simple Expression">, so search terms with spaces must be surrounded in double
977 quotes.
978
979 To get the I<Password> string of a specific entry (identified by its UUID):
980
981 my $password = $kdbx->resolve_reference('{REF:P@I:46C9B1FFBD4ABC4BBB260C6190BAD20C}');
982
983 =cut
984
985 sub resolve_reference {
986 my $self = shift;
987 my $wanted = shift // return;
988 my $search_in = shift;
989 my $text = shift;
990
991 if (!defined $text) {
992 $wanted =~ s/^\{REF:([^\}]+)\}$/$1/i;
993 ($wanted, $search_in, $text) = $wanted =~ /^([TUPANI])\@([TUPANIO]):(.*)$/i;
994 }
995 $wanted && $search_in && nonempty($text) or return;
996
997 my %fields = (
998 T => 'expanded_title',
999 U => 'expanded_username',
1000 P => 'expanded_password',
1001 A => 'expanded_url',
1002 N => 'expanded_notes',
1003 I => 'uuid',
1004 O => 'other_strings',
1005 );
1006 $wanted = $fields{$wanted} or return;
1007 $search_in = $fields{$search_in} or return;
1008
1009 my $query = $search_in eq 'uuid' ? query($search_in => uuid($text))
1010 : simple_expression_query($text, '=~', $search_in);
1011
1012 my ($entry) = $self->find_entries($query, limit => 1);
1013 $entry or return;
1014
1015 return $entry->$wanted;
1016 }
1017
1018 our %PLACEHOLDERS = (
1019 # placeholder => sub { my ($entry, $arg) = @_; ... };
1020 'TITLE' => sub { $_[0]->expanded_title },
1021 'USERNAME' => sub { $_[0]->expanded_username },
1022 'PASSWORD' => sub { $_[0]->expanded_password },
1023 'NOTES' => sub { $_[0]->expanded_notes },
1024 'S:' => sub { $_[0]->string_value($_[1]) },
1025 'URL' => sub { $_[0]->expanded_url },
1026 'URL:RMVSCM' => sub { local $_ = $_[0]->url; s!^[^:/\?\#]+://!!; $_ },
1027 'URL:WITHOUTSCHEME' => sub { local $_ = $_[0]->url; s!^[^:/\?\#]+://!!; $_ },
1028 'URL:SCM' => sub { (split_url($_[0]->url))[0] },
1029 'URL:SCHEME' => sub { (split_url($_[0]->url))[0] }, # non-standard
1030 'URL:HOST' => sub { (split_url($_[0]->url))[2] },
1031 'URL:PORT' => sub { (split_url($_[0]->url))[3] },
1032 'URL:PATH' => sub { (split_url($_[0]->url))[4] },
1033 'URL:QUERY' => sub { (split_url($_[0]->url))[5] },
1034 'URL:HASH' => sub { (split_url($_[0]->url))[6] }, # non-standard
1035 'URL:FRAGMENT' => sub { (split_url($_[0]->url))[6] }, # non-standard
1036 'URL:USERINFO' => sub { (split_url($_[0]->url))[1] },
1037 'URL:USERNAME' => sub { (split_url($_[0]->url))[7] },
1038 'URL:PASSWORD' => sub { (split_url($_[0]->url))[8] },
1039 'UUID' => sub { local $_ = format_uuid($_[0]->uuid); s/-//g; $_ },
1040 'REF:' => sub { $_[0]->kdbx->resolve_reference($_[1]) },
1041 'INTERNETEXPLORER' => sub { load_optional('IPC::Cmd'); IPC::Cmd::can_run('iexplore') },
1042 'FIREFOX' => sub { load_optional('IPC::Cmd'); IPC::Cmd::can_run('firefox') },
1043 'GOOGLECHROME' => sub { load_optional('IPC::Cmd'); IPC::Cmd::can_run('google-chrome') },
1044 'OPERA' => sub { load_optional('IPC::Cmd'); IPC::Cmd::can_run('opera') },
1045 'SAFARI' => sub { load_optional('IPC::Cmd'); IPC::Cmd::can_run('safari') },
1046 'APPDIR' => sub { load_optional('FindBin'); $FindBin::Bin },
1047 'GROUP' => sub { my $p = $_[0]->parent; $p ? $p->name : undef },
1048 'GROUP_PATH' => sub { $_[0]->path },
1049 'GROUP_NOTES' => sub { my $p = $_[0]->parent; $p ? $p->notes : undef },
1050 # 'GROUP_SEL'
1051 # 'GROUP_SEL_PATH'
1052 # 'GROUP_SEL_NOTES'
1053 # 'DB_PATH'
1054 # 'DB_DIR'
1055 # 'DB_NAME'
1056 # 'DB_BASENAME'
1057 # 'DB_EXT'
1058 'ENV:' => sub { $ENV{$_[1]} },
1059 'ENV_DIRSEP' => sub { load_optional('File::Spec')->catfile('', '') },
1060 'ENV_PROGRAMFILES_X86' => sub { $ENV{'ProgramFiles(x86)'} || $ENV{'ProgramFiles'} },
1061 # 'T-REPLACE-RX:'
1062 # 'T-CONV:'
1063 'DT_SIMPLE' => sub { localtime->strftime('%Y%m%d%H%M%S') },
1064 'DT_YEAR' => sub { localtime->strftime('%Y') },
1065 'DT_MONTH' => sub { localtime->strftime('%m') },
1066 'DT_DAY' => sub { localtime->strftime('%d') },
1067 'DT_HOUR' => sub { localtime->strftime('%H') },
1068 'DT_MINUTE' => sub { localtime->strftime('%M') },
1069 'DT_SECOND' => sub { localtime->strftime('%S') },
1070 'DT_UTC_SIMPLE' => sub { gmtime->strftime('%Y%m%d%H%M%S') },
1071 'DT_UTC_YEAR' => sub { gmtime->strftime('%Y') },
1072 'DT_UTC_MONTH' => sub { gmtime->strftime('%m') },
1073 'DT_UTC_DAY' => sub { gmtime->strftime('%d') },
1074 'DT_UTC_HOUR' => sub { gmtime->strftime('%H') },
1075 'DT_UTC_MINUTE' => sub { gmtime->strftime('%M') },
1076 'DT_UTC_SECOND' => sub { gmtime->strftime('%S') },
1077 # 'PICKCHARS'
1078 # 'PICKCHARS:'
1079 # 'PICKFIELD'
1080 # 'NEWPASSWORD'
1081 # 'NEWPASSWORD:'
1082 # 'PASSWORD_ENC'
1083 'HMACOTP' => sub { $_[0]->hmac_otp },
1084 'TIMEOTP' => sub { $_[0]->time_otp },
1085 'C:' => sub { '' }, # comment
1086 # 'BASE'
1087 # 'BASE:'
1088 # 'CLIPBOARD'
1089 # 'CLIPBOARD-SET:'
1090 # 'CMD:'
1091 );
1092
1093 ##############################################################################
1094
1095 =method lock
1096
1097 $kdbx->lock;
1098
1099 Encrypt all protected binaries strings in a database. The encrypted strings are stored in
1100 a L<File::KDBX::Safe> associated with the database and the actual strings will be replaced with C<undef> to
1101 indicate their protected state. Returns itself to allow method chaining.
1102
1103 =cut
1104
1105 sub _safe {
1106 my $self = shift;
1107 $SAFE{$self} = shift if @_;
1108 $SAFE{$self};
1109 }
1110
1111 sub _remove_safe { delete $SAFE{$_[0]} }
1112
1113 sub lock {
1114 my $self = shift;
1115
1116 $self->_safe and return $self;
1117
1118 my @strings;
1119
1120 my $entries = $self->all_entries(history => 1);
1121 for my $entry (@$entries) {
1122 push @strings, grep { $_->{protect} } values %{$entry->strings}, values %{$entry->binaries};
1123 }
1124
1125 $self->_safe(File::KDBX::Safe->new(\@strings));
1126
1127 return $self;
1128 }
1129
1130 =method unlock
1131
1132 $kdbx->unlock;
1133
1134 Decrypt all protected strings in a database, replacing C<undef> placeholders with unprotected values. Returns
1135 itself to allow method chaining.
1136
1137 =cut
1138
1139 sub unlock {
1140 my $self = shift;
1141 my $safe = $self->_safe or return $self;
1142
1143 $safe->unlock;
1144 $self->_remove_safe;
1145
1146 return $self;
1147 }
1148
1149 =method unlock_scoped
1150
1151 $guard = $kdbx->unlock_scoped;
1152
1153 Unlock a database temporarily, relocking when the guard is released (typically at the end of a scope). Returns
1154 C<undef> if the database is already unlocked.
1155
1156 See L</lock> and L</unlock>.
1157
1158 =cut
1159
1160 sub unlock_scoped {
1161 throw 'Programmer error: Cannot call unlock_scoped in void context' if !defined wantarray;
1162 my $self = shift;
1163 return if !$self->is_locked;
1164 require Scope::Guard;
1165 my $guard = Scope::Guard->new(sub { $self->lock });
1166 $self->unlock;
1167 return $guard;
1168 }
1169
1170 =method peek
1171
1172 $string = $kdbx->peek(\%string);
1173 $string = $kdbx->peek(\%binary);
1174
1175 Peek at the value of a protected string or binary without unlocking the whole database. The argument can be
1176 a string or binary hashref as returned by L<File::KDBX::Entry/string> or L<File::KDBX::Entry/binary>.
1177
1178 =cut
1179
1180 sub peek {
1181 my $self = shift;
1182 my $string = shift;
1183 my $safe = $self->_safe or return;
1184 return $safe->peek($string);
1185 }
1186
1187 =method is_locked
1188
1189 $bool = $kdbx->is_locked;
1190
1191 Get whether or not a database's strings are memory-protected. If this is true, then some or all of the
1192 protected strings within the database will be unavailable (literally have C<undef> values) until L</unlock> is
1193 called.
1194
1195 =cut
1196
1197 sub is_locked { $_[0]->_safe ? 1 : 0 }
1198
1199 ##############################################################################
1200
1201 =method randomize_seeds
1202
1203 $kdbx->randomize_seeds;
1204
1205 Set various keys, seeds and IVs to random values. These values are used by the cryptographic functions that
1206 secure the database when dumped. The attributes that will be randomized are:
1207
1208 =for :list
1209 * L</encryption_iv>
1210 * L</inner_random_stream_key>
1211 * L</master_seed>
1212 * L</stream_start_bytes>
1213 * L</transform_seed>
1214
1215 Randomizing these values has no effect on a loaded database. These are only used when a database is dumped.
1216 You normally do not need to call this method explicitly because the dumper does it explicitly by default.
1217
1218 =cut
1219
1220 sub randomize_seeds {
1221 my $self = shift;
1222 $self->encryption_iv(random_bytes(16));
1223 $self->inner_random_stream_key(random_bytes(64));
1224 $self->master_seed(random_bytes(32));
1225 $self->stream_start_bytes(random_bytes(32));
1226 $self->transform_seed(random_bytes(32));
1227 }
1228
1229 ##############################################################################
1230
1231 =method key
1232
1233 $key = $kdbx->key;
1234 $key = $kdbx->key($key);
1235 $key = $kdbx->key($primitive);
1236
1237 Get or set a L<File::KDBX::Key>. This is the master key (e.g. a password or a key file that can decrypt
1238 a database). See L<File::KDBX::Key/new> for an explanation of what the primitive can be.
1239
1240 You generally don't need to call this directly because you can provide the key directly to the loader or
1241 dumper when loading or dumping a KDBX file.
1242
1243 =cut
1244
1245 sub key {
1246 my $self = shift;
1247 $KEYS{$self} = File::KDBX::Key->new(@_) if @_;
1248 $KEYS{$self};
1249 }
1250
1251 =method composite_key
1252
1253 $key = $kdbx->composite_key($key);
1254 $key = $kdbx->composite_key($primitive);
1255
1256 Construct a L<File::KDBX::Key::Composite> from a primitive. See L<File::KDBX::Key/new> for an explanation of
1257 what the primitive can be. If the primitive does not represent a composite key, it will be wrapped.
1258
1259 You generally don't need to call this directly. The parser and writer use it to transform a master key into
1260 a raw encryption key.
1261
1262 =cut
1263
1264 sub composite_key {
1265 my $self = shift;
1266 require File::KDBX::Key::Composite;
1267 return File::KDBX::Key::Composite->new(@_);
1268 }
1269
1270 =method kdf
1271
1272 $kdf = $kdbx->kdf(%options);
1273 $kdf = $kdbx->kdf(\%parameters, %options);
1274
1275 Get a L<File::KDBX::KDF> (key derivation function).
1276
1277 Options:
1278
1279 =for :list
1280 * C<params> - KDF parameters, same as C<\%parameters> (default: value of L</kdf_parameters>)
1281
1282 =cut
1283
1284 sub kdf {
1285 my $self = shift;
1286 my %args = @_ % 2 == 1 ? (params => shift, @_) : @_;
1287
1288 my $params = $args{params};
1289 my $compat = $args{compatible} // 1;
1290
1291 $params //= $self->kdf_parameters;
1292 $params = {%{$params || {}}};
1293
1294 if (empty $params || !defined $params->{+KDF_PARAM_UUID}) {
1295 $params->{+KDF_PARAM_UUID} = KDF_UUID_AES;
1296 }
1297 if ($params->{+KDF_PARAM_UUID} eq KDF_UUID_AES) {
1298 # AES_CHALLENGE_RESPONSE is equivalent to AES if there are no challenge-response keys, and since
1299 # non-KeePassXC implementations don't support challenge-response keys anyway, there's no problem with
1300 # always using AES_CHALLENGE_RESPONSE for all KDBX4+ databases.
1301 # For compatibility, we should not *write* AES_CHALLENGE_RESPONSE, but the dumper handles that.
1302 if ($self->version >= KDBX_VERSION_4_0) {
1303 $params->{+KDF_PARAM_UUID} = KDF_UUID_AES_CHALLENGE_RESPONSE;
1304 }
1305 $params->{+KDF_PARAM_AES_SEED} //= $self->transform_seed;
1306 $params->{+KDF_PARAM_AES_ROUNDS} //= $self->transform_rounds;
1307 }
1308
1309 require File::KDBX::KDF;
1310 return File::KDBX::KDF->new(%$params);
1311 }
1312
1313 sub transform_seed {
1314 my $self = shift;
1315 $self->headers->{+HEADER_TRANSFORM_SEED} =
1316 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_SEED} = shift if @_;
1317 $self->headers->{+HEADER_TRANSFORM_SEED} =
1318 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_SEED} //= random_bytes(32);
1319 }
1320
1321 sub transform_rounds {
1322 my $self = shift;
1323 $self->headers->{+HEADER_TRANSFORM_ROUNDS} =
1324 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_ROUNDS} = shift if @_;
1325 $self->headers->{+HEADER_TRANSFORM_ROUNDS} =
1326 $self->headers->{+HEADER_KDF_PARAMETERS}{+KDF_PARAM_AES_ROUNDS} //= 100_000;
1327 }
1328
1329 =method cipher
1330
1331 $cipher = $kdbx->cipher(key => $key);
1332 $cipher = $kdbx->cipher(key => $key, iv => $iv, uuid => $uuid);
1333
1334 Get a L<File::KDBX::Cipher> capable of encrypting and decrypting the body of a database file.
1335
1336 A key is required. This should be a raw encryption key made up of a fixed number of octets (depending on the
1337 cipher), not a L<File::KDBX::Key> or primitive.
1338
1339 If not passed, the UUID comes from C<< $kdbx->headers->{cipher_id} >> and the encryption IV comes from
1340 C<< $kdbx->headers->{encryption_iv} >>.
1341
1342 You generally don't need to call this directly. The parser and writer use it to decrypt and encrypt KDBX
1343 files.
1344
1345 =cut
1346
1347 sub cipher {
1348 my $self = shift;
1349 my %args = @_;
1350
1351 $args{uuid} //= $self->headers->{+HEADER_CIPHER_ID};
1352 $args{iv} //= $self->headers->{+HEADER_ENCRYPTION_IV};
1353
1354 require File::KDBX::Cipher;
1355 return File::KDBX::Cipher->new(%args);
1356 }
1357
1358 =method random_stream
1359
1360 $cipher = $kdbx->random_stream;
1361 $cipher = $kdbx->random_stream(id => $stream_id, key => $key);
1362
1363 Get a L<File::KDBX::Cipher::Stream> for decrypting and encrypting protected values.
1364
1365 If not passed, the ID and encryption key comes from C<< $kdbx->headers->{inner_random_stream_id} >> and
1366 C<< $kdbx->headers->{inner_random_stream_key} >> (respectively) for KDBX3 files and from
1367 C<< $kdbx->inner_headers->{inner_random_stream_key} >> and
1368 C<< $kdbx->inner_headers->{inner_random_stream_id} >> (respectively) for KDBX4 files.
1369
1370 You generally don't need to call this directly. The parser and writer use it to scramble protected strings.
1371
1372 =cut
1373
1374 sub random_stream {
1375 my $self = shift;
1376 my %args = @_;
1377
1378 $args{stream_id} //= delete $args{id} // $self->inner_random_stream_id;
1379 $args{key} //= $self->inner_random_stream_key;
1380
1381 require File::KDBX::Cipher;
1382 File::KDBX::Cipher->new(%args);
1383 }
1384
1385 sub inner_random_stream_id {
1386 my $self = shift;
1387 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_ID}
1388 = $self->headers->{+HEADER_INNER_RANDOM_STREAM_ID} = shift if @_;
1389 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_ID}
1390 //= $self->headers->{+HEADER_INNER_RANDOM_STREAM_ID} //= do {
1391 my $version = $self->minimum_version;
1392 $version < KDBX_VERSION_4_0 ? STREAM_ID_SALSA20 : STREAM_ID_CHACHA20;
1393 };
1394 }
1395
1396 sub inner_random_stream_key {
1397 my $self = shift;
1398 if (@_) {
1399 # These are probably the same SvPV so erasing one will CoW, but erasing the second should do the
1400 # trick anyway.
1401 erase \$self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY};
1402 erase \$self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY};
1403 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY}
1404 = $self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY} = shift;
1405 }
1406 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY}
1407 //= $self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY} //= random_bytes(64); # 32
1408 }
1409
1410 #########################################################################################
1411
1412 # sub check {
1413 # - Fixer tool. Can repair inconsistencies, including:
1414 # - Orphaned binaries... not really a thing anymore since we now distribute binaries amongst entries
1415 # - Unused custom icons (OFF, data loss)
1416 # - Duplicate icons
1417 # - All data types are valid
1418 # - date times are correct
1419 # - boolean fields
1420 # - All UUIDs refer to things that exist
1421 # - previous parent group
1422 # - recycle bin
1423 # - last selected group
1424 # - last visible group
1425 # - Enforce history size limits (ON)
1426 # - Check headers/meta (ON)
1427 # - Duplicate deleted objects (ON)
1428 # - Duplicate window associations (OFF)
1429 # - Only one root group (ON)
1430 # - Header UUIDs match known ciphers/KDFs?
1431 # }
1432
1433 #########################################################################################
1434
1435 sub _handle_signal {
1436 my $self = shift;
1437 my $object = shift;
1438 my $type = shift;
1439
1440 my %handlers = (
1441 'entry.uuid.changed' => \&_handle_entry_uuid_changed,
1442 'group.uuid.changed' => \&_handle_group_uuid_changed,
1443 'entry.uuid.removed' => \&_handle_object_removed,
1444 'group.uuid.removed' => \&_handle_object_removed,
1445 );
1446 my $handler = $handlers{$type} or return;
1447 $self->$handler($object, @_);
1448 }
1449
1450 sub _handle_group_uuid_changed {
1451 my $self = shift;
1452 my $object = shift;
1453 my $new_uuid = shift;
1454 my $old_uuid = shift // return;
1455
1456 my $meta = $self->meta;
1457 $self->recycle_bin_uuid($new_uuid) if $old_uuid eq ($meta->{recycle_bin_uuid} // '');
1458 $self->entry_templates_group($new_uuid) if $old_uuid eq ($meta->{entry_templates_group} // '');
1459 $self->last_selected_group($new_uuid) if $old_uuid eq ($meta->{last_selected_group} // '');
1460 $self->last_top_visible_group($new_uuid) if $old_uuid eq ($meta->{last_top_visible_group} // '');
1461
1462 for my $group (@{$self->all_groups}) {
1463 $group->last_top_visible_entry($new_uuid) if $old_uuid eq ($group->{last_top_visible_entry} // '');
1464 $group->previous_parent_group($new_uuid) if $old_uuid eq ($group->{previous_parent_group} // '');
1465 }
1466 for my $entry (@{$self->all_entries}) {
1467 $entry->previous_parent_group($new_uuid) if $old_uuid eq ($entry->{previous_parent_group} // '');
1468 }
1469 }
1470
1471 sub _handle_entry_uuid_changed {
1472 my $self = shift;
1473 my $object = shift;
1474 my $new_uuid = shift;
1475 my $old_uuid = shift // return;
1476
1477 my $old_pretty = format_uuid($old_uuid);
1478 my $new_pretty = format_uuid($new_uuid);
1479 my $fieldref_match = qr/\{REF:([TUPANI])\@I:\Q$old_pretty\E\}/is;
1480
1481 for my $entry (@{$self->all_entries}) {
1482 $entry->previous_parent_group($new_uuid) if $old_uuid eq ($entry->{previous_parent_group} // '');
1483
1484 for my $string (values %{$entry->strings}) {
1485 next if !defined $string->{value} || $string->{value} !~ $fieldref_match;
1486 my $txn = $entry->begin_work;
1487 $string->{value} =~ s/$fieldref_match/{REF:$1\@I:$new_pretty}/g;
1488 $txn->commit;
1489 }
1490 }
1491 }
1492
1493 sub _handle_object_removed {
1494 my $self = shift;
1495 my $object = shift;
1496 $self->add_delete_object($object->uuid);
1497 }
1498
1499 #########################################################################################
1500
1501 =attr comment
1502
1503 A text string associated with the database. Often unset.
1504
1505 =attr cipher_id
1506
1507 The UUID of a cipher used to encrypt the database when stored as a file.
1508
1509 See L</File::KDBX::Cipher>.
1510
1511 =attr compression_flags
1512
1513 Configuration for whether or not and how the database gets compressed. See
1514 L<File::KDBX::Constants/":compression">.
1515
1516 =attr master_seed
1517
1518 The master seed is a string of 32 random bytes that is used as salt in hashing the master key when loading
1519 and saving the database. If a challenge-response key is used in the master key, the master seed is also the
1520 challenge.
1521
1522 The master seed I<should> be changed each time the database is saved to file.
1523
1524 =attr transform_seed
1525
1526 The transform seed is a string of 32 random bytes that is used in the key derivation function, either as the
1527 salt or the key (depending on the algorithm).
1528
1529 The transform seed I<should> be changed each time the database is saved to file.
1530
1531 =attr transform_rounds
1532
1533 The number of rounds or iterations used in the key derivation function. Increasing this number makes loading
1534 and saving the database slower by design in order to make dictionary and brute force attacks more costly.
1535
1536 =attr encryption_iv
1537
1538 The initialization vector used by the cipher.
1539
1540 The encryption IV I<should> be changed each time the database is saved to file.
1541
1542 =attr inner_random_stream_key
1543
1544 The encryption key (possibly including the IV, depending on the cipher) used to encrypt the protected strings
1545 within the database.
1546
1547 =attr stream_start_bytes
1548
1549 A string of 32 random bytes written in the header and encrypted in the body. If the bytes do not match when
1550 loading a file then the wrong master key was used or the file is corrupt. Only KDBX 2 and KDBX 3 files use
1551 this. KDBX 4 files use an improved HMAC method to verify the master key and data integrity of the header and
1552 entire file body.
1553
1554 =attr inner_random_stream_id
1555
1556 A number indicating the cipher algorithm used to encrypt the protected strings within the database, usually
1557 Salsa20 or ChaCha20. See L<File::KDBX::Constants/":random_stream">.
1558
1559 =attr kdf_parameters
1560
1561 A hash/dict of key-value pairs used to configure the key derivation function. This is the KDBX4+ way to
1562 configure the KDF, superceding L</transform_seed> and L</transform_rounds>.
1563
1564 =attr generator
1565
1566 The name of the software used to generate the KDBX file.
1567
1568 =attr header_hash
1569
1570 The header hash used to verify that the file header is not corrupt. (KDBX 2 - KDBX 3.1, removed KDBX 4.0)
1571
1572 =attr database_name
1573
1574 Name of the database.
1575
1576 =attr database_name_changed
1577
1578 Timestamp indicating when the database name was last changed.
1579
1580 =attr database_description
1581
1582 Description of the database
1583
1584 =attr database_description_changed
1585
1586 Timestamp indicating when the database description was last changed.
1587
1588 =attr default_username
1589
1590 When a new entry is created, the I<UserName> string will be populated with this value.
1591
1592 =attr default_username_changed
1593
1594 Timestamp indicating when the default username was last changed.
1595
1596 =attr maintenance_history_days
1597
1598 TODO... not really sure what this is. 😀
1599
1600 =attr color
1601
1602 A color associated with the database (in the form C<#ffffff> where "f" is a hexidecimal digit). Some agents
1603 use this to help users visually distinguish between different databases.
1604
1605 =attr master_key_changed
1606
1607 Timestamp indicating when the master key was last changed.
1608
1609 =attr master_key_change_rec
1610
1611 Number of days until the agent should prompt to recommend changing the master key.
1612
1613 =attr master_key_change_force
1614
1615 Number of days until the agent should prompt to force changing the master key.
1616
1617 Note: This is purely advisory. It is up to the individual agent software to actually enforce it.
1618 C<File::KDBX> does NOT enforce it.
1619
1620 =attr recycle_bin_enabled
1621
1622 Boolean indicating whether removed groups and entries should go to a recycle bin or be immediately deleted.
1623
1624 =attr recycle_bin_uuid
1625
1626 The UUID of a group used to store thrown-away groups and entries.
1627
1628 =attr recycle_bin_changed
1629
1630 Timestamp indicating when the recycle bin was last changed.
1631
1632 =attr entry_templates_group
1633
1634 The UUID of a group containing template entries used when creating new entries.
1635
1636 =attr entry_templates_group_changed
1637
1638 Timestamp indicating when the entry templates group was last changed.
1639
1640 =attr last_selected_group
1641
1642 The UUID of the previously-selected group.
1643
1644 =attr last_top_visible_group
1645
1646 The UUID of the group visible at the top of the list.
1647
1648 =attr history_max_items
1649
1650 The maximum number of historical entries allowed to be saved for each entry.
1651
1652 =attr history_max_size
1653
1654 The maximum total size (in bytes) that each individual entry's history is allowed to grow.
1655
1656 =attr settings_changed
1657
1658 Timestamp indicating when the database settings were last updated.
1659
1660 =attr protect_title
1661
1662 Alias of the L</memory_protection> setting for the I<Title> string.
1663
1664 =attr protect_username
1665
1666 Alias of the L</memory_protection> setting for the I<UserName> string.
1667
1668 =attr protect_password
1669
1670 Alias of the L</memory_protection> setting for the I<Password> string.
1671
1672 =attr protect_url
1673
1674 Alias of the L</memory_protection> setting for the I<URL> string.
1675
1676 =attr protect_notes
1677
1678 Alias of the L</memory_protection> setting for the I<Notes> string.
1679
1680 =cut
1681
1682 #########################################################################################
1683
1684 sub TO_JSON { +{%{$_[0]}} }
1685
1686 1;
1687 __END__
1688
1689 =for Pod::Coverage STORABLE_freeze STORABLE_thaw TO_JSON
1690
1691 =head1 SYNOPSIS
1692
1693 use File::KDBX;
1694
1695 my $kdbx = File::KDBX->new;
1696
1697 my $group = $kdbx->add_group(
1698 name => 'Passwords',
1699 );
1700
1701 my $entry = $group->add_entry(
1702 title => 'My Bank',
1703 password => 's3cr3t',
1704 );
1705
1706 $kdbx->dump_file('passwords.kdbx', 'M@st3rP@ssw0rd!');
1707
1708 $kdbx = File::KDBX->load_file('passwords.kdbx', 'M@st3rP@ssw0rd!');
1709
1710 for my $entry (@{ $kdbx->all_entries }) {
1711 say 'Entry: ', $entry->title;
1712 }
1713
1714 =head1 DESCRIPTION
1715
1716 B<File::KDBX> provides everything you need to work with a KDBX database. A KDBX database is a hierarchical
1717 object database which is commonly used to store secret information securely. It was developed for the KeePass
1718 password safe. See L</"KDBX Introduction"> for more information about KDBX.
1719
1720 This module lets you query entries, create new entries, delete entries and modify entries. The distribution
1721 also includes various parsers and generators for serializing and persisting databases.
1722
1723 This design of this software was influenced by the L<KeePassXC|https://github.com/keepassxreboot/keepassxc>
1724 implementation of KeePass as well as the L<File::KeePass> module. B<File::KeePass> is an alternative module
1725 that works well in most cases but has a small backlog of bugs and security issues and also does not work with
1726 newer KDBX version 4 files. If you're coming here from the B<File::KeePass> world, you might be interested in
1727 L<File::KeePass::KDBX> that is a drop-in replacement for B<File::KeePass> that uses B<File::KDBX> for storage.
1728
1729 =head2 KDBX Introduction
1730
1731 A KDBX database consists of a hierarchical I<group> of I<entries>. Entries can contain zero or more key-value
1732 pairs of I<strings> and zero or more I<binaries> (i.e. octet strings). Groups, entries, strings and binaries:
1733 that's the KDBX vernacular. A small amount of metadata (timestamps, etc.) is associated with each entry, group
1734 and the database as a whole.
1735
1736 You can think of a KDBX database kind of like a file system, where groups are directories, entries are files,
1737 and strings and binaries make up a file's contents.
1738
1739 Databases are typically persisted as a encrypted, compressed files. They are usually accessed directly (i.e.
1740 not over a network). The primary focus of this type of database is data security. It is ideal for storing
1741 relatively small amounts of data (strings and binaries) that must remain secret except to such individuals as
1742 have the correct I<master key>. Even if the database file were to be "leaked" to the public Internet, it
1743 should be virtually impossible to crack with a strong key. See L</SECURITY> for an overview of security
1744 considerations.
1745
1746 =head1 RECIPES
1747
1748 =head2 Create a new database
1749
1750 my $kdbx = File::KDBX->new;
1751
1752 my $group = $kdbx->add_group(name => 'Passwords);
1753 my $entry = $group->add_entry(
1754 title => 'WayneCorp',
1755 username => 'bwayne',
1756 password => 'iambatman',
1757 url => 'https://example.com/login'
1758 );
1759 $entry->add_auto_type_window_association('WayneCorp - Mozilla Firefox', '{PASSWORD}{ENTER}');
1760
1761 $kdbx->dump_file('mypasswords.kdbx', 'master password CHANGEME');
1762
1763 =head2 Read an existing database
1764
1765 my $kdbx = File::KDBX->load_file('mypasswords.kdbx', 'master password CHANGEME');
1766 $kdbx->unlock;
1767
1768 for my $entry (@{ $kdbx->all_entries }) {
1769 say 'Found password for ', $entry->title, ':';
1770 say ' Username: ', $entry->username;
1771 say ' Password: ', $entry->password;
1772 }
1773
1774 =head2 Search for entries
1775
1776 my @entries = $kdbx->find_entries({
1777 title => 'WayneCorp',
1778 }, search => 1);
1779
1780 See L</QUERY> for many more query examples.
1781
1782 =head2 Search for entries by auto-type window association
1783
1784 my @entry_key_sequences = $kdbx->find_entries_for_window('WayneCorp - Mozilla Firefox');
1785 for my $pair (@entry_key_sequences) {
1786 my ($entry, $key_sequence) = @$pair;
1787 say 'Entry title: ', $entry->title, ', key sequence: ', $key_sequence;
1788 }
1789
1790 Example output:
1791
1792 Entry title: WayneCorp, key sequence: {PASSWORD}{ENTER}
1793
1794 =head1 SECURITY
1795
1796 One of the biggest threats to your database security is how easily the encryption key can be brute-forced.
1797 Strong brute-force protection depends on a couple factors:
1798
1799 =for :list
1800 * Using unguessable passwords, passphrases and key files.
1801 * Using a brute-force resistent key derivation function.
1802
1803 The first factor is up to you. This module does not enforce strong master keys. It is up to you to pick or
1804 generate strong keys.
1805
1806 The KDBX format allows for the key derivation function to be tuned. The idea is that you want each single
1807 brute-foce attempt to be expensive (in terms of time, CPU usage or memory usage), so that making a lot of
1808 attempts (which would be required if you have a strong master key) gets I<really> expensive.
1809
1810 How expensive you want to make each attempt is up to you and can depend on the application.
1811
1812 This and other KDBX-related security issues are covered here more in depth:
1813 L<https://keepass.info/help/base/security.html>
1814
1815 Here are other security risks you should be thinking about:
1816
1817 =head2 Cryptography
1818
1819 This distribution uses the excellent L<CryptX> and L<Crypt::Argon2> packages to handle all crypto-related
1820 functions. As such, a lot of the security depends on the quality of these dependencies. Fortunately these
1821 modules are maintained and appear to have good track records.
1822
1823 The KDBX format has evolved over time to incorporate improved security practices and cryptographic functions.
1824 This package uses the following functions for authentication, hashing, encryption and random number
1825 generation:
1826
1827 =for :list
1828 * AES-128 (legacy)
1829 * AES-256
1830 * Argon2d & Argon2id
1831 * CBC block mode
1832 * HMAC-SHA256
1833 * SHA256
1834 * SHA512
1835 * Salsa20 & ChaCha20
1836 * Twofish
1837
1838 At the time of this writing, I am not aware of any successful attacks against any of these functions. These
1839 are among the most-analyzed and widely-adopted crypto functions available.
1840
1841 The KDBX format allows the body cipher and key derivation function to be configured. If a flaw is discovered
1842 in one of these functions, you can hopefully just switch to a better function without needing to update this
1843 software. A later software release may phase out the use of any functions which are no longer secure.
1844
1845 =head2 Memory Protection
1846
1847 It is not a good idea to keep secret information unencrypted in system memory for longer than is needed. The
1848 address space of your program can generally be read by a user with elevated privileges on the system. If your
1849 system is memory-constrained or goes into a hibernation mode, the contents of your address space could be
1850 written to a disk where it might be persisted for long time.
1851
1852 There might be system-level things you can do to reduce your risk, like using swap encryption and limiting
1853 system access to your program's address space while your program is running.
1854
1855 B<File::KDBX> helps minimize (but not eliminate) risk by keeping secrets encrypted in memory until accessed
1856 and zeroing out memory that holds secrets after they're no longer needed, but it's not a silver bullet.
1857
1858 For one thing, the encryption key is stored in the same address space. If core is dumped, the encryption key
1859 is available to be found out. But at least there is the chance that the encryption key and the encrypted
1860 secrets won't both be paged out while memory-constrained.
1861
1862 Another problem is that some perls (somewhat notoriously) copy around memory behind the scenes willy nilly,
1863 and it's difficult know when perl makes a copy of a secret in order to be able to zero it out later. It might
1864 be impossible. The good news is that perls with SvPV copy-on-write (enabled by default beginning with perl
1865 5.20) are much better in this regard. With COW, it's mostly possible to know what operations will cause perl
1866 to copy the memory of a scalar string, and the number of copies will be significantly reduced. There is a unit
1867 test named F<t/memory-protection.t> in this distribution that can be run on POSIX systems to determine how
1868 well B<File::KDBX> memory protection is working.
1869
1870 Memory protection also depends on how your application handles secrets. If your app code is handling scalar
1871 strings with secret information, it's up to you to make sure its memory is zeroed out when no longer needed.
1872 L<File::KDBX::Util/erase> et al. provide some tools to help accomplish this. Or if you're not too concerned
1873 about the risks memory protection is meant to mitigate, then maybe don't worry about it. The security policy
1874 of B<File::KDBX> is to try hard to keep secrets protected while in memory so that your app might claim a high
1875 level of security, in case you care about that.
1876
1877 There are some memory protection strategies that B<File::KDBX> does NOT use today but could in the future:
1878
1879 Many systems allow programs to mark unswappable pages. Secret information should ideally be stored in such
1880 pages. You could potentially use L<mlockall(2)> (or equivalent for your system) in your own application to
1881 prevent the entire address space from being swapped.
1882
1883 Some systems provide special syscalls for storing secrets in memory while keeping the encryption key outside
1884 of the program's address space, like C<CryptProtectMemory> for Windows. This could be a good option, though
1885 unfortunately not portable.
1886
1887 =head1 QUERY
1888
1889 Several methods take a I<query> as an argument (e.g. L</find_entries>). A query is just a subroutine that you
1890 can either write yourself or have generated for you based on either a simple expression or a declarative
1891 structure. It's easier to have your query generated, so I'll cover that first.
1892
1893 =head2 Simple Expression
1894
1895 A simple expression is mostly compatible with the KeePass 2 implementation
1896 L<described here|https://keepass.info/help/base/search.html#mode_se>.
1897
1898 An expression is a string with one or more space-separated terms. Terms with spaces can be enclosed in double
1899 quotes. Terms are negated if they are prefixed with a minus sign. A record must match every term on at least
1900 one of the given fields.
1901
1902 So a simple expression is something like what you might type into a search engine. You can generate a simple
1903 expression query using L<File::KDBX::Util/simple_expression_query> or by passing the simple expression as
1904 a B<string reference> to search methods like L</find_entries>.
1905
1906 To search for all entries in a database with the word "canyon" appearing anywhere in the title:
1907
1908 my @entries = $kdbx->find_entries([ \'canyon', qw(title) ]);
1909
1910 Notice the first argument is a B<stringref>. This diambiguates a simple expression from other types of queries
1911 covered below.
1912
1913 As mentioned, a simple expression can have multiple terms. This simple expression query matches any entry that
1914 has the words "red" B<and> "canyon" anywhere in the title:
1915
1916 my @entries = $kdbx->find_entries([ \'red canyon', qw(title) ]);
1917
1918 Each term in the simple expression must be found for an entry to match.
1919
1920 To search for entries with "red" in the title but B<not> "canyon", just prepend "canyon" with a minus sign:
1921
1922 my @entries = $kdbx->find_entries([ \'red -canyon', qw(title) ]);
1923
1924 To search over multiple fields simultaneously, just list them. To search for entries with "grocery" in the
1925 title or notes but not "Foodland":
1926
1927 my @entries = $kdbx->find_entries([ \'grocery -Foodland', qw(title notes) ]);
1928
1929 The default operator is a case-insensitive regexp match, which is fine for searching text loosely. You can use
1930 just about any binary comparison operator that perl supports. To specify an operator, list it after the simple
1931 expression. For example, to search for any entry that has been used at least five times:
1932
1933 my @entries = $kdbx->find_entries([ \5, '>=', qw(usage_count) ]);
1934
1935 It helps to read it right-to-left, like "usage_count is >= 5".
1936
1937 If you find the disambiguating structures to be confusing, you can also the L</find_entries_simple> method as
1938 a more intuitive alternative. The following example is equivalent to the previous:
1939
1940 my @entries = $kdbx->find_entries_simple(5, '>=', qw(usage_count));
1941
1942 =head2 Declarative Query
1943
1944 Structuring a declarative query is similar to L<SQL::Abstract/"WHERE CLAUSES">, but you don't have to be
1945 familiar with that module. Just learn by examples.
1946
1947 To search for all entries in a database titled "My Bank":
1948
1949 my @entries = $kdbx->find_entries({ title => 'My Bank' });
1950
1951 The query here is C<< { title => 'My Bank' } >>. A hashref can contain key-value pairs where the key is
1952 a attribute of the thing being searched for (in this case an entry) and the value is what you want the thing's
1953 attribute to be to consider it a match. In this case, the attribute we're using as our match criteria is
1954 L<File::KDBX::Entry/title>, a text field. If an entry has its title attribute equal to "My Bank", it's
1955 a match.
1956
1957 A hashref can contain multiple attributes. The search candidate will be a match if I<all> of the specified
1958 attributes are equal to their respective values. For example, to search for all entries with a particular URL
1959 B<AND> username:
1960
1961 my @entries = $kdbx->find_entries({
1962 url => 'https://example.com',
1963 username => 'neo',
1964 });
1965
1966 To search for entries matching I<any> criteria, just change the hashref to an arrayref. To search for entries
1967 with a particular URL B<OR> a particular username:
1968
1969 my @entries = $kdbx->find_entries([ # <-- square bracket
1970 url => 'https://example.com',
1971 username => 'neo',
1972 ]);
1973
1974 You can user different operators to test different types of attributes. The L<File::KDBX::Entry/icon_id>
1975 attribute is a number, so we should use a number comparison operator. To find entries using the smartphone
1976 icon:
1977
1978 my @entries = $kdbx->find_entries({
1979 icon_id => { '==', ICON_SMARTPHONE },
1980 });
1981
1982 Note: L<File::KDBX::Constants/ICON_SMARTPHONE> is just a constant from L<File::KDBX::Constants>. It isn't
1983 special to this example or to queries generally. We could have just used a literal number.
1984
1985 The important thing to notice here is how we wrapped the condition in another arrayref with a single key-pair
1986 where the key is the name of an operator and the value is the thing to match against. The supported operators
1987 are:
1988
1989 =for :list
1990 * C<eq> - String equal
1991 * C<ne> - String not equal
1992 * C<lt> - String less than
1993 * C<gt> - String greater than
1994 * C<le> - String less than or equal
1995 * C<ge> - String greater than or equal
1996 * C<==> - Number equal
1997 * C<!=> - Number not equal
1998 * C<< < >> - Number less than
1999 * C<< > >>> - Number greater than
2000 * C<< <= >> - Number less than or equal
2001 * C<< >= >> - Number less than or equal
2002 * C<=~> - String match regular expression
2003 * C<!~> - String does not match regular expression
2004 * C<!> - Boolean false
2005 * C<!!> - Boolean true
2006
2007 Other special operators:
2008
2009 =for :list
2010 * C<-true> - Boolean true
2011 * C<-false> - Boolean false
2012 * C<-not> - Boolean false (alias for C<-false>)
2013 * C<-defined> - Is defined
2014 * C<-undef> - Is not d efined
2015 * C<-empty> - Is empty
2016 * C<-nonempty> - Is not empty
2017 * C<-or> - Logical or
2018 * C<-and> - Logical and
2019
2020 Let's see another example using an explicit operator. To find all groups except one in particular (identified
2021 by its L<File::KDBX::Group/uuid>), we can use the C<ne> (string not equal) operator:
2022
2023 my ($group, @other) = $kdbx->find_groups({
2024 uuid => {
2025 'ne' => uuid('596f7520-6172-6520-7370-656369616c2e'),
2026 },
2027 });
2028 if (@other) { say "Problem: there can be only one!" }
2029
2030 Note: L<File::KDBX::Util/uuid> is a little helper function to convert a UUID in its pretty form into octets.
2031 This helper function isn't special to this example or to queries generally. It could have been written with
2032 a literal such as C<"\x59\x6f\x75\x20\x61...">, but that's harder to read.
2033
2034 Notice we searched for groups this time. Finding groups works exactly the same as it does for entries.
2035
2036 Testing the truthiness of an attribute is a little bit different because it isn't a binary operation. To find
2037 all entries with the password quality check disabled:
2038
2039 my @entries = $kdbx->find_entries({ '!' => 'quality_check' });
2040
2041 This time the string after the operator is the attribute name rather than a value to compare the attribute
2042 against. To test that a boolean value is true, use the C<!!> operator (or C<-true> if C<!!> seems a little too
2043 weird for your taste):
2044
2045 my @entries = $kdbx->find_entries({ '!!' => 'quality_check' });
2046 my @entries = $kdbx->find_entries({ -true => 'quality_check' });
2047
2048 Yes, there is also a C<-false> and a C<-not> if you prefer one of those over C<!>. C<-false> and C<-not>
2049 (along with C<-true>) are also special in that you can use them to invert the logic of a subquery. These are
2050 logically equivalent:
2051
2052 my @entries = $kdbx->find_entries([ -not => { title => 'My Bank' } ]);
2053 my @entries = $kdbx->find_entries({ title => { 'ne' => 'My Bank' } });
2054
2055 These special operators become more useful when combined with two more special operators: C<-and> and C<-or>.
2056 With these, it is possible to construct more interesting queries with groups of logic. For example:
2057
2058 my @entries = $kdbx->find_entries({
2059 title => { '=~', qr/bank/ },
2060 -not => {
2061 -or => {
2062 notes => { '=~', qr/business/ },
2063 icon_id => { '==', ICON_TRASHCAN_FULL },
2064 },
2065 },
2066 });
2067
2068 In English, find entries where the word "bank" appears anywhere in the title but also do not have either the
2069 word "business" in the notes or is using the full trashcan icon.
2070
2071 =head2 Subroutine Query
2072
2073 Lastly, as mentioned at the top, you can ignore all this and write your own subroutine. Your subroutine will
2074 be called once for each thing being searched over. The single argument is the search candidate. The subroutine
2075 should match the candidate against whatever criteria you want and return true if it matches. The C<find_*>
2076 methods collect all matching things and return them.
2077
2078 For example, to find all entries in the database titled "My Bank":
2079
2080 my @entries = $kdbx->find_entries(sub { shift->title eq 'My Bank' });
2081 # logically the same as this declarative structure:
2082 my @entries = $kdbx->find_entries({ title => 'My Bank' });
2083 # as well as this simple expression:
2084 my @entries = $kdbx->find_entries([ \'My Bank', 'eq', qw{title} ]);
2085
2086 This is a trivial example, but of course your subroutine can be arbitrarily complex.
2087
2088 All of these query mechanisms described in this section are just tools, each with its own set of limitations.
2089 If the tools are getting in your way, you can of course iterate over the contents of a database and implement
2090 your own query logic, like this:
2091
2092 for my $entry (@{ $kdbx->all_entries }) {
2093 if (wanted($entry)) {
2094 do_something($entry);
2095 }
2096 else {
2097 ...
2098 }
2099 }
2100
2101 =head1 ERRORS
2102
2103 Errors in this package are constructed as L<File::KDBX::Error> objects and propagated using perl's built-in
2104 mechanisms. Fatal errors are propagated using L<functions/die> and non-fatal errors (a.k.a. warnings) are
2105 propagated using L<functions/warn> while adhering to perl's L<warnings> system. If you're already familiar
2106 with these mechanisms, you can skip this section.
2107
2108 You can catch fatal errors using L<functions/eval> (or something like L<Try::Tiny>) and non-fatal errors using
2109 C<$SIG{__WARN__}> (see L<variables/%SIG>). Examples:
2110
2111 use File::KDBX::Error qw(error);
2112
2113 my $key = ''; # uh oh
2114 eval {
2115 $kdbx->load_file('whatever.kdbx', $key);
2116 };
2117 if (my $error = error($@)) {
2118 handle_missing_key($error) if $error->type eq 'key.missing';
2119 $error->throw;
2120 }
2121
2122 or using C<Try::Tiny>:
2123
2124 try {
2125 $kdbx->load_file('whatever.kdbx', $key);
2126 }
2127 catch {
2128 handle_error($_);
2129 };
2130
2131 Catching non-fatal errors:
2132
2133 my @warnings;
2134 local $SIG{__WARN__} = sub { push @warnings, $_[0] };
2135
2136 $kdbx->load_file('whatever.kdbx', $key);
2137
2138 handle_warnings(@warnings) if @warnings;
2139
2140 By default perl prints warnings to C<STDERR> if you don't catch them. If you don't want to catch them and also
2141 don't want them printed to C<STDERR>, you can suppress them lexically (perl v5.28 or higher required):
2142
2143 {
2144 no warnings 'File::KDBX';
2145 ...
2146 }
2147
2148 or locally:
2149
2150 {
2151 local $File::KDBX::WARNINGS = 0;
2152 ...
2153 }
2154
2155 or globally in your program:
2156
2157 $File::KDBX::WARNINGS = 0;
2158
2159 You cannot suppress fatal errors, and if you don't catch them your program will exit.
2160
2161 =head1 ENVIRONMENT
2162
2163 This software will alter its behavior depending on the value of certain environment variables:
2164
2165 =for :list
2166 * C<PERL_FILE_KDBX_XS> - Do not use L<File::KDBX::XS> if false (default: true)
2167 * C<PERL_ONLY> - Do not use L<File::KDBX::XS> if true (default: false)
2168 * C<NO_FORK> - Do not fork if true (default: false)
2169
2170 =head1 CAVEATS
2171
2172 Some features (e.g. parsing) require 64-bit perl. It should be possible and actually pretty easy to make it
2173 work using L<Math::BigInt>, but I need to build a 32-bit perl in order to test it and frankly I'm still
2174 figuring out how. I'm sure it's simple so I'll mark this one "TODO", but for now an exception will be thrown
2175 when trying to use such features with undersized IVs.
2176
2177 =head1 SEE ALSO
2178
2179 L<File::KeePass> is a much older alternative. It's good but has a backlog of bugs and lacks support for newer
2180 KDBX features.
2181
2182 =attr sig1
2183
2184 =attr sig2
2185
2186 =attr version
2187
2188 =attr headers
2189
2190 =attr inner_headers
2191
2192 =attr meta
2193
2194 =attr binaries
2195
2196 =attr deleted_objects
2197
2198 =attr raw
2199
2200 $value = $kdbx->$attr;
2201 $kdbx->$attr($value);
2202
2203 Get and set attributes.
2204
2205 =cut
This page took 0.184491 seconds and 4 git commands to generate.