File indexing completed on 2024-12-22 05:05:20
0001 // SPDX-FileCopyrightText: 2015 Sandro Knauß <knauss@kolabsys.com> 0002 // SPDX-License-Identifier: LGPL-2.0-or-later 0003 0004 #pragma once 0005 0006 #include "mimetreeparser_core_export.h" 0007 #include "partmetadata.h" 0008 0009 #include <gpgme++/decryptionresult.h> 0010 #include <gpgme++/importresult.h> 0011 #include <gpgme++/verificationresult.h> 0012 0013 #include <KMime/Message> 0014 0015 #include <QMap> 0016 #include <QSharedPointer> 0017 #include <QString> 0018 0019 namespace KMime 0020 { 0021 class Content; 0022 } 0023 0024 namespace QGpgME 0025 { 0026 class Protocol; 0027 } 0028 0029 namespace MimeTreeParser 0030 { 0031 0032 /** Flags for the encryption state. */ 0033 typedef enum { KMMsgEncryptionStateUnknown, KMMsgNotEncrypted, KMMsgPartiallyEncrypted, KMMsgFullyEncrypted, KMMsgEncryptionProblematic } KMMsgEncryptionState; 0034 0035 /** Flags for the signature state. */ 0036 typedef enum { KMMsgSignatureStateUnknown, KMMsgNotSigned, KMMsgPartiallySigned, KMMsgFullySigned, KMMsgSignatureProblematic } KMMsgSignatureState; 0037 0038 class ObjectTreeParser; 0039 class MultiPartAlternativeBodyPartFormatter; 0040 0041 class SignedMessagePart; 0042 class EncryptedMessagePart; 0043 0044 class MIMETREEPARSER_CORE_EXPORT MessagePart : public QObject 0045 { 0046 Q_OBJECT 0047 Q_PROPERTY(bool attachment READ isAttachment CONSTANT) 0048 Q_PROPERTY(bool root READ isRoot CONSTANT) 0049 Q_PROPERTY(bool isHtml READ isHtml CONSTANT) 0050 Q_PROPERTY(QString plaintextContent READ plaintextContent CONSTANT) 0051 Q_PROPERTY(QString htmlContent READ htmlContent CONSTANT) 0052 public: 0053 enum Disposition { Inline, Attachment, Invalid }; 0054 using Ptr = QSharedPointer<MessagePart>; 0055 using List = QList<Ptr>; 0056 MessagePart(ObjectTreeParser *otp, const QString &text, KMime::Content *node = nullptr); 0057 0058 virtual ~MessagePart(); 0059 0060 virtual QString text() const; 0061 void setText(const QString &text); 0062 virtual bool isAttachment() const; 0063 0064 void setIsRoot(bool root); 0065 bool isRoot() const; 0066 0067 void setParentPart(MessagePart *parentPart); 0068 MessagePart *parentPart() const; 0069 0070 virtual QString plaintextContent() const; 0071 virtual QString htmlContent() const; 0072 0073 virtual bool isHtml() const; 0074 0075 QByteArray mimeType() const; 0076 QByteArray charset() const; 0077 QString filename() const; 0078 Disposition disposition() const; 0079 bool isText() const; 0080 0081 enum Error { NoError = 0, PassphraseError, NoKeyError, UnknownError }; 0082 0083 Error error() const; 0084 QString errorString() const; 0085 0086 PartMetaData *partMetaData(); 0087 0088 void appendSubPart(const MessagePart::Ptr &messagePart); 0089 const QList<MessagePart::Ptr> &subParts() const; 0090 bool hasSubParts() const; 0091 0092 KMime::Content *node() const; 0093 0094 virtual KMMsgSignatureState signatureState() const; 0095 virtual KMMsgEncryptionState encryptionState() const; 0096 0097 QList<SignedMessagePart *> signatures() const; 0098 QList<EncryptedMessagePart *> encryptions() const; 0099 0100 /** 0101 * Retrieve the header @header in this part or any parent parent. 0102 * 0103 * Useful for MemoryHole support. 0104 */ 0105 KMime::Headers::Base *header(const char *header) const; 0106 0107 void bindLifetime(KMime::Content *); 0108 0109 protected: 0110 void parseInternal(KMime::Content *node, bool onlyOneMimePart = false); 0111 void parseInternal(const QByteArray &data); 0112 QString renderInternalText() const; 0113 0114 QString mText; 0115 ObjectTreeParser *mOtp; 0116 PartMetaData mMetaData; 0117 MessagePart *mParentPart; 0118 KMime::Content *mNode; 0119 QList<KMime::Content *> mNodesToDelete; 0120 Error mError; 0121 0122 private: 0123 QList<MessagePart::Ptr> mBlocks; 0124 bool mRoot; 0125 }; 0126 0127 class MIMETREEPARSER_CORE_EXPORT MimeMessagePart : public MessagePart 0128 { 0129 Q_OBJECT 0130 public: 0131 typedef QSharedPointer<MimeMessagePart> Ptr; 0132 MimeMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node, bool onlyOneMimePart = false); 0133 virtual ~MimeMessagePart(); 0134 0135 QString text() const Q_DECL_OVERRIDE; 0136 0137 QString plaintextContent() const Q_DECL_OVERRIDE; 0138 QString htmlContent() const Q_DECL_OVERRIDE; 0139 0140 private: 0141 friend class AlternativeMessagePart; 0142 }; 0143 0144 class MIMETREEPARSER_CORE_EXPORT MessagePartList : public MessagePart 0145 { 0146 Q_OBJECT 0147 public: 0148 typedef QSharedPointer<MessagePartList> Ptr; 0149 MessagePartList(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); 0150 virtual ~MessagePartList() = default; 0151 0152 QString text() const Q_DECL_OVERRIDE; 0153 0154 QString plaintextContent() const Q_DECL_OVERRIDE; 0155 QString htmlContent() const Q_DECL_OVERRIDE; 0156 }; 0157 0158 class MIMETREEPARSER_CORE_EXPORT TextMessagePart : public MessagePartList 0159 { 0160 Q_OBJECT 0161 public: 0162 typedef QSharedPointer<TextMessagePart> Ptr; 0163 TextMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); 0164 virtual ~TextMessagePart() = default; 0165 0166 KMMsgSignatureState signatureState() const Q_DECL_OVERRIDE; 0167 KMMsgEncryptionState encryptionState() const Q_DECL_OVERRIDE; 0168 0169 private: 0170 void parseContent(); 0171 0172 KMMsgSignatureState mSignatureState; 0173 KMMsgEncryptionState mEncryptionState; 0174 0175 friend class ObjectTreeParser; 0176 }; 0177 0178 class MIMETREEPARSER_CORE_EXPORT AttachmentMessagePart : public TextMessagePart 0179 { 0180 Q_OBJECT 0181 public: 0182 typedef QSharedPointer<AttachmentMessagePart> Ptr; 0183 AttachmentMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); 0184 virtual ~AttachmentMessagePart() = default; 0185 virtual bool isAttachment() const Q_DECL_OVERRIDE 0186 { 0187 return true; 0188 } 0189 }; 0190 0191 class MIMETREEPARSER_CORE_EXPORT HtmlMessagePart : public MessagePart 0192 { 0193 Q_OBJECT 0194 public: 0195 typedef QSharedPointer<HtmlMessagePart> Ptr; 0196 HtmlMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); 0197 virtual ~HtmlMessagePart() = default; 0198 bool isHtml() const Q_DECL_OVERRIDE 0199 { 0200 return true; 0201 }; 0202 }; 0203 0204 class MIMETREEPARSER_CORE_EXPORT AlternativeMessagePart : public MessagePart 0205 { 0206 Q_OBJECT 0207 public: 0208 enum HtmlMode { 0209 Normal, ///< A normal plaintext message, non-multipart 0210 Html, ///< A HTML message, non-multipart 0211 MultipartPlain, ///< A multipart/alternative message, the plain text part is currently displayed 0212 MultipartHtml, ///< A multipart/altervative message, the HTML part is currently displayed 0213 MultipartIcal ///< A multipart/altervative message, the ICal part is currently displayed 0214 }; 0215 0216 typedef QSharedPointer<AlternativeMessagePart> Ptr; 0217 AlternativeMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node); 0218 virtual ~AlternativeMessagePart(); 0219 0220 QString text() const Q_DECL_OVERRIDE; 0221 0222 bool isHtml() const Q_DECL_OVERRIDE; 0223 0224 QString plaintextContent() const Q_DECL_OVERRIDE; 0225 QString htmlContent() const Q_DECL_OVERRIDE; 0226 QString icalContent() const; 0227 0228 QList<HtmlMode> availableModes(); 0229 0230 private: 0231 QMap<HtmlMode, MessagePart::Ptr> mChildParts; 0232 0233 friend class ObjectTreeParser; 0234 friend class MultiPartAlternativeBodyPartFormatter; 0235 }; 0236 0237 class MIMETREEPARSER_CORE_EXPORT CertMessagePart : public MessagePart 0238 { 0239 Q_OBJECT 0240 public: 0241 typedef QSharedPointer<CertMessagePart> Ptr; 0242 CertMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node, QGpgME::Protocol *cryptoProto); 0243 virtual ~CertMessagePart(); 0244 0245 QString text() const Q_DECL_OVERRIDE; 0246 0247 private: 0248 const QGpgME::Protocol *mCryptoProto; 0249 GpgME::ImportResult mInportResult; 0250 }; 0251 0252 class MIMETREEPARSER_CORE_EXPORT EncapsulatedRfc822MessagePart : public MessagePart 0253 { 0254 Q_OBJECT 0255 public: 0256 typedef QSharedPointer<EncapsulatedRfc822MessagePart> Ptr; 0257 EncapsulatedRfc822MessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *node, const KMime::Message::Ptr &message); 0258 virtual ~EncapsulatedRfc822MessagePart() = default; 0259 0260 QString text() const Q_DECL_OVERRIDE; 0261 QString from() const; 0262 QDateTime date() const; 0263 0264 private: 0265 const KMime::Message::Ptr mMessage; 0266 }; 0267 0268 class MIMETREEPARSER_CORE_EXPORT EncryptedMessagePart : public MessagePart 0269 { 0270 Q_OBJECT 0271 Q_PROPERTY(bool decryptMessage READ decryptMessage WRITE setDecryptMessage) 0272 Q_PROPERTY(bool isEncrypted READ isEncrypted) 0273 Q_PROPERTY(bool isNoSecKey READ isNoSecKey) 0274 Q_PROPERTY(bool passphraseError READ passphraseError) 0275 public: 0276 typedef QSharedPointer<EncryptedMessagePart> Ptr; 0277 EncryptedMessagePart(ObjectTreeParser *otp, 0278 const QString &text, 0279 const QGpgME::Protocol *protocol, 0280 KMime::Content *node, 0281 KMime::Content *encryptedNode = nullptr, 0282 bool parseAfterDecryption = true); 0283 0284 virtual ~EncryptedMessagePart() = default; 0285 0286 QString text() const Q_DECL_OVERRIDE; 0287 0288 void setDecryptMessage(bool decrypt); 0289 [[nodiscard]] bool decryptMessage() const; 0290 0291 void setIsEncrypted(bool encrypted); 0292 [[nodiscard]] bool isEncrypted() const; 0293 0294 [[nodiscard]] bool isDecryptable() const; 0295 0296 [[nodiscard]] bool isNoSecKey() const; 0297 [[nodiscard]] bool passphraseError() const; 0298 0299 void startDecryption(KMime::Content *data); 0300 void startDecryption(); 0301 0302 QByteArray mDecryptedData; 0303 0304 QString plaintextContent() const override; 0305 QString htmlContent() const override; 0306 0307 const QGpgME::Protocol *cryptoProto() const; 0308 0309 std::vector<std::pair<GpgME::DecryptionResult::Recipient, GpgME::Key>> decryptRecipients() const; 0310 0311 private: 0312 bool decrypt(KMime::Content &data); 0313 bool mParseAfterDecryption{true}; 0314 0315 protected: 0316 bool mPassphraseError; 0317 bool mNoSecKey; 0318 bool mDecryptMessage; 0319 const QGpgME::Protocol *mCryptoProto; 0320 QByteArray mVerifiedText; 0321 std::vector<std::pair<GpgME::DecryptionResult::Recipient, GpgME::Key>> mDecryptRecipients; 0322 KMime::Content *mEncryptedNode; 0323 }; 0324 0325 class MIMETREEPARSER_CORE_EXPORT SignedMessagePart : public MessagePart 0326 { 0327 Q_OBJECT 0328 Q_PROPERTY(bool isSigned READ isSigned CONSTANT) 0329 public: 0330 typedef QSharedPointer<SignedMessagePart> Ptr; 0331 SignedMessagePart(ObjectTreeParser *otp, 0332 const QGpgME::Protocol *protocol, 0333 KMime::Content *node, 0334 KMime::Content *signedData, 0335 bool parseAfterDecryption = true); 0336 0337 virtual ~SignedMessagePart(); 0338 0339 void setIsSigned(bool isSigned); 0340 bool isSigned() const; 0341 0342 void startVerification(); 0343 0344 QString plaintextContent() const Q_DECL_OVERRIDE; 0345 QString htmlContent() const Q_DECL_OVERRIDE; 0346 0347 const QGpgME::Protocol *cryptoProto() const; 0348 0349 private: 0350 void sigStatusToMetaData(); 0351 void setVerificationResult(const GpgME::VerificationResult &result, const QByteArray &signedData); 0352 bool mParseAfterDecryption{true}; 0353 0354 protected: 0355 const QGpgME::Protocol *mCryptoProto; 0356 KMime::Content *mSignedData; 0357 std::vector<GpgME::Signature> mSignatures; 0358 0359 friend EncryptedMessagePart; 0360 }; 0361 0362 class MIMETREEPARSER_CORE_EXPORT HeadersPart : public MessagePart 0363 { 0364 Q_OBJECT 0365 public: 0366 typedef QSharedPointer<HeadersPart> Ptr; 0367 HeadersPart(ObjectTreeParser *otp, KMime::Content *node); 0368 virtual ~HeadersPart() = default; 0369 }; 0370 0371 }