#!/usr/bin/perl # # FOR MORE DOCUMENTATION .. please see http://sighsy.cup.edu/~dinselj # # It became too hard to keep this file and the html docs up to date .. # Only the obvious necessities remain here. # # Originally written by jason steiner, # jsteiner@anwsun.phya.utoledo.edu, Jan 1993 # # Modified COMPLETELY by Jeremy Dinsel (dinselj@sighsy.cup.edu). # Special thanks to Bradley M Alexander # for his assistance in the creation process of mailpgp .75b and his # beta-testing (cheerfully being a Guinny Pig). Thanks. # # How to use: # Set the pine configurations "editor" to the full path of # this program such as /home/$USERNAME/bin/mailPGP # Enable the Alternative editor (either with the key sequence or full time). # I prefer full time. # Signing messages to be sent is now configured properly. Next, configure # the display-filters value. It should read # _LEADING("-----BEGIN PGP")_ /home/dinselj/bin/mailPGP RECEIVE _TMPFILE_ # .. for the best luck in working. This part of the code may still need work. # There were problems with getting the correct file read back into pine, # but all that seems to be resolved. # This code is covered under the GPL license. Modify it, use it, but don't # blame me if it eats your harddrive! # #use strict; my $pgp_version = "2.6.2"; ## CHANGE THIS TO THE VERSION YOU USE ## Options: ## 2.6.2 -- all versions of this? ## 5.0 -- icky slow on my 486 my $pgp = '/usr/local/bin/pgp'; ## PGP 50 information ... my $pgps = '/home/gerr/bin/pgps'; my $pgpk = '/home/gerr/bin/pgpk'; my $pgpv = '/home/gerr/bin/pgpv'; my $pgpe = '/home/gerr/bin/pgpe'; ## END USER CONFIGURABLE OPTIONS ## my $version = "0.75"; my $visual; my $i = 0; my $dopgp = 1; my @pico_opts; my $returned = 101; my $q; my $whocares; my $sign; my $sign50 = 0; my $encrypt; my $encrypt50 = 0; my $se50 = 0; my $name; my @opts; my @to_opts; $visual = ($ENV{'VISUAL'}) || ($visual = '/usr/bin/pico'); &sub_check_programs; if($visual =~ /pico/){ push(@pico_opts,'-emt'); } ## If we are called with the RECEIVED Argument, just handle the ## decyphering of the message if it needs to be done. foreach (@ARGV) { if($ARGV[$i] eq "RECEIVED"){ $ARGV[$i] = " "; &sub_decipher; exit; } $i++; } ## Check for PGP in the file. If there is some information concerning ## PGP previously written to the file, warn the user. We could be ## making their file look like a fake. if(&check_pgp_in_file == 1){ print("Aborting PGP interface.\n"); sleep(1); exit; } ## Let the user edit their mail file .. we'll hound them with questions ## when they are done. &edit_file; ## get the options from our pgp menu ($sign,$encrypt) = &pgp_menu; ## if the opts array is defined, we've been pushing values into it ## thus, the user would like to do something other than abort. if (@opts){ $name=$ARGV[$#ARGV]; ## process according to the user defined version ... if($pgp_version eq "5.0"){ $returned = &pgp50_sub; }else{ $returned = system($pgp,'-a',@opts,$name,@to_opts); } ## check the returned status .. if it's bad, let the user know ## about it .. otherwise, setup the file so that pine can import ## it back into it's buffer if($returned != 0){ &bad_returned_handler($name); }else{ system "mv ${name}.asc $name"; } ## done with the interface .. back to pine exit; } ## end main routine .. begin sub programs ## inquire from the user what they would like to do. sub pgp_menu { my $options; ## prompt with the menu .. the sign option is the default .. ## it is noted with the [ ] enclosures print("mailPGP $version using PGP $pgp_version.\nOptions:\n", "[1) Sign]\t\t2) Encrypt\t3) Acquire New Key\n", "4) Sign and Encrypt\t5) No Encryption\t6) Help\n"); chomp($options = ); ## check the choice made by the user .. setup variables ## if necessary if(($options == 1) || ($options eq "sign")){ $sign50 = 1; $sign = &sign_message; }elsif(($options == 2 ) || ($options eq "encrypt")){ $encrypt50 = 1; $encrypt = &encrypt_sub; }elsif(($options == 3)||($options eq "acquire")){ &get_new_pgp_key; &pgp_menu; }elsif(($options == 4) || ($options eq "sign")){ $se50 = 1; $sign = &sign_message; $encrypt = &encrypt_sub; ## notify the user very quickly .. might want to remove this, though }elsif(($options == 5) || ($options eq "quit")){ print("Aborting mailPGP interface, message context will remain.\n"); sleep(1); }else{ if(($options == 6) || ($options eq "h")){ &mailpgp_help(1); &pgp_menu; }else{ ## default option .. sign email message $sign50 = 1; $sign = &sign_message; } } return ($sign,$encrypt); } ## setup the options for excrypting the message ... sub encrypt_sub { $encrypt = &who_encrypt; push(@opts,'-e'); return $encrypt; } ## ask the user who's public key they would like to use to ## encrypt their message with. sub who_encrypt { my $to; print ("Your Public key ring encludes:\n"); system("$pgp -kv"); ## be noisy .. we want the user to notice this message to prevent ## them from kicking out their passphrase in plaintext print ("\n\n\aTHIS IS NOT THE TIME TO ENTER YOUR SECRET KEY PASSPHRASE!!"); print("\nEnter the public key to use for encrypting this message\n", "or NEW to acquire another key: "); chomp($to = ); ## try to get another key for the user ... if($to eq NEW){ &get_new_pgp_key; &who_encrypt; ## setup the options with who this message is for }else{ push(@to_opts,$to); } return 1; } ## setup options for signing the message sub sign_message { push(@opts,'-st','+clearsig=on'); return 1; } ## look through the file for some old PGP information .. this way we'll ## know if we're about to mess up the user's previously signed message sub check_pgp_in_file { my $filename = $ARGV[0]; my $ans; my $check_pgp = 0; open(PGP_FILE,$filename); while(){ ## look for -----BEGIN PGP at the beginning of the line .. if($_ =~ /\A-----BEGIN PGP/){ close PGP_FILE; print("This file could have been modified by PGP already.\n"); print("Are you sure you want to continue with this process? [N] "); chomp($ans = ); if(($ans eq 'Y' )||($ans eq 'y')){ ## user really wants to do this .. return 0; }else{ ## abort the editing process .. return 1; } } } close PGP_FILE; return $check_pgp; } ## check the file for PGP version .. if the version is different then ## the version we are using, we'll have to attempt to use another ## version or warn the user about this .. ## ## otherwise, we can go ahead and decypher the file ## BTW: we get here because pine detected the existance of a ## -----BEGIN at the top of this file .. thus we are positive ## that PGP has been used with this file. sub sub_decipher { my $name = $ARGV[$#ARGV]; my $filename; my $whocares; my $returned; my $found_version; my $found = 0; ## setup the filenames .. get the files in position $filename = (${name} . ".asc"); system('mv', $name, $filename); ## look for the PGP version used to sign this file open(PGP_FILE,$filename) || warn("Where did $filename go?"); while(){ if($_ =~ /\A-----BEGIN/){ chomp($_ = ); if($_ =~ /Version:/){ $found_version = $_; $found = 1; close(PGP_FILE); } } } close(PGP_FILE); ## close the file if we did not find the information we needed .. if($found != 1){ print("mailPGP could not determine the version of PGP used on ", "this message.\n"); }else{ ## we need to see if the user has the same version of pgp .. ## if not, we need to see if they can use another version ## of PGP .. yes, some people do have more than one version ## -- like me -- $returned = &check_current($found_version); } print("mailPGP $version using PGP $pgp_version attempting to decipher.\n"); if($returned eq "5"){ $returned = system($pgpv,$filename); }else{ $returned = system($pgp,$filename); } if($returned != 0){ &bad_returned_handler("$name"); } print("\n\nTake note of these messages and press return when ready."); $whocares = ; system("rm $filename"); } sub check_current{ my $found_version = $_[$#]; my $ans; my $old_version; ## save state .. $old_version = $pgp_version; ## we're using the same version as the sender if this is true if($found_version =~ /$pgp_version/){ ## setup the return .. yes yes, this is the same thing .. $pgp_version = $old_version; ## we have a different version }else{ print("mailPGP would like to use $pgp_version, but the message\n", "was signed with PGP $found_version.\n"); print("Should we try to use this other version? [Y] "); chomp($ans = ); ## try to change our version of PGP to their version ... if(($ans =~ 'i/y/') || ($ans eq '')){ if($found_version =~ /2.6./){ $pgp_version = "2.6.2"; }else{ if($found_version =~ /5.0/){ $pgp_version = "5.0"; } } ## check if the modified version programs even exist .. if(&version_check != 1){ print("You don't have the program files you need. Reverting\n", "to PGP version $old_version.\n"); sleep(1); $pgp_version = $old_version; } }else{ print("mailPGP will give the message it's best try. Keep your\n", "fingers crossed.\n"); sleep(1); } } ## return the version we have decided to use return $pgp_version; } ## check to see if the files we need for the current version even ## exist .. return a 1 if everything is good, something else if not sub version_check{ my $exist = 1; if($pgp_version eq "2.6.2"){ unless(-e $pgp){ $exist = 0; } }else{ unless((-e $pgps) && (-e $pgpk) && (-e $pgpv) && (-e $pgpe)){ $exist = 0; } } return $exist; } ## edit the file .. sub edit_file{ system('/usr/bin/pico','-e',@ARGV); } ## check for the existance of all the programs we need sub sub_check_programs{ my $bad_errors = 0; unless (-e $pgp){ print("$pgp does not exist. "); $bad_errors = 1; } unless(-e $visual){ print("$visual does not exist\n."); $bad_errors = 1; } if ($bad_errors == 1){ print("These programs are vital to this program."); exit; } } ## this happens when stale PGP information is left in the file .. ## we'll need to clean it up before we can continue .. sub bad_returned_handler{ my $name = $_[$#]; my $filename; $filename = $name . ".asc"; my $out_file = $name . ".tmp"; print("\nError handling file .. attempting to correct.\n"); print("This process will modify the displayed mail message. You may\n"); print("notice some odd PGP-like headings. You can safely ignore them.\n"); open(PGP_FILE, "$filename") || die ("Could not open $filename for processing: $!"); open(PGP_OUT_FILE, ">$out_file"); while(){ if( $_ =~ /\A-----BEGIN PGP/){ print(PGP_OUT_FILE "-----(Modified PGP heading)-----\n"); }else{ print PGP_OUT_FILE $_; } } close(PGP_FILE); close(PGP_OUT_FILE); system("mv", $out_file, $name); } ## acquire a new pgp via email or by lynx .. not sure if pgp 50 part works ## here or not sub get_new_pgp_key{ my $who = ""; my $url = "http://www-swiss.ai.mit.edu/htbin/pks-extract-key.pl"; my $returned = 101; my $method; my $delete = "/tmp/bad_file"; print("1) http 2) finger\nMethod for acquiring key: "); chomp($method = ); if($method == 1){ print("Name the key you wish to search for: "); chomp($who = ); print("Attempting to acquire new PGP key...\n"); if($pgp_version eq "5.0"){ $returned = system("lynx -dump $url\"?op=get&search=$who\"|$pgpv -a"); }else{ $returned = system("lynx -dump $url\"?op=get&search=$who\"|$pgp"); } }elsif($method == 2){ print("Enter username and site to finger: "); chomp($url = ); $returned = system("finger $url > $delete;$pgp -ka $delete;rm $delete"); }else{ print("Invalid option.\n"); } if($returned != 0){ print("Something went a foul when attempting to gain another\n", "public key. If you are not aware of this, make yourself\n", "aware of the error now.\n"); $who = ; } } ## The help module .. use call values to decipher which help to offer sub mailpgp_help{ my $helpful = $_[$#]; if($helpful == 1){ print("\n", "mailPGP provides you with an easy interface into signing\n", "and encrypting messages with PGP.\n\n", "Sign:\t Sign the message with your secret key.\n", "Encrypt: Encrypt your message with a PGP public key.\n", " mailPGP will notify you of the keys you currently", " have.\n", "Sign & Encrypt: Combine the functionality of the previous\n", "\t two options for optimum privacy.\n", "Acquire new key: PGP will use lynx to attempt an access of\n", "\t a PGP key server.\n", "Abort:\t Abort signing or encrypting. This will not effect\n", "\t any changes made to your E-Mail message.\n\n"); return; } } ## Sub to work with PGP version 5.0. Flags are set in the menu ## module as to what process to perform here. sub pgp50_sub{ my $worked = 0; if($se50){ $worked = system($pgpe,"-asr",@to_opts,$name); return $worked; } elsif($encrypt50){ $worked = system($pgpe,"-ar",@to_opts,$name); return $worked; } elsif($sign50){ $worked = system($pgps,"-at",$name); return $worked; } return $worked; }