summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-11-23 15:53:52 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-11-23 15:53:52 +0100
commitc1fc67e40c1b467d50aa27a676fa65c25b767872 (patch)
tree5b76b109ffa4d3c3d1c64adb62196541cb2bdc38
parentcbd402c36699e93c3015951f52f0adfc7320751b (diff)
downloadkube-c1fc67e40c1b467d50aa27a676fa65c25b767872.tar.gz
kube-c1fc67e40c1b467d50aa27a676fa65c25b767872.zip
Encrypted mails
-rw-r--r--framework/src/domain/composercontroller.cpp53
-rw-r--r--framework/src/domain/mime/mailtemplates.cpp45
-rw-r--r--framework/src/domain/mime/mailtemplates.h2
3 files changed, 76 insertions, 24 deletions
diff --git a/framework/src/domain/composercontroller.cpp b/framework/src/domain/composercontroller.cpp
index fb3857a5..630f9e10 100644
--- a/framework/src/domain/composercontroller.cpp
+++ b/framework/src/domain/composercontroller.cpp
@@ -38,6 +38,8 @@
38#include "mime/mailtemplates.h" 38#include "mime/mailtemplates.h"
39#include "mime/mailcrypto.h" 39#include "mime/mailcrypto.h"
40 40
41Q_DECLARE_METATYPE(GpgME::Key);
42
41class IdentitySelector : public Selector { 43class IdentitySelector : public Selector {
42public: 44public:
43 IdentitySelector(ComposerController &controller) : Selector(new IdentitiesModel), mController(controller) 45 IdentitySelector(ComposerController &controller) : Selector(new IdentitiesModel), mController(controller)
@@ -105,6 +107,18 @@ public:
105 item->setData(addressee, ComposerController::AddresseeNameRole); 107 item->setData(addressee, ComposerController::AddresseeNameRole);
106 item->setData(false, ComposerController::KeyFoundRole); 108 item->setData(false, ComposerController::KeyFoundRole);
107 appendRow(QList<QStandardItem*>() << item); 109 appendRow(QList<QStandardItem*>() << item);
110 findKey(addressee, item);
111 }
112
113 void findKey(const QString &addressee, QStandardItem *item)
114 {
115 auto keys = MailCrypto::findKeys(QStringList{} << addressee, false, MailCrypto::OPENPGP);
116 if (item) {
117 if (!keys.empty()) {
118 item->setData(true, ComposerController::KeyFoundRole);
119 item->setData(QVariant::fromValue(keys.front()), ComposerController::KeyRole);
120 }
121 }
108 } 122 }
109 123
110 void remove(const QString &addressee) 124 void remove(const QString &addressee)
@@ -118,6 +132,30 @@ public:
118 } 132 }
119 } 133 }
120 134
135 bool foundAllKeys()
136 {
137 std::vector<GpgME::Key> keys;
138 auto root = invisibleRootItem();
139 for (int row = 0; row < root->rowCount(); row++) {
140 auto item = root->child(row, 0);
141 if (!item->data(ComposerController::KeyFoundRole).toBool()) {
142 return false;
143 }
144 }
145 return true;
146 }
147
148 std::vector<GpgME::Key> getKeys()
149 {
150 std::vector<GpgME::Key> keys;
151 auto root = invisibleRootItem();
152 for (int row = 0; row < root->rowCount(); row++) {
153 auto item = root->child(row, 0);
154 keys.push_back(item->data(ComposerController::KeyRole).value<GpgME::Key>());
155 }
156 return keys;
157 }
158
121 void setStringList(const QStringList &list) 159 void setStringList(const QStringList &list)
122 { 160 {
123 clear(); 161 clear();
@@ -479,8 +517,21 @@ KMime::Message::Ptr ComposerController::assembleMessage()
479 if (getSign()) { 517 if (getSign()) {
480 signingKeys = mPersonalKeys; 518 signingKeys = mPersonalKeys;
481 } 519 }
520 std::vector<GpgME::Key> encryptionKeys;
521 if (getEncrypt()) {
522 if (!mToModel->foundAllKeys() || !mCcModel->foundAllKeys() || !mBccModel->foundAllKeys()) {
523 qWarning() << "Can't encrypt with missing keys";
524 return nullptr;
525 }
526 auto toKeys = mToModel->getKeys();
527 encryptionKeys.insert(std::end(encryptionKeys), std::begin(toKeys), std::end(toKeys));
528 auto ccKeys = mCcModel->getKeys();
529 encryptionKeys.insert(std::end(encryptionKeys), std::begin(ccKeys), std::end(ccKeys));
530 auto bccKeys = mBccModel->getKeys();
531 encryptionKeys.insert(std::end(encryptionKeys), std::begin(bccKeys), std::end(bccKeys));
532 }
482 533
483 return MailTemplates::createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), getHtmlBody(), attachments, signingKeys); 534 return MailTemplates::createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), getHtmlBody(), attachments, signingKeys, encryptionKeys);
484} 535}
485 536
486void ComposerController::updateSendAction() 537void ComposerController::updateSendAction()
diff --git a/framework/src/domain/mime/mailtemplates.cpp b/framework/src/domain/mime/mailtemplates.cpp
index bbe079d8..5f5b35df 100644
--- a/framework/src/domain/mime/mailtemplates.cpp
+++ b/framework/src/domain/mime/mailtemplates.cpp
@@ -958,7 +958,7 @@ static KMime::Types::Mailbox::List stringListToMailboxes(const QStringList &list
958 return mailboxes; 958 return mailboxes;
959} 959}
960 960
961KMime::Message::Ptr MailTemplates::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) 961KMime::Message::Ptr MailTemplates::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)
962{ 962{
963 auto mail = existingMessage; 963 auto mail = existingMessage;
964 if (!mail) { 964 if (!mail) {
@@ -995,41 +995,42 @@ KMime::Message::Ptr MailTemplates::createMessage(KMime::Message::Ptr existingMes
995 } 995 }
996 mail->assemble(); 996 mail->assemble();
997 997
998 KMime::Content *bodyPart; 998 std::unique_ptr<KMime::Content> bodyPart{[&] {
999 if (!attachments.isEmpty()) { 999 if (!attachments.isEmpty()) {
1000 bodyPart = new KMime::Content; 1000 auto bodyPart = new KMime::Content;
1001 bodyPart->contentType(true)->setMimeType("multipart/mixed"); 1001 bodyPart->contentType(true)->setMimeType("multipart/mixed");
1002 bodyPart->contentType()->setBoundary(KMime::multiPartBoundary()); 1002 bodyPart->contentType()->setBoundary(KMime::multiPartBoundary());
1003 bodyPart->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit); 1003 bodyPart->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit);
1004 bodyPart->setPreamble("This is a multi-part message in MIME format.\n"); 1004 bodyPart->setPreamble("This is a multi-part message in MIME format.\n");
1005 bodyPart->addContent(createBodyPart(body.toUtf8(), htmlBody)); 1005 bodyPart->addContent(createBodyPart(body.toUtf8(), htmlBody));
1006 for (const auto &attachment : attachments) { 1006 for (const auto &attachment : attachments) {
1007 bodyPart->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name)); 1007 bodyPart->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name));
1008 }
1009 return bodyPart;
1010 } else {
1011 return createBodyPart(body.toUtf8(), htmlBody);
1008 } 1012 }
1009 } else { 1013 }()};
1010 bodyPart = createBodyPart(body.toUtf8(), htmlBody);
1011 }
1012 bodyPart->assemble(); 1014 bodyPart->assemble();
1013 1015
1014 KMime::Content *signedResult = nullptr; 1016 QByteArray bodyData;
1015 if (!signingKeys.empty()) { 1017 if (!signingKeys.empty() || !encryptionKeys.empty()) {
1016 signedResult = MailCrypto::sign(bodyPart, signingKeys); 1018 auto result = MailCrypto::processCrypto(bodyPart.get(), signingKeys, encryptionKeys, MailCrypto::OPENPGP);
1017 if (!signedResult) { 1019 if (!result) {
1018 qWarning() << "Signing failed"; 1020 qWarning() << "Signing failed";
1019 return {}; 1021 return {};
1020 } 1022 }
1023 bodyData = result->encodedContent();
1021 } else { 1024 } else {
1022 if (!bodyPart->contentType(false)) { 1025 if (!bodyPart->contentType(false)) {
1023 bodyPart->contentType(true)->setMimeType("text/plain"); 1026 bodyPart->contentType(true)->setMimeType("text/plain");
1024 bodyPart->assemble(); 1027 bodyPart->assemble();
1025 } 1028 }
1029 bodyData = bodyPart->encodedContent();
1026 } 1030 }
1027 1031
1028 const QByteArray allData = mail->head() + (signedResult ? signedResult->encodedContent() : bodyPart->encodedContent());
1029 delete bodyPart;
1030 KMime::Message::Ptr resultMessage(new KMime::Message); 1032 KMime::Message::Ptr resultMessage(new KMime::Message);
1031 resultMessage->setContent(allData); 1033 resultMessage->setContent(mail->head() + bodyData);
1032 resultMessage->parse(); // Not strictly necessary. 1034 resultMessage->parse(); // Not strictly necessary.
1033
1034 return resultMessage; 1035 return resultMessage;
1035} 1036}
diff --git a/framework/src/domain/mime/mailtemplates.h b/framework/src/domain/mime/mailtemplates.h
index 51db2ba0..21efb5a0 100644
--- a/framework/src/domain/mime/mailtemplates.h
+++ b/framework/src/domain/mime/mailtemplates.h
@@ -37,5 +37,5 @@ namespace MailTemplates
37 void reply(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback, const KMime::Types::AddrSpecList &me = {}); 37 void reply(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback, const KMime::Types::AddrSpecList &me = {});
38 QString plaintextContent(const KMime::Message::Ptr &origMsg); 38 QString plaintextContent(const KMime::Message::Ptr &origMsg);
39 QString body(const KMime::Message::Ptr &msg, bool &isHtml); 39 QString body(const KMime::Message::Ptr &msg, bool &isHtml);
40 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 = {}); 40 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 = {});
41}; 41};