in reply to Re: Re: How about a module for "passwords"?
in thread How about a module for "passwords"?
i commented out the Kerberos part of this, but you got the basic idea. if you have a valid ticket you can connect to the server and the server can check you against its list of valid users. the server then sends the encrypted hash (with the __password and __cipher preset) back to the client to use as desired.
the Kerberos parts are much uglier. i'll need to poke around them some more before posting.
package Keystore; use strict; use warnings; use Tie::EncryptedHash; use Term::ReadKey; use Data::Dumper; my $default_keyfile = "$ENV{HOME}/.Q/keystore"; my $default_secret = 'notverysecret'; my $default_cipher = 'Blowfish'; sub _get_secret { my $prompt = shift; my $secret; print STDERR "$prompt: "; ReadMode 'noecho'; $secret = ReadLine 0; chomp $secret; ReadMode 'normal'; print STDERR "\n"; return $secret; } sub pw { my ($self,$password,$newval) = @_; my $keystore = $self->{keystore}; return undef unless (defined($password) and length $password); my $encpass = "_$password"; # Tie::Encrypted uses _ for the +encrypted keys if (exists($keystore->{$encpass})) { return $keystore->{$encpass} || ''; } elsif (defined($newval) and length $newval) { $keystore->{$encpass} = $newval; return $keystore->{$encpass} || ''; } else { $keystore->{$encpass} = _get_secret($password); return $keystore->{$encpass} || ''; } return undef; } sub new { my ($c,%param) = @_; =begin comment # this was the Kerberos part, instead of reading from a file i +t # would connect to a Kerberos server (using your credentials). # if all went well it would recieve the encrypted hash from th +e # server and would leave the keyfile 'undef' so it wouldn't be # saved on DESTROY. if the server chat failed it failed to the # file based method below. my $kks = KKS::keystore; if (ref $kks) { my $self = { keystore => $kks, keyfile => undef }; return bless $self, $c; } =cut $param{keyfile} ||= $default_keyfile; if (-f $param{keyfile} && !-r _) { $param{secret} = $default_s +ecret; } $param{secret} ||= _get_secret('secret'); my (%s,%sold); if (-f _ && -r _) { open(F,"<$param{keyfile}") or warn "open\n"; my ($cfgstr,$passwords); {local $/ = undef; $cfgstr = <F>; } eval "$cfgstr"; # ewwww!! would not do this this +way now... %sold = (%$passwords); } tie %s, 'Tie::EncryptedHash'; %s = (%sold); $s{__password} = $param{secret}; $s{__cipher} = $param{cipher} || $default_cipher; my $self = { keystore => \%s, keyfile => $param{keyfile} }; return bless $self, $c; } sub DESTROY { my ($s) = @_; my ($k,$f) = ($s->{keystore}, $s->{keyfile}); { local $^W = 0; no warnings; delete $k->{__password}; } return unless defined $f; open(F,">$f") or return; print F Data::Dumper->Dump([$k],['passwords']); close(F); } 1; =head1 NAME Keystore - Perl extension for a password keystore. =head1 SYNOPSIS use Keystore; $ks = new Keystore; $passwd = $ks->pw('cisco_console'); $passwd2 = $ks->pw('cisco_enable'); # do something query_rtr('rtr-foo',$passwd,$passwd2); # clean up if you're paranoid $passwd = $passwd2 = undef; =head1 DESCRIPTION Try it: $ mkdir $HOME/.Q # type the following on a single line so you can up-arrow and do it a +gain. $ perl -e 'use Keystore;$ks=new Keystore; \ for(qw( testpass anotherpass foopass)) { \ print $ks->pw($_),"\n";}' # type a secret, it will be used to encrypt your passwords. # since it doesn't know these passwords, it will ask. secret: testpass: foo anotherpass: lala foopass: zig # do it again, type the same secret as before. # it knows them now, doesn't need to ask. secret: foo lala zig $ cat $HOME/.Q/keystore $passwords = { '_testpass' => 'Blowfish rL0Y20zC+Fzt72VPzMSk2A 52616e646f6d4956fde +2cd4cc69fb 4ab6888532e6b2aac86', '_foopass' => 'Blowfish I4uNgfsODwP+rVYTtSNLdA 52616e646f6d49567073 +d91467ce68 e7d45d91ad73b75cc7', '_anotherpass' => 'Blowfish LjgXKT/CddvudL1xzm6wVg 52616e646f6d4956 +2070a13f37 a38f8dcd55403f697a6661' }; To delete a password, just delete the line. To completely disable the + encrypted saving of passwords: chmod -rw $HOME/.Q/keystore If it can't read the + file it will prompt for passwords when needed (but still only once per sess +ion). If it can't write the file they won't get saved. =head2 EXPORT None by default. =head1 AUTHOR =head1 SEE ALSO L<Tie::EncryptedHash>. =cut
|
|---|