[Rt-commit] r7604 - in rt/branches/3.7-EXPERIMENTAL: .
ruz at bestpractical.com
ruz at bestpractical.com
Sat Apr 21 11:44:27 EDT 2007
Author: ruz
Date: Sat Apr 21 11:44:10 2007
New Revision: 7604
Modified:
rt/branches/3.7-EXPERIMENTAL/ (props changed)
rt/branches/3.7-EXPERIMENTAL/lib/RT/Crypt/GnuPG.pm
Log:
r5046 at cubic-pc: cubic | 2007-04-21 18:48:54 +0400
* add SignEnryptInline and _SignEncryptTextInline
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 11:44:10 2007
@@ -74,9 +74,9 @@
my $format = lc RT->Config->Get('GnuPG')->{'OutgoingMessagesFormat'} || 'RFC';
if ( $format eq 'inline' ) {
- SignEncryptInline( @_ );
+ return SignEncryptInline( @_ );
} else {
- SignEncryptRFC3156( @_ );
+ return SignEncryptRFC3156( @_ );
}
}
@@ -227,6 +227,117 @@
%res;
}
+sub SignEncryptInline {
+ my %args = (@_);
+
+ my $entity = $args{'Entity'};
+ if ( $args{'Sign'} && !defined $args{'Signer'} ) {
+ $args{'Signer'} = (Mail::Address->parse( $entity->head->get( 'From' ) ))[0]->address;
+ }
+
+ my %res;
+
+ $entity->make_singlepart;
+ if ( $entity->is_multipart ) {
+ foreach ( $entity->parts ) {
+ %res = SignEncryptInline( %args, Entity => $_ );
+ return %res if $res{'exit_code'};
+ }
+ return %res;
+ }
+
+ return _SignEncryptTextInline( %args )
+ if $entity->effective_type =~ /^text\//i;
+
+ return _SignEncryptAttachmentInline( %args );
+}
+
+sub _SignEncryptTextInline {
+ my %args = (
+ Entity => undef,
+ Encrypt => 1,
+ Sign => 1,
+ Signer => undef,
+ Passphrase => 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'} ) {
+ my %seen;
+ $gnupg->options->push_recipients( $_ )
+ foreach grep $_ && !$seen{ $_ }++, map $_->address,
+ map Mail::Address->parse( $entity->head->get( $_ ) ),
+ qw(To Cc Bcc);
+ }
+
+ 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'}? 'clearsign': '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;
+ }
+
+ $entity->bodyhandle( new MIME::Body::File $tmp_fn );
+ $entity->{'__store_tmp_handle_to_avoid_early_cleanup'} = $tmp_fh;
+
+ return %res;
+}
+
+sub _SignEncryptAttachmentInline {
+
+}
+
sub FindProtectedParts {
my %args = ( Entity => undef, CheckBody => 1, @_ );
my $entity = $args{'Entity'};
More information about the Rt-commit
mailing list