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

kleopatra

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

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