Apply upstream security patch to kget

svn path=/nixpkgs/trunk/; revision=21769
This commit is contained in:
Yury G. Kudryashov 2010-05-13 22:05:08 +00:00
parent 975b88f573
commit 43106b4d04
2 changed files with 214 additions and 1 deletions

View File

@ -11,8 +11,9 @@ stdenv.mkDerivation {
};
buildInputs = [ cmake qt4 perl speex gmp libxml2 libxslt sqlite alsaLib libidn
libvncserver libmsn giflib gpgme boost stdenv.gcc.libc libv4l
libXi libXtst libXdamage libXxf86vm
libXi libXtst libXdamage libXxf86vm
kdelibs kdepimlibs automoc4 phonon qca2 soprano qimageblitz strigi ];
patches = [ ./kget-cve.patch ];
meta = {
description = "KDE network utilities";
longDescription = "Various network utilities for KDE such as a messenger client and network configuration interface";

View File

@ -0,0 +1,212 @@
Index: kget/transfer-plugins/metalink/metalink.cpp
===================================================================
--- a/kget/transfer-plugins/metalink/metalink.cpp (revision 1124973)
+++ b/kget/transfer-plugins/metalink/metalink.cpp (revision 1124974)
@@ -99,6 +99,7 @@
void Metalink::metalinkInit(const KUrl &src, const QByteArray &data)
{
kDebug(5001);
+
bool justDownloaded = !m_localMetalinkLocation.isValid();
if (!src.isEmpty())
{
@@ -121,7 +122,9 @@
//error
if (!m_metalink.isValid())
{
- kDebug(5001) << "Unknown error when trying to load the .metalink-file";
+ kError(5001) << "Unknown error when trying to load the .metalink-file. Metalink is not valid.";
+ setStatus(Job::Aborted);
+ setTransferChange(Tc_Status, true);
return;
}
@@ -202,7 +205,7 @@
if (!m_dataSourceFactory.size())
{
KMessageBox::error(0, i18n("Download failed, no working URLs were found."), i18n("Error"));
- setStatus(Job::Aborted, i18n("An error occurred...."), SmallIcon("document-preview"));
+ setStatus(Job::Aborted);
setTransferChange(Tc_Status, true);
return;
}
@@ -227,16 +230,29 @@
ui.treeView->hideColumn(FileItem::SignatureVerified);
dialog->setMainWidget(widget);
dialog->setCaption(i18n("File Selection"));
- dialog->setButtons(KDialog::Ok);
- connect(dialog, SIGNAL(finished()), this, SLOT(filesSelected()));
+ dialog->setButtons(KDialog::Ok | KDialog::Cancel);
+ connect(dialog, SIGNAL(finished(int)), this, SLOT(fileDlgFinished(int)));
dialog->show();
}
}
-void Metalink::filesSelected()
+void Metalink::fileDlgFinished(int result)
{
+ //BEGIN HACK if the dialog was not accepted untick every file, so that the download does not start
+ //generally setStatus should do the job as well, but does not as it appears
+ if (result != QDialog::Accepted) {
+ for (int row = 0; row < fileModel()->rowCount(); ++row) {
+ QModelIndex index = fileModel()->index(row, FileItem::File);
+ if (index.isValid()) {
+ fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole);
+ }
+ }
+ }
+ //END
+
QModelIndexList files = fileModel()->fileIndexes(FileItem::File);
+ int numFilesSelected = 0;
foreach (const QModelIndex &index, files)
{
const KUrl dest = fileModel()->getUrl(index);
@@ -244,6 +260,9 @@
if (m_dataSourceFactory.contains(dest))
{
m_dataSourceFactory[dest]->setDoDownload(doDownload);
+ if (doDownload) {
+ ++numFilesSelected;
+ }
}
}
@@ -252,9 +271,15 @@
processedSizeChanged();
speedChanged();
+ //no files selected to download or dialog rejected, stop the download
+ if (!numFilesSelected || (result != QDialog::Accepted)) {
+ setStatus(Job::Stopped);//FIXME
+ setTransferChange(Tc_Status, true);
+ return;
+ }
+
//some files may be set to download, so start them as long as the transfer is not stopped
- if (status() != Job::Stopped)
- {
+ if (status() != Job::Stopped) {
startMetalink();
}
}
Index: kget/transfer-plugins/metalink/metalink.h
===================================================================
--- a/kget/transfer-plugins/metalink/metalink.h (revision 1124973)
+++ b/kget/transfer-plugins/metalink/metalink.h (revision 1124974)
@@ -81,7 +81,7 @@
private Q_SLOTS:
void metalinkInit(const KUrl &url = KUrl(), const QByteArray &data = QByteArray());
- void filesSelected();
+ void fileDlgFinished(int result);
void totalSizeChanged(KIO::filesize_t size);
void processedSizeChanged();
void speedChanged();
Index: kget/ui/metalinkcreator/metalinker.h
===================================================================
--- a/kget/ui/metalinkcreator/metalinker.h (revision 1124973)
+++ b/kget/ui/metalinkcreator/metalinker.h (revision 1124974)
@@ -259,6 +259,14 @@
KIO::filesize_t size;
CommonData data;
Resources resources;
+
+ private:
+ /**
+ * Controlls if the name attribute is valid, i.e. it is not empty and
+ * does not contain any directory traversal directives or information,
+ * as described in the Metalink 4.0 specification 4.1.2.1.
+ */
+ bool isValidNameAttribute() const;
};
class Files
Index: kget/ui/metalinkcreator/metalinker.cpp
===================================================================
--- a/kget/ui/metalinkcreator/metalinker.cpp (revision 1124973)
+++ b/kget/ui/metalinkcreator/metalinker.cpp (revision 1124974)
@@ -528,14 +528,14 @@
bool KGetMetalink::File::isValid() const
{
- return !name.isEmpty() && resources.isValid();
+ return isValidNameAttribute() && resources.isValid();
}
void KGetMetalink::File::load(const QDomElement &e)
{
data.load(e);
- name = e.attribute("name");
+ name = QUrl::fromPercentEncoding(e.attribute("name").toAscii());
size = e.firstChildElement("size").text().toULongLong();
verification.load(e);
@@ -575,6 +575,22 @@
resources.clear();
}
+
+bool KGetMetalink::File::isValidNameAttribute() const
+{
+ if (name.isEmpty()) {
+ kError(5001) << "Name attribute of Metalink::File is empty.";
+ return false;
+ }
+
+ if (name.contains(QRegExp("$(\\.\\.?)?/")) || name.contains("/../") || name.endsWith("/..")) {
+ kError(5001) << "Name attribute of Metalink::File contains directory traversal directives:" << name;
+ return false;
+ }
+
+ return true;
+}
+
#ifdef HAVE_NEPOMUK
QHash<QUrl, Nepomuk::Variant> KGetMetalink::File::properties() const
{
@@ -584,13 +600,28 @@
bool KGetMetalink::Files::isValid() const
{
- bool isValid = !files.empty();
- foreach (const File &file, files)
- {
- isValid &= file.isValid();
+ if (files.isEmpty()) {
+ return false;
}
- return isValid;
+ QStringList fileNames;
+ foreach (const File &file, files) {
+ fileNames << file.name;
+ if (!file.isValid()) {
+ return false;
+ }
+ }
+
+ //The value of name must be unique for each file
+ while (!fileNames.isEmpty()) {
+ const QString fileName = fileNames.takeFirst();
+ if (fileNames.contains(fileName)) {
+ kError(5001) << "Metalink::File name" << fileName << "exists multiple times.";
+ return false;
+ }
+ }
+
+ return true;
}
void KGetMetalink::Files::load(const QDomElement &e)
@@ -751,7 +782,7 @@
for (QDomElement elem = filesElem.firstChildElement("file"); !elem.isNull(); elem = elem.nextSiblingElement("file")) {
File file;
- file.name = elem.attribute("name");
+ file.name = QUrl::fromPercentEncoding(elem.attribute("name").toAscii());
file.size = elem.firstChildElement("size").text().toULongLong();
file.data = parseCommonData(elem);