[Rt-commit] rt branch, 5.0/support-gpg-2.2, created. rt-5.0.0alpha1-468-g42488ef006

? sunnavy sunnavy at bestpractical.com
Fri May 15 20:37:50 EDT 2020


The branch, 5.0/support-gpg-2.2 has been created
        at  42488ef0061d96da027e5eb9dcb5bdba940da743 (commit)

- Log -----------------------------------------------------------------
commit 734bc6972fd8250718b00344907ff2aa280c9101
Author: Aaron Trevena <ast at bestpractical.com>
Date:   Mon May 4 14:17:13 2020 +0100

    Fix uninitialized warnings of $latest_user_main_key for gpg 2.2
    
    $latest_user_main_key is set by USERID_HINT line, which is absent in gpg
    2.2 output.

diff --git a/lib/RT/Crypt/GnuPG.pm b/lib/RT/Crypt/GnuPG.pm
index c78a870b65..7fe0164db1 100644
--- a/lib/RT/Crypt/GnuPG.pm
+++ b/lib/RT/Crypt/GnuPG.pm
@@ -1542,10 +1542,12 @@ sub ParseStatus {
                 Class          => $props[3],
                 Timestamp      => $props[4],
                 KeyFingerprint => $props[5],
-                User           => $user_hint{ $latest_user_main_key },
+                ( defined $latest_user_main_key ? ( User => $user_hint{$latest_user_main_key} ) : () )
             };
-            $res[-1]->{Message} .= ' by '. $user_hint{ $latest_user_main_key }->{'EmailAddress'}
-                if $user_hint{ $latest_user_main_key };
+            if ($latest_user_main_key) {
+                $res[-1]->{Message} .= ' by '. $user_hint{ $latest_user_main_key }->{'EmailAddress'}
+                    if $user_hint{ $latest_user_main_key };
+            }
         }
         elsif ( $keyword eq 'INV_RECP' ) {
             my ($rcode, $recipient) = split /\s+/, $args, 2;

commit 4cc1b76b74dee34c42364d24e2e6ac0ba08ef9cf
Author: Aaron Trevena <ast at bestpractical.com>
Date:   Fri May 1 21:26:01 2020 +0100

    Handle FAILURE keyword for gpg 2.2

diff --git a/lib/RT/Crypt/GnuPG.pm b/lib/RT/Crypt/GnuPG.pm
index 7fe0164db1..e0311b27a5 100644
--- a/lib/RT/Crypt/GnuPG.pm
+++ b/lib/RT/Crypt/GnuPG.pm
@@ -1344,7 +1344,7 @@ my %parse_keyword = map { $_ => 1 } qw(
     DECRYPTION_FAILED DECRYPTION_OKAY
     BAD_PASSPHRASE GOOD_PASSPHRASE
     NO_SECKEY NO_PUBKEY
-    NO_RECP INV_RECP NODATA UNEXPECTED
+    NO_RECP INV_RECP NODATA UNEXPECTED FAILURE
 );
 
 # keywords we ignore without any messages as we parse them using other
@@ -1572,8 +1572,20 @@ sub ParseStatus {
                 Reason     => $reason,
             };
         }
+        elsif ( $keyword eq 'FAILURE' ) {
+            # FAILURE encrypt 167772218
+            my ($op, $rcode) = split /\s+/, $args;
+            my $reason = ReasonCodeToText( $keyword, $rcode );
+            push @res, {
+                Operation  => ucfirst($op),
+                Status     => 'ERROR',
+                Message    => "Failed to $op",
+                ReasonCode => $rcode,
+                Reason     => $reason,
+            };
+        }
         else {
-            $RT::Logger->warning("Keyword $keyword is unknown");
+            $RT::Logger->warning("Keyword $keyword is unknown : status line is $line");
             next;
         }
         $res[-1]{'Keyword'} = $keyword if @res && !$res[-1]{'Keyword'};

commit ee9a2a7bcf0f26376aca19e9fdb5e4568a1728be
Author: Aaron Trevena <ast at bestpractical.com>
Date:   Wed May 6 17:00:50 2020 +0100

    Add extra ignored keywords for gnupg 2.2.x

diff --git a/lib/RT/Crypt/GnuPG.pm b/lib/RT/Crypt/GnuPG.pm
index e0311b27a5..93ee2d56ec 100644
--- a/lib/RT/Crypt/GnuPG.pm
+++ b/lib/RT/Crypt/GnuPG.pm
@@ -1354,7 +1354,8 @@ my %ignore_keyword = map { $_ => 1 } qw(
     BEGIN_ENCRYPTION SIG_ID VALIDSIG
     ENC_TO BEGIN_DECRYPTION END_DECRYPTION GOODMDC
     TRUST_UNDEFINED TRUST_NEVER TRUST_MARGINAL TRUST_FULLY TRUST_ULTIMATE
-    DECRYPTION_INFO
+    DECRYPTION_INFO KEY_CONSIDERED DECRYPTION_KEY NEWSIG PINENTRY_LAUNCHED
+    IMPORT_OK DECRYPTION_COMPLIANCE_MODE PROGRESS INV_SGNR
 );
 
 sub ParseStatus {

commit 37eb1901a631db493f33ffe7dcaa5db543ce4bf3
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri May 15 15:32:00 2020 +0800

    Default cert-digest-algo from SHA1 to SHA256
    
    Since 2.2.18, SHA1 is not allowed any more, the error message is:
    
        third-party key signatures using the SHA1 algorithm are rejected

diff --git a/lib/RT/Crypt/GnuPG.pm b/lib/RT/Crypt/GnuPG.pm
index 93ee2d56ec..f0c9a6d12f 100644
--- a/lib/RT/Crypt/GnuPG.pm
+++ b/lib/RT/Crypt/GnuPG.pm
@@ -330,6 +330,7 @@ sub CallGnuPG {
     my %GnuPGOptions = RT->Config->Get('GnuPGOptions');
     my %opt = (
         'digest-algo' => 'SHA1',
+        'cert-digest-algo' => 'SHA256',
         %GnuPGOptions,
         %{ $args{Options} || {} },
     );

commit d7db6faad89d0b53803859b81a255cf843746866
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat May 16 00:37:00 2020 +0800

    Add gpg.conf for gpg 2.2 so we can specify passphrase in command line
    
    The option "pinentry-mode loopback" is invalid in gpg 1.4, so we need to
    delete the conf file accordingly.

diff --git a/lib/RT/Test/GnuPG.pm b/lib/RT/Test/GnuPG.pm
index 414097e810..afa0a42ec8 100644
--- a/lib/RT/Test/GnuPG.pm
+++ b/lib/RT/Test/GnuPG.pm
@@ -52,6 +52,7 @@ use warnings;
 use Test::More;
 use base qw(RT::Test);
 use File::Temp qw(tempdir);
+use 5.010;
 
 our @EXPORT =
   qw(create_a_ticket update_ticket cleanup_headers set_queue_crypt_options 
@@ -96,6 +97,16 @@ sub bootstrap_more_config {
     );
     $gnupg_options{homedir} ||= scalar tempdir( CLEANUP => 1 );
 
+    my $conf = File::Spec->catfile( $gnupg_options{homedir}, 'gpg.conf' );
+    if ( gnupg_version() >= 2 ) {
+        open my $fh, '>', $conf or die $!;
+        print $fh "pinentry-mode loopback\n";
+        close $fh;
+    }
+    else {
+        unlink $conf if -e $conf;
+    }
+
     use Data::Dumper;
     local $Data::Dumper::Terse = 1; # "{...}" instead of "$VAR1 = {...};"
     my $dumped_gnupg_options = Dumper(\%gnupg_options);
@@ -363,3 +374,11 @@ sub create_and_test_outgoing_emails {
         }
     }
 }
+
+sub gnupg_version {
+    require GnuPG::Interface;
+    require version;
+    state $gnupg_version = version->parse(GnuPG::Interface->new->version);
+}
+
+1;

commit 3722d4c20550d3f5f364e7bccc3b8ba7fe8831f1
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri May 15 20:16:10 2020 +0800

    Update warning message tests for gpg 2.2

diff --git a/t/crypt/no-signer-address.t b/t/crypt/no-signer-address.t
index 31ba5ebc2a..4c459c06a8 100644
--- a/t/crypt/no-signer-address.t
+++ b/t/crypt/no-signer-address.t
@@ -36,7 +36,6 @@ my ($status, undef, $msg) = $ticket->Create(
 ok( $status, "created ticket" ) or diag "error: $msg";
 
 is( scalar @warnings, 1, "Got a warning" );
-like( $warnings[0], qr{signing failed: secret key not available},
-    "Found warning of no secret key");
+like( $warnings[0], qr{signing failed: (?:secret key not available|No secret key)}, "Found warning of no secret key" );
 
 done_testing;
diff --git a/t/mail/gnupg-reverification.t b/t/mail/gnupg-reverification.t
index e5dcf09bb4..1ec9aa19e8 100644
--- a/t/mail/gnupg-reverification.t
+++ b/t/mail/gnupg-reverification.t
@@ -60,11 +60,11 @@ foreach my $file ( @files ) {
     );
     $m->content_like(qr/This is .*ID:$eid/ims, "$eid: content is there and message is decrypted");
 
-    $m->next_warning_like(qr/public key not found/);
+    $m->next_warning_like(qr/public key not found|No public key/);
 
     # some mails contain multiple signatures
     if ($eid == 5 || $eid == 17 || $eid == 18) {
-        $m->next_warning_like(qr/public key not found/);
+        $m->next_warning_like(qr/public key not found|No public key/);
     }
 
     $m->no_leftover_warnings_ok;
diff --git a/t/security/CVE-2012-4735-incoming-encryption-header.t b/t/security/CVE-2012-4735-incoming-encryption-header.t
index 6c15632979..bd89e67566 100644
--- a/t/security/CVE-2012-4735-incoming-encryption-header.t
+++ b/t/security/CVE-2012-4735-incoming-encryption-header.t
@@ -57,7 +57,7 @@ EOF
     warnings_like {
         ($status, $id) = RT::Test->send_via_mailgate($mail);
         ok $id, "created a ticket";
-    } [qr/keyring .* created/,
+    } [qr/(?:keyring|keybox) .* created/,
        qr/Failure during GnuPG data: No data has been found\. The reason is 'Invalid packet found'/,
        qr/Failure during GnuPG data: No data has been found\. The reason is 'No armored data'/,
    ];
diff --git a/t/web/crypt-gnupg.t b/t/web/crypt-gnupg.t
index fed621ce46..827d06d2c6 100644
--- a/t/web/crypt-gnupg.t
+++ b/t/web/crypt-gnupg.t
@@ -355,7 +355,7 @@ warning_like {
     $tick->Create(Subject => 'owner lacks pubkey', Queue => 'general',
                   Owner => $nokey);
 } [
-    qr/nokey\@example.com: skipped: public key not found/,
+    qr/nokey\@example.com: skipped: public key not found|error retrieving 'nokey\@example.com' via WKD: No data/,
     qr/Recipient 'nokey\@example.com' is unusable/,
 ];
 ok(my $id = $tick->id, 'created ticket for owner-without-pubkey');
@@ -377,7 +377,7 @@ my $status;
 warning_like {
     ($status, $id) = RT::Test->send_via_mailgate($mail);
 } [
-    qr/nokey\@example.com: skipped: public key not found/,
+    qr/nokey\@example.com: skipped: public key not found|error retrieving 'nokey\@example.com' via WKD: No data/,
     qr/Recipient 'nokey\@example.com' is unusable/,
 ];
 
@@ -458,8 +458,8 @@ like($content, qr/KR-<recipient\@example\.com>-K/,
 like($content, qr/KR-nokey \(no pubkey!\)-K/,
      "KeyRequestors DOES issue no-pubkey warning for nokey\@example.com");
 
-$m->next_warning_like(qr/public key not found/);
-$m->next_warning_like(qr/public key not found/);
+$m->next_warning_like(qr/public key not found|No public key/);
+$m->next_warning_like(qr/public key not found|No public key/);
 $m->no_leftover_warnings_ok;
 
 done_testing;
diff --git a/t/web/gnupg-select-keys-on-create.t b/t/web/gnupg-select-keys-on-create.t
index 64d6c6e46d..78e1fbba02 100644
--- a/t/web/gnupg-select-keys-on-create.t
+++ b/t/web/gnupg-select-keys-on-create.t
@@ -28,7 +28,7 @@ diag "check that signing doesn't work if there is no key";
         'unable to sign outgoing email messages',
         'problems with passphrase'
     );
-    $m->warning_like(qr/signing failed: secret key not available/);
+    $m->warning_like(qr/signing failed: (?:secret key not available|No secret key)/);
 
     my @mail = RT::Test->fetch_caught_mails;
     ok !@mail, 'there are no outgoing emails';
@@ -66,7 +66,7 @@ diag "check that things don't work if there is no key";
     my @mail = RT::Test->fetch_caught_mails;
     ok !@mail, 'there are no outgoing emails';
 
-    $m->next_warning_like(qr/public key not found/) for 1 .. 2;
+    $m->next_warning_like(qr/public key not found|No public key/) for 1 .. 2;
     $m->no_leftover_warnings_ok;
 }
 

commit 147ebd0beb771565392bf4a382a9f7be56e9d5d7
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat May 16 03:35:09 2020 +0800

    Don't override fingerprint if it exsits already
    
    With gpg 2.2, subkey fingerprints also show up(after mainkeys), thus we
    need to prevent them from wrongly overridding ones of mainkeys.

diff --git a/lib/RT/Crypt/GnuPG.pm b/lib/RT/Crypt/GnuPG.pm
index f0c9a6d12f..4ece75390a 100644
--- a/lib/RT/Crypt/GnuPG.pm
+++ b/lib/RT/Crypt/GnuPG.pm
@@ -1755,7 +1755,7 @@ sub ParseKeysInfo {
             push @{ $res[-1]{'User'} ||= [] }, \%info;
         }
         elsif ( $tag eq 'fpr' ) {
-            $res[-1]{'Fingerprint'} = (split /:/, $line, 10)[8];
+            $res[-1]{'Fingerprint'} ||= (split /:/, $line, 10)[8];
         }
     }
     return @res;

commit 0063439530bfbe004e890cb8da485977d039691d
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri May 15 23:20:56 2020 +0800

    Make t/mail/crypt-gnupg.t happy with gpg 2.2
    
    Besides the differences of returned info from gpg 1.4 and 2.2, the
    missing passphrase tests are skipped because otherwise the test would
    hang(probably waiting for passphrase input)

diff --git a/t/mail/crypt-gnupg.t b/t/mail/crypt-gnupg.t
index 567573e934..a19235fc5a 100644
--- a/t/mail/crypt-gnupg.t
+++ b/t/mail/crypt-gnupg.t
@@ -10,9 +10,11 @@ BEGIN {
         qw/data gnupg keyrings/ );
 }
 
-use RT::Test::GnuPG tests => 100, gnupg_options => { homedir => $homedir };
+use RT::Test::GnuPG tests => undef, gnupg_options => { homedir => $homedir, quiet => 1 };
 use Test::Warn;
 
+my $gnupg_version = RT::Test::GnuPG::gnupg_version;
+
 use_ok('RT::Crypt');
 use_ok('MIME::Entity');
 
@@ -29,12 +31,22 @@ diag 'only signing. correct passphrase';
     my @status = RT::Crypt->ParseStatus(
         Protocol => $res{'Protocol'}, Status => $res{'status'}
     );
-    is( scalar @status, 2, 'two records: passphrase, signing');
-    is( $status[0]->{'Operation'}, 'PassphraseCheck', 'operation is correct');
-    is( $status[0]->{'Status'}, 'DONE', 'good passphrase');
-    is( $status[1]->{'Operation'}, 'Sign', 'operation is correct');
-    is( $status[1]->{'Status'}, 'DONE', 'done');
-    is( $status[1]->{'User'}->{'EmailAddress'}, 'rt at example.com', 'correct email');
+
+    if ( $gnupg_version < 2 ) {
+        is( scalar @status,                         2,                 'two records: passphrase, signing' );
+        is( $status[0]->{'Operation'},              'PassphraseCheck', 'operation is correct' );
+        is( $status[0]->{'Status'},                 'DONE',            'good passphrase' );
+        is( $status[1]->{'Operation'},              'Sign',            'operation is correct' );
+        is( $status[1]->{'Status'},                 'DONE',            'done' );
+        is( $status[1]->{'User'}->{'EmailAddress'}, 'rt at example.com',  'correct email' );
+    }
+    else {
+        is( scalar @status,                 1,                                          'one record: signing' );
+        is( $status[0]->{'Operation'},      'Sign',                                     'operation is correct' );
+        is( $status[0]->{'Status'},         'DONE',                                     'done' );
+        is( $status[0]->{'Message'},        'Signed message',                           'message is correct' );
+        is( $status[0]->{'KeyFingerprint'}, 'F23574193C1BA40ACB8DC6A4B5A462194345F7A5', 'signing key is correct' );
+    }
 
     ok( $entity->is_multipart, 'signed message is multipart' );
     is( $entity->parts, 2, 'two parts' );
@@ -56,8 +68,12 @@ diag 'only signing. correct passphrase';
     is( $status[0]->{'Trust'}, 'ULTIMATE', 'have trust value');
 }
 
+# To forget passphrase
+system( 'gpg-connect-agent', "--homedir", $homedir, 'reloadagent', '/bye' );
+
 diag 'only signing. missing passphrase';
-{
+SKIP: {
+    skip "Test hangs waiting for passphrase", 6 unless $gnupg_version < 2;
     my $entity = MIME::Entity->build(
         From    => 'rt at example.com',
         Subject => 'test',
@@ -97,7 +113,7 @@ diag 'only signing. wrong passphrase';
             Encrypt    => 0,
             Passphrase => 'wrong',
         );
-    } qr/bad passphrase/;
+    } qr/bad passphrase/i;
 
     ok( $res{'exit_code'}, "couldn't sign with bad passphrase");
     ok( $res{'error'} || $res{'logger'}, "error is here" );
@@ -106,8 +122,8 @@ diag 'only signing. wrong passphrase';
         Protocol => $res{'Protocol'}, Status => $res{'status'}
     );
     is( scalar @status, 1, 'one record');
-    is( $status[0]->{'Operation'}, 'PassphraseCheck', 'operation is correct');
-    is( $status[0]->{'Status'}, 'BAD', 'wrong passphrase');
+    like( $status[0]->{'Operation'}, qr/PassphraseCheck|Sign/, 'operation is correct');
+    like( $status[0]->{'Status'}, qr/BAD|ERROR/, 'wrong passphrase');
 }
 
 diag 'encryption only';
@@ -153,7 +169,7 @@ diag 'encryption only, bad recipient';
             Entity => $entity,
             Sign   => 0,
         );
-    } qr/public key not found/;
+    } qr/public key not found|error retrieving 'keyless\@example.com' via WKD: No data/;
 
     ok( $res{'exit_code'}, 'no way to encrypt without keys of recipients');
     ok( $res{'logger'}, "errors are in logger" );
@@ -161,8 +177,15 @@ diag 'encryption only, bad recipient';
     my @status = RT::Crypt->ParseStatus(
         Protocol => $res{'Protocol'}, Status => $res{'status'}
     );
-    is( scalar @status, 1, 'one record');
-    is( $status[0]->{'Keyword'}, 'INV_RECP', 'invalid recipient');
+    if ( $gnupg_version < 2 ) {
+        is( scalar @status,          1,          'one record' );
+        is( $status[0]->{'Keyword'}, 'INV_RECP', 'invalid recipient' );
+    }
+    else {
+        is( scalar @status,          2,          '2 records' );
+        is( $status[0]->{'Keyword'}, 'INV_RECP', 'invalid recipient' );
+        is( $status[1]->{'Keyword'}, 'FAILURE',  'failure' );
+    }
 }
 
 diag 'encryption and signing with combined method';
@@ -175,18 +198,27 @@ diag 'encryption and signing with combined method';
     );
     my %res = RT::Crypt->SignEncrypt( Entity => $entity, Passphrase => 'test' );
     ok( !$res{'exit_code'}, "successful encryption with signing" );
-    ok( !$res{'logger'}, "no records in logger" );
+    ok( !$res{'logger'}, "log is here as well" ) or diag $res{'logger'};
 
     my @status = RT::Crypt->ParseStatus(
         Protocol => $res{'Protocol'}, Status => $res{'status'}
     );
-    is( scalar @status, 3, 'three records: passphrase, sign and encrypt');
-    is( $status[0]->{'Operation'}, 'PassphraseCheck', 'operation is correct');
-    is( $status[0]->{'Status'}, 'DONE', 'done');
-    is( $status[1]->{'Operation'}, 'Sign', 'operation is correct');
-    is( $status[1]->{'Status'}, 'DONE', 'done');
-    is( $status[2]->{'Operation'}, 'Encrypt', 'operation is correct');
-    is( $status[2]->{'Status'}, 'DONE', 'done');
+    if ($gnupg_version < 2) {
+        is( scalar @status, 3, 'three records: passphrase, sign and encrypt');
+        is( $status[0]->{'Operation'}, 'PassphraseCheck', 'operation is correct');
+        is( $status[0]->{'Status'}, 'DONE', 'done');
+        is( $status[1]->{'Operation'}, 'Sign', 'operation is correct');
+        is( $status[1]->{'Status'}, 'DONE', 'done');
+        is( $status[2]->{'Operation'}, 'Encrypt', 'operation is correct');
+        is( $status[2]->{'Status'}, 'DONE', 'done');
+    }
+    else {
+        is( scalar @status, 2, 'two records: sign and encrypt');
+        is( $status[0]->{'Operation'}, 'Sign', 'operation is correct');
+        is( $status[0]->{'Status'}, 'DONE', 'done');
+        is( $status[1]->{'Operation'}, 'Encrypt', 'operation is correct');
+        is( $status[1]->{'Status'}, 'DONE', 'done');
+    }
 
     ok($entity, 'get an encrypted and signed part');
 
@@ -353,3 +385,4 @@ diag 'verify inline and in attachment signatures';
     $parser->filer->purge();
 }
 
+done_testing;

commit 77ed189c47c35c6c32ba7e539650e27b6d2fe922
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat May 16 04:46:45 2020 +0800

    Bump GnuPG::Interface to 1.00 to support gpg 2.2

diff --git a/etc/cpanfile b/etc/cpanfile
index 995dd9730e..a4f903c1e9 100644
--- a/etc/cpanfile
+++ b/etc/cpanfile
@@ -182,7 +182,7 @@ feature 'sqlite' => sub {
 # Optional features
 feature 'gpg' => sub {
     requires 'File::Which';
-    requires 'GnuPG::Interface';
+    requires 'GnuPG::Interface', '>= 1.00';
     requires 'PerlIO::eol';
 };
 

commit e8d43332faa300c1b8d7c1138021951742a02669
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat May 16 05:53:55 2020 +0800

    Quit gpg-agent after tests for gpg 2.2

diff --git a/lib/RT/Test/GnuPG.pm b/lib/RT/Test/GnuPG.pm
index afa0a42ec8..b8356f4a5f 100644
--- a/lib/RT/Test/GnuPG.pm
+++ b/lib/RT/Test/GnuPG.pm
@@ -381,4 +381,11 @@ sub gnupg_version {
     state $gnupg_version = version->parse(GnuPG::Interface->new->version);
 }
 
+END {
+    if ( gnupg_version() >= 2 ) {
+        system( 'gpgconf', '--homedir', RT->Config->Get('GnuPGOptions')->{homedir}, '--quiet', '--kill', 'gpg-agent' )
+            && warn $!;
+    }
+}
+
 1;

commit 194b1ac55b24c503f7ea4b410d2f1d253fdeaef0
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat May 16 07:17:05 2020 +0800

    Move signed_old_style_with_attachment.eml to emails directory where it belongs to

diff --git a/t/data/gnupg/keyrings/signed_old_style_with_attachment.eml b/t/data/gnupg/emails/signed_old_style_with_attachment.eml
similarity index 100%
rename from t/data/gnupg/keyrings/signed_old_style_with_attachment.eml
rename to t/data/gnupg/emails/signed_old_style_with_attachment.eml
diff --git a/t/mail/crypt-gnupg.t b/t/mail/crypt-gnupg.t
index a19235fc5a..0f6243aec9 100644
--- a/t/mail/crypt-gnupg.t
+++ b/t/mail/crypt-gnupg.t
@@ -358,7 +358,7 @@ diag 'wrong signed/encrypted parts: wrong proto';
 
 diag 'verify inline and in attachment signatures';
 {
-    open( my $fh, '<', "$homedir/signed_old_style_with_attachment.eml" ) or die $!;
+    open( my $fh, '<', "t/data/gnupg/emails/signed_old_style_with_attachment.eml" ) or die $!;
     my $parser = new MIME::Parser;
     my $entity = $parser->parse( $fh );
 

commit 42488ef0061d96da027e5eb9dcb5bdba940da743
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat May 16 07:50:40 2020 +0800

    Always use temp gpg homedir to get a cleaner env
    
    There are some temporary files(like gpg.conf) created and also other
    content changes in gpg homedir, using a clean gpg homedir is more robust
    and could prevent possible conflicts in the future.

diff --git a/lib/RT/Test/GnuPG.pm b/lib/RT/Test/GnuPG.pm
index b8356f4a5f..8e911236c3 100644
--- a/lib/RT/Test/GnuPG.pm
+++ b/lib/RT/Test/GnuPG.pm
@@ -52,6 +52,8 @@ use warnings;
 use Test::More;
 use base qw(RT::Test);
 use File::Temp qw(tempdir);
+use IPC::Run3 'run3';
+use File::Copy;
 use 5.010;
 
 our @EXPORT =
@@ -95,7 +97,7 @@ sub bootstrap_more_config {
         'no-permission-warning' => undef,
         $args->{gnupg_options} ? %{ $args->{gnupg_options} } : (),
     );
-    $gnupg_options{homedir} ||= scalar tempdir( CLEANUP => 1 );
+    $gnupg_options{homedir} ||= new_homedir();
 
     my $conf = File::Spec->catfile( $gnupg_options{homedir}, 'gpg.conf' );
     if ( gnupg_version() >= 2 ) {
@@ -381,6 +383,25 @@ sub gnupg_version {
     state $gnupg_version = version->parse(GnuPG::Interface->new->version);
 }
 
+sub new_homedir {
+    my $source = shift;
+    my $dir = tempdir();
+
+    if ($source) {
+        opendir my $dh, $source or die $!;
+        for my $file ( grep {/\.gpg$/} readdir $dh ) {
+            copy( File::Spec->catfile( $source, $file ), File::Spec->catfile( $dir, $file ) ) or die $!;
+        }
+        closedir $dh;
+        if ( gnupg_version() >= 2 ) {
+            # Do the data migration
+            run3( [ 'gpg', '--homedir', $dir, '--list-secret-keys' ], \undef, \undef, \undef );
+        }
+    }
+
+    return $dir;
+}
+
 END {
     if ( gnupg_version() >= 2 ) {
         system( 'gpgconf', '--homedir', RT->Config->Get('GnuPGOptions')->{homedir}, '--quiet', '--kill', 'gpg-agent' )
diff --git a/t/mail/crypt-gnupg.t b/t/mail/crypt-gnupg.t
index 0f6243aec9..70c7447831 100644
--- a/t/mail/crypt-gnupg.t
+++ b/t/mail/crypt-gnupg.t
@@ -4,10 +4,9 @@ use warnings;
 
 my $homedir;
 BEGIN {
-    require RT::Test;
-    $homedir =
-      RT::Test::get_abs_relocatable_dir( File::Spec->updir(),
-        qw/data gnupg keyrings/ );
+    require RT::Test::GnuPG;
+    $homedir = RT::Test::GnuPG::new_homedir(
+        RT::Test::get_abs_relocatable_dir( File::Spec->updir(), qw/data gnupg keyrings/ ) );
 }
 
 use RT::Test::GnuPG tests => undef, gnupg_options => { homedir => $homedir, quiet => 1 };
diff --git a/t/mail/gnupg-bad.t b/t/mail/gnupg-bad.t
index a9fd45a493..3ecbdb9bf0 100644
--- a/t/mail/gnupg-bad.t
+++ b/t/mail/gnupg-bad.t
@@ -5,9 +5,9 @@ use RT::Test::GnuPG
   tests         => 7,
   gnupg_options => {
     passphrase => 'rt-test',
-    homedir => RT::Test::get_abs_relocatable_dir(
+    homedir => RT::Test::GnuPG::new_homedir(RT::Test::get_abs_relocatable_dir(
         File::Spec->updir(), qw/data gnupg keyrings/
-    ),
+    )),
   };
 
 my ($baseurl, $m) = RT::Test->started_ok;
diff --git a/t/mail/gnupg-incoming.t b/t/mail/gnupg-incoming.t
index 54b30d2a36..7b373e54bd 100644
--- a/t/mail/gnupg-incoming.t
+++ b/t/mail/gnupg-incoming.t
@@ -3,10 +3,9 @@ use warnings;
 
 my $homedir;
 BEGIN {
-    require RT::Test;
-    $homedir =
-      RT::Test::get_abs_relocatable_dir( File::Spec->updir(),
-        qw/data gnupg keyrings/ );
+    require RT::Test::GnuPG;
+    $homedir = RT::Test::GnuPG::new_homedir(
+        RT::Test::get_abs_relocatable_dir( File::Spec->updir(), qw/data gnupg keyrings/ ) ),
 }
 
 use RT::Test::GnuPG

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


More information about the rt-commit mailing list