Skip to content

Commit

Permalink
draft code for TNEF winmail.dat #1012
Browse files Browse the repository at this point in the history
  • Loading branch information
the-djmaze committed Mar 6, 2024
1 parent 8fe5cd3 commit 565e8f0
Show file tree
Hide file tree
Showing 37 changed files with 5,073 additions and 16 deletions.
1,745 changes: 1,745 additions & 0 deletions examples/eml/tnef.eml

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions examples/eml/tnef2.eml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
From: Alice <[email protected]>
To: Bob <[email protected]>
Subject: TNEF test 2
Date: Thu, 10 Feb 2022 12:19:57 +0100
Message-ID: <[email protected]>
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_NextPart_000_001E_01D81E78.84E7EB50"
X-Mailer: Microsoft Outlook 16.0
Content-Language: cs
X-MS-TNEF-Correlator: 0000000045EA84AB25A1494B8CD618FC27E0940E04CA7500
Authentication-Results: example.net;
dkim=pass header.d=example.net header.s=mail header.b=UH8A3Z8P;
dmarc=pass (policy=reject) header.from=example.net;
spf=pass () smtp.mailfrom=[email protected]

This is a multipart message in MIME format.

------=_NextPart_000_001E_01D81E78.84E7EB50
Content-Type: text/plain;
charset="iso-8859-2"
Content-Transfer-Encoding: quoted-printable
Dobr=FD den,
=20
pos=EDl=E1m zku=B9ebn=ED e-mail:
=20
P=F8=EDli=B9 =BElu=BBou=E8k=FD k=F9=F2 =FAp=ECl =EF=E1belsk=E9 =F3dy
=20
S pozdravem
=20
Mgr. Milo=B9 Bart=E1k
------=_NextPart_000_001E_01D81E78.84E7EB50
Content-Type: application/ms-tnef;
name="winmail.dat"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="winmail.dat"
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
------=_NextPart_000_001E_01D81E78.84E7EB50--

Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ public function GetHtmlAndPlainParts() : array
/**
* No text found, is it encrypted?
* If so, just return that.
* Only when \RainLoop\Api::Config()->Get('security', 'openpgp', true)
*/
if (!$aParts) {
$gEncryptedParts = $this->SearchByContentType('multipart/encrypted');
Expand Down
20 changes: 4 additions & 16 deletions snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,18 +148,6 @@ public function Message(string $sFolderName, int $iIndex, bool $bIndexIsUid = tr
}
$aFetchItems[] = $sLine;
}
/*
$gSignatureParts = $oBodyStructure->SearchByContentType('multipart/signed');
foreach ($gSignatureParts as $oPart) {
if ($oPart->isPgpSigned()) {
// 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].
$aFetchItems[] = FetchType::BODY_PEEK.'['.$oPart->SubParts()[0]->PartID().'.MIME]';
$aFetchItems[] = FetchType::BODY_PEEK.'['.$oPart->SubParts()[0]->PartID().']';
$aFetchItems[] = FetchType::BODY_PEEK.'['.$oPart->SubParts()[1]->PartID().']';
}
}
*/
}
}

Expand Down Expand Up @@ -500,11 +488,11 @@ protected function MessageListByRequestIndexOrUids(MessageCollection $oMessageCo
$aFetchIterator = $this->oImapClient->FetchIterate($aFetchItems, (string) $oRange, $oRange->UID);
// FETCH does not respond in the id order of the SequenceSet, so we prefill $aCollection for the right sort order.
$aCollection = \array_fill_keys($oRange->getArrayCopy(), null);
foreach ($aFetchIterator as $oFetchResponseItem) {
foreach ($aFetchIterator as $oFetchResponse) {
$id = $oRange->UID
? $oFetchResponseItem->GetFetchValue(FetchType::UID)
: $oFetchResponseItem->oImapResponse->ResponseList[1];
$oMessage = Message::fromFetchResponse($oMessageCollection->FolderName, $oFetchResponseItem);
? $oFetchResponse->GetFetchValue(FetchType::UID)
: $oFetchResponse->oImapResponse->ResponseList[1];
$oMessage = Message::fromFetchResponse($oMessageCollection->FolderName, $oFetchResponse);
if ($oMessage) {
if ($aAllThreads) {
$iUid = $oMessage->Uid;
Expand Down
10 changes: 10 additions & 0 deletions snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ public function Attachments() : ?AttachmentCollection
return $this->Attachments;
}

public function setPlain(string $value) : void
{
$this->sPlain = $value;
}

public function setHtml(string $value) : void
{
$this->sHtml = $value;
}

private function setSpamScore($value) : void
{
$this->SpamScore = \intval(\max(0, \min(100, $value)));
Expand Down
23 changes: 23 additions & 0 deletions snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,29 @@ public function DoMessage() : array
} catch (\Throwable $e) {
$this->logException($e);
}
/*
if (!$oMessage->sPlain && !$oMessage->sHtml && !$oMessage->pgpEncrypted && !$oMessage->smimeEncrypted) {
$aAttachments = $oMessage->Attachments ?: [];
foreach ($aAttachments as $oAttachment) {
// \in_array($oAttachment->ContentType(), ['application/vnd.ms-tnef', 'application/ms-tnef'])
if ('winmail.dat' === \strtolower($oAttachment->FileName())) {
$sData = $this->ImapClient()->FetchMessagePart(
$oMessage->Uid,
$oAttachment->PartID()
);
$oTNEF = new \TNEFDecoder\TNEFAttachment;
$oTNEF->decodeTnef($sData);
foreach ($oTNEF->getFiles() as $oFile) {
if (\in_array($oFile->type, ['application/rtf', 'text/rtf'])) {
$rtf = new \SnappyMail\Rtf\Document($oFile->content);
$oMessage->setHtml($rtf->toHTML());
}
}
break;
}
}
}
*/
}
catch (\Throwable $oException)
{
Expand Down
Loading

0 comments on commit 565e8f0

Please sign in to comment.