• 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
  • commands
deletecertificatescommand.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  deleteCertificatescommand.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2007 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 "deletecertificatescommand.h"
36 
37 #include "command_p.h"
38 
39 #include <dialogs/deletecertificatesdialog.h>
40 
41 #include <models/keycache.h>
42 #include <models/predicates.h>
43 
44 #include <kleo/stl_util.h>
45 #include <kleo/cryptobackend.h>
46 #include <kleo/cryptobackendfactory.h>
47 #include <kleo/multideletejob.h>
48 #include <kleo/deletejob.h>
49 
50 #include <gpgme++/key.h>
51 
52 #include <KLocalizedString>
53 
54 #include <QPointer>
55 #include <QAbstractItemView>
56 
57 #ifndef Q_MOC_RUN
58 #include <boost/bind.hpp>
59 #endif
60 
61 #include <algorithm>
62 #include <vector>
63 #include <cassert>
64 
65 using namespace boost;
66 using namespace GpgME;
67 using namespace Kleo;
68 using namespace Kleo::Dialogs;
69 
70 class DeleteCertificatesCommand::Private : public Command::Private {
71  friend class ::Kleo::DeleteCertificatesCommand;
72  DeleteCertificatesCommand * q_func() const { return static_cast<DeleteCertificatesCommand*>(q); }
73 public:
74  explicit Private( DeleteCertificatesCommand * qq, KeyListController * c );
75  ~Private();
76 
77  void startDeleteJob( GpgME::Protocol protocol );
78 
79  void cancelJobs();
80  void pgpDeleteResult( const GpgME::Error & );
81  void cmsDeleteResult( const GpgME::Error & );
82  void showErrorsAndFinish();
83 
84  bool canDelete( GpgME::Protocol proto ) const {
85  if ( const CryptoBackend::Protocol * const cbp = CryptoBackendFactory::instance()->protocol( proto ) )
86  if ( DeleteJob * const job = cbp->deleteJob() ) {
87  job->slotCancel();
88  return true;
89  }
90  return false;
91  }
92 
93  void ensureDialogCreated() {
94  if ( dialog )
95  return;
96  dialog = new DeleteCertificatesDialog;
97  applyWindowID( dialog );
98  dialog->setAttribute( Qt::WA_DeleteOnClose );
99  dialog->setWindowTitle( i18nc("@title:window", "Delete Certificates") );
100  connect( dialog, SIGNAL(accepted()), q_func(), SLOT(slotDialogAccepted()) );
101  connect( dialog, SIGNAL(rejected()), q_func(), SLOT(slotDialogRejected()) );
102  }
103  void ensureDialogShown() {
104  if ( dialog )
105  dialog->show();
106  }
107 
108  void slotDialogAccepted();
109  void slotDialogRejected() {
110  canceled();
111  }
112 
113 private:
114  QPointer<DeleteCertificatesDialog> dialog;
115  QPointer<MultiDeleteJob> cmsJob, pgpJob;
116  GpgME::Error cmsError, pgpError;
117  std::vector<Key> cmsKeys, pgpKeys;
118 };
119 
120 DeleteCertificatesCommand::Private * DeleteCertificatesCommand::d_func() { return static_cast<Private*>(d.get()); }
121 const DeleteCertificatesCommand::Private * DeleteCertificatesCommand::d_func() const { return static_cast<const Private*>(d.get()); }
122 
123 #define d d_func()
124 #define q q_func()
125 
126 DeleteCertificatesCommand::Private::Private( DeleteCertificatesCommand * qq, KeyListController * c )
127  : Command::Private( qq, c )
128 {
129 
130 }
131 
132 DeleteCertificatesCommand::Private::~Private() {}
133 
134 
135 DeleteCertificatesCommand::DeleteCertificatesCommand( KeyListController * p )
136  : Command( new Private( this, p ) )
137 {
138 
139 }
140 
141 DeleteCertificatesCommand::DeleteCertificatesCommand( QAbstractItemView * v, KeyListController * p )
142  : Command( v, new Private( this, p ) )
143 {
144 
145 }
146 
147 DeleteCertificatesCommand::~DeleteCertificatesCommand() {}
148 
149 namespace {
150 
151  enum Action { Nothing = 0, Failure = 1, ClearCMS = 2, ClearPGP = 4 };
152 
153  // const unsigned int errorCase =
154  // openpgp.empty() << 3U | d->canDelete( OpenPGP ) << 2U |
155  // cms.empty() << 1U | d->canDelete( CMS ) << 0U ;
156 
157  static const struct {
158  const char * text;
159  Action actions;
160  } deletionErrorCases[16] = {
161  // if havePGP
162  // if cantPGP
163  // if haveCMS
164  { I18N_NOOP( "Neither the OpenPGP nor the CMS "
165  "backends support certificate deletion.\n"
166  "Check your installation." ),
167  Failure }, // cantCMS
168  { I18N_NOOP( "The OpenPGP backend does not support "
169  "certificate deletion.\n"
170  "Check your installation.\n"
171  "Only the selected CMS certificates "
172  "will be deleted." ),
173  ClearPGP }, // canCMS
174  // if !haveCMS
175  { I18N_NOOP( "The OpenPGP backend does not support "
176  "certificate deletion.\n"
177  "Check your installation." ),
178  Failure },
179  { I18N_NOOP( "The OpenPGP backend does not support "
180  "certificate deletion.\n"
181  "Check your installation." ),
182  Failure },
183  // if canPGP
184  // if haveCMS
185  { I18N_NOOP( "The CMS backend does not support "
186  "certificate deletion.\n"
187  "Check your installation.\n"
188  "Only the selected OpenPGP certificates "
189  "will be deleted." ),
190  ClearCMS }, // cantCMS
191  { 0,
192  Nothing }, // canCMS
193  // if !haveCMS
194  { 0,
195  Nothing }, // cantCMS
196  { 0,
197  Nothing }, // canCMS
198  // if !havePGP
199  // if cantPGP
200  // if haveCMS
201  { I18N_NOOP( "The CMS backend does not support "
202  "certificate deletion.\n"
203  "Check your installation." ),
204  Failure }, // cantCMS
205  { 0,
206  Nothing }, // canCMS
207  // if !haveCMS
208  { 0,
209  Nothing }, // cantCMS
210  { 0,
211  Nothing }, // canCMS
212  // if canPGP
213  // if haveCMS
214  { I18N_NOOP( "The CMS backend does not support "
215  "certificate deletion.\n"
216  "Check your installation." ),
217  Failure }, // cantCMS
218  { 0,
219  Nothing }, // canCMS
220  // if !haveCMS
221  { 0,
222  Nothing }, // cantCMS
223  { 0,
224  Nothing }, // canCMS
225  };
226 } // anon namespace
227 
228 void DeleteCertificatesCommand::doStart() {
229 
230  std::vector<Key> selected = d->keys();
231  if ( selected.empty() ) {
232  d->finished();
233  return;
234  }
235 
236  kdtools::sort( selected, _detail::ByFingerprint<std::less>() );
237 
238  // Calculate the closure of the selected keys (those that need to
239  // be deleted with them, though not selected themselves):
240 
241  std::vector<Key> toBeDeleted = KeyCache::instance()->findSubjects( selected );
242  kdtools::sort( toBeDeleted, _detail::ByFingerprint<std::less>() );
243 
244  std::vector<Key> unselected;
245  unselected.reserve( toBeDeleted.size() );
246  std::set_difference( toBeDeleted.begin(), toBeDeleted.end(),
247  selected.begin(), selected.end(),
248  std::back_inserter( unselected ),
249  _detail::ByFingerprint<std::less>() );
250 
251  d->ensureDialogCreated();
252 
253  d->dialog->setSelectedKeys( selected );
254  d->dialog->setUnselectedKeys( unselected );
255 
256  d->ensureDialogShown();
257 
258 }
259 
260 void DeleteCertificatesCommand::Private::slotDialogAccepted() {
261  std::vector<Key> keys = dialog->keys();
262  assert( !keys.empty() );
263 
264  std::vector<Key>::iterator
265  pgpBegin = keys.begin(),
266  pgpEnd = std::stable_partition( pgpBegin, keys.end(),
267  boost::bind( &GpgME::Key::protocol, _1 ) != CMS ),
268  cmsBegin = pgpEnd,
269  cmsEnd = keys.end() ;
270 
271  std::vector<Key> openpgp( pgpBegin, pgpEnd );
272  std::vector<Key> cms( cmsBegin, cmsEnd );
273 
274  const unsigned int errorCase =
275  openpgp.empty() << 3U | canDelete( OpenPGP ) << 2U |
276  cms.empty() << 1U | canDelete( CMS ) << 0U ;
277 
278  if ( const unsigned int actions = deletionErrorCases[errorCase].actions ) {
279  information( i18n( deletionErrorCases[errorCase].text ),
280  (actions & Failure)
281  ? i18n( "Certificate Deletion Failed" )
282  : i18n( "Certificate Deletion Problem" ) );
283  if ( actions & ClearCMS )
284  cms.clear();
285  if ( actions & ClearPGP )
286  openpgp.clear();
287  if ( actions & Failure ) {
288  canceled();
289  return;
290  }
291  }
292 
293  assert( !openpgp.empty() || !cms.empty() );
294 
295  pgpKeys.swap( openpgp );
296  cmsKeys.swap( cms );
297 
298  if ( !pgpKeys.empty() )
299  startDeleteJob( GpgME::OpenPGP );
300  if ( !cmsKeys.empty() )
301  startDeleteJob( GpgME::CMS );
302 
303  if ( ( pgpKeys.empty() || pgpError.code() ) &&
304  ( cmsKeys.empty() || cmsError.code() ) )
305  showErrorsAndFinish();
306 }
307 
308 void DeleteCertificatesCommand::Private::startDeleteJob( GpgME::Protocol protocol ) {
309  assert( protocol != GpgME::UnknownProtocol );
310 
311  const std::vector<Key> & keys = protocol == CMS ? cmsKeys : pgpKeys ;
312 
313  const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( protocol );
314  assert( backend );
315 
316  std::auto_ptr<MultiDeleteJob> job( new MultiDeleteJob( backend ) );
317 
318  if ( protocol == CMS )
319  connect( job.get(), SIGNAL(result(GpgME::Error,GpgME::Key)),
320  q_func(), SLOT(cmsDeleteResult(GpgME::Error)) );
321  else
322  connect( job.get(), SIGNAL(result(GpgME::Error,GpgME::Key)),
323  q_func(), SLOT(pgpDeleteResult(GpgME::Error)) );
324 
325  connect( job.get(), SIGNAL(progress(QString,int,int)),
326  q, SIGNAL(progress(QString,int,int)) );
327 
328  if ( const Error err = job->start( keys, true /*allowSecretKeyDeletion*/ ) )
329  ( protocol == CMS ? cmsError : pgpError ) = err;
330  else
331  ( protocol == CMS ? cmsJob : pgpJob ) = job.release();
332 }
333 
334 void DeleteCertificatesCommand::Private::showErrorsAndFinish() {
335 
336  assert( !pgpJob ); assert( !cmsJob );
337 
338  if ( pgpError || cmsError ) {
339  QString pgpErrorString;
340  if ( pgpError )
341  pgpErrorString = i18n( "OpenPGP backend: %1", QString::fromLocal8Bit( pgpError.asString() ) );
342  QString cmsErrorString;
343  if ( cmsError )
344  cmsErrorString = i18n( "CMS backend: %1", QString::fromLocal8Bit( cmsError.asString() ) );
345 
346  const QString msg = i18n("<qt><p>An error occurred while trying to delete "
347  "the certificate:</p>"
348  "<p><b>%1</b></p></qt>",
349  pgpError ? cmsError ? pgpErrorString + QLatin1String("</br>") + cmsErrorString : pgpErrorString : cmsErrorString );
350  error( msg, i18n("Certificate Deletion Failed") );
351  } else {
352  std::vector<Key> keys = pgpKeys;
353  keys.insert( keys.end(), cmsKeys.begin(), cmsKeys.end() );
354  KeyCache::mutableInstance()->remove( keys );
355  }
356 
357  finished();
358 }
359 
360 void DeleteCertificatesCommand::doCancel() {
361  d->cancelJobs();
362 }
363 
364 void DeleteCertificatesCommand::Private::pgpDeleteResult( const Error & err ) {
365  pgpError = err;
366  pgpJob = 0;
367  if ( !cmsJob )
368  showErrorsAndFinish();
369 }
370 
371 void DeleteCertificatesCommand::Private::cmsDeleteResult( const Error & err ) {
372  cmsError = err;
373  cmsJob = 0;
374  if ( !pgpJob )
375  showErrorsAndFinish();
376 }
377 
378 void DeleteCertificatesCommand::Private::cancelJobs()
379 {
380  if ( cmsJob )
381  cmsJob->slotCancel();
382  if ( pgpJob )
383  pgpJob->slotCancel();
384 }
385 
386 #undef d
387 #undef q
388 
389 #include "moc_deletecertificatescommand.cpp"
Kleo::DeleteCertificatesCommand::DeleteCertificatesCommand
DeleteCertificatesCommand(QAbstractItemView *view, KeyListController *parent)
Definition: deletecertificatescommand.cpp:141
Action
Action
Definition: deletecertificatescommand.cpp:151
QAbstractItemView
Kleo::Command::Private
Definition: commands/command_p.h:52
Kleo::KeyListController
Definition: keylistcontroller.h:55
deletecertificatescommand.h
QPointer< DeleteCertificatesDialog >
Kleo::Command::d
kdtools::pimpl_ptr< Private > d
Definition: commands/command.h:129
q
#define q
Definition: deletecertificatescommand.cpp:124
QString::fromLocal8Bit
QString fromLocal8Bit(const char *str, int size)
Kleo::Class::OpenPGP
Definition: classify.h:49
Kleo::Class::CMS
Definition: classify.h:48
QString
deletecertificatesdialog.h
command_p.h
Kleo::Dialogs::DeleteCertificatesDialog
Definition: deletecertificatesdialog.h:49
QLatin1String
predicates.h
Kleo::KeyCache::instance
static boost::shared_ptr< const KeyCache > instance()
Definition: keycache.cpp:190
Kleo::DeleteCertificatesCommand::~DeleteCertificatesCommand
~DeleteCertificatesCommand()
Definition: deletecertificatescommand.cpp:147
keycache.h
d
#define d
Definition: deletecertificatescommand.cpp:123
Kleo::DeleteCertificatesCommand
Definition: deletecertificatescommand.h:39
Kleo::Command
Definition: commands/command.h:58
Kleo::KeyCache::mutableInstance
static boost::shared_ptr< KeyCache > mutableInstance()
Definition: keycache.cpp:194
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