[Rt-commit] r7606 - in rt/branches/3.7-EXPERIMENTAL: .
ruz at bestpractical.com
ruz at bestpractical.com
Sat Apr 21 22:24:38 EDT 2007
Author: ruz
Date: Sat Apr 21 22:24:37 2007
New Revision: 7606
Modified:
rt/branches/3.7-EXPERIMENTAL/ (props changed)
rt/branches/3.7-EXPERIMENTAL/lib/RT/Crypt/GnuPG.pm
Log:
r5061 at cubic-pc: cubic | 2007-04-22 06:23:05 +0400
* preparse recipients
* encrypt/sign attachments inline
Modified: rt/branches/3.7-EXPERIMENTAL/lib/RT/Crypt/GnuPG.pm
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL/lib/RT/Crypt/GnuPG.pm (original)
+++ rt/branches/3.7-EXPERIMENTAL/lib/RT/Crypt/GnuPG.pm Sat Apr 21 22:24:37 2007
@@ -67,7 +67,7 @@
local *STDERR = $stderr;
local @ENV{'LANG', 'LC_ALL'} = ('C', 'C');
- shift->();
+ return shift->();
}
sub SignEncrypt {
@@ -224,7 +224,7 @@
);
$entity->parts(-1)->bodyhandle->{'_dirty_hack_to_save_a_ref_tmp_fh'} = $tmp_fh;
}
- %res;
+ return %res;
}
sub SignEncryptInline {
@@ -234,6 +234,14 @@
if ( $args{'Sign'} && !defined $args{'Signer'} ) {
$args{'Signer'} = (Mail::Address->parse( $entity->head->get( 'From' ) ))[0]->address;
}
+ if ( $args{'Encrypt'} && !$args{'Recipients'} ) {
+ my %seen;
+ $args{'Recipients'} = [
+ grep $_ && !$seen{ $_ }++, map $_->address,
+ map Mail::Address->parse( $entity->head->get( $_ ) ),
+ qw(To Cc Bcc)
+ ];
+ }
my %res;
@@ -255,10 +263,14 @@
sub _SignEncryptTextInline {
my %args = (
Entity => undef,
- Encrypt => 1,
+
Sign => 1,
Signer => undef,
Passphrase => undef,
+
+ Encrypt => 1,
+ Recipients => undef,
+
@_
);
return unless $args{'Sign'} || $args{'Encrypt'};
@@ -279,11 +291,16 @@
my $entity = $args{'Entity'};
if ( $args{'Encrypt'} ) {
- my %seen;
- $gnupg->options->push_recipients( $_ )
- foreach grep $_ && !$seen{ $_ }++, map $_->address,
- map Mail::Address->parse( $entity->head->get( $_ ) ),
- qw(To Cc Bcc);
+ unless ( $args{'Recipients'} ) {
+ my %seen;
+ $gnupg->options->push_recipients( $_ )
+ foreach grep $_ && !$seen{ $_ }++, map $_->address,
+ map Mail::Address->parse( $entity->head->get( $_ ) ),
+ qw(To Cc Bcc);
+ } else {
+ $gnupg->options->push_recipients( $_ )
+ foreach @{ $args{'Recipients'} };
+ }
}
my %res;
@@ -335,6 +352,109 @@
}
sub _SignEncryptAttachmentInline {
+ my %args = (
+ Entity => undef,
+
+ Sign => 1,
+ Signer => undef,
+ Passphrase => undef,
+
+ Encrypt => 1,
+ Recipients => undef,
+
+ @_
+ );
+ return unless $args{'Sign'} || $args{'Encrypt'};
+
+ if ( $args{'Sign'} && !defined $args{'Passphrase'} ) {
+ $args{'Passphrase'} = GetPassphrase();
+ }
+
+ my $gnupg = new GnuPG::Interface;
+ my %opt = RT->Config->Get('GnuPGOptions');
+ $opt{'digest-algo'} ||= 'SHA1';
+ $gnupg->options->hash_init(
+ _PrepareGnuPGOptions( %opt ),
+ armor => 1,
+ meta_interactive => 0,
+ ( $args{'Sign'} && $args{'Signer'}? (default_key => $args{'Signer'}): () ),
+ );
+
+ my $entity = $args{'Entity'};
+ if ( $args{'Encrypt'} ) {
+ unless ( $args{'Recipients'} ) {
+ my %seen;
+ $gnupg->options->push_recipients( $_ )
+ foreach grep $_ && !$seen{ $_ }++, map $_->address,
+ map Mail::Address->parse( $entity->head->get( $_ ) ),
+ qw(To Cc Bcc);
+ } else {
+ $gnupg->options->push_recipients( $_ )
+ foreach @{ $args{'Recipients'} };
+ }
+ }
+
+ my %res;
+
+ my ($tmp_fh, $tmp_fn) = File::Temp::tempfile();
+ binmode $tmp_fh, ':raw';
+
+ my %handle;
+ my $handles = GnuPG::Handles->new(
+ stdin => ($handle{'input'} = new IO::Handle),
+ stdout => $tmp_fh,
+ stderr => ($handle{'error'} = new IO::Handle),
+ logger => ($handle{'logger'} = new IO::Handle),
+ status => ($handle{'status'} = new IO::Handle),
+ );
+ $handles->options( 'stdout' )->{'direct'} = 1;
+ $gnupg->passphrase( $args{'Passphrase'} ) if $args{'Sign'};
+
+ eval {
+ local $SIG{'CHLD'} = 'DEFAULT';
+ my $method = $args{'Sign'} && $args{'Encrypt'}
+ ? 'sign_and_encrypt'
+ : ($args{'Sign'}? 'detach_sign': 'encrypt');
+ my $pid = _safe_run_child { $gnupg->$method( handles => $handles ) };
+ $entity->bodyhandle->print( $handle{'input'} );
+ close $handle{'input'};
+ waitpid $pid, 0;
+ };
+ $res{'exit_code'} = $?;
+ my $err = $@;
+
+ foreach ( qw(error logger status) ) {
+ $res{$_} = do { local $/; readline $handle{$_} };
+ delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s;
+ close $handle{$_};
+ }
+ $RT::Logger->debug( $res{'status'} ) if $res{'status'};
+ $RT::Logger->warning( $res{'error'} ) if $res{'error'};
+ $RT::Logger->error( $res{'logger'} ) if $res{'logger'} && $?;
+ if ( $err || $res{'exit_code'} ) {
+ $res{'message'} = $err? $err : "gpg exitted with error code ". ($res{'exit_code'} >> 8);
+ return %res;
+ }
+
+ my $filename = $entity->head->recommended_filename || 'no_name';
+ if ( $args{'Sign'} && !$args{'Encrypt'} ) {
+ $entity->make_multipart;
+ $entity->attach(
+ Type => 'application/octeat-stream',
+ Path => $tmp_fn,
+ Filename => "$filename.sig",
+ Disposition => 'attachment',
+ );
+ } else {
+ $entity->bodyhandle( new MIME::Body::File $tmp_fn );
+ $entity->effective_type('application/octeat-stream');
+ $args{'Data'}->head->mime_attr( $_ => "$filename.pgp" )
+ foreach (qw(Content-Type.name Content-Disposition.filename));
+
+ }
+ $entity->{'__store_tmp_handle_to_avoid_early_cleanup'} = $tmp_fh;
+
+ return %res;
}
More information about the Rt-commit
mailing list