[Rt-commit] rt branch, 3.8/partitioned-gpg, created. rt-3.8.11-18-g258ec2f

Alex Vandiver alexmv at bestpractical.com
Wed May 9 19:02:11 EDT 2012


The branch, 3.8/partitioned-gpg has been created
        at  258ec2fb531c83df00afae3f428975b9871e1f68 (commit)

- Log -----------------------------------------------------------------
commit 258ec2fb531c83df00afae3f428975b9871e1f68
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed May 9 18:45:06 2012 -0400

    Support "partitioned" GPG mail whose bodies are transfer-encoded
    
    Most PGP clients do not put a Content-Transfer-Encoding on inline PGP
    messages, as the content of the body is already base64 encoded.
    However, some clients (or MTAs enroute) may elect to do so.  As
    RT::EmailParser->ParseMIMEntity is passed Exact => 1, which forces
    MIME::Parser->decode_bodies(0), ->open('r') thus gets the _undecoded_
    body of the message, and searches for ---BEGIN PGP MESSAGE--- fail.
    
    Temporarily pass the body through MIME::Decoder to undo transfer
    encoding before checking for the PGP armoring in inline messages.
    11231ea already ensures that the decoded body is used to the actual
    decryption process later, once recognition has happened.

diff --git a/lib/RT/Crypt/GnuPG.pm b/lib/RT/Crypt/GnuPG.pm
index bb8b2db..2efee33 100644
--- a/lib/RT/Crypt/GnuPG.pm
+++ b/lib/RT/Crypt/GnuPG.pm
@@ -900,6 +900,19 @@ 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 ) {
+            pipe( my ($read_decoded, $write_decoded) );
+            my $decoder = MIME::Decoder->new( $entity->head->mime_encoding );
+            if ($decoder) {
+                eval { $decoder->decode($io, $write_decoded) };
+                $io = $read_decoded;
+            }
+        }
+
         while ( defined($_ = $io->getline) ) {
             next unless /^-----BEGIN PGP (SIGNED )?MESSAGE-----/;
             my $type = $1? 'signed': 'encrypted';
diff --git a/t/mail/gnupg-incoming.t b/t/mail/gnupg-incoming.t
index 230aa9c..c34ed99 100644
--- a/t/mail/gnupg-incoming.t
+++ b/t/mail/gnupg-incoming.t
@@ -2,18 +2,18 @@
 use strict;
 use warnings;
 
-use RT::Test tests => 39;
+use RT::Test tests => 47;
 
 plan skip_all => 'GnuPG required.'
     unless eval 'use GnuPG::Interface; 1';
 plan skip_all => 'gpg executable is required.'
     unless RT::Test->find_executable('gpg');
 
-
 use File::Temp;
 use Cwd 'getcwd';
 use String::ShellQuote 'shell_quote';
 use IPC::Run3 'run3';
+use MIME::Base64;
 
 my $homedir = RT::Test::get_abs_relocatable_dir(File::Spec->updir(),
     qw(data gnupg keyrings));
@@ -206,6 +206,44 @@ RT::Test->close_mailgate_ok($mail);
     ok(index($orig->Content, $buf) != -1, 'found original msg');
 }
 
+
+# test that if it gets base64 transfer-encoded, we still get the content out
+$buf = encode_base64($buf);
+$mail = RT::Test->open_mailgate_ok($baseurl);
+print $mail <<"EOF";
+From: recipient\@example.com
+To: general\@$RT::rtname
+Content-transfer-encoding: base64
+Subject: Encrypted message for queue
+
+$buf
+EOF
+RT::Test->close_mailgate_ok($mail);
+
+{
+    my $tick = RT::Test->last_ticket;
+    is( $tick->Subject, 'Encrypted message for queue',
+        "Created the ticket"
+    );
+
+    my $txn = $tick->Transactions->First;
+    my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef};
+
+    is( $msg->GetHeader('X-RT-Incoming-Encryption'),
+        'Success',
+        'recorded incoming mail that is encrypted'
+    );
+    is( $msg->GetHeader('X-RT-Privacy'),
+        'PGP',
+        'recorded incoming mail that is encrypted'
+    );
+    like( $attach->Content, qr/orz/);
+
+    is( $orig->GetHeader('Content-Type'), 'application/x-rt-original-message');
+    ok(index($orig->Content, $buf) != -1, 'found original msg');
+}
+
+
 # test for signed mail by other key
 $buf = '';
 

-----------------------------------------------------------------------


More information about the Rt-commit mailing list