Backport r950340 | aacid | 2009-04-06 23:21:18 +0200 (Mon, 06 Apr 2009) | 4 lines
[kdepim.git] / kmail / keyresolver.h
blobd6283138d3d9d75d91ed097daf0d72619af182b4
1 /* -*- c++ -*-
2 keyresolver.h
4 This file is part of libkleopatra, the KDE keymanagement library
5 Copyright (c) 2004 Klarälvdalens Datakonsult AB
7 Based on kpgp.h
8 Copyright (C) 2001,2002 the KPGP authors
9 See file libkdenetwork/AUTHORS.kpgp for details
11 Libkleopatra is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
16 Libkleopatra is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 In addition, as a special exception, the copyright holders give
26 permission to link the code of this program with any edition of
27 the Qt library by Trolltech AS, Norway (or with modified versions
28 of Qt that use the same license as Qt), and distribute linked
29 combinations including the two. You must obey the GNU General
30 Public License in all respects for all of the code used other than
31 Qt. If you modify this file, you may extend this exception to
32 your version of the file, but you are not obligated to do so. If
33 you do not wish to do so, delete this exception statement from
34 your version.
37 #ifndef __KLEO_KEYRESOLVER_H__
38 #define __KLEO_KEYRESOLVER_H__
40 #include "libkleo/ui/keyapprovaldialog.h"
41 #include "kleo/enum.h"
43 #include <libkpgp/kpgp.h> // for Kpgp::Result
44 #include <gpgme++/key.h>
46 #include <vector>
48 class QStringList;
50 namespace Kleo {
53 /**
54 \short A class to resolve signing/encryption keys w.r.t. per-recipient preferences
56 \section Step 1: Set the information needed
58 The constructor takes some basic options as arguments, such as
59 whether or not encryption was actually requested. Recipient and
60 sender information is then set by using \c
61 setEncryptToSelfKeys(), \c setSigningKeys(), \c
62 setPrimaryRecipients() (To/Cc) and \c setSecondaryRecipients()
63 (Bcc).
65 \section Step 2: Lookup and check per-recipient crypto preferences / Opportunistic Encryption
67 First, \c checkSigningPreferences() goes through all recipient's
68 signing perferences, to determine whether or not to sign. It also
69 takes into account the available signing keys and whether or not
70 the user explicitly requested signing.
72 \c checkEncryptionPreferences() does the same for encryption
73 preferences. If opportunistic encryption is enabled, recipients
74 without encryption preferences set are treated as if they had a
75 preference of \c AskWheneverPossible.
77 In both cases an Action code is returned, with the following
78 meanings:
80 <dl><dt>Conflict</dt><dd>A conflict was detected. E.g. one
81 recipient's preference was set to "always encrypt", while another
82 one's preference was set to "never encrypt". You should ask the
83 user what to do.</dd></dt>
85 <dt>DoIt, DontDoIt</dt><dd>Do/Don't sign/encrypt</dd>
87 <dt>Ask</dt><dd>(Some) crypto preferences request to prompt the
88 user, so do it.</dd>
90 <dt>Impossible</dt><dd>Signing or encryption is impossible,
91 e.g. due to missing keys or unsupported formats.</dd> </dl>
93 \section Step 3: Resolve all keys.
95 In case signing or encryption was implicitly or explicitly
96 requested by the user, \c resolveAllKeys() tries to find signing
97 keys for each required format, as well as encryption keys for all
98 recipients (incl. the sender, if encrypt-to-self is set).
100 \section Step 4: Get signing keys.
102 If, after key resolving, signing is still requested and
103 apparently possible, you can get the result of all this by
104 iterating over the available message formats and retrieving the
105 set of signing keys to use with a call to \c signingKeys().
107 \section Step 5: Get encrytion key sets.
109 If after key resolving, encryption is still requested and
110 apparently possible, you can get the result of all this by
111 calling \c encryptionItems() with the current message format at
112 hand as its argument.
114 This will return a list of recipient-list/key-list pairs that
115 each describe a copy of the (possibly signed) message to be
116 encrypted independantly.
118 Note that it's only necessary to sign the message once for each
119 message format, although it might be necessary to create more
120 than one message when encrypting. This is because encryption
121 allows the recipients to learn about the other recipients the
122 message was encrypted to, so each secondary (BCC) recipient need
123 a copy of it's own to hide the other secondary recipients.
126 class KeyResolver {
127 public:
128 KeyResolver( bool encToSelf, bool showApproval, bool oppEncryption,
129 unsigned int format,
130 int encrKeyNearExpiryThresholdDays,
131 int signKeyNearExpiryThresholdDays,
132 int encrRootCertNearExpiryThresholdDays,
133 int signRootCertNearExpiryThresholdDays,
134 int encrChainCertNearExpiryThresholdDays,
135 int signChainCertNearExpiryThresholdDays );
137 ~KeyResolver();
139 struct Item : public KeyApprovalDialog::Item {
140 Item()
141 : KeyApprovalDialog::Item(),
142 signPref( UnknownSigningPreference ),
143 format( AutoFormat ),
144 needKeys( true ) {}
145 Item( const QString & a,
146 EncryptionPreference e, SigningPreference s,
147 CryptoMessageFormat f )
148 : KeyApprovalDialog::Item( a, std::vector<GpgME::Key>(), e ),
149 signPref( s ), format( f ), needKeys( true ) {}
150 Item( const QString & a, const std::vector<GpgME::Key> & k,
151 EncryptionPreference e, SigningPreference s,
152 CryptoMessageFormat f )
153 : KeyApprovalDialog::Item( a, k, e ),
154 signPref( s ), format( f ), needKeys( false ) {}
156 SigningPreference signPref;
157 CryptoMessageFormat format;
158 bool needKeys;
163 Set the fingerprints of keys to be used for encrypting to
164 self. Also looks them up and complains if they're not usable or
165 found.
167 Kpgp::Result setEncryptToSelfKeys( const QStringList & fingerprints );
169 Set the fingerprints of keys to be used for signing. Also
170 looks them up and complains if they're not usable or found.
172 Kpgp::Result setSigningKeys( const QStringList & fingerprints );
174 Set the list of primary (To/CC) recipient addresses. Also looks
175 up possible keys, but doesn't interact with the user.
177 void setPrimaryRecipients( const QStringList & addresses );
179 Set the list of secondary (BCC) recipient addresses. Also looks
180 up possible keys, but doesn't interact with the user.
182 void setSecondaryRecipients( const QStringList & addresses );
186 Determine whether to sign or not, depending on the
187 per-recipient signing preferences, as well as the availability
188 of usable signing keys.
190 Action checkSigningPreferences( bool signingRequested ) const;
192 Determine whether to encrypt or not, depending on the
193 per-recipient encryption preferences, as well as the availability
194 of usable encryption keys.
196 Action checkEncryptionPreferences( bool encryptionRequested ) const;
199 Queries the user for missing keys and displays a key approval
200 dialog if needed.
202 Kpgp::Result resolveAllKeys( bool& signingRequested, bool& encryptionRequested );
205 @return the signing keys to use (if any) for the given message
206 format.
208 std::vector<GpgME::Key> signingKeys( CryptoMessageFormat f ) const;
210 struct SplitInfo {
211 SplitInfo() {}
212 SplitInfo( const QStringList & r ) : recipients( r ) {}
213 SplitInfo( const QStringList & r, const std::vector<GpgME::Key> & k )
214 : recipients( r ), keys( k ) {}
215 QStringList recipients;
216 std::vector<GpgME::Key> keys;
218 /** @return the found distinct sets of items for format \a f. The
219 returned vector will contain more than one item only if
220 secondary recipients have been specified.
222 std::vector<SplitInfo> encryptionItems( CryptoMessageFormat f ) const;
224 private:
225 void dump() const;
226 std::vector<Item> getEncryptionItems( const QStringList & recipients );
227 std::vector<GpgME::Key> getEncryptionKeys( const QString & recipient, bool quiet ) const;
229 Kpgp::Result showKeyApprovalDialog();
231 bool encryptionPossible() const;
232 bool signingPossible() const;
233 Kpgp::Result resolveEncryptionKeys( bool signingRequested );
234 Kpgp::Result resolveSigningKeysForEncryption();
235 Kpgp::Result resolveSigningKeysForSigningOnly();
236 Kpgp::Result checkKeyNearExpiry( const GpgME::Key & key,
237 const char * dontAskAgainName, bool mine,
238 bool sign, bool ca=false, int recurse_limit=100,
239 const GpgME::Key & orig_key=GpgME::Key::null ) const;
240 void collapseAllSplitInfos();
241 void addToAllSplitInfos( const std::vector<GpgME::Key> & keys, unsigned int formats );
242 void addKeys( const std::vector<Item> & items, CryptoMessageFormat f );
243 void addKeys( const std::vector<Item> & items );
244 QStringList allRecipients() const;
245 std::vector<GpgME::Key> signingKeysFor( CryptoMessageFormat f ) const;
246 std::vector<GpgME::Key> encryptToSelfKeysFor( CryptoMessageFormat f ) const;
248 std::vector<GpgME::Key> lookup( const QStringList & patterns, bool secret=false ) const;
250 bool haveTrustedEncryptionKey( const QString & person ) const;
252 std::vector<GpgME::Key> selectKeys( const QString & person, const QString & msg,
253 const std::vector<GpgME::Key> & selectedKeys=std::vector<GpgME::Key>() ) const;
255 QStringList keysForAddress( const QString & address ) const;
256 void setKeysForAddress( const QString & address, const QStringList& pgpKeyFingerprints, const QStringList& smimeCertFingerprints ) const;
258 bool encryptToSelf() const { return mEncryptToSelf; }
259 bool showApprovalDialog() const { return mShowApprovalDialog; }
261 int encryptKeyNearExpiryWarningThresholdInDays() const {
262 return mEncryptKeyNearExpiryWarningThreshold;
264 int signingKeyNearExpiryWarningThresholdInDays() const {
265 return mSigningKeyNearExpiryWarningThreshold;
268 int encryptRootCertNearExpiryWarningThresholdInDays() const {
269 return mEncryptRootCertNearExpiryWarningThreshold;
271 int signingRootCertNearExpiryWarningThresholdInDays() const {
272 return mSigningRootCertNearExpiryWarningThreshold;
275 int encryptChainCertNearExpiryWarningThresholdInDays() const {
276 return mEncryptChainCertNearExpiryWarningThreshold;
278 int signingChainCertNearExpiryWarningThresholdInDays() const {
279 return mSigningChainCertNearExpiryWarningThreshold;
282 struct ContactPreferences {
283 ContactPreferences();
284 Kleo::EncryptionPreference encryptionPreference;
285 Kleo::SigningPreference signingPreference;
286 Kleo::CryptoMessageFormat cryptoMessageFormat;
287 QStringList pgpKeyFingerprints;
288 QStringList smimeCertFingerprints;
291 ContactPreferences lookupContactPreferences( const QString& address ) const;
292 void saveContactPreference( const QString& email, const ContactPreferences& pref ) const;
294 private:
295 class EncryptionPreferenceCounter;
296 friend class ::Kleo::KeyResolver::EncryptionPreferenceCounter;
297 class SigningPreferenceCounter;
298 friend class ::Kleo::KeyResolver::SigningPreferenceCounter;
300 struct Private;
301 Private * d;
303 bool mEncryptToSelf;
304 const bool mShowApprovalDialog : 1;
305 const bool mOpportunisticEncyption : 1;
306 const unsigned int mCryptoMessageFormats;
308 const int mEncryptKeyNearExpiryWarningThreshold;
309 const int mSigningKeyNearExpiryWarningThreshold;
310 const int mEncryptRootCertNearExpiryWarningThreshold;
311 const int mSigningRootCertNearExpiryWarningThreshold;
312 const int mEncryptChainCertNearExpiryWarningThreshold;
313 const int mSigningChainCertNearExpiryWarningThreshold;
316 } // namespace Kleo
318 #endif // __KLEO_KEYRESOLVER_H__