File indexing completed on 2023-10-03 07:53:57
0001 /************************************************************************** 0002 * Copyright (C) 2009-2011 Matthias Fuchs <mat69@gmx.net> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the * 0016 * Free Software Foundation, Inc., * 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 0018 ***************************************************************************/ 0019 0020 #include "keydownloader.h" 0021 #include "settings.h" 0022 #include "signature_p.h" 0023 0024 #include "kget_debug.h" 0025 #include <KIO/Job> 0026 #include <KLocalizedString> 0027 #include <KMessageBox> 0028 #include <QDebug> 0029 0030 #ifdef HAVE_QGPGME 0031 #include <gpgme++/context.h> 0032 #include <gpgme++/data.h> 0033 #include <gpgme++/importresult.h> 0034 #include <qgpgme/dataprovider.h> 0035 #endif 0036 0037 KeyDownloader::KeyDownloader(QObject *parent) 0038 : QObject(parent) 0039 { 0040 } 0041 0042 bool KeyDownloader::isValid() const 0043 { 0044 #ifdef HAVE_QGPGME 0045 return true; 0046 #else // HAVE_QGPGME 0047 return false; 0048 #endif // HAVE_QGPGME 0049 } 0050 0051 void KeyDownloader::downloadKey(QString fingerprint, Signature *sig) 0052 { 0053 downloadKey(fingerprint, sig, false); 0054 } 0055 0056 void KeyDownloader::downloadKey(QString fingerprint, Signature *sig, bool mirrorFailed) 0057 { 0058 if (fingerprint.isEmpty() || (!sig && !mirrorFailed)) { 0059 return; 0060 } 0061 0062 if (!fingerprint.startsWith(QLatin1String("0x"))) { 0063 fingerprint = "0x" + fingerprint; 0064 } 0065 0066 if (m_downloading.contains(fingerprint) && !mirrorFailed) { 0067 if (!m_downloading.contains(fingerprint, sig)) { 0068 m_downloading.insert(fingerprint, sig); 0069 } 0070 } else { 0071 const QStringList servers = Settings::signatureKeyServers(); 0072 if (!servers.count()) { 0073 KMessageBox::error(nullptr, i18n("No server for downloading keys is specified in settings. Downloading aborted."), i18n("No key server")); 0074 return; 0075 } 0076 0077 QString mirror; 0078 if (mirrorFailed) { 0079 const QStringList failedMirrors = m_triedMirrors.values(fingerprint); 0080 for (int i = 0; i < servers.count(); ++i) { 0081 if (!m_triedMirrors.contains(fingerprint, servers.at(i))) { 0082 mirror = servers.at(i); 0083 break; 0084 } 0085 } 0086 } else { 0087 mirror = servers.first(); 0088 } 0089 0090 if (mirror.isEmpty()) { 0091 KMessageBox::error(nullptr, 0092 i18n("No useful key server found, key not downloaded. Add more servers to the settings or restart KGet and retry downloading."), 0093 i18n("No key server")); 0094 return; 0095 } 0096 0097 m_triedMirrors.insert(fingerprint, mirror); 0098 if (!mirrorFailed) { 0099 m_downloading.insert(fingerprint, sig); 0100 } 0101 0102 QUrl url; 0103 url.setPath(mirror + "pks/lookup"); 0104 url.setQuery("op=get&options=mr&search=" + fingerprint); 0105 url.setPort(11371); 0106 0107 qCDebug(KGET_DEBUG) << "Downloading:" << url; 0108 0109 KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); 0110 m_jobs[job] = fingerprint; 0111 connect(job, &KJob::finished, this, &KeyDownloader::slotDownloaded); 0112 } 0113 } 0114 0115 void KeyDownloader::slotDownloaded(KJob *job) 0116 { 0117 #ifdef HAVE_QGPGME 0118 if (!m_jobs.contains(job)) { 0119 return; 0120 } 0121 0122 const QString fingerprint = m_jobs[job]; 0123 auto *transferJob = static_cast<KIO::StoredTransferJob *>(job); 0124 0125 if (transferJob->isErrorPage()) { 0126 qCDebug(KGET_DEBUG) << "Mirror did not work, try another one."; 0127 downloadKey(fingerprint, nullptr, true); 0128 return; 0129 } 0130 0131 QByteArray data = transferJob->data(); 0132 if (data.isEmpty()) { 0133 qCDebug(KGET_DEBUG) << "Downloaded data is empty."; 0134 downloadKey(fingerprint, nullptr, true); 0135 return; 0136 } 0137 0138 const int indexStart = data.indexOf("<pre>"); 0139 const int indexEnd = data.indexOf("</pre>", indexStart); 0140 if ((indexStart == -1) || (indexEnd == -1)) { 0141 qCDebug(KGET_DEBUG) << "Could not find a key."; 0142 downloadKey(fingerprint, nullptr, true); 0143 return; 0144 } 0145 0146 data = data.mid(indexStart + 6, indexEnd - indexStart - 6); 0147 0148 GpgME::initializeLibrary(); 0149 GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP); 0150 if (err) { 0151 qCDebug(KGET_DEBUG) << "Problem checking the engine."; 0152 return; 0153 } 0154 0155 QScopedPointer<GpgME::Context> context(GpgME::Context::createForProtocol(GpgME::OpenPGP)); 0156 if (!context.data()) { 0157 qCDebug(KGET_DEBUG) << "Could not create context."; 0158 return; 0159 } 0160 0161 QGpgME::QByteArrayDataProvider keyBA(data); 0162 GpgME::Data key(&keyBA); 0163 GpgME::ImportResult importResult = context->importKeys(key); 0164 err = importResult.error(); 0165 if (err) { 0166 qCDebug(KGET_DEBUG) << "Error while importing key."; 0167 ; 0168 return; 0169 } 0170 0171 qCDebug(KGET_DEBUG) << "Key downloaded, notifying requesters."; 0172 0173 QList<Signature *> sigs = m_downloading.values(fingerprint); 0174 foreach (Signature *sig, sigs) { 0175 sig->d->signatureDownloaded(); 0176 } 0177 m_downloading.remove(fingerprint); 0178 #else // HAVE_QGPGME 0179 Q_UNUSED(job) 0180 qCWarning(KGET_DEBUG) << "No QGPGME support."; 0181 #endif // HAVE_QGPGME 0182 } 0183 0184 #include "moc_keydownloader.cpp"