File indexing completed on 2024-05-26 05:27:51

0001 /*
0002     Copyright (C) 2015 Sandro Knauß <knauss@kolabsys.com>
0003     Copyright (C) 2001,2002 the KPGP authors
0004     See file AUTHORS.kpgp for details
0005 
0006     Kmail is free software; you can redistribute it and/or modify
0007     it under the terms of the GNU General Public License as published by
0008     the Free Software Foundation; either version 2 of the License, or
0009     (at your option) any later version.
0010 
0011     You should have received a copy of the GNU General Public License
0012     along with this program; if not, write to the Free Software Foundation,
0013     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
0014  */
0015 
0016 #include "cryptohelper.h"
0017 
0018 using namespace MimeTreeParser;
0019 
0020 PGPBlockType Block::determineType() const
0021 {
0022     const QByteArray data = text();
0023     if (data.startsWith("-----BEGIN PGP SIGNED")) {
0024         return ClearsignedBlock;
0025     } else if (data.startsWith("-----BEGIN PGP SIGNATURE")) {
0026         return SignatureBlock;
0027     } else if (data.startsWith("-----BEGIN PGP PUBLIC")) {
0028         return PublicKeyBlock;
0029     } else if (data.startsWith("-----BEGIN PGP PRIVATE")
0030                || data.startsWith("-----BEGIN PGP SECRET")) {
0031         return PrivateKeyBlock;
0032     } else if (data.startsWith("-----BEGIN PGP MESSAGE")) {
0033         if (data.startsWith("-----BEGIN PGP MESSAGE PART")) {
0034             return MultiPgpMessageBlock;
0035         } else {
0036             return PgpMessageBlock;
0037         }
0038     } else if (data.startsWith("-----BEGIN PGP ARMORED FILE")) {
0039         return PgpMessageBlock;
0040     } else if (data.startsWith("-----BEGIN PGP ")) {
0041         return UnknownBlock;
0042     } else {
0043         return NoPgpBlock;
0044     }
0045 }
0046 
0047 QList<Block> MimeTreeParser::prepareMessageForDecryption(const QByteArray &msg)
0048 {
0049     PGPBlockType pgpBlock = NoPgpBlock;
0050     QList<Block>  blocks;
0051     int start = -1;   // start of the current PGP block
0052     int lastEnd = -1; // end of the last PGP block
0053     const int length = msg.length();
0054 
0055     if (msg.isEmpty()) {
0056         return blocks;
0057     }
0058 
0059     if (msg.startsWith("-----BEGIN PGP ")) {
0060         start = 0;
0061     } else {
0062         start = msg.indexOf("\n-----BEGIN PGP ") + 1;
0063         if (start == 0) {
0064             blocks.append(Block(msg, NoPgpBlock));
0065             return blocks;
0066         }
0067     }
0068 
0069     while (start != -1) {
0070         int nextEnd, nextStart;
0071 
0072         // is the PGP block a clearsigned block?
0073         if (!strncmp(msg.constData() + start + 15, "SIGNED", 6)) {
0074             pgpBlock = ClearsignedBlock;
0075         } else {
0076             pgpBlock = UnknownBlock;
0077         }
0078 
0079         nextEnd = msg.indexOf("\n-----END PGP ", start + 15);
0080         nextStart = msg.indexOf("\n-----BEGIN PGP ", start + 15);
0081 
0082         if (nextEnd == -1) {        // Missing END PGP line
0083             if (lastEnd != -1) {
0084                 blocks.append(Block(msg.mid(lastEnd + 1), UnknownBlock));
0085             } else {
0086                 blocks.append(Block(msg.mid(start), UnknownBlock));
0087             }
0088             break;
0089         }
0090 
0091         if ((nextStart == -1) || (nextEnd < nextStart) || (pgpBlock == ClearsignedBlock)) {
0092             // most likely we found a PGP block (but we don't check if it's valid)
0093 
0094             // store the preceding non-PGP block
0095             if (start - lastEnd - 1 > 0) {
0096                 blocks.append(Block(msg.mid(lastEnd + 1, start - lastEnd - 1), NoPgpBlock));
0097             }
0098 
0099             lastEnd = msg.indexOf("\n", nextEnd + 14);
0100             if (lastEnd == -1) {
0101                 if (start < length) {
0102                     blocks.append(Block(msg.mid(start)));
0103                 }
0104                 break;
0105             } else {
0106                 blocks.append(Block(msg.mid(start, lastEnd + 1 - start)));
0107                 if ((nextStart != -1) && (nextEnd > nextStart)) {
0108                     nextStart = msg.indexOf("\n-----BEGIN PGP ", lastEnd + 1);
0109                 }
0110             }
0111         }
0112 
0113         start = nextStart;
0114 
0115         if (start == -1) {
0116             if (lastEnd + 1 < length) {
0117                 //rest of mail is no PGP Block
0118                 blocks.append(Block(msg.mid(lastEnd + 1), NoPgpBlock));
0119             }
0120             break;
0121         } else {
0122             start++; // move start behind the '\n'
0123         }
0124     }
0125 
0126     return blocks;
0127 }
0128 
0129 Block::Block(const QByteArray &m)
0130     : msg(m)
0131 {
0132     mType = determineType();
0133 }
0134 
0135 Block::Block(const QByteArray &m, PGPBlockType t)
0136     : msg(m)
0137     , mType(t)
0138 {
0139 
0140 }
0141 
0142 QByteArray MimeTreeParser::Block::text() const
0143 {
0144     return msg;
0145 }
0146 
0147 PGPBlockType Block::type() const
0148 {
0149     return mType;
0150 }