mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 04:29:21 +03:00
pre-verify S/MIME opaque signed messages so we have a body to view
This commit is contained in:
parent
a98f8aa1f6
commit
5552d3c1b9
7 changed files with 44 additions and 27 deletions
|
|
@ -24,6 +24,8 @@ import { LanguageStore } from 'Stores/Language';
|
|||
|
||||
import Remote from 'Remote/User/Fetch';
|
||||
|
||||
import { MimeToMessage } from 'Mime/Utils';
|
||||
|
||||
const
|
||||
msgHtml = msg => cleanHtml(msg.html(), msg.attachments(), '#rl-msg-' + msg.hash),
|
||||
|
||||
|
|
@ -196,6 +198,11 @@ export class MessageModel extends AbstractModel {
|
|||
return options;
|
||||
}
|
||||
});
|
||||
|
||||
this.smimeSigned.subscribe(value => {
|
||||
value?.body && MimeToMessage(value.body, this);
|
||||
value?.body && this.smimeVerified(value.verified);
|
||||
});
|
||||
}
|
||||
|
||||
get requestHash() {
|
||||
|
|
|
|||
|
|
@ -671,7 +671,7 @@ export class MailMessageView extends AbstractViewRight {
|
|||
message.html() ? message.viewHtml() : message.viewPlain();
|
||||
response.Result.body = null;
|
||||
}
|
||||
message.smimeVerified(response.Result);
|
||||
message.smimeVerified(response.Result.success);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,6 +132,26 @@ trait Messages
|
|||
return $aReturn;
|
||||
}
|
||||
|
||||
public function FetchMessagePart(int $iUid, string $sPartId) : string
|
||||
{
|
||||
if ('TEXT' === $sPartId) {
|
||||
$oFetchResponse = $this->Fetch([
|
||||
FetchType::BODY_PEEK.'['.$sPartId.']',
|
||||
FetchType::BODY_HEADER_PEEK
|
||||
], $iUid, true)[0];
|
||||
$sHeader = $oFetchResponse->GetFetchValue(FetchType::BODY_HEADER);
|
||||
} else {
|
||||
$oFetchResponse = $this->Fetch([
|
||||
FetchType::BODY_PEEK.'['.$sPartId.']',
|
||||
// An empty section specification refers to the entire message, including the header.
|
||||
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
|
||||
FetchType::BODY_PEEK.'['.$sPartId.'.MIME]'
|
||||
], $iUid, true)[0];
|
||||
$sHeader = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.'.MIME]');
|
||||
}
|
||||
return $sHeader . $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends message to specified folder
|
||||
*
|
||||
|
|
|
|||
|
|
@ -171,6 +171,16 @@ class MailClient
|
|||
$aFetchResponse = $this->oImapClient->Fetch($aFetchItems, $iIndex, $bIndexIsUid);
|
||||
if (\count($aFetchResponse)) {
|
||||
$oMessage = Message::fromFetchResponse($sFolderName, $aFetchResponse[0], $oBodyStructure);
|
||||
// S/MIME opaque signed. Verify it, so we have the raw mime body to show
|
||||
if ($oMessage->smimeSigned && !$oMessage->smimeSigned['detached']) {
|
||||
$sBody = $this->oImapClient->FetchMessagePart(
|
||||
$oMessage->Uid,
|
||||
$oMessage->smimeSigned['partId']
|
||||
);
|
||||
$result = (new \SnappyMail\SMime\OpenSSL(''))->verify($sBody, null, true);
|
||||
$oMessage->smimeSigned['body'] = $result['body'];
|
||||
$oMessage->smimeSigned['verified'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $oMessage;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class Message implements \JsonSerializable
|
|||
private ?array $pgpSigned = null;
|
||||
private ?array $pgpEncrypted = null;
|
||||
|
||||
private ?array $smimeSigned = null;
|
||||
public ?array $smimeSigned = null;
|
||||
private ?array $smimeEncrypted = null;
|
||||
|
||||
private ?\MailSo\Mime\EmailCollection
|
||||
|
|
|
|||
|
|
@ -118,32 +118,12 @@ trait SMime
|
|||
$sPartId = $this->GetActionParam('partId', '');
|
||||
$bDetached = !empty($this->GetActionParam('detached', 0));
|
||||
if (!$sBody && $sPartId) {
|
||||
$sFolderName = $this->GetActionParam('folder', '');
|
||||
$iUid = (int) $this->GetActionParam('uid', 0);
|
||||
$sMicAlg = $this->GetActionParam('micAlg', '');
|
||||
|
||||
// $sMicAlg = $this->GetActionParam('micAlg', '');
|
||||
$this->initMailClientConnection();
|
||||
$oImapClient = $this->ImapClient();
|
||||
$oImapClient->FolderExamine($sFolderName);
|
||||
|
||||
if ('TEXT' === $sPartId) {
|
||||
$oFetchResponse = $oImapClient->Fetch([
|
||||
FetchType::BODY_PEEK.'['.$sPartId.']',
|
||||
// An empty section specification refers to the entire message, including the header.
|
||||
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
|
||||
FetchType::BODY_HEADER_PEEK
|
||||
], $iUid, true)[0];
|
||||
$sBody = $oFetchResponse->GetFetchValue(FetchType::BODY_HEADER);
|
||||
} else {
|
||||
$oFetchResponse = $oImapClient->Fetch([
|
||||
FetchType::BODY_PEEK.'['.$sPartId.']',
|
||||
// An empty section specification refers to the entire message, including the header.
|
||||
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
|
||||
FetchType::BODY_PEEK.'['.$sPartId.'.MIME]'
|
||||
], $iUid, true)[0];
|
||||
$sBody = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.'.MIME]');
|
||||
}
|
||||
$sBody .= $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
|
||||
$oImapClient->FolderExamine($this->GetActionParam('folder', ''));
|
||||
$sBody = $oImapClient->FetchMessagePart($iUid, $sPartId);
|
||||
}
|
||||
|
||||
$result = $this->SMIME()->verify($sBody, null, !$bDetached);
|
||||
|
|
@ -151,7 +131,7 @@ trait SMime
|
|||
// Import the certificates automatically
|
||||
$sBody = $this->GetActionParam('sigPart', '');
|
||||
$sPartId = $this->GetActionParam('sigPartId', '') ?: $sPartId;
|
||||
if (!$sBody && $sPartId) {
|
||||
if (!$sBody && $sPartId && $oImapClient) {
|
||||
$sBody = $oImapClient->Fetch(
|
||||
[FetchType::BODY_PEEK.'['.$sPartId.']'],
|
||||
$iUid,
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div data-bind="visible: message().smimeSigned()">
|
||||
<div class="crypto-control signed" data-bind="css: {success: message().smimeVerified() && message().smimeVerified().success, error: message().smimeVerified() && !message().smimeVerified().success}">
|
||||
<div class="crypto-control signed" data-bind="css: {success: true === message().smimeVerified(), error: false === message().smimeVerified()}">
|
||||
<span data-icon="✍" data-i18n="SMIME/SIGNED_MESSAGE"></span>
|
||||
<button class="btn" data-bind="click: smimeVerify" data-i18n="CRYPTO/VERIFY"></button>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue