• 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
  • dialogs
certificatedetailsdialog.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  dialogs/certificatedetailsdialog.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 "certificatedetailsdialog.h"
36 
37 #include "ui_certificatedetailsdialog.h"
38 
39 #include <models/useridlistmodel.h>
40 #include <models/subkeylistmodel.h>
41 #include <models/keycache.h>
42 
43 #include <commands/changepassphrasecommand.h>
44 #include <commands/changeownertrustcommand.h>
45 #include <commands/changeexpirycommand.h>
46 #include <commands/adduseridcommand.h>
47 #include <commands/certifycertificatecommand.h>
48 #include <commands/dumpcertificatecommand.h>
49 
50 #include <utils/formatting.h>
51 #include <utils/gnupg-helper.h>
52 
53 #include <kleo/cryptobackendfactory.h>
54 #include <kleo/cryptobackend.h>
55 #include <kleo/keylistjob.h>
56 #include <kleo/dn.h>
57 
58 #include <gpgme++/key.h>
59 #include <gpgme++/keylistresult.h>
60 
61 #include <KDebug>
62 #include <KMessageBox>
63 #include <KLocalizedString>
64 #include <KGlobalSettings>
65 
66 #include <QPointer>
67 #include <QHeaderView>
68 
69 #include <boost/mem_fn.hpp>
70 
71 #include <algorithm>
72 #include <cassert>
73 
74 using namespace Kleo;
75 using namespace Kleo::Dialogs;
76 using namespace Kleo::Commands;
77 using namespace GpgME;
78 using namespace boost;
79 
80 static bool own( const std::vector<UserID::Signature> & sigs ) {
81  const shared_ptr<const KeyCache> kc = KeyCache::instance();
82  Q_FOREACH( const UserID::Signature & sig, sigs ) {
83  const Key signer = kc->findByKeyIDOrFingerprint( sig.signerKeyID() );
84  if ( signer.isNull() || !signer.hasSecret() )
85  return false;
86  }
87  return !sigs.empty();
88 }
89 
90 class CertificateDetailsDialog::Private {
91  friend class ::Kleo::Dialogs::CertificateDetailsDialog;
92  CertificateDetailsDialog * const q;
93 public:
94  explicit Private( CertificateDetailsDialog * qq )
95  : q( qq ),
96  key(),
97  certificationsModel(),
98  subkeysModel(),
99  ui( q )
100  {
101  ui.certificationsTV->setModel( &certificationsModel );
102  connect( ui.certificationsTV->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
103  q, SLOT(slotCertificationSelectionChanged()) );
104  connect( ui.changePassphrasePB, SIGNAL(clicked()),
105  q, SLOT(slotChangePassphraseClicked()) );
106  connect( ui.changeTrustLevelPB, SIGNAL(clicked()),
107  q, SLOT(slotChangeTrustLevelClicked()) );
108  connect( ui.changeExpiryDatePB, SIGNAL(clicked()),
109  q, SLOT(slotChangeExpiryDateClicked()) );
110  connect( ui.revokeCertificationPB, SIGNAL(clicked()),
111  q, SLOT(slotRevokeCertificationClicked()) );
112  connect( ui.addUserIDPB, SIGNAL(clicked()),
113  q, SLOT(slotAddUserIDClicked()) );
114  connect( ui.revokeUserIDPB, SIGNAL(clicked()),
115  q, SLOT(slotRevokeUserIDClicked()) );
116  connect( ui.certifyUserIDPB, SIGNAL(clicked()),
117  q, SLOT(slotCertifyUserIDClicked()) );
118  connect( ui.revokeCertificationPB, SIGNAL(clicked()),
119  q, SLOT(slotRevokeCertificationClicked()) );
120  connect( ui.showCertificationsPB, SIGNAL(clicked()),
121  q, SLOT(slotShowCertificationsClicked()) );
122 
123 
124  ui.subkeyTV->setModel( &subkeysModel );
125  // no selection (yet)
126 
127  connect( KeyCache::instance().get(), SIGNAL(keysMayHaveChanged()),
128  q, SLOT(slotKeysMayHaveChanged()) );
129  }
130 
131 private:
132  void startCommandImplementation( const QPointer<Command> & ptr, const char * slot ) {
133  connect( ptr, SIGNAL(finished()), q, slot );
134  ptr->start();
135  enableDisableWidgets();
136  }
137  template <typename T, typename A>
138  void startCommand( QPointer<Command> & ptr, const A & arg, const char * slot ) {
139  if ( ptr )
140  return;
141  ptr = new T( arg );
142  startCommandImplementation( ptr, slot );
143  }
144  template <typename T>
145  void startCommand( QPointer<Command> & ptr, const char * slot ) {
146  startCommand<T>( ptr, this->key, slot );
147  }
148  void commandFinished( QPointer<Command> & ptr ) {
149  ptr = 0;
150  enableDisableWidgets();
151  }
152 
153  void slotChangePassphraseClicked() {
154  startCommand<ChangePassphraseCommand>( changePassphraseCommand, SLOT(slotChangePassphraseCommandFinished()) );
155  }
156  void slotChangePassphraseCommandFinished() {
157  commandFinished( changePassphraseCommand );
158  }
159 
160  void slotChangeTrustLevelClicked() {
161  startCommand<ChangeOwnerTrustCommand>( changeOwnerTrustCommand, SLOT(slotChangeOwnerTrustCommandFinished()) );
162  }
163  void slotChangeOwnerTrustCommandFinished() {
164  commandFinished( changeOwnerTrustCommand );
165  }
166 
167  void slotChangeExpiryDateClicked() {
168  startCommand<ChangeExpiryCommand>( changeExpiryDateCommand, SLOT(slotChangeExpiryDateCommandFinished()) );
169  }
170  void slotChangeExpiryDateCommandFinished() {
171  commandFinished( changeExpiryDateCommand );
172  }
173 
174  void slotAddUserIDClicked() {
175  startCommand<AddUserIDCommand>( addUserIDCommand, SLOT(slotAddUserIDCommandFinished()) );
176  }
177  void slotAddUserIDCommandFinished() {
178  commandFinished( addUserIDCommand );
179  }
180 
181  void slotCertifyUserIDClicked() {
182  const std::vector<UserID> uids = selectedUserIDs();
183  if ( uids.empty() )
184  return;
185  startCommand<CertifyCertificateCommand>( signCertificateCommand, uids, SLOT(slotSignCertificateCommandFinished()) );
186  }
187  void slotSignCertificateCommandFinished() {
188  commandFinished( signCertificateCommand );
189  }
190 
191  void slotRevokeCertificateClicked() {
192 
193  }
194 
195  void slotRevokeUserIDClicked() {
196 
197  }
198 
199  void slotRevokeCertificationClicked() {
200 
201  }
202 
203  void slotShowCertificationsClicked() {
204  startSignatureListing();
205  enableDisableWidgets();
206  }
207 
208  void startSignatureListing() {
209  if ( keyListJob )
210  return;
211  const CryptoBackend::Protocol * const protocol = CryptoBackendFactory::instance()->protocol( key.protocol() );
212  if ( !protocol )
213  return;
214  KeyListJob * const job = protocol->keyListJob( /*remote*/false, /*includeSigs*/true, /*validate*/true );
215  if ( !job )
216  return;
217  connect( job, SIGNAL(result(GpgME::KeyListResult)),
218  q, SLOT(slotSignatureListingDone(GpgME::KeyListResult)) );
219  connect( job, SIGNAL(nextKey(GpgME::Key)),
220  q, SLOT(slotSignatureListingNextKey(GpgME::Key)) );
221  if ( const Error err = job->start( QStringList( QString::fromLatin1( key.primaryFingerprint() ) ) ) )
222  showSignatureListingErrorDialog( err );
223  else
224  keyListJob = job;
225  }
226  void slotSignatureListingNextKey( const Key & key ) {
227  // don't lose the secret flags ...
228  Key merged = key;
229  merged.mergeWith( this->key );
230  q->setKey( merged );
231 
232  // fixup the tree view
233  ui.certificationsTV->expandAll();
234  ui.certificationsTV->header()->resizeSections( QHeaderView::ResizeToContents );
235  }
236  void slotSignatureListingDone( const KeyListResult & result ) {
237  if ( result.error().isCanceled() )
238  ;
239  else if ( result.error() )
240  showSignatureListingErrorDialog( result.error() );
241  else {
242  ; // nothing to do
243  }
244  keyListJob = 0;
245  enableDisableWidgets();
246  }
247  void showSignatureListingErrorDialog( const Error & err ) {
248  KMessageBox::information( q, i18nc("@info",
249  "<para>An error occurred while loading the certifications: "
250  "<message>%1</message></para>",
251  QString::fromLocal8Bit( err.asString() ) ),
252  i18nc("@title","Certifications Loading Failed") );
253  }
254 
255  void slotCertificationSelectionChanged() {
256  enableDisableWidgets();
257  }
258 
259  void slotKeysMayHaveChanged() {
260  if ( const char * const fpr = key.primaryFingerprint() )
261  if ( !(key.keyListMode() & Extern) )
262  q->setKey( KeyCache::instance()->findByFingerprint( fpr ) );
263  }
264 
265  void slotDumpCertificate() {
266 
267  if ( dumpCertificateCommand )
268  return;
269 
270  if ( key.protocol() != CMS ) {
271  ui.dumpLTW->clear();
272  return;
273  }
274 
275  ui.dumpLTW->setLines( QStringList( i18n("Please wait while generating the dump...") ) );
276 
277  dumpCertificateCommand = new DumpCertificateCommand( key );
278  dumpCertificateCommand->setUseDialog( false );
279  QPointer<Command> cmd = dumpCertificateCommand.data();
280  startCommandImplementation( cmd, SLOT(slotDumpCertificateCommandFinished()) );
281  }
282 
283  void slotDumpCertificateCommandFinished() {
284  ui.dumpLTW->setLines( dumpCertificateCommand->output() );
285  }
286 
287 private:
288  void updateWidgetVisibility() {
289  const bool x509 = key.protocol() == CMS;
290  const bool pgp = key.protocol() == OpenPGP;
291  const bool secret = key.hasSecret();
292  const bool sigs = (key.keyListMode() & Signatures);
293  const bool ultimateTrust = key.ownerTrust() == Key::Ultimate;
294  const bool external = (key.keyListMode() & Extern);
295 
296  // Overview Tab
297  ui.overviewActionsGB->setVisible( !external );
298  ui.changePassphrasePB->setVisible( secret );
299  ui.changeTrustLevelPB->setVisible( pgp && ( !secret || !ultimateTrust ) );
300  ui.changeExpiryDatePB->setVisible( pgp && secret );
301 
302  // Certifications Tab
303  ui.userIDsActionsGB->setVisible( !external && pgp );
304  ui.certificationsActionGB->setVisible( !external && pgp );
305  ui.addUserIDPB->setVisible( secret );
306  ui.expandAllCertificationsPB->setVisible( pgp && sigs );
307  ui.collapseAllCertificationsPB->setVisible( pgp && sigs );
308  ui.showCertificationsPB->setVisible( !external && pgp && !sigs );
309 
310  // Technical Details Tab
311  ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.detailsTab ), pgp );
312 
313  // Chain tab
314  ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.chainTab ), x509 );
315 
316  // Dump tab
317  ui.tabWidget->setTabEnabled( ui.tabWidget->indexOf( ui.dumpTab ), x509 );
318 
319  // not implemented:
320  ui.revokeCertificatePB->hide();
321  ui.revokeUserIDPB->hide();
322  ui.certificationsActionGB->hide();
323  }
324 
325  QModelIndexList selectedCertificationsIndexes() const {
326  return ui.certificationsTV->selectionModel()->selectedRows();
327  }
328 
329  std::vector<UserID> selectedUserIDs() const {
330  const QModelIndexList mil = selectedCertificationsIndexes();
331  std::vector<UserID> uids = certificationsModel.userIDs( mil, true );
332  uids.erase( std::remove_if( uids.begin(), uids.end(), mem_fn( &UserID::isNull ) ), uids.end() );
333  return uids;
334  }
335 
336  std::vector<UserID::Signature> selectedSignatures() const {
337  const QModelIndexList mil = selectedCertificationsIndexes();
338  std::vector<UserID::Signature> sigs = certificationsModel.signatures( mil );
339  sigs.erase( std::remove_if( sigs.begin(), sigs.end(), mem_fn( &UserID::Signature::isNull ) ), sigs.end() );
340  return sigs;
341  }
342 
343  void enableDisableWidgets() {
344  // Overview Tab
345  ui.changePassphrasePB->setEnabled( !changePassphraseCommand );
346  ui.changeTrustLevelPB->setEnabled( !changeOwnerTrustCommand );
347  ui.changeExpiryDatePB->setEnabled( !changeExpiryDateCommand );
348 
349  // Certifications Tab
350  ui.addUserIDPB->setEnabled( !addUserIDCommand );
351  ui.showCertificationsPB->setEnabled( !keyListJob );
352  ui.showCertificationsPB->setText( keyListJob
353  ? i18n("(please wait while certifications are being loaded)")
354  : i18n("Load Certifications (may take a while)") );
355 
356  const std::vector<UserID> uids = selectedUserIDs();
357  const std::vector<UserID::Signature> sigs = selectedSignatures();
358 
359  ui.certifyUserIDPB->setEnabled( !uids.empty() && sigs.empty() && !signCertificateCommand );
360  ui.revokeUserIDPB->setEnabled( !uids.empty() && sigs.empty() );
361  ui.revokeCertificationPB->setEnabled( uids.empty() && !sigs.empty() && own( sigs ) );
362  }
363 
364  void updateLabel() {
365  ui.overviewLB->setText( Formatting::formatOverview( key ) );
366  }
367 
368  void updateChainTab() {
369  ui.chainTW->clear();
370 
371  if ( key.protocol() != CMS )
372  return;
373 
374  QTreeWidgetItem * last = 0;
375  const std::vector<Key> chain = KeyCache::instance()->findIssuers( key, KeyCache::RecursiveSearch|KeyCache::IncludeSubject );
376  if ( chain.empty() )
377  return;
378  if ( !chain.back().isRoot() ) {
379  last = new QTreeWidgetItem( ui.chainTW );
380  last->setText( 0, i18n("Issuer Certificate Not Found (%1)",
381  DN( chain.back().issuerName() ).prettyDN() ) );
382  //last->setSelectable( false );
383  const QBrush & fg = ui.chainTW->palette().brush( QPalette::Disabled, QPalette::WindowText );
384  last->setForeground( 0, fg );
385  }
386  for ( std::vector<Key>::const_reverse_iterator it = chain.rbegin(), end = chain.rend() ; it != end ; ++it ) {
387  last = last ? new QTreeWidgetItem( last ) : new QTreeWidgetItem( ui.chainTW ) ;
388  last->setText( 0, DN( it->userID(0).id() ).prettyDN() );
389  //last->setSelectable( true );
390  }
391  ui.chainTW->expandAll();
392  }
393 
394  void propagateKey() {
395  certificationsModel.setKey( key );
396  const QModelIndexList uidIndexes = certificationsModel.indexes( key.userIDs() );
397  Q_FOREACH( const QModelIndex & idx, uidIndexes )
398  ui.certificationsTV->setFirstColumnSpanned( idx.row(), idx.parent(), true );
399 
400  subkeysModel.setKey( key );
401  ui.subkeyTV->header()->resizeSections( QHeaderView::ResizeToContents );
402 
403  updateChainTab();
404  slotDumpCertificate();
405  }
406 
407 
408 private:
409  Key key;
410  UserIDListModel certificationsModel;
411  SubkeyListModel subkeysModel;
412 
413  QPointer<Command> changePassphraseCommand;
414  QPointer<Command> changeOwnerTrustCommand;
415  QPointer<Command> changeExpiryDateCommand;
416 
417  QPointer<Command> addUserIDCommand;
418  QPointer<Command> signCertificateCommand;
419 
420  QPointer<DumpCertificateCommand> dumpCertificateCommand;
421 
422  QPointer<KeyListJob> keyListJob;
423 
424  struct UI : public Ui_CertificateDetailsDialog {
425  explicit UI( Dialogs::CertificateDetailsDialog * qq )
426  : Ui_CertificateDetailsDialog()
427  {
428  setupUi( qq->mainWidget() );
429  qq->setButtons( KDialog::Help | KDialog::Close );
430  qq->setHelp(QString(), QLatin1String("kleopatra"));
431  chainTW->header()->setResizeMode( 0, QHeaderView::Stretch );
432 
433  dumpLTW->setFont( KGlobalSettings::fixedFont() );
434  dumpLTW->setMinimumVisibleLines( 15 );
435  dumpLTW->setMinimumVisibleColumns( 40 );
436 
437  subkeyHLine->setTitle( i18nc("@title","Subkeys") );
438  }
439  } ui;
440 };
441 
442 CertificateDetailsDialog::CertificateDetailsDialog( QWidget * p, Qt::WindowFlags f )
443  : KDialog( p, f ), d( new Private( this ) )
444 {
445 
446 }
447 
448 CertificateDetailsDialog::~CertificateDetailsDialog() {}
449 
450 
451 void CertificateDetailsDialog::setKey( const Key & key ) {
452  d->key = key;
453  d->updateWidgetVisibility();
454  d->updateLabel();
455  d->propagateKey();
456  d->enableDisableWidgets();
457 }
458 
459 Key CertificateDetailsDialog::key() const {
460  return d->key;
461 }
462 
463 
464 #include "moc_certificatedetailsdialog.cpp"
Kleo::Dialogs::CertificateDetailsDialog::setKey
void setKey(const GpgME::Key &key)
Definition: certificatedetailsdialog.cpp:451
Kleo::Dialogs::CertificateDetailsDialog::CertificateDetailsDialog
CertificateDetailsDialog(QWidget *parent=0, Qt::WindowFlags f=0)
Definition: certificatedetailsdialog.cpp:442
adduseridcommand.h
useridlistmodel.h
Kleo::Formatting::formatOverview
QString formatOverview(const GpgME::Key &key)
QWidget
formatting.h
KDialog
Kleo::KeyCache::RecursiveSearch
Definition: keycache.h:121
boost::shared_ptr
Definition: encryptemailcontroller.h:51
d
#define d
Definition: adduseridcommand.cpp:90
own
static bool own(const std::vector< UserID::Signature > &sigs)
Definition: certificatedetailsdialog.cpp:80
Kleo::SubkeyListModel
Definition: subkeylistmodel.h:48
Kleo::Dialogs::CertificateDetailsDialog::~CertificateDetailsDialog
~CertificateDetailsDialog()
Definition: certificatedetailsdialog.cpp:448
Kleo::Class::OpenPGP
Definition: classify.h:49
changeownertrustcommand.h
Kleo::Class::CMS
Definition: classify.h:48
subkeylistmodel.h
gnupg-helper.h
Kleo::KeyCache::IncludeSubject
Definition: keycache.h:122
dumpcertificatecommand.h
Kleo::UserIDListModel
Definition: useridlistmodel.h:45
q
#define q
Definition: adduseridcommand.cpp:91
Kleo::KeyCache::instance
static boost::shared_ptr< const KeyCache > instance()
Definition: keycache.cpp:189
certifycertificatecommand.h
certificatedetailsdialog.h
Kleo::Commands::DumpCertificateCommand
Definition: dumpcertificatecommand.h:41
keycache.h
changeexpirycommand.h
Kleo::Command
Definition: commands/command.h:58
Kleo::Dialogs::CertificateDetailsDialog::key
GpgME::Key key() const
Definition: certificatedetailsdialog.cpp:459
Kleo::Dialogs::CertificateDetailsDialog
Definition: certificatedetailsdialog.h:49
slot
const char * slot
Definition: keytreeview.cpp:360
QHeaderView
changepassphrasecommand.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:40 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