Backport fix google translator
[kdepim.git] / kleopatra / crypto / certificateresolver.cpp
blob1157637e30a97d1b1eff02b7db0e8d75272dfd91
1 /* -*- mode: c++; c-basic-offset:4 -*-
2 crypto/certificateresolver.cpp
4 This file is part of Kleopatra, the KDE keymanager
5 Copyright (c) 2007 Klarälvdalens Datakonsult AB
7 Kleopatra is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 Kleopatra is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 In addition, as a special exception, the copyright holders give
22 permission to link the code of this program with any edition of
23 the Qt library by Trolltech AS, Norway (or with modified versions
24 of Qt that use the same license as Qt), and distribute linked
25 combinations including the two. You must obey the GNU General
26 Public License in all respects for all of the code used other than
27 Qt. If you modify this file, you may extend this exception to
28 your version of the file, but you are not obligated to do so. If
29 you do not wish to do so, delete this exception statement from
30 your version.
33 #include <config-kleopatra.h>
35 #include "certificateresolver.h"
37 #include <models/keycache.h>
39 #include <gpgme++/key.h>
41 #include <KConfig>
42 #include <KConfigGroup>
43 #include <QRegularExpression>
45 #include <QByteArray>
46 #include <QHash>
47 #include <QSet>
49 #include <boost/bind.hpp>
51 #include <algorithm>
52 #include <iterator>
54 using namespace Kleo;
55 using namespace Kleo::Crypto;
56 using namespace boost;
57 using namespace GpgME;
58 using namespace KMime::Types;
59 using namespace KMime::HeaderParsing;
61 std::vector< std::vector<Key> > CertificateResolver::resolveRecipients(const std::vector<Mailbox> &recipients, Protocol proto)
63 std::vector< std::vector<Key> > result;
64 std::transform(recipients.begin(), recipients.end(),
65 std::back_inserter(result), boost::bind(&resolveRecipient, _1, proto));
66 return result;
69 std::vector<Key> CertificateResolver::resolveRecipient(const Mailbox &recipient, Protocol proto)
71 std::vector<Key> result = KeyCache::instance()->findByEMailAddress(recipient.address());
72 std::vector<Key>::iterator end = std::remove_if(result.begin(), result.end(),
73 !boost::bind(&Key::canEncrypt, _1));
75 if (proto != UnknownProtocol)
76 end = std::remove_if(result.begin(), end,
77 boost::bind(&Key::protocol, _1) != proto);
79 result.erase(end, result.end());
80 return result;
83 std::vector< std::vector<Key> > CertificateResolver::resolveSigners(const std::vector<Mailbox> &signers, Protocol proto)
85 std::vector< std::vector<Key> > result;
86 std::transform(signers.begin(), signers.end(),
87 std::back_inserter(result), boost::bind(&resolveSigner, _1, proto));
88 return result;
91 std::vector<Key> CertificateResolver::resolveSigner(const Mailbox &signer, Protocol proto)
93 std::vector<Key> result = KeyCache::instance()->findByEMailAddress(signer.address());
94 std::vector<Key>::iterator end
95 = std::remove_if(result.begin(), result.end(),
96 !boost::bind(&Key::hasSecret, _1));
97 end = std::remove_if(result.begin(), end,
98 !boost::bind(&Key::canReallySign, _1));
99 if (proto != UnknownProtocol)
100 end = std::remove_if(result.begin(), end,
101 boost::bind(&Key::protocol, _1) != proto);
102 result.erase(end, result.end());
103 return result;
106 class KConfigBasedRecipientPreferences::Private
108 friend class ::Kleo::Crypto::KConfigBasedRecipientPreferences;
109 KConfigBasedRecipientPreferences *const q;
110 public:
111 explicit Private(const KSharedConfigPtr &config, KConfigBasedRecipientPreferences *qq);
112 ~Private();
114 private:
115 void ensurePrefsParsed() const;
116 void writePrefs();
118 private:
119 KSharedConfigPtr m_config;
121 mutable QHash<QByteArray, QByteArray> pgpPrefs;
122 mutable QHash<QByteArray, QByteArray> cmsPrefs;
123 mutable bool m_parsed;
124 mutable bool m_dirty;
127 KConfigBasedRecipientPreferences::Private::Private(const KSharedConfigPtr &config, KConfigBasedRecipientPreferences *qq) : q(qq), m_config(config), m_parsed(false), m_dirty(false)
129 assert(m_config);
132 KConfigBasedRecipientPreferences::Private::~Private()
134 writePrefs();
137 void KConfigBasedRecipientPreferences::Private::writePrefs()
139 if (!m_dirty) {
140 return;
142 const QSet<QByteArray> keys = pgpPrefs.keys().toSet() + cmsPrefs.keys().toSet();
144 int n = 0;
145 Q_FOREACH (const QByteArray &i, keys) {
146 KConfigGroup group(m_config, QStringLiteral("EncryptionPreference_%1").arg(n++));
147 group.writeEntry("email", i);
148 const QByteArray pgp = pgpPrefs.value(i);
149 if (!pgp.isEmpty()) {
150 group.writeEntry("pgpCertificate", pgp);
152 const QByteArray cms = cmsPrefs.value(i);
153 if (!cms.isEmpty()) {
154 group.writeEntry("cmsCertificate", cms);
157 m_config->sync();
158 m_dirty = false;
160 void KConfigBasedRecipientPreferences::Private::ensurePrefsParsed() const
162 if (m_parsed) {
163 return;
165 const QStringList groups = m_config->groupList().filter(QRegularExpression(QStringLiteral("^EncryptionPreference_\\d+$")));
167 Q_FOREACH (const QString &i, groups) {
168 const KConfigGroup group(m_config, i);
169 const QByteArray id = group.readEntry("email", QByteArray());
170 if (id.isEmpty()) {
171 continue;
173 pgpPrefs.insert(id, group.readEntry("pgpCertificate", QByteArray()));
174 cmsPrefs.insert(id, group.readEntry("cmsCertificate", QByteArray()));
176 m_parsed = true;
179 KConfigBasedRecipientPreferences::KConfigBasedRecipientPreferences(const KSharedConfigPtr &config) : d(new Private(config, this))
183 KConfigBasedRecipientPreferences::~KConfigBasedRecipientPreferences()
185 d->writePrefs();
188 Key KConfigBasedRecipientPreferences::preferredCertificate(const Mailbox &recipient, Protocol protocol)
190 d->ensurePrefsParsed();
192 const QByteArray keyId = (protocol == CMS ? d->cmsPrefs : d->pgpPrefs).value(recipient.address());
193 return KeyCache::instance()->findByKeyIDOrFingerprint(keyId);
196 void KConfigBasedRecipientPreferences::setPreferredCertificate(const Mailbox &recipient, Protocol protocol, const Key &certificate)
198 d->ensurePrefsParsed();
199 if (!recipient.hasAddress()) {
200 return;
202 (protocol == CMS ? d->cmsPrefs : d->pgpPrefs).insert(recipient.address(), certificate.keyID());
203 d->m_dirty = true;
206 class KConfigBasedSigningPreferences::Private
208 friend class ::Kleo::Crypto::KConfigBasedSigningPreferences;
209 KConfigBasedSigningPreferences *const q;
210 public:
211 explicit Private(const KSharedConfigPtr &config, KConfigBasedSigningPreferences *qq);
212 ~Private();
214 private:
215 void ensurePrefsParsed() const;
216 void writePrefs();
218 private:
219 KSharedConfigPtr m_config;
221 mutable QByteArray pgpSigningCertificate;
222 mutable QByteArray cmsSigningCertificate;
223 mutable bool m_parsed;
224 mutable bool m_dirty;
227 KConfigBasedSigningPreferences::Private::Private(const KSharedConfigPtr &config, KConfigBasedSigningPreferences *qq) : q(qq), m_config(config), m_parsed(false), m_dirty(false)
229 assert(m_config);
232 void KConfigBasedSigningPreferences::Private::ensurePrefsParsed() const
234 if (m_parsed) {
235 return;
237 const KConfigGroup group(m_config, "SigningPreferences");
238 pgpSigningCertificate = group.readEntry("pgpSigningCertificate", QByteArray());
239 cmsSigningCertificate = group.readEntry("cmsSigningCertificate", QByteArray());
240 m_parsed = true;
243 void KConfigBasedSigningPreferences::Private::writePrefs()
245 if (!m_dirty) {
246 return;
248 KConfigGroup group(m_config, "SigningPreferences");
249 group.writeEntry("pgpSigningCertificate", pgpSigningCertificate);
250 group.writeEntry("cmsSigningCertificate", cmsSigningCertificate);
251 m_config->sync();
252 m_dirty = false;
255 KConfigBasedSigningPreferences::Private::~Private()
257 writePrefs();
260 KConfigBasedSigningPreferences::KConfigBasedSigningPreferences(const KSharedConfigPtr &config) : d(new Private(config, this))
264 KConfigBasedSigningPreferences::~KConfigBasedSigningPreferences()
266 d->writePrefs();
269 Key KConfigBasedSigningPreferences::preferredCertificate(Protocol protocol)
271 d->ensurePrefsParsed();
273 const QByteArray keyId = (protocol == CMS ? d->cmsSigningCertificate : d->pgpSigningCertificate);
274 const Key key = KeyCache::instance()->findByKeyIDOrFingerprint(keyId);
275 return key.hasSecret() ? key : Key::null;
278 void KConfigBasedSigningPreferences::setPreferredCertificate(Protocol protocol, const Key &certificate)
280 d->ensurePrefsParsed();
281 (protocol == CMS ? d->cmsSigningCertificate : d->pgpSigningCertificate) = certificate.keyID();
282 d->m_dirty = true;