File indexing completed on 2024-06-23 05:20:29

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