Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F40810927
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
18 KB
Subscribers
None
View Options
diff --git a/client/editor/composerviewbase.cpp b/client/editor/composerviewbase.cpp
index 19323be..3a68d8e 100644
--- a/client/editor/composerviewbase.cpp
+++ b/client/editor/composerviewbase.cpp
@@ -256,39 +256,44 @@ inline Kleo::chrono::days encryptChainCertNearExpiryWarningThresholdInDays()
} // nameless namespace
-Kleo::KeyResolver *ComposerViewBase::fillKeyResolver(bool encryptSomething)
+template void ComposerViewBase::fillKeyResolver<Kleo::KeyResolver>(Kleo::KeyResolver *, bool encrypt, Kleo::CryptoMessageFormat cryptoMessageFormat);
+template void ComposerViewBase::fillKeyResolver<Kleo::KeyResolverCore>(Kleo::KeyResolverCore *, bool encrypt, Kleo::CryptoMessageFormat cryptoMessageFormat);
+
+template<typename T>
+void ComposerViewBase::fillKeyResolver(T *resolver, bool encrypt, Kleo::CryptoMessageFormat cryptoMessageFormat)
{
- auto keyResolverCore = new Kleo::KeyResolver(m_encrypt, m_sign, GpgME::UnknownProtocol, false);
- keyResolverCore->setMinimumValidity(GpgME::UserID::Unknown);
+ resolver->setMinimumValidity(GpgME::UserID::Unknown);
QStringList signingKeys, encryptionKeys;
- if (m_cryptoMessageFormat & Kleo::AnyOpenPGP) {
+ if (cryptoMessageFormat & Kleo::AnyOpenPGP) {
if (!m_identity.pgpSigningKey().isEmpty()) {
signingKeys.push_back(QLatin1String(m_identity.pgpSigningKey()));
}
- if (!m_identity.pgpEncryptionKey().isEmpty()) {
+ if (m_identity.encryptSelfPGP() && !m_identity.pgpEncryptionKey().isEmpty()) {
encryptionKeys.push_back(QLatin1String(m_identity.pgpEncryptionKey()));
}
+ if (!m_identity.encryptSelfCustomPGPKey().isEmpty()) {
+ encryptionKeys.push_back(m_identity.encryptSelfCustomPGPKey());
+ }
}
- if (m_cryptoMessageFormat & Kleo::AnySMIME) {
+ if (cryptoMessageFormat & Kleo::AnySMIME) {
if (!m_identity.smimeSigningKey().isEmpty()) {
signingKeys.push_back(QLatin1String(m_identity.smimeSigningKey()));
}
- if (!m_identity.smimeEncryptionKey().isEmpty()) {
+ if (m_identity.encryptSelfSMIME() && !m_identity.smimeEncryptionKey().isEmpty()) {
encryptionKeys.push_back(QLatin1String(m_identity.smimeEncryptionKey()));
}
}
- keyResolverCore->setSender(m_identity.fullEmailAddr());
-
+ resolver->setSender(m_identity.fullEmailAddr());
const auto normalized = GpgME::UserID::addrSpecFromString(m_identity.fullEmailAddr().toUtf8().constData());
const auto normalizedSender = QString::fromUtf8(normalized.c_str());
- keyResolverCore->setSigningKeys(signingKeys);
- keyResolverCore->setOverrideKeys({{GpgME::UnknownProtocol, {{normalizedSender, encryptionKeys}}}});
+ resolver->setSigningKeys(signingKeys);
+ resolver->setOverrideKeys({{GpgME::UnknownProtocol, {{normalizedSender, encryptionKeys}}}});
- if (encryptSomething) {
+ if (encrypt) {
QStringList recipients;
const auto lst = m_recipientsEditor->lines();
for (auto line : lst) {
@@ -296,9 +301,8 @@ Kleo::KeyResolver *ComposerViewBase::fillKeyResolver(bool encryptSomething)
recipients.push_back(recipient->email());
}
- keyResolverCore->setRecipients(recipients);
+ resolver->setRecipients(recipients);
}
- return keyResolverCore;
}
void ComposerViewBase::generateCryptoMessages()
@@ -366,9 +370,15 @@ void ComposerViewBase::generateCryptoMessages()
return;
}
- auto keyResolver = fillKeyResolver(encryptSomething);
+ // NOTE: Using allow_mixed=false, for the moment, to avoid unsolved UI ambiguity issues.
+ // Other parts of the code actually support mixed formats (if perhaps not in a perfect fashion, yet).
+ // Two separate mails would be sent in that case.
+ // If changing, here, also change the corresponding line in ComposerWindow!
+ auto keyResolver = new Kleo::KeyResolver(encryptSomething, signSomething, GpgME::UnknownProtocol, /* allow_mixed */ false);
+ fillKeyResolver(keyResolver, encryptSomething, m_cryptoMessageFormat);
connect(keyResolver, &Kleo::KeyResolver::keysResolved, this, [this, encryptSomething, signSomething, keyResolver](bool success, bool sendUnencrypted) {
+ keyResolver->deleteLater();
if (!success) {
qCDebug(EDITOR_LOG) << "resolveAllKeys: failed to resolve keys! oh noes";
Q_EMIT failed(i18n("Failed to resolve keys. Please contact your administrator."));
@@ -408,17 +418,14 @@ void ComposerViewBase::generateCryptoMessages()
for (const auto &[recipient, keys] : result.encryptionKeys.asKeyValueRange()) {
const auto recipientKeys = result.encryptionKeys[recipient];
- if (recipientKeys.size() > 1) {
- // TODO Carl group handling
- } else {
- const auto &key = recipientKeys[0];
- expiryChecker()->checkKey(recipientKeys[0], Kleo::ExpiryChecker::EncryptionKey);
+ for (const auto &key : recipientKeys) {
+ expiryChecker()->checkKey(key, Kleo::ExpiryChecker::EncryptionKey);
if (key.protocol() == GpgME::CMS) {
smimeRecipients.append(recipient);
- smimeKeys.push_back(recipientKeys[0]);
+ smimeKeys.push_back(key);
} else {
pgpRecipients.append(recipient);
- pgpKeys.push_back(recipientKeys[0]);
+ pgpKeys.push_back(key);
}
}
}
diff --git a/client/editor/composerviewbase.h b/client/editor/composerviewbase.h
index 92268ae..9d9da24 100644
--- a/client/editor/composerviewbase.h
+++ b/client/editor/composerviewbase.h
@@ -207,6 +207,10 @@ public:
[[nodiscard]] std::shared_ptr<Kleo::ExpiryChecker> expiryChecker();
+ /// Fill the composer with the signing/encryption key of the sender as well as the email
+ /// addresses from the recipients.
+ template<typename T>
+ void fillKeyResolver(T *resolver, bool encrypt, Kleo::CryptoMessageFormat cryptoMessageFormat);
public Q_SLOTS:
void identityChanged(const KIdentityManagementCore::Identity &ident, const KIdentityManagementCore::Identity &oldIdent, bool msgCleared = false);
@@ -266,9 +270,6 @@ private:
UseUnExpandedRecipients,
};
void fillComposer(MessageComposer::ComposerJob *composer, ComposerViewBase::RecipientExpansion expansion, bool autoresize);
- /// Fill the composer with the signing/encryption key of the sender as well as the email
- /// addresses from the recipients.
- [[nodiscard]] Kleo::KeyResolver *fillKeyResolver(bool encryptSomething);
/// Create one or multiple MessageComposer::Composer depending on the crypto settings
/// Emits composerCreated when finished.
diff --git a/client/editor/composerwindow.cpp b/client/editor/composerwindow.cpp
index fb42572..677a1a7 100644
--- a/client/editor/composerwindow.cpp
+++ b/client/editor/composerwindow.cpp
@@ -627,50 +627,6 @@ void ComposerWindow::setSigning(bool sign, bool setByUser)
//}
}
-std::unique_ptr<Kleo::KeyResolverCore> ComposerWindow::fillKeyResolver()
-{
- auto keyResolverCore = std::make_unique<Kleo::KeyResolverCore>(true, sign());
-
- keyResolverCore->setMinimumValidity(GpgME::UserID::Unknown);
-
- QStringList signingKeys, encryptionKeys;
-
- if (cryptoMessageFormat() & Kleo::AnyOpenPGP) {
- if (!mIdentity.pgpSigningKey().isEmpty()) {
- signingKeys.push_back(QLatin1String(mIdentity.pgpSigningKey()));
- }
- if (!mIdentity.pgpEncryptionKey().isEmpty()) {
- encryptionKeys.push_back(QLatin1String(mIdentity.pgpEncryptionKey()));
- }
- }
-
- if (cryptoMessageFormat() & Kleo::AnySMIME) {
- if (!mIdentity.smimeSigningKey().isEmpty()) {
- signingKeys.push_back(QLatin1String(mIdentity.smimeSigningKey()));
- }
- if (!mIdentity.smimeEncryptionKey().isEmpty()) {
- encryptionKeys.push_back(QLatin1String(mIdentity.smimeEncryptionKey()));
- }
- }
-
- keyResolverCore->setSender(mIdentity.fullEmailAddr());
- keyResolverCore->setSigningKeys(signingKeys);
- keyResolverCore->setOverrideKeys({{GpgME::UnknownProtocol, {{keyResolverCore->normalizedSender(), encryptionKeys}}}});
-
- QStringList recipients;
- const auto lst = mRecipientEditor->lines();
- for (auto line : lst) {
- auto recipient = line->data().dynamicCast<Recipient>();
- recipients.push_back(recipient->email());
- }
-
- keyResolverCore->setRecipients(recipients);
-
- qWarning() << recipients;
-
- return keyResolverCore;
-}
-
void ComposerWindow::slotEncryptionButtonIconUpdate()
{
const auto state = mEncryptAction->isChecked();
@@ -711,8 +667,10 @@ void ComposerWindow::slotEncryptionButtonIconUpdate()
void ComposerWindow::runKeyResolver()
{
- auto keyResolverCore = fillKeyResolver();
- auto result = keyResolverCore->resolve();
+ Kleo::KeyResolverCore keyResolverCore(true, sign());
+ keyResolverCore.setAllowMixedProtocols(false);
+ mComposerBase->fillKeyResolver(&keyResolverCore, true, cryptoMessageFormat());
+ auto result = keyResolverCore.resolve();
const auto lst = mRecipientEditor->lines();
diff --git a/client/editor/composerwindow.h b/client/editor/composerwindow.h
index 8a36d71..42753ce 100644
--- a/client/editor/composerwindow.h
+++ b/client/editor/composerwindow.h
@@ -149,7 +149,6 @@ private:
int validateLineWrapWidth() const;
void disableWordWrap();
void checkOwnKeyExpiry(const KIdentityManagementCore::Identity &ident);
- std::unique_ptr<Kleo::KeyResolverCore> fillKeyResolver();
/// Returns true if the message was modified by the user.
[[nodiscard]] bool isModified() const;
diff --git a/client/identity/identity.cpp b/client/identity/identity.cpp
index c0a493a..576e6da 100644
--- a/client/identity/identity.cpp
+++ b/client/identity/identity.cpp
@@ -180,7 +180,9 @@ QDataStream &KIdentityManagementCore::operator<<(QDataStream &stream, const KIde
<< i.mPropertiesMap[QLatin1StringView(s_defaultDomainName)] << i.mPropertiesMap[QLatin1StringView(s_autocryptEnabled)]
<< i.mPropertiesMap[QLatin1StringView(s_autocryptPrefer)] << i.mPropertiesMap[QLatin1StringView(s_encryptionOverride)]
<< i.mPropertiesMap[QLatin1StringView(s_pgpautosign)] << i.mPropertiesMap[QLatin1StringView(s_pgpautoencrypt)]
- << i.mPropertiesMap[QLatin1StringView(s_warnnotencrypt)] << i.mPropertiesMap[QLatin1StringView(s_warnnotsign)];
+ << i.mPropertiesMap[QLatin1StringView(s_warnnotencrypt)] << i.mPropertiesMap[QLatin1StringView(s_warnnotsign)]
+ << i.mPropertiesMap[QLatin1StringView(s_encryptSelfPGP)] << i.mPropertiesMap[QLatin1StringView(s_encryptSelfSMIME)]
+ << i.mPropertiesMap[QLatin1StringView(s_encryptSelfCustomPGPKey)];
}
QDataStream &KIdentityManagementCore::operator>>(QDataStream &stream, KIdentityManagementCore::Identity &i)
@@ -199,7 +201,9 @@ QDataStream &KIdentityManagementCore::operator>>(QDataStream &stream, KIdentityM
>> i.mPropertiesMap[QLatin1StringView(s_defaultDomainName)] >> i.mPropertiesMap[QLatin1StringView(s_autocryptEnabled)]
>> i.mPropertiesMap[QLatin1StringView(s_autocryptPrefer)] >> i.mPropertiesMap[QLatin1StringView(s_encryptionOverride)]
>> i.mPropertiesMap[QLatin1StringView(s_pgpautosign)] >> i.mPropertiesMap[QLatin1StringView(s_pgpautoencrypt)]
- >> i.mPropertiesMap[QLatin1StringView(s_warnnotencrypt)] >> i.mPropertiesMap[QLatin1StringView(s_warnnotsign)];
+ >> i.mPropertiesMap[QLatin1StringView(s_warnnotencrypt)] >> i.mPropertiesMap[QLatin1StringView(s_warnnotsign)]
+ >> i.mPropertiesMap[QLatin1StringView(s_encryptSelfPGP)] >> i.mPropertiesMap[QLatin1StringView(s_encryptSelfSMIME)]
+ >> i.mPropertiesMap[QLatin1StringView(s_encryptSelfCustomPGPKey)];
i.setProperty(QLatin1StringView(s_uoid), uoid);
return stream;
@@ -771,6 +775,36 @@ void Identity::setWarnNotSign(const bool on)
setProperty(QLatin1StringView(s_warnnotsign), on);
}
+bool Identity::encryptSelfPGP() const
+{
+ return property(QLatin1StringView(s_encryptSelfPGP)).toBool();
+}
+
+void Identity::setEncryptSelfPGP(const bool on)
+{
+ setProperty(QLatin1StringView(s_encryptSelfPGP), on);
+}
+
+bool Identity::encryptSelfSMIME() const
+{
+ return property(QLatin1StringView(s_encryptSelfSMIME)).toBool();
+}
+
+void Identity::setEncryptSelfSMIME(const bool on)
+{
+ setProperty(QLatin1StringView(s_encryptSelfSMIME), on);
+}
+
+QString Identity::encryptSelfCustomPGPKey() const
+{
+ return property(QLatin1StringView(s_encryptSelfCustomPGPKey)).toString();
+}
+
+void Identity::setEncryptSelfCustomPGPKey(const QString &keyid)
+{
+ setProperty(QLatin1StringView(s_encryptSelfCustomPGPKey), keyid);
+}
+
QString Identity::defaultDomainName() const
{
return property(QLatin1StringView(s_defaultDomainName)).toString();
diff --git a/client/identity/identity.h b/client/identity/identity.h
index ba8f093..e2e7a07 100644
--- a/client/identity/identity.h
+++ b/client/identity/identity.h
@@ -62,6 +62,9 @@ static const char s_warnnotencrypt[] = "Warn not Encrypt";
static const char s_defaultDomainName[] = "Default Domain";
static const char s_autocryptEnabled[] = "Autocrypt";
static const char s_autocryptPrefer[] = "Autocrypt Prefer";
+static const char s_encryptSelfPGP[] = "Encrypt self to own PGP key";
+static const char s_encryptSelfSMIME[] = "Encrypt self to own SMIME key";
+static const char s_encryptSelfCustomPGPKey[] = "Encrypt self to custom PGP key";
QDataStream &operator<<(QDataStream &stream, const KIdentityManagementCore::Identity &ident);
QDataStream &operator>>(QDataStream &stream, KIdentityManagementCore::Identity &ident);
@@ -96,6 +99,9 @@ class Identity
Q_PROPERTY(bool encryptionOverride READ encryptionOverride WRITE setEncryptionOverride)
Q_PROPERTY(bool warnNotSign READ warnNotSign WRITE setWarnNotSign)
Q_PROPERTY(bool warnNotEncrypt READ warnNotEncrypt WRITE setWarnNotEncrypt)
+ Q_PROPERTY(bool encryptSelfPGP READ encryptSelfPGP WRITE setEncryptSelfPGP);
+ Q_PROPERTY(bool encryptSelfSMIME READ encryptSelfSMIME WRITE setEncryptSelfSMIME);
+ Q_PROPERTY(QString encryptSelfCustomPGPKey READ encryptSelfCustomPGPKey WRITE setEncryptSelfCustomPGPKey);
Q_PROPERTY(QString defaultDomainName READ defaultDomainName WRITE setDefaultDomainName)
Q_PROPERTY(Signature signature READ signature WRITE setSignature)
Q_PROPERTY(QString signatureText READ signatureText)
@@ -310,6 +316,15 @@ public:
[[nodiscard]] bool warnNotEncrypt() const;
void setWarnNotEncrypt(const bool);
+ [[nodiscard]] bool encryptSelfPGP() const;
+ void setEncryptSelfPGP(const bool on);
+
+ [[nodiscard]] bool encryptSelfSMIME() const;
+ void setEncryptSelfSMIME(const bool on);
+
+ [[nodiscard]] QString encryptSelfCustomPGPKey() const;
+ void setEncryptSelfCustomPGPKey(const QString &keyid);
+
/**
* @return The default domain name
* @since 4.14
diff --git a/client/identity/identitydialog.cpp b/client/identity/identitydialog.cpp
index 763dc55..f7d4f5b 100644
--- a/client/identity/identitydialog.cpp
+++ b/client/identity/identitydialog.cpp
@@ -536,6 +536,24 @@ IdentityDialog::IdentityDialog(QWidget *parent)
mWarnNotEncrypt = new QCheckBox(i18n("Warn when trying to send unencrypted messages"));
formLayout->addRow(QString(), mWarnNotEncrypt);
+ auto group = new QGroupBox(i18n("When sending encrypted mails, also encrypt to these keys:"));
+ group->setToolTip(
+ i18n("Even as the sender of an encrypted email, you will not be able to decrpt "
+ "it without having access to at least one secret key to which the email was encrypted. "
+ "You may therefore want to encrypt outgoing emails to your own key(s) in addition "
+ "to the recipients' keys."));
+ auto groupbox = new QVBoxLayout(group);
+ mPGPencryptSelf = new QCheckBox(i18nc("@checkbox", "My own OpenPGP key as configured above"));
+ mSMIMEencryptSelf = new QCheckBox(i18nc("@checkbox", "My own SMIME key as configured above"));
+ auto hbox = new QHBoxLayout();
+ hbox->addWidget(new QLabel(i18n("The following key: ")));
+ mPGPencryptSelfKeyRequester = new KeySelectionCombo(KeySelectionCombo::EncryptionKey, GpgME::OpenPGP, mCryptographyTab);
+ hbox->addWidget(mPGPencryptSelfKeyRequester);
+ groupbox->addWidget(mPGPencryptSelf);
+ groupbox->addWidget(mSMIMEencryptSelf);
+ groupbox->addLayout(hbox);
+ formLayout->addRow(group);
+
//
// Tab Widget: Signature
//
@@ -658,6 +676,10 @@ void IdentityDialog::setIdentity(KIdentityManagementCore::Identity &ident)
mWarnNotEncrypt->setChecked(ident.warnNotEncrypt());
+ mPGPencryptSelf->setChecked(ident.encryptSelfPGP());
+ mSMIMEencryptSelf->setChecked(ident.encryptSelfSMIME());
+ mPGPencryptSelfKeyRequester->setDefaultKey(ident.encryptSelfCustomPGPKey());
+
// "Signature" tab:
mSignatureConfigurator->setSignature(ident.signature());
@@ -688,6 +710,9 @@ void IdentityDialog::updateIdentity(KIdentityManagementCore::Identity &ident)
ident.setEncryptionOverride(true);
ident.setWarnNotEncrypt(mWarnNotEncrypt->isChecked());
ident.setWarnNotEncrypt(mWarnNotEncrypt->isChecked());
+ ident.setEncryptSelfPGP(mPGPencryptSelf->isChecked());
+ ident.setEncryptSelfSMIME(mSMIMEencryptSelf->isChecked());
+ ident.setEncryptSelfCustomPGPKey(QString::fromLatin1(mPGPencryptSelfKeyRequester->currentKey().primaryFingerprint()));
// "Advanced" tab:
ident.setDictionary(mDictionaryCombo->currentDictionaryName());
diff --git a/client/identity/identitydialog.h b/client/identity/identitydialog.h
index 6f9d240..6af4981 100644
--- a/client/identity/identitydialog.h
+++ b/client/identity/identitydialog.h
@@ -82,6 +82,9 @@ private:
KeySelectionCombo *mSMIMEEncryptionKeyRequester = nullptr;
QCheckBox *mPGPSameKey = nullptr;
QCheckBox *mWarnNotEncrypt = nullptr;
+ QCheckBox *mPGPencryptSelf = nullptr;
+ QCheckBox *mSMIMEencryptSelf = nullptr;
+ KeySelectionCombo *mPGPencryptSelfKeyRequester = nullptr;
QSet<KeySelectionCombo *> mInitialLoadingFinished;
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Apr 25, 3:42 PM (14 h, 30 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
e5/f4/4d8c77ae3d68e02f5bf76e29c76c
Attached To
rOJ GpgOL.js
Event Timeline
Log In to Comment