[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