start of package verification

This commit is contained in:
Aaron Seigo 2011-05-26 16:02:56 +02:00
parent 3b6a49b5bd
commit 73758abf97
8 changed files with 132 additions and 12 deletions

View File

@ -42,6 +42,7 @@
#include <kprocess.h>
#include <kuser.h>
#include "plasma/package.h"
#include <cstdio> // FILE
@ -493,6 +494,39 @@ TrustLevel Signing::trustLevelOf(const QString &keyID) const
return d->addKeyToCache(keyID.toAscii());
}
QString Signing::signerOf(const Package &package) const
{
const QString contents = package.path() + "CONTENTS";
kDebug() << "gonna go in for" << package.path();
kDebug() << "hash is" << package.contentsHash();
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();
}
char hash[10 * 1024];
qint64 read = file.read(hash, 10 * 1024 - 1);
if (read < 1) {
kDebug() << "failed to read the CONTENTS file at" << contents;
}
hash[read + 1] = '\0';
const QString actualHash = package.contentsHash();
if (actualHash != hash) {
kDebug() << "CONTENTS does not match contents of package" << package.path();
}
return "Success!";
}
QString Signing::signerOf(const KUrl &package, const KUrl &signature) const
{
kDebug() << "Checking existence of " << package.pathOrUrl();
@ -503,25 +537,28 @@ QString Signing::signerOf(const KUrl &package, const KUrl &signature) const
return QString();
}
const QString packagePath = package.path();
if (!QFile::exists(packagePath)) {
kDebug() << "Package" << packagePath << "does not exist: signature verification aborted.";
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() ? packagePath + (".sig")
: signature.path();
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 " << packagePath << " and " << signaturePath << " matches";
//kDebug() << "Cheking if " << filePath << " and " << signaturePath << " matches";
FILE *pFile = fopen(packagePath.toLocal8Bit().data(), "r");
FILE *pFile = fopen(filePath.toLocal8Bit().data(), "r");
if (!pFile) {
kDebug() << "failed to open package file" << packagePath;
kDebug() << "failed to open file" << filePath;
return QString();
}
@ -535,7 +572,7 @@ QString Signing::signerOf(const KUrl &package, const KUrl &signature) const
GpgME::Data file(pFile);
GpgME::Data sig(pSig);
GpgME::VerificationResult vRes = d->m_gpgContext->verifyDetachedSignature(sig, file);
GpgME::VerificationResult vRes = m_gpgContext->verifyDetachedSignature(sig, file);
QString rv;
if (!vRes.error()) {
@ -547,7 +584,7 @@ QString Signing::signerOf(const KUrl &package, const KUrl &signature) const
}
}
//kDebug() << "message " << packagePath << " and signature " << signaturePath << "matched! The fingerprint of the signer is: " << rv;
//kDebug() << "message " << filePath << " and signature " << signaturePath << "matched! The fingerprint of the signer is: " << rv;
}
fclose(pFile);

View File

@ -38,6 +38,7 @@ class QString;
namespace Plasma
{
class Package;
class SigningPrivate;
/**
@ -116,6 +117,20 @@ public:
*/
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
@ -128,7 +143,7 @@ public:
*
* @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 informatoin can then be used with trustLevelOf and/or
* 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 ;

View File

@ -54,6 +54,7 @@ public:
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);

BIN
tests/signed.plasmoid Normal file

Binary file not shown.

BIN
tests/signed.plasmoid.sig Normal file

Binary file not shown.

View 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!")
}

View 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

View File

@ -33,7 +33,7 @@ SigningTest::SigningTest(QObject *parent)
{
const QString prefix = QString::fromLatin1(KDESRCDIR);
m_path = prefix + "signed.plasmoid";
m_sig = prefix + "signed.plasmoid.asc";
m_sig = prefix + "signed.plasmoid.sig";
m_invalidSig = prefix + "signed.plasmoid.invalid.sig";
}
@ -77,6 +77,7 @@ void SigningTest::validSignatureWithoutDefinedSigFile()
void SigningTest::validPackage()
{
QVERIFY(!m_signing->signerOf(m_package).isEmpty());
}
void SigningTest::confirmDtorPerformance()