16#include <config-libkleo.h>
18#include "keyrequester.h"
20#include "keyselectiondialog.h"
22#include <libkleo/algorithm.h>
23#include <libkleo/compliance.h>
24#include <libkleo/dn.h>
25#include <libkleo/formatting.h>
26#include <libkleo/keyhelpers.h>
28#include <KLocalizedString>
31#include <QGpgME/KeyListJob>
33#include <QApplication>
39#include <gpgme++/key.h>
40#include <gpgme++/keylistresult.h>
42using namespace QGpgME;
45Kleo::KeyRequester::KeyRequester(
unsigned int allowedKeys,
bool multipleKeys,
QWidget *parent)
47 , mOpenPGPBackend(nullptr)
48 , mSMIMEBackend(nullptr)
49 , mMulti(multipleKeys)
50 , mKeyUsage(allowedKeys)
57Kleo::KeyRequester::KeyRequester(
QWidget *parent)
59 , mOpenPGPBackend(nullptr)
60 , mSMIMEBackend(nullptr)
69void Kleo::KeyRequester::init()
72 hlay->setContentsMargins(0, 0, 0, 0);
74 if (DeVSCompliance::isCompliant()) {
75 mComplianceIcon =
new QLabel{
this};
76 mComplianceIcon->
setPixmap(Formatting::questionIcon().pixmap(22));
95 if (mComplianceIcon) {
96 hlay->addWidget(mComplianceIcon);
98 hlay->addWidget(mLabel, 1);
99 hlay->addWidget(mEraseButton);
100 hlay->addWidget(mDialogButton);
107 setAllowedKeys(mKeyUsage);
110Kleo::KeyRequester::~KeyRequester()
114const std::vector<GpgME::Key> &Kleo::KeyRequester::keys()
const
119const GpgME::Key &Kleo::KeyRequester::key()
const
121 static const GpgME::Key null = GpgME::Key::null;
125 return mKeys.front();
132 for (
auto it = keys.begin(); it != keys.end(); ++it) {
134 mKeys.push_back(*it);
144 mKeys.push_back(key);
149QString Kleo::KeyRequester::fingerprint()
const
158QStringList Kleo::KeyRequester::fingerprints()
const
161 for (
auto it = mKeys.begin(); it != mKeys.end(); ++it) {
163 if (
const char *fpr = it->primaryFingerprint()) {
178 startKeyListJob(fingerprints);
181void Kleo::KeyRequester::updateKeys()
184 if (mComplianceIcon) {
185 mComplianceIcon->setPixmap(Formatting::unavailableIcon().pixmap(22));
186 mComplianceIcon->setToolTip(
QString{});
191 if (mKeys.size() > 1) {
192 setMultipleKeysEnabled(
true);
197 for (std::vector<GpgME::Key>::const_iterator it = mKeys.begin(); it != mKeys.end(); ++it) {
204 if (
const char *uid = it->userID(0).id()) {
205 if (it->protocol() == GpgME::OpenPGP) {
211 toolTipText +=
xi18n(
"<placeholder>unknown</placeholder>");
215 if (mComplianceIcon) {
216 if (Kleo::all_of(mKeys, &Kleo::DeVSCompliance::keyIsCompliant)) {
217 mComplianceIcon->setPixmap(Formatting::successIcon().pixmap(22));
218 mComplianceIcon->setToolTip(DeVSCompliance::name(
true));
220 mComplianceIcon->setPixmap(Formatting::warningIcon().pixmap(22));
221 mComplianceIcon->setToolTip(DeVSCompliance::name(
false));
225 mLabel->setToolTip(toolTipText);
228#ifndef __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
229#define __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
230static void showKeyListError(
QWidget *parent,
const GpgME::Error &err)
234 "<qt><p>An error occurred while fetching "
235 "the keys from the backend:</p>"
236 "<p><b>%1</b></p></qt>",
237 Formatting::errorAsString(err));
243void Kleo::KeyRequester::startKeyListJob(
const QStringList &fingerprints)
245 if (!mSMIMEBackend && !mOpenPGPBackend) {
252 unsigned int count = 0;
254 if (!(*it).trimmed().isEmpty()) {
262 setKey(GpgME::Key::null);
266 if (mOpenPGPBackend) {
267 KeyListJob *job = mOpenPGPBackend->keyListJob(
false);
270 i18n(
"The OpenPGP backend does not support listing keys. "
271 "Check your installation."),
272 i18n(
"Key Listing Failed"));
274 connect(job, &KeyListJob::result,
this, &SigningKeyRequester::slotKeyListResult);
275 connect(job, &KeyListJob::nextKey,
this, &SigningKeyRequester::slotNextKey);
277 const GpgME::Error err =
278 job->start(fingerprints, mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && !(mKeyUsage & Kleo::KeySelectionDialog::PublicKeys));
281 showKeyListError(
this, err);
289 KeyListJob *job = mSMIMEBackend->keyListJob(
false);
292 i18n(
"The S/MIME backend does not support listing keys. "
293 "Check your installation."),
294 i18n(
"Key Listing Failed"));
296 connect(job, &KeyListJob::result,
this, &SigningKeyRequester::slotKeyListResult);
297 connect(job, &KeyListJob::nextKey,
this, &SigningKeyRequester::slotNextKey);
299 const GpgME::Error err =
300 job->start(fingerprints, mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && !(mKeyUsage & Kleo::KeySelectionDialog::PublicKeys));
303 showKeyListError(
this, err);
311 mEraseButton->setEnabled(
false);
312 mDialogButton->setEnabled(
false);
316void Kleo::KeyRequester::slotNextKey(
const GpgME::Key &key)
319 mTmpKeys.push_back(key);
323void Kleo::KeyRequester::slotKeyListResult(
const GpgME::KeyListResult &res)
326 showKeyListError(
this, res.error());
330 mEraseButton->setEnabled(
true);
331 mDialogButton->setEnabled(
true);
338void Kleo::KeyRequester::slotDialogButtonClicked()
340 KeySelectionDialog *dlg = mKeys.empty() ?
new KeySelectionDialog(mDialogCaption, mDialogMessage, mInitialQuery, mKeyUsage, mMulti,
false,
this)
341 : new KeySelectionDialog(mDialogCaption, mDialogCaption, mKeys, mKeyUsage, mMulti, false, this);
345 setKeys(dlg->selectedKeys());
347 setKey(dlg->selectedKey());
355void Kleo::KeyRequester::slotEraseButtonClicked()
357 if (!mKeys.empty()) {
364void Kleo::KeyRequester::setDialogCaption(
const QString &caption)
366 mDialogCaption = caption;
369void Kleo::KeyRequester::setDialogMessage(
const QString &msg)
371 mDialogMessage = msg;
374bool Kleo::KeyRequester::isMultipleKeysEnabled()
const
379void Kleo::KeyRequester::setMultipleKeysEnabled(
bool multi)
381 if (multi == mMulti) {
385 if (!multi && !mKeys.empty()) {
386 mKeys.erase(mKeys.begin() + 1, mKeys.end());
393unsigned int Kleo::KeyRequester::allowedKeys()
const
398void Kleo::KeyRequester::setAllowedKeys(
unsigned int keyUsage)
400 mKeyUsage = keyUsage;
401 mOpenPGPBackend =
nullptr;
402 mSMIMEBackend =
nullptr;
404 if (mKeyUsage & KeySelectionDialog::OpenPGPKeys) {
405 mOpenPGPBackend = openpgp();
407 if (mKeyUsage & KeySelectionDialog::SMIMEKeys) {
408 mSMIMEBackend = smime();
411 if (mOpenPGPBackend && !mSMIMEBackend) {
412 mDialogCaption =
i18n(
"OpenPGP Key Selection");
413 mDialogMessage =
i18n(
"Please select an OpenPGP key to use.");
414 }
else if (!mOpenPGPBackend && mSMIMEBackend) {
415 mDialogCaption =
i18n(
"S/MIME Key Selection");
416 mDialogMessage =
i18n(
"Please select an S/MIME key to use.");
418 mDialogCaption =
i18n(
"Key Selection");
419 mDialogMessage =
i18n(
"Please select an (OpenPGP or S/MIME) key to use.");
425 return mDialogButton;
433static inline unsigned int foo(
bool openpgp,
bool smime,
bool trusted,
bool valid)
435 unsigned int result = 0;
437 result |= Kleo::KeySelectionDialog::OpenPGPKeys;
440 result |= Kleo::KeySelectionDialog::SMIMEKeys;
443 result |= Kleo::KeySelectionDialog::TrustedKeys;
446 result |= Kleo::KeySelectionDialog::ValidKeys;
451static inline unsigned int encryptionKeyUsage(
bool openpgp,
bool smime,
bool trusted,
bool valid)
453 return foo(openpgp, smime, trusted, valid) | Kleo::KeySelectionDialog::EncryptionKeys | Kleo::KeySelectionDialog::PublicKeys;
456static inline unsigned int signingKeyUsage(
bool openpgp,
bool smime,
bool trusted,
bool valid)
458 return foo(openpgp, smime, trusted, valid) | Kleo::KeySelectionDialog::SigningKeys | Kleo::KeySelectionDialog::SecretKeys;
461Kleo::EncryptionKeyRequester::EncryptionKeyRequester(
bool multi,
unsigned int proto,
QWidget *parent,
bool onlyTrusted,
bool onlyValid)
462 :
KeyRequester(encryptionKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid), multi, parent)
467Kleo::EncryptionKeyRequester::EncryptionKeyRequester(
QWidget *parent)
473Kleo::EncryptionKeyRequester::~EncryptionKeyRequester()
477void Kleo::EncryptionKeyRequester::setAllowedKeys(
unsigned int proto,
bool onlyTrusted,
bool onlyValid)
479 KeyRequester::setAllowedKeys(encryptionKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid));
482Kleo::SigningKeyRequester::SigningKeyRequester(
bool multi,
unsigned int proto,
QWidget *parent,
bool onlyTrusted,
bool onlyValid)
483 :
KeyRequester(signingKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid), multi, parent)
488Kleo::SigningKeyRequester::SigningKeyRequester(
QWidget *parent)
494Kleo::SigningKeyRequester::~SigningKeyRequester()
498void Kleo::SigningKeyRequester::setAllowedKeys(
unsigned int proto,
bool onlyTrusted,
bool onlyValid)
500 KeyRequester::setAllowedKeys(signingKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid));
503void Kleo::KeyRequester::virtual_hook(
int,
void *)
506void Kleo::EncryptionKeyRequester::virtual_hook(
int id,
void *data)
508 KeyRequester::virtual_hook(
id, data);
510void Kleo::SigningKeyRequester::virtual_hook(
int id,
void *data)
512 KeyRequester::virtual_hook(
id, data);
515#include "moc_keyrequester.cpp"
Base class for SigningKeyRequester and EncryptionKeyRequester.
void setFingerprint(const QString &fingerprint)
Set the key by fingerprint.
void setFingerprints(const QStringList &fingerprints)
Set the keys by fingerprint.
void setKeys(const std::vector< GpgME::Key > &keys)
Preferred method to set a key for multi-KeyRequesters.
void setKey(const GpgME::Key &key)
Preferred method to set a key for non-multi-KeyRequesters.
QString xi18n(const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
void setFrameStyle(int style)
QIcon fromTheme(const QString &name)
void setPixmap(const QPixmap &)
void push_back(parameter_type value)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString fromUtf8(QByteArrayView str)
QString right(qsizetype n) const const
QString join(QChar separator) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)