File indexing completed on 2024-04-14 05:43:28
0001 /* 0002 SPDX-FileCopyrightText: 2010-2022 Rolf Eike Beer <kde@opensource.sf-tec.de> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "kgpgdecrypt.h" 0007 0008 #include "gpgproc.h" 0009 #include "kgpgsettings.h" 0010 0011 #include <KLocalizedString> 0012 0013 KGpgDecrypt::KGpgDecrypt(QObject *parent, const QString &text) 0014 : KGpgTextOrFileTransaction(parent, text), 0015 m_fileIndex(-1), 0016 m_plainLength(-1) 0017 { 0018 } 0019 0020 KGpgDecrypt::KGpgDecrypt(QObject *parent, const QList<QUrl> &files) 0021 : KGpgTextOrFileTransaction(parent, files), 0022 m_fileIndex(0), 0023 m_plainLength(-1) 0024 { 0025 } 0026 0027 KGpgDecrypt::KGpgDecrypt(QObject* parent, const QUrl& infile, const QUrl& outfile) 0028 : KGpgTextOrFileTransaction(parent, QList<QUrl>({infile})), 0029 m_fileIndex(0), 0030 m_plainLength(-1), 0031 m_outFilename(outfile.toLocalFile()) 0032 { 0033 } 0034 0035 QStringList 0036 KGpgDecrypt::command() const 0037 { 0038 QStringList ret; 0039 0040 ret << QLatin1String("--decrypt") << QLatin1String("--command-fd=0"); 0041 0042 if (!m_outFilename.isEmpty()) 0043 ret << QLatin1String("-o") << m_outFilename; 0044 0045 ret << KGpgSettings::customDecrypt().simplified().split(QLatin1Char(' '), Qt::SkipEmptyParts); 0046 0047 return ret; 0048 } 0049 0050 QStringList 0051 KGpgDecrypt::decryptedText() const 0052 { 0053 QStringList result; 0054 int txtlength = 0; 0055 0056 for (const QString &line : getMessages()) 0057 if (!line.startsWith(QLatin1String("[GNUPG:] "))) { 0058 result.append(line); 0059 txtlength += line.length() + 1; 0060 } 0061 0062 if (result.isEmpty()) 0063 return result; 0064 0065 QString last = result.last(); 0066 // this may happen when the original text did not end with a newline 0067 if (last.endsWith(QLatin1String("[GNUPG:] DECRYPTION_OKAY"))) { 0068 // if GnuPG doesn't tell us the length assume that this happend 0069 // if it told us the length then check if it _really_ happend 0070 if (((m_plainLength != -1) && (txtlength != m_plainLength)) || 0071 (m_plainLength == -1)) { 0072 last.chop(24); 0073 result[result.count() - 1] = last; 0074 } 0075 } 0076 0077 return result; 0078 } 0079 0080 bool 0081 KGpgDecrypt::isEncryptedText(const QString &text, int *startPos, int *endPos) 0082 { 0083 int posStart = text.indexOf(QLatin1String("-----BEGIN PGP MESSAGE-----")); 0084 if (posStart == -1) 0085 return false; 0086 0087 int posEnd = text.indexOf(QLatin1String("-----END PGP MESSAGE-----"), posStart); 0088 if (posEnd == -1) 0089 return false; 0090 0091 if (startPos != nullptr) 0092 *startPos = posStart; 0093 if (endPos != nullptr) 0094 *endPos = posEnd; 0095 0096 return true; 0097 } 0098 0099 bool 0100 KGpgDecrypt::nextLine(const QString& line) 0101 { 0102 const QList<QUrl> &inputFiles = getInputFiles(); 0103 0104 if (line == QLatin1String("[GNUPG:] DECRYPTION_OKAY")) { 0105 // Assume Gpg decryption was successful even if gpg returns 0106 // an error code. 0107 decryptSuccess = true; 0108 } else if (!inputFiles.isEmpty()) { 0109 if (line == QLatin1String("[GNUPG:] BEGIN_DECRYPTION")) { 0110 Q_EMIT statusMessage(i18nc("Status message 'Decrypting <filename>' (operation starts)", "Decrypting %1", inputFiles.at(m_fileIndex).fileName())); 0111 Q_EMIT infoProgress(2 * m_fileIndex + 1, inputFiles.count() * 2); 0112 } else if (line == QLatin1String("[GNUPG:] END_DECRYPTION")) { 0113 Q_EMIT statusMessage(i18nc("Status message 'Decrypted <filename>' (operation was completed)", "Decrypted %1", inputFiles.at(m_fileIndex).fileName())); 0114 m_fileIndex++; 0115 Q_EMIT infoProgress(2 * m_fileIndex, inputFiles.count() * 2); 0116 } 0117 } else { 0118 if (line.startsWith(QLatin1String("[GNUPG:] PLAINTEXT_LENGTH "))) { 0119 bool ok; 0120 m_plainLength = QStringView(line).mid(26).toInt(&ok); 0121 if (!ok) 0122 m_plainLength = -1; 0123 } else if (line == QLatin1String("[GNUPG:] BEGIN_DECRYPTION")) { 0124 // close the command channel (if any) to signal GnuPG that it 0125 // can start sending the output. 0126 getProcess()->closeWriteChannel(); 0127 } 0128 } 0129 0130 return KGpgTextOrFileTransaction::nextLine(line); 0131 } 0132 0133 void 0134 KGpgDecrypt::finish() 0135 { 0136 if (decryptSuccess) { 0137 // Gpg error code is ignored. 0138 // https://bugs.kde.org/show_bug.cgi?id=357462 0139 setSuccess(TS_OK); 0140 } else { 0141 KGpgTextOrFileTransaction::finish(); 0142 } 0143 } 0144 0145 bool KGpgDecrypt::closeInputAfterText() const 0146 { 0147 // otherwise decryption does never start in GnuPG 2.3, 0148 // but doesn't hurt on older versions as well 0149 return true; 0150 }