#!/usr/bin/perl # # $RCSfile: encmail.txt,v $ # Original Author...: Anthony Awtrey # Version...........: $Revision: 1.1 $ # Last Modified By..: $Author: aawtrey $ # Last Modified.....: $Date: 2005/04/04 14:44:38 $ # # Copyright 2005 Anthony L. Awtrey # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Purpose: # This script replaces sendmail in CGI forms that send mail. It uses GnuPG # to encrypt email based on the email address in the To: header. If no key # is available it passes the mail through to sendmail unencrypted. # #################### # Adjust these variables #################### # The full sendmail commandline. Typically, "/usr/sbin/sendmail -t" $sendmail = "/usr/sbin/sendmail -t -i"; # The path to the gpg executable $gnupg = "/usr/bin/gpg"; # A place the script can write temporary files. $tmpdir = "/tmp"; # Location of the keyring files $homedir = "/home/dir/.gnupg"; #################### # Start Main Code #################### #################### # Pull the email from STDIN and break out the components #################### while () { #################### # The headers and the body are seperated by a single newline # Test for a newline to mark the start of the email body #################### if ( /^\n/ && $start_body!=1 ) { $start_body = 1; #################### # If we haven't found the bare newline yet, switch based on the header field # name to collect the headers. #################### } elsif ($start_body!=1) { #################### # Remove the newline #################### chop; #################### # Split the line at the colon ':' #################### ($field, $data) = split(/:/, $_, 2); #################### # Set an element in an array if we get a valid header. # Valid Headers: To From Subject Fcc Bcc Cc Sender X-sender Date X-Url #################### SWITCH: for ($field) { /^To$/ && do { $headers{'To'} = $data; $email_address = &get_email($data); last; }; /^From$/ && do { $headers{'From'} = $data; last; }; /^Subject$/ && do { $headers{'Subject'} = $data; last; }; /^Cc$/ && do { $headers{'Cc'} = $data; last; }; /^Fcc$/ && do { $headers{'Fcc'} = $data; last; }; /^Bcc$/ && do { $headers{'Bcc'} = $data; last; }; /^Sender$/ && do { $headers{'Sender'} = $data; last; }; /^X-sender$/ && do { $headers{'X-sender'} = $data; last; }; /^Date$/ && do { $headers{'Date'} = $data; last; }; /^X-url$/ && do { $headers{'X-url'} = $data; last; }; } #################### # If we have found the bare newline then the rest of the message is collected # as the body #################### } else { $BODY .= "$_"; } } #################### # End the while loop collecting the data from STDIN #################### #################### # Collect a key list from gpg #################### @keys = `$gnupg --homedir=$homedir --list-keys`; foreach $key (@keys) { #################### # Ditch the newline #################### if ($key =~ /\n$/) { chop($key); } #################### # Try to find the email address in the key line #################### $key =~ s/^pub.*\<(.*)\>/$1/; #################### # Test to see if this line's email address matches the To header #################### if ($email_address eq $key) { #################### # If it does, set a variable for later #################### $enc_email = $key; } } #################### # End the key list collection #################### #################### # If the GnuPG email address matches the To address encrypt the message body #################### if ($enc_email) { #################### # Generate a tmp file name #################### srand(time|$$); @saltchars = (a..z,A..Z,0..9); for ($i=0; $i<8; $i++) { $tmpfile .= $saltchars[int(rand($#saltchars+1))]; } $tmpfile = "$tmpdir/$tmpfile"; #################### # Write message body to temp file #################### open(TMPFILE,">$tmpfile"); print TMPFILE "$BODY\n"; close(TMPFILE); #################### # Encrypt email body from the temp file #################### $BODY = `$gnupg --no-verbose --no-greeting --no-secmem-warning --homedir=$homedir -ear $enc_email < $tmpfile 2>&1`; #################### # Delete temp file #################### unlink($tmpfile); } #################### # End email encryption #################### #################### # Send the mail #################### open(MAIL,"|$sendmail"); foreach $key (keys %headers) { print MAIL "$key: $headers{$key}\n"; } print MAIL "\n"; print MAIL "$BODY"; print MAIL "\n"; close(MAIL); #################### # End Main Code #################### #################### # Begin Functions #################### sub get_email { $address = $_[0]; @parts = split(/ /,$address); foreach $part (@parts) { if ($part =~ /\?/) { $part =~ s/\//g; $email = $part; } } return($email); }