Page MenuHome GnuPG

No OneTemporary

diff --git a/src/kleo/defaultkeyfilter.cpp b/src/kleo/defaultkeyfilter.cpp
index 6878aaeb..3aab717b 100644
--- a/src/kleo/defaultkeyfilter.cpp
+++ b/src/kleo/defaultkeyfilter.cpp
@@ -1,727 +1,738 @@
/*
defaultkeyfilter.cpp
This file is part of libkleopatra, the KDE keymanagement library
SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-libkleo.h>
#include "defaultkeyfilter.h"
#include "utils/compliance.h"
#if GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE
#else
#include <libkleo/compat.h>
#endif
#include <libkleo/compliance.h>
#include <libkleo/formatting.h>
#include <libkleo/keyhelpers.h>
#include <functional>
#include <memory>
using namespace GpgME;
using namespace Kleo;
static bool is_card_key(const Key &key)
{
const std::vector<Subkey> sks = key.subkeys();
return std::find_if(sks.begin(), sks.end(), std::mem_fn(&Subkey::isCardKey)) != sks.end();
}
class DefaultKeyFilter::Private
{
public:
Private()
{
}
QColor mFgColor;
QColor mBgColor;
QString mName;
QString mIcon;
QString mId;
+ QString mDescription;
MatchContexts mMatchContexts = AnyMatchContext;
unsigned int mSpecificity = 0;
bool mItalic = false;
bool mBold = false;
bool mStrikeOut = false;
bool mUseFullFont = false;
QFont mFont;
TriState mRevoked = DoesNotMatter;
TriState mExpired = DoesNotMatter;
TriState mInvalid = DoesNotMatter;
TriState mDisabled = DoesNotMatter;
TriState mRoot = DoesNotMatter;
TriState mCanEncrypt = DoesNotMatter;
TriState mCanSign = DoesNotMatter;
TriState mCanCertify = DoesNotMatter;
TriState mCanAuthenticate = DoesNotMatter;
TriState mHasEncrypt = DoesNotMatter;
TriState mHasSign = DoesNotMatter;
TriState mHasCertify = DoesNotMatter;
TriState mHasAuthenticate = DoesNotMatter;
TriState mQualified = DoesNotMatter;
TriState mCardKey = DoesNotMatter;
TriState mHasSecret = DoesNotMatter;
TriState mIsOpenPGP = DoesNotMatter;
TriState mWasValidated = DoesNotMatter;
TriState mIsDeVs = DoesNotMatter;
TriState mBad = DoesNotMatter;
TriState mValidIfSMIME = DoesNotMatter;
LevelState mOwnerTrust = LevelDoesNotMatter;
GpgME::Key::OwnerTrust mOwnerTrustReferenceLevel = Key::OwnerTrust::Unknown;
LevelState mValidity = LevelDoesNotMatter;
GpgME::UserID::Validity mValidityReferenceLevel = UserID::Validity::Unknown;
};
DefaultKeyFilter::DefaultKeyFilter()
: KeyFilter{}
, d{new Private}
{
}
DefaultKeyFilter::~DefaultKeyFilter() = default;
bool DefaultKeyFilter::matches(const Key &key, MatchContexts contexts) const
{
if (!(d->mMatchContexts & contexts)) {
return false;
}
#ifdef MATCH
#undef MATCH
#endif
#define MATCH(member, method) \
do { \
if (member != DoesNotMatter && key.method() != bool(member == Set)) { \
return false; \
} \
} while (false)
#define IS_MATCH(what) MATCH(d->m##what, is##what)
#define CAN_MATCH(what) MATCH(d->mCan##what, can##what)
#if GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE
#define HAS_MATCH(what) MATCH(d->mHas##what, has##what)
#else
#define HAS_MATCH(what) \
do { \
if (d->mHas##what != DoesNotMatter && Kleo::keyHas##what(key) != bool(d->mHas##what == Set)) { \
return false; \
} \
} while (false)
#endif
IS_MATCH(Revoked);
IS_MATCH(Expired);
IS_MATCH(Invalid);
IS_MATCH(Disabled);
IS_MATCH(Root);
CAN_MATCH(Encrypt);
CAN_MATCH(Sign);
CAN_MATCH(Certify);
CAN_MATCH(Authenticate);
HAS_MATCH(Encrypt);
HAS_MATCH(Sign);
HAS_MATCH(Certify);
HAS_MATCH(Authenticate);
IS_MATCH(Qualified);
if (d->mCardKey != DoesNotMatter) {
if ((d->mCardKey == Set && !is_card_key(key)) || (d->mCardKey == NotSet && is_card_key(key))) {
return false;
}
}
MATCH(d->mHasSecret, hasSecret);
#undef MATCH
if (d->mIsOpenPGP != DoesNotMatter && bool(key.protocol() == GpgME::OpenPGP) != bool(d->mIsOpenPGP == Set)) {
return false;
}
if (d->mWasValidated != DoesNotMatter && bool(key.keyListMode() & GpgME::Validate) != bool(d->mWasValidated == Set)) {
return false;
}
if (d->mIsDeVs != DoesNotMatter && bool(DeVSCompliance::keyIsCompliant(key)) != bool(d->mIsDeVs == Set)) {
return false;
}
if (d->mBad != DoesNotMatter &&
/* This is similar to GPGME::Key::isBad which was introduced in GPGME 1.13.0 */
bool(key.isNull() || key.isRevoked() || key.isExpired() || key.isDisabled() || key.isInvalid()) != bool(d->mBad == Set)) {
return false;
}
const UserID uid = key.userID(0);
if ((key.protocol() == GpgME::CMS) //
&& (d->mValidIfSMIME != DoesNotMatter) //
&& (bool(uid.validity() >= UserID::Full) != bool(d->mValidIfSMIME == Set))) {
return false;
}
switch (d->mOwnerTrust) {
default:
case LevelDoesNotMatter:
break;
case Is:
if (key.ownerTrust() != d->mOwnerTrustReferenceLevel) {
return false;
}
break;
case IsNot:
if (key.ownerTrust() == d->mOwnerTrustReferenceLevel) {
return false;
}
break;
case IsAtLeast:
if (static_cast<int>(key.ownerTrust()) < static_cast<int>(d->mOwnerTrustReferenceLevel)) {
return false;
}
break;
case IsAtMost:
if (static_cast<int>(key.ownerTrust()) > static_cast<int>(d->mOwnerTrustReferenceLevel)) {
return false;
}
break;
}
switch (d->mValidity) {
default:
case LevelDoesNotMatter:
break;
case Is:
if (uid.validity() != d->mValidityReferenceLevel) {
return false;
}
break;
case IsNot:
if (uid.validity() == d->mValidityReferenceLevel) {
return false;
}
break;
case IsAtLeast:
if (static_cast<int>(uid.validity()) < static_cast<int>(d->mValidityReferenceLevel)) {
return false;
}
break;
case IsAtMost:
if (static_cast<int>(uid.validity()) > static_cast<int>(d->mValidityReferenceLevel)) {
return false;
}
break;
}
return true;
}
bool DefaultKeyFilter::matches(const UserID &userID, MatchContexts contexts) const
{
if (!(d->mMatchContexts & contexts)) {
return false;
}
#ifdef MATCH_KEY
#undef MATCH_KEY
#endif
#define MATCH_KEY(member, method) \
do { \
if (member != DoesNotMatter && userID.parent().method() != bool(member == Set)) { \
return false; \
} \
} while (false)
#define IS_MATCH_KEY(what) MATCH_KEY(d->m##what, is##what)
#define CAN_MATCH_KEY(what) MATCH_KEY(d->mCan##what, can##what)
#if GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE
#define HAS_MATCH_KEY(what) MATCH_KEY(d->mHas##what, has##what)
#else
#define HAS_MATCH_KEY(what) \
do { \
if (d->mHas##what != DoesNotMatter && Kleo::keyHas##what(userID.parent()) != bool(d->mHas##what == Set)) { \
return false; \
} \
} while (false)
#endif
#ifdef MATCH
#undef MATCH
#endif
#define MATCH(member, method) \
do { \
if (member != DoesNotMatter && (userID.parent().method() != bool(member == Set) || userID.method() != bool(member == Set))) { \
return false; \
} \
} while (false)
#define IS_MATCH(what) MATCH(d->m##what, is##what)
IS_MATCH(Revoked);
IS_MATCH_KEY(Expired);
// We have to do this manually since there's no UserID::isExpired()
if (d->mExpired != DoesNotMatter && (userID.parent().isExpired() != bool(d->mExpired == Set) || isExpired(userID) != bool(d->mExpired == Set))) {
return false;
}
IS_MATCH(Invalid);
IS_MATCH_KEY(Disabled);
IS_MATCH_KEY(Root);
CAN_MATCH_KEY(Encrypt);
CAN_MATCH_KEY(Sign);
CAN_MATCH_KEY(Certify);
CAN_MATCH_KEY(Authenticate);
HAS_MATCH_KEY(Encrypt);
HAS_MATCH_KEY(Sign);
HAS_MATCH_KEY(Certify);
HAS_MATCH_KEY(Authenticate);
IS_MATCH_KEY(Qualified);
if (d->mCardKey != DoesNotMatter) {
if ((d->mCardKey == Set && !is_card_key(userID.parent())) || (d->mCardKey == NotSet && is_card_key(userID.parent()))) {
return false;
}
}
MATCH_KEY(d->mHasSecret, hasSecret);
#undef MATCH
if (d->mIsOpenPGP != DoesNotMatter && bool(userID.parent().protocol() == GpgME::OpenPGP) != bool(d->mIsOpenPGP == Set)) {
return false;
}
if (d->mWasValidated != DoesNotMatter && bool(userID.parent().keyListMode() & GpgME::Validate) != bool(d->mWasValidated == Set)) {
return false;
}
if (d->mIsDeVs != DoesNotMatter && bool(DeVSCompliance::userIDIsCompliant(userID)) != bool(d->mIsDeVs == Set)) {
return false;
}
if (d->mBad != DoesNotMatter &&
/* This is similar to GPGME::Key::isBad which was introduced in GPGME 1.13.0 */
bool(userID.parent().isNull() || userID.isNull() || userID.parent().isRevoked() || userID.isRevoked() || userID.parent().isExpired()
|| userID.parent().isDisabled() || userID.parent().isInvalid() || userID.isInvalid())
!= bool(d->mBad == Set)) {
return false;
}
if ((userID.parent().protocol() == GpgME::CMS) //
&& (d->mValidIfSMIME != DoesNotMatter) //
&& (bool(userID.validity() >= UserID::Full) != bool(d->mValidIfSMIME == Set))) {
return false;
}
switch (d->mOwnerTrust) {
default:
case LevelDoesNotMatter:
break;
case Is:
if (userID.parent().ownerTrust() != d->mOwnerTrustReferenceLevel) {
return false;
}
break;
case IsNot:
if (userID.parent().ownerTrust() == d->mOwnerTrustReferenceLevel) {
return false;
}
break;
case IsAtLeast:
if (static_cast<int>(userID.parent().ownerTrust()) < static_cast<int>(d->mOwnerTrustReferenceLevel)) {
return false;
}
break;
case IsAtMost:
if (static_cast<int>(userID.parent().ownerTrust()) > static_cast<int>(d->mOwnerTrustReferenceLevel)) {
return false;
}
break;
}
switch (d->mValidity) {
default:
case LevelDoesNotMatter:
break;
case Is:
if (userID.validity() != d->mValidityReferenceLevel) {
return false;
}
break;
case IsNot:
if (userID.validity() == d->mValidityReferenceLevel) {
return false;
}
break;
case IsAtLeast:
if (static_cast<int>(userID.validity()) < static_cast<int>(d->mValidityReferenceLevel)) {
return false;
}
break;
case IsAtMost:
if (static_cast<int>(userID.validity()) > static_cast<int>(d->mValidityReferenceLevel)) {
return false;
}
break;
}
return true;
}
KeyFilter::FontDescription DefaultKeyFilter::fontDescription() const
{
if (d->mUseFullFont) {
return FontDescription::create(font(), bold(), italic(), strikeOut());
} else {
return FontDescription::create(bold(), italic(), strikeOut());
}
}
void DefaultKeyFilter::setFgColor(const QColor &value)
{
d->mFgColor = value;
}
void DefaultKeyFilter::setBgColor(const QColor &value)
{
d->mBgColor = value;
}
void DefaultKeyFilter::setName(const QString &value)
{
d->mName = value;
}
void DefaultKeyFilter::setIcon(const QString &value)
{
d->mIcon = value;
}
void DefaultKeyFilter::setId(const QString &value)
{
d->mId = value;
}
void DefaultKeyFilter::setMatchContexts(MatchContexts value)
{
d->mMatchContexts = value;
}
void DefaultKeyFilter::setSpecificity(unsigned int value)
{
d->mSpecificity = value;
}
void DefaultKeyFilter::setItalic(bool value)
{
d->mItalic = value;
}
void DefaultKeyFilter::setBold(bool value)
{
d->mBold = value;
}
void DefaultKeyFilter::setStrikeOut(bool value)
{
d->mStrikeOut = value;
}
void DefaultKeyFilter::setUseFullFont(bool value)
{
d->mUseFullFont = value;
}
void DefaultKeyFilter::setFont(const QFont &value)
{
d->mFont = value;
}
void DefaultKeyFilter::setRevoked(DefaultKeyFilter::TriState value)
{
d->mRevoked = value;
}
void DefaultKeyFilter::setExpired(DefaultKeyFilter::TriState value)
{
d->mExpired = value;
}
void DefaultKeyFilter::setInvalid(DefaultKeyFilter::TriState value)
{
d->mInvalid = value;
}
void DefaultKeyFilter::setDisabled(DefaultKeyFilter::TriState value)
{
d->mDisabled = value;
}
void DefaultKeyFilter::setRoot(DefaultKeyFilter::TriState value)
{
d->mRoot = value;
}
void DefaultKeyFilter::setCanEncrypt(DefaultKeyFilter::TriState value)
{
d->mCanEncrypt = value;
}
void DefaultKeyFilter::setCanSign(DefaultKeyFilter::TriState value)
{
d->mCanSign = value;
}
void DefaultKeyFilter::setCanCertify(DefaultKeyFilter::TriState value)
{
d->mCanCertify = value;
}
void DefaultKeyFilter::setCanAuthenticate(DefaultKeyFilter::TriState value)
{
d->mCanAuthenticate = value;
}
void DefaultKeyFilter::setHasEncrypt(DefaultKeyFilter::TriState value)
{
d->mHasEncrypt = value;
}
void DefaultKeyFilter::setHasSign(DefaultKeyFilter::TriState value)
{
d->mHasSign = value;
}
void DefaultKeyFilter::setHasCertify(DefaultKeyFilter::TriState value)
{
d->mHasCertify = value;
}
void DefaultKeyFilter::setHasAuthenticate(DefaultKeyFilter::TriState value)
{
d->mHasAuthenticate = value;
}
void DefaultKeyFilter::setQualified(DefaultKeyFilter::TriState value)
{
d->mQualified = value;
}
void DefaultKeyFilter::setCardKey(DefaultKeyFilter::TriState value)
{
d->mCardKey = value;
}
void DefaultKeyFilter::setHasSecret(DefaultKeyFilter::TriState value)
{
d->mHasSecret = value;
}
void DefaultKeyFilter::setIsOpenPGP(DefaultKeyFilter::TriState value)
{
d->mIsOpenPGP = value;
}
void DefaultKeyFilter::setWasValidated(DefaultKeyFilter::TriState value)
{
d->mWasValidated = value;
}
void DefaultKeyFilter::setOwnerTrust(DefaultKeyFilter::LevelState value)
{
d->mOwnerTrust = value;
}
void DefaultKeyFilter::setOwnerTrustReferenceLevel(GpgME::Key::OwnerTrust value)
{
d->mOwnerTrustReferenceLevel = value;
}
void DefaultKeyFilter::setValidity(DefaultKeyFilter::LevelState value)
{
d->mValidity = value;
}
void DefaultKeyFilter::setValidityReferenceLevel(GpgME::UserID::Validity value)
{
d->mValidityReferenceLevel = value;
}
void DefaultKeyFilter::setIsDeVs(DefaultKeyFilter::TriState value)
{
d->mIsDeVs = value;
}
void DefaultKeyFilter::setIsBad(DefaultKeyFilter::TriState value)
{
d->mBad = value;
}
void DefaultKeyFilter::setValidIfSMIME(DefaultKeyFilter::TriState value)
{
d->mValidIfSMIME = value;
}
QColor DefaultKeyFilter::fgColor() const
{
return d->mFgColor;
}
QColor DefaultKeyFilter::bgColor() const
{
return d->mBgColor;
}
QString DefaultKeyFilter::name() const
{
return d->mName;
}
QString DefaultKeyFilter::icon() const
{
return d->mIcon;
}
QString DefaultKeyFilter::id() const
{
return d->mId;
}
QFont DefaultKeyFilter::font() const
{
return d->mFont;
}
KeyFilter::MatchContexts DefaultKeyFilter::availableMatchContexts() const
{
return d->mMatchContexts;
}
unsigned int DefaultKeyFilter::specificity() const
{
return d->mSpecificity;
}
bool DefaultKeyFilter::italic() const
{
return d->mItalic;
}
bool DefaultKeyFilter::bold() const
{
return d->mBold;
}
bool DefaultKeyFilter::strikeOut() const
{
return d->mStrikeOut;
}
bool DefaultKeyFilter::useFullFont() const
{
return d->mUseFullFont;
}
DefaultKeyFilter::TriState DefaultKeyFilter::revoked() const
{
return d->mRevoked;
}
DefaultKeyFilter::TriState DefaultKeyFilter::expired() const
{
return d->mExpired;
}
DefaultKeyFilter::TriState DefaultKeyFilter::invalid() const
{
return d->mInvalid;
}
DefaultKeyFilter::TriState DefaultKeyFilter::disabled() const
{
return d->mDisabled;
}
DefaultKeyFilter::TriState DefaultKeyFilter::root() const
{
return d->mRoot;
}
DefaultKeyFilter::TriState DefaultKeyFilter::canEncrypt() const
{
return d->mCanEncrypt;
}
DefaultKeyFilter::TriState DefaultKeyFilter::canSign() const
{
return d->mCanSign;
}
DefaultKeyFilter::TriState DefaultKeyFilter::canCertify() const
{
return d->mCanCertify;
}
DefaultKeyFilter::TriState DefaultKeyFilter::canAuthenticate() const
{
return d->mCanAuthenticate;
}
DefaultKeyFilter::TriState DefaultKeyFilter::hasEncrypt() const
{
return d->mHasEncrypt;
}
DefaultKeyFilter::TriState DefaultKeyFilter::hasSign() const
{
return d->mHasSign;
}
DefaultKeyFilter::TriState DefaultKeyFilter::hasCertify() const
{
return d->mHasCertify;
}
DefaultKeyFilter::TriState DefaultKeyFilter::hasAuthenticate() const
{
return d->mHasAuthenticate;
}
DefaultKeyFilter::TriState DefaultKeyFilter::qualified() const
{
return d->mQualified;
}
DefaultKeyFilter::TriState DefaultKeyFilter::cardKey() const
{
return d->mCardKey;
}
DefaultKeyFilter::TriState DefaultKeyFilter::hasSecret() const
{
return d->mHasSecret;
}
DefaultKeyFilter::TriState DefaultKeyFilter::isOpenPGP() const
{
return d->mIsOpenPGP;
}
DefaultKeyFilter::TriState DefaultKeyFilter::wasValidated() const
{
return d->mWasValidated;
}
DefaultKeyFilter::LevelState DefaultKeyFilter::ownerTrust() const
{
return d->mOwnerTrust;
}
GpgME::Key::OwnerTrust DefaultKeyFilter::ownerTrustReferenceLevel() const
{
return d->mOwnerTrustReferenceLevel;
}
DefaultKeyFilter::LevelState DefaultKeyFilter::validity() const
{
return d->mValidity;
}
GpgME::UserID::Validity DefaultKeyFilter::validityReferenceLevel() const
{
return d->mValidityReferenceLevel;
}
DefaultKeyFilter::TriState DefaultKeyFilter::isDeVS() const
{
return d->mIsDeVs;
}
DefaultKeyFilter::TriState DefaultKeyFilter::isBad() const
{
return d->mBad;
}
DefaultKeyFilter::TriState DefaultKeyFilter::validIfSMIME() const
{
return d->mValidIfSMIME;
}
+
+QString DefaultKeyFilter::description() const
+{
+ return d->mDescription;
+}
+
+void DefaultKeyFilter::setDescription(const QString &description)
+{
+ d->mDescription = description;
+}
diff --git a/src/kleo/defaultkeyfilter.h b/src/kleo/defaultkeyfilter.h
index f0ee1296..f65d49fc 100644
--- a/src/kleo/defaultkeyfilter.h
+++ b/src/kleo/defaultkeyfilter.h
@@ -1,154 +1,156 @@
/*
defaultkeyfilter.h
This file is part of libkleopatra, the KDE keymanagement library
SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "keyfilter.h"
#include "kleo_export.h"
#include <QColor>
#include <QFont>
#include <QString>
#include <gpgme++/key.h>
#include <memory>
namespace Kleo
{
/** Default implementation of key filter class. */
class KLEO_EXPORT DefaultKeyFilter : public KeyFilter
{
public:
DefaultKeyFilter();
~DefaultKeyFilter() override;
/** Used for bool checks */
enum TriState {
// clang-format off
DoesNotMatter = 0,
Set = 1,
NotSet = 2,
// clang-format on
};
/** Used for level checks */
enum LevelState {
// clang-format off
LevelDoesNotMatter = 0,
Is = 1,
IsNot = 2,
IsAtLeast = 3,
IsAtMost = 4,
// clang-format on
};
bool matches(const GpgME::Key &key, MatchContexts ctx) const override;
bool matches(const GpgME::UserID &userID, MatchContexts ctx) const override;
unsigned int specificity() const override;
void setSpecificity(unsigned int value);
QString id() const override;
void setId(const QString &value);
KeyFilter::MatchContexts availableMatchContexts() const override;
void setMatchContexts(KeyFilter::MatchContexts value);
QColor fgColor() const override;
void setFgColor(const QColor &value);
QColor bgColor() const override;
void setBgColor(const QColor &value);
FontDescription fontDescription() const override;
QString name() const override;
void setName(const QString &value);
QString icon() const override;
void setIcon(const QString &value);
QFont font() const;
void setFont(const QFont &value);
+ QString description() const override;
+ void setDescription(const QString &description);
TriState revoked() const;
TriState expired() const;
TriState invalid() const;
TriState disabled() const;
TriState root() const;
TriState canEncrypt() const;
TriState canSign() const;
TriState canCertify() const;
TriState canAuthenticate() const;
TriState hasEncrypt() const;
TriState hasSign() const;
TriState hasCertify() const;
TriState hasAuthenticate() const;
TriState qualified() const;
TriState cardKey() const;
TriState hasSecret() const;
TriState isOpenPGP() const;
TriState wasValidated() const;
TriState isDeVS() const;
TriState isBad() const;
LevelState ownerTrust() const;
GpgME::Key::OwnerTrust ownerTrustReferenceLevel() const;
LevelState validity() const;
GpgME::UserID::Validity validityReferenceLevel() const;
bool italic() const;
bool bold() const;
bool strikeOut() const;
bool useFullFont() const;
void setRevoked(const TriState);
void setExpired(const TriState);
void setInvalid(const TriState);
void setDisabled(const TriState);
void setRoot(const TriState);
void setCanEncrypt(const TriState);
void setCanSign(const TriState);
void setCanCertify(const TriState);
void setCanAuthenticate(const TriState);
void setHasEncrypt(const TriState);
void setHasSign(const TriState);
void setHasCertify(const TriState);
void setHasAuthenticate(const TriState);
void setQualified(const TriState);
void setCardKey(const TriState);
void setHasSecret(const TriState);
void setIsOpenPGP(const TriState);
void setWasValidated(const TriState);
void setIsDeVs(const TriState);
void setIsBad(const TriState);
/**
* If \p value is \c Set, then invalid S/MIME certificates do not match.
* If \p value is \c NotSet, then valid S/MIME certificates do not match.
*/
void setValidIfSMIME(TriState value);
TriState validIfSMIME() const;
void setOwnerTrust(const LevelState);
void setOwnerTrustReferenceLevel(const GpgME::Key::OwnerTrust);
void setValidity(const LevelState);
void setValidityReferenceLevel(const GpgME::UserID::Validity);
void setItalic(bool value);
void setBold(bool value);
void setStrikeOut(bool value);
void setUseFullFont(bool value);
private:
class Private;
const std::unique_ptr<Private> d;
};
} // namespace Kleo
diff --git a/src/kleo/kconfigbasedkeyfilter.cpp b/src/kleo/kconfigbasedkeyfilter.cpp
index ddd9ce74..7e9704e1 100644
--- a/src/kleo/kconfigbasedkeyfilter.cpp
+++ b/src/kleo/kconfigbasedkeyfilter.cpp
@@ -1,249 +1,250 @@
/*
kconfigbasedkeyfilter.cpp
This file is part of libkleopatra, the KDE keymanagement library
SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-libkleo.h>
#include "kconfigbasedkeyfilter.h"
#include <KConfigBase>
#include <KConfigGroup>
#include <QDebug>
#include <QRegularExpression>
#include <algorithm>
using namespace Kleo;
using namespace GpgME;
//
//
// FontDescription - intuitive font property resolving
// (QFont::resolve doesn't work for us)
//
//
struct KeyFilter::FontDescription::Private {
bool bold, italic, strikeOut, fullFont;
QFont font;
};
KeyFilter::FontDescription::FontDescription()
: d(new Private)
{
d->bold = d->italic = d->strikeOut = d->fullFont = false;
}
KeyFilter::FontDescription::FontDescription(const FontDescription &other)
: d(new Private(*other.d))
{
}
KeyFilter::FontDescription::~FontDescription() = default;
KeyFilter::FontDescription KeyFilter::FontDescription::create(bool b, bool i, bool s)
{
FontDescription fd;
fd.d->bold = b;
fd.d->italic = i;
fd.d->strikeOut = s;
return fd;
}
KeyFilter::FontDescription KeyFilter::FontDescription::create(const QFont &f, bool b, bool i, bool s)
{
FontDescription fd;
fd.d->fullFont = true;
fd.d->font = f;
fd.d->bold = b;
fd.d->italic = i;
fd.d->strikeOut = s;
return fd;
}
QFont KeyFilter::FontDescription::font(const QFont &base) const
{
QFont font;
if (d->fullFont) {
font = d->font;
font.setPointSize(base.pointSize());
} else {
font = base;
}
if (d->bold) {
font.setBold(true);
}
if (d->italic) {
font.setItalic(true);
}
if (d->strikeOut) {
font.setStrikeOut(true);
}
return font;
}
KeyFilter::FontDescription KeyFilter::FontDescription::resolve(const FontDescription &other) const
{
FontDescription fd;
fd.d->fullFont = this->d->fullFont || other.d->fullFont;
if (fd.d->fullFont) {
fd.d->font = this->d->fullFont ? this->d->font : other.d->font;
}
fd.d->bold = this->d->bold || other.d->bold;
fd.d->italic = this->d->italic || other.d->italic;
fd.d->strikeOut = this->d->strikeOut || other.d->strikeOut;
return fd;
}
static const struct {
const char *name;
Key::OwnerTrust trust;
UserID::Validity validity;
} ownerTrustAndValidityMap[] = {
// clang-format off
{"unknown", Key::Unknown, UserID::Unknown },
{"undefined", Key::Undefined, UserID::Undefined},
{"never", Key::Never, UserID::Never },
{"marginal", Key::Marginal, UserID::Marginal },
{"full", Key::Full, UserID::Full },
{"ultimate", Key::Ultimate, UserID::Ultimate },
// clang-format on
};
static Key::OwnerTrust map2OwnerTrust(const QString &s)
{
for (unsigned int i = 0; i < sizeof ownerTrustAndValidityMap / sizeof *ownerTrustAndValidityMap; ++i) {
if (s.toLower() == QLatin1String(ownerTrustAndValidityMap[i].name)) {
return ownerTrustAndValidityMap[i].trust;
}
}
return ownerTrustAndValidityMap[0].trust;
}
static UserID::Validity map2Validity(const QString &s)
{
for (unsigned int i = 0; i < sizeof ownerTrustAndValidityMap / sizeof *ownerTrustAndValidityMap; ++i) {
if (s.toLower() == QLatin1String(ownerTrustAndValidityMap[i].name)) {
return ownerTrustAndValidityMap[i].validity;
}
}
return ownerTrustAndValidityMap[0].validity;
}
KConfigBasedKeyFilter::KConfigBasedKeyFilter(const KConfigGroup &config)
: DefaultKeyFilter()
{
setFgColor(config.readEntry<QColor>("foreground-color", QColor()));
setBgColor(config.readEntry<QColor>("background-color", QColor()));
setName(config.readEntry("Name", config.name()));
+ setDescription(config.readEntry("Description", QString()));
setIcon(config.readEntry("icon"));
setId(config.readEntry("id", config.name()));
if (config.hasKey("font")) {
setUseFullFont(true);
setFont(config.readEntry("font"));
} else {
setUseFullFont(false);
setItalic(config.readEntry("font-italic", false));
setBold(config.readEntry("font-bold", false));
}
setStrikeOut(config.readEntry("font-strikeout", false));
#ifdef SET
#undef SET
#endif
#define SET(member, key) \
if (config.hasKey(key)) { \
set##member(config.readEntry(key, false) ? Set : NotSet); \
setSpecificity(specificity() + 1); \
}
SET(Revoked, "is-revoked");
SET(Expired, "is-expired");
SET(Disabled, "is-disabled");
SET(Root, "is-root-certificate");
SET(CanEncrypt, "can-encrypt");
SET(CanSign, "can-sign");
SET(CanCertify, "can-certify");
SET(CanAuthenticate, "can-authenticate");
SET(HasEncrypt, "has-encrypt");
SET(HasSign, "has-sign");
SET(HasCertify, "has-certify");
SET(HasAuthenticate, "has-authenticate");
SET(Qualified, "is-qualified");
SET(CardKey, "is-cardkey");
SET(HasSecret, "has-secret-key");
SET(IsOpenPGP, "is-openpgp-key");
SET(WasValidated, "was-validated");
SET(IsDeVs, "is-de-vs");
#undef SET
static const struct {
const char *prefix;
LevelState state;
} prefixMap[] = {
{"is-", Is},
{"is-not-", IsNot},
{"is-at-least-", IsAtLeast},
{"is-at-most-", IsAtMost},
};
for (unsigned int i = 0; i < sizeof prefixMap / sizeof *prefixMap; ++i) {
const QString key = QLatin1String(prefixMap[i].prefix) + QLatin1String("ownertrust");
if (config.hasKey(key)) {
setOwnerTrust(prefixMap[i].state);
setOwnerTrustReferenceLevel(map2OwnerTrust(config.readEntry(key, QString())));
setSpecificity(specificity() + 1);
break;
}
}
for (unsigned int i = 0; i < sizeof prefixMap / sizeof *prefixMap; ++i) {
const QString key = QLatin1String(prefixMap[i].prefix) + QLatin1String("validity");
if (config.hasKey(key)) {
setValidity(prefixMap[i].state);
setValidityReferenceLevel(map2Validity(config.readEntry(key, QString())));
setSpecificity(specificity() + 1);
break;
}
}
if (config.hasKey("specificity")) {
setSpecificity(config.readEntry("specificity", 0u));
}
static const struct {
const char *key;
MatchContext context;
} matchMap[] = {
{"any", AnyMatchContext},
{"appearance", Appearance},
{"filtering", Filtering},
};
static const QRegularExpression reg(QRegularExpression(QLatin1String("[^a-z!]+")));
const QStringList contexts = config.readEntry("match-contexts", "any").toLower().split(reg, Qt::SkipEmptyParts);
setMatchContexts(NoMatchContext);
for (const QString &ctx : contexts) {
bool found = false;
for (unsigned int i = 0; i < sizeof matchMap / sizeof *matchMap; ++i) {
if (ctx == QLatin1String(matchMap[i].key)) {
setMatchContexts(availableMatchContexts() |= matchMap[i].context);
found = true;
break;
} else if (ctx.startsWith(QLatin1Char('!')) && ctx.mid(1) == QLatin1String(matchMap[i].key)) {
setMatchContexts(availableMatchContexts() &= matchMap[i].context);
found = true;
break;
}
}
if (!found) {
qWarning() << QStringLiteral("KConfigBasedKeyFilter: found unknown match context '%1' in group '%2'").arg(ctx, config.name());
}
}
if (availableMatchContexts() == NoMatchContext) {
qWarning() << QStringLiteral(
"KConfigBasedKeyFilter: match context in group '%1' evaluates to NoMatchContext, "
"replaced by AnyMatchContext")
.arg(config.name());
setMatchContexts(AnyMatchContext);
}
}
diff --git a/src/kleo/keyfilter.h b/src/kleo/keyfilter.h
index 67af7438..c8da52a1 100644
--- a/src/kleo/keyfilter.h
+++ b/src/kleo/keyfilter.h
@@ -1,106 +1,107 @@
/*
keyfilter.h
This file is part of libkleopatra, the KDE keymanagement library
SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "kleo_export.h"
#include <QFlags>
#include <algorithm>
#include <memory>
namespace GpgME
{
class Key;
class UserID;
}
class QFont;
class QColor;
class QString;
namespace Kleo
{
/**
@short An abstract base class key filters
*/
class KLEO_EXPORT KeyFilter
{
public:
virtual ~KeyFilter()
{
}
enum MatchContext {
// clang-format off
NoMatchContext = 0x0,
Appearance = 0x1,
Filtering = 0x2,
AnyMatchContext = Appearance | Filtering
// clang-format on
};
Q_DECLARE_FLAGS(MatchContexts, MatchContext)
virtual bool matches(const GpgME::Key &key, MatchContexts ctx) const = 0;
virtual bool matches(const GpgME::UserID &userID, MatchContexts ctx) const = 0;
virtual unsigned int specificity() const = 0;
virtual QString id() const = 0;
virtual MatchContexts availableMatchContexts() const = 0;
// not sure if we want these here, but for the time being, it's
// the easiest way:
virtual QColor fgColor() const = 0;
virtual QColor bgColor() const = 0;
virtual QString name() const = 0;
virtual QString icon() const = 0;
+ virtual QString description() const = 0;
class FontDescription
{
public:
FontDescription();
FontDescription(const FontDescription &other);
FontDescription &operator=(const FontDescription &other)
{
FontDescription copy(other);
swap(copy);
return *this;
}
~FontDescription();
static FontDescription create(bool bold, bool italic, bool strikeOut);
static FontDescription create(const QFont &font, bool bold, bool italic, bool strikeOut);
QFont font(const QFont &base) const;
FontDescription resolve(const FontDescription &other) const;
void swap(FontDescription &other)
{
std::swap(this->d, other.d);
}
struct Private;
private:
std::unique_ptr<Private> d;
};
virtual FontDescription fontDescription() const = 0;
};
}
Q_DECLARE_OPERATORS_FOR_FLAGS(Kleo::KeyFilter::MatchContexts)
#include <QObject>
Q_DECLARE_METATYPE(Kleo::KeyFilter::MatchContexts)
diff --git a/src/kleo/keyfiltermanager.cpp b/src/kleo/keyfiltermanager.cpp
index c77b5ba1..72d50c22 100644
--- a/src/kleo/keyfiltermanager.cpp
+++ b/src/kleo/keyfiltermanager.cpp
@@ -1,630 +1,638 @@
/*
keyfiltermanager.cpp
This file is part of libkleopatra, the KDE keymanagement library
SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-libkleo.h>
#include "keyfiltermanager.h"
#include "defaultkeyfilter.h"
#include "kconfigbasedkeyfilter.h"
#include "stl_util.h"
#include <libkleo/algorithm.h>
#include <libkleo/compliance.h>
#include <libkleo/gnupg.h>
#include <libkleo/keyhelpers.h>
#include <libkleo_debug.h>
#include <KConfig>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig>
#include <QAbstractListModel>
#include <QCoreApplication>
#include <QIcon>
#include <QModelIndex>
#include <QRegularExpression>
#include <QStringList>
#include <algorithm>
#include <climits>
#include <functional>
using namespace Kleo;
using namespace GpgME;
Q_DECLARE_METATYPE(std::shared_ptr<KeyFilter>)
namespace
{
void adjustFilters(std::vector<std::shared_ptr<KeyFilter>> &filters, Protocol protocol)
{
if (protocol != GpgME::UnknownProtocol) {
// remove filters with conflicting isOpenPGP rule
const auto conflictingValue = (protocol == GpgME::OpenPGP) ? DefaultKeyFilter::NotSet : DefaultKeyFilter::Set;
Kleo::erase_if(filters, [conflictingValue](const auto &f) {
const auto filter = std::dynamic_pointer_cast<DefaultKeyFilter>(f);
Q_ASSERT(filter);
return filter->isOpenPGP() == conflictingValue;
});
// add isOpenPGP rule to all filters
const auto isOpenPGPValue = (protocol == GpgME::OpenPGP) ? DefaultKeyFilter::Set : DefaultKeyFilter::NotSet;
std::for_each(std::begin(filters), std::end(filters), [isOpenPGPValue](auto &f) {
const auto filter = std::dynamic_pointer_cast<DefaultKeyFilter>(f);
Q_ASSERT(filter);
return filter->setIsOpenPGP(isOpenPGPValue);
});
}
}
class Model : public QAbstractListModel
{
KeyFilterManager::Private *m_keyFilterManagerPrivate;
public:
explicit Model(KeyFilterManager::Private *p)
: QAbstractListModel(nullptr)
, m_keyFilterManagerPrivate(p)
{
}
int rowCount(const QModelIndex &) const override;
QVariant data(const QModelIndex &idx, int role) const override;
/* upgrade to public */ using QAbstractListModel::beginResetModel;
/* upgrade to public */ using QAbstractListModel::endResetModel;
};
class AllCertificatesKeyFilter : public DefaultKeyFilter
{
public:
AllCertificatesKeyFilter()
: DefaultKeyFilter()
{
setSpecificity(UINT_MAX); // overly high for ordering
setName(i18nc("All Certificates", "All"));
+ setDescription(i18n("All certificates"));
setId(QStringLiteral("all-certificates"));
setMatchContexts(Filtering);
}
};
class MyCertificatesKeyFilter : public DefaultKeyFilter
{
public:
MyCertificatesKeyFilter()
: DefaultKeyFilter()
{
setHasSecret(Set);
setSpecificity(UINT_MAX - 2); // overly high for ordering
setName(i18nc("My own Certificates", "My Own"));
+ setDescription(i18n("My own certificates"));
setId(QStringLiteral("my-certificates"));
setMatchContexts(AnyMatchContext);
setBold(true);
}
};
class FullCertificatesKeyFilter : public DefaultKeyFilter
{
public:
FullCertificatesKeyFilter()
: DefaultKeyFilter()
{
setRevoked(NotSet);
setValidity(IsAtLeast);
setValidityReferenceLevel(UserID::Full);
setSpecificity(UINT_MAX - 4);
setName(i18nc("Certified Certificates", "Certified"));
+ setDescription(i18n("Certificates for which the primary user ID is certified"));
setId(QStringLiteral("trusted-certificates"));
setMatchContexts(Filtering);
}
};
class OtherCertificatesKeyFilter : public DefaultKeyFilter
{
public:
OtherCertificatesKeyFilter()
: DefaultKeyFilter()
{
setHasSecret(NotSet);
setValidity(IsAtMost);
setValidityReferenceLevel(UserID::Marginal);
setSpecificity(UINT_MAX - 6); // overly high for ordering
setName(i18nc("Not Certified Certificates", "Not Certified"));
+ setDescription(i18n("Certificates for which the primary user ID is not certified"));
setId(QStringLiteral("other-certificates"));
setMatchContexts(Filtering);
}
};
/* This filter selects uncertified OpenPGP keys, i.e. "good" OpenPGP keys with
* unrevoked user IDs that are not fully valid. */
class UncertifiedOpenPGPKeysFilter : public DefaultKeyFilter
{
public:
UncertifiedOpenPGPKeysFilter()
: DefaultKeyFilter()
{
setSpecificity(UINT_MAX - 7); // overly high for ordering
setName(i18nc("Certificates to certify by the user", "To Certify"));
+ setDescription(i18n("Certificates that are not fully certified and that you may want to certify yourself"));
setId(QStringLiteral("not-certified-certificates"));
setMatchContexts(Filtering);
setIsOpenPGP(Set);
setIsBad(NotSet);
}
bool matches(const Key &key, MatchContexts contexts) const override
{
return DefaultKeyFilter::matches(key, contexts) && !Kleo::allUserIDsHaveFullValidity(key);
}
bool matches(const UserID &userID, MatchContexts contexts) const override
{
return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() < UserID::Full;
}
};
/* This filter selects only invalid keys (i.e. those where not all
* UIDs are at least fully valid). */
class KeyNotValidFilter : public DefaultKeyFilter
{
public:
KeyNotValidFilter()
: DefaultKeyFilter()
{
setSpecificity(UINT_MAX - 5); // overly high for ordering
setName(i18nc("Not Fully Certified Certificates", "Not Fully Certified"));
+ setDescription(i18n("Certificates for which not all user IDs are certified"));
setId(QStringLiteral("not-validated-certificates"));
setMatchContexts(Filtering);
}
bool matches(const Key &key, MatchContexts contexts) const override
{
return DefaultKeyFilter::matches(key, contexts) && !Kleo::allUserIDsHaveFullValidity(key);
}
bool matches(const UserID &userID, MatchContexts contexts) const override
{
return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() < UserID::Full;
}
};
}
class KeyFullyCertifiedFilter : public DefaultKeyFilter
{
public:
KeyFullyCertifiedFilter()
: DefaultKeyFilter()
{
setSpecificity(UINT_MAX - 3);
setName(i18nc("Fully Certified Certificates", "Fully Certified"));
+ setDescription(i18n("Certificates for which all user IDs are certified"));
setId(QStringLiteral("full-certificates"));
setMatchContexts(Filtering);
}
bool matches(const Key &key, MatchContexts contexts) const override
{
return DefaultKeyFilter::matches(key, contexts) && Kleo::allUserIDsHaveFullValidity(key);
}
bool matches(const UserID &userID, MatchContexts contexts) const override
{
return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() >= UserID::Full;
}
};
static std::vector<std::shared_ptr<KeyFilter>> defaultFilters()
{
return {
std::shared_ptr<KeyFilter>(new MyCertificatesKeyFilter),
std::shared_ptr<KeyFilter>(new FullCertificatesKeyFilter),
std::shared_ptr<KeyFilter>(new OtherCertificatesKeyFilter),
std::shared_ptr<KeyFilter>(new AllCertificatesKeyFilter),
std::shared_ptr<KeyFilter>(new UncertifiedOpenPGPKeysFilter),
std::shared_ptr<KeyFilter>(new KeyFullyCertifiedFilter),
std::shared_ptr<KeyFilter>(new KeyNotValidFilter),
};
}
class KeyFilterManager::Private
{
public:
Private()
: filters()
, model(this)
{
}
void clear()
{
model.beginResetModel();
filters.clear();
model.endResetModel();
}
std::vector<std::shared_ptr<KeyFilter>> filters;
Model model;
GpgME::Protocol protocol = GpgME::UnknownProtocol;
};
KeyFilterManager *KeyFilterManager::mSelf = nullptr;
KeyFilterManager::KeyFilterManager(QObject *parent)
: QObject(parent)
, d(new Private)
{
mSelf = this;
// ### DF: doesn't a KStaticDeleter work more reliably?
if (QCoreApplication *app = QCoreApplication::instance()) {
connect(app, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
}
reload();
}
KeyFilterManager::~KeyFilterManager()
{
mSelf = nullptr;
if (d) {
d->clear();
}
}
KeyFilterManager *KeyFilterManager::instance()
{
if (!mSelf) {
mSelf = new KeyFilterManager();
}
return mSelf;
}
void KeyFilterManager::alwaysFilterByProtocol(GpgME::Protocol protocol)
{
if (protocol != d->protocol) {
d->protocol = protocol;
reload();
Q_EMIT alwaysFilterByProtocolChanged(protocol);
}
}
const std::shared_ptr<KeyFilter> &KeyFilterManager::filterMatching(const Key &key, KeyFilter::MatchContexts contexts) const
{
const auto it = std::find_if(d->filters.cbegin(), d->filters.cend(), [&key, contexts](const std::shared_ptr<KeyFilter> &filter) {
return filter->matches(key, contexts);
});
if (it != d->filters.cend()) {
return *it;
}
static const std::shared_ptr<KeyFilter> null;
return null;
}
std::vector<std::shared_ptr<KeyFilter>> KeyFilterManager::filtersMatching(const Key &key, KeyFilter::MatchContexts contexts) const
{
std::vector<std::shared_ptr<KeyFilter>> result;
result.reserve(d->filters.size());
std::remove_copy_if(d->filters.begin(), d->filters.end(), std::back_inserter(result), [&key, contexts](const std::shared_ptr<KeyFilter> &filter) {
return !filter->matches(key, contexts);
});
return result;
}
namespace
{
static const auto byDecreasingSpecificity = [](const std::shared_ptr<KeyFilter> &lhs, const std::shared_ptr<KeyFilter> &rhs) {
return lhs->specificity() > rhs->specificity();
};
}
void KeyFilterManager::reload()
{
d->clear();
d->filters = defaultFilters();
KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("libkleopatrarc"));
const QStringList groups = config->groupList().filter(QRegularExpression(QStringLiteral("^Key Filter #\\d+$")));
const bool ignoreDeVs = !DeVSCompliance::isCompliant();
for (QStringList::const_iterator it = groups.begin(); it != groups.end(); ++it) {
const KConfigGroup cfg(config, *it);
if (cfg.hasKey("is-de-vs") && ignoreDeVs) {
/* Don't show de-vs filters in other compliance modes */
continue;
}
d->filters.push_back(std::shared_ptr<KeyFilter>(new KConfigBasedKeyFilter(cfg)));
}
std::stable_sort(d->filters.begin(), d->filters.end(), byDecreasingSpecificity);
adjustFilters(d->filters, d->protocol);
qCDebug(LIBKLEO_LOG) << "KeyFilterManager::" << __func__ << "final filter count is" << d->filters.size();
}
QAbstractItemModel *KeyFilterManager::model() const
{
return &d->model;
}
const std::shared_ptr<KeyFilter> &KeyFilterManager::keyFilterByID(const QString &id) const
{
const auto it = std::find_if(d->filters.begin(), d->filters.end(), [id](const std::shared_ptr<KeyFilter> &filter) {
return filter->id() == id;
});
if (it != d->filters.end()) {
return *it;
}
static const std::shared_ptr<KeyFilter> null;
return null;
}
const std::shared_ptr<KeyFilter> &KeyFilterManager::fromModelIndex(const QModelIndex &idx) const
{
if (!idx.isValid() || idx.model() != &d->model || idx.row() < 0 || static_cast<unsigned>(idx.row()) >= d->filters.size()) {
static const std::shared_ptr<KeyFilter> null;
return null;
}
return d->filters[idx.row()];
}
QModelIndex KeyFilterManager::toModelIndex(const std::shared_ptr<KeyFilter> &kf) const
{
if (!kf) {
return {};
}
const auto pair = std::equal_range(d->filters.cbegin(), d->filters.cend(), kf, byDecreasingSpecificity);
const auto it = std::find(pair.first, pair.second, kf);
if (it != pair.second) {
return d->model.index(it - d->filters.begin());
} else {
return QModelIndex();
}
}
int Model::rowCount(const QModelIndex &) const
{
return m_keyFilterManagerPrivate->filters.size();
}
QVariant Model::data(const QModelIndex &idx, int role) const
{
if (!idx.isValid() || idx.model() != this || idx.row() < 0 || static_cast<unsigned>(idx.row()) > m_keyFilterManagerPrivate->filters.size()) {
return QVariant();
}
const auto filter = m_keyFilterManagerPrivate->filters[idx.row()];
switch (role) {
case Qt::DecorationRole:
return filter->icon();
case Qt::DisplayRole:
case Qt::EditRole:
- case Qt::ToolTipRole: /* Most useless tooltip ever. */
return filter->name();
+ case Qt::ToolTipRole:
+ return filter->description();
case KeyFilterManager::FilterIdRole:
return filter->id();
case KeyFilterManager::FilterMatchContextsRole:
return QVariant::fromValue(filter->availableMatchContexts());
case KeyFilterManager::FilterRole:
return QVariant::fromValue(filter);
default:
return QVariant();
}
}
static KeyFilter::FontDescription
get_fontdescription(const std::vector<std::shared_ptr<KeyFilter>> &filters, const Key &key, const KeyFilter::FontDescription &initial)
{
return kdtools::accumulate_if(
filters.begin(),
filters.end(),
[&key](const std::shared_ptr<KeyFilter> &filter) {
return filter->matches(key, KeyFilter::Appearance);
},
initial,
[](const KeyFilter::FontDescription &lhs, const std::shared_ptr<KeyFilter> &rhs) {
return lhs.resolve(rhs->fontDescription());
});
}
QFont KeyFilterManager::font(const Key &key, const QFont &baseFont) const
{
const KeyFilter::FontDescription fd = get_fontdescription(d->filters, key, KeyFilter::FontDescription());
return fd.font(baseFont);
}
static QColor get_color(const std::vector<std::shared_ptr<KeyFilter>> &filters, const Key &key, QColor (KeyFilter::*fun)() const)
{
const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &key](const std::shared_ptr<KeyFilter> &filter) {
return filter->matches(key, KeyFilter::Appearance) && (filter.get()->*fun)().isValid();
});
if (it == filters.cend()) {
return {};
} else {
return (it->get()->*fun)();
}
}
static QColor get_color(const std::vector<std::shared_ptr<KeyFilter>> &filters, const UserID &userID, QColor (KeyFilter::*fun)() const)
{
const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &userID](const std::shared_ptr<KeyFilter> &filter) {
return filter->matches(userID, KeyFilter::Appearance) && (filter.get()->*fun)().isValid();
});
if (it == filters.cend()) {
return {};
} else {
return (it->get()->*fun)();
}
}
static QString get_string(const std::vector<std::shared_ptr<KeyFilter>> &filters, const Key &key, QString (KeyFilter::*fun)() const)
{
const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &key](const std::shared_ptr<KeyFilter> &filter) {
return filter->matches(key, KeyFilter::Appearance) && !(filter.get()->*fun)().isEmpty();
});
if (it == filters.cend()) {
return QString();
} else {
return (*it)->icon();
}
}
QColor KeyFilterManager::bgColor(const Key &key) const
{
return get_color(d->filters, key, &KeyFilter::bgColor);
}
QColor KeyFilterManager::fgColor(const Key &key) const
{
return get_color(d->filters, key, &KeyFilter::fgColor);
}
QColor KeyFilterManager::bgColor(const UserID &userID) const
{
return get_color(d->filters, userID, &KeyFilter::bgColor);
}
QColor KeyFilterManager::fgColor(const UserID &userID) const
{
return get_color(d->filters, userID, &KeyFilter::fgColor);
}
QIcon KeyFilterManager::icon(const Key &key) const
{
const QString icon = get_string(d->filters, key, &KeyFilter::icon);
return icon.isEmpty() ? QIcon() : QIcon::fromTheme(icon);
}
Protocol KeyFilterManager::protocol() const
{
return d->protocol;
}
class KeyFilterModel::Private
{
friend class KeyFilterModel;
std::vector<std::shared_ptr<KeyFilter>> customFilters;
};
KeyFilterModel::KeyFilterModel(QObject *parent)
: QSortFilterProxyModel(parent)
, d(new Private)
{
setSourceModel(KeyFilterManager::instance()->model());
connect(KeyFilterManager::instance(), &KeyFilterManager::alwaysFilterByProtocolChanged, this, [this](auto protocol) {
beginResetModel();
adjustFilters(d->customFilters, protocol);
endResetModel();
});
}
KeyFilterModel::~KeyFilterModel() = default;
void KeyFilterModel::prependCustomFilter(const std::shared_ptr<KeyFilter> &filter)
{
beginResetModel();
d->customFilters.insert(d->customFilters.begin(), filter);
adjustFilters(d->customFilters, KeyFilterManager::instance()->protocol());
endResetModel();
}
bool KeyFilterModel::isCustomFilter(int row) const
{
return (row >= 0) && (row < int(d->customFilters.size()));
}
int KeyFilterModel::rowCount(const QModelIndex &parent) const
{
return d->customFilters.size() + QSortFilterProxyModel::rowCount(parent);
}
int KeyFilterModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
// pretend that there is only one column to workaround a bug in
// QAccessibleTable which provides the accessibility interface for the
// pop-up of the combo box
return 1;
}
QModelIndex KeyFilterModel::mapToSource(const QModelIndex &index) const
{
if (!index.isValid()) {
return {};
}
if (!isCustomFilter(index.row())) {
const int sourceRow = index.row() - d->customFilters.size();
return QSortFilterProxyModel::mapToSource(createIndex(sourceRow, index.column(), index.internalPointer()));
}
return {};
}
QModelIndex KeyFilterModel::mapFromSource(const QModelIndex &source_index) const
{
const QModelIndex idx = QSortFilterProxyModel::mapFromSource(source_index);
return createIndex(d->customFilters.size() + idx.row(), idx.column(), idx.internalPointer());
}
QModelIndex KeyFilterModel::index(int row, int column, const QModelIndex &parent) const
{
if (row < 0 || row >= rowCount()) {
return {};
}
if (row < int(d->customFilters.size())) {
return createIndex(row, column, nullptr);
} else {
const QModelIndex mi = QSortFilterProxyModel::index(row - d->customFilters.size(), column, parent);
return createIndex(row, column, mi.internalPointer());
}
}
Qt::ItemFlags KeyFilterModel::flags(const QModelIndex &index) const
{
Q_UNUSED(index)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren;
}
QModelIndex KeyFilterModel::parent(const QModelIndex &) const
{
// Flat list
return {};
}
QVariant KeyFilterModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return QVariant();
}
if (isCustomFilter(index.row())) {
const auto filter = d->customFilters[index.row()];
switch (role) {
case Qt::DecorationRole:
return filter->icon();
case Qt::DisplayRole:
case Qt::EditRole:
return filter->name();
case KeyFilterManager::FilterIdRole:
return filter->id();
case KeyFilterManager::FilterMatchContextsRole:
return QVariant::fromValue(filter->availableMatchContexts());
case KeyFilterManager::FilterRole:
return QVariant::fromValue(filter);
default:
return QVariant();
}
}
return QSortFilterProxyModel::data(index, role);
}
diff --git a/src/libkleopatrarc-win32.desktop b/src/libkleopatrarc-win32.desktop
index 25130671..c7fd50e1 100644
--- a/src/libkleopatrarc-win32.desktop
+++ b/src/libkleopatrarc-win32.desktop
@@ -1,413 +1,427 @@
[Archive Definition #0]
extensions-openpgp=tar
extensions-cms=tar.gz,tgz
id=tar
Name=TAR (PGP®-compatible)
Name[ar]=‏TAR (متوافق مع PGP®)
Name[ca]=TAR (compatible amb PGP®)
Name[ca@valencia]=TAR (compatible amb PGP®)
Name[cs]=TAR (PGP® kompatibilní)
Name[da]=TAR (PGP®-kompatibel)
Name[de]=TAR (PGP®-kompatibel)
Name[en_GB]=TAR (PGP®-compatible)
Name[eo]=TAR (PGP®-kongrua)
Name[es]=TAR (compatible PGP®)
Name[et]=TAR (PGP® ühilduv)
Name[eu]=TAR (PGP®-rekin bateragarria)
Name[fi]=TAR (PGP-yhteensopiva)
Name[fr]=TAR (compatible PGP®)
Name[gl]=TAR (compatíbel con PGP®)
Name[hu]=TAR (PGP® kompatibilis)
Name[ia]=TAR (compatibile con PGP®)
Name[ie]=TAR (compatibil con PGP®)
Name[it]=TAR (compatibile PGP®)
Name[ja]=TAR (PGP® 互換)
Name[ka]=TAR (PGP®-თავსებადი)
Name[ko]=TAR(PGP® 호환)
Name[nb]=TAR (PGP®-kompatibel)
Name[nl]=TAR (PGP®-compatible)
Name[nn]=TAR (PGP®-kompatibel)
Name[pl]=TAR (zgodny z PGP®)
Name[pt]=TAR (compatível com o PGP®)
Name[pt_BR]=TAR (compatível com PGP®)
Name[ru]=TAR (PGP®-совместимый)
Name[sk]=TAR (PGP® kompatibilné)
Name[sl]=TAR (združljiv s PGP®)
Name[sr]=тар (ПГП®-сагласно)
Name[sr@ijekavian]=тар (ПГП®-сагласно)
Name[sr@ijekavianlatin]=tar (PGP®-saglasno)
Name[sr@latin]=tar (PGP®-saglasno)
Name[sv]=TAR (fungerar med PGP®)
Name[tr]=TAR (PGP®-uyumlu)
Name[uk]=TAR (сумісні з PGP®)
Name[x-test]=xxTAR (PGP®-compatible)xx
Name[zh_CN]=TAR(PGP® 兼容)
Name[zh_TW]=TAR (相容 PGP®)
pack-command-openpgp=0|%I/gpgtar --utf8-strings --openpgp --skip-crypto --output - --encrypt -T- --null --
pack-command-cms=0|%I/gpgtar --utf8-strings --cms --skip-crypto --output - --encrypt -T- --null --
unpack-command-openpgp=%I/gpgtar --utf8-strings --openpgp --skip-crypto --set-filename %F --decrypt -- -
unpack-command-cms=%I/gpgtar --utf8-strings --cms --skip-crypto --set-filename %F --decrypt -- -
[Checksum Definition #0]
file-patterns=sha256sum.txt,.*\\\\.sha256,.*\\\\.sha2
output-file=sha256sum.txt
id=sha256sum
Name=sha256sum
Name[ar]=تدقيق SHA256
Name[ca]=sha256sum
Name[ca@valencia]=sha256sum
Name[cs]=sha256sum
Name[da]=sha256sum
Name[de]=sha256sum
Name[en_GB]=sha256sum
Name[eo]=sha256sum
Name[es]=sha256sum
Name[et]=sha256sum
Name[eu]=sha256sum
Name[fi]=sha256sum
Name[fr]=sha256sum
Name[gl]=sha256sum
Name[hu]=sha256sum
Name[ia]=sha256sum
Name[ie]=sha256sum
Name[it]=sha256sum
Name[ja]=sha256sum
Name[ka]=sha256sum
Name[ko]=sha256sum
Name[nb]=sha256sum
Name[nl]=sha256sum
Name[nn]=sha256sum
Name[pl]=sha256sum
Name[pt]=sha256sum
Name[pt_BR]=sha256sum
Name[ru]=sha256sum
Name[sk]=sha256sum
Name[sl]=sha256sum
Name[sr]=СХА‑256 сума
Name[sr@ijekavian]=СХА‑256 сума
Name[sr@ijekavianlatin]=SHA‑256 suma
Name[sr@latin]=SHA‑256 suma
Name[sv]=SHA256-summa
Name[tr]=sha256sum
Name[uk]=sha256sum
Name[x-test]=xxsha256sumxx
Name[zh_CN]=sha256sum
Name[zh_TW]=sha256sum
create-command=0|%I/sha256sum -0 -
verify-command=%I/sha256sum -c
[Checksum Definition #1]
file-patterns=sha1sum.txt,.*\\\\.sha1
output-file=sha1sum.txt
id=sha1sum
Name=sha1sum
Name[ar]=تدقيق SHA1
Name[ca]=sha1sum
Name[ca@valencia]=sha1sum
Name[cs]=sha1sum
Name[da]=sha1sum
Name[de]=sha1sum
Name[en_GB]=sha1sum
Name[eo]=sha1sum
Name[es]=sha1sum
Name[et]=sha1sum
Name[eu]=sha1sum
Name[fi]=sha1sum
Name[fr]=sha1sum
Name[gl]=sha1sum
Name[hu]=sha1sum
Name[ia]=sha1sum
Name[ie]=sha1sum
Name[it]=sha1sum
Name[ja]=sha1sum
Name[ka]=sha1sum
Name[ko]=sha1sum
Name[nb]=sha1sum
Name[nl]=sha1sum
Name[nn]=sha1sum
Name[pl]=sha1sum
Name[pt]=sha1sum
Name[pt_BR]=sha1sum
Name[ru]=sha1sum
Name[sk]=sha1sum
Name[sl]=sha1sum
Name[sr]=СХА‑1 сума
Name[sr@ijekavian]=СХА‑1 сума
Name[sr@ijekavianlatin]=SHA‑1 suma
Name[sr@latin]=SHA‑1 suma
Name[sv]=SHA1-summa
Name[tr]=sha1sum
Name[uk]=sha1sum
Name[x-test]=xxsha1sumxx
Name[zh_CN]=sha1sum
Name[zh_TW]=sha1sum
create-command=0|%I/sha1sum -0 -
verify-command=%I/sha1sum -c
[Checksum Definition #2]
file-patterns=md5sum.txt,.*\\\\.md5
output-file=md5sum.txt
id=md5sum
Name=md5sum
Name[ar]=تدقيق MD5
Name[ca]=md5sum
Name[ca@valencia]=md5sum
Name[cs]=md5sum
Name[da]=md5sum
Name[de]=md5sum
Name[en_GB]=md5sum
Name[eo]=md5sumo
Name[es]=md5sum
Name[et]=md5sum
Name[eu]=md5sum
Name[fi]=md5sum
Name[fr]=md5sum
Name[gl]=md5sum
Name[hu]=md5sum
Name[ia]=md5sum
Name[ie]=md5sum
Name[it]=md5sum
Name[ja]=md5sum
Name[ka]=md5sum
Name[ko]=md5sum
Name[nb]=md5sum
Name[nl]=md5sum
Name[nn]=md5sum
Name[pl]=md5sum
Name[pt]=md5sum
Name[pt_BR]=md5sum
Name[ru]=md5sum
Name[sk]=md5sum
Name[sl]=md5sum
Name[sr]=МД5 сума
Name[sr@ijekavian]=МД5 сума
Name[sr@ijekavianlatin]=MD5 suma
Name[sr@latin]=MD5 suma
Name[sv]=MD5-summa
Name[tr]=md5sum
Name[uk]=md5sum
Name[x-test]=xxmd5sumxx
Name[zh_CN]=md5sum
Name[zh_TW]=md5sum
create-command=0|%I/md5sum -0 -
verify-command=%I/md5sum -c
[Key Filter #0]
was-validated=false
Name=Not Validated
+Description=Certificates that were not validated
[Key Filter #1]
is-expired=true
is-revoked=false
foreground-color=255,0,0
Name=Expired
+Description=Certificates that are invalid because they have expired
[Key Filter #2]
is-revoked=true
Name=Revoked
+Description=Certificates that are invalid because they have been revoked
[Key Filter #3]
was-validated=true
is-root-certificate=true
is-validity=ultimate
Name=Trusted Root Certificates
+Description=S/MIME root certificates that are trusted
background-color=95,135,255
font-bold=true
[Key Filter #4]
was-validated=true
is-root-certificate=true
is-not-validity=ultimate
Name=Not Trusted Root Certificates
+Description=S/MIME root certificates that are not trusted
[Key Filter #5]
was-validated=true
is-qualified=true
font-bold=true
Name=For Qualified Signatures
+Description=Certificates usable for qualified signatures
[Key Filter #6]
was-validated=true
Name=Validated
+Description=Certificates that were validated
[Key Filter #7]
is-cardkey=true
Name=On Smart Card
+Description=Certificates stored on smart cards
icon=smartcard
[Key Filter #8]
is-openpgp-key=true
Name=OpenPGP
+Description=OpenPGP certificates
[Key Filter #9]
is-openpgp-key=false
Name=S/MIME
+Description=S/MIME certificates
# Filters that filter for is-de-vs
# are only shown in compliance mode
# de-vs
[Key Filter #10]
is-de-vs=true
was-validated=true
id=de-vs-filter
Name=VS-NfD Compliant
Name[ar]=متوافق مع VS-NfD
Name[ca]=Conforme amb VS-NfD
Name[ca@valencia]=Conforme amb VS-NfD
Name[cs]=Splňující VS-NfD
Name[de]=VS-NfD-konform
Name[en_GB]=VS-NfD Compliant
Name[eo]=VS-NfD Konforma
Name[es]=Compatible con VS-NfD
Name[et]=VS-NfD ühilduv
Name[eu]=«VS-NfD»rekin manakorra
Name[fi]=VS-NfD-yhteensopiva
Name[fr]=Compatible VS-NfD
Name[gl]=Cumpre con VS-NfD
Name[hu]=VS-NfD kompatibilis
Name[ia]=Conforme a VS-NfD
Name[ie]=Conformant a VS-NfD
Name[it]=Conforme allo standard VS-NfD
Name[ka]=VS-NfD თავსებადი
Name[ko]=VS-NfD 적합
Name[nl]=VS-NfD Compliant
Name[pl]=Zgodny z VS-NfD
Name[pt]=Compatível com o VS-NfD
Name[pt_BR]=Compatível com VS-NfD
Name[ru]=Уровень «VS-NfD» (секретно — только для служебного пользования)
Name[sk]=Zhodný s VS-NfD
Name[sl]=Združljiv z VS-NfD
Name[sv]=Stöder VS-NfD
Name[tr]=VS-NfD Uyumlu
Name[uk]=Сумісний із VS-NfD
Name[x-test]=xxVS-NfD Compliantxx
Name[zh_CN]=VS-NfD 兼容
Name[zh_TW]=相容 VS-NfD
+Description=Certificates that are VS-NfD compliant
foreground-color=0,0,0
background-color=213,250,226
[Key Filter #11]
is-de-vs=false
was-validated=true
id=not-de-vs-filter
Name=Not VS-NfD Compliant
Name[ar]=غير متوافق مع VS-NfD
Name[ca]=No conforme amb VS-NfD
Name[ca@valencia]=No conforme amb VS-NfD
Name[cs]=Nesplňující VS-NfD
Name[de]=Nicht VS-NfD-konform
Name[en_GB]=Not VS-NfD Compliant
Name[eo]=Ne konforma al VS-NfD
Name[es]=No compatible con VS-NfD
Name[et]=VS-NfD ühildumatu
Name[eu]=«VS-NfD»rekin ez manakorra
Name[fi]=Ei VS-NfD-yhteensopiva
Name[fr]=Incompatible VS-NfD
Name[gl]=Non cumpre con VS-NfD
Name[hu]=Nem VS-NfD kompatibilis
Name[ia]=Non conforme a VS-NfD
Name[ie]=Ínconformant a VS-NfD
Name[it]=Non conforme allo standard VS-NfD
Name[ka]=VS-NfD შეუთავსებელი
Name[ko]=VS-NfD 부적합
Name[nl]=Niet VS-NfD Compliant
Name[pl]=Niezgodny z VS-NfD
Name[pt]=Incompatível com o VS-NfD
Name[pt_BR]=Não compatível com VS-NfD
Name[ru]=Не соотвествует уровеню «VS-NfD» (секретно — только для служебного пользования)
Name[sk]=Nezhodný s VS-NfD
Name[sl]=Nezdružljiv z VS-NfD
Name[sv]=Stöder inte VS-NfD
Name[tr]=VS-NfD Uyumlu Değil
Name[uk]=Несумісний із VS-NfD
Name[x-test]=xxNot VS-NfD Compliantxx
Name[zh_CN]=VS-NfD 不兼容
Name[zh_TW]=不相容 VS-NfD
+Description=Certificates that are not VS-NfD compliant
foreground-color=0,0,0
background-color=250,233,235
[Key Filter #12]
match-contexts=appearance
is-de-vs=false
is-expired=true
is-revoked=false
id=not-de-vs-expired-filter
Name=Not VS-NfD Compliant (Expired)
Name[ar]=غير متوافق مع VS-NfD (منتهي)
Name[ca]=No conforme amb VS-NfD (caducada)
Name[ca@valencia]=No conforme amb VS-NfD (caducada)
Name[cs]=Nesplňující VS-NfD (vypršelo)
Name[de]=Nicht VS-NfD-konform (Abgelaufen)
Name[en_GB]=Not VS-NfD Compliant (Expired)
Name[eo]=Ne Konforma al VS-NfD (Eksvalidigita)
Name[es]=No compatible con VS-NfD (expirado)
Name[eu]=«VS-NfD»rekin ez manakorra (iraungita)
Name[fi]=Ei VS-NfD-yhteensopiva (vanhentunut)
Name[fr]=Non compatible avec « VS-NfD » (Expiré)
Name[gl]=Non cumpre con VS-NfD (caducou)
Name[ia]=Non conforme a VS-NfD (Expirate)
Name[ie]=Ínconformant a VS-NfD (expirat)
Name[it]=Non conforme allo standard VS-NfD (scaduto)
Name[ka]=VS-NfD შეუთავსებელი (ვადაგასული)
Name[ko]=VS-NfD 부적합(만료됨)
Name[nl]=Niet VS-NfD Compliant (verlopen)
Name[pl]=Niezgodny z VS-NfD (wygasły)
Name[pt]=Incompatível com o VS-NfD (Expirado)
Name[pt_BR]=Não compatível com VS-NfD (expirado)
Name[ru]=Не соотвествует уровеню «VS-NfD» (секретно — только для служебного пользования) (устаревший)
Name[sl]=Nezdružljiv z VS-NfD (Preteklo)
Name[sv]=Stöder inte VS-NfD (utgången)
Name[tr]=VS-NfD Uyumlu Değil (Süresi dolmuş)
Name[uk]=Несумісний із VS-NfD (строк дії вичерпано)
Name[x-test]=xxNot VS-NfD Compliant (Expired)xx
Name[zh_CN]=VS-NfD 不兼容 (已过期)
+Description=Expired certificates (if VS-NfD compliance mode is active)
foreground-color=0,0,0
background-color=250,233,235
[Key Filter #13]
match-contexts=appearance
is-de-vs=false
is-revoked=true
id=not-de-vs-revoked-filter
Name=Not VS-NfD Compliant (Revoked)
Name[ar]=غير متوافق مع VS-NfD (ملغي)
Name[ca]=No conforme amb VS-NfD (revocada)
Name[ca@valencia]=No conforme amb VS-NfD (revocada)
Name[cs]=Nesplňující VS-NfD (odvoláno)
Name[de]=Nicht VS-NfD-konform (Widerrufen)
Name[en_GB]=Not VS-NfD Compliant (Revoked)
Name[eo]=Ne Konforme al VS-NfD (Revokita)
Name[es]=No compatible con VS-NfD (revocado)
Name[eu]=«VS-NfD»rekin ez manakorra (baliogetua)
Name[fi]=Ei VS-NfD-yhteensopiva (peruttu)
Name[fr]=Non compatible avec « VS-NfD » (Révoqué)
Name[gl]=Non cumpre con VS-NfD (revogouse)
Name[ia]=Non conforme a VS-NfD (Revocate)
Name[ie]=Ínconformant a VS-NfD (revocat)
Name[it]=Non conforme allo standard VS-NfD (revocato)
Name[ka]=VS-NfD შეუთავსებელი (გაუქმებული)
Name[ko]=VS-NfD 부적합(취소됨)
Name[nl]=Niet VS-NfD Compliant (ingetrokken)
Name[pl]=Niezgodny z VS-NfD (odwołany)
Name[pt]=Incompatível com o VS-NfD (Revogado)
Name[pt_BR]=Não compatível com VS-NfD (revogado)
Name[ru]=Не соотвествует уровеню «VS-NfD» (секретно — только для служебного пользования) (отозван)
Name[sl]=Nezdružljiv z VS-NfD (Preklicano)
Name[sv]=Stöder inte VS-NfD (återkallad)
Name[tr]=VS-NfD Uyumlu Değil (Yürürlükten kaldırılmış)
Name[uk]=Несумісний із VS-NfD (відкликано)
Name[x-test]=xxNot VS-NfD Compliant (Revoked)xx
Name[zh_CN]=VS-NfD 不兼容 (已吊销)
+Description=Revoked certificates (if VS-NfD compliance mode is active)
foreground-color=0,0,0
background-color=250,233,235
[Key Filter #14]
Name=Disabled Certificates
Description=Certificates that are disabled
match-contexts=appearance
is-disabled=true
# UINT_MAX - 1
specificity=4294967294
diff --git a/src/libkleopatrarc.desktop b/src/libkleopatrarc.desktop
index 8b8467f9..873cfdf3 100644
--- a/src/libkleopatrarc.desktop
+++ b/src/libkleopatrarc.desktop
@@ -1,544 +1,558 @@
[Archive Definition #0]
extensions-openpgp=tar
extensions-cms=tar.gz,tgz
id=tar
Name=TAR (PGP®-compatible)
Name[ar]=‏TAR (متوافق مع PGP®)
Name[ca]=TAR (compatible amb PGP®)
Name[ca@valencia]=TAR (compatible amb PGP®)
Name[cs]=TAR (PGP® kompatibilní)
Name[da]=TAR (PGP®-kompatibel)
Name[de]=TAR (PGP®-kompatibel)
Name[en_GB]=TAR (PGP®-compatible)
Name[eo]=TAR (PGP®-kongrua)
Name[es]=TAR (compatible PGP®)
Name[et]=TAR (PGP® ühilduv)
Name[eu]=TAR (PGP®-rekin bateragarria)
Name[fi]=TAR (PGP-yhteensopiva)
Name[fr]=TAR (compatible PGP®)
Name[gl]=TAR (compatíbel con PGP®)
Name[hu]=TAR (PGP® kompatibilis)
Name[ia]=TAR (compatibile con PGP®)
Name[ie]=TAR (compatibil con PGP®)
Name[it]=TAR (compatibile PGP®)
Name[ja]=TAR (PGP® 互換)
Name[ka]=TAR (PGP®-თავსებადი)
Name[ko]=TAR(PGP® 호환)
Name[nb]=TAR (PGP®-kompatibel)
Name[nl]=TAR (PGP®-compatible)
Name[nn]=TAR (PGP®-kompatibel)
Name[pl]=TAR (zgodny z PGP®)
Name[pt]=TAR (compatível com o PGP®)
Name[pt_BR]=TAR (compatível com PGP®)
Name[ru]=TAR (PGP®-совместимый)
Name[sk]=TAR (PGP® kompatibilné)
Name[sl]=TAR (združljiv s PGP®)
Name[sr]=тар (ПГП®-сагласно)
Name[sr@ijekavian]=тар (ПГП®-сагласно)
Name[sr@ijekavianlatin]=tar (PGP®-saglasno)
Name[sr@latin]=tar (PGP®-saglasno)
Name[sv]=TAR (fungerar med PGP®)
Name[tr]=TAR (PGP®-uyumlu)
Name[uk]=TAR (сумісні з PGP®)
Name[x-test]=xxTAR (PGP®-compatible)xx
Name[zh_CN]=TAR(PGP® 兼容)
Name[zh_TW]=TAR (相容 PGP®)
pack-command-openpgp=0|tar cf - --null -T-
pack-command-cms=0|tar cfz - --null -T-
unpack-command-openpgp=tar xf -
unpack-command-cms=tar xfz -
## ZIP can't unpack from stdin, so commented out:
#[Archive Definition #1]
#extensions=zip
#id=zip
#Name=ZIP
#Name[ca]=ZIP
#Name[ca@valencia]=ZIP
#Name[cs]=ZIP
#Name[da]=ZIP
#Name[de]=ZIP
#Name[el]=ZIP
#Name[en_GB]=ZIP
#Name[eo]=ZIP
#Name[es]=ZIP
#Name[et]=ZIP
#Name[fr]=ZIP
#Name[gl]=ZIP
#Name[it]=ZIP
#Name[ja]=ZIP
#Name[kk]=ZIP
#Name[km]=ZIP
#Name[lt]=ZIP
#Name[lv]=ZIP
#Name[nb]=ZIP
#Name[nds]=Zip
#Name[nl]=ZIP
#Name[nn]=ZIP
#Name[pa]=ZIP
#Name[pl]=ZIP
#Name[pt]=ZIP
#Name[pt_BR]=ZIP
#Name[sl]=ZIP
#Name[sv]=ZIP
#Name[tr]=ZIP
#Name[uk]=ZIP
#Name[x-test]=xxZIPxx
#Name[zh_CN]=ZIP
#Name[zh_TW]=ZIP
#pack-command=zip -r - %f
[Archive Definition #3]
extensions=tar.bz2,tbz2
id=bzip2
Name=TAR (with bzip2 compression)
Name[ar]=‏TAR (بضغط bzip2)
Name[ca]=TAR (amb compressió bzip2)
Name[ca@valencia]=TAR (amb compressió bzip2)
Name[cs]=TAR (s bzip2 kompresí)
Name[da]=TAR (med bzip2-komprimering)
Name[de]=TAR (mit bzip2-Kompression)
Name[en_GB]=TAR (with bzip2 compression)
Name[eo]=TAR (kun bzip2 kunpremado)
Name[es]=TAR (con compresión bzip2)
Name[et]=TAR (bzip2 tihendusega)
Name[eu]=TAR (bzip2 konpresioarekin)
Name[fi]=TAR (bzip2-pakattu)
Name[fr]=TAR (avec compression bzip2)
Name[gl]=TAR (con compresión bzip2)
Name[hu]=TAR (bzip2 tömörítéssel)
Name[ia]=TAR (con compression bzip2)
Name[ie]=TAR (compresset med bzip2)
Name[it]=TAR (con compressione bzip2)
Name[ja]=TAR (bzip2 圧縮)
Name[ka]=TAR (bzip2 შეკუმშვით)
Name[ko]=TAR(bzip2 압축)
Name[nb]=TAR (med bzip2-komprimering)
Name[nl]=TAR (met bzip2 compressie)
Name[nn]=TAR (med bzip2-komprimering)
Name[pl]=TAR (z kompresją bzip2)
Name[pt]=TAR (com a compressão 'bzip2')
Name[pt_BR]=TAR (compressão com bzip2)
Name[ru]=TAR (со сжатием bzip2)
Name[sk]=TAR (s bzip2 kompresiou)
Name[sl]=TAR (s stiskanjem bzip2)
Name[sr]=тар 1.1 (уз компресију бзип2)
Name[sr@ijekavian]=тар 1.1 (уз компресију бзип2)
Name[sr@ijekavianlatin]=tar 1.1 (uz kompresiju bzip2)
Name[sr@latin]=tar 1.1 (uz kompresiju bzip2)
Name[sv]=TAR (med komprimering av bzip2)
Name[tr]=TAR (bzip2 sıkıştırmalı)
Name[uk]=TAR (зі стисканням bzip2)
Name[x-test]=xxTAR (with bzip2 compression)xx
Name[zh_CN]=TAR(bzip2 压缩)
Name[zh_TW]=TAR (藉由 bzip2 壓縮)
pack-command=0|tar cfj - --null -T-
unpack-command=tar xfj -
[Checksum Definition #0]
file-patterns=sha256sum.txt,.*\\\\.sha256,.*\\\\.sha2
output-file=sha256sum.txt
id=sha256sum
Name=sha256sum
Name[ar]=تدقيق SHA256
Name[ca]=sha256sum
Name[ca@valencia]=sha256sum
Name[cs]=sha256sum
Name[da]=sha256sum
Name[de]=sha256sum
Name[en_GB]=sha256sum
Name[eo]=sha256sum
Name[es]=sha256sum
Name[et]=sha256sum
Name[eu]=sha256sum
Name[fi]=sha256sum
Name[fr]=sha256sum
Name[gl]=sha256sum
Name[hu]=sha256sum
Name[ia]=sha256sum
Name[ie]=sha256sum
Name[it]=sha256sum
Name[ja]=sha256sum
Name[ka]=sha256sum
Name[ko]=sha256sum
Name[nb]=sha256sum
Name[nl]=sha256sum
Name[nn]=sha256sum
Name[pl]=sha256sum
Name[pt]=sha256sum
Name[pt_BR]=sha256sum
Name[ru]=sha256sum
Name[sk]=sha256sum
Name[sl]=sha256sum
Name[sr]=СХА‑256 сума
Name[sr@ijekavian]=СХА‑256 сума
Name[sr@ijekavianlatin]=SHA‑256 suma
Name[sr@latin]=SHA‑256 suma
Name[sv]=SHA256-summa
Name[tr]=sha256sum
Name[uk]=sha256sum
Name[x-test]=xxsha256sumxx
Name[zh_CN]=sha256sum
Name[zh_TW]=sha256sum
create-command=0|xargs -0 sha256sum --
verify-command=sha256sum -c --
[Checksum Definition #1]
file-patterns=sha1sum.txt,.*\\\\.sha1
output-file=sha1sum.txt
id=sha1sum
Name=sha1sum
Name[ar]=تدقيق SHA1
Name[ca]=sha1sum
Name[ca@valencia]=sha1sum
Name[cs]=sha1sum
Name[da]=sha1sum
Name[de]=sha1sum
Name[en_GB]=sha1sum
Name[eo]=sha1sum
Name[es]=sha1sum
Name[et]=sha1sum
Name[eu]=sha1sum
Name[fi]=sha1sum
Name[fr]=sha1sum
Name[gl]=sha1sum
Name[hu]=sha1sum
Name[ia]=sha1sum
Name[ie]=sha1sum
Name[it]=sha1sum
Name[ja]=sha1sum
Name[ka]=sha1sum
Name[ko]=sha1sum
Name[nb]=sha1sum
Name[nl]=sha1sum
Name[nn]=sha1sum
Name[pl]=sha1sum
Name[pt]=sha1sum
Name[pt_BR]=sha1sum
Name[ru]=sha1sum
Name[sk]=sha1sum
Name[sl]=sha1sum
Name[sr]=СХА‑1 сума
Name[sr@ijekavian]=СХА‑1 сума
Name[sr@ijekavianlatin]=SHA‑1 suma
Name[sr@latin]=SHA‑1 suma
Name[sv]=SHA1-summa
Name[tr]=sha1sum
Name[uk]=sha1sum
Name[x-test]=xxsha1sumxx
Name[zh_CN]=sha1sum
Name[zh_TW]=sha1sum
create-command=0|xargs -0 sha1sum --
verify-command=sha1sum -c --
[Checksum Definition #2]
file-patterns=sha512sum.txt,.*\\\\.sha1
output-file=sha512sum.txt
id=sha512sum
Name=sha512sum
Name[ar]=تدقيق SHA512
Name[ca]=sha512sum
Name[ca@valencia]=sha512sum
Name[cs]=sha512sum
Name[de]=sha512sum
Name[en_GB]=sha512sum
Name[eo]=sha512sum
Name[es]=suma sha512
Name[et]=sha512sum
Name[eu]=sha512sum
Name[fi]=sha512sum
Name[fr]=sha512sum
Name[gl]=sha512sum
Name[hu]=sha512sum
Name[ia]=sha512sum
Name[ie]=sha512sum
Name[it]=sha512sum
Name[ka]=sha512sum
Name[ko]=sha512sum
Name[nl]=sha512sum
Name[nn]=sha512sum
Name[pl]=sha512sum
Name[pt]=sha512sum
Name[pt_BR]=sha512sum
Name[ru]=sha512sum
Name[sk]=sha512sum
Name[sl]=sha512sum
Name[sr]=СХА‑512 сума
Name[sr@ijekavian]=СХА‑512 сума
Name[sr@ijekavianlatin]=SHA‑512 suma
Name[sr@latin]=SHA‑512 suma
Name[sv]=SHA512-summa
Name[tr]=sha512sum
Name[uk]=sha512sum
Name[x-test]=xxsha512sumxx
Name[zh_CN]=sha512sum
Name[zh_TW]=sha512sum
create-command=0|xargs -0 sha512sum --
verify-command=sha512sum -c --
[Checksum Definition #3]
file-patterns=md5sum.txt,.*\\\\.md5
output-file=md5sum.txt
id=md5sum
Name=md5sum
Name[ar]=تدقيق MD5
Name[ca]=md5sum
Name[ca@valencia]=md5sum
Name[cs]=md5sum
Name[da]=md5sum
Name[de]=md5sum
Name[en_GB]=md5sum
Name[eo]=md5sumo
Name[es]=md5sum
Name[et]=md5sum
Name[eu]=md5sum
Name[fi]=md5sum
Name[fr]=md5sum
Name[gl]=md5sum
Name[hu]=md5sum
Name[ia]=md5sum
Name[ie]=md5sum
Name[it]=md5sum
Name[ja]=md5sum
Name[ka]=md5sum
Name[ko]=md5sum
Name[nb]=md5sum
Name[nl]=md5sum
Name[nn]=md5sum
Name[pl]=md5sum
Name[pt]=md5sum
Name[pt_BR]=md5sum
Name[ru]=md5sum
Name[sk]=md5sum
Name[sl]=md5sum
Name[sr]=МД5 сума
Name[sr@ijekavian]=МД5 сума
Name[sr@ijekavianlatin]=MD5 suma
Name[sr@latin]=MD5 suma
Name[sv]=MD5-summa
Name[tr]=md5sum
Name[uk]=md5sum
Name[x-test]=xxmd5sumxx
Name[zh_CN]=md5sum
Name[zh_TW]=md5sum
create-command=0|xargs -0 md5sum --
verify-command=md5sum -c --
[Key Filter #0]
was-validated=false
Name=Not Validated
+Description=Certificates that were not validated
[Key Filter #1]
is-expired=true
is-revoked=false
foreground-color=255,0,0
Name=Expired
+Description=Certificates that are invalid because they have expired
[Key Filter #2]
is-revoked=true
Name=Revoked
+Description=Certificates that are invalid because they have been revoked
[Key Filter #3]
was-validated=true
is-root-certificate=true
is-validity=ultimate
Name=Trusted Root Certificates
+Description=S/MIME root certificates that are trusted
background-color=95,135,255
font-bold=true
[Key Filter #4]
was-validated=true
is-root-certificate=true
is-not-validity=ultimate
Name=Not Trusted Root Certificates
+Description=S/MIME root certificates that are not trusted
[Key Filter #5]
was-validated=true
is-qualified=true
font-bold=true
Name=For Qualified Signatures
+Description=Certificates usable for qualified signatures
[Key Filter #6]
was-validated=true
Name=Validated
+Description=Certificates that were validated
[Key Filter #7]
is-cardkey=true
Name=On Smart Card
+Description=Certificates stored on smart cards
icon=smartcard
[Key Filter #8]
is-openpgp-key=true
Name=OpenPGP
+Description=OpenPGP certificates
[Key Filter #9]
is-openpgp-key=false
Name=S/MIME
+Description=S/MIME certificates
# Filters that filter for is-de-vs
# are only shown in compliance mode
# de-vs
[Key Filter #10]
is-de-vs=true
was-validated=true
id=de-vs-filter
Name=VS-NfD Compliant
Name[ar]=متوافق مع VS-NfD
Name[ca]=Conforme amb VS-NfD
Name[ca@valencia]=Conforme amb VS-NfD
Name[cs]=Splňující VS-NfD
Name[de]=VS-NfD-konform
Name[en_GB]=VS-NfD Compliant
Name[eo]=VS-NfD Konforma
Name[es]=Compatible con VS-NfD
Name[et]=VS-NfD ühilduv
Name[eu]=«VS-NfD»rekin manakorra
Name[fi]=VS-NfD-yhteensopiva
Name[fr]=Compatible VS-NfD
Name[gl]=Cumpre con VS-NfD
Name[hu]=VS-NfD kompatibilis
Name[ia]=Conforme a VS-NfD
Name[ie]=Conformant a VS-NfD
Name[it]=Conforme allo standard VS-NfD
Name[ka]=VS-NfD თავსებადი
Name[ko]=VS-NfD 적합
Name[nl]=VS-NfD Compliant
Name[pl]=Zgodny z VS-NfD
Name[pt]=Compatível com o VS-NfD
Name[pt_BR]=Compatível com VS-NfD
Name[ru]=Уровень «VS-NfD» (секретно — только для служебного пользования)
Name[sk]=Zhodný s VS-NfD
Name[sl]=Združljiv z VS-NfD
Name[sv]=Stöder VS-NfD
Name[tr]=VS-NfD Uyumlu
Name[uk]=Сумісний із VS-NfD
Name[x-test]=xxVS-NfD Compliantxx
Name[zh_CN]=VS-NfD 兼容
Name[zh_TW]=相容 VS-NfD
+Description=Certificates that are compliant with VS-NfD
foreground-color=0,0,0
background-color=213,250,226
[Key Filter #11]
is-de-vs=false
was-validated=true
id=not-de-vs-filter
Name=Not VS-NfD Compliant
Name[ar]=غير متوافق مع VS-NfD
Name[ca]=No conforme amb VS-NfD
Name[ca@valencia]=No conforme amb VS-NfD
Name[cs]=Nesplňující VS-NfD
Name[de]=Nicht VS-NfD-konform
Name[en_GB]=Not VS-NfD Compliant
Name[eo]=Ne konforma al VS-NfD
Name[es]=No compatible con VS-NfD
Name[et]=VS-NfD ühildumatu
Name[eu]=«VS-NfD»rekin ez manakorra
Name[fi]=Ei VS-NfD-yhteensopiva
Name[fr]=Incompatible VS-NfD
Name[gl]=Non cumpre con VS-NfD
Name[hu]=Nem VS-NfD kompatibilis
Name[ia]=Non conforme a VS-NfD
Name[ie]=Ínconformant a VS-NfD
Name[it]=Non conforme allo standard VS-NfD
Name[ka]=VS-NfD შეუთავსებელი
Name[ko]=VS-NfD 부적합
Name[nl]=Niet VS-NfD Compliant
Name[pl]=Niezgodny z VS-NfD
Name[pt]=Incompatível com o VS-NfD
Name[pt_BR]=Não compatível com VS-NfD
Name[ru]=Не соотвествует уровеню «VS-NfD» (секретно — только для служебного пользования)
Name[sk]=Nezhodný s VS-NfD
Name[sl]=Nezdružljiv z VS-NfD
Name[sv]=Stöder inte VS-NfD
Name[tr]=VS-NfD Uyumlu Değil
Name[uk]=Несумісний із VS-NfD
Name[x-test]=xxNot VS-NfD Compliantxx
Name[zh_CN]=VS-NfD 不兼容
Name[zh_TW]=不相容 VS-NfD
+Description=Certificates that are not VS-NfD compliant
foreground-color=0,0,0
background-color=250,233,235
[Key Filter #12]
match-contexts=appearance
is-de-vs=false
is-expired=true
is-revoked=false
id=not-de-vs-expired-filter
Name=Not VS-NfD Compliant (Expired)
Name[ar]=غير متوافق مع VS-NfD (منتهي)
Name[ca]=No conforme amb VS-NfD (caducada)
Name[ca@valencia]=No conforme amb VS-NfD (caducada)
Name[cs]=Nesplňující VS-NfD (vypršelo)
Name[de]=Nicht VS-NfD-konform (Abgelaufen)
Name[en_GB]=Not VS-NfD Compliant (Expired)
Name[eo]=Ne Konforma al VS-NfD (Eksvalidigita)
Name[es]=No compatible con VS-NfD (expirado)
Name[eu]=«VS-NfD»rekin ez manakorra (iraungita)
Name[fi]=Ei VS-NfD-yhteensopiva (vanhentunut)
Name[fr]=Non compatible avec « VS-NfD » (Expiré)
Name[gl]=Non cumpre con VS-NfD (caducou)
Name[ia]=Non conforme a VS-NfD (Expirate)
Name[ie]=Ínconformant a VS-NfD (expirat)
Name[it]=Non conforme allo standard VS-NfD (scaduto)
Name[ka]=VS-NfD შეუთავსებელი (ვადაგასული)
Name[ko]=VS-NfD 부적합(만료됨)
Name[nl]=Niet VS-NfD Compliant (verlopen)
Name[pl]=Niezgodny z VS-NfD (wygasły)
Name[pt]=Incompatível com o VS-NfD (Expirado)
Name[pt_BR]=Não compatível com VS-NfD (expirado)
Name[ru]=Не соотвествует уровеню «VS-NfD» (секретно — только для служебного пользования) (устаревший)
Name[sl]=Nezdružljiv z VS-NfD (Preteklo)
Name[sv]=Stöder inte VS-NfD (utgången)
Name[tr]=VS-NfD Uyumlu Değil (Süresi dolmuş)
Name[uk]=Несумісний із VS-NfD (строк дії вичерпано)
Name[x-test]=xxNot VS-NfD Compliant (Expired)xx
Name[zh_CN]=VS-NfD 不兼容 (已过期)
+Description=Expired certificates (if VS-NfD compliance mode is active)
foreground-color=0,0,0
background-color=250,233,235
[Key Filter #13]
match-contexts=appearance
is-de-vs=false
is-revoked=true
id=not-de-vs-revoked-filter
Name=Not VS-NfD Compliant (Revoked)
Name[ar]=غير متوافق مع VS-NfD (ملغي)
Name[ca]=No conforme amb VS-NfD (revocada)
Name[ca@valencia]=No conforme amb VS-NfD (revocada)
Name[cs]=Nesplňující VS-NfD (odvoláno)
Name[de]=Nicht VS-NfD-konform (Widerrufen)
Name[en_GB]=Not VS-NfD Compliant (Revoked)
Name[eo]=Ne Konforme al VS-NfD (Revokita)
Name[es]=No compatible con VS-NfD (revocado)
Name[eu]=«VS-NfD»rekin ez manakorra (baliogetua)
Name[fi]=Ei VS-NfD-yhteensopiva (peruttu)
Name[fr]=Non compatible avec « VS-NfD » (Révoqué)
Name[gl]=Non cumpre con VS-NfD (revogouse)
Name[ia]=Non conforme a VS-NfD (Revocate)
Name[ie]=Ínconformant a VS-NfD (revocat)
Name[it]=Non conforme allo standard VS-NfD (revocato)
Name[ka]=VS-NfD შეუთავსებელი (გაუქმებული)
Name[ko]=VS-NfD 부적합(취소됨)
Name[nl]=Niet VS-NfD Compliant (ingetrokken)
Name[pl]=Niezgodny z VS-NfD (odwołany)
Name[pt]=Incompatível com o VS-NfD (Revogado)
Name[pt_BR]=Não compatível com VS-NfD (revogado)
Name[ru]=Не соотвествует уровеню «VS-NfD» (секретно — только для служебного пользования) (отозван)
Name[sl]=Nezdružljiv z VS-NfD (Preklicano)
Name[sv]=Stöder inte VS-NfD (återkallad)
Name[tr]=VS-NfD Uyumlu Değil (Yürürlükten kaldırılmış)
Name[uk]=Несумісний із VS-NfD (відкликано)
Name[x-test]=xxNot VS-NfD Compliant (Revoked)xx
Name[zh_CN]=VS-NfD 不兼容 (已吊销)
+Description=Revoked certificates (if VS-NfD compliance mode is active)
foreground-color=0,0,0
background-color=250,233,235
[Key Filter #14]
Name=Disabled Certificates
Description=Certificates that are disabled
match-contexts=appearance
is-disabled=true
# UINT_MAX - 1
specificity=4294967294

File Metadata

Mime Type
text/x-diff
Expires
Fri, Dec 5, 5:42 PM (1 d, 20 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
0c/3f/357b7538fe9eb31c6406cf477ea5

Event Timeline