#!/usr/bin/perl -w #### # passman Version 1.1.0 # July 13, 2000 # Released under the Artistic Licence # # Simple script to manage multiple passwords. # # Uses Counterpane's Twofish algorithm. Module # avilable from: # http://www.cpan.org/modules/by-module/Crypt/Twofish-1.0.tar.gz # # More information on Twofish available at: # http://www.counterpane.com/ # # Author: Will England (will@mylanders.com) # Homepage: http://will.mylanders.com/develop/perl/passman/ # #### # HOW_TO_USE # # 1) See usage from command line. # 2) the 'Key' is very important -- it is the # password that everything else is encrypted with. # # You can use different keys for each system, but # do not forget your key. If you do, you loose the # data. You must use the same key you added a system # with to get the info. # #### # WARNING: This is not to be considered secure. About # any teenager could compromise the stored passwords. # All it is is a replacement for sticky-notes under the # keyboard. Do not use this product for critical data. # The author takes no responsibility or liability for # any use of this product. Contents may settle. No right # turn on red. # #### # Install: Copy this script to a directory in your path. #### # # Config: Change this variable if you want to change the # location or name of the data file. my $datfile .= "$ENV{HOME}/bin/.systems_data"; # # #### # No user variables from here down. # use Crypt::Twofish; use strict; ### Usage if (!@ARGV) { defUsage(); exit(1); } ### Set up # Pop first command line argument. my ($input) = shift; # basically global (to this script) # variables to save passing stuff to # the subroutines. my ($key, $system, $password); ### Begin handling command line options. ### List all systems if ($input =~ /list/i) { open (FILE, "<$datfile") || die "Cannot open data file: $!"; my (%system, $text, $item); while () { ($item, $text) = split(); $system{$item} = $item; } foreach $item (sort(keys(%system))) { print $item . "\n"; } close (FILE); exit(1); } ### stuff new system / pass into file if ($input =~ /add/i) { my $sys_input; my $cyphertext; get_key(); $system = shift; if (!$system) { get_sys(); } get_pass(); #check for duplicate, remove if found. open (READ, "<$datfile") || die "Cannot open data file: $!"; while () { my ($in_sys, $crypt) = split(); if ($in_sys eq $system) { pop_sys(); } } open (FILE, ">>$datfile") || die "Cannot open data file: $!"; $cyphertext = Encipher($key, length($key), $password); # Hack here -- # standard unix files don't work well with binary # and text data combined. So, take the binary output # from Encipher and unpack it to a hex string. print FILE $system . " " . unpack('H*',$cyphertext) . "\n"; close (FILE); exit (1); ### retrieve system / pass from file. } elsif($input =~ /get/i) { my ($line, $sys_read, $crypto, $plaintext); get_key(); $system = shift; if (!$system) { get_sys(); } open (FILE, "<$datfile") || die "Cannot open data file: $!"; while () { ($sys_read, $crypto)= split(); # Hack here -- # Since we stored the crypted password # as hex text, we have to revert it # to binary with pack(); $crypto = pack('H*',$crypto); # match the system we want and decipher. if ($sys_read eq $system) { $plaintext = Decipher($key, length($key), $crypto, length($crypto)); } } close(FILE); if ($plaintext) { print "\nPassword for $system is $plaintext\n\n"; exit (1); } else { print "\n$system not found.\n\n"; exit (0); } ### handle removal of systems } elsif ($input =~ /pop/i) { $system = shift; if (!$system) { get_sys(); } if (pop_sys()) { print "$system popped\n"; exit (1); } else { print "Couldn't pop $system\n"; exit (0); } ### luser entered garbage on command line. } else { defUsage(); exit(0); } ######### # Subroutines ######### ### Prints the usage directions. sub defUsage { print "\nUSAGE: passman add|get|pop|list [system]\n \tSimple program to store various passwords.\n\n \tTO ENCRYPT: passman add [system].\n\n \tTO DECRYPT: passman get [system]\n\n \tTO LIST SYSTEMS: passman list\n\n \tTO REMOVE A SYSTEM: passman pop [system] \n\n\t\t[system] is optional in all cases. \n\t\tIf not provided, you will be prompted for it.\n\n\tIf you get garbage like \"mÇØÿÃÉnjDÌcòÔ\" instead of a\n \tpassword, you fumbled the key.\n\n"; } ### Gets the encryption key. sub get_key { print "\nKey: "; $key = ; chomp ($key); if (length($key) == 0) { defUsage(); exit(0); } } ### Gets the system to work with sub get_sys { print "\nSystem: "; $system = ; chomp ($system); if (length($system) == 0) { defUsage(); exit(0); } } ### Gets the password for a system sub get_pass { print "Password: "; $password = ; chomp($password); if (length($password) == 0) { defUsage(); exit(0); } } ### Removes system from datafile sub pop_sys { my $flag = 0; open (INFILE, "<$datfile") || die "Cannot open data file: $!"; open (OUTFILE, ">/tmp/$$.tmp") || die "Cannot open temp file: $!"; while () { my ($in_sys, $crypt) = split(); if ($in_sys ne $system) { print OUTFILE $in_sys . " " . $crypt . "\n"; } else { $flag = 1; } } close (FILE); close (OUTFILE); `mv /tmp/$$.tmp $datfile`; return ($flag); }