Passwd-Keyring-KDEWallet
view release on metacpan or search on metacpan
lib/Passwd/Keyring/KDEWallet.pm view on Meta::CPAN
it, this option disables this behaviour
=item kwalletd_path
path to kwalletd binary, used in case we try starting it. Default:
C<kwalletd> (relative path means searching in C<PATH>).
=back
=cut
sub new {
my ($cls, %args) = @_;
my $self = {};
$self->{app} = $args{app} || 'Passwd::Keyring::KDEWallet';
$self->{group} = $args{group} || 'Passwd::Keyring::default';
$self->{dont_start_daemon} = $args{dont_start_daemon} || '';
$self->{service_name} = 'org.kde.kwalletd';
$self->{module_name} = '/modules/kwalletd';
bless $self, $cls;
$self->{kwalletd_path} = $args{kwalletd_path} || $self->_which_kwalletd;
#$self->{bus} = Net::DBus->find()
$self->{bus} = Net::DBus->session()
or croak("KWallet not available (can't access DBus)");
$self->_init_kwallet();
$self->_open_if_not_open();
unless($self->{kwallet}->hasFolder($self->{handle}, $self->{group}, $self->{app})) {
$self->{kwallet}->createFolder($self->{handle}, $self->{group}, $self->{app})
or croak("Failed to create or access $self->{group} folder (app $self->{app}).\nDid you reject prompt to open the wallet?\n");
}
return $self;
}
sub _which_kwalletd {
my ($self) = @_;
for my $kwalletd ('kwalletd','kwalletd5') {
my $which = which($kwalletd);
if ($which) {
$self->{service_name} = "org.kde.$kwalletd";
$self->{module_name} = "/modules/$kwalletd";
return $which;
}
}
croak("KWallet not available (no binary found)");
}
# Called from the constructor, setups self->{kwallet} attribute (top level
# service object)
sub _init_kwallet {
my $self = shift;
# get_service may fail by itself, if kwalletd is down, in some
# cases it fails with
#
# org.freedesktop.DBus.Error.ServiceUnknown: The name org.kde.kwalletd was not provided by any .service files
my $kwallet_svc;
my $error;
try {
$kwallet_svc = $self->{bus}->get_service($self->{service_name});
} catch {
$error = $_;
chomp($error);
};
unless($kwallet_svc) {
# Mayhaps we are allowed to start kwalletd?
if(! $self->{dont_start_daemon}
&& $error =~ /^org\.freedesktop\.DBus\.Error\.ServiceUnknown:/) {
print STDERR "KWallet service not available, attempting to start $self->{kwalletd_path}\n";
# spawn kwalletd
my $pid = sync_exec
sub {
# Without this prove (tests) hang
close (STDOUT);
return 1;
},
$self->{kwalletd_path};
unless($pid) {
croak "KWallet not available (not installed or not started)\nand attempt to start it failed\nOriginal error:\n$error" . "Attempted command:\n" . $self->{kwalletd_path} . "\nCommand failure: $!\n";
};
my $error2;
my $DEADLINE = time() + $KWALLETD_START_TIMEOUT;
# while($proc->alive && time() <= $DEADLINE) {
while(time() <= $DEADLINE) {
try {
$kwallet_svc = $self->{bus}->get_service('org.kde.kwalletd');
} catch {
$error2 = $_;
chomp($error2);
# warn "Still not available: $@\n";
};
last if $kwallet_svc;
sleep($KWALLETD_CHECK_FREQUENCY);
}
unless($kwallet_svc) {
croak "KWallet not available (not installed or not started),\nand attempt to start it did not help\nFirst error:\n$error\nLast error:\n$error2\nAttempted command: $self->{kwalletd_path}\n";
}
} else {
croak "KWallet not available (not installed or not started),\nand we are forbidden to start it ourselves.\nOriginal error:\n$error\n";
}
}
$self->{kwallet} = $kwallet_svc->get_object(
$self->{module_name}, 'org.kde.KWallet')
or croak("Kwallet not available (can't find wallet)");
}
sub _open_if_not_open {
my $self = shift;
if($self->{handle}) {
if($self->{kwallet}->isOpen($self->{handle})) {
return;
}
}
my $net_wallet = $self->{kwallet}->networkWallet()
or croak("Kwallet not available (can't access network wallet");
$self->{handle} = $self->{kwallet}->open($net_wallet, 0, $self->{app})
or croak("Failed to open the KDE wallet");
}
=head2 set_password(username, password, realm)
Sets (stores) password identified by given realm for given user
=cut
sub set_password {
( run in 1.259 second using v1.01-cache-2.11-cpan-4ac696b4eb4 )