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

In reply to Re to the three: How about a module for "passwords"? by zengargoyle
in thread How about a module for "passwords"? by John M. Dlugosz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.