diff --git a/0001-BUG-337742-REVIEW-120431.-Fix-and-future-proof-secur.patch b/0001-BUG-337742-REVIEW-120431.-Fix-and-future-proof-secur.patch new file mode 100644 index 0000000..70e191d --- /dev/null +++ b/0001-BUG-337742-REVIEW-120431.-Fix-and-future-proof-secur.patch @@ -0,0 +1,361 @@ +From 61070476b491baa046c7c40722e0270a10d7d622 Mon Sep 17 00:00:00 2001 +From: Ian Wadham +Date: Fri, 10 Oct 2014 09:11:06 +1100 +Subject: [PATCH 1/1] BUG: 337742 REVIEW: 120431. Fix and future-proof security + in Dr Konqi. + +In July 2014, the bugs.kde.org database switched to v4.4.5 of Bugzilla +and cookies were no longer accepted, causing bug 337742. This patch uses +the new security system, based on tokens, and implements the future use +of passwords only, whenever Bugzilla changes to the announced v4.5.x. It +also avoids a crash in Dr K on Apple OS X when KCookieJar is not found. + +Forward port of review 120431 to plasma-workspace. + +REVIEW: 120876 +--- + drkonqi/bugzillaintegration/bugzillalib.cpp | 129 +++++++++++++++++---- + drkonqi/bugzillaintegration/bugzillalib.h | 16 +++ + .../reportassistantpages_bugzilla.cpp | 21 +++- + .../reportassistantpages_bugzilla.h | 2 + + 4 files changed, 144 insertions(+), 24 deletions(-) + +diff --git a/drkonqi/bugzillaintegration/bugzillalib.cpp b/drkonqi/bugzillaintegration/bugzillalib.cpp +index 8fd8399baab804a2a6ef839435c604edda90c1a5..54fca48a99146b3be78f4abe88a58d07ab416446 100644 +--- a/drkonqi/bugzillaintegration/bugzillalib.cpp ++++ b/drkonqi/bugzillaintegration/bugzillalib.cpp +@@ -20,6 +20,7 @@ + + #include "bugzillalib.h" + ++#include + #include + #include + #include +@@ -33,6 +34,7 @@ + #include + #include + ++#define MAKE_BUGZILLA_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c)) + + static const char columns[] = "bug_severity,priority,bug_status,product,short_desc,resolution"; + +@@ -62,23 +64,110 @@ BugzillaManager::BugzillaManager(const QString &bugTrackerUrl, QObject *parent) + { + m_xmlRpcClient = new KXmlRpc::Client(QUrl(m_bugTrackerUrl + "xmlrpc.cgi"), this); + m_xmlRpcClient->setUserAgent(QLatin1String("DrKonqi")); ++ // Allow constructors for ReportInterface and assistant dialogs to finish. ++ // We do not want them to be racing the remote Bugzilla database. ++ QMetaObject::invokeMethod (this, "lookupVersion", Qt::QueuedConnection); + } + ++// BEGIN Checks of Bugzilla software versions. ++void BugzillaManager::lookupVersion() ++{ ++ QMap args; ++ callBugzilla("Bugzilla.version", "version", args, SecurityDisabled); ++} ++ ++void BugzillaManager::setFeaturesForVersion(const QString& version) ++{ ++ // A procedure to change Dr Konqi behaviour automatically when Bugzilla ++ // software versions change. ++ // ++ // Changes should be added to Dr Konqi AHEAD of when the corresponding ++ // Bugzilla software changes are released into bugs.kde.org, so that ++ // Dr Konqi can continue to operate smoothly, without bug reports and a ++ // reactive KDE software release. ++ // ++ // If Bugzilla announces a change to its software that affects Dr Konqi, ++ // add executable code to implement the change automatically when the ++ // Bugzilla software version changes. It goes at the end of this procedure ++ // and elsewhere in this class (BugzillaManager) and/or other classes where ++ // the change should actually be implemented. ++ ++ const int nVersionParts = 3; ++ QString seps = QLatin1String("[._-]"); ++ QStringList digits = version.split(QRegExp(seps), QString::SkipEmptyParts); ++ while (digits.count() < nVersionParts) { ++ digits << QLatin1String("0"); ++ } ++ if (digits.count() > nVersionParts) { ++ qWarning() << QString("Current Bugzilla version %1 has more than %2 parts. Check that this is not a problem.").arg(version).arg(nVersionParts); ++ } ++ int currentVersion = MAKE_BUGZILLA_VERSION(digits.at(0).toUInt(), ++ digits.at(1).toUInt(), digits.at(2).toUInt()); ++ ++ // Set the code(s) for historical versions of Bugzilla - before any change. ++ m_security = UseCookies; // Used to have cookies for update-security. ++ ++ if (currentVersion >= MAKE_BUGZILLA_VERSION(4, 4, 3)) { ++ // Security method changes from cookies to tokens in v4.4.3. ++ m_security = UseTokens; ++ } ++ if (currentVersion >= MAKE_BUGZILLA_VERSION(4, 5, 0)) { ++ // Security method changes from tokens to password-only in v4.5.x. ++ m_security = UsePasswords; ++ } ++ ++ qDebug() << "VERSION" << version << "SECURITY" << m_security; ++} ++// END Checks of Bugzilla software versions. ++ ++// BEGIN Generic remote-procedure (RPC) call to Bugzilla ++void BugzillaManager::callBugzilla(const char* method, const char* id, ++ QMap& args, ++ SecurityStatus security) ++{ ++ if (security == SecurityEnabled) { ++ switch (m_security) { ++ case UseTokens: ++ qDebug() << method << id << "using token"; ++ args.insert(QLatin1String("Bugzilla_token"), m_token); ++ break; ++ case UsePasswords: ++ qDebug() << method << id << "using username" << m_username; ++ args.insert(QLatin1String("Bugzilla_login"), m_username); ++ args.insert(QLatin1String("Bugzilla_password"), m_password); ++ break; ++ case UseCookies: ++ qDebug() << method << id << "using cookies"; ++ // Some KDE process other than Dr Konqi should provide cookies. ++ break; ++ } ++ } ++ ++ m_xmlRpcClient->call(QLatin1String(method), args, ++ this, SLOT(callMessage(QList,QVariant)), ++ this, SLOT(callFault(int,QString,QVariant)), ++ QString::fromAscii(id)); ++} ++// END Generic call to Bugzilla ++ + //BEGIN Login methods + void BugzillaManager::tryLogin(const QString& username, const QString& password) + { + m_username = username; ++ if (m_security == UsePasswords) { ++ m_password = password; ++ } + m_logged = false; + + QMap args; + args.insert(QLatin1String("login"), username); + args.insert(QLatin1String("password"), password); +- args.insert(QLatin1String("remember"), false); ++ if (m_security == UseCookies) { ++ // Removed in Bugzilla 4.4.3 software, which no longer issues cookies. ++ args.insert(QLatin1String("remember"), false); ++ } + +- m_xmlRpcClient->call(QLatin1String("User.login"), args, +- this, SLOT(callMessage(QList,QVariant)), +- this, SLOT(callFault(int,QString,QVariant)), +- QString::fromAscii("login")); ++ callBugzilla("User.login", "login", args, SecurityDisabled); + } + + bool BugzillaManager::getLogged() const +@@ -147,10 +236,7 @@ void BugzillaManager::sendReport(const BugReport & report) + args.insert(QLatin1String("priority"), report.priority()); + args.insert(QLatin1String("severity"), report.bugSeverity()); + +- m_xmlRpcClient->call(QLatin1String("Bug.create"), args, +- this, SLOT(callMessage(QList,QVariant)), +- this, SLOT(callFault(int,QString,QVariant)), +- QString::fromAscii("Bug.create")); ++ callBugzilla("Bug.create", "Bug.create", args, SecurityEnabled); + } + + void BugzillaManager::attachTextToReport(const QString & text, const QString & filename, +@@ -166,10 +252,8 @@ void BugzillaManager::attachTextToReport(const QString & text, const QString & f + //data needs to be a QByteArray so that it is encoded in base64 (query.cpp:246) + args.insert(QLatin1String("data"), text.toUtf8()); + +- m_xmlRpcClient->call(QLatin1String("Bug.add_attachment"), args, +- this, SLOT(callMessage(QList,QVariant)), +- this, SLOT(callFault(int,QString,QVariant)), +- QString::fromAscii("Bug.add_attachment")); ++ callBugzilla("Bug.add_attachment", "Bug.add_attachment", args, ++ SecurityEnabled); + } + + void BugzillaManager::addMeToCC(int bugId) +@@ -181,10 +265,7 @@ void BugzillaManager::addMeToCC(int bugId) + ccChanges.insert(QLatin1String("add"), QVariantList() << m_username); + args.insert(QLatin1String("cc"), ccChanges); + +- m_xmlRpcClient->call(QLatin1String("Bug.update"), args, +- this, SLOT(callMessage(QList,QVariant)), +- this, SLOT(callFault(int,QString,QVariant)), +- QString::fromAscii("Bug.update.cc")); ++ callBugzilla("Bug.update", "Bug.update.cc", args, SecurityEnabled); + } + + void BugzillaManager::fetchProductInfo(const QString & product) +@@ -199,10 +280,7 @@ void BugzillaManager::fetchProductInfo(const QString & product) + + args.insert("include_fields", includeFields) ; + +- m_xmlRpcClient->call(QLatin1String("Product.get"), args, +- this, SLOT(callMessage(QList,QVariant)), +- this, SLOT(callFault(int,QString,QVariant)), +- QString::fromAscii("Product.get.versions")); ++ callBugzilla("Product.get", "Product.get.versions", args, SecurityDisabled); + } + + +@@ -333,6 +411,10 @@ void BugzillaManager::callMessage(const QList & result, const QVariant + qDebug() << id << result; + + if (id.toString() == QLatin1String("login")) { ++ if ((m_security == UseTokens) && (result.count() > 0)) { ++ QVariantMap map = result.at(0).toMap(); ++ m_token = map.value(QLatin1String("token")).toString(); ++ } + m_logged = true; + Q_EMIT loginFinished(true); + } else if (id.toString() == QLatin1String("Product.get.versions")) { +@@ -359,6 +441,11 @@ void BugzillaManager::callMessage(const QList & result, const QVariant + int bug_id = map.value(QLatin1String("id")).toInt(); + Q_ASSERT(bug_id != 0); + Q_EMIT addMeToCCFinished(bug_id); ++ } else if (id.toString() == QLatin1String("version")) { ++ QVariantMap map = result.at(0).toMap(); ++ QString bugzillaVersion = map.value(QLatin1String("version")).toString(); ++ setFeaturesForVersion(bugzillaVersion); ++ Q_EMIT bugzillaVersionFound(); + } + } + +diff --git a/drkonqi/bugzillaintegration/bugzillalib.h b/drkonqi/bugzillaintegration/bugzillalib.h +index 570169bb6afc5b124a6c7866dbb5bf30ba61cf41..481805cb31799d50c071feaec78101317b488d93 100644 +--- a/drkonqi/bugzillaintegration/bugzillalib.h ++++ b/drkonqi/bugzillaintegration/bugzillalib.h +@@ -387,12 +387,18 @@ public: + + void stopCurrentSearch(); + ++ /* Codes for security methods used by Bugzilla in various versions. */ ++ enum SecurityMethod {UseCookies, UseTokens, UsePasswords}; ++ SecurityMethod securityMethod() { return m_security; }; ++ + private Q_SLOTS: + /* Slots to handle KJob::finished */ + void fetchBugJobFinished(KJob*); + void searchBugsJobFinished(KJob*); + void fetchProductInfoFinished(const QVariantMap&); + ++ void lookupVersion(); ++ + void callMessage(const QList & result, const QVariant & id); + void callFault(int errorCode, const QString & errorString, const QVariant &id); + +@@ -405,6 +411,7 @@ Q_SIGNALS: + void attachToReportSent(int); + void addMeToCCFinished(int); + void productInfoFetched(Product); ++ void bugzillaVersionFound(); + + /* Bugzilla actions had errors */ + void loginError(const QString & errorMsg, const QString & extendedErrorMsg = QString()); +@@ -419,10 +426,19 @@ Q_SIGNALS: + private: + QString m_bugTrackerUrl; + QString m_username; ++ QString m_token; ++ QString m_password; + bool m_logged; ++ SecurityMethod m_security; + + KIO::Job * m_searchJob; + KXmlRpc::Client *m_xmlRpcClient; ++ ++ enum SecurityStatus {SecurityDisabled, SecurityEnabled}; ++ void callBugzilla(const char* method, const char* id, ++ QMap& args, ++ SecurityStatus security); ++ void setFeaturesForVersion(const QString& version); + }; + + #endif +diff --git a/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.cpp b/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.cpp +index 5a6096f1483950ba6c9e037c7c4c5068a5382e82..3a25b44757027ecebf4687b4e96fcedf20c24cb7 100644 +--- a/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.cpp ++++ b/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.cpp +@@ -66,8 +66,10 @@ static const char konquerorKWalletEntryPassword[] = "Bugzilla_password"; + + BugzillaLoginPage::BugzillaLoginPage(ReportAssistantDialog * parent) : + ReportAssistantPage(parent), +- m_wallet(0), m_walletWasOpenedBefore(false) ++ m_wallet(0), m_walletWasOpenedBefore(false), ++ m_bugzillaVersionFound(false) + { ++ connect(bugzillaManager(), SIGNAL(bugzillaVersionFound()), this, SLOT(bugzillaVersionFound())); + connect(bugzillaManager(), SIGNAL(loginFinished(bool)), this, SLOT(loginFinished(bool))); + connect(bugzillaManager(), SIGNAL(loginError(QString,QString)), this, SLOT(loginError(QString,QString))); + +@@ -107,10 +109,18 @@ bool BugzillaLoginPage::isComplete() + return bugzillaManager()->getLogged(); + } + ++void BugzillaLoginPage::bugzillaVersionFound() ++{ ++ // Login depends on first knowing the Bugzilla software version number. ++ m_bugzillaVersionFound = true; ++ updateLoginButtonStatus(); ++} ++ + void BugzillaLoginPage::updateLoginButtonStatus() + { + ui.m_loginButton->setEnabled( !ui.m_userEdit->text().isEmpty() && +- !ui.m_passwordEdit->text().isEmpty() ); ++ !ui.m_passwordEdit->text().isEmpty() && ++ m_bugzillaVersionFound ); + } + + void BugzillaLoginPage::loginError(const QString & err, const QString & extendedMessage) +@@ -223,6 +233,10 @@ void BugzillaLoginPage::walletLogin() + + bool BugzillaLoginPage::canSetCookies() + { ++ if (bugzillaManager()->securityMethod() != BugzillaManager::UseCookies) { ++ qDebug() << "Bugzilla software no longer issues cookies."; ++ return false; ++ } + QDBusInterface kded(QLatin1String("org.kde.kded5"), + QLatin1String("/kded"), + QLatin1String("org.kde.kded5")); +@@ -285,7 +299,8 @@ void BugzillaLoginPage::loginClicked() + { + if (!(ui.m_userEdit->text().isEmpty() || ui.m_passwordEdit->text().isEmpty())) { + +- if (!canSetCookies()) { ++ if ((bugzillaManager()->securityMethod() == BugzillaManager::UseCookies) ++ && (!canSetCookies())) { + return; + } + +diff --git a/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.h b/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.h +index 50cf05f5ce724984e9900ca111533aec75c08cbe..da2d39f88f9aa6e69784e35e29ee06ab44b66c76 100644 +--- a/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.h ++++ b/drkonqi/bugzillaintegration/reportassistantpages_bugzilla.h +@@ -45,6 +45,7 @@ public: + bool isComplete(); + + private Q_SLOTS: ++ void bugzillaVersionFound(); + void loginClicked(); + void loginFinished(bool); + void loginError(const QString &, const QString &); +@@ -65,6 +66,7 @@ private: + + KWallet::Wallet * m_wallet; + bool m_walletWasOpenedBefore; ++ bool m_bugzillaVersionFound; + }; + + /** Title and details page **/ +-- +2.1.3 + diff --git a/plasma5-workspace.changes b/plasma5-workspace.changes index a8f655c..e207011 100644 --- a/plasma5-workspace.changes +++ b/plasma5-workspace.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Nov 12 19:12:25 UTC 2014 - hrvoje.senjan@gmail.com + +- Added 0001-BUG-337742-REVIEW-120431.-Fix-and-future-proof-secur.patch + from upstream (kde#337742) + ------------------------------------------------------------------- Thu Nov 6 20:14:21 UTC 2014 - hrvoje.senjan@gmail.com diff --git a/plasma5-workspace.spec b/plasma5-workspace.spec index f0d76f6..e75a4a8 100644 --- a/plasma5-workspace.spec +++ b/plasma5-workspace.spec @@ -33,6 +33,8 @@ Patch1: create_kdehome.patch # PATCH-FIX_OPENSUSE 0003-Remove-export-of-QT_PLUGIN_PATH.patch -- we install plugins to directory known to Qt5, so export just pollutes both Qt4 and Qt5 plugins Patch2: 0003-Remove-export-of-QT_PLUGIN_PATH.patch # PATCHES 100-1000 and above are from upstream 5.1 branch +# PATCH-FIX-UPSTREAM 0001-BUG-337742-REVIEW-120431.-Fix-and-future-proof-secur.patch +Patch100: 0001-BUG-337742-REVIEW-120431.-Fix-and-future-proof-secur.patch # PATCHES 1000 and above are from upstream master/5.2 branch # PATCH-FIX-UPSTREAM 0001-LocationRunner-Convert-case-insensitive-path-to-a-pr.patch -- kde#333395 Patch1000: 0001-LocationRunner-Convert-case-insensitive-path-to-a-pr.patch @@ -182,6 +184,7 @@ workspace. Development files. %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch100 -p1 %patch1000 -p1 %patch1001 -p1