File indexing completed on 2024-05-12 05:28:19

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