00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
#include <qfileinfo.h>
00017
00018
00019
#include <kconfig.h>
00020
#include <kdebug.h>
00021
#include <kglobal.h>
00022
#include <kio/netaccess.h>
00023
#include <klocale.h>
00024
#include <kmessagebox.h>
00025
#include <kstandarddirs.h>
00026
#include <ktar.h>
00027
#include <ktempdir.h>
00028
00029
00030
#include "engine.h"
00031
#include "knewstuffsecure.h"
00032
#include "security.h"
00033
00034
using namespace KNS;
00035
00036 KNewStuffSecure::KNewStuffSecure(
const QString &type,
QWidget *parentWidget)
00037 :
KNewStuff(type, parentWidget)
00038 {
00039 m_tempDir = 0L;
00040 connect(
engine(), SIGNAL(uploadFinished(
bool)), SLOT(slotUploadFinished(
bool)));
00041 }
00042
00043
00044 KNewStuffSecure::~KNewStuffSecure()
00045 {
00046
removeTempDirectory();
00047 }
00048
00049 bool KNewStuffSecure::install(
const QString &fileName)
00050 {
00051
bool ok =
true;
00052
00053
removeTempDirectory();
00054 m_tempDir =
new KTempDir();
00055 m_tempDir->setAutoDelete(
true);
00056 KTar tar(fileName,
"application/x-gzip");
00057
if (tar.open(IO_ReadOnly))
00058 {
00059
const KArchiveDirectory *directory = tar.directory();
00060 directory->copyTo(m_tempDir->name(),
true);
00061 m_tarName =
"";
00062
QStringList entries = directory->entries();
00063
for (QStringList::Iterator it = entries.begin(); it != entries.end(); ++it)
00064 {
00065
if (*it !=
"signature" && *it !=
"md5sum")
00066 {
00067 m_tarName = *it;
00068
break;
00069 }
00070 }
00071 tar.close();
00072
if (m_tarName.isEmpty())
00073 ok =
false;
00074
else
00075 {
00076 m_tarName.prepend(m_tempDir->name());
00077 connect(Security::ref(), SIGNAL(validityResult(
int)),
this, SLOT(slotValidated(
int)));
00078 Security::ref()->checkValidity(m_tarName);
00079 }
00080 }
else
00081 ok =
false;
00082
if (!ok)
00083 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"));
00084
return ok;
00085 }
00086
00087
void KNewStuffSecure::slotValidated(
int result)
00088 {
00089
QString errorString;
00090
QString signatureStr;
00091
bool valid =
true;
00092
if (result == -1)
00093 {
00094 errorString =
"<br>- " + i18n(
"No keys were found.");
00095 valid =
false;
00096 }
else
00097
if (result == 0)
00098 {
00099 errorString =
"<br>- " + i18n(
"The validation failed for unknown reason.");
00100 valid =
false;
00101 }
else
00102 {
00103 KeyStruct key = Security::ref()->signatureKey();
00104
if (!(result & Security::MD5_OK ))
00105 {
00106 errorString =
"<br>- " + i18n(
"The MD5SUM check failed, the archive might be broken.");
00107 valid =
false;
00108 }
00109
if (result & Security::SIGNED_BAD)
00110 {
00111 errorString +=
"<br>- " + i18n(
"The signature is bad, the archive might be broken or altered.");
00112 valid =
false;
00113 }
00114
if (result & Security::SIGNED_OK)
00115 {
00116
if (result & Security::TRUSTED)
00117 {
00118 kdDebug() <<
"Signed and trusted " << endl;
00119 }
else
00120 {
00121 errorString +=
"<br>- " + i18n(
"The signature is valid, but untrusted.");
00122 valid =
false;
00123 }
00124 }
00125
if (result & Security::UNKNOWN)
00126 {
00127 errorString +=
"<br>- " + i18n(
"The signature is unknown.");
00128 valid =
false;
00129 }
else
00130 {
00131 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);
00132 }
00133 }
00134
if (!valid)
00135 {
00136 signatureStr.prepend(
"<br>");
00137
if (KMessageBox::warningYesNo(
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::Yes)
00138 valid =
true;
00139 }
else
00140 KMessageBox::information(
parentWidget(), i18n(
"<qt>%1<br><br>Press OK to install it.</qt>").arg(signatureStr), i18n(
"Valid Resource"),
"Show Valid Signature Information");
00141
if (valid)
00142 {
00143
installResource();
00144 emit installFinished();
00145 }
else
00146 {
00147 KConfig *cfg = KGlobal::config();
00148 cfg->deleteGroup(
"KNewStuffStatus");
00149 cfg->setGroup(
"KNewStuffStatus");
00150
for (
QMap<QString, QString>::ConstIterator it = m_installedResources.constBegin(); it != m_installedResources.constEnd(); ++it)
00151 {
00152 cfg->writeEntry(it.key(), it.data());
00153 }
00154 cfg->sync();
00155 }
00156
removeTempDirectory();
00157 disconnect(Security::ref(), SIGNAL(validityResult(
int)),
this, SLOT(slotValidated(
int)));
00158 }
00159
00160 void KNewStuffSecure::downloadResource()
00161 {
00162 KConfig *cfg = KGlobal::config();
00163 m_installedResources = cfg->entryMap(
"KNewStuffStatus");
00164
engine()->
ignoreInstallResult(
true);
00165
KNewStuff::download();
00166 }
00167
00168 bool KNewStuffSecure::createUploadFile(
const QString &fileName)
00169 {
00170 Q_UNUSED(fileName);
00171
return true;
00172 }
00173
00174 void KNewStuffSecure::uploadResource(
const QString& fileName)
00175 {
00176 connect(Security::ref(), SIGNAL(fileSigned(
int)),
this, SLOT(slotFileSigned(
int)));
00177
removeTempDirectory();
00178 m_tempDir =
new KTempDir();
00179 m_tempDir->setAutoDelete(
true);
00180
QFileInfo f(fileName);
00181 m_signedFileName = m_tempDir->name() +
"/" + f.fileName();
00182 KIO::NetAccess::file_copy(KURL::fromPathOrURL(fileName), KURL::fromPathOrURL(m_signedFileName), -1,
true);
00183 Security::ref()->signFile(m_signedFileName);
00184 }
00185
00186
void KNewStuffSecure::slotFileSigned(
int result)
00187 {
00188
if (result == 0)
00189 {
00190 KMessageBox::error(
parentWidget(), i18n(
"The signing failed for unknown reason."));
00191 }
else
00192 {
00193
if (result & Security::BAD_PASSPHRASE)
00194 {
00195
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)
00196 {
00197 disconnect(Security::ref(), SIGNAL(fileSigned(
int)),
this, SLOT(slotFileSigned(
int)));
00198
removeTempDirectory();
00199
return;
00200 }
00201 }
00202 KTar tar(m_signedFileName +
".signed",
"application/x-gzip");
00203 tar.open(IO_WriteOnly);
00204
QStringList files;
00205 files << m_signedFileName;
00206 files << m_tempDir->name() +
"/md5sum";
00207 files << m_tempDir->name() +
"/signature";
00208
00209
for (QStringList::Iterator it_f = files.begin(); it_f != files.end(); ++it_f)
00210 {
00211
QFile file(*it_f);
00212 file.open(IO_ReadOnly);
00213
QByteArray bArray = file.readAll();
00214 tar.writeFile(
QFileInfo(file).fileName(),
"user",
"group", bArray.size(), bArray.data());
00215 file.close();
00216 }
00217 tar.close();
00218 KIO::NetAccess::file_move(KURL::fromPathOrURL(m_signedFileName +
".signed"), KURL::fromPathOrURL(m_signedFileName), -1,
true);
00219
KNewStuff::upload(m_signedFileName, QString::null);
00220 disconnect(Security::ref(), SIGNAL(fileSigned(
int)),
this, SLOT(slotFileSigned(
int)));
00221 }
00222 }
00223
00224
void KNewStuffSecure::slotUploadFinished(
bool result)
00225 {
00226 Q_UNUSED(result);
00227
removeTempDirectory();
00228 }
00229
00230 void KNewStuffSecure::removeTempDirectory()
00231 {
00232
if (m_tempDir)
00233 {
00234 KIO::NetAccess::del(KURL().fromPathOrURL(m_tempDir->name()),
parentWidget());
00235
delete m_tempDir;
00236 m_tempDir = 0L;
00237 }
00238 }
00239
00240
#include "knewstuffsecure.moc"