summaryrefslogtreecommitdiffstats
path: root/framework/src
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src')
-rw-r--r--framework/src/domain/composercontroller.cpp32
-rw-r--r--framework/src/domain/composercontroller.h7
-rw-r--r--framework/src/domain/mime/mailcrypto.cpp99
-rw-r--r--framework/src/domain/mime/mailcrypto.h23
-rw-r--r--framework/src/domain/mime/mailtemplates.cpp4
-rw-r--r--framework/src/domain/mime/mailtemplates.h4
-rw-r--r--framework/src/domain/mime/tests/mailtemplatetest.cpp50
7 files changed, 100 insertions, 119 deletions
diff --git a/framework/src/domain/composercontroller.cpp b/framework/src/domain/composercontroller.cpp
index a71e66f9..fc436003 100644
--- a/framework/src/domain/composercontroller.cpp
+++ b/framework/src/domain/composercontroller.cpp
@@ -36,7 +36,7 @@
36#include "mime/mailcrypto.h" 36#include "mime/mailcrypto.h"
37#include "async.h" 37#include "async.h"
38 38
39std::vector<GpgME::Key> &operator+=(std::vector<GpgME::Key> &list, const std::vector<GpgME::Key> &add) 39std::vector<MailCrypto::Key> &operator+=(std::vector<MailCrypto::Key> &list, const std::vector<MailCrypto::Key> &add)
40{ 40{
41 list.insert(std::end(list), std::begin(add), std::end(add)); 41 list.insert(std::end(list), std::begin(add), std::end(add));
42 return list; 42 return list;
@@ -133,16 +133,16 @@ public:
133 mb.fromUnicodeString(addressee); 133 mb.fromUnicodeString(addressee);
134 134
135 SinkLog() << "Searching key for: " << mb.address(); 135 SinkLog() << "Searching key for: " << mb.address();
136 asyncRun<std::vector<GpgME::Key>>(this, 136 asyncRun<std::vector<MailCrypto::Key>>(this,
137 [mb] { 137 [mb] {
138 return MailCrypto::findKeys(QStringList{} << mb.address(), false, false); 138 return MailCrypto::findKeys(QStringList{} << mb.address(), false, false);
139 }, 139 },
140 [this, addressee, id](const std::vector<GpgME::Key> &keys) { 140 [this, addressee, id](const std::vector<MailCrypto::Key> &keys) {
141 if (!keys.empty()) { 141 if (!keys.empty()) {
142 if (keys.size() > 1) { 142 if (keys.size() > 1) {
143 SinkWarning() << "Found more than one key, encrypting to all of them."; 143 SinkWarning() << "Found more than one key, encrypting to all of them.";
144 } 144 }
145 SinkLog() << "Found key: " << keys.front().primaryFingerprint(); 145 SinkLog() << "Found key: " << keys.front();
146 setValue(id, "keyFound", true); 146 setValue(id, "keyFound", true);
147 setValue(id, "key", QVariant::fromValue(keys)); 147 setValue(id, "key", QVariant::fromValue(keys));
148 mMissingKeys.remove(id); 148 mMissingKeys.remove(id);
@@ -227,10 +227,10 @@ void ComposerController::findPersonalKey()
227{ 227{
228 auto identity = getIdentity(); 228 auto identity = getIdentity();
229 SinkLog() << "Looking for personal key for: " << identity.address(); 229 SinkLog() << "Looking for personal key for: " << identity.address();
230 asyncRun<std::vector<GpgME::Key>>(this, [=] { 230 asyncRun<std::vector<MailCrypto::Key>>(this, [=] {
231 return MailCrypto::findKeys(QStringList{} << identity.address(), true); 231 return MailCrypto::findKeys(QStringList{} << identity.address(), true);
232 }, 232 },
233 [this](const std::vector<GpgME::Key> &keys) { 233 [this](const std::vector<MailCrypto::Key> &keys) {
234 if (keys.empty()) { 234 if (keys.empty()) {
235 SinkWarning() << "Failed to find a personal key."; 235 SinkWarning() << "Failed to find a personal key.";
236 } else if (keys.size() > 1) { 236 } else if (keys.size() > 1) {
@@ -419,23 +419,23 @@ void ComposerController::recordForAutocompletion(const QByteArray &addrSpec, con
419 } 419 }
420} 420}
421 421
422std::vector<GpgME::Key> ComposerController::getRecipientKeys() 422std::vector<MailCrypto::Key> ComposerController::getRecipientKeys()
423{ 423{
424 std::vector<GpgME::Key> keys; 424 std::vector<MailCrypto::Key> keys;
425 { 425 {
426 const auto list = toController()->getList<std::vector<GpgME::Key>>("key"); 426 const auto list = toController()->getList<std::vector<MailCrypto::Key>>("key");
427 for (const auto &l: list) { 427 for (const auto &l: list) {
428 keys.insert(std::end(keys), std::begin(l), std::end(l)); 428 keys.insert(std::end(keys), std::begin(l), std::end(l));
429 } 429 }
430 } 430 }
431 { 431 {
432 const auto list = ccController()->getList<std::vector<GpgME::Key>>("key"); 432 const auto list = ccController()->getList<std::vector<MailCrypto::Key>>("key");
433 for (const auto &l: list) { 433 for (const auto &l: list) {
434 keys.insert(std::end(keys), std::begin(l), std::end(l)); 434 keys.insert(std::end(keys), std::begin(l), std::end(l));
435 } 435 }
436 } 436 }
437 { 437 {
438 const auto list = bccController()->getList<std::vector<GpgME::Key>>("key"); 438 const auto list = bccController()->getList<std::vector<MailCrypto::Key>>("key");
439 for (const auto &l: list) { 439 for (const auto &l: list) {
440 keys.insert(std::end(keys), std::begin(l), std::end(l)); 440 keys.insert(std::end(keys), std::begin(l), std::end(l));
441 } 441 }
@@ -463,17 +463,17 @@ KMime::Message::Ptr ComposerController::assembleMessage()
463 }; 463 };
464 }); 464 });
465 465
466 GpgME::Key attachedKey; 466 MailCrypto::Key attachedKey;
467 std::vector<GpgME::Key> signingKeys; 467 std::vector<MailCrypto::Key> signingKeys;
468 if (getSign()) { 468 if (getSign()) {
469 signingKeys = getPersonalKeys().value<std::vector<GpgME::Key>>(); 469 signingKeys = getPersonalKeys().value<std::vector<MailCrypto::Key>>();
470 Q_ASSERT(!signingKeys.empty()); 470 Q_ASSERT(!signingKeys.empty());
471 attachedKey = signingKeys[0]; 471 attachedKey = signingKeys[0];
472 } 472 }
473 std::vector<GpgME::Key> encryptionKeys; 473 std::vector<MailCrypto::Key> encryptionKeys;
474 if (getEncrypt()) { 474 if (getEncrypt()) {
475 //Encrypt to self so we can read the sent message 475 //Encrypt to self so we can read the sent message
476 auto personalKeys = getPersonalKeys().value<std::vector<GpgME::Key>>(); 476 auto personalKeys = getPersonalKeys().value<std::vector<MailCrypto::Key>>();
477 477
478 attachedKey = personalKeys[0]; 478 attachedKey = personalKeys[0];
479 479
diff --git a/framework/src/domain/composercontroller.h b/framework/src/domain/composercontroller.h
index ac83dfd3..17271dce 100644
--- a/framework/src/domain/composercontroller.h
+++ b/framework/src/domain/composercontroller.h
@@ -26,7 +26,7 @@
26#include <QStandardItemModel> 26#include <QStandardItemModel>
27#include <sink/applicationdomaintype.h> 27#include <sink/applicationdomaintype.h>
28#include <KMime/Message> 28#include <KMime/Message>
29#include <gpgme++/key.h> 29#include <mime/mailcrypto.h>
30 30
31#include "completer.h" 31#include "completer.h"
32#include "selector.h" 32#include "selector.h"
@@ -39,7 +39,6 @@ inline bool operator !=(const KMime::Types::Mailbox &l, const KMime::Types::Mail
39 39
40Q_DECLARE_METATYPE(KMime::Types::Mailbox); 40Q_DECLARE_METATYPE(KMime::Types::Mailbox);
41 41
42Q_DECLARE_METATYPE(GpgME::Key);
43 42
44namespace KMime { 43namespace KMime {
45class Message; 44class Message;
@@ -66,7 +65,7 @@ class ComposerController : public Kube::Controller
66 KUBE_CONTROLLER_PROPERTY(KMime::Message::Ptr, ExistingMessage, existingMessage) 65 KUBE_CONTROLLER_PROPERTY(KMime::Message::Ptr, ExistingMessage, existingMessage)
67 KUBE_CONTROLLER_PROPERTY(Sink::ApplicationDomain::Mail, ExistingMail, existingMail) 66 KUBE_CONTROLLER_PROPERTY(Sink::ApplicationDomain::Mail, ExistingMail, existingMail)
68 67
69 KUBE_CONTROLLER_PROPERTY(/*std::vector<GpgME::Key>*/QVariant, PersonalKeys, personalKeys) 68 KUBE_CONTROLLER_PROPERTY(/*std::vector<MailCrypto::Key>*/QVariant, PersonalKeys, personalKeys)
70 KUBE_CONTROLLER_PROPERTY(bool, FoundPersonalKeys, foundPersonalKeys) 69 KUBE_CONTROLLER_PROPERTY(bool, FoundPersonalKeys, foundPersonalKeys)
71 70
72 KUBE_CONTROLLER_LISTCONTROLLER(to) 71 KUBE_CONTROLLER_LISTCONTROLLER(to)
@@ -110,7 +109,7 @@ private:
110 void setMessage(const QSharedPointer<KMime::Message> &msg); 109 void setMessage(const QSharedPointer<KMime::Message> &msg);
111 void addAttachmentPart(KMime::Content *partToAttach); 110 void addAttachmentPart(KMime::Content *partToAttach);
112 KMime::Message::Ptr assembleMessage(); 111 KMime::Message::Ptr assembleMessage();
113 std::vector<GpgME::Key> getRecipientKeys(); 112 std::vector<MailCrypto::Key> getRecipientKeys();
114 113
115 QScopedPointer<Completer> mRecipientCompleter; 114 QScopedPointer<Completer> mRecipientCompleter;
116 QScopedPointer<Selector> mIdentitySelector; 115 QScopedPointer<Selector> mIdentitySelector;
diff --git a/framework/src/domain/mime/mailcrypto.cpp b/framework/src/domain/mime/mailcrypto.cpp
index da1b82c7..a7f3772a 100644
--- a/framework/src/domain/mime/mailcrypto.cpp
+++ b/framework/src/domain/mime/mailcrypto.cpp
@@ -44,6 +44,21 @@
44#include <future> 44#include <future>
45#include <utility> 45#include <utility>
46 46
47using namespace MailCrypto;
48
49QDebug operator<< (QDebug d, const MailCrypto::Key &key)
50{
51 d << key.key.primaryFingerprint();
52 return d;
53}
54
55static std::vector<GpgME::Key> toGpgME(const std::vector<Key> keys)
56{
57 std::vector<GpgME::Key> list;
58 std::transform(keys.begin(), keys.end(), std::back_inserter(list), [] (const Key &key) { return key.key; });
59 return list;
60}
61
47// replace simple LFs by CRLFs for all MIME supporting CryptPlugs 62// replace simple LFs by CRLFs for all MIME supporting CryptPlugs
48// according to RfC 2633, 3.1.1 Canonicalization 63// according to RfC 2633, 3.1.1 Canonicalization
49static QByteArray canonicalizeContent(KMime::Content *content) 64static QByteArray canonicalizeContent(KMime::Content *content)
@@ -112,7 +127,7 @@ static QByteArray canonicalizeContent(KMime::Content *content)
112/** 127/**
113 * Get the given `key` in the armor format. 128 * Get the given `key` in the armor format.
114 */ 129 */
115Expected<GpgME::Error, QByteArray> exportPublicKey(const GpgME::Key &key) 130Expected<Error, QByteArray> exportPublicKey(const Key &key)
116{ 131{
117 // Not using the Qt API because it apparently blocks (the `result` signal is never 132 // Not using the Qt API because it apparently blocks (the `result` signal is never
118 // triggered) 133 // triggered)
@@ -122,11 +137,11 @@ Expected<GpgME::Error, QByteArray> exportPublicKey(const GpgME::Key &key)
122 QGpgME::QByteArrayDataProvider dp; 137 QGpgME::QByteArrayDataProvider dp;
123 GpgME::Data data(&dp); 138 GpgME::Data data(&dp);
124 139
125 qDebug() << "Exporting public key:" << key.shortKeyID(); 140 qDebug() << "Exporting public key:" << key.key.shortKeyID();
126 auto error = ctx->exportPublicKeys(key.keyID(), data); 141 auto error = ctx->exportPublicKeys(key.key.keyID(), data);
127 142
128 if (error.code()) { 143 if (error.code()) {
129 return makeUnexpected(error); 144 return makeUnexpected(Error{error});
130 } 145 }
131 146
132 return dp.data(); 147 return dp.data();
@@ -143,14 +158,14 @@ Expected<GpgME::Error, QByteArray> exportPublicKey(const GpgME::Key &key)
143 * 158 *
144 * Used by the `createSignedEmail` and `createEncryptedEmail` functions. 159 * Used by the `createSignedEmail` and `createEncryptedEmail` functions.
145 */ 160 */
146Expected<GpgME::Error, std::unique_ptr<KMime::Content>> 161Expected<Error, std::unique_ptr<KMime::Content>>
147appendPublicKey(std::unique_ptr<KMime::Content> msg, const GpgME::Key &key) 162appendPublicKey(std::unique_ptr<KMime::Content> msg, const Key &key)
148{ 163{
149 const auto publicKeyExportResult = exportPublicKey(key); 164 const auto publicKeyExportResult = exportPublicKey(key);
150 165
151 if (!publicKeyExportResult) { 166 if (!publicKeyExportResult) {
152 // "Could not export public key" 167 // "Could not export public key"
153 return makeUnexpected(publicKeyExportResult.error()); 168 return makeUnexpected(Error{publicKeyExportResult.error()});
154 } 169 }
155 170
156 const auto publicKeyData = publicKeyExportResult.value(); 171 const auto publicKeyData = publicKeyExportResult.value();
@@ -163,7 +178,7 @@ appendPublicKey(std::unique_ptr<KMime::Content> msg, const GpgME::Key &key)
163 { 178 {
164 keyAttachment->contentType()->setMimeType("application/pgp-keys"); 179 keyAttachment->contentType()->setMimeType("application/pgp-keys");
165 keyAttachment->contentDisposition()->setDisposition(KMime::Headers::CDattachment); 180 keyAttachment->contentDisposition()->setDisposition(KMime::Headers::CDattachment);
166 keyAttachment->contentDisposition()->setFilename(QString("0x") + key.shortKeyID() + ".asc"); 181 keyAttachment->contentDisposition()->setFilename(QString("0x") + key.key.shortKeyID() + ".asc");
167 keyAttachment->setBody(publicKeyData); 182 keyAttachment->setBody(publicKeyData);
168 } 183 }
169 184
@@ -177,39 +192,39 @@ appendPublicKey(std::unique_ptr<KMime::Content> msg, const GpgME::Key &key)
177 return result; 192 return result;
178} 193}
179 194
180Expected<GpgME::Error, QByteArray> encrypt(const QByteArray &content, const std::vector<GpgME::Key> &encryptionKeys) 195Expected<Error, QByteArray> encrypt(const QByteArray &content, const std::vector<Key> &encryptionKeys)
181{ 196{
182 QByteArray resultData; 197 QByteArray resultData;
183 198
184 const QGpgME::Protocol *const proto = QGpgME::openpgp(); 199 const QGpgME::Protocol *const proto = QGpgME::openpgp();
185 std::unique_ptr<QGpgME::EncryptJob> job(proto->encryptJob(/* armor = */ true)); 200 std::unique_ptr<QGpgME::EncryptJob> job(proto->encryptJob(/* armor = */ true));
186 const auto result = job->exec(encryptionKeys, content, /* alwaysTrust = */ true, resultData); 201 const auto result = job->exec(toGpgME(encryptionKeys), content, /* alwaysTrust = */ true, resultData);
187 202
188 if (result.error().code()) { 203 if (result.error().code()) {
189 qWarning() << "Encryption failed:" << result.error().asString(); 204 qWarning() << "Encryption failed:" << result.error().asString();
190 return makeUnexpected(result.error()); 205 return makeUnexpected(Error{result.error()});
191 } 206 }
192 207
193 return resultData; 208 return resultData;
194} 209}
195 210
196Expected<GpgME::Error, QByteArray> signAndEncrypt(const QByteArray &content, 211Expected<Error, QByteArray> signAndEncrypt(const QByteArray &content,
197 const std::vector<GpgME::Key> &signingKeys, const std::vector<GpgME::Key> &encryptionKeys) 212 const std::vector<Key> &signingKeys, const std::vector<Key> &encryptionKeys)
198{ 213{
199 QByteArray resultData; 214 QByteArray resultData;
200 215
201 const QGpgME::Protocol *const proto = QGpgME::openpgp(); 216 const QGpgME::Protocol *const proto = QGpgME::openpgp();
202 std::unique_ptr<QGpgME::SignEncryptJob> job(proto->signEncryptJob(/* armor = */ true)); 217 std::unique_ptr<QGpgME::SignEncryptJob> job(proto->signEncryptJob(/* armor = */ true));
203 const auto result = job->exec(signingKeys, encryptionKeys, content, /* alwaysTrust = */ true, resultData); 218 const auto result = job->exec(toGpgME(signingKeys), toGpgME(encryptionKeys), content, /* alwaysTrust = */ true, resultData);
204 219
205 if (result.first.error().code()) { 220 if (result.first.error().code()) {
206 qWarning() << "Signing failed:" << result.first.error().asString(); 221 qWarning() << "Signing failed:" << result.first.error().asString();
207 return makeUnexpected(result.first.error()); 222 return makeUnexpected(Error{result.first.error()});
208 } 223 }
209 224
210 if (result.second.error().code()) { 225 if (result.second.error().code()) {
211 qWarning() << "Encryption failed:" << result.second.error().asString(); 226 qWarning() << "Encryption failed:" << result.second.error().asString();
212 return makeUnexpected(result.second.error()); 227 return makeUnexpected(Error{result.second.error()});
213 } 228 }
214 229
215 return resultData; 230 return resultData;
@@ -276,9 +291,9 @@ std::unique_ptr<KMime::Content> createEncryptedPart(QByteArray encryptedData)
276 * - `application/pgp-keys` (the public key as attachment, which is the first of the 291 * - `application/pgp-keys` (the public key as attachment, which is the first of the
277 * `signingKeys`) 292 * `signingKeys`)
278 */ 293 */
279Expected<GpgME::Error, std::unique_ptr<KMime::Content>> 294Expected<Error, std::unique_ptr<KMime::Content>>
280createEncryptedEmail(KMime::Content *content, const std::vector<GpgME::Key> &encryptionKeys, 295createEncryptedEmail(KMime::Content *content, const std::vector<Key> &encryptionKeys,
281 const GpgME::Key &attachedKey, const std::vector<GpgME::Key> &signingKeys = {}) 296 const Key &attachedKey, const std::vector<Key> &signingKeys = {})
282{ 297{
283 auto contentToEncrypt = canonicalizeContent(content); 298 auto contentToEncrypt = canonicalizeContent(content);
284 299
@@ -287,7 +302,7 @@ createEncryptedEmail(KMime::Content *content, const std::vector<GpgME::Key> &enc
287 signAndEncrypt(contentToEncrypt, signingKeys, encryptionKeys); 302 signAndEncrypt(contentToEncrypt, signingKeys, encryptionKeys);
288 303
289 if (!encryptionResult) { 304 if (!encryptionResult) {
290 return makeUnexpected(encryptionResult.error()); 305 return makeUnexpected(Error{encryptionResult.error()});
291 } 306 }
292 307
293 auto encryptedPart = createEncryptedPart(encryptionResult.value()); 308 auto encryptedPart = createEncryptedPart(encryptionResult.value());
@@ -305,18 +320,18 @@ createEncryptedEmail(KMime::Content *content, const std::vector<GpgME::Key> &enc
305 * Sign the given content and returns the signing data and the algorithm used 320 * Sign the given content and returns the signing data and the algorithm used
306 * for integrity check in the "pgp-<algorithm>" format. 321 * for integrity check in the "pgp-<algorithm>" format.
307 */ 322 */
308Expected<GpgME::Error, std::pair<QByteArray, QString>> 323Expected<Error, std::pair<QByteArray, QString>>
309sign(const QByteArray &content, const std::vector<GpgME::Key> &signingKeys) 324sign(const QByteArray &content, const std::vector<Key> &signingKeys)
310{ 325{
311 QByteArray resultData; 326 QByteArray resultData;
312 327
313 const QGpgME::Protocol *const proto = QGpgME::openpgp(); 328 const QGpgME::Protocol *const proto = QGpgME::openpgp();
314 std::unique_ptr<QGpgME::SignJob> job(proto->signJob(/* armor = */ true)); 329 std::unique_ptr<QGpgME::SignJob> job(proto->signJob(/* armor = */ true));
315 const auto result = job->exec(signingKeys, content, GpgME::Detached, resultData); 330 const auto result = job->exec(toGpgME(signingKeys), content, GpgME::Detached, resultData);
316 331
317 if (result.error().code()) { 332 if (result.error().code()) {
318 qWarning() << "Signing failed:" << result.error().asString(); 333 qWarning() << "Signing failed:" << result.error().asString();
319 return makeUnexpected(result.error()); 334 return makeUnexpected(Error{result.error()});
320 } 335 }
321 336
322 auto algo = result.createdSignature(0).hashAlgorithmAsString(); 337 auto algo = result.createdSignature(0).hashAlgorithmAsString();
@@ -380,9 +395,9 @@ std::unique_ptr<KMime::Content> createSignedPart(
380 * - `application/pgp-keys` (the public key as attachment, which is the first of the 395 * - `application/pgp-keys` (the public key as attachment, which is the first of the
381 * `signingKeys`) 396 * `signingKeys`)
382 */ 397 */
383Expected<GpgME::Error, std::unique_ptr<KMime::Content>> 398Expected<Error, std::unique_ptr<KMime::Content>>
384createSignedEmail(std::unique_ptr<KMime::Content> content, 399createSignedEmail(std::unique_ptr<KMime::Content> content,
385 const std::vector<GpgME::Key> &signingKeys, const GpgME::Key &attachedKey) 400 const std::vector<Key> &signingKeys, const Key &attachedKey)
386{ 401{
387 Q_ASSERT(!signingKeys.empty()); 402 Q_ASSERT(!signingKeys.empty());
388 403
@@ -391,7 +406,7 @@ createSignedEmail(std::unique_ptr<KMime::Content> content,
391 auto signingResult = sign(contentToSign, signingKeys); 406 auto signingResult = sign(contentToSign, signingKeys);
392 407
393 if (!signingResult) { 408 if (!signingResult) {
394 return makeUnexpected(signingResult.error()); 409 return makeUnexpected(Error{signingResult.error()});
395 } 410 }
396 411
397 QByteArray signingData; 412 QByteArray signingData;
@@ -409,9 +424,9 @@ createSignedEmail(std::unique_ptr<KMime::Content> content,
409 return publicKeyAppendResult; 424 return publicKeyAppendResult;
410} 425}
411 426
412Expected<GpgME::Error, std::unique_ptr<KMime::Content>> 427Expected<Error, std::unique_ptr<KMime::Content>>
413MailCrypto::processCrypto(std::unique_ptr<KMime::Content> content, const std::vector<GpgME::Key> &signingKeys, 428MailCrypto::processCrypto(std::unique_ptr<KMime::Content> content, const std::vector<Key> &signingKeys,
414 const std::vector<GpgME::Key> &encryptionKeys, const GpgME::Key &attachedKey) 429 const std::vector<Key> &encryptionKeys, const Key &attachedKey)
415{ 430{
416 if (!encryptionKeys.empty()) { 431 if (!encryptionKeys.empty()) {
417 return createEncryptedEmail(content.release(), encryptionKeys, attachedKey, signingKeys); 432 return createEncryptedEmail(content.release(), encryptionKeys, attachedKey, signingKeys);
@@ -423,12 +438,12 @@ MailCrypto::processCrypto(std::unique_ptr<KMime::Content> content, const std::ve
423 } 438 }
424} 439}
425 440
426void MailCrypto::importKeys(const std::vector<GpgME::Key> &keys) 441void MailCrypto::importKeys(const std::vector<Key> &keys)
427{ 442{
428 const QGpgME::Protocol *const backend = QGpgME::openpgp(); 443 const QGpgME::Protocol *const backend = QGpgME::openpgp();
429 Q_ASSERT(backend); 444 Q_ASSERT(backend);
430 auto *job = backend->importFromKeyserverJob(); 445 auto *job = backend->importFromKeyserverJob();
431 job->exec(keys); 446 job->exec(toGpgME(keys));
432} 447}
433 448
434MailCrypto::ImportResult MailCrypto::importKey(const QByteArray &pkey) 449MailCrypto::ImportResult MailCrypto::importKey(const QByteArray &pkey)
@@ -439,7 +454,7 @@ MailCrypto::ImportResult MailCrypto::importKey(const QByteArray &pkey)
439 return {result.numConsidered(), result.numImported(), result.numUnchanged()}; 454 return {result.numConsidered(), result.numImported(), result.numUnchanged()};
440} 455}
441 456
442static GpgME::KeyListResult listKeys(const QStringList &patterns, bool secretOnly, int keyListMode, std::vector<GpgME::Key> &keys) 457static GpgME::KeyListResult listKeys(const QStringList &patterns, bool secretOnly, int keyListMode, std::vector<Key> &keys)
443{ 458{
444 QByteArrayList list; 459 QByteArrayList list;
445 std::transform(patterns.constBegin(), patterns.constEnd(), std::back_inserter(list), [] (const QString &s) { return s.toUtf8(); }); 460 std::transform(patterns.constBegin(), patterns.constEnd(), std::back_inserter(list), [] (const QString &s) { return s.toUtf8(); });
@@ -456,7 +471,7 @@ static GpgME::KeyListResult listKeys(const QStringList &patterns, bool secretOnl
456 471
457 GpgME::Error err; 472 GpgME::Error err;
458 do { 473 do {
459 keys.push_back( ctx->nextKey(err)); 474 keys.push_back( Key{ctx->nextKey(err)});
460 } while ( !err ); 475 } while ( !err );
461 476
462 keys.pop_back(); 477 keys.pop_back();
@@ -466,21 +481,21 @@ static GpgME::KeyListResult listKeys(const QStringList &patterns, bool secretOnl
466 return result; 481 return result;
467} 482}
468 483
469std::vector<GpgME::Key> MailCrypto::findKeys(const QStringList &filter, bool findPrivate, bool remote) 484std::vector<Key> MailCrypto::findKeys(const QStringList &filter, bool findPrivate, bool remote)
470{ 485{
471 std::vector<GpgME::Key> keys; 486 std::vector<Key> keys;
472 GpgME::KeyListResult res = listKeys(filter, findPrivate, remote ? GpgME::Extern : GpgME::Local, keys); 487 GpgME::KeyListResult res = listKeys(filter, findPrivate, remote ? GpgME::Extern : GpgME::Local, keys);
473 if (res.error()) { 488 if (res.error()) {
474 qWarning() << "Failed to lookup keys: " << res.error().asString(); 489 qWarning() << "Failed to lookup keys: " << res.error().asString();
475 return keys; 490 return {};
476 } 491 }
477 qWarning() << "got keys:" << keys.size(); 492 qWarning() << "got keys:" << keys.size();
478 493
479 for (std::vector< GpgME::Key >::iterator i = keys.begin(); i != keys.end(); ++i) { 494 for (auto i = keys.begin(); i != keys.end(); ++i) {
480 qWarning() << "key isnull:" << i->isNull() << "isexpired:" << i->isExpired(); 495 qWarning() << "key isnull:" << i->key.isNull() << "isexpired:" << i->key.isExpired();
481 qWarning() << "key numuserIds:" << i->numUserIDs(); 496 qWarning() << "key numuserIds:" << i->key.numUserIDs();
482 for (uint k = 0; k < i->numUserIDs(); ++k) { 497 for (uint k = 0; k < i->key.numUserIDs(); ++k) {
483 qWarning() << "userIDs:" << i->userID(k).email(); 498 qWarning() << "userIDs:" << i->key.userID(k).email();
484 } 499 }
485 } 500 }
486 501
diff --git a/framework/src/domain/mime/mailcrypto.h b/framework/src/domain/mime/mailcrypto.h
index 9e317b43..c9247859 100644
--- a/framework/src/domain/mime/mailcrypto.h
+++ b/framework/src/domain/mime/mailcrypto.h
@@ -25,19 +25,28 @@
25#include <gpgme++/key.h> 25#include <gpgme++/key.h>
26 26
27#include <QByteArray> 27#include <QByteArray>
28#include <QVariant>
28 29
29#include <functional> 30#include <functional>
30#include <memory> 31#include <memory>
31 32
32namespace MailCrypto { 33namespace MailCrypto {
33 34
34Expected<GpgME::Error, std::unique_ptr<KMime::Content>> 35struct Key {
35processCrypto(std::unique_ptr<KMime::Content> content, const std::vector<GpgME::Key> &signingKeys, 36 GpgME::Key key;
36 const std::vector<GpgME::Key> &encryptionKeys, const GpgME::Key &attachedKey); 37};
38
39struct Error {
40 GpgME::Error key;
41};
37 42
38std::vector<GpgME::Key> findKeys(const QStringList &filter, bool findPrivate = false, bool remote = false); 43Expected<Error, std::unique_ptr<KMime::Content>>
44processCrypto(std::unique_ptr<KMime::Content> content, const std::vector<Key> &signingKeys,
45 const std::vector<Key> &encryptionKeys, const Key &attachedKey);
39 46
40void importKeys(const std::vector<GpgME::Key> &keys); 47std::vector<Key> findKeys(const QStringList &filter, bool findPrivate = false, bool remote = false);
48
49void importKeys(const std::vector<Key> &keys);
41 50
42struct ImportResult { 51struct ImportResult {
43 int considered; 52 int considered;
@@ -48,3 +57,7 @@ struct ImportResult {
48ImportResult importKey(const QByteArray &key); 57ImportResult importKey(const QByteArray &key);
49 58
50}; // namespace MailCrypto 59}; // namespace MailCrypto
60
61Q_DECLARE_METATYPE(MailCrypto::Key);
62
63QDebug operator<< (QDebug d, const MailCrypto::Key &);
diff --git a/framework/src/domain/mime/mailtemplates.cpp b/framework/src/domain/mime/mailtemplates.cpp
index a614da1a..ac2b2b72 100644
--- a/framework/src/domain/mime/mailtemplates.cpp
+++ b/framework/src/domain/mime/mailtemplates.cpp
@@ -1027,8 +1027,8 @@ static KMime::Types::Mailbox::List stringListToMailboxes(const QStringList &list
1027KMime::Message::Ptr MailTemplates::createMessage(KMime::Message::Ptr existingMessage, 1027KMime::Message::Ptr MailTemplates::createMessage(KMime::Message::Ptr existingMessage,
1028 const QStringList &to, const QStringList &cc, const QStringList &bcc, 1028 const QStringList &to, const QStringList &cc, const QStringList &bcc,
1029 const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody, 1029 const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody,
1030 const QList<Attachment> &attachments, const std::vector<GpgME::Key> &signingKeys, 1030 const QList<Attachment> &attachments, const std::vector<MailCrypto::Key> &signingKeys,
1031 const std::vector<GpgME::Key> &encryptionKeys, const GpgME::Key &attachedKey) 1031 const std::vector<MailCrypto::Key> &encryptionKeys, const MailCrypto::Key &attachedKey)
1032{ 1032{
1033 auto mail = existingMessage; 1033 auto mail = existingMessage;
1034 if (!mail) { 1034 if (!mail) {
diff --git a/framework/src/domain/mime/mailtemplates.h b/framework/src/domain/mime/mailtemplates.h
index 154b76a2..a894d120 100644
--- a/framework/src/domain/mime/mailtemplates.h
+++ b/framework/src/domain/mime/mailtemplates.h
@@ -22,7 +22,7 @@
22#include <QByteArray> 22#include <QByteArray>
23#include <KMime/Message> 23#include <KMime/Message>
24#include <functional> 24#include <functional>
25#include <gpgme++/key.h> 25#include <mailcrypto.h>
26 26
27struct Attachment { 27struct Attachment {
28 QString name; 28 QString name;
@@ -38,5 +38,5 @@ namespace MailTemplates
38 void forward(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback); 38 void forward(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback);
39 QString plaintextContent(const KMime::Message::Ptr &origMsg); 39 QString plaintextContent(const KMime::Message::Ptr &origMsg);
40 QString body(const KMime::Message::Ptr &msg, bool &isHtml); 40 QString body(const KMime::Message::Ptr &msg, bool &isHtml);
41 KMime::Message::Ptr createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody, const QList<Attachment> &attachments, const std::vector<GpgME::Key> &signingKeys = {}, const std::vector<GpgME::Key> &encryptionKeys = {}, const GpgME::Key &attachedKey = {}); 41 KMime::Message::Ptr createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, bool htmlBody, const QList<Attachment> &attachments, const std::vector<MailCrypto::Key> &signingKeys = {}, const std::vector<MailCrypto::Key> &encryptionKeys = {}, const MailCrypto::Key &attachedKey = {});
42}; 42};
diff --git a/framework/src/domain/mime/tests/mailtemplatetest.cpp b/framework/src/domain/mime/tests/mailtemplatetest.cpp
index d07b704d..75debd75 100644
--- a/framework/src/domain/mime/tests/mailtemplatetest.cpp
+++ b/framework/src/domain/mime/tests/mailtemplatetest.cpp
@@ -6,10 +6,6 @@
6#include <QDir> 6#include <QDir>
7#include <QtWebEngine> 7#include <QtWebEngine>
8 8
9#include <QGpgME/KeyListJob>
10#include <QGpgME/Protocol>
11#include <gpgme++/key.h>
12#include <gpgme++/keylistresult.h>
13 9
14#include "mailtemplates.h" 10#include "mailtemplates.h"
15#include "mailcrypto.h" 11#include "mailcrypto.h"
@@ -24,45 +20,6 @@ static KMime::Content *getSubpart(KMime::Content *msg, const QByteArray &mimeTyp
24 return nullptr; 20 return nullptr;
25} 21}
26 22
27static std::vector< GpgME::Key, std::allocator< GpgME::Key > > getKeys(bool smime = false)
28{
29 QGpgME::KeyListJob *job = nullptr;
30
31 if (smime) {
32 const QGpgME::Protocol *const backend = QGpgME::smime();
33 Q_ASSERT(backend);
34 job = backend->keyListJob(/* remote = */ false);
35 } else {
36 const QGpgME::Protocol *const backend = QGpgME::openpgp();
37 Q_ASSERT(backend);
38 job = backend->keyListJob(/* remote = */ false);
39 }
40 Q_ASSERT(job);
41
42 std::vector< GpgME::Key > keys;
43 GpgME::KeyListResult res = job->exec(QStringList(), /* secretOnly = */ true, keys);
44
45 if (!smime) {
46 Q_ASSERT(keys.size() == 3);
47 }
48
49 Q_ASSERT(!res.error());
50
51 /*
52 qDebug() << "got private keys:" << keys.size();
53
54 for (std::vector< GpgME::Key >::iterator i = keys.begin(); i != keys.end(); ++i) {
55 qDebug() << "key isnull:" << i->isNull() << "isexpired:" << i->isExpired();
56 qDebug() << "key numuserIds:" << i->numUserIDs();
57 for (uint k = 0; k < i->numUserIDs(); ++k) {
58 qDebug() << "userIDs:" << i->userID(k).email();
59 }
60 }
61 */
62
63 return keys;
64}
65
66static QByteArray readMailFromFile(const QString &mailFile) 23static QByteArray readMailFromFile(const QString &mailFile)
67{ 24{
68 Q_ASSERT(!QString::fromLatin1(MAIL_DATA_DIR).isEmpty()); 25 Q_ASSERT(!QString::fromLatin1(MAIL_DATA_DIR).isEmpty());
@@ -399,8 +356,7 @@ private slots:
399 QString body = "body"; 356 QString body = "body";
400 QList<Attachment> attachments; 357 QList<Attachment> attachments;
401 358
402 std::vector<GpgME::Key> keys = getKeys(); 359 auto keys = MailCrypto::findKeys({}, true, false);
403
404 auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments, keys, {}, keys[0]); 360 auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments, keys, {}, keys[0]);
405 361
406 QVERIFY(result); 362 QVERIFY(result);
@@ -442,9 +398,7 @@ private slots:
442 QString body = "body"; 398 QString body = "body";
443 QList<Attachment> attachments = {{"name", "filename", "mimetype", true, "inlineAttachment"}, {"name", "filename", "mimetype", false, "nonInlineAttachment"}}; 399 QList<Attachment> attachments = {{"name", "filename", "mimetype", true, "inlineAttachment"}, {"name", "filename", "mimetype", false, "nonInlineAttachment"}};
444 400
445 std::vector<GpgME::Key> keys = getKeys(); 401 auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments, MailCrypto::findKeys({}, true, false));
446
447 auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments, keys);
448 402
449 QVERIFY(result); 403 QVERIFY(result);
450 QCOMPARE(result->subject()->asUnicodeString(), subject); 404 QCOMPARE(result->subject()->asUnicodeString(), subject);