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 }