• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kleopatra

  • sources
  • kde-4.12
  • kdepim
  • kleopatra
  • crypto
decryptverifytask.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  decryptverifytask.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2008 Klarälvdalens Datakonsult AB
6 
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.
11 
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.
16 
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
20 
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.
31 */
32 
33 #include <config-kleopatra.h>
34 
35 #include "decryptverifytask.h"
36 
37 
38 #include <kleo/cryptobackendfactory.h>
39 #include <kleo/verifyopaquejob.h>
40 #include <kleo/verifydetachedjob.h>
41 #include <kleo/decryptjob.h>
42 #include <kleo/decryptverifyjob.h>
43 #include <kleo/dn.h>
44 #include <kleo/exception.h>
45 #include <kleo/stl_util.h>
46 
47 #include <models/keycache.h>
48 #include <models/predicates.h>
49 
50 #include <utils/detail_p.h>
51 #include <utils/input.h>
52 #include <utils/output.h>
53 #include <utils/classify.h>
54 #include <utils/formatting.h>
55 #include <utils/kleo_assert.h>
56 #include <utils/auditlog.h>
57 
58 #include <kmime/kmime_header_parsing.h>
59 
60 #include <gpgme++/error.h>
61 #include <gpgme++/key.h>
62 #include <gpgme++/verificationresult.h>
63 #include <gpgme++/decryptionresult.h>
64 
65 #include <gpg-error.h>
66 
67 #include <KIconLoader>
68 #include <KLocale>
69 #include <KLocalizedString>
70 #include <KDebug>
71 
72 #include <QByteArray>
73 #include <QColor>
74 #include <QDateTime>
75 #include <QStringList>
76 #include <QTextDocument> // Qt::escape
77 
78 #include <boost/bind.hpp>
79 
80 #include <algorithm>
81 #include <cassert>
82 #include <sstream>
83 
84 using namespace Kleo::Crypto;
85 using namespace Kleo;
86 using namespace GpgME;
87 using namespace boost;
88 using namespace KMime::Types;
89 
90 namespace {
91 
92 static Error make_error( const gpg_err_code_t code ) {
93  return Error( gpg_error( code ) );
94 }
95 
96 static AuditLog auditLogFromSender( QObject* sender ) {
97  return AuditLog::fromJob( qobject_cast<const Job*>( sender ) );
98 }
99 
100 static bool addrspec_equal( const AddrSpec & lhs, const AddrSpec & rhs, Qt::CaseSensitivity cs ) {
101  return lhs.localPart.compare( rhs.localPart, cs ) == 0 && lhs.domain.compare( rhs.domain, Qt::CaseInsensitive ) == 0;
102 }
103 
104 static bool mailbox_equal( const Mailbox & lhs, const Mailbox & rhs, Qt::CaseSensitivity cs ) {
105  return addrspec_equal( lhs.addrSpec(), rhs.addrSpec(), cs );
106 }
107 
108 static std::string stripAngleBrackets( const std::string & str ) {
109  if ( str.empty() )
110  return str;
111  if ( str[0] == '<' && str[str.size()-1] == '>' )
112  return str.substr( 1, str.size() - 2 );
113  return str;
114 }
115 
116 static std::string email( const UserID & uid ) {
117 
118  if ( uid.parent().protocol() == OpenPGP )
119  if ( const char * const email = uid.email() )
120  return stripAngleBrackets( email );
121  else
122  return std::string();
123 
124  assert( uid.parent().protocol() == CMS );
125 
126  if ( const char * const id = uid.id() )
127  if ( *id == '<' )
128  return stripAngleBrackets( id );
129  else
130  return DN( id )[QLatin1String("EMAIL")].trimmed().toUtf8().constData();
131  else
132  return std::string();
133 }
134 
135 static Mailbox mailbox( const UserID & uid ) {
136  const std::string e = email( uid );
137  Mailbox mbox;
138  if ( !e.empty() )
139  mbox.setAddress( e.c_str() );
140  return mbox;
141 }
142 
143 static std::vector<Mailbox> extractMailboxes( const Key & key ) {
144  std::vector<Mailbox> res;
145  Q_FOREACH( const UserID & id, key.userIDs() ) {
146  const Mailbox mbox = mailbox( id );
147  if ( !mbox.addrSpec().isEmpty() )
148  res.push_back( mbox );
149  }
150  return res;
151 }
152 
153 static std::vector<Mailbox> extractMailboxes( const std::vector<Key> & signers ) {
154  std::vector<Mailbox> res;
155  Q_FOREACH( const Key & i, signers ) {
156  const std::vector<Mailbox> bxs = extractMailboxes( i );
157  res.insert( res.end(), bxs.begin(), bxs.end() );
158  }
159  return res;
160 }
161 
162 static bool keyContainsMailbox( const Key & key, const Mailbox & mbox ) {
163  const std::vector<Mailbox> mbxs = extractMailboxes( key );
164  return std::find_if( mbxs.begin(), mbxs.end(), boost::bind( mailbox_equal, mbox, _1, Qt::CaseInsensitive ) ) != mbxs.end();
165 }
166 
167 static bool keysContainMailbox( const std::vector<Key> & keys, const Mailbox & mbox ) {
168  return std::find_if( keys.begin(), keys.end(), boost::bind( keyContainsMailbox, _1, mbox ) ) != keys.end();
169 }
170 
171 static bool relevantInDecryptVerifyContext( const VerificationResult & r ) {
172  // for D/V operations, we ignore verification results which are not errors and contain
173  // no signatures (which means that the data was just not signed)
174  return r.error() || r.numSignatures() > 0;
175 }
176 
177 static QString signatureSummaryToString( int summary )
178 {
179  if ( summary & Signature::None )
180  return i18n( "Error: Signature not verified" );
181  else if ( summary & Signature::Valid || summary & Signature::Green )
182  return i18n( "Good signature" );
183  else if ( summary & Signature::Red )
184  return i18n( "Bad signature" );
185  else if ( summary & Signature::KeyRevoked )
186  return i18n( "Signing certificate revoked" );
187  else if ( summary & Signature::KeyExpired )
188  return i18n( "Signing certificate expired" );
189  else if ( summary & Signature::KeyMissing )
190  return i18n( "No public certificate to verify the signature" );
191  else if ( summary & Signature::SigExpired )
192  return i18n( "Signature expired" );
193  else if ( summary & Signature::KeyMissing )
194  return i18n( "Certificate missing" );
195  else if ( summary & Signature::CrlMissing )
196  return i18n( "CRL missing" );
197  else if ( summary & Signature::CrlTooOld )
198  return i18n( "CRL too old" );
199  else if ( summary & Signature::BadPolicy )
200  return i18n( "Bad policy" );
201  else if ( summary & Signature::SysError )
202  return i18n( "System error" ); //### retrieve system error details?
203  return QString();
204 }
205 
206 static QString formatValidSignatureWithTrustLevel( const UserID & id ) {
207  if ( id.isNull() )
208  return QString();
209  switch ( id.validity() ) {
210  case UserID::Marginal:
211  return i18n( "The signature is valid but the trust in the certificate's validity is only marginal." );
212  case UserID::Full:
213  return i18n( "The signature is valid and the certificate's validity is fully trusted." );
214  case UserID::Ultimate:
215  return i18n( "The signature is valid and the certificate's validity is ultimately trusted." );
216  case UserID::Never:
217  return i18n( "The signature is valid but the certificate's validity is <em>not trusted</em>." );
218  case UserID::Unknown:
219  return i18n( "The signature is valid but the certificate's validity is unknown." );
220  case UserID::Undefined:
221  default:
222  return i18n( "The signature is valid but the certificate's validity is undefined." );
223  }
224 }
225 
226 static QString renderFingerprint( const char * fpr ) {
227  if ( !fpr )
228  return QString();
229  return QString::fromLatin1( "0x%1" ).arg( QString::fromLatin1( fpr ).toUpper() );
230 }
231 
232 static QString renderKeyLink( const QString & fpr, const QString & text ) {
233  return QString::fromLatin1( "<a href=\"key:%1\">%2</a>" ).arg( fpr, text );
234 }
235 
236 static QString renderKey( const Key & key ) {
237  if ( key.isNull() )
238  return i18n( "Unknown certificate" );
239  return renderKeyLink( QLatin1String(key.primaryFingerprint()), Formatting::prettyName( key ) );
240 }
241 
242 static QString renderKeyEMailOnlyNameAsFallback( const Key & key ) {
243  if ( key.isNull() )
244  return i18n( "Unknown certificate" );
245  const QString email = Formatting::prettyEMail( key );
246  const QString user = !email.isEmpty() ? email : Formatting::prettyName( key );
247  return renderKeyLink( QLatin1String(key.primaryFingerprint()), user );
248 }
249 
250 static QString formatDate( const QDateTime & dt ) {
251  return KGlobal::locale()->formatDateTime( dt );
252 }
253 static QString formatSigningInformation( const Signature & sig, const Key & key ) {
254  if ( sig.isNull() )
255  return QString();
256  const QDateTime dt = sig.creationTime() != 0 ? QDateTime::fromTime_t( sig.creationTime() ) : QDateTime();
257  const QString signer = key.isNull() ? QString() : renderKeyEMailOnlyNameAsFallback( key );
258  const bool haveKey = !key.isNull();
259  const bool haveSigner = !signer.isEmpty();
260  const bool haveDate = dt.isValid();
261  if ( !haveKey ) {
262  if ( haveDate )
263  return i18n( "Signed on %1 with unknown certificate %2.", formatDate( dt ), renderFingerprint( sig.fingerprint() ) );
264  else
265  return i18n( "Signed with unknown certificate %1.", renderFingerprint( sig.fingerprint() ) );
266  }
267  if ( haveSigner ) {
268  if ( haveDate )
269  return i18nc( "date, key owner, key ID",
270  "Signed on %1 by %2 (Key ID: %3).",
271  formatDate( dt ),
272  signer,
273  renderFingerprint( key.shortKeyID() ) );
274  else
275  return i18n( "Signed by %1 with certificate %2.", signer, renderKey( key ) );
276  }
277  if ( haveDate )
278  return i18n( "Signed on %1 with certificate %2.", formatDate( dt ), renderKey( key ) );
279  return i18n( "Signed with certificate %1.", renderKey( key ) );
280 
281 }
282 
283 static QString strikeOut( const QString & str, bool strike ) {
284  return QString( strike ? QLatin1String("<s>%1</s>") : QLatin1String("%1") ).arg( Qt::escape( str ) );
285 }
286 
287 static QString formatInputOutputLabel( const QString & input, const QString & output, bool inputDeleted, bool outputDeleted ) {
288  if ( output.isEmpty() )
289  return strikeOut( input, inputDeleted );
290  return i18nc( "Input file --> Output file (rarr is arrow", "%1 &rarr; %2",
291  strikeOut( input, inputDeleted ),
292  strikeOut( output, outputDeleted ) );
293 }
294 
295 static bool IsErrorOrCanceled( const GpgME::Error & err )
296 {
297  return err || err.isCanceled();
298 }
299 
300 static bool IsErrorOrCanceled( const Result & res )
301 {
302  return IsErrorOrCanceled( res.error() );
303 }
304 
305 static bool IsBad( const Signature & sig ) {
306  return sig.summary() & Signature::Red;
307 }
308 
309 static bool IsGoodOrValid( const Signature & sig ) {
310  return (sig.summary() & Signature::Valid) || (sig.summary() & Signature::Green);
311 }
312 
313 static UserID findUserIDByMailbox( const Key & key, const Mailbox & mbox ) {
314  Q_FOREACH( const UserID & id, key.userIDs() )
315  if ( mailbox_equal( mailbox( id ), mbox, Qt::CaseInsensitive ) )
316  return id;
317  return UserID();
318 }
319 
320 }
321 
322 class DecryptVerifyResult::SenderInfo {
323 public:
324  explicit SenderInfo( const Mailbox & infSender, const std::vector<Key> & signers_ ) : informativeSender( infSender ), signers( signers_ ) {}
325  const Mailbox informativeSender;
326  const std::vector<Key> signers;
327  bool hasInformativeSender() const { return !informativeSender.addrSpec().isEmpty(); }
328  bool conflicts() const { return hasInformativeSender() && hasKeys() && !keysContainMailbox( signers, informativeSender ); }
329  bool hasKeys() const { return kdtools::any( signers, !boost::bind( &Key::isNull, _1 ) ); }
330  std::vector<Mailbox> signerMailboxes() const {return extractMailboxes( signers ); }
331 };
332 
333 namespace {
334 
335 static Task::Result::VisualCode codeForVerificationResult( const VerificationResult & res )
336 {
337  if ( res.isNull() )
338  return Task::Result::NeutralSuccess;
339 
340  const std::vector<Signature> sigs = res.signatures();
341  if ( sigs.empty() )
342  return Task::Result::Warning;
343 
344  if ( std::find_if( sigs.begin(), sigs.end(), IsBad ) != sigs.end() )
345  return Task::Result::Danger;
346 
347  if ( std::count_if( sigs.begin(), sigs.end(), IsGoodOrValid ) == sigs.size() )
348  return Task::Result::AllGood;
349 
350  return Task::Result::Warning;
351 }
352 
353 static QString formatVerificationResultOverview( const VerificationResult & res, const DecryptVerifyResult::SenderInfo & info ) {
354  if ( res.isNull() )
355  return QString();
356 
357  const Error err = res.error();
358 
359  if ( err.isCanceled() )
360  return i18n("<b>Verification canceled.</b>");
361  else if ( err )
362  return i18n( "<b>Verification failed: %1.</b>", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) );
363 
364  const std::vector<Signature> sigs = res.signatures();
365  const std::vector<Key> signers = info.signers;
366 
367  if ( sigs.empty() )
368  return i18n( "<b>No signatures found.</b>" );
369 
370  const uint bad = std::count_if( sigs.begin(), sigs.end(), IsBad );
371  if ( bad > 0 ) {
372  return i18np("<b>Invalid signature.</b>", "<b>%1 invalid signatures.</b>", bad );
373  }
374  const uint warn = std::count_if( sigs.begin(), sigs.end(), !boost::bind( IsGoodOrValid, _1 ) );
375  if ( warn > 0 )
376  return i18np("<b>Not enough information to check signature validity.</b>", "<b>%1 signatures could not be verified.</b>", warn );
377 
378  //Good signature:
379  QString text;
380  if ( sigs.size() == 1 ) {
381  const Key key = DecryptVerifyResult::keyForSignature( sigs[0], signers );
382  if ( key.isNull() )
383  return i18n( "<b>Signature is valid.</b>" );
384  text = i18n( "<b>Signed by %1</b>", renderKeyEMailOnlyNameAsFallback( key ) );
385  if ( info.conflicts() )
386  text += i18n( "<br/><b>Warning:</b> The sender's mail address is not stored in the %1 used for signing.",
387  renderKeyLink( QLatin1String(key.primaryFingerprint()), i18n( "certificate" ) ) );
388  }
389  else {
390  text = i18np("<b>Valid signature.</b>", "<b>%1 valid signatures.</b>", sigs.size() );
391  if ( info.conflicts() )
392  text += i18n( "<br/><b>Warning:</b> The sender's mail address is not stored in the certificates used for signing." );
393  }
394 
395  return text;
396 }
397 
398 static QString formatDecryptionResultOverview( const DecryptionResult & result, const QString& errorString = QString() )
399 {
400  const Error err = result.error();
401 
402  if ( err.isCanceled() )
403  return i18n("<b>Decryption canceled.</b>");
404  else if ( !errorString.isEmpty() )
405  return i18n( "<b>Decryption failed: %1.</b>", Qt::escape( errorString ) );
406  else if ( err )
407  return i18n( "<b>Decryption failed: %1.</b>", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) );
408  return i18n("<b>Decryption succeeded.</b>" );
409 }
410 
411 static QString formatSignature( const Signature & sig, const Key & key, const DecryptVerifyResult::SenderInfo & info ) {
412  if ( sig.isNull() )
413  return QString();
414 
415  const QString text = formatSigningInformation( sig, key ) + QLatin1String("<br/>");
416 
417  const bool red = sig.summary() & Signature::Red;
418  if ( sig.summary() & Signature::Valid ) {
419  const UserID id = findUserIDByMailbox( key, info.informativeSender );
420  return text + formatValidSignatureWithTrustLevel( !id.isNull() ? id : key.userID( 0 ) );
421  }
422  if ( red )
423  return text + i18n("The signature is bad.");
424  if ( !sig.summary() )
425  return text + i18n("The validity of the signature cannot be verified.");
426  return text + i18n("The signature is invalid: %1", signatureSummaryToString( sig.summary() ) );
427 }
428 
429 static QStringList format( const std::vector<Mailbox> & mbxs ) {
430  QStringList res;
431  std::transform( mbxs.begin(), mbxs.end(), std::back_inserter( res ), boost::bind( &Mailbox::prettyAddress, _1 ) );
432  return res;
433 }
434 
435 static QString formatVerificationResultDetails( const VerificationResult & res, const DecryptVerifyResult::SenderInfo & info, const QString& errorString )
436 {
437  if( (res.error().code() == GPG_ERR_EIO || res.error().code() == GPG_ERR_NO_DATA) && !errorString.isEmpty() )
438  return i18n( "Input error: %1", errorString );
439 
440  const std::vector<Signature> sigs = res.signatures();
441  const std::vector<Key> signers = KeyCache::instance()->findSigners( res );
442  QString details;
443  Q_FOREACH ( const Signature & sig, sigs )
444  details += formatSignature( sig, DecryptVerifyResult::keyForSignature( sig, signers ), info ) + QLatin1Char('\n');
445  details = details.trimmed();
446  details.replace( QLatin1Char('\n'), QLatin1String("<br/>") );
447  if ( info.conflicts() )
448  details += i18n( "<p>The sender's address %1 is not stored in the certificate. Stored: %2</p>", info.informativeSender.prettyAddress(), format( info.signerMailboxes() ).join( i18nc("separator for a list of e-mail addresses", ", " ) ) );
449  return details;
450 }
451 
452 static QString formatDecryptionResultDetails( const DecryptionResult & res, const std::vector<Key> & recipients, const QString& errorString )
453 {
454  if( (res.error().code() == GPG_ERR_EIO || res.error().code() == GPG_ERR_NO_DATA) && !errorString.isEmpty() )
455  return i18n( "Input error: %1", errorString );
456 
457  if ( res.isNull() || !res.error() || res.error().isCanceled() )
458  return QString();
459 
460  if ( recipients.empty() && res.numRecipients() > 0 )
461  return QLatin1String( "<i>") + i18np( "One unknown recipient.", "%1 unknown recipients.", res.numRecipients() ) + QLatin1String("</i>");
462 
463  QString details;
464  if ( !recipients.empty() ) {
465  details += i18np( "Recipient:", "Recipients:", res.numRecipients() );
466  if ( res.numRecipients() == 1 )
467  return details + renderKey( recipients.front() );
468 
469  details += QLatin1String("<ul>");
470  Q_FOREACH( const Key & key, recipients )
471  details += QLatin1String("<li>") + renderKey( key ) + QLatin1String("</li>");
472  if ( recipients.size() < res.numRecipients() )
473  details += QLatin1String("<li><i>") + i18np( "One unknown recipient", "%1 unknown recipients",
474  res.numRecipients() - recipients.size() ) + QLatin1String("</i></li>");
475 
476  details += QLatin1String("</ul>");
477  }
478 
479  return details;
480 }
481 
482 static QString formatDecryptVerifyResultOverview( const DecryptionResult & dr, const VerificationResult & vr, const DecryptVerifyResult::SenderInfo & info )
483 {
484  if ( IsErrorOrCanceled( dr ) || !relevantInDecryptVerifyContext( vr ) )
485  return formatDecryptionResultOverview( dr );
486  return formatVerificationResultOverview( vr, info );
487 }
488 
489 static QString formatDecryptVerifyResultDetails( const DecryptionResult & dr,
490  const VerificationResult & vr,
491  const std::vector<Key> & recipients,
492  const DecryptVerifyResult::SenderInfo & info,
493  const QString& errorString )
494 {
495  const QString drDetails = formatDecryptionResultDetails( dr, recipients, errorString );
496  if ( IsErrorOrCanceled( dr ) || !relevantInDecryptVerifyContext( vr ) )
497  return drDetails;
498  return drDetails + ( drDetails.isEmpty() ? QString() : QLatin1String("<br/>") ) + formatVerificationResultDetails( vr, info, errorString );
499 }
500 
501 } // anon namespace
502 
503 class DecryptVerifyResult::Private {
504  DecryptVerifyResult* const q;
505 public:
506  Private( DecryptVerifyOperation type,
507  const VerificationResult & vr,
508  const DecryptionResult & dr,
509  const QByteArray & stuff,
510  int errCode,
511  const QString & errString,
512  const QString & input,
513  const QString & output,
514  const AuditLog & auditLog,
515  const Mailbox & informativeSender,
516  DecryptVerifyResult* qq ) :
517  q( qq ),
518  m_type( type ),
519  m_verificationResult( vr ),
520  m_decryptionResult( dr ),
521  m_stuff( stuff ),
522  m_error( errCode ),
523  m_errorString( errString ),
524  m_inputLabel( input ),
525  m_outputLabel( output ),
526  m_auditLog( auditLog ),
527  m_informativeSender( informativeSender )
528  {
529  }
530 
531  QString label() const {
532  return formatInputOutputLabel( m_inputLabel, m_outputLabel, false, q->hasError() );
533  }
534 
535  DecryptVerifyResult::SenderInfo makeSenderInfo() const;
536 
537  bool isDecryptOnly() const { return m_type == Decrypt; }
538  bool isVerifyOnly() const { return m_type == Verify; }
539  bool isDecryptVerify() const { return m_type == DecryptVerify; }
540  DecryptVerifyOperation m_type;
541  VerificationResult m_verificationResult;
542  DecryptionResult m_decryptionResult;
543  QByteArray m_stuff;
544  int m_error;
545  QString m_errorString;
546  QString m_inputLabel;
547  QString m_outputLabel;
548  const AuditLog m_auditLog;
549  const Mailbox m_informativeSender;
550 };
551 
552 DecryptVerifyResult::SenderInfo DecryptVerifyResult::Private::makeSenderInfo() const {
553  return SenderInfo( m_informativeSender, KeyCache::instance()->findSigners( m_verificationResult ) );
554 }
555 
556 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptResult( const DecryptionResult & dr, const QByteArray & plaintext, const AuditLog & auditLog ) {
557  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
558  Decrypt,
559  VerificationResult(),
560  dr,
561  plaintext,
562  0,
563  QString(),
564  inputLabel(),
565  outputLabel(),
566  auditLog,
567  informativeSender() ) );
568 }
569 
570 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptResult( const GpgME::Error & err, const QString& what, const AuditLog & auditLog ) {
571  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
572  Decrypt,
573  VerificationResult(),
574  DecryptionResult( err ),
575  QByteArray(),
576  err.code(),
577  what,
578  inputLabel(),
579  outputLabel(),
580  auditLog,
581  informativeSender() ) );
582 }
583 
584 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptVerifyResult( const DecryptionResult & dr, const VerificationResult & vr, const QByteArray & plaintext, const AuditLog & auditLog ) {
585  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
586  DecryptVerify,
587  vr,
588  dr,
589  plaintext,
590  0,
591  QString(),
592  inputLabel(),
593  outputLabel(),
594  auditLog,
595  informativeSender() ) );
596 }
597 
598 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromDecryptVerifyResult( const GpgME::Error & err, const QString & details, const AuditLog & auditLog ) {
599  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
600  DecryptVerify,
601  VerificationResult(),
602  DecryptionResult( err ),
603  QByteArray(),
604  err.code(),
605  details,
606  inputLabel(),
607  outputLabel(),
608  auditLog,
609  informativeSender() ) );
610 }
611 
612 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyOpaqueResult( const VerificationResult & vr, const QByteArray & plaintext, const AuditLog & auditLog ) {
613  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
614  Verify,
615  vr,
616  DecryptionResult(),
617  plaintext,
618  0,
619  QString(),
620  inputLabel(),
621  outputLabel(),
622  auditLog,
623  informativeSender() ) );
624 }
625 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyOpaqueResult( const GpgME::Error & err, const QString & details, const AuditLog & auditLog ) {
626  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
627  Verify,
628  VerificationResult( err ),
629  DecryptionResult(),
630  QByteArray(),
631  err.code(),
632  details,
633  inputLabel(),
634  outputLabel(),
635  auditLog,
636  informativeSender() ) );
637 }
638 
639 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyDetachedResult( const VerificationResult & vr, const AuditLog & auditLog ) {
640  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
641  Verify,
642  vr,
643  DecryptionResult(),
644  QByteArray(),
645  0,
646  QString(),
647  inputLabel(),
648  outputLabel(),
649  auditLog,
650  informativeSender() ) );
651 }
652 shared_ptr<DecryptVerifyResult> AbstractDecryptVerifyTask::fromVerifyDetachedResult( const GpgME::Error & err, const QString & details, const AuditLog & auditLog ) {
653  return shared_ptr<DecryptVerifyResult>( new DecryptVerifyResult(
654  Verify,
655  VerificationResult( err ),
656  DecryptionResult(),
657  QByteArray(),
658  err.code(),
659  details,
660  inputLabel(),
661  outputLabel(),
662  auditLog,
663  informativeSender() ) );
664 }
665 
666 DecryptVerifyResult::DecryptVerifyResult( DecryptVerifyOperation type,
667  const VerificationResult& vr,
668  const DecryptionResult& dr,
669  const QByteArray& stuff,
670  int errCode,
671  const QString & errString,
672  const QString & inputLabel,
673  const QString & outputLabel,
674  const AuditLog & auditLog,
675  const Mailbox & informativeSender )
676  : Task::Result(), d( new Private( type, vr, dr, stuff, errCode, errString, inputLabel, outputLabel, auditLog, informativeSender, this ) )
677 {
678 }
679 
680 QString DecryptVerifyResult::overview() const
681 {
682  QString ov;
683  if ( d->isDecryptOnly() )
684  ov = formatDecryptionResultOverview( d->m_decryptionResult );
685  else if ( d->isVerifyOnly() )
686  ov = formatVerificationResultOverview( d->m_verificationResult, d->makeSenderInfo() );
687  else
688  ov = formatDecryptVerifyResultOverview( d->m_decryptionResult, d->m_verificationResult, d->makeSenderInfo() );
689  return i18nc( "label: result example: foo.sig: Verification failed. ", "%1: %2", d->label(), ov );
690 }
691 
692 QString DecryptVerifyResult::details() const
693 {
694  if ( d->isDecryptOnly() )
695  return formatDecryptionResultDetails( d->m_decryptionResult, KeyCache::instance()->findRecipients( d->m_decryptionResult ), errorString() );
696  if ( d->isVerifyOnly() )
697  return formatVerificationResultDetails( d->m_verificationResult, d->makeSenderInfo(), errorString() );
698  return formatDecryptVerifyResultDetails( d->m_decryptionResult,
699  d->m_verificationResult, KeyCache::instance()->findRecipients(
700  d->m_decryptionResult ), d->makeSenderInfo(), errorString() );
701 }
702 
703 bool DecryptVerifyResult::hasError() const
704 {
705  return d->m_error != 0;
706 }
707 
708 int DecryptVerifyResult::errorCode() const
709 {
710  return d->m_error;
711 }
712 
713 QString DecryptVerifyResult::errorString() const
714 {
715  return d->m_errorString;
716 }
717 
718 AuditLog DecryptVerifyResult::auditLog() const {
719  return d->m_auditLog;
720 }
721 
722 Task::Result::VisualCode DecryptVerifyResult::code() const {
723  if ( ( d->m_type == DecryptVerify || d->m_type == Verify ) && relevantInDecryptVerifyContext( verificationResult() ) )
724  return codeForVerificationResult( verificationResult() );
725  return hasError() ? NeutralError : NeutralSuccess;
726 }
727 
728 GpgME::VerificationResult DecryptVerifyResult::verificationResult() const
729 {
730  return d->m_verificationResult;
731 }
732 
733 const Key & DecryptVerifyResult::keyForSignature( const Signature & sig, const std::vector<Key> & keys ) {
734  if ( const char * const fpr = sig.fingerprint() ) {
735  const std::vector<Key>::const_iterator it
736  = std::lower_bound( keys.begin(), keys.end(), fpr, _detail::ByFingerprint<std::less>() );
737  if ( it != keys.end() && _detail::ByFingerprint<std::equal_to>()( *it, fpr ) )
738  return *it;
739  }
740  static const Key null;
741  return null;
742 }
743 
744 class AbstractDecryptVerifyTask::Private {
745 public:
746  Mailbox informativeSender;
747 };
748 
749 
750 AbstractDecryptVerifyTask::AbstractDecryptVerifyTask( QObject * parent ) : Task( parent ), d( new Private ) {}
751 
752 AbstractDecryptVerifyTask::~AbstractDecryptVerifyTask() {}
753 
754 
755 Mailbox AbstractDecryptVerifyTask::informativeSender() const {
756  return d->informativeSender;
757 }
758 
759 
760 void AbstractDecryptVerifyTask::setInformativeSender( const Mailbox & sender ) {
761  d->informativeSender = sender;
762 }
763 
764 class DecryptVerifyTask::Private {
765  DecryptVerifyTask* const q;
766 public:
767  explicit Private( DecryptVerifyTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
768 
769  void slotResult( const DecryptionResult&, const VerificationResult&, const QByteArray& );
770 
771  void registerJob( DecryptVerifyJob * job ) {
772  q->connect( job, SIGNAL(result(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)),
773  q, SLOT(slotResult(GpgME::DecryptionResult,GpgME::VerificationResult,QByteArray)) );
774  q->connect( job, SIGNAL(progress(QString,int,int)),
775  q, SLOT(setProgress(QString,int,int)) );
776  }
777 
778  void emitResult( const shared_ptr<DecryptVerifyResult>& result );
779 
780  shared_ptr<Input> m_input;
781  shared_ptr<Output> m_output;
782  const CryptoBackend::Protocol* m_backend;
783  Protocol m_protocol;
784 };
785 
786 
787 void DecryptVerifyTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
788 {
789  q->emitResult( result );
790  emit q->decryptVerifyResult( result );
791 }
792 
793 void DecryptVerifyTask::Private::slotResult( const DecryptionResult& dr, const VerificationResult& vr, const QByteArray& plainText )
794 {
795  {
796  std::stringstream ss;
797  ss << dr << '\n' << vr;
798  kDebug() << ss.str().c_str();
799  }
800  const AuditLog auditLog = auditLogFromSender( q->sender() );
801  if ( dr.error().code() || vr.error().code() ) {
802  m_output->cancel();
803  } else {
804  try {
805  kleo_assert( !dr.isNull() || !vr.isNull() );
806  m_output->finalize();
807  } catch ( const GpgME::Exception & e ) {
808  emitResult( q->fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
809  return;
810  } catch ( const std::exception & e ) {
811  emitResult( q->fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), auditLog ) );
812  return;
813  } catch ( ... ) {
814  emitResult( q->fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught unknown exception"), auditLog ) );
815  return;
816  }
817  }
818  const int drErr = dr.error().code();
819  const QString errorString = m_output->errorString();
820  if ( (drErr == GPG_ERR_EIO || drErr == GPG_ERR_NO_DATA) && !errorString.isEmpty() ) {
821  emitResult( q->fromDecryptResult( dr.error(), errorString, auditLog ) );
822  return;
823  }
824 
825  emitResult( q->fromDecryptVerifyResult( dr, vr, plainText, auditLog ) );
826 }
827 
828 
829 DecryptVerifyTask::DecryptVerifyTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
830 {
831 }
832 
833 DecryptVerifyTask::~DecryptVerifyTask()
834 {
835 }
836 
837 void DecryptVerifyTask::setInput( const shared_ptr<Input> & input )
838 {
839  d->m_input = input;
840  kleo_assert( d->m_input && d->m_input->ioDevice() );
841 }
842 
843 void DecryptVerifyTask::setOutput( const shared_ptr<Output> & output )
844 {
845  d->m_output = output;
846  kleo_assert( d->m_output && d->m_output->ioDevice() );
847 }
848 
849 void DecryptVerifyTask::setProtocol( Protocol prot )
850 {
851  kleo_assert( prot != UnknownProtocol );
852  d->m_protocol = prot;
853  d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
854  kleo_assert( d->m_backend );
855 }
856 
857 void DecryptVerifyTask::autodetectProtocolFromInput()
858 {
859  if ( !d->m_input )
860  return;
861  const Protocol p = findProtocol( d->m_input->classification() );
862  if ( p == UnknownProtocol )
863  throw Exception( gpg_error( GPG_ERR_NOTHING_FOUND ), i18n("Could not determine whether this is an S/MIME or an OpenPGP signature/ciphertext - maybe it is neither ciphertext nor a signature?"), Exception::MessageOnly );
864  setProtocol( p );
865 }
866 
867 QString DecryptVerifyTask::label() const
868 {
869  return i18n( "Decrypting: %1...", d->m_input->label() );
870 }
871 
872 unsigned long long DecryptVerifyTask::inputSize() const
873 {
874  return d->m_input ? d->m_input->size() : 0;
875 }
876 
877 QString DecryptVerifyTask::inputLabel() const
878 {
879  return d->m_input ? d->m_input->label() : QString();
880 }
881 
882 QString DecryptVerifyTask::outputLabel() const
883 {
884  return d->m_output ? d->m_output->label() : QString();
885 }
886 
887 Protocol DecryptVerifyTask::protocol() const
888 {
889  return d->m_protocol;
890 }
891 
892 void DecryptVerifyTask::cancel()
893 {
894 
895 }
896 
897 void DecryptVerifyTask::doStart()
898 {
899  kleo_assert( d->m_backend );
900  try {
901  DecryptVerifyJob * const job = d->m_backend->decryptVerifyJob();
902  kleo_assert( job );
903  d->registerJob( job );
904  job->start( d->m_input->ioDevice(), d->m_output->ioDevice() );
905  } catch ( const GpgME::Exception & e ) {
906  d->emitResult( fromDecryptVerifyResult( e.error(), QString::fromLocal8Bit( e.what() ), AuditLog() ) );
907  } catch ( const std::exception & e ) {
908  d->emitResult( fromDecryptVerifyResult( make_error( GPG_ERR_INTERNAL ), i18n( "Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), AuditLog() ) );
909  } catch ( ... ) {
910  d->emitResult( fromDecryptVerifyResult( make_error( GPG_ERR_INTERNAL ), i18n( "Caught unknown exception" ), AuditLog() ) );
911  }
912 
913 }
914 
915 class DecryptTask::Private {
916  DecryptTask* const q;
917 public:
918  explicit Private( DecryptTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
919 
920  void slotResult( const DecryptionResult&, const QByteArray& );
921 
922  void registerJob( DecryptJob * job ) {
923  q->connect( job, SIGNAL(result(GpgME::DecryptionResult,QByteArray)),
924  q, SLOT(slotResult(GpgME::DecryptionResult,QByteArray)) );
925  q->connect( job, SIGNAL(progress(QString,int,int)),
926  q, SLOT(setProgress(QString,int,int)) );
927  }
928 
929  void emitResult( const shared_ptr<DecryptVerifyResult>& result );
930 
931  shared_ptr<Input> m_input;
932  shared_ptr<Output> m_output;
933  const CryptoBackend::Protocol* m_backend;
934  Protocol m_protocol;
935 };
936 
937 
938 void DecryptTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
939 {
940  q->emitResult( result );
941  emit q->decryptVerifyResult( result );
942 }
943 
944 void DecryptTask::Private::slotResult( const DecryptionResult& result, const QByteArray& plainText )
945 {
946  {
947  std::stringstream ss;
948  ss << result;
949  kDebug() << ss.str().c_str();
950  }
951  const AuditLog auditLog = auditLogFromSender( q->sender() );
952  if ( result.error().code() ) {
953  m_output->cancel();
954  } else {
955  try {
956  kleo_assert( !result.isNull() );
957  m_output->finalize();
958  } catch ( const GpgME::Exception & e ) {
959  emitResult( q->fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
960  return;
961  } catch ( const std::exception & e ) {
962  emitResult( q->fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), auditLog ) );
963  return;
964  } catch ( ... ) {
965  emitResult( q->fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught unknown exception"), auditLog ) );
966  return;
967  }
968  }
969 
970  const int drErr = result.error().code();
971  const QString errorString = m_output->errorString();
972  if ( (drErr == GPG_ERR_EIO || drErr == GPG_ERR_NO_DATA) && !errorString.isEmpty() ) {
973  emitResult( q->fromDecryptResult( result.error(), errorString, auditLog ) );
974  return;
975  }
976 
977  emitResult( q->fromDecryptResult( result, plainText, auditLog ) );
978 }
979 
980 DecryptTask::DecryptTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
981 {
982 }
983 
984 DecryptTask::~DecryptTask()
985 {
986 }
987 
988 void DecryptTask::setInput( const shared_ptr<Input> & input )
989 {
990  d->m_input = input;
991  kleo_assert( d->m_input && d->m_input->ioDevice() );
992 }
993 
994 void DecryptTask::setOutput( const shared_ptr<Output> & output )
995 {
996  d->m_output = output;
997  kleo_assert( d->m_output && d->m_output->ioDevice() );
998 }
999 
1000 void DecryptTask::setProtocol( Protocol prot )
1001 {
1002  kleo_assert( prot != UnknownProtocol );
1003  d->m_protocol = prot;
1004  d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
1005  kleo_assert( d->m_backend );
1006 }
1007 
1008 void DecryptTask::autodetectProtocolFromInput()
1009 {
1010  if ( !d->m_input )
1011  return;
1012  const Protocol p = findProtocol( d->m_input->classification() );
1013  if ( p == UnknownProtocol )
1014  throw Exception( gpg_error( GPG_ERR_NOTHING_FOUND ), i18n("Could not determine whether this was S/MIME- or OpenPGP-encrypted - maybe it is not ciphertext at all?"), Exception::MessageOnly );
1015  setProtocol( p );
1016 }
1017 
1018 QString DecryptTask::label() const
1019 {
1020  return i18n( "Decrypting: %1...", d->m_input->label() );
1021 }
1022 
1023 unsigned long long DecryptTask::inputSize() const
1024 {
1025  return d->m_input ? d->m_input->size() : 0;
1026 }
1027 
1028 QString DecryptTask::inputLabel() const
1029 {
1030  return d->m_input ? d->m_input->label() : QString();
1031 }
1032 
1033 QString DecryptTask::outputLabel() const
1034 {
1035  return d->m_output ? d->m_output->label() : QString();
1036 }
1037 
1038 Protocol DecryptTask::protocol() const
1039 {
1040  kleo_assert( !"not implemented" );
1041  return UnknownProtocol; // ### TODO
1042 }
1043 
1044 void DecryptTask::cancel()
1045 {
1046 
1047 }
1048 
1049 void DecryptTask::doStart()
1050 {
1051  kleo_assert( d->m_backend );
1052 
1053  try {
1054  DecryptJob * const job = d->m_backend->decryptJob();
1055  kleo_assert( job );
1056  d->registerJob( job );
1057  job->start( d->m_input->ioDevice(), d->m_output->ioDevice() );
1058  } catch ( const GpgME::Exception & e ) {
1059  d->emitResult( fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), AuditLog() ) );
1060  } catch ( const std::exception & e ) {
1061  d->emitResult( fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), AuditLog() ) );
1062  } catch ( ... ) {
1063  d->emitResult( fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught unknown exception"), AuditLog() ) );
1064  }
1065 }
1066 
1067 class VerifyOpaqueTask::Private {
1068  VerifyOpaqueTask* const q;
1069 public:
1070  explicit Private( VerifyOpaqueTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
1071 
1072  void slotResult( const VerificationResult&, const QByteArray& );
1073 
1074  void registerJob( VerifyOpaqueJob* job ) {
1075  q->connect( job, SIGNAL(result(GpgME::VerificationResult,QByteArray)),
1076  q, SLOT(slotResult(GpgME::VerificationResult,QByteArray)) );
1077  q->connect( job, SIGNAL(progress(QString,int,int)),
1078  q, SLOT(setProgress(QString,int,int)) );
1079  }
1080 
1081  void emitResult( const shared_ptr<DecryptVerifyResult>& result );
1082 
1083  shared_ptr<Input> m_input;
1084  shared_ptr<Output> m_output;
1085  const CryptoBackend::Protocol* m_backend;
1086  Protocol m_protocol;
1087 };
1088 
1089 
1090 void VerifyOpaqueTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
1091 {
1092  q->emitResult( result );
1093  emit q->decryptVerifyResult( result );
1094 }
1095 
1096 void VerifyOpaqueTask::Private::slotResult( const VerificationResult& result, const QByteArray& plainText )
1097 {
1098  {
1099  std::stringstream ss;
1100  ss << result;
1101  kDebug() << ss.str().c_str();
1102  }
1103  const AuditLog auditLog = auditLogFromSender( q->sender() );
1104  if ( result.error().code() ) {
1105  m_output->cancel();
1106  } else {
1107  try {
1108  kleo_assert( !result.isNull() );
1109  m_output->finalize();
1110  } catch ( const GpgME::Exception & e ) {
1111  emitResult( q->fromDecryptResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
1112  return;
1113  } catch ( const std::exception & e ) {
1114  emitResult( q->fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), auditLog ) );
1115  return;
1116  } catch ( ... ) {
1117  emitResult( q->fromDecryptResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught unknown exception"), auditLog ) );
1118  return;
1119  }
1120  }
1121 
1122  const int drErr = result.error().code();
1123  const QString errorString = m_output->errorString();
1124  if ( (drErr == GPG_ERR_EIO || drErr == GPG_ERR_NO_DATA) && !errorString.isEmpty() ) {
1125  emitResult( q->fromDecryptResult( result.error(), errorString, auditLog ) );
1126  return;
1127  }
1128 
1129  emitResult( q->fromVerifyOpaqueResult( result, plainText, auditLog ) );
1130 }
1131 
1132 VerifyOpaqueTask::VerifyOpaqueTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
1133 {
1134 }
1135 
1136 VerifyOpaqueTask::~VerifyOpaqueTask()
1137 {
1138 }
1139 
1140 void VerifyOpaqueTask::setInput( const shared_ptr<Input> & input )
1141 {
1142  d->m_input = input;
1143  kleo_assert( d->m_input && d->m_input->ioDevice() );
1144 }
1145 
1146 void VerifyOpaqueTask::setOutput( const shared_ptr<Output> & output )
1147 {
1148  d->m_output = output;
1149  kleo_assert( d->m_output && d->m_output->ioDevice() );
1150 }
1151 
1152 void VerifyOpaqueTask::setProtocol( Protocol prot )
1153 {
1154  kleo_assert( prot != UnknownProtocol );
1155  d->m_protocol = prot;
1156  d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
1157  kleo_assert( d->m_backend );
1158 }
1159 
1160 void VerifyOpaqueTask::autodetectProtocolFromInput()
1161 {
1162  if ( !d->m_input )
1163  return;
1164  const Protocol p = findProtocol( d->m_input->classification() );
1165  if ( p == UnknownProtocol )
1166  throw Exception( gpg_error( GPG_ERR_NOTHING_FOUND ), i18n("Could not determine whether this is an S/MIME or an OpenPGP signature - maybe it is not a signature at all?"), Exception::MessageOnly );
1167  setProtocol( p );
1168 }
1169 
1170 QString VerifyOpaqueTask::label() const
1171 {
1172  return i18n( "Verifying: %1...", d->m_input->label() );
1173 }
1174 
1175 unsigned long long VerifyOpaqueTask::inputSize() const
1176 {
1177  return d->m_input ? d->m_input->size() : 0;
1178 }
1179 
1180 QString VerifyOpaqueTask::inputLabel() const
1181 {
1182  return d->m_input ? d->m_input->label() : QString();
1183 }
1184 
1185 QString VerifyOpaqueTask::outputLabel() const
1186 {
1187  return d->m_output ? d->m_output->label() : QString();
1188 }
1189 
1190 Protocol VerifyOpaqueTask::protocol() const
1191 {
1192  return d->m_protocol;
1193 }
1194 
1195 void VerifyOpaqueTask::cancel()
1196 {
1197 
1198 }
1199 
1200 void VerifyOpaqueTask::doStart()
1201 {
1202  kleo_assert( d->m_backend );
1203 
1204  try {
1205  VerifyOpaqueJob * const job = d->m_backend->verifyOpaqueJob();
1206  kleo_assert( job );
1207  d->registerJob( job );
1208  job->start( d->m_input->ioDevice(), d->m_output ? d->m_output->ioDevice() : shared_ptr<QIODevice>() );
1209  } catch ( const GpgME::Exception & e ) {
1210  d->emitResult( fromVerifyOpaqueResult( e.error(), QString::fromLocal8Bit( e.what() ), AuditLog() ) );
1211  } catch ( const std::exception & e ) {
1212  d->emitResult( fromVerifyOpaqueResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), AuditLog() ) );
1213  } catch ( ... ) {
1214  d->emitResult( fromVerifyOpaqueResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught unknown exception"), AuditLog() ) );
1215  }
1216 }
1217 
1218 class VerifyDetachedTask::Private {
1219  VerifyDetachedTask* const q;
1220 public:
1221  explicit Private( VerifyDetachedTask* qq ) : q( qq ), m_backend( 0 ), m_protocol( UnknownProtocol ) {}
1222 
1223  void slotResult( const VerificationResult& );
1224 
1225  void registerJob( VerifyDetachedJob* job ) {
1226  q->connect( job, SIGNAL(result(GpgME::VerificationResult)),
1227  q, SLOT(slotResult(GpgME::VerificationResult)) );
1228  q->connect( job, SIGNAL(progress(QString,int,int)),
1229  q, SLOT(setProgress(QString,int,int)) );
1230  }
1231 
1232  void emitResult( const shared_ptr<DecryptVerifyResult>& result );
1233 
1234  shared_ptr<Input> m_input, m_signedData;
1235  const CryptoBackend::Protocol* m_backend;
1236  Protocol m_protocol;
1237 };
1238 
1239 
1240 void VerifyDetachedTask::Private::emitResult( const shared_ptr<DecryptVerifyResult>& result )
1241 {
1242  q->emitResult( result );
1243  emit q->decryptVerifyResult( result );
1244 }
1245 
1246 void VerifyDetachedTask::Private::slotResult( const VerificationResult& result )
1247 {
1248  {
1249  std::stringstream ss;
1250  ss << result;
1251  kDebug() << ss.str().c_str();
1252  }
1253  const AuditLog auditLog = auditLogFromSender( q->sender() );
1254  try {
1255  kleo_assert( !result.isNull() );
1256  emitResult( q->fromVerifyDetachedResult( result, auditLog ) );
1257  } catch ( const GpgME::Exception & e ) {
1258  emitResult( q->fromVerifyDetachedResult( e.error(), QString::fromLocal8Bit( e.what() ), auditLog ) );
1259  } catch ( const std::exception & e ) {
1260  emitResult( q->fromVerifyDetachedResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), auditLog ) );
1261  } catch ( ... ) {
1262  emitResult( q->fromVerifyDetachedResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught unknown exception"), auditLog ) );
1263  }
1264 }
1265 
1266 VerifyDetachedTask::VerifyDetachedTask( QObject* parent ) : AbstractDecryptVerifyTask( parent ), d( new Private( this ) )
1267 {
1268 }
1269 
1270 VerifyDetachedTask::~VerifyDetachedTask()
1271 {
1272 }
1273 
1274 void VerifyDetachedTask::setInput( const shared_ptr<Input> & input )
1275 {
1276  d->m_input = input;
1277  kleo_assert( d->m_input && d->m_input->ioDevice() );
1278 }
1279 
1280 void VerifyDetachedTask::setSignedData( const shared_ptr<Input> & signedData )
1281 {
1282  d->m_signedData = signedData;
1283  kleo_assert( d->m_signedData && d->m_signedData->ioDevice() );
1284 }
1285 
1286 void VerifyDetachedTask::setProtocol( Protocol prot )
1287 {
1288  kleo_assert( prot != UnknownProtocol );
1289  d->m_protocol = prot;
1290  d->m_backend = CryptoBackendFactory::instance()->protocol( prot );
1291  kleo_assert( d->m_backend );
1292 }
1293 
1294 void VerifyDetachedTask::autodetectProtocolFromInput()
1295 {
1296  if ( !d->m_input )
1297  return;
1298  const Protocol p = findProtocol( d->m_input->classification() );
1299  if ( p == UnknownProtocol )
1300  throw Exception( gpg_error( GPG_ERR_NOTHING_FOUND ), i18n("Could not determine whether this is an S/MIME or an OpenPGP signature - maybe it is not a signature at all?"), Exception::MessageOnly );
1301  setProtocol( p );
1302 }
1303 
1304 unsigned long long VerifyDetachedTask::inputSize() const
1305 {
1306  return d->m_signedData ? d->m_signedData->size() : 0;
1307 }
1308 
1309 QString VerifyDetachedTask::label() const
1310 {
1311  return i18n( "Verifying signature: %1...", d->m_input->label() );
1312 }
1313 
1314 QString VerifyDetachedTask::inputLabel() const
1315 {
1316  return d->m_input ? d->m_input->label() : QString();
1317 }
1318 
1319 QString VerifyDetachedTask::outputLabel() const
1320 {
1321  return QString();
1322 }
1323 
1324 Protocol VerifyDetachedTask::protocol() const
1325 {
1326  kleo_assert( !"not implemented" );
1327  return UnknownProtocol; // ### TODO
1328 }
1329 
1330 void VerifyDetachedTask::cancel()
1331 {
1332 
1333 }
1334 
1335 void VerifyDetachedTask::doStart()
1336 {
1337  kleo_assert( d->m_backend );
1338  try {
1339  VerifyDetachedJob * const job = d->m_backend->verifyDetachedJob();
1340  kleo_assert( job );
1341  d->registerJob( job );
1342  job->start( d->m_input->ioDevice(), d->m_signedData->ioDevice() );
1343  } catch ( const GpgME::Exception & e ) {
1344  d->emitResult( fromVerifyDetachedResult( e.error(), QString::fromLocal8Bit( e.what() ), AuditLog() ) );
1345  } catch ( const std::exception & e ) {
1346  d->emitResult( fromVerifyDetachedResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught exception: %1", QString::fromLocal8Bit( e.what() ) ), AuditLog() ) );
1347  } catch ( ... ) {
1348  d->emitResult( fromVerifyDetachedResult( make_error( GPG_ERR_INTERNAL ), i18n("Caught unknown exception"), AuditLog() ) );
1349  }
1350 }
1351 
1352 #include "decryptverifytask.moc"
Kleo::Crypto::DecryptVerifyTask::setOutput
void setOutput(const boost::shared_ptr< Output > &output)
Definition: decryptverifytask.cpp:843
Kleo::Crypto::DecryptTask::autodetectProtocolFromInput
void autodetectProtocolFromInput()
Definition: decryptverifytask.cpp:1008
Kleo::Crypto::DecryptVerifyTask::cancel
void cancel()
Definition: decryptverifytask.cpp:892
Kleo::Crypto::DecryptVerifyTask::DecryptVerifyTask
DecryptVerifyTask(QObject *parent=0)
Definition: decryptverifytask.cpp:829
Unknown
Definition: setinitialpindialog.cpp:55
Kleo::Crypto::DecryptVerifyTask::protocol
GpgME::Protocol protocol() const
Definition: decryptverifytask.cpp:887
auditlog.h
output.h
input.h
Kleo::Crypto::AbstractDecryptVerifyTask::informativeSender
KMime::Types::Mailbox informativeSender() const
Definition: decryptverifytask.cpp:755
Kleo::Crypto::AbstractDecryptVerifyTask::~AbstractDecryptVerifyTask
virtual ~AbstractDecryptVerifyTask()
Definition: decryptverifytask.cpp:752
Kleo::Formatting::type
QString type(const GpgME::Key &key)
Kleo::Crypto::Task::Result::VisualCode
VisualCode
Definition: task.h:127
Kleo::Crypto::VerifyDetachedTask::~VerifyDetachedTask
~VerifyDetachedTask()
Definition: decryptverifytask.cpp:1270
Kleo::AuditLog
Definition: auditlog.h:48
Kleo::Crypto::DecryptVerifyTask::autodetectProtocolFromInput
void autodetectProtocolFromInput()
Definition: decryptverifytask.cpp:857
email
static std::string email(const UserID &uid)
Definition: keycache.cpp:593
decryptverifytask.h
Kleo::Crypto::Task::Result::Danger
Definition: task.h:130
Kleo::Crypto::DecryptVerifyResult::errorCode
int errorCode() const
Definition: decryptverifytask.cpp:708
Kleo::Crypto::Task::Result::NeutralError
Definition: task.h:132
Kleo::Crypto::DecryptVerifyResult::details
QString details() const
Definition: decryptverifytask.cpp:692
Kleo::Crypto::Task
Definition: task.h:55
classify.h
formatting.h
Kleo::Crypto::DecryptTask::DecryptTask
DecryptTask(QObject *parent=0)
Definition: decryptverifytask.cpp:980
Kleo::Crypto::VerifyOpaqueTask::~VerifyOpaqueTask
~VerifyOpaqueTask()
Definition: decryptverifytask.cpp:1136
Kleo::Crypto::VerifyDetachedTask
Definition: decryptverifytask.h:130
Kleo::Crypto::DecryptVerifyTask::setInput
void setInput(const boost::shared_ptr< Input > &input)
Definition: decryptverifytask.cpp:837
Kleo::DecryptVerify
Definition: types.h:48
Kleo::Crypto::AbstractDecryptVerifyTask::fromVerifyOpaqueResult
boost::shared_ptr< DecryptVerifyResult > fromVerifyOpaqueResult(const GpgME::VerificationResult &vr, const QByteArray &plaintext, const AuditLog &auditLog)
is
static bool is(const QListWidgetItem *item, bool(QFont::*func)() const )
Definition: appearanceconfigwidget.cpp:102
Kleo::Crypto::VerifyOpaqueTask::cancel
void cancel()
Definition: decryptverifytask.cpp:1195
Kleo::Crypto::DecryptTask::cancel
void cancel()
Definition: decryptverifytask.cpp:1044
kleo_assert.h
Kleo::Crypto::DecryptVerifyTask::~DecryptVerifyTask
~DecryptVerifyTask()
Definition: decryptverifytask.cpp:833
Kleo::Crypto::VerifyDetachedTask::label
QString label() const
Definition: decryptverifytask.cpp:1309
Kleo::Crypto::VerifyOpaqueTask::VerifyOpaqueTask
VerifyOpaqueTask(QObject *parent=0)
Definition: decryptverifytask.cpp:1132
boost::shared_ptr
Definition: encryptemailcontroller.h:51
Kleo::Crypto::VerifyOpaqueTask
Definition: decryptverifytask.h:161
Kleo::Crypto::DecryptVerifyResult::keyForSignature
static const GpgME::Key & keyForSignature(const GpgME::Signature &sig, const std::vector< GpgME::Key > &keys)
Definition: decryptverifytask.cpp:733
d
#define d
Definition: adduseridcommand.cpp:90
Kleo::Crypto::DecryptVerifyTask
Definition: decryptverifytask.h:192
Kleo::Crypto::DecryptVerifyResult::verificationResult
GpgME::VerificationResult verificationResult() const
Definition: decryptverifytask.cpp:728
Kleo::Class::OpenPGP
Definition: classify.h:49
Kleo::Crypto::DecryptTask::setOutput
void setOutput(const boost::shared_ptr< Output > &output)
Definition: decryptverifytask.cpp:994
Kleo::Crypto::AbstractDecryptVerifyTask::fromVerifyDetachedResult
boost::shared_ptr< DecryptVerifyResult > fromVerifyDetachedResult(const GpgME::VerificationResult &vr, const AuditLog &auditLog)
Kleo::Verify
Definition: types.h:47
Kleo::Crypto::VerifyOpaqueTask::setInput
void setInput(const boost::shared_ptr< Input > &input)
Definition: decryptverifytask.cpp:1140
Kleo::DecryptVerifyOperation
DecryptVerifyOperation
Definition: types.h:45
Kleo::Class::CMS
Definition: classify.h:48
Kleo::AuditLog::fromJob
static AuditLog fromJob(const Job *)
Definition: auditlog.cpp:45
Kleo::Crypto::DecryptTask::~DecryptTask
~DecryptTask()
Definition: decryptverifytask.cpp:984
Kleo::Crypto::DecryptVerifyTask::setProtocol
void setProtocol(GpgME::Protocol prot)
Definition: decryptverifytask.cpp:849
Kleo::Crypto::DecryptVerifyResult::code
VisualCode code() const
Definition: decryptverifytask.cpp:722
Kleo::Crypto::DecryptVerifyResult::overview
QString overview() const
Definition: decryptverifytask.cpp:680
Kleo::Formatting::prettyEMail
QString prettyEMail(const char *email, const char *id)
Definition: formatting.cpp:184
Kleo::Crypto::VerifyDetachedTask::setSignedData
void setSignedData(const boost::shared_ptr< Input > &signedData)
Definition: decryptverifytask.cpp:1280
Kleo::Crypto::DecryptVerifyResult::errorString
QString errorString() const
Definition: decryptverifytask.cpp:713
Kleo::Crypto::DecryptVerifyResult::hasError
bool hasError() const
Definition: decryptverifytask.cpp:703
Kleo::Crypto::DecryptTask
Definition: decryptverifytask.h:99
Kleo::Crypto::Task::setProgress
void setProgress(const QString &msg, int processed, int total)
Definition: task.cpp:151
Kleo::Crypto::VerifyDetachedTask::cancel
void cancel()
Definition: decryptverifytask.cpp:1330
Kleo::Crypto::VerifyOpaqueTask::protocol
GpgME::Protocol protocol() const
Definition: decryptverifytask.cpp:1190
kleo_assert
#define kleo_assert(cond)
Definition: kleo_assert.h:84
Kleo::Crypto::AbstractDecryptVerifyTask::AbstractDecryptVerifyTask
AbstractDecryptVerifyTask(QObject *parent=0)
Definition: decryptverifytask.cpp:750
string
const char * string
Definition: verifychecksumscontroller.cpp:511
Kleo::Crypto::VerifyOpaqueTask::setOutput
void setOutput(const boost::shared_ptr< Output > &output)
Definition: decryptverifytask.cpp:1146
Kleo::Crypto::VerifyDetachedTask::setInput
void setInput(const boost::shared_ptr< Input > &input)
Definition: decryptverifytask.cpp:1274
Kleo::Crypto::AbstractDecryptVerifyTask::fromDecryptResult
boost::shared_ptr< DecryptVerifyResult > fromDecryptResult(const GpgME::DecryptionResult &dr, const QByteArray &plaintext, const AuditLog &auditLog)
Kleo::Crypto::Task::Result::Warning
Definition: task.h:129
predicates.h
Kleo::Crypto::VerifyDetachedTask::protocol
GpgME::Protocol protocol() const
Definition: decryptverifytask.cpp:1324
Kleo::Formatting::prettyName
QString prettyName(int proto, const char *id, const char *name, const char *comment)
Definition: formatting.cpp:64
q
#define q
Definition: adduseridcommand.cpp:91
Kleo::Crypto::DecryptVerifyResult::auditLog
AuditLog auditLog() const
Definition: decryptverifytask.cpp:718
Kleo::Crypto::DecryptVerifyTask::label
QString label() const
Definition: decryptverifytask.cpp:867
Kleo::Crypto::Task::Result::AllGood
Definition: task.h:128
Kleo::KeyCache::instance
static boost::shared_ptr< const KeyCache > instance()
Definition: keycache.cpp:189
detail_p.h
Kleo::Crypto::DecryptTask::setInput
void setInput(const boost::shared_ptr< Input > &input)
Definition: decryptverifytask.cpp:988
Kleo::Crypto::Task::Result::NeutralSuccess
Definition: task.h:131
Kleo::Decrypt
Definition: types.h:46
Kleo::Crypto::AbstractDecryptVerifyTask::fromDecryptVerifyResult
boost::shared_ptr< DecryptVerifyResult > fromDecryptVerifyResult(const GpgME::DecryptionResult &dr, const GpgME::VerificationResult &vr, const QByteArray &plaintext, const AuditLog &auditLog)
Kleo::Crypto::AbstractDecryptVerifyTask::setInformativeSender
void setInformativeSender(const KMime::Types::Mailbox &senders)
Definition: decryptverifytask.cpp:760
keycache.h
Kleo::Crypto::VerifyDetachedTask::setProtocol
void setProtocol(GpgME::Protocol prot)
Definition: decryptverifytask.cpp:1286
Kleo::Crypto::VerifyOpaqueTask::autodetectProtocolFromInput
void autodetectProtocolFromInput()
Definition: decryptverifytask.cpp:1160
Kleo::Crypto::Task::emitResult
void emitResult(const boost::shared_ptr< const Task::Result > &result)
Definition: task.cpp:178
Kleo::Crypto::DecryptTask::protocol
GpgME::Protocol protocol() const
Definition: decryptverifytask.cpp:1038
Kleo::Crypto::VerifyDetachedTask::VerifyDetachedTask
VerifyDetachedTask(QObject *parent=0)
Definition: decryptverifytask.cpp:1266
Kleo::Crypto::VerifyOpaqueTask::label
QString label() const
Definition: decryptverifytask.cpp:1170
Kleo::Crypto::DecryptTask::setProtocol
void setProtocol(GpgME::Protocol prot)
Definition: decryptverifytask.cpp:1000
Kleo::Crypto::DecryptTask::label
QString label() const
Definition: decryptverifytask.cpp:1018
Kleo::Crypto::DecryptVerifyResult
Definition: decryptverifytask.h:224
Kleo::Crypto::VerifyOpaqueTask::setProtocol
void setProtocol(GpgME::Protocol prot)
Definition: decryptverifytask.cpp:1152
Kleo::Crypto::AbstractDecryptVerifyTask
Definition: decryptverifytask.h:68
Kleo::findProtocol
ProtocolMask FormatMask TypeMask TypeMask TypeMask GpgME::Protocol findProtocol(const unsigned int classifcation)
Definition: classify.h:127
Kleo::Crypto::VerifyDetachedTask::autodetectProtocolFromInput
void autodetectProtocolFromInput()
Definition: decryptverifytask.cpp:1294
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:41 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal