[Rt-commit] rt branch, 4.4/add-crypt-status-functions, created. rt-4.4.4-174-g46d3b0d975

Dianne Skoll dianne at bestpractical.com
Fri Nov 20 10:49:14 EST 2020


The branch, 4.4/add-crypt-status-functions has been created
        at  46d3b0d9754022a50a1bfa699cc317cf3837ee3a (commit)

- Log -----------------------------------------------------------------
commit 46d3b0d9754022a50a1bfa699cc317cf3837ee3a
Author: Dianne Skoll <dianne at bestpractical.com>
Date:   Fri Nov 20 10:32:33 2020 -0500

    Add RT::Attachment->GetCryptStatus method.
    
    This returns the parsed status from the X-RT-(SMIME|GnuPG)-Status: header, if any.

diff --git a/lib/RT/Attachment.pm b/lib/RT/Attachment.pm
index 45bd479073..355ca5fd7c 100644
--- a/lib/RT/Attachment.pm
+++ b/lib/RT/Attachment.pm
@@ -864,6 +864,46 @@ sub _CanonicalizeHeaderValue {
     return $value;
 }
 
+=head2 GetCryptStatus
+
+Returns the parsed status from the X-RT-GnuPG-Status or
+X-RT-SMIME-Status header.
+
+The return value is an array of hashrefs; each hashref is as described
+in L<RT::Crypt::ParseStatus>; however, each hashref has one additional
+entry 'Protocol' which is the name of the crypto protocol used
+ and is one of 'SMIME' or 'GnuPG'.
+
+If no crypto header exists, returns the array: ( { Protocol => 'None' } )
+
+=cut
+
+sub GetCryptStatus
+{
+    my $self = shift;
+    my @result = ( {Protocol => 'None' } );
+
+    foreach my $h ($self->SplitHeaders) {
+        next unless $h =~ /^X-RT-(GnuPG|SMIME)-Status:/i;
+        my $protocol = $1;
+        my ($h_key, $h_val) = split(/:\s*/, $h, 2);
+        @result = RT::Crypt->ParseStatus(Protocol => $protocol,
+                                         Status => $h_val);
+
+        # Canonicalize protocol case so it's always SMIME or GnuPG
+        if (uc($protocol) eq 'SMIME') {
+            $protocol = 'SMIME';
+        } elsif (uc($protocol) eq 'GNUPG') {
+            $protocol = 'GnuPG';
+        }
+        foreach my $hash (@result) {
+            $hash->{'Protocol'} = $protocol;
+        }
+        last;
+    }
+    return @result;
+}
+
 =head2 SplitHeaders
 
 Returns an array of this attachment object's headers, with one header 
diff --git a/t/mail/gnupg-incoming.t b/t/mail/gnupg-incoming.t
index 7b373e54bd..c8a4fcc678 100644
--- a/t/mail/gnupg-incoming.t
+++ b/t/mail/gnupg-incoming.t
@@ -9,13 +9,15 @@ BEGIN {
 }
 
 use RT::Test::GnuPG
-  tests         => 53,
+  tests         => 55,
   actual_server => 1,
   gnupg_options => {
     passphrase => 'rt-test',
     homedir    => $homedir,
   };
 
+use Test::Deep;
+
 use String::ShellQuote 'shell_quote';
 use IPC::Run3 'run3';
 use MIME::Base64;
@@ -61,6 +63,9 @@ RT::Test->close_mailgate_ok($mail);
         'recorded incoming mail that is not encrypted'
     );
     like( $txn->Attachments->First->Content, qr/Blah/);
+    my ($msg) = @{$txn->Attachments->ItemsArrayRef};
+    my @status = $msg->GetCryptStatus;
+    cmp_deeply(\@status, [{Protocol => 'None'}], 'Got expected crypt status (Protocol => None)');
 }
 
 # test for signed mail
@@ -88,7 +93,6 @@ Subject: signed message for queue
 $buf
 EOF
 RT::Test->close_mailgate_ok($mail);
-
 {
     my $tick = RT::Test->last_ticket;
     is( $tick->Subject, 'signed message for queue',
@@ -104,6 +108,30 @@ RT::Test->close_mailgate_ok($mail);
     );
     # test for some kind of PGP-Signed-By: Header
     like( $attach->Content, qr/fnord/);
+
+    my @status = $msg->GetCryptStatus;
+    cmp_deeply(\@status, [{
+            'Protocol' => 'GnuPG',
+            'Reserved' => re('^\d+$'),
+            'Version' => '4',
+            'CreationDate' => re('^\d{4}-\d{2}-\d{2}$'),
+            'Other' => undef,
+            'HashAlgo' => '2',
+            'HashAlgoName' => 'SHA-1',
+            'PubkeyAlgo' => '17',
+            'PubkeyAlgoName' => 'DSA',
+            'Fingerprint' => '7232A3C60F796865796370A54855ED8893EB9DE7',
+            'Status' => 'DONE',
+            'Key' => '4855ED8893EB9DE7',
+            'UserString' => 'Test User <recipient at example.com>',
+            'Operation' => 'Verify',
+            'Message' => 'The signature is good, signed by Test User <recipient at example.com>, trust level is ultimate',
+            'ExpireTimestamp' => '0',
+            'Class' => '00',
+            'Timestamp' => re('^\d+$'),
+            'Trust' => 'ULTIMATE',
+            'Keyword' => 'GOODSIG',
+            'PKFingerprint' => '7232A3C60F796865796370A54855ED8893EB9DE7'}], 'Got expected crypt status');
 }
 
 # test for clear-signed mail
diff --git a/t/mail/smime/incoming.t b/t/mail/smime/incoming.t
index 07897ee53d..6b798916f9 100644
--- a/t/mail/smime/incoming.t
+++ b/t/mail/smime/incoming.t
@@ -8,6 +8,7 @@ use IPC::Run3 'run3';
 use String::ShellQuote 'shell_quote';
 use RT::Tickets;
 use Test::Warn;
+use Test::Deep;
 
 my ($url, $m) = RT::Test->started_ok;
 ok $m->login, "logged in";
@@ -52,6 +53,9 @@ RT::Test->close_mailgate_ok($mail);
         'recorded incoming mail that is not encrypted'
     );
     like( $txn->Attachments->First->Content, qr'Blah');
+    my ($msg) = @{$txn->Attachments->ItemsArrayRef};
+    my @status = $msg->GetCryptStatus;
+    cmp_deeply(\@status, [{Protocol => 'None'}], 'Got expected crypt status (Protocol => None)');
 }
 
 {
@@ -135,6 +139,13 @@ RT::Test->close_mailgate_ok($mail);
         'recorded incoming mail that is encrypted'
     );
     like( $attach->Content, qr'orzzzz');
+    my @status = $msg->GetCryptStatus;
+    cmp_deeply(\@status, [{
+        Operation   => 'Decrypt',
+        Protocol    => 'SMIME',
+        Message     => 'Decryption process succeeded',
+        EncryptedTo => [{EmailAddress => 'sender at example.com'}],
+        Status      => 'DONE'}], 'Got expected encryption status');
 }
 
 {
@@ -172,6 +183,17 @@ RT::Test->close_mailgate_ok($mail);
             "Message was signed"
         );
         like( $attach->Content, qr/This is the body/ );
+        my @status = $msg->GetCryptStatus;
+        cmp_deeply(\@status, [{
+            CreatedTimestamp => re('^\d+$'),
+            ExpireTimestamp  => re('^\d+$'),
+            Issuer           => '"CA Owner" <ca.owner at example.com>',
+            Protocol         => 'SMIME',
+            Operation        => 'Verify',
+            Status           => 'DONE',
+            Message          => 'The signature is good, signed by "Enoch Root" <root at example.com>, assured by "CA Owner" <ca.owner at example.com>, trust is full',
+            UserString       => '"Enoch Root" <root at example.com>',
+            Trust            => 'FULL'}], 'Got expected crypt status for signed message');
     }
 
     # Make the signature not match

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


More information about the rt-commit mailing list