|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
|
|
Stop making mediocre tutorials.The best tutorials are video! Camtasia Studio makes it easy to create engaging, buzz-building screen videos at any size, in any popular format. Download the free trial!
|
|
#1
|
|||
|
|||
|
Signing a multipart email with GPG
Hi Folks,
Here's what I'm attempting. I have a form with some mandatory text fields and an optional file field. The contents need to be digitally signed using GPG and emailed. I have existing code that creates an email from the text and optionally a file using MIME::Lite and sends the email with Net::SMTP. I attempted to add Crypt::GPG to sign the MIME::Lite object but this failed because apparently Crypt::GPG is not compatible with MIME::Lite Objects. It now appears that Crypt::GPG is not my best option. I've read up some on the signing process but am unsure of its particulars. Does it sign a whole email, headers and all, or maybe just the text in the message body? If a file is included, is it signed separately or as part of the whole email? Are there any modules that I can use to easily sign a MIME::Lite object and email easily with Net::SMTP? If not, can someone recommend the best combination of modules to achieve my goal? If there's any other information I can provide please let me know. Thanks for your time. |
|
#2
|
||||
|
||||
|
Mail::GPG???
__________________
--Ax without exception, there is no rule ... The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones ![]() 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0 Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. -- Jamie Zawinski |
|
#3
|
|||
|
|||
|
Quote:
Thanks for your reply. While Mail::GPG does not take MIME::Lite objects nether does any other GPG module that I found. I've been rewriting my code to use MAIL::Entity which seems to be required for Mail::GPG and for Mail::GnuPG which is the module I found before you mentioned Mail::GPG that I was considering working with. I'll keep the post updated for posterity's sake. If anyone who has done this has anything to say on the matter or a nice pre-canned script ( ) I'd be happy to hear from you! |
|
#4
|
|||
|
|||
|
Since Admin said we couldn't install MIME::Entity because of version conflicts I had to use Crypt::GPG and MIME::Lite.
It's not elegant. Crypt::GPG signs by taking and returning strings which doesn't work well if attempting to sign a file. If one merely signs the contents of the file GPG rejects the signature as bad. Since Crypt::GPG offers no nice way to sign a file I wrote system calls to GPG instead, only using Crypt::GPG to clearsign the body text. These two mods were a bit coerced together. Instead of a nice, clean PGP/MIME layout I had to go with detached signatures. I'd love to hear from someone in the future though to see how nicely MIME::Entity and Mail::GnuPG work together. Example: Code:
#!/usr/bin/perl
use warnings;
use strict;
use Crypt::GPG;
use MIME::Lite;
my $gpg = new Crypt::GPG;
$gpg->detach(0);
$gpg->armor(1);
$gpg->gpgopts('--lock-multiple');
$gpg->gpgbin('gpgbinary');
$gpg->secretkey('key');
$gpg->passphrase('pass');
my $gpge = "gpgbinary";
my $passwd = "pass";
my $msg = MIME::Lite->new(
From => 'him@nowhere.com',
To => 'her@nowhere.com',
Subject => 'sample',
Type => 'multipart/mixed',
);
my $text = "message\n";
my $enc = $gpg->sign($text);
$msg->attach(
Data => $enc,
Type => 'text/plain',
);
$gpg->detach(1);
my $file = "/tmp/image1.gif";
my $filesig = $file.".sig";
my $fileasc = $file.".sig.asc";
system("echo '$passwd' | $gpge --passphrase-fd 0 --detach-sign $file");
system("$gpge --enarmor $filesig");
system("mv $fileasc $filesig");
$msg->attach(
Type => 'image/gif',
Path => '/tmp/image1.gif',
Filename => 'image1.gif'
);
$msg->attach(
Type => 'image/gif',
Path => $filesig,
Filename => 'image1.gif.sig'
);
$msg->send();
|
|
#5
|
|||
|
|||
|
So I had the opportunity to do it all over again using Mail::GPG and MIME::Entity on a different system and it's very clean and very nice, unlike the mess with Crypt::GPG & MIME::Lite.
Code:
#!/usr/bin/perl -w
#pgpMailer.cgi
use CGI qw(:standard);
use strict;
use warnings;
use CGI::Carp qw(fatalsToBrowser);
use MIME::Entity;
use Mail::GPG;
my $filename = param("attachment");
#The keys you are using should be in this path under the directory ".gnupg" #EG. /home/nobody/.gnupg
$ENV{"HOME"} = "PATH_TO_HOME_DIRECTORY_OF_USER_AS_WHICH_YOUR_SCRIPT_RUNS"; #EG. /home/nobody
my $message;
#Only grab the filename....but is the path ever passed??
#$filename =~ s/.*[\/\\](.*)/$1/;
$message .= "deer zanta, i can haz a prezidency?";
&sendEmail($message, $filename);
sub sendEmail{
my ($message, $filename) = ($_[0], $_[1]);
my $fromAddress = 'georgeW@texas.gov'; #from_address needs to be "creative" so that
my $toAddress = 'santa@northPole.com'; #bugzilla will authenticate as a user
my $subject = "mah giftuz";
my $signedEmail = new MIME::Entity;
my $sendmailBin = "FULL_PATH_TO_YOUR_SENDMAIL_BINARY";
my $gpgBin = "FULL_PATH_TO_YOUR_GPG_BINARY";
my $uploadDir = "/tmp";
my $filePath = $uploadDir."/".$filename;
my $password = "YOUR_GPG_SECRET_KEY_PASSWORD"; #eg. "q1!w2\@e3#"
my $secretKey = "ID_OF_YOUR_SECRET_KEY_FOR_SIGNING"; #eg. "5D8E9FB1"
my $publicKey = "ID_OF_YOUR_PUBLIC_KEY_FOR_ENCRYPTION"; #eg. "5D8E9FB1"
#(The code within Mail/GPG.pm for query_key seems to grab PUBLIC keys ONLY...)
#my $secretKey = $gpg->query_keyring (
# search => $fromAddress,
#);
#To send binary files pgp/mime signed use this
my $gpg = Mail::GPG->new (
no_strict_7bit_encoding => '1'
);
# 1) Create the first textual part of the email
my $email = MIME::Entity->build(From => $fromAddress,
To => $toAddress,
Subject => $subject,
Data => $message);
# 2) If ( there is a file name provided) then { add the file too}
if ($filename){
my $fileType = uploadInfo($filename)->{'Content-Type'};
open UPLOADFILE, ">$filePath";
binmode UPLOADFILE;
while ( <$filename> ) { print UPLOADFILE; }
close UPLOADFILE;
$email->attach(Path => $filePath,
Type => $fileType);
}
#If a file name exists, then a file exists, which we want to attach and sign
if(!($filename)){
$signedEmail = $gpg->armor_sign(
entity => $email,
key_id => $secretKey,
passphrase => $password
);
}else{
#just sign the message text
$signedEmail = $gpg->mime_sign(
entity => $email,
key_id => $secretKey,
passphrase => $password
);
}
# 4) send it on its way
open(SENDMAIL, "|$sendmailBin -t") or die "Cannot open $sendmailBin: $!";
print SENDMAIL $signedEmail->stringify;
close(SENDMAIL);
# 5) clean up after yourself
`rm $filePath`;
}
|
![]() |
| Viewing: Dev Shed Forums > Programming Languages > Perl Programming > Signing a multipart email with GPG |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|
|