41 #include "keyresolver.h"
43 #include "kcursorsaver.h"
44 #include "kleo_util.h"
47 #include <libemailfunctions/email.h>
48 #include <ui/keyselectiondialog.h>
49 #include <kleo/cryptobackendfactory.h>
50 #include <kleo/keylistjob.h>
53 #include <gpgmepp/key.h>
54 #include <gpgmepp/keylistresult.h>
56 #include <tdeabc/stdaddressbook.h>
57 #include <tdelocale.h>
59 #include <kinputdialog.h>
60 #include <tdemessagebox.h>
62 #include <tqstringlist.h>
81 static inline bool EmptyKeyList(
const Kleo::KeyApprovalDialog::Item & item ) {
82 return item.keys.empty();
85 static inline TQString ItemDotAddress(
const Kleo::KeyResolver::Item & item ) {
89 static inline bool ApprovalNeeded(
const Kleo::KeyResolver::Item & item ) {
90 return item.pref == Kleo::UnknownPreference || item.pref == Kleo::NeverEncrypt || item.keys.empty() ;
93 static inline Kleo::KeyResolver::Item
94 CopyKeysAndEncryptionPreferences(
const Kleo::KeyResolver::Item & oldItem,
95 const Kleo::KeyApprovalDialog::Item & newItem ) {
96 return Kleo::KeyResolver::Item( oldItem.address, newItem.keys, newItem.pref, oldItem.signPref, oldItem.format );
99 static inline bool ByKeyID(
const GpgME::Key & left,
const GpgME::Key & right ) {
100 return qstrcmp( left.keyID(), right.keyID() ) < 0 ;
103 static inline bool WithRespectToKeyID(
const GpgME::Key & left,
const GpgME::Key & right ) {
104 return qstrcmp( left.keyID(), right.keyID() ) == 0 ;
107 static bool ValidOpenPGPEncryptionKey(
const GpgME::Key & key ) {
108 if ( key.protocol() != GpgME::Context::OpenPGP ) {
112 if ( key.isRevoked() )
113 kdWarning() <<
" is revoked" << endl;
114 if ( key.isExpired() )
115 kdWarning() <<
" is expired" << endl;
116 if ( key.isDisabled() )
117 kdWarning() <<
" is disabled" << endl;
118 if ( !key.canEncrypt() )
119 kdWarning() <<
" can't encrypt" << endl;
121 if ( key.isRevoked() || key.isExpired() || key.isDisabled() || !key.canEncrypt() )
126 static bool ValidTrustedOpenPGPEncryptionKey(
const GpgME::Key & key ) {
127 if ( !ValidOpenPGPEncryptionKey( key ) )
129 const std::vector<GpgME::UserID> uids = key.userIDs();
130 for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it ) {
131 if ( !it->isRevoked() && it->validity() >= GpgME::UserID::Marginal )
135 if ( it->isRevoked() )
136 kdWarning() <<
"a userid is revoked" << endl;
138 kdWarning() <<
"bad validity " << it->validity() << endl;
144 static bool ValidSMIMEEncryptionKey(
const GpgME::Key & key ) {
145 if ( key.protocol() != GpgME::Context::CMS )
147 if ( key.isRevoked() || key.isExpired() || key.isDisabled() || !key.canEncrypt() )
152 static bool ValidTrustedSMIMEEncryptionKey(
const GpgME::Key & key ) {
153 if ( !ValidSMIMEEncryptionKey( key ) )
158 static inline bool ValidTrustedEncryptionKey(
const GpgME::Key & key ) {
159 switch ( key.protocol() ) {
160 case GpgME::Context::OpenPGP:
161 return ValidTrustedOpenPGPEncryptionKey( key );
162 case GpgME::Context::CMS:
163 return ValidTrustedSMIMEEncryptionKey( key );
169 static inline bool ValidEncryptionKey(
const GpgME::Key & key ) {
170 switch ( key.protocol() ) {
171 case GpgME::Context::OpenPGP:
172 return ValidOpenPGPEncryptionKey( key );
173 case GpgME::Context::CMS:
174 return ValidSMIMEEncryptionKey( key );
180 static inline bool ValidSigningKey(
const GpgME::Key & key ) {
181 if ( key.isRevoked() || key.isExpired() || key.isDisabled() || !key.canSign() )
183 return key.hasSecret();
186 static inline bool ValidOpenPGPSigningKey(
const GpgME::Key & key ) {
187 return key.protocol() == GpgME::Context::OpenPGP && ValidSigningKey( key );
190 static inline bool ValidSMIMESigningKey(
const GpgME::Key & key ) {
191 return key.protocol() == GpgME::Context::CMS && ValidSigningKey( key );
194 static inline bool NotValidTrustedOpenPGPEncryptionKey(
const GpgME::Key & key ) {
195 return !ValidTrustedOpenPGPEncryptionKey( key );
198 static inline bool NotValidOpenPGPEncryptionKey(
const GpgME::Key & key ) {
199 return !ValidOpenPGPEncryptionKey( key );
202 static inline bool NotValidTrustedSMIMEEncryptionKey(
const GpgME::Key & key ) {
203 return !ValidTrustedSMIMEEncryptionKey( key );
206 static inline bool NotValidSMIMEEncryptionKey(
const GpgME::Key & key ) {
207 return !ValidSMIMEEncryptionKey( key );
210 static inline bool NotValidTrustedEncryptionKey(
const GpgME::Key & key ) {
211 return !ValidTrustedEncryptionKey( key );
214 static inline bool NotValidEncryptionKey(
const GpgME::Key & key ) {
215 return !ValidEncryptionKey( key );
218 static inline bool NotValidSigningKey(
const GpgME::Key & key ) {
219 return !ValidSigningKey( key );
222 static inline bool NotValidOpenPGPSigningKey(
const GpgME::Key & key ) {
223 return !ValidOpenPGPSigningKey( key );
226 static inline bool NotValidSMIMESigningKey(
const GpgME::Key & key ) {
227 return !ValidSMIMESigningKey( key );
231 struct ByTrustScore {
232 static int score(
const GpgME::UserID & uid ) {
233 return uid.isRevoked() || uid.isInvalid() ? -1 : uid.validity() ;
235 bool operator()(
const GpgME::UserID & lhs,
const GpgME::UserID & rhs )
const {
236 return score( lhs ) < score( rhs ) ;
241 static std::vector<GpgME::UserID> matchingUIDs(
const std::vector<GpgME::UserID> & uids,
const TQString & address ) {
242 if ( address.isEmpty() )
243 return std::vector<GpgME::UserID>();
245 std::vector<GpgME::UserID> result;
246 result.reserve( uids.size() );
247 for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin(), end = uids.end() ; it != end ; ++it )
249 if (
const char * email = it->email() )
250 if ( *email && TQString::fromUtf8( email ).stripWhiteSpace().lower() == address )
251 result.push_back( *it );
255 static GpgME::UserID findBestMatchUID(
const GpgME::Key & key,
const TQString & address ) {
256 const std::vector<GpgME::UserID> all = key.userIDs();
258 return GpgME::UserID();
259 const std::vector<GpgME::UserID> matching = matchingUIDs( all, address.lower() );
260 const std::vector<GpgME::UserID> & v = matching.empty() ? all : matching ;
261 return *std::max_element( v.begin(), v.end(), ByTrustScore() );
264 static TQStringList keysAsStrings(
const std::vector<GpgME::Key>& keys ) {
265 TQStringList strings;
266 for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it ) {
267 assert( !(*it).userID(0).isNull() );
268 TQString keyLabel = TQString::fromUtf8( (*it).userID(0).email() );
269 if ( keyLabel.isEmpty() )
270 keyLabel = TQString::fromUtf8( (*it).userID(0).name() );
271 if ( keyLabel.isEmpty() )
272 keyLabel = TQString::fromUtf8( (*it).userID(0).id() );
273 strings.append( keyLabel );
278 static std::vector<GpgME::Key> trustedOrConfirmed(
const std::vector<GpgME::Key> & keys,
const TQString & address,
bool & canceled ) {
281 std::vector<GpgME::Key> fishies;
282 std::vector<GpgME::Key> ickies;
283 std::vector<GpgME::Key> rewookies;
284 std::vector<GpgME::Key>::const_iterator it = keys.begin();
285 const std::vector<GpgME::Key>::const_iterator end = keys.end();
286 for ( ; it != end ; it++ ) {
287 const GpgME::Key & key = *it;
288 assert( ValidEncryptionKey( key ) );
289 const GpgME::UserID uid = findBestMatchUID( key, address );
290 if ( uid.isRevoked() ) {
291 rewookies.push_back( key );
293 if ( !uid.isRevoked() && uid.validity() == GpgME::UserID::Marginal ) {
294 fishies.push_back( key );
296 if ( !uid.isRevoked() && uid.validity() < GpgME::UserID::Never ) {
297 ickies.push_back( key );
301 if ( fishies.empty() && ickies.empty() && rewookies.empty() )
305 TQString msg = address.isEmpty()
306 ? i18n(
"One or more of your configured OpenPGP encryption "
307 "keys or S/MIME certificates is not fully trusted "
309 : i18n(
"One or more of the OpenPGP encryption keys or S/MIME "
310 "certificates for recipient \"%1\" is not fully trusted "
311 "for encryption.").arg(address) ;
313 if ( !fishies.empty() ) {
315 msg += i18n(
"\nThe following keys are only marginally trusted: \n");
316 msg += keysAsStrings( fishies ).join(
",");
318 if ( !ickies.empty() ) {
319 msg += i18n(
"\nThe following keys or certificates have unknown trust level: \n");
320 msg += keysAsStrings( ickies ).join(
",");
322 if ( !rewookies.empty() ) {
323 msg += i18n(
"\nThe following keys or certificates are <b>revoked</b>: \n");
324 msg += keysAsStrings( rewookies ).join(
",");
327 if( KMessageBox::warningContinueCancel( 0, msg, i18n(
"Not Fully Trusted Encryption Keys"),
329 "not fully trusted encryption key warning" )
330 == KMessageBox::Continue )
334 return std::vector<GpgME::Key>();
338 struct IsNotForFormat :
public std::function<bool(GpgME::Key)> {
339 IsNotForFormat( Kleo::CryptoMessageFormat f ) : format( f ) {}
341 bool operator()(
const GpgME::Key & key )
const {
343 ( isOpenPGP( format ) && key.protocol() != GpgME::Context::OpenPGP ) ||
344 ( isSMIME( format ) && key.protocol() != GpgME::Context::CMS );
347 const Kleo::CryptoMessageFormat format;
350 struct IsForFormat : std::function<bool(GpgME::Key)> {
351 explicit IsForFormat( Kleo::CryptoMessageFormat f )
352 : protocol( isOpenPGP( f ) ? GpgME::Context::OpenPGP :
353 isSMIME( f ) ? GpgME::Context::CMS :
354 GpgME::Context::Unknown ) {}
356 bool operator()(
const GpgME::Key & key )
const {
357 return key.protocol() == protocol ;
360 const GpgME::Context::Protocol protocol;
367 class Kleo::KeyResolver::SigningPreferenceCounter :
public std::function<void(Kleo::KeyResolver::Item)> {
369 SigningPreferenceCounter()
371 mUnknownSigningPreference( 0 ),
374 mAlwaysSignIfPossible( 0 ),
375 mAlwaysAskForSigning( 0 ),
376 mAskSigningWheneverPossible( 0 )
380 void operator()(
const Kleo::KeyResolver::Item & item );
381 #define make_int_accessor(x) unsigned int num##x() const { return m##x; }
382 make_int_accessor(UnknownSigningPreference)
383 make_int_accessor(NeverSign)
384 make_int_accessor(AlwaysSign)
385 make_int_accessor(AlwaysSignIfPossible)
386 make_int_accessor(AlwaysAskForSigning)
387 make_int_accessor(AskSigningWheneverPossible)
388 make_int_accessor(Total)
389 #undef make_int_accessor
392 unsigned int mUnknownSigningPreference, mNeverSign, mAlwaysSign,
393 mAlwaysSignIfPossible, mAlwaysAskForSigning, mAskSigningWheneverPossible;
396 void Kleo::KeyResolver::SigningPreferenceCounter::operator()(
const Kleo::KeyResolver::Item & item ) {
397 switch ( item.signPref ) {
398 #define CASE(x) case x: ++m##x; break
399 CASE(UnknownSigningPreference);
402 CASE(AlwaysSignIfPossible);
403 CASE(AlwaysAskForSigning);
404 CASE(AskSigningWheneverPossible);
412 class Kleo::KeyResolver::EncryptionPreferenceCounter :
public std::function<void(Item)> {
415 EncryptionPreferenceCounter(
const Kleo::KeyResolver * kr, EncryptionPreference defaultPreference )
417 mDefaultPreference( defaultPreference ),
421 mUnknownPreference( 0 ),
423 mAlwaysEncryptIfPossible( 0 ),
424 mAlwaysAskForEncryption( 0 ),
425 mAskWheneverPossible( 0 )
429 void operator()( Item & item );
431 template <
typename Container>
432 void process( Container & c ) {
433 *
this = std::for_each( c.begin(), c.end(), *
this );
436 #define make_int_accessor(x) unsigned int num##x() const { return m##x; }
437 make_int_accessor(NoKey)
438 make_int_accessor(NeverEncrypt)
439 make_int_accessor(UnknownPreference)
440 make_int_accessor(AlwaysEncrypt)
441 make_int_accessor(AlwaysEncryptIfPossible)
442 make_int_accessor(AlwaysAskForEncryption)
443 make_int_accessor(AskWheneverPossible)
444 make_int_accessor(Total)
445 #undef make_int_accessor
447 EncryptionPreference mDefaultPreference;
451 unsigned int mNeverEncrypt, mUnknownPreference, mAlwaysEncrypt,
452 mAlwaysEncryptIfPossible, mAlwaysAskForEncryption, mAskWheneverPossible;
455 void Kleo::KeyResolver::EncryptionPreferenceCounter::operator()( Item & item ) {
458 item.keys = _this->getEncryptionKeys( item.address,
true );
459 if ( item.keys.empty() ) {
464 switch ( !item.pref ? mDefaultPreference : item.pref ) {
465 #define CASE(x) case Kleo::x: ++m##x; break
467 CASE(UnknownPreference);
469 CASE(AlwaysEncryptIfPossible);
470 CASE(AlwaysAskForEncryption);
471 CASE(AskWheneverPossible);
479 class FormatPreferenceCounterBase :
public std::function<void(Kleo::KeyResolver::Item)> {
481 FormatPreferenceCounterBase()
491 #define make_int_accessor(x) unsigned int num##x() const { return m##x; }
492 make_int_accessor(Total)
493 make_int_accessor(InlineOpenPGP)
494 make_int_accessor(OpenPGPMIME)
495 make_int_accessor(SMIME)
496 make_int_accessor(SMIMEOpaque)
497 #undef make_int_accessor
499 unsigned int numOf( Kleo::CryptoMessageFormat f )
const {
501 #define CASE(x) case Kleo::x##Format: return m##x
513 unsigned int mInlineOpenPGP, mOpenPGPMIME, mSMIME, mSMIMEOpaque;
516 class EncryptionFormatPreferenceCounter :
public FormatPreferenceCounterBase {
518 EncryptionFormatPreferenceCounter() : FormatPreferenceCounterBase() {}
519 void operator()(
const Kleo::KeyResolver::Item & item );
522 class SigningFormatPreferenceCounter :
public FormatPreferenceCounterBase {
524 SigningFormatPreferenceCounter() : FormatPreferenceCounterBase() {}
525 void operator()(
const Kleo::KeyResolver::Item & item );
528 #define CASE(x) if ( item.format & Kleo::x##Format ) ++m##x;
529 void EncryptionFormatPreferenceCounter::operator()(
const Kleo::KeyResolver::Item & item ) {
530 if ( item.format & (Kleo::InlineOpenPGPFormat|Kleo::OpenPGPMIMEFormat) &&
531 std::find_if( item.keys.begin(), item.keys.end(),
532 ValidTrustedOpenPGPEncryptionKey ) != item.keys.end() ) {
536 if ( item.format & (Kleo::SMIMEFormat|Kleo::SMIMEOpaqueFormat) &&
537 std::find_if( item.keys.begin(), item.keys.end(),
538 ValidTrustedSMIMEEncryptionKey ) != item.keys.end() ) {
545 void SigningFormatPreferenceCounter::operator()(
const Kleo::KeyResolver::Item & item ) {
556 static TQString canonicalAddress(
const TQString & _address ) {
557 const TQString address = KPIM::getEmailAddress( _address );
558 if ( address.find(
'@') == -1 ) {
563 return address +
"@localdomain";
571 std::vector<Kleo::KeyResolver::SplitInfo> splitInfos;
572 std::vector<GpgME::Key> signKeys;
575 struct Kleo::KeyResolver::Private {
576 std::set<TQCString> alreadyWarnedFingerprints;
578 std::vector<GpgME::Key> mOpenPGPSigningKeys;
579 std::vector<GpgME::Key> mSMIMESigningKeys;
581 std::vector<GpgME::Key> mOpenPGPEncryptToSelfKeys;
582 std::vector<GpgME::Key> mSMIMEEncryptToSelfKeys;
584 std::vector<Item> mPrimaryEncryptionKeys;
585 std::vector<Item> mSecondaryEncryptionKeys;
587 std::map<CryptoMessageFormat,FormatInfo> mFormatInfoMap;
590 typedef std::map<TQString, ContactPreferences> ContactPreferencesMap;
591 ContactPreferencesMap mContactPreferencesMap;
595 Kleo::KeyResolver::KeyResolver(
bool encToSelf,
bool showApproval,
bool oppEncryption,
597 int encrWarnThresholdKey,
int signWarnThresholdKey,
598 int encrWarnThresholdRootCert,
int signWarnThresholdRootCert,
599 int encrWarnThresholdChainCert,
int signWarnThresholdChainCert )
600 : mEncryptToSelf( encToSelf ),
601 mShowApprovalDialog( showApproval ),
602 mOpportunisticEncyption( oppEncryption ),
603 mCryptoMessageFormats( f ),
604 mEncryptKeyNearExpiryWarningThreshold( encrWarnThresholdKey ),
605 mSigningKeyNearExpiryWarningThreshold( signWarnThresholdKey ),
606 mEncryptRootCertNearExpiryWarningThreshold( encrWarnThresholdRootCert ),
607 mSigningRootCertNearExpiryWarningThreshold( signWarnThresholdRootCert ),
608 mEncryptChainCertNearExpiryWarningThreshold( encrWarnThresholdChainCert ),
609 mSigningChainCertNearExpiryWarningThreshold( signWarnThresholdChainCert )
614 Kleo::KeyResolver::~KeyResolver() {
618 Kpgp::Result Kleo::KeyResolver::checkKeyNearExpiry(
const GpgME::Key & key,
const char * dontAskAgainName,
619 bool mine,
bool sign,
bool ca,
620 int recur_limit,
const GpgME::Key & orig )
const {
621 if ( recur_limit <= 0 ) {
622 kdDebug() <<
"Kleo::KeyResolver::checkKeyNearExpiry(): key chain too long (>100 certs)" << endl;
625 const GpgME::Subkey subkey = key.subkey(0);
626 if ( d->alreadyWarnedFingerprints.count( subkey.fingerprint() ) )
629 if ( subkey.neverExpires() )
631 static const double secsPerDay = 24 * 60 * 60;
632 const double secsTillExpiry = ::difftime( subkey.expirationTime(), time(0) );
633 if ( secsTillExpiry <= 0 ) {
634 const int daysSinceExpiry = 1 + int( -secsTillExpiry / secsPerDay );
635 kdDebug() <<
"Key 0x" << key.shortKeyID() <<
" expired less than "
636 << daysSinceExpiry <<
" days ago" << endl;
638 key.protocol() == GpgME::Context::OpenPGP
640 ? i18n(
"<p>Your OpenPGP signing key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
641 "<p>expired less than a day ago.</p>",
642 "<p>Your OpenPGP signing key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
643 "<p>expired %n days ago.</p>",
645 : i18n(
"<p>Your OpenPGP encryption key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
646 "<p>expired less than a day ago.</p>",
647 "<p>Your OpenPGP encryption key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
648 "<p>expired %n days ago.</p>",
650 : i18n(
"<p>The OpenPGP key for</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
651 "<p>expired less than a day ago.</p>",
652 "<p>The OpenPGP key for</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
653 "<p>expired %n days ago.</p>",
654 daysSinceExpiry ) ).arg( TQString::fromUtf8( key.userID(0).id() ),
659 ? i18n(
"<p>The root certificate</p><p align=center><b>%3</b></p>"
660 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
661 "<p>expired less than a day ago.</p>",
662 "<p>The root certificate</p><p align=center><b>%3</b></p>"
663 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
664 "<p>expired %n days ago.</p>",
666 : i18n(
"<p>The root certificate</p><p align=center><b>%3</b></p>"
667 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
668 "<p>expired less than a day ago.</p>",
669 "<p>The root certificate</p><p align=center><b>%3</b></p>"
670 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
671 "<p>expired %n days ago.</p>",
673 : i18n(
"<p>The root certificate</p><p align=center><b>%3</b></p>"
674 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
675 "<p>expired less than a day ago.</p>",
676 "<p>The root certificate</p><p align=center><b>%3</b></p>"
677 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
678 "<p>expired %n days ago.</p>",
681 ? i18n(
"<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
682 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
683 "<p>expired less than a day ago.</p>",
684 "<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
685 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
686 "<p>expired %n days ago.</p>",
688 : i18n(
"<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
689 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
690 "<p>expired less than a day ago.</p>",
691 "<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
692 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
693 "<p>expired %n days ago.</p>",
695 : i18n(
"<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
696 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
697 "<p>expired less than a day ago.</p>",
698 "<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
699 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
700 "<p>expired %n days ago.</p>",
701 daysSinceExpiry ) ) ).arg( Kleo::DN( orig.userID(0).id() ).prettyDN(),
703 Kleo::DN( key.userID(0).id() ).prettyDN() )
705 ? i18n(
"<p>Your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
706 "<p>expired less than a day ago.</p>",
707 "<p>Your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
708 "<p>expired %n days ago.</p>",
710 : i18n(
"<p>Your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
711 "<p>expired less than a day ago.</p>",
712 "<p>Your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
713 "<p>expired %n days ago.</p>",
715 : i18n(
"<p>The S/MIME certificate for</p><p align=center><b>%1</b> (serial number %2)</p>"
716 "<p>expired less than a day ago.</p>",
717 "<p>The S/MIME certificate for</p><p align=center><b>%1</b> (serial number %2)</p>"
718 "<p>expired %n days ago.</p>",
719 daysSinceExpiry ) ).arg( Kleo::DN( key.userID(0).id() ).prettyDN(),
720 key.issuerSerial() ) );
721 d->alreadyWarnedFingerprints.insert( subkey.fingerprint() );
722 if ( KMessageBox::warningContinueCancel( 0, msg,
723 key.protocol() == GpgME::Context::OpenPGP
724 ? i18n(
"OpenPGP Key Expired" )
725 : i18n(
"S/MIME Certificate Expired" ),
726 KStdGuiItem::cont(), dontAskAgainName ) == KMessageBox::Cancel )
727 return Kpgp::Canceled;
729 const int daysTillExpiry = 1 + int( secsTillExpiry / secsPerDay );
730 kdDebug() <<
"Key 0x" << key.shortKeyID() <<
" expires in less than "
731 << daysTillExpiry <<
" days" << endl;
732 const int threshold =
736 ? signingRootCertNearExpiryWarningThresholdInDays()
737 : encryptRootCertNearExpiryWarningThresholdInDays() )
739 ? signingChainCertNearExpiryWarningThresholdInDays()
740 : encryptChainCertNearExpiryWarningThresholdInDays() ) )
742 ? signingKeyNearExpiryWarningThresholdInDays()
743 : encryptKeyNearExpiryWarningThresholdInDays() );
744 if ( threshold > -1 && daysTillExpiry <= threshold ) {
746 key.protocol() == GpgME::Context::OpenPGP
748 ? i18n(
"<p>Your OpenPGP signing key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
749 "<p>expires in less than a day.</p>",
750 "<p>Your OpenPGP signing key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
751 "<p>expires in less than %n days.</p>",
753 : i18n(
"<p>Your OpenPGP encryption key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
754 "<p>expires in less than a day.</p>",
755 "<p>Your OpenPGP encryption key</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
756 "<p>expires in less than %n days.</p>",
758 : i18n(
"<p>The OpenPGP key for</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
759 "<p>expires in less than a day.</p>",
760 "<p>The OpenPGP key for</p><p align=center><b>%1</b> (KeyID 0x%2)</p>"
761 "<p>expires in less than %n days.</p>",
762 daysTillExpiry ) ).arg( TQString::fromUtf8( key.userID(0).id() ),
767 ? i18n(
"<p>The root certificate</p><p align=center><b>%3</b></p>"
768 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
769 "<p>expires in less than a day.</p>",
770 "<p>The root certificate</p><p align=center><b>%3</b></p>"
771 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
772 "<p>expires in less than %n days.</p>",
774 : i18n(
"<p>The root certificate</p><p align=center><b>%3</b></p>"
775 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
776 "<p>expires in less than a day.</p>",
777 "<p>The root certificate</p><p align=center><b>%3</b></p>"
778 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
779 "<p>expires in less than %n days.</p>",
781 : i18n(
"<p>The root certificate</p><p align=center><b>%3</b></p>"
782 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
783 "<p>expires in less than a day.</p>",
784 "<p>The root certificate</p><p align=center><b>%3</b></p>"
785 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
786 "<p>expires in less than %n days.</p>",
789 ? i18n(
"<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
790 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
791 "<p>expires in less than a day.</p>",
792 "<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
793 "<p>for your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
794 "<p>expires in less than %n days.</p>",
796 : i18n(
"<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
797 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
798 "<p>expires in less than a day.</p>",
799 "<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
800 "<p>for your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
801 "<p>expires in less than %n days.</p>",
803 : i18n(
"<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
804 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
805 "<p>expires in less than a day.</p>",
806 "<p>The intermediate CA certificate</p><p align=center><b>%3</b></p>"
807 "<p>for S/MIME certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
808 "<p>expires in less than %n days.</p>",
809 daysTillExpiry ) ) ).arg( Kleo::DN( orig.userID(0).id() ).prettyDN(),
811 Kleo::DN( key.userID(0).id() ).prettyDN() )
813 ? i18n(
"<p>Your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
814 "<p>expires in less than a day.</p>",
815 "<p>Your S/MIME signing certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
816 "<p>expires in less than %n days.</p>",
818 : i18n(
"<p>Your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
819 "<p>expires in less than a day.</p>",
820 "<p>Your S/MIME encryption certificate</p><p align=center><b>%1</b> (serial number %2)</p>"
821 "<p>expires in less than %n days.</p>",
823 : i18n(
"<p>The S/MIME certificate for</p><p align=center><b>%1</b> (serial number %2)</p>"
824 "<p>expires in less than a day.</p>",
825 "<p>The S/MIME certificate for</p><p align=center><b>%1</b> (serial number %2)</p>"
826 "<p>expires in less than %n days.</p>",
827 daysTillExpiry ) ).arg( Kleo::DN( key.userID(0).id() ).prettyDN(),
828 key.issuerSerial() ) );
829 d->alreadyWarnedFingerprints.insert( subkey.fingerprint() );
830 if ( KMessageBox::warningContinueCancel( 0, msg,
831 key.protocol() == GpgME::Context::OpenPGP
832 ? i18n(
"OpenPGP Key Expires Soon" )
833 : i18n(
"S/MIME Certificate Expires Soon" ),
834 KStdGuiItem::cont(), dontAskAgainName )
835 == KMessageBox::Cancel )
836 return Kpgp::Canceled;
841 else if (
const char * chain_id = key.chainID() ) {
842 const std::vector<GpgME::Key> issuer = lookup( chain_id,
false );
843 if ( issuer.empty() )
846 return checkKeyNearExpiry( issuer.front(), dontAskAgainName, mine, sign,
847 true, recur_limit-1, ca ? orig : key );
853 if ( !encryptToSelf() )
856 std::vector<GpgME::Key> keys = lookup( fingerprints );
857 std::remove_copy_if( keys.begin(), keys.end(),
858 std::back_inserter( d->mOpenPGPEncryptToSelfKeys ),
859 NotValidTrustedOpenPGPEncryptionKey );
860 std::remove_copy_if( keys.begin(), keys.end(),
861 std::back_inserter( d->mSMIMEEncryptToSelfKeys ),
862 NotValidTrustedSMIMEEncryptionKey );
864 if ( d->mOpenPGPEncryptToSelfKeys.size() + d->mSMIMEEncryptToSelfKeys.size()
867 const TQString msg = i18n(
"One or more of your configured OpenPGP encryption "
868 "keys or S/MIME certificates is not usable for "
869 "encryption. Please reconfigure your encryption keys "
870 "and certificates for this identity in the identity "
871 "configuration dialog.\n"
872 "If you choose to continue, and the keys are needed "
873 "later on, you will be prompted to specify the keys "
875 return KMessageBox::warningContinueCancel( 0, msg, i18n(
"Unusable Encryption Keys"),
877 "unusable own encryption key warning" )
878 == KMessageBox::Continue ? Kpgp::Ok : Kpgp::Canceled ;
883 for ( std::vector<GpgME::Key>::const_iterator it = d->mOpenPGPEncryptToSelfKeys.begin() ; it != d->mOpenPGPEncryptToSelfKeys.end() ; ++it ) {
884 const Kpgp::Result r = checkKeyNearExpiry( *it,
"own encryption key expires soon warning",
890 for ( std::vector<GpgME::Key>::const_iterator it = d->mSMIMEEncryptToSelfKeys.begin() ; it != d->mSMIMEEncryptToSelfKeys.end() ; ++it ) {
891 const Kpgp::Result r = checkKeyNearExpiry( *it,
"own encryption key expires soon warning",
901 std::vector<GpgME::Key> keys = lookup( fingerprints,
true );
902 std::remove_copy_if( keys.begin(), keys.end(),
903 std::back_inserter( d->mOpenPGPSigningKeys ),
904 NotValidOpenPGPSigningKey );
905 std::remove_copy_if( keys.begin(), keys.end(),
906 std::back_inserter( d->mSMIMESigningKeys ),
907 NotValidSMIMESigningKey );
909 if ( d->mOpenPGPSigningKeys.size() + d->mSMIMESigningKeys.size() < keys.size() ) {
911 const TQString msg = i18n(
"One or more of your configured OpenPGP signing keys "
912 "or S/MIME signing certificates is not usable for "
913 "signing. Please reconfigure your signing keys "
914 "and certificates for this identity in the identity "
915 "configuration dialog.\n"
916 "If you choose to continue, and the keys are needed "
917 "later on, you will be prompted to specify the keys "
919 return KMessageBox::warningContinueCancel( 0, msg, i18n(
"Unusable Signing Keys"),
921 "unusable signing key warning" )
922 == KMessageBox::Continue ? Kpgp::Ok : Kpgp::Canceled ;
927 for ( std::vector<GpgME::Key>::const_iterator it = d->mOpenPGPSigningKeys.begin() ; it != d->mOpenPGPSigningKeys.end() ; ++it ) {
928 const Kpgp::Result r = checkKeyNearExpiry( *it,
"signing key expires soon warning",
934 for ( std::vector<GpgME::Key>::const_iterator it = d->mSMIMESigningKeys.begin() ; it != d->mSMIMESigningKeys.end() ; ++it ) {
935 const Kpgp::Result r = checkKeyNearExpiry( *it,
"signing key expires soon warning",
945 d->mPrimaryEncryptionKeys = getEncryptionItems( addresses );
949 d->mSecondaryEncryptionKeys = getEncryptionItems( addresses );
952 std::vector<Kleo::KeyResolver::Item> Kleo::KeyResolver::getEncryptionItems(
const TQStringList & addresses ) {
953 std::vector<Item> items;
954 items.reserve( addresses.size() );
955 for ( TQStringList::const_iterator it = addresses.begin() ; it != addresses.end() ; ++it ) {
956 TQString addr = canonicalAddress( *it ).lower();
957 const ContactPreferences pref = lookupContactPreferences( addr );
959 items.push_back( Item( *it,
960 pref.encryptionPreference,
961 pref.signingPreference,
962 pref.cryptoMessageFormat ) );
967 static Kleo::Action action(
bool doit,
bool ask,
bool dont,
bool requested ) {
968 if ( requested && !dont )
970 if ( doit && !ask && !dont )
972 if ( !doit && ask && !dont )
974 if ( !doit && !ask && dont )
975 return requested ? Kleo::Conflict : Kleo::DontDoIt ;
976 if ( !doit && !ask && !dont )
977 return Kleo::DontDoIt ;
978 return Kleo::Conflict;
983 if ( signingRequested && d->mOpenPGPSigningKeys.empty() && d->mSMIMESigningKeys.empty() )
986 SigningPreferenceCounter count;
987 count = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
989 count = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
992 unsigned int sign = count.numAlwaysSign();
993 unsigned int ask = count.numAlwaysAskForSigning();
994 const unsigned int dontSign = count.numNeverSign();
995 if ( signingPossible() ) {
996 sign += count.numAlwaysSignIfPossible();
997 ask += count.numAskSigningWheneverPossible();
1000 return action( sign, ask, dontSign, signingRequested );
1003 bool Kleo::KeyResolver::signingPossible()
const {
1004 return !d->mOpenPGPSigningKeys.empty() || !d->mSMIMESigningKeys.empty() ;
1009 if ( d->mPrimaryEncryptionKeys.empty() && d->mSecondaryEncryptionKeys.empty() )
1012 if ( encryptionRequested && encryptToSelf() &&
1013 d->mOpenPGPEncryptToSelfKeys.empty() && d->mSMIMEEncryptToSelfKeys.empty() )
1016 if ( !encryptionRequested && !mOpportunisticEncyption ) {
1020 EncryptionPreferenceCounter count( 0, UnknownPreference );
1021 count.process( d->mPrimaryEncryptionKeys );
1022 count.process( d->mSecondaryEncryptionKeys );
1023 if ( !count.numAlwaysEncrypt() &&
1024 !count.numAlwaysAskForEncryption() &&
1025 !count.numAlwaysEncryptIfPossible() &&
1026 !count.numAskWheneverPossible() )
1030 EncryptionPreferenceCounter count(
this, mOpportunisticEncyption ? AskWheneverPossible : UnknownPreference );
1031 count = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1033 count = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1036 unsigned int encrypt = count.numAlwaysEncrypt();
1037 unsigned int ask = count.numAlwaysAskForEncryption();
1038 const unsigned int dontEncrypt = count.numNeverEncrypt() + count.numNoKey();
1039 if ( encryptionPossible() ) {
1040 encrypt += count.numAlwaysEncryptIfPossible();
1041 ask += count.numAskWheneverPossible();
1044 const Action act = action( encrypt, ask, dontEncrypt, encryptionRequested );
1046 std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1047 std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1048 EncryptionPreferenceCounter(
this, UnknownPreference ) ) ).numAlwaysAskForEncryption() )
1051 return AskOpportunistic;
1054 bool Kleo::KeyResolver::encryptionPossible()
const {
1055 return std::find_if( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1056 EmptyKeyList ) == d->mPrimaryEncryptionKeys.end()
1057 && std::find_if( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1058 EmptyKeyList ) == d->mSecondaryEncryptionKeys.end() ;
1062 if ( !encryptionRequested && !signingRequested ) {
1066 d->mFormatInfoMap[OpenPGPMIMEFormat].splitInfos.push_back( SplitInfo( allRecipients() ) );
1070 Kpgp::Result result = Kpgp::Ok;
1071 if ( encryptionRequested )
1072 result = resolveEncryptionKeys( signingRequested );
1073 if ( result != Kpgp::Ok )
1075 if ( signingRequested ) {
1076 if ( encryptionRequested ) {
1077 result = resolveSigningKeysForEncryption();
1080 result = resolveSigningKeysForSigningOnly();
1081 if ( result == Kpgp::Failure ) {
1082 signingRequested =
false;
1090 Kpgp::Result Kleo::KeyResolver::resolveEncryptionKeys(
bool signingRequested ) {
1095 for ( std::vector<Item>::iterator it = d->mPrimaryEncryptionKeys.begin() ; it != d->mPrimaryEncryptionKeys.end() ; ++it ) {
1096 if ( !it->needKeys )
1098 it->keys = getEncryptionKeys( it->address,
false );
1099 if ( it->keys.empty() )
1100 return Kpgp::Canceled;
1101 TQString addr = canonicalAddress( it->address ).lower();
1102 const ContactPreferences pref = lookupContactPreferences( addr );
1103 it->pref = pref.encryptionPreference;
1104 it->signPref = pref.signingPreference;
1105 it->format = pref.cryptoMessageFormat;
1108 for ( std::vector<Item>::iterator it = d->mSecondaryEncryptionKeys.begin() ; it != d->mSecondaryEncryptionKeys.end() ; ++it ) {
1109 if ( !it->needKeys )
1111 it->keys = getEncryptionKeys( it->address,
false );
1112 if ( it->keys.empty() )
1113 return Kpgp::Canceled;
1114 TQString addr = canonicalAddress( it->address ).lower();
1115 const ContactPreferences pref = lookupContactPreferences( addr );
1116 it->pref = pref.encryptionPreference;
1117 it->signPref = pref.signingPreference;
1118 it->format = pref.cryptoMessageFormat;
1123 const Kpgp::Result res = showKeyApprovalDialog();
1124 if ( res != Kpgp::Ok )
1134 const EncryptionFormatPreferenceCounter primaryCount
1135 = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1136 EncryptionFormatPreferenceCounter() );
1138 CryptoMessageFormat commonFormat = AutoFormat;
1139 for (
unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
1140 if ( !( concreteCryptoMessageFormats[i] & mCryptoMessageFormats ) )
1142 if ( signingRequested && signingKeysFor( concreteCryptoMessageFormats[i] ).empty() )
1144 if ( encryptToSelf() && encryptToSelfKeysFor( concreteCryptoMessageFormats[i] ).empty() )
1146 if ( primaryCount.numOf( concreteCryptoMessageFormats[i] ) == primaryCount.numTotal() ) {
1147 commonFormat = concreteCryptoMessageFormats[i];
1151 if ( commonFormat != AutoFormat )
1152 addKeys( d->mPrimaryEncryptionKeys, commonFormat );
1154 addKeys( d->mPrimaryEncryptionKeys );
1156 collapseAllSplitInfos();
1161 const EncryptionFormatPreferenceCounter secondaryCount
1162 = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1163 EncryptionFormatPreferenceCounter() );
1165 if ( commonFormat != AutoFormat &&
1166 secondaryCount.numOf( commonFormat ) == secondaryCount.numTotal() )
1167 addKeys( d->mSecondaryEncryptionKeys, commonFormat );
1169 addKeys( d->mSecondaryEncryptionKeys );
1173 for (
unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
1174 const std::vector<SplitInfo> si_list = encryptionItems( concreteCryptoMessageFormats[i] );
1175 for ( std::vector<SplitInfo>::const_iterator sit = si_list.begin() ; sit != si_list.end() ; ++sit )
1176 for ( std::vector<GpgME::Key>::const_iterator kit = sit->keys.begin() ; kit != sit->keys.end() ; ++kit ) {
1177 const Kpgp::Result r = checkKeyNearExpiry( *kit,
"other encryption key near expiry warning",
1179 if ( r != Kpgp::Ok )
1186 if ( !encryptToSelf() )
1191 if ( !encryptionItems( InlineOpenPGPFormat ).empty() ||
1192 !encryptionItems( OpenPGPMIMEFormat ).empty() ) {
1194 if ( d->mOpenPGPEncryptToSelfKeys.empty() ) {
1195 const TQString msg = i18n(
"Examination of recipient's encryption preferences "
1196 "yielded that the message should be encrypted using "
1197 "OpenPGP, at least for some recipients;\n"
1198 "however, you have not configured valid trusted "
1199 "OpenPGP encryption keys for this identity.\n"
1200 "You may continue without encrypting to yourself, "
1201 "but be aware that you will not be able to read your "
1202 "own messages if you do so.");
1203 if ( KMessageBox::warningContinueCancel( 0, msg,
1204 i18n(
"Unusable Encryption Keys"),
1205 KStdGuiItem::cont(),
1206 "encrypt-to-self will fail warning" )
1207 == KMessageBox::Cancel )
1208 return Kpgp::Canceled;
1211 addToAllSplitInfos( d->mOpenPGPEncryptToSelfKeys,
1212 InlineOpenPGPFormat|OpenPGPMIMEFormat );
1217 if ( !encryptionItems( SMIMEFormat ).empty() ||
1218 !encryptionItems( SMIMEOpaqueFormat ).empty() ) {
1220 if ( d->mSMIMEEncryptToSelfKeys.empty() ) {
1222 const TQString msg = i18n(
"Examination of recipient's encryption preferences "
1223 "yielded that the message should be encrypted using "
1224 "S/MIME, at least for some recipients;\n"
1225 "however, you have not configured valid "
1226 "S/MIME encryption certificates for this identity.\n"
1227 "You may continue without encrypting to yourself, "
1228 "but be aware that you will not be able to read your "
1229 "own messages if you do so.");
1230 if ( KMessageBox::warningContinueCancel( 0, msg,
1231 i18n(
"Unusable Encryption Keys"),
1232 KStdGuiItem::cont(),
1233 "encrypt-to-self will fail warning" )
1234 == KMessageBox::Cancel )
1235 return Kpgp::Canceled;
1238 addToAllSplitInfos( d->mSMIMEEncryptToSelfKeys,
1239 SMIMEFormat|SMIMEOpaqueFormat );
1248 Kpgp::Result Kleo::KeyResolver::resolveSigningKeysForEncryption() {
1249 if ( ( !encryptionItems( InlineOpenPGPFormat ).empty() ||
1250 !encryptionItems( OpenPGPMIMEFormat ).empty() )
1251 && d->mOpenPGPSigningKeys.empty() ) {
1252 const TQString msg = i18n(
"Examination of recipient's signing preferences "
1253 "yielded that the message should be signed using "
1254 "OpenPGP, at least for some recipients;\n"
1255 "however, you have not configured valid "
1256 "OpenPGP signing certificates for this identity.");
1257 if ( KMessageBox::warningContinueCancel( 0, msg,
1258 i18n(
"Unusable Signing Keys"),
1259 i18n(
"Do Not OpenPGP-Sign"),
1260 "signing will fail warning" )
1261 == KMessageBox::Cancel )
1262 return Kpgp::Canceled;
1265 if ( ( !encryptionItems( SMIMEFormat ).empty() ||
1266 !encryptionItems( SMIMEOpaqueFormat ).empty() )
1267 && d->mSMIMESigningKeys.empty() ) {
1268 const TQString msg = i18n(
"Examination of recipient's signing preferences "
1269 "yielded that the message should be signed using "
1270 "S/MIME, at least for some recipients;\n"
1271 "however, you have not configured valid "
1272 "S/MIME signing certificates for this identity.");
1273 if ( KMessageBox::warningContinueCancel( 0, msg,
1274 i18n(
"Unusable Signing Keys"),
1275 i18n(
"Do Not S/MIME-Sign"),
1276 "signing will fail warning" )
1277 == KMessageBox::Cancel )
1278 return Kpgp::Canceled;
1285 for ( std::map<CryptoMessageFormat,FormatInfo>::iterator it = d->mFormatInfoMap.begin() ; it != d->mFormatInfoMap.end() ; ++it )
1286 if ( !it->second.splitInfos.empty() ) {
1288 it->second.signKeys = signingKeysFor( it->first );
1295 Kpgp::Result Kleo::KeyResolver::resolveSigningKeysForSigningOnly() {
1300 SigningFormatPreferenceCounter count;
1301 count = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1303 count = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1308 CryptoMessageFormat commonFormat = AutoFormat;
1310 for (
unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
1311 if ( !(mCryptoMessageFormats & concreteCryptoMessageFormats[i]) )
1313 if ( signingKeysFor( concreteCryptoMessageFormats[i] ).empty() )
1315 if ( count.numOf( concreteCryptoMessageFormats[i] ) == count.numTotal() ) {
1316 commonFormat = concreteCryptoMessageFormats[i];
1321 if ( commonFormat != AutoFormat ) {
1323 FormatInfo & fi = d->mFormatInfoMap[ commonFormat ];
1324 fi.signKeys = signingKeysFor( commonFormat );
1325 fi.splitInfos.resize( 1 );
1326 fi.splitInfos.front() = SplitInfo( allRecipients() );
1331 const TQString msg = i18n(
"Examination of recipient's signing preferences "
1332 "showed no common type of signature matching your "
1333 "available signing keys.\n"
1334 "Send message without signing?" );
1335 if ( KMessageBox::warningContinueCancel( 0, msg, i18n(
"No signing possible"),
1336 KStdGuiItem::cont() )
1337 == KMessageBox::Continue ) {
1338 d->mFormatInfoMap[OpenPGPMIMEFormat].splitInfos.push_back( SplitInfo( allRecipients() ) );
1339 return Kpgp::Failure;
1341 return Kpgp::Canceled;
1344 std::vector<GpgME::Key> Kleo::KeyResolver::signingKeysFor( CryptoMessageFormat f )
const {
1345 if ( isOpenPGP( f ) )
1346 return d->mOpenPGPSigningKeys;
1348 return d->mSMIMESigningKeys;
1349 return std::vector<GpgME::Key>();
1352 std::vector<GpgME::Key> Kleo::KeyResolver::encryptToSelfKeysFor( CryptoMessageFormat f )
const {
1353 if ( isOpenPGP( f ) )
1354 return d->mOpenPGPEncryptToSelfKeys;
1356 return d->mSMIMEEncryptToSelfKeys;
1357 return std::vector<GpgME::Key>();
1360 TQStringList Kleo::KeyResolver::allRecipients()
const {
1361 TQStringList result;
1362 std::transform( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1363 std::back_inserter( result ), ItemDotAddress );
1364 std::transform( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1365 std::back_inserter( result ), ItemDotAddress );
1369 void Kleo::KeyResolver::collapseAllSplitInfos() {
1371 for (
unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
1372 std::map<CryptoMessageFormat,FormatInfo>::iterator pos =
1373 d->mFormatInfoMap.find( concreteCryptoMessageFormats[i] );
1374 if ( pos == d->mFormatInfoMap.end() )
1376 std::vector<SplitInfo> & v = pos->second.splitInfos;
1379 SplitInfo & si = v.front();
1380 for ( std::vector<SplitInfo>::const_iterator it = v.begin() + 1; it != v.end() ; ++it ) {
1381 si.keys.insert( si.keys.end(), it->keys.begin(), it->keys.end() );
1382 tqCopy( it->recipients.begin(), it->recipients.end(), std::back_inserter( si.recipients ) );
1389 void Kleo::KeyResolver::addToAllSplitInfos(
const std::vector<GpgME::Key> & keys,
unsigned int f ) {
1391 if ( !f || keys.empty() )
1393 for (
unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
1394 if ( !( f & concreteCryptoMessageFormats[i] ) )
1396 std::map<CryptoMessageFormat,FormatInfo>::iterator pos =
1397 d->mFormatInfoMap.find( concreteCryptoMessageFormats[i] );
1398 if ( pos == d->mFormatInfoMap.end() )
1400 std::vector<SplitInfo> & v = pos->second.splitInfos;
1401 for ( std::vector<SplitInfo>::iterator it = v.begin() ; it != v.end() ; ++it )
1402 it->keys.insert( it->keys.end(), keys.begin(), keys.end() );
1407 void Kleo::KeyResolver::dump()
const {
1409 if ( d->mFormatInfoMap.empty() )
1410 std::cerr <<
"Keyresolver: Format info empty" << std::endl;
1411 for ( std::map<CryptoMessageFormat,FormatInfo>::const_iterator it = d->mFormatInfoMap.begin() ; it != d->mFormatInfoMap.end() ; ++it ) {
1412 std::cerr <<
"Format info for " << Kleo::cryptoMessageFormatToString( it->first )
1414 <<
" Signing keys: ";
1415 for ( std::vector<GpgME::Key>::const_iterator sit = it->second.signKeys.begin() ; sit != it->second.signKeys.end() ; ++sit )
1416 std::cerr << sit->shortKeyID() <<
" ";
1417 std::cerr << std::endl;
1419 for ( std::vector<SplitInfo>::const_iterator sit = it->second.splitInfos.begin() ; sit != it->second.splitInfos.end() ; ++sit, ++i ) {
1420 std::cerr <<
" SplitInfo #" << i <<
" encryption keys: ";
1421 for ( std::vector<GpgME::Key>::const_iterator kit = sit->keys.begin() ; kit != sit->keys.end() ; ++kit )
1422 std::cerr << kit->shortKeyID() <<
" ";
1423 std::cerr << std::endl
1424 <<
" SplitInfo #" << i <<
" recipients: "
1425 << sit->recipients.join(
", ").utf8().data() << std::endl;
1431 Kpgp::Result Kleo::KeyResolver::showKeyApprovalDialog() {
1432 const bool showKeysForApproval = showApprovalDialog()
1433 || std::find_if( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1434 ApprovalNeeded ) != d->mPrimaryEncryptionKeys.end()
1435 || std::find_if( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1436 ApprovalNeeded ) != d->mSecondaryEncryptionKeys.end() ;
1438 if ( !showKeysForApproval )
1441 std::vector<Kleo::KeyApprovalDialog::Item> items;
1442 items.reserve( d->mPrimaryEncryptionKeys.size() +
1443 d->mSecondaryEncryptionKeys.size() );
1444 std::copy( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1445 std::back_inserter( items ) );
1446 std::copy( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1447 std::back_inserter( items ) );
1449 std::vector<GpgME::Key> senderKeys;
1450 senderKeys.reserve( d->mOpenPGPEncryptToSelfKeys.size() +
1451 d->mSMIMEEncryptToSelfKeys.size() );
1452 std::copy( d->mOpenPGPEncryptToSelfKeys.begin(), d->mOpenPGPEncryptToSelfKeys.end(),
1453 std::back_inserter( senderKeys ) );
1454 std::copy( d->mSMIMEEncryptToSelfKeys.begin(), d->mSMIMEEncryptToSelfKeys.end(),
1455 std::back_inserter( senderKeys ) );
1459 Kleo::KeyApprovalDialog dlg( items, senderKeys );
1461 if ( dlg.exec() == TQDialog::Rejected )
1462 return Kpgp::Canceled;
1464 items = dlg.items();
1465 senderKeys = dlg.senderKeys();
1467 if ( dlg.preferencesChanged() ) {
1468 for ( uint i = 0; i < items.size(); ++i ) {
1469 ContactPreferences pref = lookupContactPreferences( items[i].address );
1470 pref.encryptionPreference = items[i].pref;
1471 pref.pgpKeyFingerprints.clear();
1472 pref.smimeCertFingerprints.clear();
1473 const std::vector<GpgME::Key> & keys = items[i].keys;
1474 for ( std::vector<GpgME::Key>::const_iterator it = keys.begin(), end = keys.end() ; it != end ; ++it ) {
1475 if ( it->protocol() == GpgME::Context::OpenPGP ) {
1476 if (
const char * fpr = it->primaryFingerprint() )
1477 pref.pgpKeyFingerprints.push_back( fpr );
1478 }
else if ( it->protocol() == GpgME::Context::CMS ) {
1479 if (
const char * fpr = it->primaryFingerprint() )
1480 pref.smimeCertFingerprints.push_back( fpr );
1483 saveContactPreference( items[i].address, pref );
1489 if ( encryptToSelf() && senderKeys.empty() ) {
1490 const TQString msg = i18n(
"You did not select an encryption key for yourself "
1491 "(encrypt to self). You will not be able to decrypt "
1492 "your own message if you encrypt it.");
1493 if ( KMessageBox::warningContinueCancel( 0, msg,
1494 i18n(
"Missing Key Warning"),
1496 == KMessageBox::Cancel )
1497 return Kpgp::Canceled;
1499 mEncryptToSelf =
false;
1503 const unsigned int emptyListCount =
1504 std::count_if( items.begin(), items.end(), EmptyKeyList );
1508 if ( items.size() == emptyListCount ) {
1509 const TQString msg = ( d->mPrimaryEncryptionKeys.size() +
1510 d->mSecondaryEncryptionKeys.size() == 1 )
1511 ? i18n(
"You did not select an encryption key for the "
1512 "recipient of this message; therefore, the message "
1513 "will not be encrypted.")
1514 : i18n(
"You did not select an encryption key for any of the "
1515 "recipients of this message; therefore, the message "
1516 "will not be encrypted.");
1517 if ( KMessageBox::warningContinueCancel( 0, msg,
1518 i18n(
"Missing Key Warning"),
1519 i18n(
"Send &Unencrypted") )
1520 == KMessageBox::Cancel )
1521 return Kpgp::Canceled;
1522 }
else if ( emptyListCount > 0 ) {
1523 const TQString msg = ( emptyListCount == 1 )
1524 ? i18n(
"You did not select an encryption key for one of "
1525 "the recipients: this person will not be able to "
1526 "decrypt the message if you encrypt it.")
1527 : i18n(
"You did not select encryption keys for some of "
1528 "the recipients: these persons will not be able to "
1529 "decrypt the message if you encrypt it." );
1531 if ( KMessageBox::warningContinueCancel( 0, msg,
1532 i18n(
"Missing Key Warning"),
1534 == KMessageBox::Cancel )
1535 return Kpgp::Canceled;
1538 std::transform( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
1540 d->mPrimaryEncryptionKeys.begin(),
1541 CopyKeysAndEncryptionPreferences );
1542 std::transform( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
1543 items.begin() + d->mPrimaryEncryptionKeys.size(),
1544 d->mSecondaryEncryptionKeys.begin(),
1545 CopyKeysAndEncryptionPreferences );
1547 d->mOpenPGPEncryptToSelfKeys.clear();
1548 d->mSMIMEEncryptToSelfKeys.clear();
1550 std::remove_copy_if( senderKeys.begin(), senderKeys.end(),
1551 std::back_inserter( d->mOpenPGPEncryptToSelfKeys ),
1552 NotValidTrustedOpenPGPEncryptionKey );
1553 std::remove_copy_if( senderKeys.begin(), senderKeys.end(),
1554 std::back_inserter( d->mSMIMEEncryptToSelfKeys ),
1555 NotValidTrustedSMIMEEncryptionKey );
1562 std::map<CryptoMessageFormat,FormatInfo>::const_iterator it =
1563 d->mFormatInfoMap.find( f );
1564 return it != d->mFormatInfoMap.end() ? it->second.splitInfos : std::vector<SplitInfo>() ;
1569 std::map<CryptoMessageFormat,FormatInfo>::const_iterator it =
1570 d->mFormatInfoMap.find( f );
1571 return it != d->mFormatInfoMap.end() ? it->second.signKeys : std::vector<GpgME::Key>() ;
1581 std::vector<GpgME::Key> Kleo::KeyResolver::selectKeys(
const TQString & person,
const TQString & msg,
const std::vector<GpgME::Key> & selectedKeys )
const {
1582 const bool opgp = containsOpenPGP( mCryptoMessageFormats );
1583 const bool x509 = containsSMIME( mCryptoMessageFormats );
1585 Kleo::KeySelectionDialog dlg( i18n(
"Encryption Key Selection"),
1586 msg, KPIM::getEmailAddress(person), selectedKeys,
1587 Kleo::KeySelectionDialog::ValidEncryptionKeys
1588 & ~(opgp ? 0 : Kleo::KeySelectionDialog::OpenPGPKeys)
1589 & ~(x509 ? 0 : Kleo::KeySelectionDialog::SMIMEKeys),
1592 if ( dlg.exec() != TQDialog::Accepted )
1593 return std::vector<GpgME::Key>();
1594 std::vector<GpgME::Key> keys = dlg.selectedKeys();
1595 keys.erase( std::remove_if( keys.begin(), keys.end(),
1596 NotValidTrustedEncryptionKey ),
1598 if ( !keys.empty() && dlg.rememberSelection() )
1599 setKeysForAddress( person, dlg.pgpKeyFingerprints(), dlg.smimeFingerprints() );
1604 std::vector<GpgME::Key> Kleo::KeyResolver::getEncryptionKeys(
const TQString & person,
bool quiet )
const {
1606 const TQString address = canonicalAddress( person ).lower();
1609 const TQStringList fingerprints = keysForAddress( address );
1611 if ( !fingerprints.empty() ) {
1612 kdDebug() <<
"Using encryption keys 0x"
1613 << fingerprints.join(
", 0x" )
1614 <<
" for " << person << endl;
1615 std::vector<GpgME::Key> keys = lookup( fingerprints );
1616 if ( !keys.empty() ) {
1618 if ( std::find_if( keys.begin(), keys.end(),
1619 NotValidTrustedEncryptionKey ) != keys.end() ) {
1624 keys = selectKeys( person,
1625 i18n(
"if in your language something like "
1626 "'certificate(s)' isn't possible please "
1627 "use the plural in the translation",
1628 "There is a problem with the "
1629 "encryption certificate(s) for \"%1\".\n\n"
1630 "Please re-select the certificate(s) which should "
1631 "be used for this recipient.").arg(person),
1634 bool canceled =
false;
1635 keys = trustedOrConfirmed( keys, address, canceled );
1637 return std::vector<GpgME::Key>();
1639 if ( !keys.empty() )
1646 std::vector<GpgME::Key> matchingKeys = lookup( person );
1647 matchingKeys.erase( std::remove_if( matchingKeys.begin(), matchingKeys.end(),
1648 NotValidEncryptionKey ),
1649 matchingKeys.end() );
1652 if ( matchingKeys.empty() ) {
1653 matchingKeys = lookup( address );
1654 matchingKeys.erase( std::remove_if( matchingKeys.begin(), matchingKeys.end(),
1655 NotValidEncryptionKey ),
1656 matchingKeys.end() );
1662 bool canceled =
false;
1664 matchingKeys = trustedOrConfirmed( matchingKeys, address, canceled );
1666 return std::vector<GpgME::Key>();
1667 if ( quiet || matchingKeys.size() == 1 )
1668 return matchingKeys;
1673 return trustedOrConfirmed( selectKeys( person,
1674 matchingKeys.empty()
1675 ? i18n(
"if in your language something like "
1676 "'certificate(s)' isn't possible please "
1677 "use the plural in the translation",
1678 "<qt>No valid and trusted encryption certificate was "
1679 "found for \"%1\".<br/><br/>"
1680 "Select the certificate(s) which should "
1681 "be used for this recipient. If there is no suitable certificate in the list "
1682 "you can also search for external certificates by clicking the button: search for external certificates.</qt>")
1683 .arg( TQStyleSheet::escape(person) )
1684 : i18n(
"if in your language something like "
1685 "'certificate(s)' isn't possible please "
1686 "use the plural in the translation",
1687 "More than one certificate matches \"%1\".\n\n"
1688 "Select the certificate(s) which should "
1689 "be used for this recipient.").arg( TQStyleSheet::escape(person) ),
1690 matchingKeys ), address, canceled );
1696 std::vector<GpgME::Key> Kleo::KeyResolver::lookup(
const TQStringList & patterns,
bool secret )
const {
1697 if ( patterns.empty() )
1698 return std::vector<GpgME::Key>();
1699 kdDebug() <<
"Kleo::KeyResolver::lookup( \"" << patterns.join(
"\", \"" )
1700 <<
"\", " << secret <<
" )" << endl;
1701 std::vector<GpgME::Key> result;
1702 if ( mCryptoMessageFormats & (InlineOpenPGPFormat|OpenPGPMIMEFormat) )
1703 if (
const Kleo::CryptoBackend::Protocol * p = Kleo::CryptoBackendFactory::instance()->openpgp() ) {
1704 std::unique_ptr<Kleo::KeyListJob> job( p->keyListJob(
false,
false,
true ) );
1706 std::vector<GpgME::Key> keys;
1707 job->exec( patterns, secret, keys );
1708 result.insert( result.end(), keys.begin(), keys.end() );
1711 if ( mCryptoMessageFormats & (SMIMEFormat|SMIMEOpaqueFormat) )
1712 if (
const Kleo::CryptoBackend::Protocol * p = Kleo::CryptoBackendFactory::instance()->smime() ) {
1713 std::unique_ptr<Kleo::KeyListJob> job( p->keyListJob(
false,
false,
true ) );
1715 std::vector<GpgME::Key> keys;
1716 job->exec( patterns, secret, keys );
1717 result.insert( result.end(), keys.begin(), keys.end() );
1720 kdDebug() <<
" returned " << result.size() <<
" keys" << endl;
1724 void Kleo::KeyResolver::addKeys(
const std::vector<Item> & items, CryptoMessageFormat f ) {
1726 for ( std::vector<Item>::const_iterator it = items.begin() ; it != items.end() ; ++it ) {
1727 SplitInfo si( it->address );
1728 std::remove_copy_if( it->keys.begin(), it->keys.end(),
1729 std::back_inserter( si.keys ), IsNotForFormat( f ) );
1731 kdWarning( si.keys.empty() )
1732 <<
"Kleo::KeyResolver::addKeys(): Fix EncryptionFormatPreferenceCounter. "
1733 <<
"It detected a common format, but the list of such keys for recipient \""
1734 << it->address <<
"\" is empty!" << endl;
1735 d->mFormatInfoMap[ f ].splitInfos.push_back( si );
1740 void Kleo::KeyResolver::addKeys(
const std::vector<Item> & items ) {
1742 for ( std::vector<Item>::const_iterator it = items.begin() ; it != items.end() ; ++it ) {
1743 SplitInfo si( it->address );
1744 CryptoMessageFormat f = AutoFormat;
1745 for (
unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
1746 const CryptoMessageFormat fmt = concreteCryptoMessageFormats[i];
1747 if ( ( fmt & it->format ) &&
1748 kdtools::any( it->keys.begin(), it->keys.end(), IsForFormat( fmt ) ) )
1754 if ( f == AutoFormat )
1755 kdWarning() <<
"Kleo::KeyResolver::addKeys(): Something went wrong. Didn't find a format for \""
1756 << it->address <<
"\"" << endl;
1758 std::remove_copy_if( it->keys.begin(), it->keys.end(),
1759 std::back_inserter( si.keys ), IsNotForFormat( f ) );
1760 d->mFormatInfoMap[ f ].splitInfos.push_back( si );
1765 Kleo::KeyResolver::ContactPreferences Kleo::KeyResolver::lookupContactPreferences(
const TQString& address )
const
1767 const Private::ContactPreferencesMap::iterator it =
1768 d->mContactPreferencesMap.find( address );
1769 if ( it != d->mContactPreferencesMap.end() )
1772 TDEABC::AddressBook *ab = TDEABC::StdAddressBook::self(
true );
1773 const TDEABC::Addressee::List res = ab->findByEmail( address );
1774 ContactPreferences pref;
1775 if ( !res.isEmpty() ) {
1776 TDEABC::Addressee addr = res.first();
1777 TQString encryptPref = addr.custom(
"KADDRESSBOOK",
"CRYPTOENCRYPTPREF" );
1778 pref.encryptionPreference = Kleo::stringToEncryptionPreference( encryptPref );
1779 TQString signPref = addr.custom(
"KADDRESSBOOK",
"CRYPTOSIGNPREF" );
1780 pref.signingPreference = Kleo::stringToSigningPreference( signPref );
1781 TQString cryptoFormats = addr.custom(
"KADDRESSBOOK",
"CRYPTOPROTOPREF" );
1782 pref.cryptoMessageFormat = Kleo::stringToCryptoMessageFormat( cryptoFormats );
1783 pref.pgpKeyFingerprints = TQStringList::split(
',', addr.custom(
"KADDRESSBOOK",
"OPENPGPFP" ) );
1784 pref.smimeCertFingerprints = TQStringList::split(
',', addr.custom(
"KADDRESSBOOK",
"SMIMEFP" ) );
1787 d->mContactPreferencesMap.insert( std::make_pair( address, pref ) );
1791 void Kleo::KeyResolver::saveContactPreference(
const TQString& email,
const ContactPreferences& pref )
const
1793 d->mContactPreferencesMap.insert( std::make_pair( email, pref ) );
1794 TDEABC::AddressBook *ab = TDEABC::StdAddressBook::self(
true );
1795 TDEABC::Addressee::List res = ab->findByEmail( email );
1797 TDEABC::Addressee addr;
1798 if ( res.isEmpty() ) {
1800 TQString fullName = KInputDialog::getText( i18n(
"Name Selection" ), i18n(
"Which name shall the contact '%1' have in your addressbook?" ).arg( email ), TQString(), &ok );
1802 addr.setNameFromString( fullName );
1803 addr.insertEmail( email,
true );
1809 addr.insertCustom(
"KADDRESSBOOK",
"CRYPTOENCRYPTPREF", Kleo::encryptionPreferenceToString( pref.encryptionPreference ) );
1810 addr.insertCustom(
"KADDRESSBOOK",
"CRYPTOSIGNPREF", Kleo::signingPreferenceToString( pref.signingPreference ) );
1811 addr.insertCustom(
"KADDRESSBOOK",
"CRYPTOPROTOPREF", cryptoMessageFormatToString( pref.cryptoMessageFormat ) );
1812 addr.insertCustom(
"KADDRESSBOOK",
"OPENPGPFP", pref.pgpKeyFingerprints.join(
"," ) );
1813 addr.insertCustom(
"KADDRESSBOOK",
"SMIMEFP", pref.smimeCertFingerprints.join(
"," ) );
1815 ab->insertAddressee( addr );
1816 TDEABC::Ticket *ticket = ab->requestSaveTicket( addr.resource() );
1823 Kleo::KeyResolver::ContactPreferences::ContactPreferences()
1824 : encryptionPreference( UnknownPreference ),
1825 signingPreference( UnknownSigningPreference ),
1826 cryptoMessageFormat( AutoFormat )
1830 TQStringList Kleo::KeyResolver::keysForAddress(
const TQString & address )
const {
1831 if( address.isEmpty() ) {
1832 return TQStringList();
1834 TQString addr = canonicalAddress( address ).lower();
1835 const ContactPreferences pref = lookupContactPreferences( addr );
1836 return pref.pgpKeyFingerprints + pref.smimeCertFingerprints;
1839 void Kleo::KeyResolver::setKeysForAddress(
const TQString& address,
const TQStringList& pgpKeyFingerprints,
const TQStringList& smimeCertFingerprints )
const {
1840 if( address.isEmpty() ) {
1843 TQString addr = canonicalAddress( address ).lower();
1844 ContactPreferences pref = lookupContactPreferences( addr );
1845 pref.pgpKeyFingerprints = pgpKeyFingerprints;
1846 pref.smimeCertFingerprints = smimeCertFingerprints;
1847 saveContactPreference( addr, pref );
sets a cursor and makes sure it's restored on destruction Create a KCursorSaver object when you want ...
A class to resolve signing/encryption keys w.r.t.
std::vector< SplitInfo > encryptionItems(CryptoMessageFormat f) const
std::vector< GpgME::Key > signingKeys(CryptoMessageFormat f) const
void setSecondaryRecipients(const TQStringList &addresses)
Set the list of secondary (BCC) recipient addresses.
Action checkSigningPreferences(bool signingRequested) const
Determine whether to sign or not, depending on the per-recipient signing preferences,...
Kpgp::Result setEncryptToSelfKeys(const TQStringList &fingerprints)
Set the fingerprints of keys to be used for encrypting to self.
Action checkEncryptionPreferences(bool encryptionRequested) const
Determine whether to encrypt or not, depending on the per-recipient encryption preferences,...
Kpgp::Result setSigningKeys(const TQStringList &fingerprints)
Set the fingerprints of keys to be used for signing.
Kpgp::Result resolveAllKeys(bool &signingRequested, bool &encryptionRequested)
Queries the user for missing keys and displays a key approval dialog if needed.
void setPrimaryRecipients(const TQStringList &addresses)
Set the list of primary (To/CC) recipient addresses.