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::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)
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"