X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FCrypt%2FGnuPG.pm;h=d0587d4fe3f2976edbd847675cbffc73e6aa3f1d;hb=45d35d5739d05e602bc317739485693e0e9ff0b5;hp=c5fb12befc979202920a79ff9d194c1530a846ea;hpb=aa38c070977cf63365a4d26a3e4a7e5049ad70d0;p=freeside.git diff --git a/rt/lib/RT/Crypt/GnuPG.pm b/rt/lib/RT/Crypt/GnuPG.pm index c5fb12bef..d0587d4fe 100644 --- a/rt/lib/RT/Crypt/GnuPG.pm +++ b/rt/lib/RT/Crypt/GnuPG.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -900,6 +900,33 @@ sub FindProtectedParts { $RT::Logger->warning( "Entity of type ". $entity->effective_type ." has no body" ); return (); } + + # Deal with "partitioned" PGP mail, which (contrary to common + # sense) unnecessarily applies a base64 transfer encoding to PGP + # mail (whose content is already base64-encoded). + if ( $entity->bodyhandle->is_encoded and $entity->head->mime_encoding ) { + my $decoder = MIME::Decoder->new( $entity->head->mime_encoding ); + if ($decoder) { + local $@; + eval { + my $buf = ''; + open my $fh, '>', \$buf + or die "Couldn't open scalar for writing: $!"; + binmode $fh, ":raw"; + $decoder->decode($io, $fh); + close $fh or die "Couldn't close scalar: $!"; + + open $fh, '<', \$buf + or die "Couldn't re-open scalar for reading: $!"; + binmode $fh, ":raw"; + $io = $fh; + 1; + } or do { + $RT::Logger->error("Couldn't decode body: $@"); + } + } + } + while ( defined($_ = $io->getline) ) { next unless /^-----BEGIN PGP (SIGNED )?MESSAGE-----/; my $type = $1? 'signed': 'encrypted'; @@ -1064,9 +1091,13 @@ sub VerifyDecrypt { } if ( $args{'SetStatus'} || $args{'AddStatus'} ) { my $method = $args{'AddStatus'} ? 'add' : 'set'; + # Let the header be modified so continuations are handled + my $modify = $status_on->head->modify; + $status_on->head->modify(1); $status_on->head->$method( 'X-RT-GnuPG-Status' => $res[-1]->{'status'} ); + $status_on->head->modify($modify); } } foreach my $item( grep $_->{'Type'} eq 'encrypted', @protected ) { @@ -1083,9 +1114,13 @@ sub VerifyDecrypt { } if ( $args{'SetStatus'} || $args{'AddStatus'} ) { my $method = $args{'AddStatus'} ? 'add' : 'set'; + # Let the header be modified so continuations are handled + my $modify = $status_on->head->modify; + $status_on->head->modify(1); $status_on->head->$method( 'X-RT-GnuPG-Status' => $res[-1]->{'status'} ); + $status_on->head->modify($modify); } } return @res; @@ -2107,7 +2142,9 @@ sub GetKeysInfo { eval { local $SIG{'CHLD'} = 'DEFAULT'; my $method = $type eq 'private'? 'list_secret_keys': 'list_public_keys'; - my $pid = safe_run_child { $gnupg->$method( handles => $handles, $email? (command_args => $email) : () ) }; + my $pid = safe_run_child { $gnupg->$method( handles => $handles, $email + ? (command_args => [ "--", $email]) + : () ) }; close $handle{'stdin'}; waitpid $pid, 0; }; @@ -2123,7 +2160,10 @@ sub GetKeysInfo { } $RT::Logger->debug( $res{'status'} ) if $res{'status'}; $RT::Logger->warning( $res{'stderr'} ) if $res{'stderr'}; - $RT::Logger->error( $res{'logger'} ) if $res{'logger'} && $?; + if ( $res{'logger'} && $? ) { + $RT::Logger->error( $res{'logger'} ); + $RT::Logger->error( 'The above error may result from an unconfigured RT/GPG installation. See perldoc etc/RT_Config.pm for information about configuring or disabling GPG support for RT' ); + } if ( $@ || $? ) { $res{'message'} = $@? $@: "gpg exitted with error code ". ($? >> 8); return %res; @@ -2301,7 +2341,7 @@ sub DeleteKey { my $pid = safe_run_child { $gnupg->wrap_call( handles => $handles, commands => ['--delete-secret-and-public-key'], - command_args => [$key], + command_args => ["--", $key], ) }; close $handle{'stdin'}; while ( my $str = readline $handle{'status'} ) {