• 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
exportcertificatecommand.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  exportcertificatecommand.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 "exportcertificatecommand.h"
36 
37 #include "command_p.h"
38 
39 #include <dialogs/exportcertificatesdialog.h>
40 
41 #include <utils/classify.h>
42 #include <utils/filedialog.h>
43 
44 #include <kleo/cryptobackend.h>
45 #include <kleo/cryptobackendfactory.h>
46 #include <kleo/exportjob.h>
47 
48 #include <gpgme++/key.h>
49 
50 #include <KLocale>
51 #include <KMessageBox>
52 #include <KSaveFile>
53 
54 #include <QDataStream>
55 #include <QMap>
56 #include <QPointer>
57 #include <QTextStream>
58 
59 #include <boost/bind.hpp>
60 #include <algorithm>
61 #include <vector>
62 #include <cassert>
63 
64 using namespace Kleo;
65 using namespace Kleo::Dialogs;
66 using namespace GpgME;
67 using namespace boost;
68 
69 class ExportCertificateCommand::Private : public Command::Private {
70  friend class ::ExportCertificateCommand;
71  ExportCertificateCommand * q_func() const { return static_cast<ExportCertificateCommand*>(q); }
72 public:
73  explicit Private( ExportCertificateCommand * qq, KeyListController * c );
74  ~Private();
75  void startExportJob( GpgME::Protocol protocol, const std::vector<Key>& keys );
76  void cancelJobs();
77  void exportResult( const GpgME::Error&, const QByteArray& );
78  void showError( const GpgME::Error& error );
79 
80  bool requestFileNames( Protocol prot );
81  void finishedIfLastJob();
82 
83 private:
84  QMap<GpgME::Protocol, QString> fileNames;
85  uint jobsPending;
86  QMap<QObject*, QString> outFileForSender;
87  QPointer<ExportJob> cmsJob;
88  QPointer<ExportJob> pgpJob;
89 };
90 
91 ExportCertificateCommand::Private * ExportCertificateCommand::d_func() { return static_cast<Private*>(d.get()); }
92 const ExportCertificateCommand::Private * ExportCertificateCommand::d_func() const { return static_cast<const Private*>(d.get()); }
93 
94 #define d d_func()
95 #define q q_func()
96 
97 ExportCertificateCommand::Private::Private( ExportCertificateCommand * qq, KeyListController * c )
98  : Command::Private( qq, c ),
99  jobsPending( 0 )
100 {
101 
102 }
103 
104 ExportCertificateCommand::Private::~Private() {}
105 
106 
107 ExportCertificateCommand::ExportCertificateCommand( KeyListController * p )
108  : Command( new Private( this, p ) )
109 {
110 
111 }
112 
113 ExportCertificateCommand::ExportCertificateCommand( QAbstractItemView * v, KeyListController * p )
114  : Command( v, new Private( this, p ) )
115 {
116 
117 }
118 
119 ExportCertificateCommand::ExportCertificateCommand( const Key & key )
120  : Command( key, new Private( this, 0 ) )
121 {
122 
123 }
124 
125 ExportCertificateCommand::~ExportCertificateCommand() {}
126 
127 void ExportCertificateCommand::setOpenPGPFileName( const QString & fileName )
128 {
129  if ( !d->jobsPending )
130  d->fileNames[OpenPGP] = fileName;
131 }
132 
133 QString ExportCertificateCommand::openPGPFileName() const
134 {
135  return d->fileNames[OpenPGP];
136 }
137 
138 void ExportCertificateCommand::setX509FileName( const QString & fileName )
139 {
140  if ( !d->jobsPending )
141  d->fileNames[CMS] = fileName;
142 }
143 
144 QString ExportCertificateCommand::x509FileName() const
145 {
146  return d->fileNames[CMS];
147 }
148 
149 void ExportCertificateCommand::doStart()
150 {
151  std::vector<Key> keys = d->keys();
152  if ( keys.empty() )
153  return;
154 
155  const std::vector<Key>::iterator firstCms = std::partition( keys.begin(), keys.end(), boost::bind( &GpgME::Key::protocol, _1 ) != CMS );
156 
157  std::vector<Key> openpgp, cms;
158  std::copy( keys.begin(), firstCms, std::back_inserter( openpgp ) );
159  std::copy( firstCms, keys.end(), std::back_inserter( cms ) );
160  assert( !openpgp.empty() || !cms.empty() );
161  const bool haveBoth = !cms.empty() && !openpgp.empty();
162  const GpgME::Protocol prot = haveBoth ? UnknownProtocol : ( !cms.empty() ? CMS : OpenPGP );
163  if ( !d->requestFileNames( prot ) ) {
164  emit canceled();
165  d->finished();
166  } else {
167  if ( !openpgp.empty() )
168  d->startExportJob( GpgME::OpenPGP, openpgp );
169  if ( !cms.empty() )
170  d->startExportJob( GpgME::CMS, cms );
171  }
172 }
173 
174 bool ExportCertificateCommand::Private::requestFileNames( GpgME::Protocol protocol )
175 {
176  if ( protocol == UnknownProtocol )
177  {
178  if ( !fileNames[OpenPGP].isEmpty() && !fileNames[CMS].isEmpty() )
179  return true;
180  const QPointer<ExportCertificatesDialog> dlg( new ExportCertificatesDialog );
181  applyWindowID( dlg );
182  dlg->setOpenPgpExportFileName( fileNames[OpenPGP] );
183  dlg->setCmsExportFileName( fileNames[CMS] );
184  const bool accepted = dlg->exec() == QDialog::Accepted && dlg ;
185  if ( accepted )
186  {
187  fileNames[OpenPGP] = dlg->openPgpExportFileName();
188  fileNames[CMS] = dlg->cmsExportFileName();
189  }
190  else
191  {
192  fileNames.clear();
193  }
194  delete dlg;
195  return accepted;
196  }
197 
198  if ( !fileNames[protocol].isEmpty() )
199  return true;
200 
201  QString proposedFileName;
202  if ( keys().size() == 1 )
203  proposedFileName
204  = QString::fromLatin1( keys().front().primaryFingerprint() )
205  + QLatin1Char( '.' )
206  + QString::fromLatin1( outputFileExtension( protocol == OpenPGP
207  ? Class::OpenPGP|Class::Ascii|Class::Certificate
208  : Class::CMS|Class::Ascii|Class::Certificate ) )
209  ;
210 
211  const QString fname = FileDialog::getSaveFileNameEx( parentWidgetOrView(),
212  i18n( "Export Certificates" ),
213  QLatin1String("imp"),
214  proposedFileName,
215  protocol == GpgME::OpenPGP
216  ? i18n( "OpenPGP Certificates" ) + QLatin1String(" (*.asc *.gpg *.pgp)")
217  : i18n( "S/MIME Certificates" ) + QLatin1String(" (*.pem *.der)" ));
218  fileNames[protocol] = fname;
219  return !fname.isEmpty();
220 }
221 
222 void ExportCertificateCommand::Private::startExportJob( GpgME::Protocol protocol, const std::vector<Key>& keys )
223 {
224  assert( protocol != GpgME::UnknownProtocol );
225 
226  const CryptoBackend::Protocol* const backend = CryptoBackendFactory::instance()->protocol( protocol );
227  assert( backend );
228  const QString fileName = fileNames[protocol];
229  const bool binary = protocol == GpgME::OpenPGP
230  ? fileName.endsWith( QLatin1String( ".gpg" ), Qt::CaseInsensitive ) || fileName.endsWith( QLatin1String( ".pgp" ), Qt::CaseInsensitive )
231  : fileName.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) ;
232  std::auto_ptr<ExportJob> job( backend->publicKeyExportJob( !binary ) );
233  assert( job.get() );
234 
235  connect( job.get(), SIGNAL(result(GpgME::Error,QByteArray)),
236  q, SLOT(exportResult(GpgME::Error,QByteArray)) );
237 
238  connect( job.get(), SIGNAL(progress(QString,int,int)),
239  q, SIGNAL(progress(QString,int,int)) );
240 
241  QStringList fingerprints;
242  Q_FOREACH ( const Key& i, keys )
243  fingerprints << QLatin1String(i.primaryFingerprint());
244 
245  const GpgME::Error err = job->start( fingerprints );
246  if ( err ) {
247  showError( err );
248  finished();
249  return;
250  }
251  emit q->info( i18n( "Exporting certificates..." ) );
252  ++jobsPending;
253  const QPointer<ExportJob> exportJob( job.release() );
254 
255  outFileForSender[exportJob.data()] = fileName;
256  ( protocol == CMS ? cmsJob : pgpJob ) = exportJob;
257 }
258 
259 void ExportCertificateCommand::Private::showError( const GpgME::Error& err )
260 {
261  assert( err );
262  const QString msg = i18n("<qt><p>An error occurred while trying to export "
263  "the certificate:</p>"
264  "<p><b>%1</b></p></qt>",
265  QString::fromLocal8Bit( err.asString() ) );
266  error( msg, i18n("Certificate Export Failed") );
267 }
268 
269 void ExportCertificateCommand::doCancel()
270 {
271  d->cancelJobs();
272 }
273 
274 void ExportCertificateCommand::Private::finishedIfLastJob()
275 {
276  if ( jobsPending <= 0 )
277  finished();
278 }
279 
280 static bool write_complete( QIODevice & iod, const QByteArray & data ) {
281  qint64 total = 0;
282  qint64 toWrite = data.size();
283  while ( total < toWrite ) {
284  const qint64 written = iod.write( data.data() + total, toWrite );
285  if ( written < 0 )
286  return false;
287  total += written;
288  toWrite -= written;
289  }
290  return true;
291 }
292 
293 void ExportCertificateCommand::Private::exportResult( const GpgME::Error& err, const QByteArray& data )
294 {
295  assert( jobsPending > 0 );
296  --jobsPending;
297 
298  assert( outFileForSender.contains( q->sender() ) );
299  const QString outFile = outFileForSender[q->sender()];
300 
301  if ( err ) {
302  showError( err );
303  finishedIfLastJob();
304  return;
305  }
306  KSaveFile savefile( outFile );
307  //TODO: use KIO
308  const QString writeErrorMsg = i18n( "Could not write to file %1.", outFile );
309  const QString errorCaption = i18n( "Certificate Export Failed" );
310  if ( !savefile.open() )
311  {
312  error( writeErrorMsg, errorCaption );
313  finishedIfLastJob();
314  return;
315  }
316 
317  if ( !write_complete( savefile, data ) ||
318  !savefile.finalize() )
319  error( writeErrorMsg, errorCaption );
320  finishedIfLastJob();
321 }
322 
323 void ExportCertificateCommand::Private::cancelJobs()
324 {
325  if ( cmsJob )
326  cmsJob->slotCancel();
327  if ( pgpJob )
328  pgpJob->slotCancel();
329 }
330 
331 #undef d
332 #undef q
333 
334 #include "moc_exportcertificatecommand.cpp"
Kleo::ExportCertificateCommand::openPGPFileName
QString openPGPFileName() const
Definition: exportcertificatecommand.cpp:133
Kleo::Dialogs::ExportCertificatesDialog
Definition: exportcertificatesdialog.h:45
Kleo::outputFileExtension
const char * outputFileExtension(unsigned int classification)
Definition: classify.cpp:292
Kleo::Command::Private
Definition: commands/command_p.h:52
Kleo::KeyListController
Definition: keylistcontroller.h:55
classify.h
write_complete
static bool write_complete(QIODevice &iod, const QByteArray &data)
Definition: exportcertificatecommand.cpp:280
q
#define q
Definition: exportcertificatecommand.cpp:95
Kleo::Class::Ascii
Definition: classify.h:56
Kleo::Command::d
kdtools::pimpl_ptr< Private > d
Definition: commands/command.h:129
Kleo::Class::OpenPGP
Definition: classify.h:49
d
#define d
Definition: exportcertificatecommand.cpp:94
Kleo::Class::CMS
Definition: classify.h:48
Kleo::ExportCertificateCommand::~ExportCertificateCommand
~ExportCertificateCommand()
Definition: exportcertificatecommand.cpp:125
Kleo::ExportCertificateCommand
Definition: exportcertificatecommand.h:39
Kleo::FileDialog::getSaveFileNameEx
QString getSaveFileNameEx(QWidget *parent=0, const QString &caption=QString(), const QString &dirID=QString(), const QString &proposedFileName=QString(), const QString &filter=QString())
Definition: filedialog.cpp:136
command_p.h
Kleo::ExportCertificateCommand::ExportCertificateCommand
ExportCertificateCommand(QAbstractItemView *view, KeyListController *parent)
Definition: exportcertificatecommand.cpp:113
Kleo::ExportCertificateCommand::setOpenPGPFileName
void setOpenPGPFileName(const QString &fileName)
Definition: exportcertificatecommand.cpp:127
Kleo::Command::canceled
void canceled()
Kleo::ExportCertificateCommand::setX509FileName
void setX509FileName(const QString &fileName)
Definition: exportcertificatecommand.cpp:138
Kleo::Class::Certificate
Definition: classify.h:73
Kleo::ExportCertificateCommand::x509FileName
QString x509FileName() const
Definition: exportcertificatecommand.cpp:144
exportcertificatecommand.h
QIODevice
exportcertificatesdialog.h
Kleo::Command
Definition: commands/command.h:58
QMap< GpgME::Protocol, QString >
filedialog.h
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