File indexing completed on 2025-01-19 04:46:49

0001 /*
0002   SPDX-FileCopyrightText: 2016 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "pgpkeymessagepart.h"
0008 
0009 #include <QProcess>
0010 
0011 #include <KMime/Content>
0012 #include <MimeTreeParser/BodyPart>
0013 
0014 PgpKeyMessagePart::PgpKeyMessagePart(MimeTreeParser::Interface::BodyPart *part)
0015     : MimeTreeParser::MessagePart(part->objectTreeParser(), QString())
0016 {
0017     setContent(part->content());
0018     parseContent(part->content());
0019 }
0020 
0021 QDateTime PgpKeyMessagePart::keyDate() const
0022 {
0023     return mKeyDate;
0024 }
0025 
0026 QString PgpKeyMessagePart::keyID() const
0027 {
0028     return mKeyID;
0029 }
0030 
0031 QString PgpKeyMessagePart::userID() const
0032 {
0033     return mUserID;
0034 }
0035 
0036 QString PgpKeyMessagePart::fingerprint() const
0037 {
0038     return mFingerprint;
0039 }
0040 
0041 GpgME::Key PgpKeyMessagePart::key() const
0042 {
0043     return mKey;
0044 }
0045 
0046 void PgpKeyMessagePart::setKey(const GpgME::Key &key)
0047 {
0048     mKey = key;
0049 }
0050 
0051 QString PgpKeyMessagePart::error() const
0052 {
0053     return mError;
0054 }
0055 
0056 void PgpKeyMessagePart::setError(const QString &error)
0057 {
0058     mError = error;
0059 }
0060 
0061 QByteArray PgpKeyMessagePart::rawKey() const
0062 {
0063     return content()->decodedContent();
0064 }
0065 
0066 void PgpKeyMessagePart::setSearchRunning(bool searchRunning)
0067 {
0068     mSearchRunning = searchRunning;
0069 }
0070 
0071 bool PgpKeyMessagePart::searchRunning() const
0072 {
0073     return mSearchRunning;
0074 }
0075 
0076 void PgpKeyMessagePart::parseContent(KMime::Content *node)
0077 {
0078     // TODO if GpgME dependency is 1.9.0 this can use
0079     // GpgME::Data::toKeys
0080     //
0081     // something like:
0082     // QGpgME::QByteArrayDataProvider dp(node->decodedContent());
0083     // Data data(&dp);
0084     // std::vector <Key> keys = data.toKeys();
0085     QProcess p;
0086     p.start(QStringLiteral("gpg"), {QStringLiteral("--with-colons"), QStringLiteral("--fixed-list-mode"), QStringLiteral("--with-fingerprint")});
0087     p.waitForStarted();
0088     p.write(node->decodedContent());
0089     p.closeWriteChannel();
0090     p.waitForReadyRead();
0091     const QByteArray result = p.readAllStandardOutput();
0092     p.waitForFinished();
0093 
0094     const auto lines = result.split('\n');
0095     for (const auto &line : lines) {
0096         const auto cols = line.split(':');
0097         if (cols.isEmpty()) {
0098             continue;
0099         }
0100 
0101         const int size = cols.size();
0102 
0103         // "pub" line can appear multiple times, but we are only interested in
0104         // the first one
0105         if (cols[0] == "pub" && mKeyID.isEmpty()) {
0106             if (size > 4) {
0107                 mKeyID = QString::fromUtf8(cols[4]);
0108             }
0109             // gpg1: "pub" contains UID
0110             if (size > 9) {
0111                 mUserID = QString::fromUtf8(cols[9]);
0112             }
0113             if (size > 6) {
0114                 mKeyDate = QDateTime::fromSecsSinceEpoch(cols[5].toUInt());
0115             }
0116             // gpg2: UID is on a separate line
0117         } else if (cols[0] == "uid" && size > 9 && mUserID.isEmpty()) {
0118             mUserID = QString::fromUtf8(cols[9]);
0119         } else if (cols[0] == "fpr" && size > 9 && mFingerprint.isEmpty()) {
0120             mFingerprint = QString::fromLatin1(cols[9]);
0121         }
0122     }
0123 }
0124 
0125 #include "moc_pgpkeymessagepart.cpp"