• 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
  • commands
lookupcertificatescommand.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  commands/lookupcertificatescommand.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2008, 2009 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 "lookupcertificatescommand.h"
36 
37 #include "importcertificatescommand_p.h"
38 
39 #include "detailscommand.h"
40 
41 #include <dialogs/lookupcertificatesdialog.h>
42 
43 #include <utils/formatting.h>
44 
45 #include <kleo/stl_util.h>
46 #include <kleo/importfromkeyserverjob.h>
47 #include <kleo/keylistjob.h>
48 #include <kleo/cryptobackendfactory.h>
49 #include <kleo/cryptobackend.h>
50 #include <kleo/cryptoconfig.h>
51 
52 #include <gpgme++/key.h>
53 #include <gpgme++/keylistresult.h>
54 #include <gpgme++/importresult.h>
55 
56 #include <KLocale>
57 #include <KMessageBox>
58 #include <kdebug.h>
59 
60 #include <QBuffer>
61 #include <QRegExp>
62 #include <QLineEdit>
63 
64 #include <boost/bind.hpp>
65 #include <boost/shared_ptr.hpp>
66 
67 #include <vector>
68 #include <map>
69 #include <algorithm>
70 #include <cassert>
71 
72 using namespace Kleo;
73 using namespace Kleo::Commands;
74 using namespace Kleo::Dialogs;
75 using namespace GpgME;
76 using namespace boost;
77 
78 class LookupCertificatesCommand::Private : public ImportCertificatesCommand::Private {
79  friend class ::Kleo::Commands::LookupCertificatesCommand;
80  LookupCertificatesCommand * q_func() const { return static_cast<LookupCertificatesCommand*>( q ); }
81 public:
82  explicit Private( LookupCertificatesCommand * qq, KeyListController * c );
83  ~Private();
84 
85  QString fingerPrint;
86  void init();
87 
88 private:
89  void slotSearchTextChanged( const QString & str );
90  void slotNextKey( const Key & key ) {
91  keyListing.keys.push_back( key );
92  }
93  void slotKeyListResult( const KeyListResult & result );
94  void slotImportRequested( const std::vector<Key> & keys );
95  void slotDetailsRequested( const Key & key );
96  void slotSaveAsRequested( const std::vector<Key> & keys );
97  void slotDialogRejected() {
98  canceled();
99  }
100 
101 private:
102  using ImportCertificatesCommand::Private::showError;
103  void showError( QWidget * parent, const KeyListResult & result );
104  void showResult( QWidget * parent, const KeyListResult & result );
105  void createDialog();
106  KeyListJob * createKeyListJob( GpgME::Protocol proto ) const {
107  const CryptoBackend::Protocol * const cbp = CryptoBackendFactory::instance()->protocol( proto );
108  return cbp ? cbp->keyListJob( true ) : 0 ;
109  }
110  ImportFromKeyserverJob * createImportJob( GpgME::Protocol proto ) const {
111  const CryptoBackend::Protocol * const cbp = CryptoBackendFactory::instance()->protocol( proto );
112  return cbp ? cbp->importFromKeyserverJob() : 0 ;
113  }
114  void startKeyListJob( GpgME::Protocol proto, const QString & str );
115  bool checkConfig() const;
116 
117  QWidget * dialogOrParentWidgetOrView() const { if ( dialog ) return dialog; else return parentWidgetOrView(); }
118 
119 private:
120  QPointer<LookupCertificatesDialog> dialog;
121  struct KeyListingVariables {
122  QPointer<KeyListJob> cms, openpgp;
123  KeyListResult result;
124  std::vector<Key> keys;
125 
126  void reset() { *this = KeyListingVariables(); }
127  } keyListing;
128 };
129 
130 
131 LookupCertificatesCommand::Private * LookupCertificatesCommand::d_func() { return static_cast<Private*>( d.get() ); }
132 const LookupCertificatesCommand::Private * LookupCertificatesCommand::d_func() const { return static_cast<const Private*>( d.get() ); }
133 
134 #define d d_func()
135 #define q q_func()
136 
137 LookupCertificatesCommand::Private::Private( LookupCertificatesCommand * qq, KeyListController * c )
138  : ImportCertificatesCommand::Private( qq, c ),
139  dialog()
140 {
141 
142 }
143 
144 LookupCertificatesCommand::Private::~Private() {
145  kDebug();
146  delete dialog;
147 }
148 
149 LookupCertificatesCommand::LookupCertificatesCommand( KeyListController * c )
150  : ImportCertificatesCommand( new Private( this, c ) )
151 {
152  d->init();
153 }
154 
155 LookupCertificatesCommand::LookupCertificatesCommand( const QString & fingerPrint, KeyListController * c )
156  : ImportCertificatesCommand( new Private( this, c ) )
157 {
158  d->init();
159  d->fingerPrint = fingerPrint;
160 }
161 
162 LookupCertificatesCommand::LookupCertificatesCommand( QAbstractItemView * v, KeyListController * c )
163  : ImportCertificatesCommand( v, new Private( this, c ) )
164 {
165  d->init();
166 }
167 
168 void LookupCertificatesCommand::Private::init() {
169 
170 }
171 
172 LookupCertificatesCommand::~LookupCertificatesCommand() { kDebug(); }
173 
174 
175 void LookupCertificatesCommand::doStart() {
176 
177  if ( !d->checkConfig() ) {
178  d->finished();
179  return;
180  }
181 
182  d->createDialog();
183  assert( d->dialog );
184 
185  // if have prespecified fingerPrint, load into find field
186  // and start search
187  if ( ! d->fingerPrint.isEmpty() ) {
188  if ( !d->fingerPrint.startsWith( QLatin1String("0x") ) )
189  d->fingerPrint = QLatin1String("0x") + d->fingerPrint;
190  d->dialog->setSearchText( d->fingerPrint );
191  // Start Search
192  d->slotSearchTextChanged( d->fingerPrint );
193  }
194 
195  d->dialog->setPassive( false );
196  d->dialog->show();
197 
198 }
199 
200 void LookupCertificatesCommand::Private::createDialog() {
201  if ( dialog )
202  return;
203  dialog = new LookupCertificatesDialog;
204  applyWindowID( dialog );
205  dialog->setAttribute( Qt::WA_DeleteOnClose );
206  connect( dialog, SIGNAL(searchTextChanged(QString)),
207  q, SLOT(slotSearchTextChanged(QString)) );
208  connect( dialog, SIGNAL(saveAsRequested(std::vector<GpgME::Key>)),
209  q, SLOT(slotSaveAsRequested(std::vector<GpgME::Key>)) );
210  connect( dialog, SIGNAL(importRequested(std::vector<GpgME::Key>)),
211  q, SLOT(slotImportRequested(std::vector<GpgME::Key>)) );
212  connect( dialog, SIGNAL(detailsRequested(GpgME::Key)),
213  q, SLOT(slotDetailsRequested(GpgME::Key)) );
214  connect( dialog, SIGNAL(rejected()),
215  q, SLOT(slotDialogRejected()) );
216 }
217 
218 void LookupCertificatesCommand::Private::slotSearchTextChanged( const QString & str ) {
219  // pressing return might trigger both search and dialog destruction (search focused and default key set)
220  // On Windows, the dialog is then destroyed before this slot is called
221  if ( dialog ) { //thus test
222  dialog->setPassive( true );
223  dialog->setCertificates( std::vector<Key>() );
224  }
225 
226  const QRegExp rx( QLatin1String( "(?:0x|0X)?[0-9a-fA-F]{6,}" ) );
227  if ( rx.exactMatch( str ) )
228  information( str.startsWith( QLatin1String( "0x" ), Qt::CaseInsensitive )
229  ? i18n("<p>You seem to be searching for a fingerPrint or a key-id.</p>"
230  "<p>Different keyservers expect different ways to search for these. "
231  "Some require a \"0x\" prefix, while others require there be no such prefix.</p>"
232  "<p>If your search does not yield any results, try removing the 0x prefix from your search.</p>")
233  : i18n("<p>You seem to be searching for a fingerPrint or a key-id.</p>"
234  "<p>Different keyservers expect different ways to search for these. "
235  "Some require a \"0x\" prefix, while others require there be no such prefix.</p>"
236  "<p>If your search does not yield any results, try adding the 0x prefix to your search.</p>"),
237  i18n("Hex-String Search"),
238  QLatin1String( "lookup-certificates-warn-0x-prefix" ) );
239 
240  startKeyListJob( CMS, str );
241  startKeyListJob( OpenPGP, str );
242 
243 }
244 
245 void LookupCertificatesCommand::Private::startKeyListJob( GpgME::Protocol proto, const QString & str ) {
246  KeyListJob * const klj = createKeyListJob( proto );
247  if ( !klj )
248  return;
249  connect( klj, SIGNAL(result(GpgME::KeyListResult)),
250  q, SLOT(slotKeyListResult(GpgME::KeyListResult)) );
251  connect( klj, SIGNAL(nextKey(GpgME::Key)),
252  q, SLOT(slotNextKey(GpgME::Key)) );
253  if ( const Error err = klj->start( QStringList( str ) ) )
254  keyListing.result.mergeWith( KeyListResult( err ) );
255  else
256  if ( proto == CMS )
257  keyListing.cms = klj;
258  else
259  keyListing.openpgp = klj;
260 }
261 
262 void LookupCertificatesCommand::Private::slotKeyListResult( const KeyListResult & r ) {
263 
264  if ( q->sender() == keyListing.cms )
265  keyListing.cms = 0;
266  else if ( q->sender() == keyListing.openpgp )
267  keyListing.openpgp = 0;
268  else
269  kDebug() << "unknown sender()" << q->sender();
270 
271  keyListing.result.mergeWith( r );
272  if ( keyListing.cms || keyListing.openpgp ) // still waiting for jobs to complete
273  return;
274 
275  if ( keyListing.result.error() && !keyListing.result.error().isCanceled() )
276  showError( dialog, keyListing.result );
277 
278  if ( keyListing.result.isTruncated() )
279  showResult( dialog, keyListing.result );
280 
281  if ( dialog ) {
282  dialog->setPassive( false );
283  dialog->setCertificates( keyListing.keys );
284  } else {
285  finished();
286  }
287 
288 
289  keyListing.reset();
290 }
291 
292 void LookupCertificatesCommand::Private::slotImportRequested( const std::vector<Key> & keys ) {
293  dialog = 0;
294 
295  assert( !keys.empty() );
296  assert( kdtools::none_of( keys, mem_fn( &Key::isNull ) ) );
297 
298  std::vector<Key> pgp, cms;
299  pgp.reserve( keys.size() );
300  cms.reserve( keys.size() );
301  kdtools::separate_if( keys.begin(), keys.end(),
302  std::back_inserter( pgp ),
303  std::back_inserter( cms ),
304  boost::bind( &Key::protocol, _1 ) == OpenPGP );
305 
306  setWaitForMoreJobs( true );
307  if ( !pgp.empty() )
308  startImport( OpenPGP, pgp,
309  i18nc("@title %1:\"OpenPGP\" or \"CMS\"",
310  "%1 Certificate Server",
311  Formatting::displayName( OpenPGP ) ) );
312  if ( !cms.empty() )
313  startImport( CMS, cms,
314  i18nc("@title %1:\"OpenPGP\" or \"CMS\"",
315  "%1 Certificate Server",
316  Formatting::displayName( CMS ) ) );
317  setWaitForMoreJobs( false );
318 }
319 
320 
321 void LookupCertificatesCommand::Private::slotSaveAsRequested( const std::vector<Key> & keys ) {
322  Q_UNUSED( keys );
323  kDebug() << "not implemented";
324 }
325 
326 void LookupCertificatesCommand::Private::slotDetailsRequested( const Key & key ) {
327  Command * const cmd = new DetailsCommand( key, view(), controller() );
328  cmd->setParentWidget( dialogOrParentWidgetOrView() );
329  cmd->start();
330 }
331 
332 void LookupCertificatesCommand::doCancel() {
333  ImportCertificatesCommand::doCancel();
334  if ( QDialog * const dlg = d->dialog ) {
335  d->dialog = 0;
336  dlg->close();
337  }
338 }
339 
340 void LookupCertificatesCommand::Private::showError( QWidget * parent, const KeyListResult & result ) {
341  if ( !result.error() )
342  return;
343  KMessageBox::information( parent, i18nc( "@info",
344  "Failed to search on certificate server. The error returned was:\n%1",
345  QString::fromLocal8Bit( result.error().asString() ) ) );
346 }
347 
348 void LookupCertificatesCommand::Private::showResult( QWidget * parent, const KeyListResult & result ) {
349  if ( result.isTruncated() )
350  KMessageBox::information( parent,
351  i18nc("@info",
352  "<para>The query result has been truncated.</para>"
353  "<para>Either the local or a remote limit on "
354  "the maximum number of returned hits has "
355  "been exceeded.</para>"
356  "<para>You can try to increase the local limit "
357  "in the configuration dialog, but if one "
358  "of the configured servers is the limiting "
359  "factor, you have to refine your search.</para>"),
360  i18nc("@title", "Result Truncated"),
361  QLatin1String("lookup-certificates-truncated-result") );
362 }
363 
364 static bool haveOpenPGPKeyserverConfigured() {
365  const Kleo::CryptoConfig * const config = Kleo::CryptoBackendFactory::instance()->config();
366  if ( !config )
367  return false;
368  const Kleo::CryptoConfigEntry * const entry = config->entry( QLatin1String("gpg"), QLatin1String("Keyserver"), QLatin1String("keyserver") );
369  return entry && !entry->stringValue().isEmpty();
370 }
371 
372 
373 static bool haveX509DirectoryServerConfigured() {
374  const Kleo::CryptoConfig * const config = Kleo::CryptoBackendFactory::instance()->config();
375  if ( !config )
376  return false;
377  const Kleo::CryptoConfigEntry * entry = config->entry( QLatin1String("dirmngr"), QLatin1String("LDAP"), QLatin1String("LDAP Server") );
378  bool entriesExist = entry && !entry->urlValueList().empty();
379  entry = config->entry( QLatin1String("gpgsm"), QLatin1String("Configuration"), QLatin1String("keyserver") );
380  entriesExist |= entry && !entry->stringValueList().empty();
381  return entriesExist;
382 }
383 
384 
385 bool LookupCertificatesCommand::Private::checkConfig() const {
386  const bool ok = haveOpenPGPKeyserverConfigured() || haveX509DirectoryServerConfigured();
387  if ( !ok )
388  information( i18nc("@info",
389  "<para>You do not have any directory servers configured.</para>"
390  "<para>You need to configure at least one directory server to "
391  "search on one.</para>"
392  "<para>You can configure directory servers here: "
393  "<interface>Settings->Configure Kleopatra</interface>.</para>"),
394  i18nc("@title", "No Directory Servers Configured") );
395  return ok;
396 }
397 
398 #undef d
399 #undef q
400 
401 #include "moc_lookupcertificatescommand.cpp"
Kleo::Dialogs::LookupCertificatesDialog
Definition: lookupcertificatesdialog.h:49
Kleo::ImportCertificatesCommand::Private::showError
void showError(QWidget *parent, const GpgME::Error &error, const QString &id=QString())
QDialog
Kleo::ImportCertificatesCommand::Private
Definition: importcertificatescommand_p.h:55
Kleo::KeyListController
Definition: keylistcontroller.h:55
Kleo::Formatting::displayName
QString displayName(GpgME::Protocol prot)
QWidget
formatting.h
Kleo::Command::start
void start()
Definition: commands/command.cpp:182
importcertificatescommand_p.h
Kleo::ImportCertificatesCommand
Definition: importcertificatescommand.h:42
Kleo::Commands::LookupCertificatesCommand
Definition: lookupcertificatescommand.h:41
Kleo::Command::d
kdtools::pimpl_ptr< Private > d
Definition: commands/command.h:129
Kleo::Commands::LookupCertificatesCommand::LookupCertificatesCommand
LookupCertificatesCommand(QAbstractItemView *view, KeyListController *parent)
Definition: lookupcertificatescommand.cpp:162
lookupcertificatescommand.h
haveX509DirectoryServerConfigured
static bool haveX509DirectoryServerConfigured()
Definition: lookupcertificatescommand.cpp:373
Kleo::Class::OpenPGP
Definition: classify.h:49
Kleo::Class::CMS
Definition: classify.h:48
d
#define d
Definition: lookupcertificatescommand.cpp:134
detailscommand.h
lookupcertificatesdialog.h
Kleo::Commands::DetailsCommand
Definition: detailscommand.h:45
q
#define q
Definition: lookupcertificatescommand.cpp:135
Kleo::Commands::LookupCertificatesCommand::~LookupCertificatesCommand
~LookupCertificatesCommand()
Definition: lookupcertificatescommand.cpp:172
Kleo::ImportCertificatesCommand::doCancel
void doCancel()
Definition: importcertificatescommand.cpp:457
Kleo::Command::setParentWidget
void setParentWidget(QWidget *widget)
Definition: commands/command.cpp:136
Kleo::Command
Definition: commands/command.h:58
haveOpenPGPKeyserverConfigured
static bool haveOpenPGPKeyserverConfigured()
Definition: lookupcertificatescommand.cpp:364
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:41 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

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

kdepim API Reference

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

Search



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

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