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