130 lines
2.5 KiB
Perl
Executable File
130 lines
2.5 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
# Created by Ben Okopnik on Sun May 6 23:53:32 EDT 2007
|
|
$|++;
|
|
use lib "$ENV{HOME}/myperl/lib";
|
|
use Term::ReadKey;
|
|
use Crypt::CBC;
|
|
|
|
$ENV{TERM} = 'xterm';
|
|
|
|
$search = shift;
|
|
|
|
unless ( $search ){
|
|
print STDOUT "Usage: ", $0 =~ /([^\/]+)$/, " <search_term|-e>\n";
|
|
sleep 2;
|
|
exit 1;
|
|
}
|
|
|
|
# Read the password silently
|
|
print "Password: ";
|
|
ReadMode( 2 );
|
|
my $pass = ReadLine( 0 );
|
|
ReadMode( 0 );
|
|
print "\n";
|
|
# DES uses 8-byte keys, complains if they're longer
|
|
chomp( $pass = substr $pass, 0, 8 );
|
|
|
|
# Get the content of the 'pass' file
|
|
open Pass, "$ENV{HOME}/pass" or die "pass: $!\n";
|
|
$c = new Crypt::CBC( $pass );
|
|
|
|
{
|
|
local $/;
|
|
@out = split /\n/, $c -> decrypt( <Pass> );
|
|
}
|
|
close Pass;
|
|
|
|
END { unlink "$ENV{HOME}/.pass_edit"; system "/usr/bin/clear"; }
|
|
|
|
if ( $search =~ /^-e$/ ) {
|
|
# Check for lock...
|
|
die "The file is currently being edited; please try again later.\n"
|
|
if -e "$ENV{HOME}/.pass_edit";
|
|
|
|
# ...and create one of our own if it doesn't exist.
|
|
system ">$ENV{HOME}/.pass_edit";
|
|
|
|
{
|
|
system "/usr/bin/clear";
|
|
$answer ||= ".";
|
|
for ( 0 .. $#out ){
|
|
printf "%3d. %s\n", $_, $out[$_] if $out[$_] =~ /$answer/;
|
|
}
|
|
undef $answer;
|
|
|
|
print "\nNumber to edit, 'a' to add, 'f' to find, 's' to save, or 'q' to quit: ";
|
|
chomp( my $todo = lc <STDIN> );
|
|
|
|
$todo =~ s/^\s*(.*?)\s*$/$1/;
|
|
|
|
unless ( $todo =~ /^(\d+|[afsq])$/ ){
|
|
print "Unknown option '$todo'\n";
|
|
sleep 1;
|
|
redo;
|
|
}
|
|
print "\n";
|
|
|
|
if ( $todo eq 'a' ) {
|
|
add_entry();
|
|
}
|
|
elsif ( $todo eq 'f' ) {
|
|
print "Search for: ";
|
|
chomp( $answer = <STDIN> );
|
|
}
|
|
elsif ( $todo eq 's' ) {
|
|
save();
|
|
}
|
|
elsif ( $todo eq 'q' ) {
|
|
exit 0;
|
|
}
|
|
else {
|
|
edit_entry($todo);
|
|
}
|
|
print "\n";
|
|
|
|
redo;
|
|
}
|
|
}
|
|
else {
|
|
for (@out) {
|
|
print "$_\n" if /$search/i;
|
|
}
|
|
print "\nPress 'Enter' to continue";
|
|
<STDIN>;
|
|
exit 0;
|
|
}
|
|
|
|
sub edit_entry {
|
|
my $offset = shift;
|
|
|
|
print "Can't find offset '$offset'\n", return
|
|
unless ( $offset >= 0 and $offset <= @out );
|
|
|
|
print "Old entry:\n", "-" x 65, "\n$out[$offset]\n", "-" x 65, "\n";
|
|
print "New entry ('XXX' to erase):\n", "-" x 65, "\n";
|
|
|
|
chomp( my $entry = <STDIN> );
|
|
if ( $entry =~ /^XXX$/ ) {
|
|
print "Erasing...\n";
|
|
splice @out, $offset, 1;
|
|
}
|
|
else {
|
|
$out[$offset] = $entry;
|
|
}
|
|
}
|
|
|
|
sub add_entry {
|
|
print "What to add: ";
|
|
chomp(my $str = <STDIN>);
|
|
print "NOTHING ADDED", return unless $str =~ /\S/;
|
|
push @out, $str;
|
|
}
|
|
|
|
sub save {
|
|
open Pass, ">pass" or die "pass: $!\n";
|
|
$c = new Crypt::CBC( $pass );
|
|
print Pass $c -> encrypt( join "\n", sort @out );
|
|
close Pass or die "Pipe close failed.\n";
|
|
}
|
|
|