2 # ABSTRACT: Encrypted database to store secret text and files
7 use Crypt
::Digest
qw(digest_data);
8 use Crypt
::PRNG
qw(random_bytes);
9 use Devel
::GlobalDestruction
;
10 use File
::KDBX
::Constants
qw(:all :icon);
11 use File
::KDBX
::Error
;
13 use File
::KDBX
::Util
qw(:class :coercion :empty :search :uuid erase simple_expression_query snakify);
14 use Hash
::Util
::FieldHash
qw(fieldhashes);
15 use List
::Util
qw(any first);
16 use Ref
::Util
qw(is_ref is_arrayref is_plain_hashref);
17 use Scalar
::Util
qw(blessed);
22 our $VERSION = '0.900'; # VERSION
25 fieldhashes \
my (%SAFE, %KEYS);
32 return $_[0]->clone if @_ == 1 && blessed
$_[0] && $_[0]->isa($class);
34 my $self = bless {}, $class;
36 $self->_set_nonlazy_attributes if empty
$self;
40 sub DESTROY
{ local ($., $@, $!, $^E, $?); !in_global_destruction
and $_[0]->reset }
47 @$self{keys %args} = values %args;
55 erase
$self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY
};
56 erase
$self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY
};
67 return Storable
::dclone
($self);
76 return '', $copy, $KEYS{$self} // (), $SAFE{$self} // ();
87 @$self{keys %$clone} = values %$clone;
91 # Dualvars aren't cloned as dualvars, so coerce the compression flags.
92 $self->compression_flags($self->compression_flags);
94 $self->objects(history
=> 1)->each(sub { $_->kdbx($self) });
97 ##############################################################################
100 sub load
{ shift-
>_loader->load(@_) }
101 sub load_string
{ shift-
>_loader->load_string(@_) }
102 sub load_file
{ shift-
>_loader->load_file(@_) }
103 sub load_handle
{ shift-
>_loader->load_handle(@_) }
107 $self = $self->new if !ref $self;
108 require File
::KDBX
::Loader
;
109 File
::KDBX
::Loader-
>new(kdbx
=> $self);
113 sub dump { shift-
>_dumper->dump(@_) }
114 sub dump_string
{ shift-
>_dumper->dump_string(@_) }
115 sub dump_file
{ shift-
>_dumper->dump_file(@_) }
116 sub dump_handle
{ shift-
>_dumper->dump_handle(@_) }
120 $self = $self->new if !ref $self;
121 require File
::KDBX
::Dumper
;
122 File
::KDBX
::Dumper-
>new(kdbx
=> $self);
125 ##############################################################################
128 sub user_agent_string
{
130 sprintf('%s/%s (%s/%s; %s/%s; %s)',
131 __PACKAGE__
, $VERSION, @Config::Config
{qw(package version osname osvers archname)});
134 has sig1
=> KDBX_SIG1
, coerce
=> \
&to_number
;
135 has sig2
=> KDBX_SIG2_2
, coerce
=> \
&to_number
;
136 has version
=> KDBX_VERSION_3_1
, coerce
=> \
&to_number
;
138 has inner_headers
=> {};
141 has deleted_objects
=> {};
142 has raw
=> coerce
=> \
&to_string
;
145 has 'headers.comment' => '', coerce
=> \
&to_string
;
146 has 'headers.cipher_id' => CIPHER_UUID_CHACHA20
, coerce
=> \
&to_uuid
;
147 has 'headers.compression_flags' => COMPRESSION_GZIP
, coerce
=> \
&to_compression_constant
;
148 has 'headers.master_seed' => sub { random_bytes
(32) }, coerce
=> \
&to_string
;
149 has 'headers.encryption_iv' => sub { random_bytes
(16) }, coerce
=> \
&to_string
;
150 has 'headers.stream_start_bytes' => sub { random_bytes
(32) }, coerce
=> \
&to_string
;
151 has 'headers.kdf_parameters' => sub {
153 KDF_PARAM_UUID
() => KDF_UUID_AES
,
154 KDF_PARAM_AES_ROUNDS
() => $_[0]->headers->{+HEADER_TRANSFORM_ROUNDS
} // KDF_DEFAULT_AES_ROUNDS
,
155 KDF_PARAM_AES_SEED
() => $_[0]->headers->{+HEADER_TRANSFORM_SEED
} // random_bytes
(32),
158 # has 'headers.transform_seed' => sub { random_bytes(32) };
159 # has 'headers.transform_rounds' => 100_000;
160 # has 'headers.inner_random_stream_key' => sub { random_bytes(32) }; # 64 ?
161 # has 'headers.inner_random_stream_id' => STREAM_ID_CHACHA20;
162 # has 'headers.public_custom_data' => {};
165 has 'meta.generator' => '', coerce
=> \
&to_string
;
166 has 'meta.header_hash' => '', coerce
=> \
&to_string
;
167 has 'meta.database_name' => '', coerce
=> \
&to_string
;
168 has 'meta.database_name_changed' => sub { gmtime }, coerce
=> \
&to_time
;
169 has 'meta.database_description' => '', coerce
=> \
&to_string
;
170 has 'meta.database_description_changed' => sub { gmtime }, coerce
=> \
&to_time
;
171 has 'meta.default_username' => '', coerce
=> \
&to_string
;
172 has 'meta.default_username_changed' => sub { gmtime }, coerce
=> \
&to_time
;
173 has 'meta.maintenance_history_days' => HISTORY_DEFAULT_MAX_AGE
, coerce
=> \
&to_number
;
174 has 'meta.color' => '', coerce
=> \
&to_string
;
175 has 'meta.master_key_changed' => sub { gmtime }, coerce
=> \
&to_time
;
176 has 'meta.master_key_change_rec' => -1, coerce
=> \
&to_number
;
177 has 'meta.master_key_change_force' => -1, coerce
=> \
&to_number
;
178 # has 'meta.memory_protection' => {};
179 has 'meta.custom_icons' => [];
180 has 'meta.recycle_bin_enabled' => true
, coerce
=> \
&to_bool
;
181 has 'meta.recycle_bin_uuid' => UUID_NULL
, coerce
=> \
&to_uuid
;
182 has 'meta.recycle_bin_changed' => sub { gmtime }, coerce
=> \
&to_time
;
183 has 'meta.entry_templates_group' => UUID_NULL
, coerce
=> \
&to_uuid
;
184 has 'meta.entry_templates_group_changed' => sub { gmtime }, coerce
=> \
&to_time
;
185 has 'meta.last_selected_group' => UUID_NULL
, coerce
=> \
&to_uuid
;
186 has 'meta.last_top_visible_group' => UUID_NULL
, coerce
=> \
&to_uuid
;
187 has 'meta.history_max_items' => HISTORY_DEFAULT_MAX_ITEMS
, coerce
=> \
&to_number
;
188 has 'meta.history_max_size' => HISTORY_DEFAULT_MAX_SIZE
, coerce
=> \
&to_number
;
189 has 'meta.settings_changed' => sub { gmtime }, coerce
=> \
&to_time
;
190 # has 'meta.binaries' => {};
191 # has 'meta.custom_data' => {};
193 has 'memory_protection.protect_title' => false
, coerce
=> \
&to_bool
;
194 has 'memory_protection.protect_username' => false
, coerce
=> \
&to_bool
;
195 has 'memory_protection.protect_password' => true
, coerce
=> \
&to_bool
;
196 has 'memory_protection.protect_url' => false
, coerce
=> \
&to_bool
;
197 has 'memory_protection.protect_notes' => false
, coerce
=> \
&to_bool
;
198 # has 'memory_protection.auto_enable_visual_hiding' => false;
201 HEADER_TRANSFORM_SEED
,
202 HEADER_TRANSFORM_ROUNDS
,
203 HEADER_INNER_RANDOM_STREAM_KEY
,
204 HEADER_INNER_RANDOM_STREAM_ID
,
205 HEADER_PUBLIC_CUSTOM_DATA
,
207 sub _set_nonlazy_attributes
{
209 $self->$_ for list_attributes
(ref $self), @ATTRS;
213 sub memory_protection
{
215 $self->{meta
}{memory_protection
} = shift if @_ == 1 && is_plain_hashref
($_[0]);
216 return $self->{meta
}{memory_protection
} //= {} if !@_;
218 my $string_key = shift;
219 my $key = 'protect_' . lc($string_key);
221 $self->meta->{memory_protection
}{$key} = shift if @_;
222 $self->meta->{memory_protection
}{$key};
226 sub minimum_version
{
229 return KDBX_VERSION_4_1
if any
{
230 nonempty
$_->{last_modification_time
}
231 } values %{$self->custom_data};
233 return KDBX_VERSION_4_1
if any
{
234 nonempty
$_->{name
} || nonempty
$_->{last_modification_time
}
235 } @{$self->custom_icons};
237 return KDBX_VERSION_4_1
if $self->groups->next(sub {
238 nonempty
$_->previous_parent_group ||
240 (any
{ nonempty
$_->{last_modification_time
} } values %{$_->custom_data})
243 return KDBX_VERSION_4_1
if $self->entries(history
=> 1)->next(sub {
244 nonempty
$_->previous_parent_group ||
245 (defined $_->quality_check && !$_->quality_check) ||
246 (any
{ nonempty
$_->{last_modification_time
} } values %{$_->custom_data})
249 return KDBX_VERSION_4_0
if $self->kdf->uuid ne KDF_UUID_AES
;
251 return KDBX_VERSION_4_0
if nonempty
$self->public_custom_data;
253 return KDBX_VERSION_4_0
if $self->objects->next(sub {
254 nonempty
$_->custom_data
257 return KDBX_VERSION_3_1
;
260 ##############################################################################
266 $self->{root
} = $self->_wrap_group(@_);
267 $self->{root
}->kdbx($self);
269 $self->{root
} //= $self->_implicit_root;
270 return $self->_wrap_group($self->{root
});
273 # Called by File::KeePass::KDBX so that a File::KDBX an be treated as a File::KDBX::Group in that both types
274 # can have subgroups. File::KDBX already has a `groups' method that does something different from the
275 # File::KDBX::Groups `groups' method.
278 return [] if !$self->{root
};
279 return $self->_has_implicit_root ? $self->root->groups : [$self->root];
282 sub _has_implicit_root
{
284 my $root = $self->root;
285 my $temp = __PACKAGE__-
>_implicit_root;
286 # If an implicit root group has been changed in any significant way, it is no longer implicit.
287 return $root->name eq $temp->name &&
288 $root->is_expanded ^ $temp->is_expanded &&
289 $root->notes eq $temp->notes &&
290 !@{$root->entries} &&
291 !defined $root->custom_icon_uuid &&
292 !keys %{$root->custom_data} &&
293 $root->icon_id == $temp->icon_id &&
294 $root->expires ^ $temp->expires &&
295 $root->default_auto_type_sequence eq $temp->default_auto_type_sequence &&
296 !defined $root->enable_auto_type &&
297 !defined $root->enable_searching;
302 require File
::KDBX
::Group
;
303 return File
::KDBX
::Group-
>new(
306 notes
=> 'Added as an implicit root group by '.__PACKAGE__
.'.',
307 ref $self ? (kdbx
=> $self) : (),
315 return $object->lineage(@_);
323 push @lineage, $self->root if !@lineage;
324 my $base = $lineage[-1] or return [];
326 my $uuid = $object->uuid;
327 return \
@lineage if any
{ $_->uuid eq $uuid } @{$base->groups}, @{$base->entries};
329 for my $subgroup (@{$base->groups}) {
330 my $result = $self->_trace_lineage($object, @lineage, $subgroup);
331 return $result if $result;
338 if (my $group = shift) {
339 $self->recycle_bin_uuid($group->uuid);
343 my $uuid = $self->recycle_bin_uuid;
344 $group = $self->groups->grep(uuid
=> $uuid)->next if $uuid ne UUID_NULL
;
345 if (!$group && $self->recycle_bin_enabled) {
346 $group = $self->add_group(
347 name
=> 'Recycle Bin',
348 icon_id
=> ICON_TRASHCAN_FULL
,
349 enable_auto_type
=> false
,
350 enable_searching
=> false
,
352 $self->recycle_bin_uuid($group->uuid);
358 sub entry_templates
{
360 if (my $group = shift) {
361 $self->entry_templates_group($group->uuid);
364 my $uuid = $self->entry_templates_group;
365 return if $uuid eq UUID_NULL
;
366 return $self->groups->grep(uuid
=> $uuid)->next;
372 if (my $group = shift) {
373 $self->last_selected_group($group->uuid);
376 my $uuid = $self->last_selected_group;
377 return if $uuid eq UUID_NULL
;
378 return $self->groups->grep(uuid
=> $uuid)->next;
382 sub last_top_visible
{
384 if (my $group = shift) {
385 $self->last_top_visible_group($group->uuid);
388 my $uuid = $self->last_top_visible_group;
389 return if $uuid eq UUID_NULL
;
390 return $self->groups->grep(uuid
=> $uuid)->next;
393 ##############################################################################
398 my $group = @_ % 2 == 1 ? shift : undef;
401 # find the right group to add the group to
402 my $parent = delete $args{group
} // $self->root;
403 $parent = $self->groups->grep({uuid
=> $parent})->next if !ref $parent;
404 $parent or throw
'Invalid group';
406 return $parent->add_group(defined $group ? $group : (), %args, kdbx
=> $self);
412 require File
::KDBX
::Group
;
413 return File
::KDBX
::Group-
>wrap($group, $self);
419 my %args = @_ % 2 == 0 ? @_ : (base
=> shift, @_);
420 my $base = delete $args{base
} // $self->root;
422 return $base->groups_deeply(%args);
425 ##############################################################################
430 my $entry = @_ % 2 == 1 ? shift : undef;
433 # find the right group to add the entry to
434 my $parent = delete $args{group
} // $self->root;
435 $parent = $self->groups->grep({uuid
=> $parent})->next if !ref $parent;
436 $parent or throw
'Invalid group';
438 return $parent->add_entry(defined $entry ? $entry : (), %args, kdbx
=> $self);
444 require File
::KDBX
::Entry
;
445 return File
::KDBX
::Entry-
>wrap($entry, $self);
451 my %args = @_ % 2 == 0 ? @_ : (base
=> shift, @_);
452 my $base = delete $args{base
} // $self->root;
454 return $base->entries_deeply(%args);
457 ##############################################################################
462 my %args = @_ % 2 == 0 ? @_ : (base
=> shift, @_);
463 my $base = delete $args{base
} // $self->root;
465 return $base->objects_deeply(%args);
468 sub __iter__
{ $_[0]->objects }
470 ##############################################################################
475 my %args = @_ == 2 ? (uuid
=> shift, data
=> shift)
476 : @_ % 2 == 1 ? (uuid
=> shift, @_) : @_;
478 if (!$args{uuid
} && !$args{data
}) {
479 my %standard = (uuid
=> 1, data
=> 1, name
=> 1, last_modification_time
=> 1);
480 my @other_keys = grep { !$standard{$_} } keys %args;
481 if (@other_keys == 1) {
482 my $key = $args{key
} = $other_keys[0];
483 $args{data
} = delete $args{$key};
487 my $uuid = $args{uuid
} or throw
'Must provide a custom icon UUID to access';
488 my $icon = (first
{ $_->{uuid
} eq $uuid } @{$self->custom_icons}) // do {
489 push @{$self->custom_icons}, my $i = { uuid
=> $uuid };
494 $fields = $args{data
} if is_plain_hashref
($args{data
});
496 while (my ($field, $value) = each %$fields) {
497 $icon->{$field} = $value;
503 sub custom_icon_data
{
505 my $uuid = shift // return;
506 my $icon = first
{ $_->{uuid
} eq $uuid } @{$self->custom_icons} or return;
507 return $icon->{data
};
511 sub add_custom_icon
{
513 my %args = @_ % 2 == 1 ? (data
=> shift, @_) : @_;
515 defined $args{data
} or throw
'Must provide image data';
517 my $uuid = $args{uuid
} // generate_uuid
;
518 push @{$self->custom_icons}, {
527 sub remove_custom_icon
{
531 @{$self->custom_icons} = grep { $_->{uuid
} eq $uuid ? do { push @deleted, $_; 0 } : 1 }
532 @{$self->custom_icons};
533 $self->add_deleted_object($uuid) if @deleted;
537 ##############################################################################
542 $self->{meta
}{custom_data
} = shift if @_ == 1 && is_plain_hashref
($_[0]);
543 return $self->{meta
}{custom_data
} //= {} if !@_;
545 my %args = @_ == 2 ? (key
=> shift, value
=> shift)
546 : @_ % 2 == 1 ? (key
=> shift, @_) : @_;
548 if (!$args{key
} && !$args{value
}) {
549 my %standard = (key
=> 1, value
=> 1, last_modification_time
=> 1);
550 my @other_keys = grep { !$standard{$_} } keys %args;
551 if (@other_keys == 1) {
552 my $key = $args{key
} = $other_keys[0];
553 $args{value
} = delete $args{$key};
557 my $key = $args{key
} or throw
'Must provide a custom_data key to access';
559 return $self->{meta
}{custom_data
}{$key} = $args{value
} if is_plain_hashref
($args{value
});
561 while (my ($field, $value) = each %args) {
562 $self->{meta
}{custom_data
}{$key}{$field} = $value;
564 return $self->{meta
}{custom_data
}{$key};
568 sub custom_data_value
{
570 my $data = $self->custom_data(@_) // return;
571 return $data->{value
};
575 sub public_custom_data
{
577 $self->{headers
}{+HEADER_PUBLIC_CUSTOM_DATA
} = shift if @_ == 1 && is_plain_hashref
($_[0]);
578 return $self->{headers
}{+HEADER_PUBLIC_CUSTOM_DATA
} //= {} if !@_;
580 my $key = shift or throw
'Must provide a public_custom_data key to access';
581 $self->{headers
}{+HEADER_PUBLIC_CUSTOM_DATA
}{$key} = shift if @_;
582 return $self->{headers
}{+HEADER_PUBLIC_CUSTOM_DATA
}{$key};
585 ##############################################################################
592 # my %options = @_; # prefer_old / prefer_new
593 # $other->merge_from($self);
600 # die 'Not implemented';
604 sub add_deleted_object
{
608 # ignore null and meta stream UUIDs
609 return if $uuid eq UUID_NULL
|| $uuid eq '0' x
16;
611 $self->deleted_objects->{$uuid} = {
613 deletion_time
=> scalar gmtime,
618 sub remove_deleted_object
{
621 delete $self->deleted_objects->{$uuid};
625 sub clear_deleted_objects
{
627 %{$self->deleted_objects} = ();
630 ##############################################################################
633 sub resolve_reference
{
635 my $wanted = shift // return;
636 my $search_in = shift;
639 if (!defined $text) {
640 $wanted =~ s/^\{REF:([^\}]+)\}$/$1/i;
641 ($wanted, $search_in, $text) = $wanted =~ /^([TUPANI])\@([TUPANIO]):(.*)$/i;
643 $wanted && $search_in && nonempty
($text) or return;
647 U
=> 'expand_username',
648 P
=> 'expand_password',
652 O
=> 'other_strings',
654 $wanted = $fields{$wanted} or return;
655 $search_in = $fields{$search_in} or return;
657 my $query = $search_in eq 'uuid' ? query
($search_in => uuid
($text))
658 : simple_expression_query
($text, '=~', $search_in);
660 my $entry = $self->entries->grep($query)->next;
663 return $entry->$wanted;
666 our %PLACEHOLDERS = (
667 # 'PLACEHOLDER' => sub { my ($entry, $arg) = @_; ... };
668 'TITLE' => sub { $_[0]->expand_title },
669 'USERNAME' => sub { $_[0]->expand_username },
670 'PASSWORD' => sub { $_[0]->expand_password },
671 'NOTES' => sub { $_[0]->expand_notes },
672 'S:' => sub { $_[0]->string_value($_[1]) },
673 'URL' => sub { $_[0]->expand_url },
674 'URL:RMVSCM' => sub { local $_ = $_[0]->url; s!^[^:/\?\#]+://!!; $_ },
675 'URL:WITHOUTSCHEME' => sub { local $_ = $_[0]->url; s!^[^:/\?\#]+://!!; $_ },
676 'URL:SCM' => sub { (split_url
($_[0]->url))[0] },
677 'URL:SCHEME' => sub { (split_url
($_[0]->url))[0] }, # non-standard
678 'URL:HOST' => sub { (split_url
($_[0]->url))[2] },
679 'URL:PORT' => sub { (split_url
($_[0]->url))[3] },
680 'URL:PATH' => sub { (split_url
($_[0]->url))[4] },
681 'URL:QUERY' => sub { (split_url
($_[0]->url))[5] },
682 'URL:HASH' => sub { (split_url
($_[0]->url))[6] }, # non-standard
683 'URL:FRAGMENT' => sub { (split_url
($_[0]->url))[6] }, # non-standard
684 'URL:USERINFO' => sub { (split_url
($_[0]->url))[1] },
685 'URL:USERNAME' => sub { (split_url
($_[0]->url))[7] },
686 'URL:PASSWORD' => sub { (split_url
($_[0]->url))[8] },
687 'UUID' => sub { local $_ = format_uuid
($_[0]->uuid); s/-//g; $_ },
688 'REF:' => sub { $_[0]->kdbx->resolve_reference($_[1]) },
689 'INTERNETEXPLORER' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('iexplore') },
690 'FIREFOX' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('firefox') },
691 'GOOGLECHROME' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('google-chrome') },
692 'OPERA' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('opera') },
693 'SAFARI' => sub { load_optional
('IPC::Cmd'); IPC
::Cmd
::can_run
('safari') },
694 'APPDIR' => sub { load_optional
('FindBin'); $FindBin::Bin
},
695 'GROUP' => sub { my $p = $_[0]->group; $p ? $p->name : undef },
696 'GROUP_PATH' => sub { $_[0]->path },
697 'GROUP_NOTES' => sub { my $p = $_[0]->group; $p ? $p->notes : undef },
706 'ENV:' => sub { $ENV{$_[1]} },
707 'ENV_DIRSEP' => sub { load_optional
('File::Spec')->catfile('', '') },
708 'ENV_PROGRAMFILES_X86' => sub { $ENV{'ProgramFiles(x86)'} || $ENV{'ProgramFiles'} },
711 'DT_SIMPLE' => sub { localtime-
>strftime('%Y%m%d%H%M%S') },
712 'DT_YEAR' => sub { localtime-
>strftime('%Y') },
713 'DT_MONTH' => sub { localtime-
>strftime('%m') },
714 'DT_DAY' => sub { localtime-
>strftime('%d') },
715 'DT_HOUR' => sub { localtime-
>strftime('%H') },
716 'DT_MINUTE' => sub { localtime-
>strftime('%M') },
717 'DT_SECOND' => sub { localtime-
>strftime('%S') },
718 'DT_UTC_SIMPLE' => sub { gmtime-
>strftime('%Y%m%d%H%M%S') },
719 'DT_UTC_YEAR' => sub { gmtime-
>strftime('%Y') },
720 'DT_UTC_MONTH' => sub { gmtime-
>strftime('%m') },
721 'DT_UTC_DAY' => sub { gmtime-
>strftime('%d') },
722 'DT_UTC_HOUR' => sub { gmtime-
>strftime('%H') },
723 'DT_UTC_MINUTE' => sub { gmtime-
>strftime('%M') },
724 'DT_UTC_SECOND' => sub { gmtime-
>strftime('%S') },
731 'HMACOTP' => sub { $_[0]->hmac_otp },
732 'TIMEOTP' => sub { $_[0]->time_otp },
733 'C:' => sub { '' }, # comment
741 ##############################################################################
746 $SAFE{$self} = shift if @_;
750 sub _remove_safe
{ delete $SAFE{$_[0]} }
755 $self->_safe and return $self;
759 $self->entries(history
=> 1)->each(sub {
760 push @strings, grep { $_->{protect
} } values %{$_->strings}, values %{$_->binaries};
763 $self->_safe(File
::KDBX
::Safe-
>new(\
@strings));
771 my $safe = $self->_safe or return $self;
781 throw
'Programmer error: Cannot call unlock_scoped in void context' if !defined wantarray;
783 return if !$self->is_locked;
784 require Scope
::Guard
;
785 my $guard = Scope
::Guard-
>new(sub { $self->lock });
794 my $safe = $self->_safe or return;
795 return $safe->peek($string);
799 sub is_locked
{ $_[0]->_safe ? 1 : 0 }
801 ##############################################################################
804 # - Fixer tool. Can repair inconsistencies, including:
805 # - Orphaned binaries... not really a thing anymore since we now distribute binaries amongst entries
806 # - Unused custom icons (OFF, data loss)
808 # - All data types are valid
809 # - date times are correct
811 # - All UUIDs refer to things that exist
812 # - previous parent group
814 # - last selected group
815 # - last visible group
816 # - Enforce history size limits (ON)
817 # - Check headers/meta (ON)
818 # - Duplicate deleted objects (ON)
819 # - Duplicate window associations (OFF)
820 # - Header UUIDs match known ciphers/KDFs?
824 sub remove_empty_groups
{
827 $self->groups(algorithm
=> 'dfs')
828 ->where(-true
=> 'is_empty')
829 ->each(sub { push @removed, $_->remove });
834 sub remove_unused_icons
{
836 my %icons = map { $_->{uuid
} => 0 } @{$self->custom_icons};
838 $self->objects->each(sub { ++$icons{$_->custom_icon_uuid // ''} });
841 push @removed, $self->remove_custom_icon($_) for grep { $icons{$_} == 0 } keys %icons;
846 sub remove_duplicate_icons
{
851 for my $icon (@{$self->custom_icons}) {
852 my $digest = digest_data
('SHA256', $icon->{data
});
853 if (my $other = $seen{$digest}) {
854 $dup{$icon->{uuid
}} = $other->{uuid
};
857 $seen{$digest} = $icon;
862 while (my ($old_uuid, $new_uuid) = each %dup) {
864 ->where(custom_icon_uuid
=> $old_uuid)
865 ->each(sub { $_->custom_icon_uuid($new_uuid) });
866 push @removed, $self->remove_custom_icon($old_uuid);
876 my $max_items = $args{max_items
} // $self->history_max_items // HISTORY_DEFAULT_MAX_ITEMS
;
877 my $max_size = $args{max_size
} // $self->history_max_size // HISTORY_DEFAULT_MAX_SIZE
;
878 my $max_age = $args{max_age
} // $self->maintenance_history_days // HISTORY_DEFAULT_MAX_AGE
;
881 $self->entries->each(sub {
882 push @removed, $_->prune_history(
883 max_items
=> $max_items,
884 max_size
=> $max_size,
892 sub randomize_seeds
{
894 $self->encryption_iv(random_bytes
(16));
895 $self->inner_random_stream_key(random_bytes
(64));
896 $self->master_seed(random_bytes
(32));
897 $self->stream_start_bytes(random_bytes
(32));
898 $self->transform_seed(random_bytes
(32));
901 ##############################################################################
906 $KEYS{$self} = File
::KDBX
::Key-
>new(@_) if @_;
913 require File
::KDBX
::Key
::Composite
;
914 return File
::KDBX
::Key
::Composite-
>new(@_);
920 my %args = @_ % 2 == 1 ? (params
=> shift, @_) : @_;
922 my $params = $args{params
};
923 my $compat = $args{compatible
} // 1;
925 $params //= $self->kdf_parameters;
926 $params = {%{$params || {}}};
928 if (empty
$params || !defined $params->{+KDF_PARAM_UUID
}) {
929 $params->{+KDF_PARAM_UUID
} = KDF_UUID_AES
;
931 if ($params->{+KDF_PARAM_UUID
} eq KDF_UUID_AES
) {
932 # AES_CHALLENGE_RESPONSE is equivalent to AES if there are no challenge-response keys, and since
933 # non-KeePassXC implementations don't support challenge-response keys anyway, there's no problem with
934 # always using AES_CHALLENGE_RESPONSE for all KDBX4+ databases.
935 # For compatibility, we should not *write* AES_CHALLENGE_RESPONSE, but the dumper handles that.
936 if ($self->version >= KDBX_VERSION_4_0
) {
937 $params->{+KDF_PARAM_UUID
} = KDF_UUID_AES_CHALLENGE_RESPONSE
;
939 $params->{+KDF_PARAM_AES_SEED
} //= $self->transform_seed;
940 $params->{+KDF_PARAM_AES_ROUNDS
} //= $self->transform_rounds;
943 require File
::KDBX
::KDF
;
944 return File
::KDBX
::KDF-
>new(%$params);
949 $self->headers->{+HEADER_TRANSFORM_SEED
} =
950 $self->headers->{+HEADER_KDF_PARAMETERS
}{+KDF_PARAM_AES_SEED
} = shift if @_;
951 $self->headers->{+HEADER_TRANSFORM_SEED
} =
952 $self->headers->{+HEADER_KDF_PARAMETERS
}{+KDF_PARAM_AES_SEED
} //= random_bytes
(32);
955 sub transform_rounds
{
957 $self->headers->{+HEADER_TRANSFORM_ROUNDS
} =
958 $self->headers->{+HEADER_KDF_PARAMETERS
}{+KDF_PARAM_AES_ROUNDS
} = shift if @_;
959 $self->headers->{+HEADER_TRANSFORM_ROUNDS
} =
960 $self->headers->{+HEADER_KDF_PARAMETERS
}{+KDF_PARAM_AES_ROUNDS
} //= 100_000;
968 $args{uuid
} //= $self->headers->{+HEADER_CIPHER_ID
};
969 $args{iv
} //= $self->headers->{+HEADER_ENCRYPTION_IV
};
971 require File
::KDBX
::Cipher
;
972 return File
::KDBX
::Cipher-
>new(%args);
980 $args{stream_id
} //= delete $args{id
} // $self->inner_random_stream_id;
981 $args{key
} //= $self->inner_random_stream_key;
983 require File
::KDBX
::Cipher
;
984 File
::KDBX
::Cipher-
>new(%args);
987 sub inner_random_stream_id
{
989 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_ID
}
990 = $self->headers->{+HEADER_INNER_RANDOM_STREAM_ID
} = shift if @_;
991 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_ID
}
992 //= $self->headers->{+HEADER_INNER_RANDOM_STREAM_ID
} //= do {
993 my $version = $self->minimum_version;
994 $version < KDBX_VERSION_4_0
? STREAM_ID_SALSA20
: STREAM_ID_CHACHA20
;
998 sub inner_random_stream_key
{
1001 # These are probably the same SvPV so erasing one will CoW, but erasing the second should do the
1003 erase \
$self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY
};
1004 erase \
$self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY
};
1005 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY
}
1006 = $self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY
} = shift;
1008 $self->inner_headers->{+INNER_HEADER_INNER_RANDOM_STREAM_KEY
}
1009 //= $self->headers->{+HEADER_INNER_RANDOM_STREAM_KEY
} //= random_bytes
(64); # 32
1012 #########################################################################################
1014 sub _handle_signal
{
1020 'entry.added' => \
&_handle_object_added
,
1021 'group.added' => \
&_handle_object_added
,
1022 'entry.removed' => \
&_handle_object_removed
,
1023 'group.removed' => \
&_handle_object_removed
,
1024 'entry.uuid.changed' => \
&_handle_entry_uuid_changed
,
1025 'group.uuid.changed' => \
&_handle_group_uuid_changed
,
1027 my $handler = $handlers{$type} or return;
1028 $self->$handler($object, @_);
1031 sub _handle_object_added
{
1034 $self->remove_deleted_object($object->uuid);
1037 sub _handle_object_removed
{
1040 my $old_uuid = $object->{uuid
} // return;
1042 my $meta = $self->meta;
1043 $self->recycle_bin_uuid(UUID_NULL
) if $old_uuid eq ($meta->{recycle_bin_uuid
} // '');
1044 $self->entry_templates_group(UUID_NULL
) if $old_uuid eq ($meta->{entry_templates_group
} // '');
1045 $self->last_selected_group(UUID_NULL
) if $old_uuid eq ($meta->{last_selected_group
} // '');
1046 $self->last_top_visible_group(UUID_NULL
) if $old_uuid eq ($meta->{last_top_visible_group
} // '');
1048 $self->add_deleted_object($old_uuid);
1051 sub _handle_entry_uuid_changed
{
1054 my $new_uuid = shift;
1055 my $old_uuid = shift // return;
1057 my $old_pretty = format_uuid
($old_uuid);
1058 my $new_pretty = format_uuid
($new_uuid);
1059 my $fieldref_match = qr/\{REF:([TUPANI])\@I:\Q$old_pretty\E\}/is;
1061 $self->entries->each(sub {
1062 $_->previous_parent_group($new_uuid) if $old_uuid eq ($_->{previous_parent_group
} // '');
1064 for my $string (values %{$_->strings}) {
1065 next if !defined $string->{value
} || $string->{value
} !~ $fieldref_match;
1066 my $txn = $_->begin_work;
1067 $string->{value
} =~ s/$fieldref_match/{REF:$1\@I:$new_pretty}/g;
1073 sub _handle_group_uuid_changed
{
1076 my $new_uuid = shift;
1077 my $old_uuid = shift // return;
1079 my $meta = $self->meta;
1080 $self->recycle_bin_uuid($new_uuid) if $old_uuid eq ($meta->{recycle_bin_uuid
} // '');
1081 $self->entry_templates_group($new_uuid) if $old_uuid eq ($meta->{entry_templates_group
} // '');
1082 $self->last_selected_group($new_uuid) if $old_uuid eq ($meta->{last_selected_group
} // '');
1083 $self->last_top_visible_group($new_uuid) if $old_uuid eq ($meta->{last_top_visible_group
} // '');
1085 $self->groups->each(sub {
1086 $_->last_top_visible_entry($new_uuid) if $old_uuid eq ($_->{last_top_visible_entry
} // '');
1087 $_->previous_parent_group($new_uuid) if $old_uuid eq ($_->{previous_parent_group
} // '');
1089 $self->entries->each(sub {
1090 $_->previous_parent_group($new_uuid) if $old_uuid eq ($_->{previous_parent_group
} // '');
1094 #########################################################################################
1097 #########################################################################################
1099 sub TO_JSON
{ +{%{$_[0]}} }
1109 =for markdown [![Linux](https://github.com/chazmcgarvey/File-KDBX/actions/workflows/linux.yml/badge.svg)](https://github.com/chazmcgarvey/File-KDBX/actions/workflows/linux.yml)
1110 [![macOS](https://github.com/chazmcgarvey/File-KDBX/actions/workflows/macos.yml/badge.svg)](https://github.com/chazmcgarvey/File-KDBX/actions/workflows/macos.yml)
1111 [![Windows](https://github.com/chazmcgarvey/File-KDBX/actions/workflows/windows.yml/badge.svg)](https://github.com/chazmcgarvey/File-KDBX/actions/workflows/windows.yml)
1113 =for HTML <a title="Linux" href="https://github.com/chazmcgarvey/File-KDBX/actions/workflows/linux.yml"><img src="https://github.com/chazmcgarvey/File-KDBX/actions/workflows/linux.yml/badge.svg"></a>
1114 <a title="macOS" href="https://github.com/chazmcgarvey/File-KDBX/actions/workflows/macos.yml"><img src="https://github.com/chazmcgarvey/File-KDBX/actions/workflows/macos.yml/badge.svg"></a>
1115 <a title="Windows" href="https://github.com/chazmcgarvey/File-KDBX/actions/workflows/windows.yml"><img src="https://github.com/chazmcgarvey/File-KDBX/actions/workflows/windows.yml/badge.svg"></a>
1119 File::KDBX - Encrypted database to store secret text and files
1129 my $kdbx = File::KDBX->new;
1131 my $group = $kdbx->add_group(
1132 name => 'Passwords',
1135 my $entry = $group->add_entry(
1137 password => 's3cr3t',
1140 $kdbx->dump_file('passwords.kdbx', 'M@st3rP@ssw0rd!');
1142 $kdbx = File::KDBX->load_file('passwords.kdbx', 'M@st3rP@ssw0rd!');
1144 $kdbx->entries->each(sub {
1146 say 'Entry: ', $entry->title;
1149 See L</RECIPES> for more examples.
1153 B<File::KDBX> provides everything you need to work with KDBX databases. A KDBX database is a hierarchical
1154 object database which is commonly used to store secret information securely. It was developed for the KeePass
1155 password safe. See L</"Introduction to KDBX"> for more information about KDBX.
1157 This module lets you query entries, create new entries, delete entries, modify entries and more. The
1158 distribution also includes various parsers and generators for serializing and persisting databases.
1160 The design of this software was influenced by the L<KeePassXC|https://github.com/keepassxreboot/keepassxc>
1161 implementation of KeePass as well as the L<File::KeePass> module. B<File::KeePass> is an alternative module
1162 that works well in most cases but has a small backlog of bugs and security issues and also does not work with
1163 newer KDBX version 4 files. If you're coming here from the B<File::KeePass> world, you might be interested in
1164 L<File::KeePass::KDBX> that is a drop-in replacement for B<File::KeePass> that uses B<File::KDBX> for storage.
1166 This software is a B<pre-1.0 release>. The interface should be considered pretty stable, but there might be
1167 minor changes up until a 1.0 release. Breaking changes will be noted in the F<Changes> file.
1175 ☑ Read and write KDBX version 3 - version 4.1
1179 ☑ Read and write KDB files (requires L<File::KeePass>)
1183 ☑ Unicode character strings
1187 ☑ L</"Simple Expression"> Searching
1191 ☑ L<Placeholders|File::KDBX::Entry/Placeholders> and L<field references|/resolve_reference>
1195 ☑ L<One-time passwords|File::KDBX::Entry/"One-time Passwords">
1199 ☑ L<Very secure|/SECURITY>
1203 ☑ L</"Memory Protection">
1207 ☑ Challenge-response key components, like L<YubiKey|File::KDBX::Key::YubiKey>
1211 ☑ Variety of L<key file|File::KDBX::Key::File> types: binary, hexed, hashed, XML v1 and v2
1215 ☑ Pluggable registration of different kinds of ciphers and key derivation functions
1219 ☑ Built-in database maintenance functions
1223 ☑ Pretty fast, with L<XS optimizations|File::KDBX::XS> available
1227 ☒ Database synchronization / merging (not yet)
1231 =head2 Introduction to KDBX
1233 A KDBX database consists of a tree of I<groups> and I<entries>, with a single I<root> group. Entries can
1234 contain zero or more key-value pairs of I<strings> and zero or more I<binaries> (i.e. octet strings). Groups,
1235 entries, strings and binaries: that's the KDBX vernacular. A small amount of metadata (timestamps, etc.) is
1236 associated with each entry, group and the database as a whole.
1238 You can think of a KDBX database kind of like a file system, where groups are directories, entries are files,
1239 and strings and binaries make up a file's contents.
1241 Databases are typically persisted as encrypted, compressed files. They are usually accessed directly (i.e.
1242 not over a network). The primary focus of this type of database is data security. It is ideal for storing
1243 relatively small amounts of data (strings and binaries) that must remain secret except to such individuals as
1244 have the correct I<master key>. Even if the database file were to be "leaked" to the public Internet, it
1245 should be virtually impossible to crack with a strong key. The KDBX format is most often used by password
1246 managers to store passwords so that users can know a single strong password and not have to reuse passwords
1247 across different websites. See L</SECURITY> for an overview of security considerations.
1259 =head2 inner_headers
1265 =head2 deleted_objects
1267 Hash of UUIDs for objects that have been deleted. This includes groups, entries and even custom icons.
1271 Bytes contained within the encrypted layer of a KDBX file. This is only set when using
1272 L<File::KDBX::Loader::Raw>.
1276 A text string associated with the database. Often unset.
1280 The UUID of a cipher used to encrypt the database when stored as a file.
1282 See L</File::KDBX::Cipher>.
1284 =head2 compression_flags
1286 Configuration for whether or not and how the database gets compressed. See
1287 L<File::KDBX::Constants/":compression">.
1291 The master seed is a string of 32 random bytes that is used as salt in hashing the master key when loading
1292 and saving the database. If a challenge-response key is used in the master key, the master seed is also the
1295 The master seed I<should> be changed each time the database is saved to file.
1297 =head2 transform_seed
1299 The transform seed is a string of 32 random bytes that is used in the key derivation function, either as the
1300 salt or the key (depending on the algorithm).
1302 The transform seed I<should> be changed each time the database is saved to file.
1304 =head2 transform_rounds
1306 The number of rounds or iterations used in the key derivation function. Increasing this number makes loading
1307 and saving the database slower by design in order to make dictionary and brute force attacks more costly.
1309 =head2 encryption_iv
1311 The initialization vector used by the cipher.
1313 The encryption IV I<should> be changed each time the database is saved to file.
1315 =head2 inner_random_stream_key
1317 The encryption key (possibly including the IV, depending on the cipher) used to encrypt the protected strings
1318 within the database.
1320 =head2 stream_start_bytes
1322 A string of 32 random bytes written in the header and encrypted in the body. If the bytes do not match when
1323 loading a file then the wrong master key was used or the file is corrupt. Only KDBX 2 and KDBX 3 files use
1324 this. KDBX 4 files use an improved HMAC method to verify the master key and data integrity of the header and
1327 =head2 inner_random_stream_id
1329 A number indicating the cipher algorithm used to encrypt the protected strings within the database, usually
1330 Salsa20 or ChaCha20. See L<File::KDBX::Constants/":random_stream">.
1332 =head2 kdf_parameters
1334 A hash/dict of key-value pairs used to configure the key derivation function. This is the KDBX4+ way to
1335 configure the KDF, superceding L</transform_seed> and L</transform_rounds>.
1339 The name of the software used to generate the KDBX file.
1343 The header hash used to verify that the file header is not corrupt. (KDBX 2 - KDBX 3.1, removed KDBX 4.0)
1345 =head2 database_name
1347 Name of the database.
1349 =head2 database_name_changed
1351 Timestamp indicating when the database name was last changed.
1353 =head2 database_description
1355 Description of the database
1357 =head2 database_description_changed
1359 Timestamp indicating when the database description was last changed.
1361 =head2 default_username
1363 When a new entry is created, the I<UserName> string will be populated with this value.
1365 =head2 default_username_changed
1367 Timestamp indicating when the default username was last changed.
1371 A color associated with the database (in the form C<#ffffff> where "f" is a hexidecimal digit). Some agents
1372 use this to help users visually distinguish between different databases.
1374 =head2 master_key_changed
1376 Timestamp indicating when the master key was last changed.
1378 =head2 master_key_change_rec
1380 Number of days until the agent should prompt to recommend changing the master key.
1382 =head2 master_key_change_force
1384 Number of days until the agent should prompt to force changing the master key.
1386 Note: This is purely advisory. It is up to the individual agent software to actually enforce it.
1387 C<File::KDBX> does NOT enforce it.
1391 Array of custom icons that can be associated with groups and entries.
1393 This list can be managed with the methods L</add_custom_icon> and L</remove_custom_icon>.
1395 =head2 recycle_bin_enabled
1397 Boolean indicating whether removed groups and entries should go to a recycle bin or be immediately deleted.
1399 =head2 recycle_bin_uuid
1401 The UUID of a group used to store thrown-away groups and entries.
1403 =head2 recycle_bin_changed
1405 Timestamp indicating when the recycle bin group was last changed.
1407 =head2 entry_templates_group
1409 The UUID of a group containing template entries used when creating new entries.
1411 =head2 entry_templates_group_changed
1413 Timestamp indicating when the entry templates group was last changed.
1415 =head2 last_selected_group
1417 The UUID of the previously-selected group.
1419 =head2 last_top_visible_group
1421 The UUID of the group visible at the top of the list.
1423 =head2 history_max_items
1425 The maximum number of historical entries that should be kept for each entry. Default is 10.
1427 =head2 history_max_size
1429 The maximum total size (in bytes) that each individual entry's history is allowed to grow. Default is 6 MiB.
1431 =head2 maintenance_history_days
1433 The maximum age (in days) historical entries should be kept. Default it 365.
1435 =head2 settings_changed
1437 Timestamp indicating when the database settings were last updated.
1439 =head2 protect_title
1441 Alias of the L</memory_protection> setting for the I<Title> string.
1443 =head2 protect_username
1445 Alias of the L</memory_protection> setting for the I<UserName> string.
1447 =head2 protect_password
1449 Alias of the L</memory_protection> setting for the I<Password> string.
1453 Alias of the L</memory_protection> setting for the I<URL> string.
1455 =head2 protect_notes
1457 Alias of the L</memory_protection> setting for the I<Notes> string.
1463 $kdbx = File::KDBX->new(%attributes);
1464 $kdbx = File::KDBX->new($kdbx); # copy constructor
1466 Construct a new L<File::KDBX>.
1470 $kdbx = $kdbx->init(%attributes);
1472 Initialize a L<File::KDBX> with a set of attributes. Returns itself to allow method chaining.
1474 This is called by L</new>.
1478 $kdbx = $kdbx->reset;
1480 Set a L<File::KDBX> to an empty state, ready to load a KDBX file or build a new one. Returns itself to allow
1485 $kdbx_copy = $kdbx->clone;
1486 $kdbx_copy = File::KDBX->new($kdbx);
1488 Clone a L<File::KDBX>. The clone will be an exact copy and completely independent of the original.
1498 $kdbx = KDBX::File->load(\$string, $key);
1499 $kdbx = KDBX::File->load(*IO, $key);
1500 $kdbx = KDBX::File->load($filepath, $key);
1501 $kdbx->load(...); # also instance method
1503 $kdbx = File::KDBX->load_string($string, $key);
1504 $kdbx = File::KDBX->load_string(\$string, $key);
1505 $kdbx->load_string(...); # also instance method
1507 $kdbx = File::KDBX->load_file($filepath, $key);
1508 $kdbx->load_file(...); # also instance method
1510 $kdbx = File::KDBX->load_handle($fh, $key);
1511 $kdbx = File::KDBX->load_handle(*IO, $key);
1512 $kdbx->load_handle(...); # also instance method
1514 Load a KDBX file from a string buffer, IO handle or file from a filesystem.
1516 L<File::KDBX::Loader> does the heavy lifting.
1526 $kdbx->dump(\$string, $key);
1527 $kdbx->dump(*IO, $key);
1528 $kdbx->dump($filepath, $key);
1530 $kdbx->dump_string(\$string, $key);
1531 \$string = $kdbx->dump_string($key);
1533 $kdbx->dump_file($filepath, $key);
1535 $kdbx->dump_handle($fh, $key);
1536 $kdbx->dump_handle(*IO, $key);
1538 Dump a KDBX file to a string buffer, IO handle or file in a filesystem.
1540 L<File::KDBX::Dumper> does the heavy lifting.
1542 =head2 user_agent_string
1544 $string = $kdbx->user_agent_string;
1546 Get a text string identifying the database client software.
1548 =head2 memory_protection
1550 \%settings = $kdbx->memory_protection
1551 $kdbx->memory_protection(\%settings);
1553 $bool = $kdbx->memory_protection($string_key);
1554 $kdbx->memory_protection($string_key => $bool);
1556 Get or set memory protection settings. This globally (for the whole database) configures whether and which of
1557 the standard strings should be memory-protected. The default setting is to memory-protect only I<Password>
1560 Memory protection can be toggled individually for each entry string, and individual settings take precedence
1561 over these global settings.
1563 =head2 minimum_version
1565 $version = $kdbx->minimum_version;
1567 Determine the minimum file version required to save a database losslessly. Using certain databases features
1568 might increase this value. For example, setting the KDF to Argon2 will increase the minimum version to at
1569 least C<KDBX_VERSION_4_0> (i.e. C<0x00040000>) because Argon2 was introduced with KDBX4.
1571 This method never returns less than C<KDBX_VERSION_3_1> (i.e. C<0x00030001>). That file version is so
1572 ubiquitious and well-supported, there are seldom reasons to dump in a lesser format nowadays.
1574 B<WARNING:> If you dump a database with a minimum version higher than the current L</version>, the dumper will
1575 typically issue a warning and automatically upgrade the database. This seems like the safest behavior in order
1576 to avoid data loss, but lower versions have the benefit of being compatible with more software. It is possible
1577 to prevent auto-upgrades by explicitly telling the dumper which version to use, but you do run the risk of
1578 data loss. A database will never be automatically downgraded.
1582 $group = $kdbx->root;
1583 $kdbx->root($group);
1585 Get or set a database's root group. You don't necessarily need to explicitly create or set a root group
1586 because it autovivifies when adding entries and groups to the database.
1588 Every database has only a single root group at a time. Some old KDB files might have multiple root groups.
1589 When reading such files, a single implicit root group is created to contain the actual root groups. When
1590 writing to such a format, if the root group looks like it was implicitly created then it won't be written and
1591 the resulting file might have multiple root groups, as it was before loading. This allows working with older
1592 files without changing their written internal structure while still adhering to modern semantics while the
1595 The root group of a KDBX database contains all of the database's entries and other groups. If you replace the
1596 root group, you are essentially replacing the entire database contents with something else.
1598 =head2 trace_lineage
1600 \@lineage = $kdbx->trace_lineage($group);
1601 \@lineage = $kdbx->trace_lineage($group, $base_group);
1602 \@lineage = $kdbx->trace_lineage($entry);
1603 \@lineage = $kdbx->trace_lineage($entry, $base_group);
1605 Get the direct line of ancestors from C<$base_group> (default: the root group) to a group or entry. The
1606 lineage includes the base group but I<not> the target group or entry. Returns C<undef> if the target is not in
1607 the database structure.
1611 $group = $kdbx->recycle_bin;
1612 $kdbx->recycle_bin($group);
1614 Get or set the recycle bin group. Returns C<undef> if there is no recycle bin and L</recycle_bin_enabled> is
1615 false, otherwise the current recycle bin or an autovivified recycle bin group is returned.
1617 =head2 entry_templates
1619 $group = $kdbx->entry_templates;
1620 $kdbx->entry_templates($group);
1622 Get or set the entry templates group. May return C<undef> if unset.
1624 =head2 last_selected
1626 $group = $kdbx->last_selected;
1627 $kdbx->last_selected($group);
1629 Get or set the last selected group. May return C<undef> if unset.
1631 =head2 last_top_visible
1633 $group = $kdbx->last_top_visible;
1634 $kdbx->last_top_visible($group);
1636 Get or set the last top visible group. May return C<undef> if unset.
1640 $kdbx->add_group($group);
1641 $kdbx->add_group(%group_attributes, %options);
1643 Add a group to a database. This is equivalent to identifying a parent group and calling
1644 L<File::KDBX::Group/add_group> on the parent group, forwarding the arguments. Available options:
1650 C<group> - Group object or group UUID to add the group to (default: root group)
1656 \&iterator = $kdbx->groups(%options);
1657 \&iterator = $kdbx->groups($base_group, %options);
1659 Get an L<File::KDBX::Iterator> over I<groups> within a database. Options:
1665 C<base> - Only include groups within a base group (same as C<$base_group>) (default: L</root>)
1669 C<inclusive> - Include the base group in the results (default: true)
1673 C<algorithm> - Search algorithm, one of C<ids>, C<bfs> or C<dfs> (default: C<ids>)
1679 $kdbx->add_entry($entry, %options);
1680 $kdbx->add_entry(%entry_attributes, %options);
1682 Add a entry to a database. This is equivalent to identifying a parent group and calling
1683 L<File::KDBX::Group/add_entry> on the parent group, forwarding the arguments. Available options:
1689 C<group> - Group object or group UUID to add the entry to (default: root group)
1695 \&iterator = $kdbx->entries(%options);
1696 \&iterator = $kdbx->entries($base_group, %options);
1698 Get an L<File::KDBX::Iterator> over I<entries> within a database. Supports the same options as L</groups>,
1705 C<auto_type> - Only include entries with auto-type enabled (default: false, include all)
1709 C<searching> - Only include entries within groups with searching enabled (default: false, include all)
1713 C<history> - Also include historical entries (default: false, include only current entries)
1719 \&iterator = $kdbx->objects(%options);
1720 \&iterator = $kdbx->objects($base_group, %options);
1722 Get an L<File::KDBX::Iterator> over I<objects> within a database. Groups and entries are considered objects,
1723 so this is essentially a combination of L</groups> and L</entries>. This won't often be useful, but it can be
1724 convenient for maintenance tasks. This method takes the same options as L</groups> and L</entries>.
1728 \%icon = $kdbx->custom_icon($uuid);
1729 $kdbx->custom_icon($uuid => \%icon);
1730 $kdbx->custom_icon(%icon);
1731 $kdbx->custom_icon(uuid => $value, %icon);
1733 Get or set custom icons.
1735 =head2 custom_icon_data
1737 $image_data = $kdbx->custom_icon_data($uuid);
1739 Get a custom icon image data.
1741 =head2 add_custom_icon
1743 $uuid = $kdbx->add_custom_icon($image_data, %attributes);
1744 $uuid = $kdbx->add_custom_icon(%attributes);
1746 Add a custom icon and get its UUID. If not provided, a random UUID will be generated. Possible attributes:
1752 C<uuid> - Icon UUID (default: autogenerated)
1756 C<data> - Image data (same as C<$image_data>)
1760 C<name> - Name of the icon (text, KDBX4.1+)
1764 C<last_modification_time> - Just what it says (datetime, KDBX4.1+)
1768 =head2 remove_custom_icon
1770 $kdbx->remove_custom_icon($uuid);
1772 Remove a custom icon.
1776 \%all_data = $kdbx->custom_data;
1777 $kdbx->custom_data(\%all_data);
1779 \%data = $kdbx->custom_data($key);
1780 $kdbx->custom_data($key => \%data);
1781 $kdbx->custom_data(%data);
1782 $kdbx->custom_data(key => $value, %data);
1784 Get and set custom data. Custom data is metadata associated with a database.
1786 Each data item can have a few attributes associated with it.
1792 C<key> - A unique text string identifier used to look up the data item (required)
1796 C<value> - A text string value (required)
1800 C<last_modification_time> (optional, KDBX4.1+)
1804 =head2 custom_data_value
1806 $value = $kdbx->custom_data_value($key);
1808 Exactly the same as L</custom_data> except returns just the custom data's value rather than a structure of
1809 attributes. This is a shortcut for:
1811 my $data = $kdbx->custom_data($key);
1812 my $value = defined $data ? $data->{value} : undef;
1814 =head2 public_custom_data
1816 \%all_data = $kdbx->public_custom_data;
1817 $kdbx->public_custom_data(\%all_data);
1819 $value = $kdbx->public_custom_data($key);
1820 $kdbx->public_custom_data($key => $value);
1822 Get and set public custom data. Public custom data is similar to custom data but different in some important
1823 ways. Public custom data:
1829 can store strings, booleans and up to 64-bit integer values (custom data can only store text values)
1833 is NOT encrypted within a KDBX file (hence the "public" part of the name)
1837 is a plain hash/dict of key-value pairs with no other associated fields (like modification times)
1841 =head2 add_deleted_object
1843 $kdbx->add_deleted_object($uuid);
1845 Add a UUID to the deleted objects list. This list is used to support automatic database merging.
1847 You typically do not need to call this yourself because the list will be populated automatically as objects
1850 =head2 remove_deleted_object
1852 $kdbx->remove_deleted_object($uuid);
1854 Remove a UUID from the deleted objects list. This list is used to support automatic database merging.
1856 You typically do not need to call this yourself because the list will be maintained automatically as objects
1859 =head2 clear_deleted_objects
1861 Remove all UUIDs from the deleted objects list. This list is used to support automatic database merging, but
1862 if you don't need merging then you can clear deleted objects to reduce the database file size.
1864 =head2 resolve_reference
1866 $string = $kdbx->resolve_reference($reference);
1867 $string = $kdbx->resolve_reference($wanted, $search_in, $expression);
1869 Resolve a L<field reference|https://keepass.info/help/base/fieldrefs.html>. A field reference is a kind of
1870 string placeholder. You can use a field reference to refer directly to a standard field within an entry. Field
1871 references are resolved automatically while expanding entry strings (i.e. replacing placeholders), but you can
1872 use this method to resolve on-the-fly references that aren't part of any actual string in the database.
1874 If the reference does not resolve to any field, C<undef> is returned. If the reference resolves to multiple
1875 fields, only the first one is returned (in the same order as iterated by L</entries>). To avoid ambiguity, you
1876 can refer to a specific entry by its UUID.
1878 The syntax of a reference is: C<< {REF:<WantedField>@<SearchIn>:<Text>} >>. C<Text> is a
1879 L</"Simple Expression">. C<WantedField> and C<SearchIn> are both single character codes representing a field:
1909 C<O> - Other custom strings
1913 Since C<O> does not represent any specific field, it cannot be used as the C<WantedField>.
1917 To get the value of the I<UserName> string of the first entry with "My Bank" in the title:
1919 my $username = $kdbx->resolve_reference('{REF:U@T:"My Bank"}');
1920 # OR the {REF:...} wrapper is optional
1921 my $username = $kdbx->resolve_reference('U@T:"My Bank"');
1922 # OR separate the arguments
1923 my $username = $kdbx->resolve_reference(U => T => '"My Bank"');
1925 Note how the text is a L</"Simple Expression">, so search terms with spaces must be surrounded in double
1928 To get the I<Password> string of a specific entry (identified by its UUID):
1930 my $password = $kdbx->resolve_reference('{REF:P@I:46C9B1FFBD4ABC4BBB260C6190BAD20C}');
1936 Encrypt all protected binaries strings in a database. The encrypted strings are stored in
1937 a L<File::KDBX::Safe> associated with the database and the actual strings will be replaced with C<undef> to
1938 indicate their protected state. Returns itself to allow method chaining.
1940 You can call C<code> on an already-locked database to memory-protect any unprotected strings and binaries
1941 added after the last time the database was locked.
1947 Decrypt all protected strings in a database, replacing C<undef> placeholders with unprotected values. Returns
1948 itself to allow method chaining.
1950 =head2 unlock_scoped
1952 $guard = $kdbx->unlock_scoped;
1954 Unlock a database temporarily, relocking when the guard is released (typically at the end of a scope). Returns
1955 C<undef> if the database is already unlocked.
1957 See L</lock> and L</unlock>.
1961 $string = $kdbx->peek(\%string);
1962 $string = $kdbx->peek(\%binary);
1964 Peek at the value of a protected string or binary without unlocking the whole database. The argument can be
1965 a string or binary hashref as returned by L<File::KDBX::Entry/string> or L<File::KDBX::Entry/binary>.
1969 $bool = $kdbx->is_locked;
1971 Get whether or not a database's strings are memory-protected. If this is true, then some or all of the
1972 protected strings within the database will be unavailable (literally have C<undef> values) until L</unlock> is
1975 =head2 remove_empty_groups
1977 $kdbx->remove_empty_groups;
1979 Remove groups with no subgroups and no entries.
1981 =head2 remove_unused_icons
1983 $kdbx->remove_unused_icons;
1985 Remove icons that are not associated with any entry or group in the database.
1987 =head2 remove_duplicate_icons
1989 $kdbx->remove_duplicate_icons;
1991 Remove duplicate icons as determined by hashing the icon data.
1993 =head2 prune_history
1995 $kdbx->prune_history(%options);
1997 Remove just as many older historical entries as necessary to get under certain limits.
2003 C<max_items> - Maximum number of historical entries to keep (default: value of L</history_max_items>, no limit: -1)
2007 C<max_size> - Maximum total size (in bytes) of historical entries to keep (default: value of L</history_max_size>, no limit: -1)
2011 C<max_age> - Maximum age (in days) of historical entries to keep (default: 365, no limit: -1)
2015 =head2 randomize_seeds
2017 $kdbx->randomize_seeds;
2019 Set various keys, seeds and IVs to random values. These values are used by the cryptographic functions that
2020 secure the database when dumped. The attributes that will be randomized are:
2030 L</inner_random_stream_key>
2038 L</stream_start_bytes>
2046 Randomizing these values has no effect on a loaded database. These are only used when a database is dumped.
2047 You normally do not need to call this method explicitly because the dumper does it explicitly by default.
2052 $key = $kdbx->key($key);
2053 $key = $kdbx->key($primitive);
2055 Get or set a L<File::KDBX::Key>. This is the master key (e.g. a password or a key file that can decrypt
2056 a database). You can also pass a primitive that can be cast to a B<Key>. See L<File::KDBX::Key/new> for an
2057 explanation of what the primitive can be.
2059 You generally don't need to call this directly because you can provide the key directly to the loader or
2060 dumper when loading or dumping a KDBX file.
2062 =head2 composite_key
2064 $key = $kdbx->composite_key($key);
2065 $key = $kdbx->composite_key($primitive);
2067 Construct a L<File::KDBX::Key::Composite> from a B<Key> or primitive. See L<File::KDBX::Key/new> for an
2068 explanation of what the primitive can be. If the primitive does not represent a composite key, it will be
2071 You generally don't need to call this directly. The loader and dumper use it to transform a master key into
2072 a raw encryption key.
2076 $kdf = $kdbx->kdf(%options);
2077 $kdf = $kdbx->kdf(\%parameters, %options);
2079 Get a L<File::KDBX::KDF> (key derivation function).
2087 C<params> - KDF parameters, same as C<\%parameters> (default: value of L</kdf_parameters>)
2093 $cipher = $kdbx->cipher(key => $key);
2094 $cipher = $kdbx->cipher(key => $key, iv => $iv, uuid => $uuid);
2096 Get a L<File::KDBX::Cipher> capable of encrypting and decrypting the body of a database file.
2098 A key is required. This should be a raw encryption key made up of a fixed number of octets (depending on the
2099 cipher), not a L<File::KDBX::Key> or primitive.
2101 If not passed, the UUID comes from C<< $kdbx->headers->{cipher_id} >> and the encryption IV comes from
2102 C<< $kdbx->headers->{encryption_iv} >>.
2104 You generally don't need to call this directly. The loader and dumper use it to decrypt and encrypt KDBX
2107 =head2 random_stream
2109 $cipher = $kdbx->random_stream;
2110 $cipher = $kdbx->random_stream(id => $stream_id, key => $key);
2112 Get a L<File::KDBX::Cipher::Stream> for decrypting and encrypting protected values.
2114 If not passed, the ID and encryption key comes from C<< $kdbx->headers->{inner_random_stream_id} >> and
2115 C<< $kdbx->headers->{inner_random_stream_key} >> (respectively) for KDBX3 files and from
2116 C<< $kdbx->inner_headers->{inner_random_stream_key} >> and
2117 C<< $kdbx->inner_headers->{inner_random_stream_id} >> (respectively) for KDBX4 files.
2119 You generally don't need to call this directly. The loader and dumper use it to scramble protected strings.
2121 =for Pod::Coverage STORABLE_freeze STORABLE_thaw TO_JSON
2125 =head2 Create a new database
2127 my $kdbx = File::KDBX->new;
2129 my $group = $kdbx->add_group(name => 'Passwords);
2130 my $entry = $group->add_entry(
2131 title => 'WayneCorp',
2132 username => 'bwayne',
2133 password => 'iambatman',
2134 url => 'https://example.com/login'
2136 $entry->add_auto_type_window_association('WayneCorp - Mozilla Firefox', '{PASSWORD}{ENTER}');
2138 $kdbx->dump_file('mypasswords.kdbx', 'master password CHANGEME');
2140 =head2 Read an existing database
2142 my $kdbx = File::KDBX->load_file('mypasswords.kdbx', 'master password CHANGEME');
2143 $kdbx->unlock; # cause $entry->password below to be defined
2145 $kdbx->entries->each(sub {
2147 say 'Found password for: ', $entry->title;
2148 say ' Username: ', $entry->username;
2149 say ' Password: ', $entry->password;
2152 =head2 Search for entries
2154 my @entries = $kdbx->entries(searching => 1)
2155 ->grep(title => 'WayneCorp')
2156 ->each; # return all matches
2158 The C<searching> option limits results to only entries within groups with searching enabled. Other options are
2159 also available. See L</entries>.
2161 See L</QUERY> for many more query examples.
2163 =head2 Search for entries by auto-type window association
2165 my $window_title = 'WayneCorp - Mozilla Firefox';
2167 my $entries = $kdbx->entries(auto_type => 1)
2169 my ($ata) = grep { $_->{window} =~ /\Q$window_title\E/i } @{$_->auto_type_associations};
2170 return [$_, $ata->{keystroke_sequence}] if $ata;
2173 my ($entry, $keys) = @$_;
2174 say 'Entry title: ', $entry->title, ', key sequence: ', $keys;
2179 Entry title: WayneCorp, key sequence: {PASSWORD}{ENTER}
2181 =head2 Remove entries from a database
2184 ->grep(notes => {'=~' => qr/too old/i})
2185 ->each(sub { $_->recycle });
2187 Recycle all entries with the string "too old" appearing in the B<Notes> string.
2189 =head2 Remove empty groups
2191 $kdbx->groups(algorithm => 'dfs')
2192 ->where(-true => 'is_empty')
2195 With the search/iteration C<algorithm> set to "dfs", groups will be ordered deepest first and the root group
2196 will be last. This allows removing groups that only contain empty groups.
2198 This can also be done with one call to L</remove_empty_groups>.
2202 One of the biggest threats to your database security is how easily the encryption key can be brute-forced.
2203 Strong brute-force protection depends on:
2209 Using unguessable passwords, passphrases and key files.
2213 Using a brute-force resistent key derivation function.
2217 The first factor is up to you. This module does not enforce strong master keys. It is up to you to pick or
2218 generate strong keys.
2220 The KDBX format allows for the key derivation function to be tuned. The idea is that you want each single
2221 brute-foce attempt to be expensive (in terms of time, CPU usage or memory usage), so that making a lot of
2222 attempts (which would be required if you have a strong master key) gets I<really> expensive.
2224 How expensive you want to make each attempt is up to you and can depend on the application.
2226 This and other KDBX-related security issues are covered here more in depth:
2227 L<https://keepass.info/help/base/security.html>
2229 Here are other security risks you should be thinking about:
2233 This distribution uses the excellent L<CryptX> and L<Crypt::Argon2> packages to handle all crypto-related
2234 functions. As such, a lot of the security depends on the quality of these dependencies. Fortunately these
2235 modules are maintained and appear to have good track records.
2237 The KDBX format has evolved over time to incorporate improved security practices and cryptographic functions.
2238 This package uses the following functions for authentication, hashing, encryption and random number
2281 At the time of this writing, I am not aware of any successful attacks against any of these functions. These
2282 are among the most-analyzed and widely-adopted crypto functions available.
2284 The KDBX format allows the body cipher and key derivation function to be configured. If a flaw is discovered
2285 in one of these functions, you can hopefully just switch to a better function without needing to update this
2286 software. A later software release may phase out the use of any functions which are no longer secure.
2288 =head2 Memory Protection
2290 It is not a good idea to keep secret information unencrypted in system memory for longer than is needed. The
2291 address space of your program can generally be read by a user with elevated privileges on the system. If your
2292 system is memory-constrained or goes into a hibernation mode, the contents of your address space could be
2293 written to a disk where it might be persisted for long time.
2295 There might be system-level things you can do to reduce your risk, like using swap encryption and limiting
2296 system access to your program's address space while your program is running.
2298 B<File::KDBX> helps minimize (but not eliminate) risk by keeping secrets encrypted in memory until accessed
2299 and zeroing out memory that holds secrets after they're no longer needed, but it's not a silver bullet.
2301 For one thing, the encryption key is stored in the same address space. If core is dumped, the encryption key
2302 is available to be found out. But at least there is the chance that the encryption key and the encrypted
2303 secrets won't both be paged out together while memory-constrained.
2305 Another problem is that some perls (somewhat notoriously) copy around memory behind the scenes willy nilly,
2306 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
2307 be impossible. The good news is that perls with SvPV copy-on-write (enabled by default beginning with perl
2308 5.20) are much better in this regard. With COW, it's mostly possible to know what operations will cause perl
2309 to copy the memory of a scalar string, and the number of copies will be significantly reduced. There is a unit
2310 test named F<t/memory-protection.t> in this distribution that can be run on POSIX systems to determine how
2311 well B<File::KDBX> memory protection is working.
2313 Memory protection also depends on how your application handles secrets. If your app code is handling scalar
2314 strings with secret information, it's up to you to make sure its memory is zeroed out when no longer needed.
2315 L<File::KDBX::Util/erase> et al. provide some tools to help accomplish this. Or if you're not too concerned
2316 about the risks memory protection is meant to mitigate, then maybe don't worry about it. The security policy
2317 of B<File::KDBX> is to try hard to keep secrets protected while in memory so that your app might claim a high
2318 level of security, in case you care about that.
2320 There are some memory protection strategies that B<File::KDBX> does NOT use today but could in the future:
2322 Many systems allow programs to mark unswappable pages. Secret information should ideally be stored in such
2323 pages. You could potentially use L<mlockall(2)> (or equivalent for your system) in your own application to
2324 prevent the entire address space from being swapped.
2326 Some systems provide special syscalls for storing secrets in memory while keeping the encryption key outside
2327 of the program's address space, like C<CryptProtectMemory> for Windows. This could be a good option, though
2328 unfortunately not portable.
2332 To find things in a KDBX database, you should use a filtered iterator. If you have an iterator, such as
2333 returned by L</entries>, L</groups> or even L</objects> you can filter it using L<File::KDBX::Iterator/where>.
2335 my $filtered_entries = $kdbx->entries->where(\&query);
2337 A C<\&query> is just a subroutine that you can either write yourself or have generated for you from either
2338 a L</"Simple Expression"> or L</"Declarative Syntax">. It's easier to have your query generated, so I'll cover
2341 =head2 Simple Expression
2343 A simple expression is mostly compatible with the KeePass 2 implementation
2344 L<described here|https://keepass.info/help/base/search.html#mode_se>.
2346 An expression is a string with one or more space-separated terms. Terms with spaces can be enclosed in double
2347 quotes. Terms are negated if they are prefixed with a minus sign. A record must match every term on at least
2348 one of the given fields.
2350 So a simple expression is something like what you might type into a search engine. You can generate a simple
2351 expression query using L<File::KDBX::Util/simple_expression_query> or by passing the simple expression as
2352 a B<scalar reference> to C<where>.
2354 To search for all entries in a database with the word "canyon" appearing anywhere in the title:
2356 my $entries = $kdbx->entries->where(\'canyon', qw[title]);
2358 Notice the first argument is a B<scalarref>. This disambiguates a simple expression from other types of
2359 queries covered below.
2361 As mentioned, a simple expression can have multiple terms. This simple expression query matches any entry that
2362 has the words "red" B<and> "canyon" anywhere in the title:
2364 my $entries = $kdbx->entries->where(\'red canyon', qw[title]);
2366 Each term in the simple expression must be found for an entry to match.
2368 To search for entries with "red" in the title but B<not> "canyon", just prepend "canyon" with a minus sign:
2370 my $entries = $kdbx->entries->where(\'red -canyon', qw[title]);
2372 To search over multiple fields simultaneously, just list them all. To search for entries with "grocery" (but
2373 not "Foodland") in the title or notes:
2375 my $entries = $kdbx->entries->where(\'grocery -Foodland', qw[title notes]);
2377 The default operator is a case-insensitive regexp match, which is fine for searching text loosely. You can use
2378 just about any binary comparison operator that perl supports. To specify an operator, list it after the simple
2379 expression. For example, to search for any entry that has been used at least five times:
2381 my $entries = $kdbx->entries->where(\5, '>=', qw[usage_count]);
2383 It helps to read it right-to-left, like "usage_count is greater than or equal to 5".
2385 If you find the disambiguating structures to be distracting or confusing, you can also the
2386 L<File::KDBX::Util/simple_expression_query> function as a more intuitive alternative. The following example is
2387 equivalent to the previous:
2389 my $entries = $kdbx->entries->where(simple_expression_query(5, '>=', qw[usage_count]));
2391 =head2 Declarative Syntax
2393 Structuring a declarative query is similar to L<SQL::Abstract/"WHERE CLAUSES">, but you don't have to be
2394 familiar with that module. Just learn by examples here.
2396 To search for all entries in a database titled "My Bank":
2398 my $entries = $kdbx->entries->where({ title => 'My Bank' });
2400 The query here is C<< { title => 'My Bank' } >>. A hashref can contain key-value pairs where the key is an
2401 attribute of the thing being searched for (in this case an entry) and the value is what you want the thing's
2402 attribute to be to consider it a match. In this case, the attribute we're using as our match criteria is
2403 L<File::KDBX::Entry/title>, a text field. If an entry has its title attribute equal to "My Bank", it's
2406 A hashref can contain multiple attributes. The search candidate will be a match if I<all> of the specified
2407 attributes are equal to their respective values. For example, to search for all entries with a particular URL
2410 my $entries = $kdbx->entries->where({
2411 url => 'https://example.com',
2415 To search for entries matching I<any> criteria, just change the hashref to an arrayref. To search for entries
2416 with a particular URL B<OR> username:
2418 my $entries = $kdbx->entries->where([ # <-- Notice the square bracket
2419 url => 'https://example.com',
2423 You can use different operators to test different types of attributes. The L<File::KDBX::Entry/icon_id>
2424 attribute is a number, so we should use a number comparison operator. To find entries using the smartphone
2427 my $entries = $kdbx->entries->where({
2428 icon_id => { '==', ICON_SMARTPHONE },
2431 Note: L<File::KDBX::Constants/ICON_SMARTPHONE> is just a constant from L<File::KDBX::Constants>. It isn't
2432 special to this example or to queries generally. We could have just used a literal number.
2434 The important thing to notice here is how we wrapped the condition in another arrayref with a single key-value
2435 pair where the key is the name of an operator and the value is the thing to match against. The supported
2442 C<eq> - String equal
2446 C<ne> - String not equal
2450 C<lt> - String less than
2454 C<gt> - String greater than
2458 C<le> - String less than or equal
2462 C<ge> - String greater than or equal
2466 C<==> - Number equal
2470 C<!=> - Number not equal
2474 C<< < >> - Number less than
2478 C<< > >> - Number greater than
2482 C<< <= >> - Number less than or equal
2486 C<< >= >> - Number less than or equal
2490 C<=~> - String match regular expression
2494 C<!~> - String does not match regular expression
2498 C<!> - Boolean false
2502 C<!!> - Boolean true
2506 Other special operators:
2512 C<-true> - Boolean true
2516 C<-false> - Boolean false
2520 C<-not> - Boolean false (alias for C<-false>)
2524 C<-defined> - Is defined
2528 C<-undef> - Is not defined
2532 C<-empty> - Is empty
2536 C<-nonempty> - Is not empty
2544 C<-and> - Logical and
2548 Let's see another example using an explicit operator. To find all groups except one in particular (identified
2549 by its L<File::KDBX::Group/uuid>), we can use the C<ne> (string not equal) operator:
2551 my $groups = $kdbx->groups->where(
2553 'ne' => uuid('596f7520-6172-6520-7370-656369616c2e'),
2557 Note: L<File::KDBX::Util/uuid> is a little utility function to convert a UUID in its pretty form into bytes.
2558 This utility function isn't special to this example or to queries generally. It could have been written with
2559 a literal such as C<"\x59\x6f\x75\x20\x61...">, but that's harder to read.
2561 Notice we searched for groups this time. Finding groups works exactly the same as it does for entries.
2563 Notice also that we didn't wrap the query in hashref curly-braces or arrayref square-braces. Those are
2564 optional. By default it will only match ALL attributes (as if there were curly-braces).
2566 Testing the truthiness of an attribute is a little bit different because it isn't a binary operation. To find
2567 all entries with the password quality check disabled:
2569 my $entries = $kdbx->entries->where('!' => 'quality_check');
2571 This time the string after the operator is the attribute name rather than a value to compare the attribute
2572 against. To test that a boolean value is true, use the C<!!> operator (or C<-true> if C<!!> seems a little too
2573 weird for your taste):
2575 my $entries = $kdbx->entries->where('!!' => 'quality_check');
2576 my $entries = $kdbx->entries->where(-true => 'quality_check'); # same thing
2578 Yes, there is also a C<-false> and a C<-not> if you prefer one of those over C<!>. C<-false> and C<-not>
2579 (along with C<-true>) are also special in that you can use them to invert the logic of a subquery. These are
2580 logically equivalent:
2582 my $entries = $kdbx->entries->where(-not => { title => 'My Bank' });
2583 my $entries = $kdbx->entries->where(title => { 'ne' => 'My Bank' });
2585 These special operators become more useful when combined with two more special operators: C<-and> and C<-or>.
2586 With these, it is possible to construct more interesting queries with groups of logic. For example:
2588 my $entries = $kdbx->entries->where({
2589 title => { '=~', qr/bank/ },
2592 notes => { '=~', qr/business/ },
2593 icon_id => { '==', ICON_TRASHCAN_FULL },
2598 In English, find entries where the word "bank" appears anywhere in the title but also do not have either the
2599 word "business" in the notes or are using the full trashcan icon.
2601 =head2 Subroutine Query
2603 Lastly, as mentioned at the top, you can ignore all this and write your own subroutine. Your subroutine will
2604 be called once for each object being searched over. The subroutine should match the candidate against whatever
2605 criteria you want and return true if it matches or false to skip. To do this, just pass your subroutine
2606 coderef to C<where>.
2608 To review the different types of queries, these are all equivalent to find all entries in the database titled
2611 my $entries = $kdbx->entries->where(\'"My Bank"', 'eq', qw[title]); # simple expression
2612 my $entries = $kdbx->entries->where(title => 'My Bank'); # declarative syntax
2613 my $entries = $kdbx->entries->where(sub { $_->title eq 'My Bank' }); # subroutine query
2615 This is a trivial example, but of course your subroutine can be arbitrarily complex.
2617 All of these query mechanisms described in this section are just tools, each with its own set of limitations.
2618 If the tools are getting in your way, you can of course iterate over the contents of a database and implement
2619 your own query logic, like this:
2621 my $entries = $kdbx->entries;
2622 while (my $entry = $entries->next) {
2623 if (wanted($entry)) {
2624 do_something($entry);
2633 Iterators are the built-in way to navigate or walk the database tree. You get an iterator from L</entries>,
2634 L</groups> and L</objects>. You can specify the search algorithm to iterate over objects in different orders
2635 using the C<algorith> option, which can be one of these L<constants|File::KDBX::Constants/":iteration">:
2641 C<ITERATION_IDS> - Iterative deepening search (default)
2645 C<ITERATION_DFS> - Depth-first search
2649 C<ITERATION_BFS> - Breadth-first search
2653 When iterating over objects generically, groups always precede their direct entries (if any). When the
2654 C<history> option is used, current entries always precede historical entries.
2656 If you have a database tree like this:
2671 IDS order of groups is: Root, Group1, Group2, Group3
2675 IDS order of entries is: EntryA, EntryB, EntryC
2679 IDS order of objects is: Root, Group1, EntryA, Group2, EntryB, Group3, EntryC
2683 DFS order of groups is: Group2, Group1, Group3, Root
2687 DFS order of entries is: EntryB, EntryA, EntryC
2691 DFS order of objects is: Group2, EntryB, Group1, EntryA, Group3, EntryC, Root
2695 BFS order of groups is: Root, Group1, Group3, Group2
2699 BFS order of entries is: EntryA, EntryC, EntryB
2703 BFS order of objects is: Root, Group1, EntryA, Group3, EntryC, Group2, EntryB
2707 =head1 SYNCHRONIZING
2709 B<TODO> - This is a planned feature, not yet implemented.
2713 Errors in this package are constructed as L<File::KDBX::Error> objects and propagated using perl's built-in
2714 mechanisms. Fatal errors are propagated using L<functions/die> and non-fatal errors (a.k.a. warnings) are
2715 propagated using L<functions/warn> while adhering to perl's L<warnings> system. If you're already familiar
2716 with these mechanisms, you can skip this section.
2718 You can catch fatal errors using L<functions/eval> (or something like L<Try::Tiny>) and non-fatal errors using
2719 C<$SIG{__WARN__}> (see L<variables/%SIG>). Examples:
2721 use File::KDBX::Error qw(error);
2723 my $key = ''; # uh oh
2725 $kdbx->load_file('whatever.kdbx', $key);
2727 if (my $error = error($@)) {
2728 handle_missing_key($error) if $error->type eq 'key.missing';
2732 or using C<Try::Tiny>:
2735 $kdbx->load_file('whatever.kdbx', $key);
2741 Catching non-fatal errors:
2744 local $SIG{__WARN__} = sub { push @warnings, $_[0] };
2746 $kdbx->load_file('whatever.kdbx', $key);
2748 handle_warnings(@warnings) if @warnings;
2750 By default perl prints warnings to C<STDERR> if you don't catch them. If you don't want to catch them and also
2751 don't want them printed to C<STDERR>, you can suppress them lexically (perl v5.28 or higher required):
2754 no warnings 'File::KDBX';
2761 local $File::KDBX::WARNINGS = 0;
2765 or globally in your program:
2767 $File::KDBX::WARNINGS = 0;
2769 You cannot suppress fatal errors, and if you don't catch them your program will exit.
2773 This software will alter its behavior depending on the value of certain environment variables:
2779 C<PERL_FILE_KDBX_XS> - Do not use L<File::KDBX::XS> if false (default: true)
2783 C<PERL_ONLY> - Do not use L<File::KDBX::XS> if true (default: false)
2787 C<NO_FORK> - Do not fork if true (default: false)
2793 Some features (e.g. parsing) require 64-bit perl. It should be possible and actually pretty easy to make it
2794 work using L<Math::BigInt>, but I need to build a 32-bit perl in order to test it and frankly I'm still
2795 figuring out how. I'm sure it's simple so I'll mark this one "TODO", but for now an exception will be thrown
2796 when trying to use such features with undersized IVs.
2804 L<KeePass Password Safe|https://keepass.info/> - The original KeePass
2808 L<KeePassXC|https://keepassxc.org/> - Cross-Platform Password Manager written in C++
2812 L<File::KeePass> has overlapping functionality. It's good but has a backlog of some pretty critical bugs and lacks support for newer KDBX features.
2818 Please report any bugs or feature requests on the bugtracker website
2819 L<https://github.com/chazmcgarvey/File-KDBX/issues>
2821 When submitting a bug or request, please include a test-file or a
2822 patch to an existing test-file that illustrates the bug or desired
2827 Charles McGarvey <ccm@cpan.org>
2829 =head1 COPYRIGHT AND LICENSE
2831 This software is copyright (c) 2022 by Charles McGarvey.
2833 This is free software; you can redistribute it and/or modify it under
2834 the same terms as the Perl 5 programming language system itself.