use File::KDBX::Constants qw(:yubikey);
use File::KDBX::Error;
-use File::KDBX::Util qw(:io pad_pkcs7);
-use IPC::Cmd 0.52 qw(run_forked);
+use File::KDBX::Util qw(:class :io pad_pkcs7);
+use IPC::Cmd 0.84 qw(run_forked);
use Ref::Util qw(is_arrayref);
use Symbol qw(gensym);
use namespace::clean;
-use parent 'File::KDBX::Key::ChallengeResponse';
+extends 'File::KDBX::Key::ChallengeResponse';
our $VERSION = '999.999'; # VERSION
@keys = File::KDBX::Key::YubiKey->scan(%options);
Find connected, configured YubiKeys that are capable of responding to a challenge. This can take several
-second.
+seconds.
Options:
$device = $key->device($device);
Get or set the device number, which is the index number starting and incrementing from zero assigned
-to the YubiKey device. If there is only one detected YubiKey device, it's number is C<0>.
+to the YubiKey device. If there is only one detected YubiKey device, its number is C<0>.
Defaults to C<0>.
=cut
-my %ATTRS = (
- device => 0,
- slot => 1,
- timeout => 10,
- pre_challenge => undef,
- post_challenge => undef,
- ykchalresp => sub { $ENV{YKCHALRESP} || 'ykchalresp' },
- ykinfo => sub { $ENV{YKINFO} || 'ykinfo' },
-);
-while (my ($subname, $default) = each %ATTRS) {
- no strict 'refs'; ## no critic (ProhibitNoStrict)
- *{$subname} = sub {
- my $self = shift;
- $self->{$subname} = shift if @_;
- $self->{$subname} //= (ref $default eq 'CODE') ? $default->($self) : $default;
- };
-}
-
-my %INFO = (
- serial => undef,
- version => undef,
- touch_level => undef,
- vendor_id => undef,
- product_id => undef,
-);
-while (my ($subname, $default) = each %INFO) {
- no strict 'refs'; ## no critic (ProhibitNoStrict)
- *{$subname} = sub {
- my $self = shift;
- $self->{$subname} = shift if @_;
- defined $self->{$subname} or $self->_set_yubikey_info;
- $self->{$subname} // $default;
- };
-}
+has device => 0;
+has slot => 1;
+has timeout => 10;
+has pre_challenge => undef;
+has post_challenge => undef;
+has ykchalresp => sub { $ENV{YKCHALRESP} || 'ykchalresp' };
+has ykinfo => sub { $ENV{YKINFO} || 'ykinfo' };
=method serial
Get the vendor ID or product ID for the device associated with this key (or C<undef>).
+=cut
+
+has serial => sub { $_[0]->_set_yubikey_info; $_[0]->{serial} };
+has version => sub { $_[0]->_set_yubikey_info; $_[0]->{version} };
+has touch_level => sub { $_[0]->_set_yubikey_info; $_[0]->{touch_level} };
+has vendor_id => sub { $_[0]->_set_yubikey_info; $_[0]->{vendor_id} };
+has product_id => sub { $_[0]->_set_yubikey_info; $_[0]->{product_id} };
+
=method name
$name = $key->name;
This doesn't work yet on Windows, probably. The hangup is pretty silly: IPC. Theoretically it would work if
C<run_forked> from L<IPC::Cmd> worked in Windows, but it probably doesn't. I spent a couple hours applying
various quirks to L<IPC::Open3> and L<IPC::Cmd> implementations but never quite got it to worked reliably
-without deadlocks. Maybe I'll revisit this later. Hit me up so I know if there's demand.
+without deadlocks. Maybe I'll revisit this later. Hit me up so I know if there's interest.
-It would also be possible to implement this is an XS module that incorporated ykcore, using libusb-1 which
+It would also be possible to implement this as an XS module that incorporated ykcore, using libusb-1 which
would probably make it more portable with Windows. Perhaps if I get around to it.
=cut