#!/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 =~ /([^\/]+)$/, " \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( ); } 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 ); $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 = ); } 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"; ; 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 = ); if ( $entry =~ /^XXX$/ ) { print "Erasing...\n"; splice @out, $offset, 1; } else { $out[$offset] = $entry; } } sub add_entry { print "What to add: "; chomp(my $str = ); 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"; }