diff options
4 files changed, 125 insertions, 19 deletions
diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.cpp b/framework/src/domain/mime/mimetreeparser/messagepart.cpp index 17719ff8..9b677d86 100644 --- a/framework/src/domain/mime/mimetreeparser/messagepart.cpp +++ b/framework/src/domain/mime/mimetreeparser/messagepart.cpp | |||
@@ -261,6 +261,28 @@ void MessagePart::parseInternal(KMime::Content *node, bool onlyOneMimePart) | |||
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | void MessagePart::parseInternal(const QByteArray &data) | ||
265 | { | ||
266 | auto tempNode = new KMime::Content(); | ||
267 | |||
268 | const auto lfData = KMime::CRLFtoLF(data); | ||
269 | //We have to deal with both bodies and full parts. In inline encrypted/signed parts we can have nested parts, | ||
270 | //or just plain-text, and both ends up here. setContent defaults to setting only the header, so we have to avoid this. | ||
271 | if (lfData.contains("\n\n")) { | ||
272 | tempNode->setContent(lfData); | ||
273 | } else { | ||
274 | tempNode->setBody(lfData); | ||
275 | } | ||
276 | tempNode->parse(); | ||
277 | bindLifetime(tempNode); | ||
278 | |||
279 | if (!tempNode->head().isEmpty()) { | ||
280 | tempNode->contentDescription()->from7BitString("temporary node"); | ||
281 | } | ||
282 | |||
283 | parseInternal(tempNode, false); | ||
284 | } | ||
285 | |||
264 | QString MessagePart::renderInternalText() const | 286 | QString MessagePart::renderInternalText() const |
265 | { | 287 | { |
266 | QString text; | 288 | QString text; |
@@ -392,7 +414,8 @@ void TextMessagePart::parseContent() | |||
392 | const QString &fromAddress = mOtp->nodeHelper()->fromAsString(mNode); | 414 | const QString &fromAddress = mOtp->nodeHelper()->fromAsString(mNode); |
393 | mSignatureState = KMMsgNotSigned; | 415 | mSignatureState = KMMsgNotSigned; |
394 | mEncryptionState = KMMsgNotEncrypted; | 416 | mEncryptionState = KMMsgNotEncrypted; |
395 | const auto blocks = prepareMessageForDecryption(mNode->decodedContent()); | 417 | auto body = mNode->decodedContent(); |
418 | const auto blocks = prepareMessageForDecryption(body); | ||
396 | 419 | ||
397 | const auto cryptProto = GpgME::OpenPGP; | 420 | const auto cryptProto = GpgME::OpenPGP; |
398 | 421 | ||
@@ -880,15 +903,8 @@ void SignedMessagePart::setVerificationResult(const GpgME::VerificationResult &r | |||
880 | mOtp->mNodeHelper->setPartMetaData(mNode, mMetaData); | 903 | mOtp->mNodeHelper->setPartMetaData(mNode, mMetaData); |
881 | } | 904 | } |
882 | if (!plainText.isEmpty() && parseText) { | 905 | if (!plainText.isEmpty() && parseText) { |
883 | auto tempNode = new KMime::Content(); | 906 | parseInternal(plainText); |
884 | tempNode->setBody(plainText); | ||
885 | tempNode->parse(); | ||
886 | bindLifetime(tempNode); | ||
887 | 907 | ||
888 | if (!tempNode->head().isEmpty()) { | ||
889 | tempNode->contentDescription()->from7BitString("signed data"); | ||
890 | } | ||
891 | parseInternal(tempNode, false); | ||
892 | } | 908 | } |
893 | } | 909 | } |
894 | } | 910 | } |
@@ -1072,16 +1088,7 @@ void EncryptedMessagePart::startDecryption(KMime::Content *data) | |||
1072 | 1088 | ||
1073 | if (mNode && !mMetaData.isSigned) { | 1089 | if (mNode && !mMetaData.isSigned) { |
1074 | mOtp->mNodeHelper->setPartMetaData(mNode, mMetaData); | 1090 | mOtp->mNodeHelper->setPartMetaData(mNode, mMetaData); |
1075 | auto tempNode = new KMime::Content(); | 1091 | parseInternal(mDecryptedData); |
1076 | tempNode->setContent(KMime::CRLFtoLF(mDecryptedData.constData())); | ||
1077 | tempNode->parse(); | ||
1078 | bindLifetime(tempNode); | ||
1079 | |||
1080 | if (!tempNode->head().isEmpty()) { | ||
1081 | tempNode->contentDescription()->from7BitString("encrypted data"); | ||
1082 | } | ||
1083 | |||
1084 | parseInternal(tempNode, false); | ||
1085 | } | 1092 | } |
1086 | } | 1093 | } |
1087 | 1094 | ||
diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.h b/framework/src/domain/mime/mimetreeparser/messagepart.h index c039637a..8cd74717 100644 --- a/framework/src/domain/mime/mimetreeparser/messagepart.h +++ b/framework/src/domain/mime/mimetreeparser/messagepart.h | |||
@@ -125,6 +125,7 @@ public: | |||
125 | 125 | ||
126 | protected: | 126 | protected: |
127 | void parseInternal(KMime::Content *node, bool onlyOneMimePart); | 127 | void parseInternal(KMime::Content *node, bool onlyOneMimePart); |
128 | void parseInternal(const QByteArray &data); | ||
128 | QString renderInternalText() const; | 129 | QString renderInternalText() const; |
129 | 130 | ||
130 | QString mText; | 131 | QString mText; |
diff --git a/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp b/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp index 90a07a7c..38857d58 100644 --- a/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp +++ b/framework/src/domain/mime/mimetreeparser/tests/mimetreeparsertest.cpp | |||
@@ -386,6 +386,21 @@ private slots: | |||
386 | QCOMPARE(part->encryptionState(), MimeTreeParser::KMMsgFullyEncrypted); | 386 | QCOMPARE(part->encryptionState(), MimeTreeParser::KMMsgFullyEncrypted); |
387 | QCOMPARE(otp.plainTextContent(), QString::fromUtf8("sdflskjsdf\n\n-- \nThis is a HTML signature.\n")); | 387 | QCOMPARE(otp.plainTextContent(), QString::fromUtf8("sdflskjsdf\n\n-- \nThis is a HTML signature.\n")); |
388 | } | 388 | } |
389 | |||
390 | void testOpenpgpMultipartEmbeddedSigned() | ||
391 | { | ||
392 | MimeTreeParser::ObjectTreeParser otp; | ||
393 | otp.parseObjectTree(readMailFromFile("openpgp-multipart-embedded-signed.mbox")); | ||
394 | otp.decryptParts(); | ||
395 | auto partList = otp.collectContentParts(); | ||
396 | QCOMPARE(partList.size(), 1); | ||
397 | auto part = partList[0].dynamicCast<MimeTreeParser::MessagePart>(); | ||
398 | QCOMPARE(part->encryptions().size(), 1); | ||
399 | QCOMPARE(part->signatures().size(), 1); | ||
400 | QCOMPARE(part->encryptionState(), MimeTreeParser::KMMsgFullyEncrypted); | ||
401 | QCOMPARE(part->signatureState(), MimeTreeParser::KMMsgFullySigned); | ||
402 | QCOMPARE(otp.plainTextContent(), QString::fromUtf8("test\n\n-- \nThis is a HTML signature.\n")); | ||
403 | } | ||
389 | }; | 404 | }; |
390 | 405 | ||
391 | QTEST_GUILESS_MAIN(InterfaceTest) | 406 | QTEST_GUILESS_MAIN(InterfaceTest) |
diff --git a/framework/src/domain/mime/testdata/openpgp-multipart-embedded-signed.mbox b/framework/src/domain/mime/testdata/openpgp-multipart-embedded-signed.mbox new file mode 100644 index 00000000..23f4305d --- /dev/null +++ b/framework/src/domain/mime/testdata/openpgp-multipart-embedded-signed.mbox | |||
@@ -0,0 +1,83 @@ | |||
1 | To: test@kolab.org | ||
2 | From: test1 <test1@kolab.org> | ||
3 | Openpgp: preference=signencrypt | ||
4 | Autocrypt: addr=test1@kolab.org; prefer-encrypt=mutual; keydata= | ||
5 | xsBNBFrd3FcBCADAGsU4BTBJ7nXGZ2IV6ZpSDcuZeCteDdrp9YNGYdax49Z9rn2RIfMur07i | ||
6 | A3zkLuQSI63QpWr/sp8Kkcs+OMRfeNAHSyQcdOwE/SU/PF45LHYcgvdgL7bvNRiyrn++eXar | ||
7 | woCH/QNZFgsy4PQCBW4DXor4jeDgeKisdk+ArpSY+Dd5l+Gdna8GQyUHWOL15gKUEDBq9dta | ||
8 | fswI18LxTSIbofsSxnQ0BgHNgn4bFXRLWiFJMyjvXXwZAXmChpxchESeIyu3Bvu38kA+jNDh | ||
9 | QmJL359mbXtu6JtvUjL0T9xhydHhGQ8iHCUpUkAh50KDJUUFQAUD+wSeMbsr7dk/osBdABEB | ||
10 | AAHNHVRlc3QxIEtvbGFiIDx0ZXN0MUBrb2xhYi5vcmc+wsCOBBMBCAA4FiEEy9EWSF25Vgyj | ||
11 | zZHgLjt3h7G3WSAFAlrd3FcCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQLjt3h7G3 | ||
12 | WSBwjAf6A9D/BOo6ixWfrTAfunk06TIt309P33/aIrhmICUoJ3KxatnMfcFr9GDnVtGv7RZl | ||
13 | VG43dWLMz8ghjGVjWOQUzlYl19HS/7KfHFE3jQHawcidYHcsVBbD/Ml9lCRnE4CcO/7MqObh | ||
14 | FHVIO+M0XJK82Qqu1kZ2ySNOMG+DJ3JGMEWMwrf8HjdwfANCn9uW4G9+q3dyN7TWUaYVLf74 | ||
15 | Ekz2KpCxi0Y/b/01+8UR6iSRbn+5R2CIPhgdrrfYlHaB1HHeeJlue8JK3zxYcRTfD4B2c8Jj | ||
16 | UAMO0Y8A7PMTj9SpnBt+t4XUyrTwwqLwulRBAQBHSPI7jQ6JVM2yTOe7Yy1dbc7ATQRa3dxX | ||
17 | AQgAy/RH8KEQHk2SJ60G0YJkOSioGNU+sAMP6rKIH8AXljZEwriiWqxcunoHlrOHOfuyBBL2 | ||
18 | TTiien0247g7q2i7aPBZhll7/cp4DZKcsLZ9QIkB4sHY1SaVT865dIfhoxcKwi8NzbemDsUQ | ||
19 | QB6f9P3CSZqFW2EohzKf3vfYnLVLTRvzlndAzThYXso1iWeX9v1JtzOi4w7JP5RvTMx+FXCy | ||
20 | ibfkLGJL2ZG6rapK7jtn8SfJGiQeH441OmEDjtfqrADKDY/pKJdPeEzakuZuxhrh8FtFjtZX | ||
21 | WU9dbzE46uXUA/ChLW0H/zuyxseVCHyAbF5pFyibGfk1hmYFVwjQotHojwARAQABwsB2BBgB | ||
22 | CAAgFiEEy9EWSF25VgyjzZHgLjt3h7G3WSAFAlrd3FcCGwwACgkQLjt3h7G3WSDJrAgApMbl | ||
23 | U4PAoe04jVSIMApU8Q22NNysZGS3l6KLpOqS/1DXd2U0S6EbFcCmUUwu3tk6nz6qCBKu7SEe | ||
24 | E1bjJUSB5880IA3C8HC1VDHCdVMJGJKvpqnj/4Jf8STQROL7UeQXZvby5CRZGMV7lBDAquG6 | ||
25 | vk3Eo3CeAfKel+XtHA/qruayTVHn1PV3/22ThcnXkwB3Mpdflz/tmPwHZqwOPavpJMckE03K | ||
26 | HNzSulXDNXdGqd4kKu43UIYnfm/3jnfK/LOrOK8zl40mk26Vm19MMRgc2TP6a70J5r6H1RLU | ||
27 | BTEkoVskD4m6I1G4FEIPq1g8jv7e0zcukh3vdpdKKxR+69M/2w== | ||
28 | Message-ID: <a85660b4-6fdf-9d74-ad1c-e6899f57e4b0@kolab.org> | ||
29 | Date: Tue, 24 Apr 2018 18:47:20 +0200 | ||
30 | User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 | ||
31 | Thunderbird/52.7.0 | ||
32 | MIME-Version: 1.0 | ||
33 | Subject: Encrypted Message | ||
34 | Content-Type: multipart/encrypted; | ||
35 | protocol="application/pgp-encrypted"; | ||
36 | boundary="aG9NpScyJQ450kGR5wZ2xj8QJwiCdpvXm" | ||
37 | |||
38 | This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156) | ||
39 | --aG9NpScyJQ450kGR5wZ2xj8QJwiCdpvXm | ||
40 | Content-Type: application/pgp-encrypted | ||
41 | Content-Description: PGP/MIME version identification | ||
42 | |||
43 | Version: 1 | ||
44 | |||
45 | --aG9NpScyJQ450kGR5wZ2xj8QJwiCdpvXm | ||
46 | Content-Type: application/octet-stream; name="encrypted.asc" | ||
47 | Content-Description: OpenPGP encrypted message | ||
48 | Content-Disposition: inline; filename="encrypted.asc" | ||
49 | |||
50 | -----BEGIN PGP MESSAGE----- | ||
51 | |||
52 | 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 | ||
79 | rbexuTVmwmXN695s/V0= | ||
80 | =1o3V | ||
81 | -----END PGP MESSAGE----- | ||
82 | |||
83 | --aG9NpScyJQ450kGR5wZ2xj8QJwiCdpvXm-- | ||