You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/knewstuff/knewstuffsecure.cpp

241 lines
7.9 KiB

/***************************************************************************
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 &lt;%3&gt;</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"