[Rt-commit] rt branch, 4.4/crypt-minor-fixes, updated. rt-4.4.4-243-gcce6227e08
Dianne Skoll
dianne at bestpractical.com
Fri Feb 5 16:09:40 EST 2021
The branch, 4.4/crypt-minor-fixes has been updated
via cce6227e080013764694b0a38aa0b95cc70ab08c (commit)
from 53e13897f11ac805df63f1c6d9c0a713ac9cad9e (commit)
Summary of changes:
lib/RT/Crypt/SMIME.pm | 49 ++++++++++++++++++++++++++++++++++++++
share/html/Crypt/GetSMIMECert.html | 23 +++++++++++++-----
2 files changed, 66 insertions(+), 6 deletions(-)
- Log -----------------------------------------------------------------
commit cce6227e080013764694b0a38aa0b95cc70ab08c
Author: Dianne Skoll <dianne at bestpractical.com>
Date: Fri Feb 5 16:09:00 2021 -0500
Download S/MIME certificate attached to transaction rather than user
This guarantees that the certificate we download is the one that
was actually used to sign the mail attached to the transaction.
diff --git a/lib/RT/Crypt/SMIME.pm b/lib/RT/Crypt/SMIME.pm
index e7540bb558..29b7295228 100644
--- a/lib/RT/Crypt/SMIME.pm
+++ b/lib/RT/Crypt/SMIME.pm
@@ -1255,4 +1255,53 @@ sub SupportsCRLfile {
return $OpenSSL_Supports_CRLfile;
};
+# Given a Transaction object, find the application/x-rt-original-message
+# (if any). If found, try to find the S/MIME signature. Return
+# the certificate found in that signature.
+# Returns: undef if we could not find a certificate; otherwise, an
+# S/MIME certificate in PEM format.
+sub GetCertificateForTransaction {
+ my ($self, $txn) = @_;
+
+ my $attachments = $txn->Attachments;
+ my $found;
+
+ # Look for the application/x-rt-original-message attachment
+ while (my $a = $attachments->Next) {
+ if (lc($a->ContentType) eq 'application/x-rt-original-message') {
+ $found = $a;
+ last;
+ }
+ }
+ return undef unless $found;
+
+ my $str = $found->Content;
+ return undef unless $str;
+
+ my $tmpdir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
+ my $p = MIME::Parser->new();
+ $p->output_dir($tmpdir);
+ my $entity = $p->parse_data($str);
+ return undef unless $entity;
+
+ # Now look for application/pkcs7-signature
+ $found = undef;
+ foreach my $part ($entity->parts_DFS) {
+ if (lc($part->mime_type) eq 'application/pkcs7-signature') {
+ $found = $part;
+ last;
+ }
+ }
+ return undef unless $found;
+ return undef unless $found->bodyhandle;
+
+ # Feed to openssl and extract the certificate
+ my $pkcs7 = $found->bodyhandle->as_string;
+ my $out = '';
+ my $err = '';
+ safe_run_child { run3( [$self->OpenSSLPath, 'pkcs7', '-inform', 'DER', '-print_certs' ],
+ \$pkcs7, \$out, \$err ) };
+ return undef unless $out =~ /-----BEGIN CERTIFICATE-----/;
+ return $out;
+}
1;
diff --git a/share/html/Crypt/GetSMIMECert.html b/share/html/Crypt/GetSMIMECert.html
index 99c9f1948b..e7b0bf822b 100644
--- a/share/html/Crypt/GetSMIMECert.html
+++ b/share/html/Crypt/GetSMIMECert.html
@@ -67,15 +67,26 @@ if (!$TxnId || $TxnId !~ /^\d+$/) {
if (!$status) {
push(@results, $msg);
} else {
- my $u = RT::User->new(RT->SystemUser);
- $u->Load($txn->Creator);
- if (!$u->id || !$u->SMIMECertificate) {
- push(@results, loc('Could not find S/MIME certificate for specified user'));
+ my $cert = RT::Crypt::SMIME->GetCertificateForTransaction($txn);
+ if (!$cert) {
+ push(@results, loc('Could not find S/MIME certificate for specified transaction'));
} else {
- my $name = $u->EmailAddress || $u->Name || $u->id;
+ # We don't really need the user, but we try to get it
+ # anyway just to give the certificate a sensible filename
+ # when it is downloaded. If we can't get the user, or the
+ # user lacks and email address and name, we just default
+ # to "smime.crt" for the download filename.
+ my $u = RT::User->new(RT->SystemUser);
+ my $name;
+ if ($txn->Creator) {
+ $u->Load($txn->Creator);
+ $name = $u->EmailAddress || $u->Name || "smime";
+ } else {
+ $name = "smime";
+ }
$r->content_type('application/x-x509-user-cert');
$r->header_out('Content-Disposition' => "attachment; filename=\"$name.crt\"");
- $m->out($u->SMIMECertificate);
+ $m->out($cert);
$m->flush_buffer;
$m->abort();
}
-----------------------------------------------------------------------
More information about the rt-commit
mailing list