Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34113457
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
86 KB
Subscribers
None
View Options
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
Details
Attached
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
Attached To
rLIBKLEO Libkleo
Event Timeline
Log In to Comment