Commit e95071f1 authored by Laurent Montel's avatar Laurent Montel 😁
Browse files

Implement delete keys

parent 38bbff89
......@@ -6,4 +6,4 @@ org.kde.pim.messageviewer messagelib (messageviewer) IDENTIFIER [MESSAGEVIEWER_L
org.kde.pim.templateparser messagelib (templateparser) IDENTIFIER [MIMETREEPARSER_LOG]
org.kde.pim.mimetreeparser messagelib (mimetreeparser) IDENTIFIER [TEMPLATEPARSER_LOG]
org.kde.pim.webengineviewer messagelib (webengineviewer) IDENTIFIER [WEBENGINEVIEWER_LOG]
org.kde.pim.messageviewer_dkimchecker messagelib (messageviewer) IDENTIFIER [MESSAGEVIEWER_DKIMCHECKER_LOG]
org.kde.pim.messageviewer_dkimchecker messagelib (messageviewer dkim support) IDENTIFIER [MESSAGEVIEWER_DKIMCHECKER_LOG]
......@@ -335,6 +335,8 @@ if (DKIM_CHECKER_BUILD)
DKIMManagerKey
DKIMCheckSignatureJob
DKIMManager
DKIMManagerKeyWidget
DKIMManagerKeyDialog
DKIMInfo
REQUIRED_HEADERS MessageViewer_dkimverify_HEADERS
PREFIX MessageViewer
......
......@@ -31,7 +31,7 @@ void DKIMCheckSignatureJobTest::shouldHaveDefaultValues()
{
MessageViewer::DKIMCheckSignatureJob job;
QVERIFY(job.dkimValue().isEmpty());
QVERIFY(job.warningFound().isEmpty());
QCOMPARE(job.status(), MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Unknown);
QCOMPARE(job.error(), MessageViewer::DKIMCheckSignatureJob::DKIMError::Any);
QCOMPARE(job.warning(), MessageViewer::DKIMCheckSignatureJob::DKIMWarning::Any);
}
......@@ -19,11 +19,12 @@
#include "dkimchecksignaturejob.h"
#include "dkimdownloadkeyjob.h"
#include "dkimmanagerkey.h"
#include "dkiminfo.h"
#include "dkimutil.h"
#include "dkimkeyrecord.h"
#include "messageviewer_dkimcheckerdebug.h"
#include <KLocalizedString>
#include "settings/messageviewersettings.h"
#include <QDateTime>
//see https://tools.ietf.org/html/rfc6376
......@@ -40,7 +41,7 @@ DKIMCheckSignatureJob::~DKIMCheckSignatureJob()
void DKIMCheckSignatureJob::start()
{
if (!mMessage) {
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid, mError, mWarning);
deleteLater();
return;
}
......@@ -48,20 +49,20 @@ void DKIMCheckSignatureJob::start()
mDkimValue = hrd->asUnicodeString();
}
if (mDkimValue.isEmpty()) {
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::EmailNotSigned);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::EmailNotSigned, mError, mWarning);
deleteLater();
return;
}
if (!mDkimInfo.parseDKIM(mDkimValue)) {
qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Impossible to parse header" << mDkimValue;
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid, mError, mWarning);
deleteLater();
return;
}
const MessageViewer::DKIMCheckSignatureJob::DKIMStatus status = checkSignature(mDkimInfo);
if (status != MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Valid) {
Q_EMIT result(status);
Q_EMIT result(status, mError, mWarning);
deleteLater();
return;
}
......@@ -70,7 +71,7 @@ void DKIMCheckSignatureJob::start()
switch (mDkimInfo.bodyCanonization()) {
case MessageViewer::DKIMInfo::CanonicalizationType::Unknown:
mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InvalidBodyCanonicalization;
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid, mError, mWarning);
deleteLater();
return;
case MessageViewer::DKIMInfo::CanonicalizationType::Simple:
......@@ -97,7 +98,7 @@ void DKIMCheckSignatureJob::start()
switch (mDkimInfo.headerCanonization()) {
case MessageViewer::DKIMInfo::CanonicalizationType::Unknown:
mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::InvalidHeaderCanonicalization;
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid, mError, mWarning);
deleteLater();
return;
case MessageViewer::DKIMInfo::CanonicalizationType::Simple:
......@@ -109,7 +110,14 @@ void DKIMCheckSignatureJob::start()
}
qDebug() << " headerCanonizationResult" << headerCanonizationResult;
downloadKey(mDkimInfo);
if (MessageViewer::MessageViewerSettings::self()->saveKey()) {
const QString keyValue = MessageViewer::DKIMManagerKey::self()->keyValue(mDkimInfo.selector(), mDkimInfo.domain());
if (keyValue.isEmpty()) {
downloadKey(mDkimInfo);
} else {
parseDKIMKeyRecord(keyValue, mDkimInfo.domain(), mDkimInfo.selector(), false);
}
}
}
QString DKIMCheckSignatureJob::bodyCanonizationSimple() const
......@@ -231,21 +239,21 @@ void DKIMCheckSignatureJob::slotDownloadKeyDone(const QList<QByteArray> &lst, co
} else {
ba = lst.at(0);
}
parseDKIMKeyRecord(QString::fromLocal8Bit(ba), domain, selector);
parseDKIMKeyRecord(QString::fromLocal8Bit(ba), domain, selector, true);
}
void DKIMCheckSignatureJob::parseDKIMKeyRecord(const QString &str, const QString &domain, const QString &selector)
void DKIMCheckSignatureJob::parseDKIMKeyRecord(const QString &str, const QString &domain, const QString &selector, bool storeKeyValue)
{
if (!mDkimKeyRecord.parseKey(str)) {
qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Impossible to parse key record " << str;
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid, mError, mWarning);
deleteLater();
return;
}
if (mDkimKeyRecord.keyType() != QLatin1String("rsa")) {
qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "mDkimKeyRecord key type is unknown " << mDkimKeyRecord.keyType() << " str " << str;
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid, mError, mWarning);
deleteLater();
return;
}
......@@ -262,12 +270,14 @@ void DKIMCheckSignatureJob::parseDKIMKeyRecord(const QString &str, const QString
// empty value means that this public key has been revoked
qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "mDkimKeyRecord public key is empty. It was revoked ";
mError = MessageViewer::DKIMCheckSignatureJob::DKIMError::PublicKeyWasRevoked;
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid);
Q_EMIT result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus::Invalid, mError, mWarning);
deleteLater();
return;
}
Q_EMIT storeKey(str, domain, selector);
if (storeKeyValue) {
Q_EMIT storeKey(str, domain, selector);
}
verifyRSASignature();
}
......@@ -278,6 +288,16 @@ void DKIMCheckSignatureJob::verifyRSASignature()
deleteLater();
}
DKIMCheckSignatureJob::DKIMWarning DKIMCheckSignatureJob::warning() const
{
return mWarning;
}
void DKIMCheckSignatureJob::setWarning(const DKIMCheckSignatureJob::DKIMWarning &warning)
{
mWarning = warning;
}
KMime::Message::Ptr DKIMCheckSignatureJob::message() const
{
return mMessage;
......@@ -292,10 +312,10 @@ MessageViewer::DKIMCheckSignatureJob::DKIMStatus DKIMCheckSignatureJob::checkSig
{
const qint64 currentDate = QDateTime::currentSecsSinceEpoch();
if (info.expireTime() != -1 && info.expireTime() < currentDate) {
mWarningFound = i18n("Signature Expired");
mWarning = DKIMCheckSignatureJob::DKIMWarning::SignatureExpired;
}
if (info.signatureTimeStamp() != -1 && info.signatureTimeStamp() > currentDate) {
mWarningFound += i18n("Signature created in the future");
mWarning = DKIMCheckSignatureJob::DKIMWarning::SignatureCreatedInFuture;
}
if (info.signature().isEmpty()) {
qCWarning(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Signature doesn't exist";
......@@ -339,16 +359,6 @@ DKIMCheckSignatureJob::DKIMError DKIMCheckSignatureJob::error() const
return mError;
}
QString DKIMCheckSignatureJob::warningFound() const
{
return mWarningFound;
}
void DKIMCheckSignatureJob::setWarningFound(const QString &warningFound)
{
mWarningFound = warningFound;
}
DKIMCheckSignatureJob::DKIMStatus DKIMCheckSignatureJob::status() const
{
return mStatus;
......
......@@ -53,6 +53,11 @@ public:
//TODO add more
};
enum class DKIMWarning {
Any,
SignatureExpired,
SignatureCreatedInFuture,
};
explicit DKIMCheckSignatureJob(QObject *parent = nullptr);
~DKIMCheckSignatureJob();
......@@ -63,8 +68,6 @@ public:
Q_REQUIRED_RESULT DKIMCheckSignatureJob::DKIMStatus status() const;
void setStatus(const DKIMCheckSignatureJob::DKIMStatus &status);
Q_REQUIRED_RESULT QString warningFound() const;
void setWarningFound(const QString &warningFound);
Q_REQUIRED_RESULT MessageViewer::DKIMCheckSignatureJob::DKIMStatus checkSignature(const MessageViewer::DKIMInfo &info);
Q_REQUIRED_RESULT DKIMCheckSignatureJob::DKIMError error() const;
......@@ -72,14 +75,17 @@ public:
Q_REQUIRED_RESULT KMime::Message::Ptr message() const;
void setMessage(const KMime::Message::Ptr &message);
Q_REQUIRED_RESULT DKIMCheckSignatureJob::DKIMWarning warning() const;
void setWarning(const DKIMWarning &warning);
Q_SIGNALS:
void result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus status);
void result(MessageViewer::DKIMCheckSignatureJob::DKIMStatus status, MessageViewer::DKIMCheckSignatureJob::DKIMError error, MessageViewer::DKIMCheckSignatureJob::DKIMWarning warning);
void storeKey(const QString &key, const QString &domain, const QString &selector);
private:
void downloadKey(const DKIMInfo &info);
void slotDownloadKeyDone(const QList<QByteArray> &lst, const QString &domain, const QString &selector);
void parseDKIMKeyRecord(const QString &str, const QString &domain, const QString &selector);
void parseDKIMKeyRecord(const QString &str, const QString &domain, const QString &selector, bool storeKeyValue = true);
QString headerCanonizationSimple() const;
QString headerCanonizationRelaxed() const;
QString bodyCanonizationRelaxed() const;
......@@ -89,8 +95,8 @@ private:
DKIMInfo mDkimInfo;
DKIMKeyRecord mDkimKeyRecord;
QString mDkimValue;
QString mWarningFound;
DKIMCheckSignatureJob::DKIMError mError = DKIMCheckSignatureJob::DKIMError::Any;
DKIMCheckSignatureJob::DKIMWarning mWarning = DKIMCheckSignatureJob::DKIMWarning::Any;
DKIMCheckSignatureJob::DKIMStatus mStatus = DKIMCheckSignatureJob::DKIMStatus::Unknown;
};
}
......
......@@ -41,6 +41,16 @@ DKIMManagerKey *DKIMManagerKey::self()
return &s_self;
}
QString DKIMManagerKey::keyValue(const QString &selector, const QString &domain)
{
for (const KeyInfo &keyInfo : mKeys) {
if (keyInfo.selector == selector && keyInfo.domain == domain) {
return keyInfo.keyValue;
}
}
return {};
}
void DKIMManagerKey::addKey(const KeyInfo &key)
{
if (!mKeys.contains(key)) {
......@@ -50,7 +60,12 @@ void DKIMManagerKey::addKey(const KeyInfo &key)
void DKIMManagerKey::removeKey(const QString &key)
{
//TODO
for (const KeyInfo &keyInfo : mKeys) {
if (keyInfo.keyValue == key) {
mKeys.removeAll(keyInfo);
break;
}
}
}
QVector<KeyInfo> DKIMManagerKey::keys() const
......
......@@ -55,6 +55,7 @@ public:
Q_REQUIRED_RESULT QVector<KeyInfo> keys() const;
void saveKeys();
Q_REQUIRED_RESULT QString keyValue(const QString &selector, const QString &domain);
private:
QVector<KeyInfo> mKeys;
};
......
......@@ -21,11 +21,11 @@
#define DKIMMANAGERKEYDIALOG_H
#include <QDialog>
#include "messageviewer_private_export.h"
#include "messageviewer_export.h"
namespace MessageViewer {
class DKIMManagerKeyWidget;
class MESSAGEVIEWER_TESTS_EXPORT DKIMManagerKeyDialog : public QDialog
class MESSAGEVIEWER_EXPORT DKIMManagerKeyDialog : public QDialog
{
Q_OBJECT
public:
......
......@@ -23,6 +23,7 @@
#include <QTreeWidget>
#include <QVBoxLayout>
#include <KLocalizedString>
#include <QMenu>
using namespace MessageViewer;
DKIMManagerKeyWidget::DKIMManagerKeyWidget(QWidget *parent)
......@@ -34,23 +35,41 @@ DKIMManagerKeyWidget::DKIMManagerKeyWidget(QWidget *parent)
mTreeWidget = new QTreeWidget(this);
mTreeWidget->setObjectName(QStringLiteral("treewidget"));
mTreeWidget->setRootIsDecorated(false);
mTreeWidget->setHeaderLabels({i18n("SDID"), i18n("Selector"), i18n("DKIM Key")});
mainLayout->addWidget(mTreeWidget);
//TODO add remove keys
mTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
mTreeWidget->setAlternatingRowColors(true);
connect(mTreeWidget, &QTreeWidget::customContextMenuRequested, this, &DKIMManagerKeyWidget::customContextMenuRequested);
}
DKIMManagerKeyWidget::~DKIMManagerKeyWidget()
{
}
void DKIMManagerKeyWidget::customContextMenuRequested(const QPoint &)
{
QTreeWidgetItem *item = mTreeWidget->currentItem();
if (!item) {
return;
}
QMenu menu(this);
menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Remove Key"), this, [this, item]() {
delete item;
});
menu.exec(QCursor::pos());
}
void DKIMManagerKeyWidget::loadKeys()
{
mTreeWidget->clear();
const QVector<MessageViewer::KeyInfo> lst = DKIMManagerKey::self()->keys();
for (const MessageViewer::KeyInfo &key : lst) {
QTreeWidgetItem *item = new QTreeWidgetItem(mTreeWidget);
item->setText(0, key.domain);
item->setText(1, key.selector);
item->setText(2, key.keyValue);
item->setToolTip(2, key.keyValue);
}
}
......@@ -64,3 +83,8 @@ void DKIMManagerKeyWidget::saveKeys()
}
DKIMManagerKey::self()->saveKeys(lst);
}
void DKIMManagerKeyWidget::resetKeys()
{
loadKeys();
}
......@@ -20,10 +20,10 @@
#define DKIMMANAGERKEYWIDGET_H
#include <QWidget>
#include "messageviewer_private_export.h"
#include "messageviewer_export.h"
class QTreeWidget;
namespace MessageViewer {
class MESSAGEVIEWER_TESTS_EXPORT DKIMManagerKeyWidget : public QWidget
class MESSAGEVIEWER_EXPORT DKIMManagerKeyWidget : public QWidget
{
Q_OBJECT
public:
......@@ -32,7 +32,9 @@ public:
void loadKeys();
void saveKeys();
void resetKeys();
private:
void customContextMenuRequested(const QPoint &);
QTreeWidget *mTreeWidget = nullptr;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment