Merge branch 'libplasma2_signedpackages' into libplasma2
Conflicts: plasma/package.cpp
This commit is contained in:
commit
cd32321b68
@ -47,6 +47,11 @@ if(QCA2_FOUND)
|
||||
endif(QCA2_FOUND)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-plasma.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-plasma.h)
|
||||
|
||||
#FIXME: gpgme++ is in kdepimlibs, must move somewhere else!
|
||||
macro_optional_find_package(KdepimLibs 4.5.60)
|
||||
macro_log_feature(KDEPIMLIBS_FOUND "kdepimlibs" "KDE PIM libraries" "http://www.kde.org" FALSE "" "Needed for building several Plasma DataEngines")
|
||||
include_directories(${KDEPIMLIBS_INCLUDE_DIRS})
|
||||
|
||||
add_subdirectory(tests)
|
||||
add_definitions(-DKDE_DEFAULT_DEBUG_AREA=1209)
|
||||
|
||||
@ -109,7 +114,6 @@ set(plasma_LIB_SRCS
|
||||
private/dataenginebindings.cpp
|
||||
private/dataengineconsumer.cpp
|
||||
private/dataengineservice.cpp
|
||||
private/denyallauthorization.cpp
|
||||
private/effectwatcher.cpp
|
||||
private/extenderapplet.cpp
|
||||
private/extenderitemmimedata.cpp
|
||||
@ -117,8 +121,6 @@ set(plasma_LIB_SRCS
|
||||
private/getsource.cpp
|
||||
private/nativetabbar.cpp
|
||||
private/packages.cpp
|
||||
private/pinpairingauthorization.cpp
|
||||
private/pinpairingdialog.cpp
|
||||
private/plasmoidservice.cpp
|
||||
private/remotedataengine.cpp
|
||||
private/remoteservice.cpp
|
||||
@ -128,7 +130,6 @@ set(plasma_LIB_SRCS
|
||||
private/storage.cpp
|
||||
private/storagethread.cpp
|
||||
private/style.cpp
|
||||
private/trustedonlyauthorization.cpp
|
||||
private/tooltip.cpp
|
||||
private/wallpaperrenderthread.cpp
|
||||
private/windowpreview.cpp
|
||||
@ -144,7 +145,12 @@ set(plasma_LIB_SRCS
|
||||
remote/authorizationrule.cpp
|
||||
remote/clientpinrequest.cpp
|
||||
remote/credentials.cpp
|
||||
remote/denyallauthorization.cpp
|
||||
remote/pinpairingauthorization.cpp
|
||||
remote/pinpairingdialog.cpp
|
||||
remote/serviceaccessjob.cpp
|
||||
remote/signing.cpp
|
||||
remote/trustedonlyauthorization.cpp
|
||||
runnercontext.cpp
|
||||
runnermanager.cpp
|
||||
runnersyntax.cpp
|
||||
@ -209,7 +215,7 @@ set(plasma_LIB_SRCS
|
||||
kde4_add_kcfg_files(plasma_LIB_SRCS data/kconfigxt/libplasma-theme-global.kcfgc)
|
||||
|
||||
kde4_add_ui_files(plasma_LIB_SRCS
|
||||
private/pinpairing.ui
|
||||
remote/pinpairing.ui
|
||||
private/publish.ui)
|
||||
#NEPOMUK_GENERATE_FROM_ONTOLOGY(
|
||||
# nwc.nrl
|
||||
@ -232,6 +238,8 @@ kde4_add_library(plasma ${LIBRARY_TYPE} ${plasma_LIB_SRCS})
|
||||
target_link_libraries(plasma ${QT_QTUITOOLS_LIBRARY} ${QT_QTWEBKIT_LIBRARY}
|
||||
${QT_QTSCRIPT_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSQL_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}
|
||||
${KDE4_KDEUI_LIBS} kdnssd threadweaver kdeclarative ${PLASMA_EXTRA_LIBS})
|
||||
#FIXME gpgme++ is in kdepimlibs, neeeds to be elsewhere
|
||||
target_link_libraries(plasma ${KDEPIMLIBS_GPGMEPP_LIBS})
|
||||
|
||||
if(QCA2_FOUND)
|
||||
target_link_libraries(plasma ${QCA2_LIBRARIES})
|
||||
|
@ -70,7 +70,6 @@
|
||||
#endif
|
||||
|
||||
#include "abstracttoolbox.h"
|
||||
#include "authorizationmanager.h"
|
||||
#include "authorizationrule.h"
|
||||
#include "configloader.h"
|
||||
#include "containment.h"
|
||||
@ -88,6 +87,8 @@
|
||||
#include "private/applethandle_p.h"
|
||||
#include "private/extenderitem_p.h"
|
||||
#include "private/framesvg_p.h"
|
||||
#include "remote/authorizationmanager.h"
|
||||
#include "remote/authorizationmanager_p.h"
|
||||
#include "theme.h"
|
||||
#include "view.h"
|
||||
#include "widgets/iconwidget.h"
|
||||
@ -101,7 +102,6 @@
|
||||
#include "pluginloader.h"
|
||||
|
||||
#include "private/associatedapplicationmanager_p.h"
|
||||
#include "private/authorizationmanager_p.h"
|
||||
#include "private/containment_p.h"
|
||||
#include "private/extenderapplet_p.h"
|
||||
#include "private/package_p.h"
|
||||
|
@ -32,13 +32,13 @@
|
||||
#include <kservice.h>
|
||||
#include <kstandarddirs.h>
|
||||
|
||||
#include "authorizationmanager.h"
|
||||
#include "datacontainer.h"
|
||||
#include "package.h"
|
||||
#include "remote/authorizationmanager.h"
|
||||
#include "remote/authorizationmanager_p.h"
|
||||
#include "service.h"
|
||||
#include "scripting/dataenginescript.h"
|
||||
|
||||
#include "private/authorizationmanager_p.h"
|
||||
#include "private/dataengineservice_p.h"
|
||||
#include "private/remotedataengine_p.h"
|
||||
#include "private/service_p.h"
|
||||
|
@ -44,12 +44,12 @@
|
||||
#include <kzip.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "authorizationmanager.h"
|
||||
#include "packagemetadata.h"
|
||||
#include "private/authorizationmanager_p.h"
|
||||
#include "private/package_p.h"
|
||||
#include "private/plasmoidservice_p.h"
|
||||
#include "private/service_p.h"
|
||||
#include "remote/authorizationmanager.h"
|
||||
#include "remote/authorizationmanager_p.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
15
plasma.h
15
plasma.h
@ -272,14 +272,19 @@ enum AnnouncementMethod {
|
||||
Q_DECLARE_FLAGS(AnnouncementMethods, AnnouncementMethod)
|
||||
|
||||
enum TrustLevel {
|
||||
InvalidCredentials = 0, /**< The credentials are invalid **/
|
||||
UnknownCredentials = 1, /**< The credentials are unknown **/
|
||||
ValidCredentials = 2, /**< The credentials are valid **/
|
||||
TrustedCredentials = 3, /**< The credentials are trusted **/
|
||||
UltimateCredentials = 4 /**< The ultimate trust level applies to the credentials **/
|
||||
UnverifiableTrust = 0, /**< The trust of the object can not be verified, usually because no
|
||||
trust information (e.g. a cryptographic signature) was provided */
|
||||
CompletelyUntrusted, /**< The signature is broken/expired/false */
|
||||
UnknownTrusted, /**< The signature is valid, but the key is unknown */
|
||||
UserTrusted, /**< The signature is valid and made with a key signed by one of the
|
||||
user's own keys*/
|
||||
SelfTrusted, /**< The signature is valid and made with one of the user's own keys*/
|
||||
FullyTrusted, /**< The signature is valid and made with a key signed by the vendor's key*/
|
||||
UltimatelyTrusted /**< The signature is valid and made with the vendor's key*/
|
||||
};
|
||||
Q_ENUMS(TrustLevel)
|
||||
|
||||
|
||||
/**
|
||||
* @return the scaling factor (0..1) for a ZoomLevel
|
||||
**/
|
||||
|
@ -21,9 +21,9 @@
|
||||
#include "private/accessmanager_p.h"
|
||||
|
||||
#include "authorizationmanager.h"
|
||||
#include "authorizationmanager_p.h"
|
||||
#include "service.h"
|
||||
#include "serviceaccessjob.h"
|
||||
#include "private/authorizationmanager_p.h"
|
||||
|
||||
#include "config-plasma.h"
|
||||
|
||||
|
@ -18,19 +18,19 @@
|
||||
*/
|
||||
|
||||
#include "authorizationmanager.h"
|
||||
#include "private/authorizationmanager_p.h"
|
||||
#include "authorizationmanager_p.h"
|
||||
|
||||
#include "authorizationinterface.h"
|
||||
#include "authorizationrule.h"
|
||||
#include "authorizationrule_p.h"
|
||||
#include "denyallauthorization_p.h"
|
||||
#include "credentials.h"
|
||||
#include "pinpairingauthorization_p.h"
|
||||
#include "service.h"
|
||||
#include "servicejob.h"
|
||||
#include "trustedonlyauthorization_p.h"
|
||||
|
||||
#include "private/authorizationrule_p.h"
|
||||
#include "private/denyallauthorization_p.h"
|
||||
#include "private/joliemessagehelper_p.h"
|
||||
#include "private/pinpairingauthorization_p.h"
|
||||
#include "private/trustedonlyauthorization_p.h"
|
||||
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QMap>
|
||||
|
@ -20,9 +20,9 @@
|
||||
#include "authorizationrule.h"
|
||||
|
||||
#include "authorizationmanager.h"
|
||||
#include "authorizationmanager_p.h"
|
||||
#include "authorizationrule_p.h"
|
||||
#include "credentials.h"
|
||||
#include "private/authorizationmanager_p.h"
|
||||
#include "private/authorizationrule_p.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QTimer>
|
||||
|
@ -133,7 +133,7 @@ TrustLevel Credentials::trustLevel() const
|
||||
}
|
||||
*/
|
||||
//Trust no one ;)
|
||||
return ValidCredentials;
|
||||
return UnknownTrusted;
|
||||
}
|
||||
|
||||
bool Credentials::isValid() const
|
||||
|
@ -49,7 +49,7 @@ void PinPairingAuthorization::clientPinRequest(ClientPinRequest &request)
|
||||
void PinPairingAuthorization::authorizationRequest(AuthorizationRule &rule)
|
||||
{
|
||||
kDebug();
|
||||
if (rule.credentials().trustLevel() > TrustedCredentials) {
|
||||
if (rule.credentials().trustLevel() > UnknownTrusted) {
|
||||
rule.setPolicy(AuthorizationRule::Allow);
|
||||
rule.setTargets(AuthorizationRule::AllServices);
|
||||
} else {
|
615
remote/signing.cpp
Normal file
615
remote/signing.cpp
Normal file
@ -0,0 +1,615 @@
|
||||
/*
|
||||
* Copyright (C) 2010 by Diego '[Po]lentino' Casella <polentino911@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "signing.h"
|
||||
#include "signing_p.h"
|
||||
|
||||
#include <gpgme.h>
|
||||
#include <gpgme++/gpgmefw.h>
|
||||
#include <gpgme++/global.h>
|
||||
#include <gpgme++/context.h>
|
||||
#include <gpgme++/error.h>
|
||||
#include <gpgme++/engineinfo.h>
|
||||
#include <gpgme++/key.h>
|
||||
#include <gpgme++/keylistresult.h>
|
||||
#include <gpgme++/keygenerationresult.h>
|
||||
#include <gpgme++/importresult.h>
|
||||
#include <gpgme++/data.h>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <kdirwatch.h>
|
||||
#include <kdebug.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kprocess.h>
|
||||
#include <kuser.h>
|
||||
|
||||
#include "plasma/package.h"
|
||||
|
||||
#include <cstdio> // FILE
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
SigningPrivate::SigningPrivate(Signing *auth, const QString &path)
|
||||
: q(auth),
|
||||
m_keystorePath(path)
|
||||
{
|
||||
GpgME::initializeLibrary();
|
||||
GpgME::Error error = GpgME::checkEngine(GpgME::OpenPGP);
|
||||
if (error) {
|
||||
kDebug() << "OpenPGP engine not found: authentication will not work.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_gpgContext = GpgME::Context::createForProtocol(GpgME::OpenPGP);
|
||||
m_gpgContext->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS);
|
||||
|
||||
m_keystorePath = path;
|
||||
|
||||
if (m_keystorePath.isEmpty()) {
|
||||
// From the gpgme doc: if the homeDirectory() is null, it means we are using the standard dir,
|
||||
// that is "/home/$USER/.gnupg/ ; so let's retrieve it.
|
||||
KUser user;
|
||||
m_keystorePath.append(user.homeDir()).append("/.gnupg/");
|
||||
} else {
|
||||
error = m_gpgContext->setEngineHomeDirectory(m_keystorePath.toAscii().data());
|
||||
if (error) {
|
||||
kDebug() << "Failed setting custom gpg keystore directory: using default.";
|
||||
}
|
||||
}
|
||||
|
||||
m_keystoreDir = new KDirWatch();
|
||||
m_keystoreDir->addDir(m_keystorePath);
|
||||
m_keystoreDir->addDir(ultimateKeyStoragePath());
|
||||
m_keystoreDir->startScan(true);
|
||||
|
||||
// Start watching the keystore and the dir with the kde keys, and notify for changed
|
||||
q->connect(m_keystoreDir, SIGNAL(created(const QString &)), q, SLOT(processKeystore(const QString &)));
|
||||
q->connect(m_keystoreDir, SIGNAL(dirty(const QString &)), q, SLOT(keyAdded(const QString &)));
|
||||
q->connect(m_keystoreDir, SIGNAL(deleted(const QString &)), q, SLOT(keyRemoved(const QString &)));
|
||||
}
|
||||
|
||||
SigningPrivate::~SigningPrivate()
|
||||
{
|
||||
delete m_keystoreDir;
|
||||
}
|
||||
|
||||
QString SigningPrivate::ultimateKeyStoragePath() const
|
||||
{
|
||||
return KStandardDirs::installPath("data") + "plasmakeys/";
|
||||
}
|
||||
|
||||
void SigningPrivate::registerUltimateTrustKeys()
|
||||
{
|
||||
QSet<QByteArray> tmp;
|
||||
keys[UltimatelyTrusted] = tmp;
|
||||
|
||||
if (!m_gpgContext) {
|
||||
kDebug() << "GPGME context not valid: please re-initialize the library.";
|
||||
return;
|
||||
}
|
||||
|
||||
QString path = ultimateKeyStoragePath();
|
||||
QDir dir(path);
|
||||
if (!dir.exists() || path.isEmpty()) {
|
||||
kDebug() << "Directory with KDE keys not found: aborting";
|
||||
return;
|
||||
}
|
||||
|
||||
const QStringList keyFiles = dir.entryList(QDir::Files); // QDir::Files is rendundant in this stage
|
||||
|
||||
// Foreach file found, open it and import the key into the gpg keyring.
|
||||
// First avoid firing multiple entryWritten() signals
|
||||
m_keystoreDir->stopScan();
|
||||
|
||||
foreach (QString keyFile, keyFiles) {
|
||||
FILE *fp;
|
||||
fp = fopen(keyFile.toAscii().data(), "r");
|
||||
GpgME::Data data(fp);
|
||||
GpgME::ImportResult iRes = m_gpgContext->importKeys(data);
|
||||
if (iRes.error()) {
|
||||
kDebug() << "Error while importing the key located at: " << keyFile;
|
||||
kDebug() << " The error is:" << iRes.error().asString() << "; Skipping.";
|
||||
continue;
|
||||
}
|
||||
|
||||
// The first fingerprint listed is the one we need to save
|
||||
tmp.insert(iRes.import(0).fingerprint());
|
||||
}
|
||||
keys[UltimatelyTrusted] = tmp;
|
||||
|
||||
// Restore scanning folders
|
||||
m_keystoreDir->startScan(true, true);
|
||||
}
|
||||
|
||||
void SigningPrivate::splitKeysByTrustLevel()
|
||||
{
|
||||
if (!m_gpgContext) {
|
||||
kDebug() << "GPGME context not valid: please re-initialize the library.";
|
||||
return;
|
||||
}
|
||||
|
||||
QSet<QByteArray> temp = keys[UltimatelyTrusted];
|
||||
keys.clear();
|
||||
keys[UltimatelyTrusted] = temp;
|
||||
|
||||
// Splitting the keys by their trust level is a boring task, since we have to distinguish
|
||||
// `which key has been signed with an other given key` :P
|
||||
//
|
||||
// Loop 1: import and load the KDE keys, already done in registerUltimateTrustKeys()
|
||||
//
|
||||
// Loop 2: load the user keyring (private keys only), and loop for:
|
||||
// - a: a key not yet expired;
|
||||
// - b: a key not already present in the keys[UltimatelyTrusted];
|
||||
//
|
||||
// Loop 3: load the user keyring, and loop for:
|
||||
// - a: a key not yet expired;
|
||||
// - b: a key not already present in the keys[UltimatelyTrusted];
|
||||
// - c: a key not yet in keys[SelfTrusted]
|
||||
//
|
||||
// After Loop 3, the tmp object contains the remaining keys not yet processed.
|
||||
//
|
||||
// Loop 4: foreach key not yet classified, inspect their signatures and:
|
||||
// - a: if contains a key from keys[UltimatelyTrusted], save it in keys[FullyTrusted];
|
||||
// - b: if contains a key from keys[SelfTrusted], save it in keys[UserTrusted];
|
||||
// - c: if the signature is unknown, let's save it in keys[UnknownTrusted].
|
||||
QSet<QByteArray> tmp;
|
||||
|
||||
GpgME::Error error = m_gpgContext->startKeyListing("", true);
|
||||
while (!error) { // Loop 2
|
||||
GpgME::Key key = m_gpgContext->nextKey(error);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
||||
QByteArray data(key.subkey(0).fingerprint());
|
||||
|
||||
// If the key is disabled, expired, invalid or revoked, put it in the untrusted list
|
||||
if (key.isDisabled() || key.isExpired() || key.isInvalid() || key.isRevoked()) {
|
||||
keys[CompletelyUntrusted].insert(data);
|
||||
} else if (!keys[UltimatelyTrusted].contains(data)) {
|
||||
// Ensure we are not processing twice the trusted KDE keys
|
||||
// The keys is new, valid and private: save it !
|
||||
keys[SelfTrusted].insert(data);
|
||||
}
|
||||
}
|
||||
GpgME::KeyListResult lRes = m_gpgContext->endKeyListing();
|
||||
}
|
||||
|
||||
Plasma::TrustLevel SigningPrivate::addKeyToCache(const QByteArray &fingerprint)
|
||||
{
|
||||
if (!m_gpgContext) {
|
||||
kDebug() << "GPGME context not valid: please re-initialize the library.";
|
||||
return UnknownTrusted;
|
||||
}
|
||||
|
||||
GpgME::Error error;
|
||||
GpgME::Key key = m_gpgContext->key(fingerprint.data(), error);
|
||||
if (error) {
|
||||
keys[UnknownTrusted].insert(fingerprint);
|
||||
return UnknownTrusted;
|
||||
}
|
||||
|
||||
if (keys[UltimatelyTrusted].contains(fingerprint)) {
|
||||
return UltimatelyTrusted;
|
||||
} else if (keys[SelfTrusted].contains(fingerprint)) {
|
||||
return SelfTrusted;
|
||||
}
|
||||
|
||||
// If the key is disabled, expired, invalid or revoked, put it in the untrusted list
|
||||
if (key.isDisabled() || key.isExpired() || key.isInvalid() || key.isRevoked()) {
|
||||
keys[CompletelyUntrusted].insert(fingerprint);
|
||||
return CompletelyUntrusted;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < key.numUserIDs(); ++i) {
|
||||
foreach (const GpgME::UserID::Signature &signature, key.userID(i).signatures()) {
|
||||
if (keys[UltimatelyTrusted].contains(signature.signerKeyID())) {
|
||||
// if the unknown key has a signer that is a kde key, let's trust it
|
||||
keys[FullyTrusted].insert(fingerprint);
|
||||
return FullyTrusted;
|
||||
} else if (keys[SelfTrusted].contains(signature.signerKeyID())) {
|
||||
// if the unknown key has a signer that is a user key, let's trust it
|
||||
keys[UserTrusted].insert(fingerprint);
|
||||
return UserTrusted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't stored the unknown key in the previous loop, which means that we
|
||||
// don't know the hey al all.
|
||||
keys[UnknownTrusted].insert(fingerprint);
|
||||
return UnknownTrusted;
|
||||
}
|
||||
|
||||
void SigningPrivate::dumpKeysToDebug()
|
||||
{
|
||||
kDebug() << "UltimatelyTrusted = " << keys[UltimatelyTrusted];
|
||||
kDebug() << "FullyTrusted = " << keys[FullyTrusted];
|
||||
kDebug() << "SelfTrusted = " << keys[SelfTrusted];
|
||||
kDebug() << "UserTrusted = " << keys[UserTrusted];
|
||||
kDebug() << "UnknownTrusted = " << keys[UnknownTrusted];
|
||||
kDebug() << "CompletelyUntrusted = " << keys[CompletelyUntrusted];
|
||||
}
|
||||
|
||||
QStringList SigningPrivate::keysID(const bool returnPrivate) const
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
if (!m_gpgContext) {
|
||||
kDebug() << "GPGME context not valid: please re-initialize the library.";
|
||||
return result;
|
||||
}
|
||||
|
||||
GpgME::Error error = m_gpgContext->startKeyListing("", returnPrivate);
|
||||
while (!error) {
|
||||
GpgME::Key k = m_gpgContext->nextKey(error);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
||||
result.append(k.subkey(0).fingerprint());
|
||||
}
|
||||
GpgME::KeyListResult lRes = m_gpgContext->endKeyListing();
|
||||
if (lRes.error()) {
|
||||
kDebug() << "Error while ending the keyListing operation: " << lRes.error().asString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SigningPrivate::processKeystore(const QString &path)
|
||||
{
|
||||
if (path != m_keystorePath) {
|
||||
registerUltimateTrustKeys();
|
||||
return;
|
||||
}
|
||||
|
||||
QSet<QByteArray> oldValues;
|
||||
oldValues += keys[UnverifiableTrust];
|
||||
oldValues += keys[CompletelyUntrusted];
|
||||
oldValues += keys[UnknownTrusted];
|
||||
oldValues += keys[SelfTrusted];
|
||||
oldValues += keys[FullyTrusted];
|
||||
oldValues += keys[UltimatelyTrusted];
|
||||
|
||||
splitKeysByTrustLevel();
|
||||
|
||||
QSet<QByteArray> newValues;
|
||||
newValues += keys[UnverifiableTrust];
|
||||
newValues += keys[CompletelyUntrusted];
|
||||
newValues += keys[UnknownTrusted];
|
||||
newValues += keys[SelfTrusted];
|
||||
newValues += keys[FullyTrusted];
|
||||
newValues += keys[UltimatelyTrusted];
|
||||
|
||||
QString result;
|
||||
bool keystoreIncreased = (newValues.size() >= oldValues.size());
|
||||
if (keystoreIncreased) {
|
||||
foreach (QByteArray value, newValues) {
|
||||
if (!oldValues.contains(value)) {
|
||||
// Found the key added
|
||||
result.append(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach (QByteArray value, oldValues) {
|
||||
if (!newValues.contains(value)) {
|
||||
// Found the removed key
|
||||
result.append(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
if (keystoreIncreased) {
|
||||
emit q->keyAdded(result);
|
||||
} else {
|
||||
emit q->keyRemoved(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SigningPrivate::keyAdded(const QString &path)
|
||||
{
|
||||
if (path == m_keystorePath) {
|
||||
// we don't worry about keys added to the key store path,
|
||||
// just the ultimate store dir
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid firing multiple signals by kdirwatch instances
|
||||
m_keystoreDir->stopScan();
|
||||
|
||||
FILE *fp;
|
||||
fp = fopen(path.toAscii().data(), "r");
|
||||
GpgME::Data data(fp);
|
||||
GpgME::ImportResult iRes = m_gpgContext->importKeys(data);
|
||||
|
||||
bool alreadyInMap = false;
|
||||
|
||||
// Ensure we don't already have the key
|
||||
foreach (QByteArray sec, keys[UltimatelyTrusted]) {
|
||||
if (strcmp(sec.data(), iRes.import(0).fingerprint())) {
|
||||
alreadyInMap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyInMap) {
|
||||
keys[UltimatelyTrusted] << QByteArray(iRes.import(0).fingerprint());
|
||||
splitKeysByTrustLevel();
|
||||
}
|
||||
|
||||
// Restore scanning folders
|
||||
m_keystoreDir->startScan(true, true);
|
||||
|
||||
QString result(iRes.import(0).fingerprint());
|
||||
emit(q->keyAdded(result));
|
||||
}
|
||||
|
||||
void SigningPrivate::keyRemoved(const QString &path)
|
||||
{
|
||||
// Avoid firing multiple signals by kdirwatch instances
|
||||
m_keystoreDir->stopScan();
|
||||
|
||||
if (path == m_keystorePath) {
|
||||
// Restore scanning folders
|
||||
m_keystoreDir->startScan(true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
QSet<QByteArray> oldKeys = keys[UltimatelyTrusted];
|
||||
registerUltimateTrustKeys();
|
||||
QSet<QByteArray> newkeys = keys[UltimatelyTrusted];
|
||||
|
||||
QString result;
|
||||
foreach (QByteArray key, oldKeys) {
|
||||
if (!newkeys.contains(key)) {
|
||||
// We found the missing key :)
|
||||
result.append(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GpgME::Error error = m_gpgContext->startKeyListing("");
|
||||
while (!error) {
|
||||
GpgME::Key k = m_gpgContext->nextKey(error);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.contains(k.subkey(0).fingerprint())) {
|
||||
error = m_gpgContext->startKeyDeletion(k, true); // GG
|
||||
|
||||
if (error) {
|
||||
kDebug() << "Can't delete key with fingerprint: " << result;
|
||||
m_gpgContext->endKeyListing();
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
GpgME::KeyListResult lRes = m_gpgContext->endKeyListing();
|
||||
if (lRes.error()) {
|
||||
kDebug() << "Error while ending the keyListing operation: " << lRes.error().asString();
|
||||
}
|
||||
|
||||
splitKeysByTrustLevel();
|
||||
|
||||
// Restore scanning folders
|
||||
m_keystoreDir->startScan(true, true);
|
||||
|
||||
emit(q->keyRemoved(result));
|
||||
}
|
||||
|
||||
QStringList SigningPrivate::signersOf(const QString id) const
|
||||
{
|
||||
QStringList result;
|
||||
GpgME::Error error;
|
||||
GpgME::Key key = m_gpgContext->key(id.toAscii().data(), error);
|
||||
|
||||
if (!error) {
|
||||
for (unsigned int i = 0; i < key.numUserIDs(); ++i) {
|
||||
foreach (const GpgME::UserID::Signature &signature, key.userID(i).signatures()) {
|
||||
QString sig(signature.signerKeyID());
|
||||
if (!result.contains(sig) && id != sig) {
|
||||
result.append(sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//kDebug() << "Hey, the key " << id << " has been signed with " << result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Signing::Signing(const QString &keystorePath)
|
||||
: QObject(),
|
||||
d(new SigningPrivate(this, keystorePath))
|
||||
{
|
||||
d->registerUltimateTrustKeys();
|
||||
d->splitKeysByTrustLevel();
|
||||
}
|
||||
|
||||
Signing::~Signing()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
QStringList Signing::keysByTrustLevel(TrustLevel trustLevel) const
|
||||
{
|
||||
if (trustLevel == UnverifiableTrust) {
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QSet<QByteArray> s = d->keys[trustLevel];
|
||||
QStringList tmp;
|
||||
foreach (const QByteArray &sa, s) {
|
||||
tmp.append(sa);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TrustLevel Signing::trustLevelOf(const QString &keyID) const
|
||||
{
|
||||
if (keyID.isEmpty()) {
|
||||
return Plasma::UnverifiableTrust;
|
||||
}
|
||||
|
||||
for (int i = (int)Plasma::UnverifiableTrust; i <= (int)Plasma::UltimatelyTrusted; ++i) {
|
||||
QSet<QByteArray> tmp = d->keys[(Plasma::TrustLevel)i];
|
||||
foreach (QByteArray key, tmp) {
|
||||
if (key.contains(keyID.toAscii().data())) {
|
||||
return (Plasma::TrustLevel)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return d->addKeyToCache(keyID.toAscii());
|
||||
}
|
||||
|
||||
QString Signing::signerOf(const Package &package) const
|
||||
{
|
||||
const QString contents = package.path() + "CONTENTS";
|
||||
|
||||
if (!QFile::exists(contents)) {
|
||||
kDebug() << "not contents hash for package at" << package.path();
|
||||
return QString();
|
||||
}
|
||||
|
||||
QFile file(contents);
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
kDebug() << "could not open hash file for reading" << contents;
|
||||
return QString();
|
||||
}
|
||||
|
||||
const QByteArray hash = file.read(10 * 1024);
|
||||
const QString actualHash = package.contentsHash();
|
||||
if (actualHash != hash) {
|
||||
kDebug() << "CONTENTS does not match contents of package" << package.path();
|
||||
return QString();
|
||||
}
|
||||
|
||||
return d->verifySignature(contents, QString());
|
||||
}
|
||||
|
||||
QString Signing::signerOf(const KUrl &package, const KUrl &signature) const
|
||||
{
|
||||
kDebug() << "Checking existence of " << package.pathOrUrl();
|
||||
kDebug() << "Checking existence of " << signature.pathOrUrl();
|
||||
|
||||
if (!package.isLocalFile() || (!signature.isEmpty() && !signature.isLocalFile())) {
|
||||
kDebug() << "Remote urls not yet supported. FIXME.";
|
||||
return QString();
|
||||
}
|
||||
|
||||
return d->verifySignature(package.path(), signature.path());
|
||||
}
|
||||
|
||||
QString SigningPrivate::verifySignature(const QString &filePath, const QString &signature)
|
||||
{
|
||||
if (!QFile::exists(filePath)) {
|
||||
kDebug() << "Package" << filePath << "does not exist: signature verification aborted.";
|
||||
return QString();
|
||||
}
|
||||
|
||||
const QString signaturePath = signature.isEmpty() ? filePath + (".sig") : signature;
|
||||
|
||||
if (!QFile::exists(signaturePath)) {
|
||||
kDebug() << "Signature" << signaturePath << "does not exist: signature verification aborted.";
|
||||
return QString();
|
||||
}
|
||||
|
||||
//kDebug() << "Cheking if " << filePath << " and " << signaturePath << " matches";
|
||||
|
||||
FILE *pFile = fopen(filePath.toLocal8Bit().data(), "r");
|
||||
if (!pFile) {
|
||||
kDebug() << "failed to open file" << filePath;
|
||||
return QString();
|
||||
}
|
||||
|
||||
FILE *pSig = fopen(signaturePath.toLocal8Bit().data(), "r");
|
||||
if (!pSig) {
|
||||
kDebug() << "failed to open package file" << signaturePath;
|
||||
fclose(pFile);
|
||||
return QString();
|
||||
}
|
||||
|
||||
GpgME::Data file(pFile);
|
||||
GpgME::Data sig(pSig);
|
||||
|
||||
GpgME::VerificationResult vRes = m_gpgContext->verifyDetachedSignature(sig, file);
|
||||
QString rv;
|
||||
|
||||
if (!vRes.error()) {
|
||||
//kDebug() << "got" << vRes.signatures().size() << "signatures out" << vRes.error().asString();
|
||||
foreach (GpgME::Signature sig, vRes.signatures()) {
|
||||
if (sig.fingerprint()) {
|
||||
rv = sig.fingerprint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//kDebug() << "message " << filePath << " and signature " << signaturePath << "matched! The fingerprint of the signer is: " << rv;
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
fclose(pSig);
|
||||
return rv;
|
||||
}
|
||||
|
||||
QString Signing::keyStorePath() const
|
||||
{
|
||||
return d->m_keystorePath;
|
||||
}
|
||||
|
||||
QString Signing::descriptiveString(const QString &keyID) const
|
||||
{
|
||||
if (keyID.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (!d->m_gpgContext) {
|
||||
kDebug() << "GPGME context not valid: please re-initialize the library.";
|
||||
return QString();
|
||||
}
|
||||
|
||||
GpgME::Error error;
|
||||
GpgME::Key key = d->m_gpgContext->key(keyID.toAscii().data(), error);
|
||||
if (error) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return key.userID(0).id();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "moc_signing.cpp"
|
194
remote/signing.h
Normal file
194
remote/signing.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2010 by Diego '[Po]lentino' Casella <polentino911@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AUTHENTICATION_H
|
||||
#define AUTHENTICATION_H
|
||||
|
||||
#include <plasma/plasma_export.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QDateTime>
|
||||
|
||||
#include <kurl.h>
|
||||
|
||||
#include <plasma.h>
|
||||
|
||||
class QStringList;
|
||||
class QString;
|
||||
|
||||
/**
|
||||
* Global namespace for Signing library
|
||||
*/
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class Package;
|
||||
class SigningPrivate;
|
||||
|
||||
/**
|
||||
* A class to manage authentication based on cryptographic signatures.
|
||||
*
|
||||
* The Signing class is used to get the trust level of a set of files, or package, such
|
||||
* as a scripted plasmoid by performing a check between the signature shipped with it,
|
||||
* and the PGP keys found in the user keystore.
|
||||
*
|
||||
* If the keystore is empty, this class will take charge of populating it with the
|
||||
* pre-shipped keys.
|
||||
*
|
||||
* It also performs handy operations, such as populating the local keystore with the keys shipped
|
||||
* by default with KDE/linux distro, and notify the application which is using it about changes on the
|
||||
* local keystore or in the keys folder.
|
||||
*
|
||||
* Example of usage:
|
||||
* @code
|
||||
*
|
||||
* Plasma::Signing *m_auth = new Plasma::Signing(); // the constructor takes care of loading and spltting the keys
|
||||
* // loaded by the default keystore.
|
||||
*
|
||||
* // If you want to specify a different keystore, simply put its relative path as argument:
|
||||
* Plasma::Signing *m_auth = new Plasma::Signing(keystoreFullPath);
|
||||
*
|
||||
* // Now, supposed to previously saved in plasmoidPath and signaturePath the paths of the plasmoid and signature to check; then
|
||||
* QString signer = m_auth->signerOf(plasmoidPath, signaturePath); // Returns the the hash of the signer key, if the file and
|
||||
* // the signature have been successfully verified
|
||||
*
|
||||
* // If the signature is in the same folder of the file, you can also omit its path; the library will automatically load the
|
||||
* // signature named plasmoidPath plus the ".asc" file extension.
|
||||
* QString signer = m_auth->signerOf(plasmoidPath);
|
||||
*
|
||||
* // If you need to know the authentication level associated with a specific signer, simply call:
|
||||
* Plasma::TrustLevel level = m_auth->trustLevelOf(signer)
|
||||
*
|
||||
* // If you need more details about a key with a given keyID, you have to call:
|
||||
* QString info = m_auth->descriptiveString(keyID);
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* @author Diego '[Po]lentino' Casella <polentino911@gmail.com>
|
||||
*/
|
||||
class PLASMA_EXPORT Signing : public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
* It takes charge of loading the KDE keys, splitting the keys found in the default keystore (or in the one
|
||||
* specified by @param keystorePath).
|
||||
*
|
||||
* @param keystorePath a default QString that denotes the full path of the keystore being used for the authentication
|
||||
* process. Note that once selected, you can't change it.
|
||||
*
|
||||
*/
|
||||
Signing(const QString &keystorePath = 0);
|
||||
~Signing();
|
||||
|
||||
/**
|
||||
* Returns a list of all the key IDs processed by this Signing object that match the
|
||||
* requested TrustLevel.
|
||||
*
|
||||
* @param trustLevel the TrustLevel we want to
|
||||
* @return the QStringList with all the ID of the matching keys, or an empty one otherwise
|
||||
*/
|
||||
QStringList keysByTrustLevel(TrustLevel trustLevel) const;
|
||||
|
||||
/**
|
||||
* Return the TrustLevel associated with the key passed as parameter to the function.
|
||||
*
|
||||
* @param keyID the key we want to retrieve its trust level
|
||||
* @return the TrustLevel value
|
||||
*/
|
||||
TrustLevel trustLevelOf(const QString &keyID) const;
|
||||
|
||||
/**
|
||||
* Tests for a successful match between the object and signature files, referenced by their
|
||||
* absolute path. The signature path is optional and, if not specified, the function will
|
||||
* automatically try to retrieve it by appending the string ".sig" to the package path.
|
||||
*
|
||||
* @param package a Plasma::Package object representing the package to be tested
|
||||
*
|
||||
* @return The signer's unique key id, or an empty string if a signer was not found.
|
||||
* Failure can be due to the signature not matching or the signature file missing.
|
||||
* On success, this information can then be used with trustLevelOf and/or
|
||||
* descriptiveString to get more information on the key.
|
||||
*/
|
||||
QString signerOf(const Package &package) const;
|
||||
|
||||
/**
|
||||
* Tests for a successful match between the object and signature files, referenced by their
|
||||
* absolute path. The signature path is optional and, if not specified, the function will
|
||||
* automatically try to retrieve it by appending the string ".sig" to the package path.
|
||||
*
|
||||
* The signature should be a "detached signature" for correct results.
|
||||
*
|
||||
* @arg package the full path of the package we want to test
|
||||
* @arg signature optional path for the signature file
|
||||
*
|
||||
* @return The signer's unique key id, or an empty string if a signer was not found.
|
||||
* Failure can be due to the signature not matching or the signature file missing.
|
||||
* On success, this information can then be used with trustLevelOf and/or
|
||||
* descriptiveString to get more information on the key.
|
||||
*/
|
||||
QString signerOf(const KUrl &package, const KUrl &signature = KUrl()) const ;
|
||||
|
||||
/**
|
||||
* @return the QString path of the keystore being used.
|
||||
*/
|
||||
QString keyStorePath() const;
|
||||
|
||||
/**
|
||||
* Method used to retrieve additional informations about the key passed as parameter to the function.
|
||||
*
|
||||
* @arg keyID the string containing the hash of the key we want to retrive the informations.
|
||||
*
|
||||
* @return a QString object containing the name, the email and the comment (if any) referenced by the
|
||||
* id passed as argument to the function.
|
||||
*/
|
||||
QString descriptiveString(const QString &keyID) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
/**
|
||||
* Emitted when a new key is added from the trusted keys folder. Applications should connect
|
||||
* to this signal in order to update the trust level of the associated signed objects.
|
||||
*
|
||||
* @param keyId the key added
|
||||
*/
|
||||
void keyAdded(const QString &keyId);
|
||||
|
||||
/*
|
||||
* Emitted when a new key is removed from the trusted keys folder. Applications should connect
|
||||
* to this signal in order to update the trust level of the associated signed objects.
|
||||
*
|
||||
* @param keyID the key removed
|
||||
*/
|
||||
void keyRemoved(const QString &keyId);
|
||||
|
||||
private:
|
||||
Q_PRIVATE_SLOT(d, void processKeystore(const QString &path));
|
||||
Q_PRIVATE_SLOT(d, void keyAdded(const QString &path));
|
||||
Q_PRIVATE_SLOT(d, void keyRemoved(const QString &path));
|
||||
SigningPrivate * const d;
|
||||
friend class SigningPrivate;
|
||||
};
|
||||
|
||||
} // end Plasma namespace
|
||||
|
||||
#endif // AUTHENTICATION_H
|
72
remote/signing_p.h
Normal file
72
remote/signing_p.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2010 by Diego '[Po]lentino' Casella <polentino911@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SIGNING_P_H
|
||||
#define SIGNING_P_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <KDE/KDirWatch>
|
||||
|
||||
namespace GpgME {
|
||||
class Context;
|
||||
}
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Encapsulates all the nasty GpgME stuff and shows a more friendly a simple implementation
|
||||
* for our goal.
|
||||
*/
|
||||
class SigningPrivate
|
||||
{
|
||||
|
||||
public:
|
||||
SigningPrivate(Signing *auth, const QString &keystorePath);
|
||||
~SigningPrivate();
|
||||
|
||||
Signing *q;
|
||||
// Save all the keys in a single object, splitted by their SigningLevel
|
||||
// Note: keys[CompletelyUntrusted] refers to an empty list
|
||||
QMap<TrustLevel, QSet<QByteArray> > keys;
|
||||
|
||||
QString ultimateKeyStoragePath() const;
|
||||
void registerUltimateTrustKeys();
|
||||
void splitKeysByTrustLevel();
|
||||
Plasma::TrustLevel addKeyToCache(const QByteArray &fingerprint);
|
||||
void dumpKeysToDebug();
|
||||
QStringList keysID(const bool returnPrivate) const;
|
||||
QString verifySignature(const QString &packagePath, const QString &signaturePath);
|
||||
|
||||
void processKeystore(const QString &path);
|
||||
void keyAdded(const QString &path);
|
||||
void keyRemoved(const QString &path);
|
||||
|
||||
QStringList signersOf(const QString id) const;
|
||||
|
||||
KDirWatch *m_keystoreDir; // used to be notified for changes in the gnupg folders
|
||||
GpgME::Context *m_gpgContext;
|
||||
QString m_keystorePath;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SIGNING_P_H
|
@ -45,7 +45,7 @@ void TrustedOnlyAuthorization::clientPinRequest(ClientPinRequest &request)
|
||||
|
||||
void TrustedOnlyAuthorization::authorizationRequest(AuthorizationRule &rule)
|
||||
{
|
||||
if (rule.credentials().trustLevel() > TrustedCredentials) {
|
||||
if (rule.credentials().trustLevel() > UnknownTrusted) {
|
||||
rule.setPolicy(AuthorizationRule::Allow);
|
||||
rule.setTargets(AuthorizationRule::AllServices);
|
||||
}
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
#include "service.h"
|
||||
#include "private/authorizationmanager_p.h"
|
||||
#include "private/service_p.h"
|
||||
#include "private/serviceprovider_p.h"
|
||||
|
||||
@ -41,6 +40,7 @@
|
||||
#include "private/remoteservice_p.h"
|
||||
#include "private/remoteservicejob_p.h"
|
||||
#include "pluginloader.h"
|
||||
#include "remote/authorizationmanager_p.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
@ -12,11 +12,12 @@ MACRO(PLASMA_UNIT_TESTS)
|
||||
ENDMACRO(PLASMA_UNIT_TESTS)
|
||||
|
||||
PLASMA_UNIT_TESTS(
|
||||
configloadertest
|
||||
packagestructuretest
|
||||
packagemetadatatest
|
||||
plasmoidpackagetest
|
||||
runnercontexttest
|
||||
configloadertest
|
||||
signingtest
|
||||
)
|
||||
|
||||
kde4_add_unit_test(storagetest TESTNAME plasma-storage storagetest.cpp ../private/storage.cpp ../private/storagethread.cpp)
|
||||
|
BIN
tests/signed.plasmoid
Normal file
BIN
tests/signed.plasmoid
Normal file
Binary file not shown.
BIN
tests/signed.plasmoid.invalid.sig
Normal file
BIN
tests/signed.plasmoid.invalid.sig
Normal file
Binary file not shown.
BIN
tests/signed.plasmoid.sig
Normal file
BIN
tests/signed.plasmoid.sig
Normal file
Binary file not shown.
1
tests/signedPackage/CONTENTS
Normal file
1
tests/signedPackage/CONTENTS
Normal file
@ -0,0 +1 @@
|
||||
f10e861114185f88a54b3a7bb7e2f7232c7b8835
|
BIN
tests/signedPackage/CONTENTS.sig
Normal file
BIN
tests/signedPackage/CONTENTS.sig
Normal file
Binary file not shown.
45
tests/signedPackage/contents/code/main.js
Normal file
45
tests/signedPackage/contents/code/main.js
Normal file
@ -0,0 +1,45 @@
|
||||
// because we put the following line in the metadata.desktop file, we have access
|
||||
// to the HTTP extension in this Plasmoid.
|
||||
//
|
||||
// X-Plasma-RequiredExtensions=http
|
||||
//
|
||||
// More documentation can be found here:
|
||||
//
|
||||
// http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API#Extensions
|
||||
|
||||
output = new TextEdit
|
||||
output.readOnly = true
|
||||
|
||||
layout = new LinearLayout
|
||||
layout.orientation = QtVertical
|
||||
layout.addItem(output)
|
||||
|
||||
// in case our request for HTTP urls in the metadata.desktop was rejected (e.g. due
|
||||
// to security restrictions) we won't have a plasmoid.get, so let's check for it
|
||||
// before using it!
|
||||
if (plasmoid.getUrl) {
|
||||
var getJob = plasmoid.getUrl("http://dot.kde.org/rss.xml");
|
||||
function recv(job, data)
|
||||
{
|
||||
if (job == getJob) {
|
||||
print("we have our job")
|
||||
if (data.length) {
|
||||
output.append(data.toUtf8())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fini(job)
|
||||
{
|
||||
if (job == getJob) {
|
||||
print("our job is finished")
|
||||
} else {
|
||||
print("some other job is finished?")
|
||||
}
|
||||
}
|
||||
|
||||
getJob.data.connect(recv)
|
||||
getJob.finished.connect(fini)
|
||||
} else {
|
||||
output.text = i18n("HTTP access denied!")
|
||||
}
|
21
tests/signedPackage/metadata.desktop
Normal file
21
tests/signedPackage/metadata.desktop
Normal file
@ -0,0 +1,21 @@
|
||||
[Desktop Entry]
|
||||
Name=JavaScript File Operations
|
||||
Comment=Demonstrates accessing data via HTTP in JavaScript
|
||||
Icon=text-x-generic
|
||||
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=Plasma/Applet
|
||||
|
||||
X-Plasma-API=javascript
|
||||
X-Plasma-MainScript=code/main.js
|
||||
|
||||
X-KDE-PluginInfo-Author=Aaron Seigo
|
||||
X-KDE-PluginInfo-Email=aseigo@kde.org
|
||||
X-KDE-PluginInfo-Name=org.kde.plasma.simpified-javascript-http-example
|
||||
X-KDE-PluginInfo-Version=0.1
|
||||
X-KDE-PluginInfo-Website=
|
||||
X-KDE-PluginInfo-Category=Examples
|
||||
X-KDE-PluginInfo-Depends=
|
||||
X-KDE-PluginInfo-License=GPL
|
||||
|
||||
X-Plasma-OptionalExtensions=http
|
102
tests/signingtest.cpp
Normal file
102
tests/signingtest.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/********************************************************************************
|
||||
* Copyright 2011 by Aaron Seigo <aseigo@kde.org> *
|
||||
* *
|
||||
* This library 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; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public License *
|
||||
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||
* Boston, MA 02110-1301, USA. *
|
||||
*********************************************************************************/
|
||||
|
||||
#include "signingtest.h"
|
||||
|
||||
#include <QTime>
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "plasma/applet.h"
|
||||
#include "plasma/remote/signing.h"
|
||||
|
||||
static const QString fingerprint("8B8B22090C6F7C47B1EAEE75D6B72EB1A7F1DB43");
|
||||
|
||||
SigningTest::SigningTest(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_signing(0),
|
||||
m_package(QString::fromLatin1(KDESRCDIR) + "signedPackage", Plasma::Applet::packageStructure())
|
||||
{
|
||||
const QString prefix = QString::fromLatin1(KDESRCDIR);
|
||||
m_path = prefix + "signed.plasmoid";
|
||||
m_sig = prefix + "signed.plasmoid.sig";
|
||||
m_invalidSig = prefix + "signed.plasmoid.invalid.sig";
|
||||
}
|
||||
|
||||
void SigningTest::init()
|
||||
{
|
||||
}
|
||||
|
||||
void SigningTest::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void SigningTest::confirmCtorPerformance()
|
||||
{
|
||||
QTime t;
|
||||
t.start();
|
||||
m_signing = new Plasma::Signing;
|
||||
QVERIFY(t.elapsed() < 50);
|
||||
}
|
||||
|
||||
void SigningTest::missingFiles()
|
||||
{
|
||||
QVERIFY(m_signing->signerOf(KUrl("/nonexistantpackage"), KUrl("/noneexistantsignature")).isEmpty());
|
||||
QVERIFY(m_signing->signerOf(KUrl(m_path), KUrl("/noneexistantsignature")).isEmpty());
|
||||
QVERIFY(m_signing->signerOf(KUrl("/nonexistantpackage"), KUrl(m_sig)).isEmpty());
|
||||
}
|
||||
|
||||
void SigningTest::invalidSignature()
|
||||
{
|
||||
QCOMPARE(m_signing->signerOf(m_path, m_invalidSig), QString());
|
||||
}
|
||||
|
||||
void SigningTest::validSignature()
|
||||
{
|
||||
QCOMPARE(m_signing->signerOf(m_path, m_sig), fingerprint);
|
||||
}
|
||||
|
||||
void SigningTest::validSignatureWithoutDefinedSigFile()
|
||||
{
|
||||
QCOMPARE(m_signing->signerOf(m_path), fingerprint);
|
||||
}
|
||||
|
||||
void SigningTest::validPackage()
|
||||
{
|
||||
QCOMPARE(m_signing->signerOf(m_package), fingerprint);
|
||||
}
|
||||
|
||||
void SigningTest::trustLevel()
|
||||
{
|
||||
QCOMPARE(m_signing->trustLevelOf(QString()), Plasma::UnverifiableTrust);
|
||||
QCOMPARE(m_signing->trustLevelOf(fingerprint), Plasma::SelfTrusted);
|
||||
//FIXME: need to test other TrustLevel values
|
||||
}
|
||||
|
||||
void SigningTest::confirmDtorPerformance()
|
||||
{
|
||||
QTime t;
|
||||
t.start();
|
||||
delete m_signing;
|
||||
m_signing = 0;
|
||||
QVERIFY(t.elapsed() < 50);
|
||||
}
|
||||
|
||||
QTEST_KDEMAIN(SigningTest, NoGUI)
|
||||
|
61
tests/signingtest.h
Normal file
61
tests/signingtest.h
Normal file
@ -0,0 +1,61 @@
|
||||
/********************************************************************************
|
||||
* Copyright 2011 by Aaron Seigo <aseigo@kde.org> *
|
||||
* *
|
||||
* This library 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; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public License *
|
||||
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||
* Boston, MA 02110-1301, USA. *
|
||||
*********************************************************************************/
|
||||
|
||||
#ifndef SIGNINGTEST_H
|
||||
|
||||
#include <qtest_kde.h>
|
||||
|
||||
#include "plasma/package.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
class Signing;
|
||||
}
|
||||
|
||||
|
||||
class SigningTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SigningTest(QObject *parent = 0);
|
||||
|
||||
public Q_SLOTS:
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
private Q_SLOTS:
|
||||
void confirmCtorPerformance();
|
||||
void missingFiles();
|
||||
void invalidSignature();
|
||||
void validSignature();
|
||||
void validSignatureWithoutDefinedSigFile();
|
||||
void validPackage();
|
||||
void trustLevel();
|
||||
void confirmDtorPerformance();
|
||||
|
||||
private:
|
||||
Plasma::Signing *m_signing;
|
||||
Plasma::Package m_package;
|
||||
QString m_path;
|
||||
QString m_sig;
|
||||
QString m_invalidSig;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user