diff options
Diffstat (limited to 'knewstuff/knewstuffsecure.cpp')
-rw-r--r-- | knewstuff/knewstuffsecure.cpp | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/knewstuff/knewstuffsecure.cpp b/knewstuff/knewstuffsecure.cpp new file mode 100644 index 000000000..270d9449c --- /dev/null +++ b/knewstuff/knewstuffsecure.cpp @@ -0,0 +1,240 @@ +/*************************************************************************** + knewstuffsecure.cpp - description + ------------------- + begin : Tue Jun 22 12:19:55 2004 + copyright : (C) 2004, 2005 by Andras Mantia <amantia@kde.org> + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; version 2 of the License. * + * * + ***************************************************************************/ +//qt includes +#include <qfileinfo.h> + +//kde includes +#include <kconfig.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktar.h> +#include <ktempdir.h> + +//app includes +#include "engine.h" +#include "knewstuffsecure.h" +#include "security.h" + +using namespace KNS; + +KNewStuffSecure::KNewStuffSecure(const QString &type, QWidget *parentWidget) + : KNewStuff(type, parentWidget) +{ + m_tempDir = 0L; + connect(engine(), SIGNAL(uploadFinished(bool)), SLOT(slotUploadFinished(bool))); +} + + +KNewStuffSecure::~KNewStuffSecure() +{ + removeTempDirectory(); +} + +bool KNewStuffSecure::install(const QString &fileName) +{ + bool ok = true; + + removeTempDirectory(); + m_tempDir = new KTempDir(); + m_tempDir->setAutoDelete(true); + KTar tar(fileName, "application/x-gzip"); + if (tar.open(IO_ReadOnly)) + { + const KArchiveDirectory *directory = tar.directory(); + directory->copyTo(m_tempDir->name(), true); + m_tarName = ""; + QStringList entries = directory->entries(); + for (QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) + { + if (*it != "signature" && *it != "md5sum") + { + m_tarName = *it; + break; + } + } + tar.close(); + if (m_tarName.isEmpty()) + ok = false; + else + { + m_tarName.prepend(m_tempDir->name()); + connect(Security::ref(), SIGNAL(validityResult(int)), this, SLOT(slotValidated(int))); + Security::ref()->checkValidity(m_tarName); + } + } else + ok = false; + if (!ok) + KMessageBox::error(parentWidget(), i18n("There was an error with the downloaded resource tarball file. Possible causes are damaged archive or invalid directory structure in the archive."), i18n("Resource Installation Error")); + return ok; +} + +void KNewStuffSecure::slotValidated(int result) +{ + QString errorString; + QString signatureStr; + bool valid = true; + if (result == -1) + { + errorString ="<br>- " + i18n("No keys were found."); + valid = false; + } else + if (result == 0) + { + errorString ="<br>- " + i18n("The validation failed for unknown reason."); + valid = false; + } else + { + KeyStruct key = Security::ref()->signatureKey(); + if (!(result & Security::MD5_OK )) + { + errorString = "<br>- " + i18n("The MD5SUM check failed, the archive might be broken."); + valid = false; + } + if (result & Security::SIGNED_BAD) + { + errorString += "<br>- " + i18n("The signature is bad, the archive might be broken or altered."); + valid = false; + } + if (result & Security::SIGNED_OK) + { + if (result & Security::TRUSTED) + { + kdDebug() << "Signed and trusted " << endl; + } else + { + errorString += "<br>- " + i18n("The signature is valid, but untrusted."); + valid = false; + } + } + if (result & Security::UNKNOWN) + { + errorString += "<br>- " + i18n("The signature is unknown."); + valid = false; + } else + { + signatureStr = i18n("The resource was signed with key <i>0x%1</i>, belonging to <i>%2 <%3></i>.").arg(key.id.right(8)).arg(key.name).arg(key.mail); + } + } + if (!valid) + { + signatureStr.prepend( "<br>"); + if (KMessageBox::warningContinueCancel(parentWidget(), i18n("<qt>There is a problem with the resource file you have downloaded. The errors are :<b>%1</b><br>%2<br><br>Installation of the resource is <b>not recommended</b>.<br><br>Do you want to proceed with the installation?</qt>").arg(errorString).arg(signatureStr), i18n("Problematic Resource File")) == KMessageBox::Continue) + valid = true; + } else + KMessageBox::information(parentWidget(), i18n("<qt>%1<br><br>Press OK to install it.</qt>").arg(signatureStr), i18n("Valid Resource"), "Show Valid Signature Information"); + if (valid) + { + installResource(); + emit installFinished(); + } else + { + KConfig *cfg = KGlobal::config(); + cfg->deleteGroup("KNewStuffStatus"); + cfg->setGroup("KNewStuffStatus"); + for (QMap<QString, QString>::ConstIterator it = m_installedResources.constBegin(); it != m_installedResources.constEnd(); ++it) + { + cfg->writeEntry(it.key(), it.data()); + } + cfg->sync(); + } + removeTempDirectory(); + disconnect(Security::ref(), SIGNAL(validityResult(int)), this, SLOT(slotValidated(int))); +} + +void KNewStuffSecure::downloadResource() +{ + KConfig *cfg = KGlobal::config(); + m_installedResources = cfg->entryMap("KNewStuffStatus"); + engine()->ignoreInstallResult(true); + KNewStuff::download(); +} + +bool KNewStuffSecure::createUploadFile(const QString &fileName) +{ + Q_UNUSED(fileName); + return true; +} + +void KNewStuffSecure::uploadResource(const QString& fileName) +{ + connect(Security::ref(), SIGNAL(fileSigned(int)), this, SLOT(slotFileSigned(int))); + removeTempDirectory(); + m_tempDir = new KTempDir(); + m_tempDir->setAutoDelete(true); + QFileInfo f(fileName); + m_signedFileName = m_tempDir->name() + "/" + f.fileName(); + KIO::NetAccess::file_copy(KURL::fromPathOrURL(fileName), KURL::fromPathOrURL(m_signedFileName), -1, true); + Security::ref()->signFile(m_signedFileName); +} + +void KNewStuffSecure::slotFileSigned(int result) +{ + if (result == 0) + { + KMessageBox::error(parentWidget(), i18n("The signing failed for unknown reason.")); + } else + { + if (result & Security::BAD_PASSPHRASE) + { + if (KMessageBox::warningContinueCancel(parentWidget(), i18n("There are no keys usable for signing or you did not entered the correct passphrase.\nProceed without signing the resource?")) == KMessageBox::Cancel) + { + disconnect(Security::ref(), SIGNAL(fileSigned(int)), this, SLOT(slotFileSigned(int))); + removeTempDirectory(); + return; + } + } + KTar tar(m_signedFileName + ".signed", "application/x-gzip"); + tar.open(IO_WriteOnly); + QStringList files; + files << m_signedFileName; + files << m_tempDir->name() + "/md5sum"; + files << m_tempDir->name() + "/signature"; + + for (QStringList::Iterator it_f = files.begin(); it_f != files.end(); ++it_f) + { + QFile file(*it_f); + file.open(IO_ReadOnly); + QByteArray bArray = file.readAll(); + tar.writeFile(QFileInfo(file).fileName(), "user", "group", bArray.size(), bArray.data()); + file.close(); + } + tar.close(); + KIO::NetAccess::file_move(KURL::fromPathOrURL(m_signedFileName + ".signed"), KURL::fromPathOrURL(m_signedFileName), -1, true); + KNewStuff::upload(m_signedFileName, QString::null); + disconnect(Security::ref(), SIGNAL(fileSigned(int)), this, SLOT(slotFileSigned(int))); + } +} + +void KNewStuffSecure::slotUploadFinished(bool result) +{ + Q_UNUSED(result); + removeTempDirectory(); +} + +void KNewStuffSecure::removeTempDirectory() +{ + if (m_tempDir) + { + KIO::NetAccess::del(KURL().fromPathOrURL(m_tempDir->name()), parentWidget()); + delete m_tempDir; + m_tempDir = 0L; + } +} + +#include "knewstuffsecure.moc" |