37 #include "certmanager.h"
39 #include "certlistview.h"
40 #include "certificatewizardimpl.h"
41 #include "certificateinfowidgetimpl.h"
43 #include "customactions.h"
44 #include "hierarchyanalyser.h"
45 #include "storedtransferjob.h"
46 #include "conf/configuredialog.h"
49 #include <kleo/cryptobackendfactory.h>
50 #include <kleo/downloadjob.h>
51 #include <kleo/importjob.h>
52 #include <kleo/exportjob.h>
53 #include <kleo/multideletejob.h>
54 #include <kleo/deletejob.h>
55 #include <kleo/keylistjob.h>
57 #include <kleo/keyfilter.h>
58 #include <kleo/keyfiltermanager.h>
59 #include <kleo/hierarchicalkeylistjob.h>
60 #include <kleo/refreshkeysjob.h>
61 #include <kleo/cryptoconfig.h>
63 #include <ui/progressdialog.h>
64 #include <ui/progressbar.h>
65 #include <ui/keyselectiondialog.h>
66 #include <ui/cryptoconfigdialog.h>
69 #include <gpgmepp/importresult.h>
70 #include <gpgmepp/keylistresult.h>
71 #include <gpgmepp/key.h>
74 #include <tdefiledialog.h>
75 #include <tdeprocess.h>
76 #include <tdeaction.h>
77 #include <tdeapplication.h>
78 #include <tdelocale.h>
79 #include <tdemessagebox.h>
80 #include <dcopclient.h>
81 #include <tdetoolbar.h>
82 #include <kstatusbar.h>
83 #include <kstandarddirs.h>
85 #include <kdialogbase.h>
86 #include <kkeydialog.h>
87 #include <tdetempfile.h>
88 #include <tdeio/job.h>
89 #include <tdeio/netaccess.h>
90 #include <tdestdaccel.h>
93 #include <tqfontmetrics.h>
94 #include <tqpopupmenu.h>
99 #include <tdemacros.h>
100 #include <kinputdialog.h>
103 class TDE_EXPORT DisplayStrategy :
public Kleo::KeyListView::DisplayStrategy{
105 ~DisplayStrategy() {}
107 virtual TQFont keyFont(
const GpgME::Key& key,
const TQFont& font )
const {
108 const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
109 return filter ? filter->font( font ) : font;
111 virtual TQColor keyForeground(
const GpgME::Key& key,
const TQColor& c )
const {
112 const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
113 if ( filter && filter->fgColor().isValid() )
114 return filter->fgColor();
117 virtual TQColor keyBackground(
const GpgME::Key& key,
const TQColor& c )
const {
118 const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
119 if ( filter && filter->bgColor().isValid() )
120 return filter->bgColor();
125 class TDE_EXPORT ColumnStrategy :
public Kleo::KeyListView::ColumnStrategy {
129 TQString title(
int col )
const;
130 TQString text(
const GpgME::Key & key,
int col )
const;
131 int width(
int col,
const TQFontMetrics & fm )
const;
134 TQString ColumnStrategy::title(
int col )
const {
136 case 0:
return i18n(
"Subject");
137 case 1:
return i18n(
"Issuer");
138 case 2:
return i18n(
"Serial");
139 default:
return TQString();
143 TQString ColumnStrategy::text(
const GpgME::Key & key,
int col )
const {
145 case 0:
return Kleo::DN( key.userID(0).id() ).prettyDN();
146 case 1:
return Kleo::DN( key.issuerName() ).prettyDN();
147 case 2:
return key.issuerSerial() ? TQString::fromUtf8( key.issuerSerial() ) : TQString() ;
148 default:
return TQString();
152 int ColumnStrategy::width(
int col,
const TQFontMetrics & fm )
const {
155 case 0: factor = 6;
break;
156 case 1: factor = 4;
break;
159 return fm.width( title( col ) ) * factor;
163 CertManager::CertManager(
bool remote,
const TQString& query,
const TQString &
import,
164 TQWidget* parent,
const char* name, WFlags f )
165 : TDEMainWindow( parent, name, f|WDestructiveClose ),
168 mHierarchyAnalyser( 0 ),
169 mLineEditAction( 0 ),
172 mImportCertFromFileAction( 0 ),
173 mImportCRLFromFileAction( 0 ),
174 mNextFindRemote( remote ),
176 mDirMngrFound( false )
178 readConfig( query.isEmpty() );
183 setAutoSaveSettings();
186 mKeyListView =
new CertKeyListView(
new ColumnStrategy(),
new DisplayStrategy(),
this,
"mKeyListView" );
187 mKeyListView->setSelectionMode( TQListView::Extended );
188 setCentralWidget( mKeyListView );
190 connect( mKeyListView, TQ_SIGNAL(doubleClicked(Kleo::KeyListViewItem*,
const TQPoint&,
int)),
191 TQ_SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
192 connect( mKeyListView, TQ_SIGNAL(returnPressed(Kleo::KeyListViewItem*)),
193 TQ_SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
194 connect( mKeyListView, TQ_SIGNAL(selectionChanged()),
195 TQ_SLOT(slotSelectionChanged()) );
196 connect( mKeyListView, TQ_SIGNAL(contextMenu(Kleo::KeyListViewItem*,
const TQPoint&)),
197 TQ_SLOT(slotContextMenu(Kleo::KeyListViewItem*,
const TQPoint&)) );
199 connect( mKeyListView, TQ_SIGNAL(dropped(
const KURL::List&) ),
200 TQ_SLOT( slotDropped(
const KURL::List&) ) );
202 mLineEditAction->setText(query);
203 if ( !mRemote && !mNextFindRemote || !query.isEmpty() )
206 if ( !
import.isEmpty() )
207 slotImportCertFromFile( KURL(
import ) );
209 slotToggleHierarchicalView( mHierarchicalView );
210 updateStatusBarLabels();
211 slotSelectionChanged();
214 CertManager::~CertManager() {
216 delete mDirmngrProc; mDirmngrProc = 0;
217 delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
220 void CertManager::readConfig(
bool noQueryGiven ) {
221 TDEConfig config(
"kleopatrarc" );
222 config.setGroup(
"Display Options" );
223 mHierarchicalView = config.readBoolEntry(
"hierarchicalView",
false );
224 if ( noQueryGiven ) {
225 mNextFindRemote = config.readBoolEntry(
"startInRemoteMode",
false );
229 void CertManager::writeConfig() {
230 TDEConfig config(
"kleopatrarc" );
231 config.setGroup(
"Display Options" );
232 config.writeEntry(
"hierarchicalView", mKeyListView->hierarchical() );
233 config.writeEntry(
"startInRemoteMode", mNextFindRemote );
236 void CertManager::createStatusBar() {
237 KStatusBar * bar = statusBar();
238 mProgressBar =
new Kleo::ProgressBar( bar,
"mProgressBar" );
239 mProgressBar->reset();
240 mProgressBar->setFixedSize( TQSize( 100, mProgressBar->height() * 3 / 5 ) );
241 bar->addWidget( mProgressBar, 0,
true );
242 mStatusLabel =
new TQLabel( bar,
"mStatusLabel" );
243 bar->addWidget( mStatusLabel, 1,
false );
246 static inline void connectEnableOperationSignal( TQObject * s, TQObject * d ) {
247 TQObject::connect( s, TQ_SIGNAL(enableOperations(
bool)),
248 d, TQ_SLOT(setEnabled(
bool)) );
252 void CertManager::createActions() {
253 TDEAction * action = 0;
255 (void)KStdAction::quit(
this, TQ_SLOT(close()), actionCollection() );
257 action = KStdAction::redisplay(
this, TQ_SLOT(slotRedisplay()), actionCollection() );
259 TDEShortcut reloadShortcut = TDEStdAccel::shortcut(TDEStdAccel::Reload);
260 reloadShortcut.append(KKey(CTRL + Key_R));
261 action->setShortcut( reloadShortcut );
263 connectEnableOperationSignal(
this, action );
265 action =
new TDEAction( i18n(
"Stop Operation"),
"process-stop", Key_Escape,
266 this, TQ_SIGNAL(stopOperations()),
267 actionCollection(),
"view_stop_operations" );
268 action->setEnabled(
false );
270 (void)
new TDEAction( i18n(
"New Key Pair..."),
"document-new", 0,
271 this, TQ_SLOT(newCertificate()),
272 actionCollection(),
"file_new_certificate" );
274 connect(
new TDEToggleAction( i18n(
"Hierarchical Key List"), 0,
275 actionCollection(),
"view_hierarchical" ),
276 TQ_SIGNAL(toggled(
bool)), TQ_SLOT(slotToggleHierarchicalView(
bool)) );
278 action =
new TDEAction( i18n(
"Expand All"), 0, CTRL+Key_Period,
279 this, TQ_SLOT(slotExpandAll()),
280 actionCollection(),
"view_expandall" );
281 action =
new TDEAction( i18n(
"Collapse All"), 0, CTRL+Key_Comma,
282 this, TQ_SLOT(slotCollapseAll()),
283 actionCollection(),
"view_collapseall" );
285 (void)
new TDEAction( i18n(
"Refresh CRLs"), 0, 0,
286 this, TQ_SLOT(slotRefreshKeys()),
287 actionCollection(),
"certificates_refresh_clr" );
289 #ifdef NOT_IMPLEMENTED_ANYWAY
290 mRevokeCertificateAction =
new TDEAction( i18n(
"Revoke"), 0,
291 this, TQ_SLOT(revokeCertificate()),
292 actionCollection(),
"edit_revoke_certificate" );
293 connectEnableOperationSignal(
this, mRevokeCertificateAction );
295 mExtendCertificateAction =
new TDEAction( i18n(
"Extend"), 0,
296 this, TQ_SLOT(extendCertificate()),
297 actionCollection(),
"edit_extend_certificate" );
298 connectEnableOperationSignal(
this, mExtendCertificateAction );
301 mDeleteCertificateAction =
new TDEAction( i18n(
"Delete"),
"edit-delete", Key_Delete,
302 this, TQ_SLOT(slotDeleteCertificate()),
303 actionCollection(),
"edit_delete_certificate" );
304 connectEnableOperationSignal(
this, mDeleteCertificateAction );
306 mValidateCertificateAction =
new TDEAction( i18n(
"Validate"),
"reload", SHIFT + Key_F5,
307 this, TQ_SLOT(slotValidate()),
308 actionCollection(),
"certificates_validate" );
309 connectEnableOperationSignal(
this, mValidateCertificateAction );
311 mImportCertFromFileAction =
new TDEAction( i18n(
"Import Certificates..."), 0,
312 this, TQ_SLOT(slotImportCertFromFile()),
313 actionCollection(),
"file_import_certificates" );
314 connectEnableOperationSignal(
this, mImportCertFromFileAction );
316 mImportCRLFromFileAction =
new TDEAction( i18n(
"Import CRLs..."), 0,
317 this, TQ_SLOT(importCRLFromFile()),
318 actionCollection(),
"file_import_crls" );
319 connectEnableOperationSignal(
this, mImportCRLFromFileAction );
321 mExportCertificateAction =
new TDEAction( i18n(
"Export Certificates..."),
"export", 0,
322 this, TQ_SLOT(slotExportCertificate()),
323 actionCollection(),
"file_export_certificate" );
325 mExportSecretKeyAction =
new TDEAction( i18n(
"Export Secret Key..."),
"export", 0,
326 this, TQ_SLOT(slotExportSecretKey()),
327 actionCollection(),
"file_export_secret_keys" );
328 connectEnableOperationSignal(
this, mExportSecretKeyAction );
330 mViewCertDetailsAction =
new TDEAction( i18n(
"Certificate Details..."), 0, 0,
331 this, TQ_SLOT(slotViewDetails()), actionCollection(),
332 "view_certificate_details" );
333 mDownloadCertificateAction =
new TDEAction( i18n(
"Download"), 0, 0,
334 this, TQ_SLOT(slotDownloadCertificate()), actionCollection(),
335 "download_certificate" );
337 const TQString dirmngr = TDEStandardDirs::findExe(
"gpgsm" );
338 mDirMngrFound = !dirmngr.isEmpty();
340 action =
new TDEAction( i18n(
"Dump CRL Cache..."), 0,
341 this, TQ_SLOT(slotViewCRLs()),
342 actionCollection(),
"crl_dump_crl_cache" );
343 action->setEnabled( mDirMngrFound );
345 action =
new TDEAction( i18n(
"Clear CRL Cache..."), 0,
346 this, TQ_SLOT(slotClearCRLs()),
347 actionCollection(),
"crl_clear_crl_cache" );
348 action->setEnabled( mDirMngrFound );
350 action =
new TDEAction( i18n(
"GnuPG Log Viewer..."),
"pgp-keys", 0,
this,
351 TQ_SLOT(slotStartWatchGnuPG()), actionCollection(),
"tools_start_kwatchgnupg");
353 if (TDEStandardDirs::findExe(
"kwatchgnupg").isEmpty()) action->setEnabled(
false);
355 (void)
new LabelAction( i18n(
"Search:"), actionCollection(),
"label_action" );
357 mLineEditAction =
new LineEditAction( TQString(), actionCollection(),
this,
358 TQ_SLOT(slotSearch()),
359 "query_lineedit_action");
362 lst << i18n(
"In Local Certificates") << i18n(
"In External Certificates");
363 mComboAction =
new ComboAction( lst, actionCollection(),
this, TQ_SLOT( slotToggleRemote(
int) ),
364 "location_combo_action", mNextFindRemote? 1 : 0 );
366 mFindAction =
new TDEAction( i18n(
"Find"),
"edit-find", 0,
this, TQ_SLOT(slotSearch()),
367 actionCollection(),
"find" );
369 KStdAction::keyBindings(
this, TQ_SLOT(slotEditKeybindings()), actionCollection() );
370 KStdAction::preferences(
this, TQ_SLOT(slotShowConfigurationDialog()), actionCollection() );
372 new TDEAction( i18n(
"Configure &GpgME Backend" ), 0, 0,
this, TQ_SLOT(slotConfigureGpgME()),
373 actionCollection(),
"configure_gpgme" );
375 createStandardStatusBarAction();
376 updateImportActions(
true );
379 void CertManager::updateImportActions(
bool enable ) {
380 mImportCRLFromFileAction->setEnabled( mDirMngrFound && enable );
381 mImportCertFromFileAction->setEnabled( enable );
384 void CertManager::slotEditKeybindings() {
385 KKeyDialog::configure( actionCollection(),
true );
388 void CertManager::slotShowConfigurationDialog() {
389 ConfigureDialog dlg(
this );
390 connect( &dlg, TQ_SIGNAL( configCommitted() ), TQ_SLOT( slotRepaint() ) );
394 void CertManager::slotConfigureGpgME() {
395 Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config();
397 Kleo::CryptoConfigDialog dlg( config );
399 int result = dlg.exec();
405 if ( result == TQDialog::Accepted )
408 kapp->dcopClient()->emitDCOPSignal(
"KPIM::CryptoConfig",
"changed()", TQByteArray() );
413 void CertManager::slotRepaint()
415 mKeyListView->repaintContents();
418 void CertManager::slotToggleRemote(
int idx ) {
419 mNextFindRemote = idx != 0;
422 void CertManager::slotToggleHierarchicalView(
bool hier ) {
423 mHierarchicalView = hier;
424 mKeyListView->setHierarchical( hier );
425 mKeyListView->setRootIsDecorated( hier );
426 if ( TDEAction * act = action(
"view_expandall") )
427 act->setEnabled( hier );
428 if ( TDEAction * act = action(
"view_collapseall" ) )
429 act->setEnabled( hier );
430 if ( TDEToggleAction * act =
431 static_cast<TDEToggleAction*
>( action(
"view_hierarchical") ) )
432 act->setChecked( hier );
434 if ( hier && !mCurrentQuery.isEmpty() )
435 startRedisplay(
false );
438 void CertManager::slotExpandAll() {
439 for ( TQListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
440 it.current()->setOpen(
true );
443 void CertManager::slotCollapseAll() {
444 for ( TQListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
445 it.current()->setOpen(
false );
448 void CertManager::connectJobToStatusBarProgress( Kleo::Job * job,
const TQString & initialText ) {
449 assert( mProgressBar );
452 if ( !initialText.isEmpty() )
453 statusBar()->message( initialText );
454 connect( job, TQ_SIGNAL(progress(
const TQString&,
int,
int)),
455 mProgressBar, TQ_SLOT(slotProgress(
const TQString&,
int,
int)) );
456 connect( job, TQ_SIGNAL(done()), mProgressBar, TQ_SLOT(reset()) );
457 connect(
this, TQ_SIGNAL(stopOperations()), job, TQ_SLOT(slotCancel()) );
459 action(
"view_stop_operations")->setEnabled(
true );
460 emit enableOperations(
false );
463 void CertManager::disconnectJobFromStatusBarProgress(
const GpgME::Error & err ) {
464 updateStatusBarLabels();
465 const TQString msg = err.isCanceled() ? i18n(
"Canceled.")
466 : err ? i18n(
"Failed.")
468 statusBar()->message( msg, 4000 );
470 action(
"view_stop_operations")->setEnabled(
false );
471 emit enableOperations(
true );
472 slotSelectionChanged();
475 void CertManager::updateStatusBarLabels() {
476 mKeyListView->flushKeys();
478 for ( TQListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
480 mStatusLabel->setText( i18n(
"%n Key.",
"%n Keys.", total ) );
490 static std::set<std::string> extractKeyFingerprints(
const TQPtrList<Kleo::KeyListViewItem> & items ) {
491 std::set<std::string> result;
492 for ( TQPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
493 if (
const char * fpr = it.current()->key().primaryFingerprint() )
494 result.insert( fpr );
498 static TQStringList stringlistFromSet(
const std::set<std::string> & set ) {
501 for ( std::set<std::string>::const_iterator it = set.begin() ; it != set.end() ; ++it )
503 sl.push_back( TQString::fromLatin1( it->c_str() ) );
507 void CertManager::slotRefreshKeys() {
508 const TQStringList keys = stringlistFromSet( extractKeyFingerprints( mKeyListView->selectedItems() ) );
509 Kleo::RefreshKeysJob * job = Kleo::CryptoBackendFactory::instance()->smime()->refreshKeysJob();
512 connect( job, TQ_SIGNAL(result(
const GpgME::Error&)),
513 this, TQ_SLOT(slotRefreshKeysResult(
const GpgME::Error&)) );
515 connectJobToStatusBarProgress( job, i18n(
"Refreshing keys...") );
516 if (
const GpgME::Error err = job->start( keys ) )
517 slotRefreshKeysResult( err );
520 void CertManager::slotRefreshKeysResult(
const GpgME::Error & err ) {
521 disconnectJobFromStatusBarProgress( err );
522 if ( err.isCanceled() )
525 KMessageBox::error(
this, i18n(
"An error occurred while trying to refresh "
526 "keys:\n%1").arg( TQString::fromLocal8Bit( err.asString() ) ),
527 i18n(
"Refreshing Keys Failed") );
530 static void showKeyListError( TQWidget * parent,
const GpgME::Error & err ) {
532 const TQString msg = i18n(
"<qt><p>An error occurred while fetching "
533 "the certificates from the backend:</p>"
534 "<p><b>%1</b></p></qt>" )
535 .arg( TQString::fromLocal8Bit( err.asString() ) );
537 KMessageBox::error( parent, msg, i18n(
"Certificate Listing Failed" ) );
540 void CertManager::slotSearch() {
541 mPreviouslySelectedFingerprints.clear();
543 mKeyListView->clear();
544 mCurrentQuery = mLineEditAction->text();
545 startKeyListing(
false,
false, mCurrentQuery );
548 void CertManager::startRedisplay(
bool validate ) {
549 mPreviouslySelectedFingerprints = extractKeyFingerprints( mKeyListView->selectedItems() );
550 if ( mPreviouslySelectedFingerprints.empty() )
551 startKeyListing( validate,
true, mCurrentQuery );
553 startKeyListing( validate,
true, mPreviouslySelectedFingerprints );
556 void CertManager::startKeyListing(
bool validating,
bool refresh,
const std::set<std::string> & patterns ) {
557 startKeyListing( validating, refresh, stringlistFromSet( patterns ) );
560 void CertManager::startKeyListing(
bool validating,
bool refresh,
const TQStringList & patterns ) {
561 mRemote = mNextFindRemote;
562 mLineEditAction->setEnabled(
false );
563 mComboAction->setEnabled(
false );
564 mFindAction->setEnabled(
false );
566 Kleo::KeyListJob * job = 0;
567 if ( !validating && !refresh && mKeyListView->hierarchical() && !patterns.empty() )
568 job =
new Kleo::HierarchicalKeyListJob( Kleo::CryptoBackendFactory::instance()->smime(),
569 mRemote,
false, validating );
571 job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( mRemote,
false, validating );
574 connect( job, TQ_SIGNAL(nextKey(
const GpgME::Key&)),
575 mKeyListView, refresh ? TQ_SLOT(slotRefreshKey(
const GpgME::Key&)) : TQ_SLOT(slotAddKey(
const GpgME::Key&)) );
576 connect( job, TQ_SIGNAL(result(
const GpgME::KeyListResult&)),
577 this, TQ_SLOT(slotKeyListResult(
const GpgME::KeyListResult&)) );
579 connectJobToStatusBarProgress( job, i18n(
"Fetching keys...") );
581 const GpgME::Error err = job->start( patterns ) ;
583 showKeyListError(
this, err );
586 mProgressBar->setProgress( 0, 0 );
589 static void selectKeys( Kleo::KeyListView * lv,
const std::set<std::string> & fprs ) {
590 if ( !lv || fprs.empty() )
592 for ( TQListViewItemIterator it( lv ) ; it.current() ; ++it )
593 if ( Kleo::KeyListViewItem * item = Kleo::lvi_cast<Kleo::KeyListViewItem>( it.current() ) ) {
594 const char * fpr = item->key().primaryFingerprint();
595 item->setSelected( fpr && fprs.find( fpr ) != fprs.end() );
599 void CertManager::slotKeyListResult(
const GpgME::KeyListResult & res ) {
601 showKeyListError(
this, res.error() );
602 else if ( res.isTruncated() )
603 KMessageBox::information(
this,
604 i18n(
"The query result has been truncated.\n"
605 "Either the local or a remote limit on "
606 "the maximum number of returned hits has "
608 "You can try to increase the local limit "
609 "in the configuration dialog, but if one "
610 "of the configured servers is the limiting "
611 "factor, you have to refine your search.") );
613 mLineEditAction->setEnabled(
true );
614 mComboAction->setEnabled(
true );
615 mFindAction->setEnabled(
true );
617 mLineEditAction->focusAll();
618 disconnectJobFromStatusBarProgress( res.error() );
619 selectKeys( mKeyListView, mPreviouslySelectedFingerprints );
622 void CertManager::slotContextMenu(Kleo::KeyListViewItem* item,
const TQPoint& point) {
625 if ( TQPopupMenu * popup =
static_cast<TQPopupMenu*
>(factory()->container(
"listview_popup",
this)) )
626 popup->exec( point );
632 void CertManager::newCertificate()
634 CertificateWizardImpl wizard(
this );
642 void CertManager::revokeCertificate()
644 tqDebug(
"Not Yet Implemented");
651 void CertManager::extendCertificate()
653 tqDebug(
"Not Yet Implemented");
667 void CertManager::slotImportCertFromFile()
669 const TQString filter =
"application/x-x509-ca-cert application/x-pkcs12 application/pkcs7-mime";
671 slotImportCertFromFile( KFileDialog::getOpenURL( TQString(), filter,
this,
672 i18n(
"Select Certificate File" ) ) );
675 void CertManager::slotImportCertFromFile(
const KURL & certURL )
677 if ( !certURL.isValid() )
680 mPreviouslySelectedFingerprints.clear();
683 updateImportActions(
false );
687 importJob->setWindow(
this );
688 connect( importJob, TQ_SIGNAL(result(TDEIO::Job*)), TQ_SLOT(slotImportResult(TDEIO::Job*)) );
691 void CertManager::slotImportResult( TDEIO::Job* job )
693 if ( job->error() ) {
694 job->showErrorDialog();
697 startCertificateImport( trJob->
data(), trJob->url().fileName() );
700 updateImportActions(
true );
703 static void showCertificateDownloadError( TQWidget * parent,
const GpgME::Error & err,
const TQString& certDisplayName ) {
705 const TQString msg = i18n(
"<qt><p>An error occurred while trying "
706 "to download the certificate %1:</p>"
707 "<p><b>%2</b></p></qt>" )
708 .arg( certDisplayName )
709 .arg( TQString::fromLocal8Bit( err.asString() ) );
711 KMessageBox::error( parent, msg, i18n(
"Certificate Download Failed" ) );
714 void CertManager::slotDownloadCertificate() {
715 mPreviouslySelectedFingerprints.clear();
716 TQPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
717 for ( TQPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
718 if ( !it.current()->key().isNull() )
719 if (
const char * fpr = it.current()->key().primaryFingerprint() )
720 slotStartCertificateDownload( fpr, it.current()->text(0) );
724 void CertManager::slotStartCertificateDownload(
const TQString& fingerprint,
const TQString& displayName ) {
725 if ( fingerprint.isEmpty() )
728 Kleo::DownloadJob * job =
729 Kleo::CryptoBackendFactory::instance()->smime()->downloadJob(
false );
732 connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
733 TQ_SLOT(slotCertificateDownloadResult(
const GpgME::Error&,
const TQByteArray&)) );
735 connectJobToStatusBarProgress( job, i18n(
"Fetching certificate from server...") );
737 const GpgME::Error err = job->start( fingerprint );
739 showCertificateDownloadError(
this, err, displayName );
741 mProgressBar->setProgress( 0, 0 );
742 mJobsDisplayNameMap.insert( job, displayName );
746 TQString CertManager::displayNameForJob(
const Kleo::Job *job )
748 JobsDisplayNameMap::iterator it = mJobsDisplayNameMap.find( job );
749 TQString displayName;
750 if ( it != mJobsDisplayNameMap.end() ) {
752 mJobsDisplayNameMap.remove( it );
754 kdWarning() <<
"Job not found in map: " << job << endl;
760 void CertManager::slotCertificateDownloadResult(
const GpgME::Error & err,
const TQByteArray & keyData ) {
762 TQString displayName = displayNameForJob(
static_cast<const Kleo::Job *
>( sender() ) );
765 showCertificateDownloadError(
this, err, displayName );
767 startCertificateImport( keyData, displayName );
768 disconnectJobFromStatusBarProgress( err );
771 static void showCertificateImportError( TQWidget * parent,
const GpgME::Error & err,
const TQString& certDisplayName ) {
773 const TQString msg = i18n(
"<qt><p>An error occurred while trying "
774 "to import the certificate %1:</p>"
775 "<p><b>%2</b></p></qt>" )
776 .arg( certDisplayName )
777 .arg( TQString::fromLocal8Bit( err.asString() ) );
778 KMessageBox::error( parent, msg, i18n(
"Certificate Import Failed" ) );
781 void CertManager::startCertificateImport(
const TQByteArray & keyData,
const TQString& certDisplayName ) {
782 Kleo::ImportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->importJob();
785 connect( job, TQ_SIGNAL(result(
const GpgME::ImportResult&)),
786 TQ_SLOT(slotCertificateImportResult(
const GpgME::ImportResult&)) );
788 connectJobToStatusBarProgress( job, i18n(
"Importing certificates...") );
790 kdDebug() <<
"Importing certificate. keyData size:" << keyData.size() << endl;
791 const GpgME::Error err = job->start( keyData );
793 showCertificateImportError(
this, err, certDisplayName );
795 mProgressBar->setProgress( 0, 0 );
796 mJobsDisplayNameMap.insert( job, certDisplayName );
800 void CertManager::slotCertificateImportResult(
const GpgME::ImportResult & res ) {
801 TQString displayName = displayNameForJob(
static_cast<const Kleo::Job *
>( sender() ) );
803 if ( res.error().isCanceled() ) {
805 }
else if ( res.error() ) {
806 showCertificateImportError(
this, res.error(), displayName );
809 const TQString normalLine = i18n(
"<tr><td align=\"right\">%1</td><td>%2</td></tr>");
810 const TQString boldLine = i18n(
"<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>");
813 lines.push_back( normalLine.arg( i18n(
"Total number processed:"),
814 TQString::number( res.numConsidered() ) ) );
815 lines.push_back( normalLine.arg( i18n(
"Imported:"),
816 TQString::number( res.numImported() ) ) );
817 if ( res.newSignatures() )
818 lines.push_back( normalLine.arg( i18n(
"New signatures:"),
819 TQString::number( res.newSignatures() ) ) );
820 if ( res.newUserIDs() )
821 lines.push_back( normalLine.arg( i18n(
"New user IDs:"),
822 TQString::number( res.newUserIDs() ) ) );
823 if ( res.numKeysWithoutUserID() )
824 lines.push_back( normalLine.arg( i18n(
"Keys without user IDs:"),
825 TQString::number( res.numKeysWithoutUserID() ) ) );
826 if ( res.newSubkeys() )
827 lines.push_back( normalLine.arg( i18n(
"New subkeys:"),
828 TQString::number( res.newSubkeys() ) ) );
829 if ( res.newRevocations() )
830 lines.push_back( boldLine.arg( i18n(
"Newly revoked:"),
831 TQString::number( res.newRevocations() ) ) );
832 if ( res.notImported() )
833 lines.push_back( boldLine.arg( i18n(
"Not imported:"),
834 TQString::number( res.notImported() ) ) );
835 if ( res.numUnchanged() )
836 lines.push_back( normalLine.arg( i18n(
"Unchanged:"),
837 TQString::number( res.numUnchanged() ) ) );
838 if ( res.numSecretKeysConsidered() )
839 lines.push_back( normalLine.arg( i18n(
"Secret keys processed:"),
840 TQString::number( res.numSecretKeysConsidered() ) ) );
841 if ( res.numSecretKeysImported() )
842 lines.push_back( normalLine.arg( i18n(
"Secret keys imported:"),
843 TQString::number( res.numSecretKeysImported() ) ) );
844 if ( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() > 0 )
845 lines.push_back( boldLine.arg( i18n(
"Secret keys <em>not</em> imported:"),
846 TQString::number( res.numSecretKeysConsidered()
847 - res.numSecretKeysImported()
848 - res.numSecretKeysUnchanged() ) ) );
849 if ( res.numSecretKeysUnchanged() )
850 lines.push_back( normalLine.arg( i18n(
"Secret keys unchanged:"),
851 TQString::number( res.numSecretKeysUnchanged() ) ) );
853 KMessageBox::information(
this,
854 i18n(
"<qt><p>Detailed results of importing %1:</p>"
855 "<table>%2</table></qt>" )
856 .arg( displayName ).arg( lines.join( TQString() ) ),
857 i18n(
"Certificate Import Result" ) );
859 disconnectJobFromStatusBarProgress( res.error() );
861 const std::vector<GpgME::Import> imports = res.imports();
862 for ( std::vector<GpgME::Import>::const_iterator it = imports.begin() ; it != imports.end() ; ++it )
863 mPreviouslySelectedFingerprints.insert( it->fingerprint() );
865 importNextURLOrRedisplay();
874 void CertManager::slotDirmngrExited() {
875 if ( !mDirmngrProc->normalExit() )
876 KMessageBox::error(
this, i18n(
"The GpgSM process that tried to import the CRL file ended prematurely because of an unexpected error." ), i18n(
"Certificate Manager Error" ) );
877 else if ( mDirmngrProc->exitStatus() )
878 KMessageBox::error(
this, i18n(
"An error occurred when trying to import the CRL file. The output from GpgSM was:\n%1").arg( mErrorbuffer ), i18n(
"Certificate Manager Error" ) );
880 KMessageBox::information(
this, i18n(
"CRL file imported successfully." ), i18n(
"Certificate Manager Information" ) );
882 delete mDirmngrProc; mDirmngrProc = 0;
883 if ( !mImportCRLTempFile.isEmpty() )
884 TQFile::remove( mImportCRLTempFile );
885 updateImportActions(
true );
891 void CertManager::importCRLFromFile() {
893 TQString filter = TQString(
"*.crl *.arl *-crl.der *-arl.der|") + i18n(
"Certificate Revocation List, DER encoded (*.crl *.arl *-crl.der *-arl.der)");
894 KURL url = KFileDialog::getOpenURL( TQString(),
897 i18n(
"Select CRL File" ) );
898 if ( url.isValid() ) {
899 updateImportActions(
false );
900 if ( url.isLocalFile() ) {
901 startImportCRL( url.path(),
false );
902 updateImportActions(
true );
906 destURL.setPath( tempFile.name() );
907 TDEIO::Job* copyJob = TDEIO::file_copy( url, destURL, 0600,
true,
false );
908 copyJob->setWindow(
this );
909 connect( copyJob, TQ_SIGNAL( result( TDEIO::Job * ) ),
910 TQ_SLOT( slotImportCRLJobFinished( TDEIO::Job * ) ) );
915 void CertManager::slotImportCRLJobFinished( TDEIO::Job *job )
917 TDEIO::FileCopyJob* fcjob =
static_cast<TDEIO::FileCopyJob*
>( job );
918 TQString tempFilePath = fcjob->destURL().path();
919 if ( job->error() ) {
920 job->showErrorDialog();
921 TQFile::remove( tempFilePath );
922 updateImportActions(
true );
925 startImportCRL( tempFilePath,
true );
928 bool CertManager::connectAndStartDirmngr(
const char * slot,
const char * processname ) {
930 assert( processname );
931 assert( mDirmngrProc );
932 mErrorbuffer = TQString();
933 connect( mDirmngrProc, TQ_SIGNAL(processExited(TDEProcess*)), slot );
934 connect( mDirmngrProc, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int) ),
935 this, TQ_SLOT(slotStderr(TDEProcess*,
char*,
int)) );
936 if( !mDirmngrProc->start( TDEProcess::NotifyOnExit, TDEProcess::Stderr ) ) {
937 delete mDirmngrProc; mDirmngrProc = 0;
938 KMessageBox::error(
this, i18n(
"Unable to start %1 process. Please check your installation." ).arg( processname ), i18n(
"Certificate Manager Error" ) );
944 void CertManager::startImportCRL(
const TQString& filename,
bool isTempFile )
946 assert( !mDirmngrProc );
947 mImportCRLTempFile = isTempFile ? filename : TQString();
948 mDirmngrProc =
new TDEProcess();
949 *mDirmngrProc <<
"gpgsm" <<
"--call-dirmngr" <<
"loadcrl" << filename;
950 if ( !connectAndStartDirmngr( TQ_SLOT(slotDirmngrExited()),
"gpgsm" ) ) {
951 updateImportActions(
true );
953 TQFile::remove( mImportCRLTempFile );
957 void CertManager::startClearCRLs() {
958 assert( !mDirmngrProc );
959 mDirmngrProc =
new TDEProcess();
960 *mDirmngrProc <<
"dirmngr" <<
"--flush";
962 connectAndStartDirmngr( TQ_SLOT(slotClearCRLsResult()),
"dirmngr" );
965 void CertManager::slotStderr( TDEProcess*,
char* buf,
int len ) {
966 mErrorbuffer += TQString::fromLocal8Bit( buf, len );
972 void CertManager::importCRLFromLDAP()
974 tqDebug(
"Not Yet Implemented");
977 void CertManager::slotViewCRLs() {
979 mCrlView =
new CRLView(
this );
982 mCrlView->slotUpdateView();
986 void CertManager::slotClearCRLs() {
990 void CertManager::slotClearCRLsResult() {
991 assert( mDirmngrProc );
992 if ( !mDirmngrProc->normalExit() )
993 KMessageBox::error(
this, i18n(
"The DirMngr process that tried to clear the CRL cache ended prematurely because of an unexpected error." ), i18n(
"Certificate Manager Error" ) );
994 else if ( mDirmngrProc->exitStatus() )
995 KMessageBox::error(
this, i18n(
"An error occurred when trying to clear the CRL cache. The output from DirMngr was:\n%1").arg( mErrorbuffer ), i18n(
"Certificate Manager Error" ) );
997 KMessageBox::information(
this, i18n(
"CRL cache cleared successfully." ), i18n(
"Certificate Manager Information" ) );
998 delete mDirmngrProc; mDirmngrProc = 0;
1001 static void showDeleteError( TQWidget * parent,
const GpgME::Error & err ) {
1003 const TQString msg = i18n(
"<qt><p>An error occurred while trying to delete "
1004 "the certificates:</p>"
1005 "<p><b>%1</b></p></qt>")
1006 .arg( TQString::fromLocal8Bit( err.asString() ) );
1007 KMessageBox::error( parent, msg, i18n(
"Certificate Deletion Failed") );
1010 static bool ByFingerprint(
const GpgME::Key & left,
const GpgME::Key & right ) {
1011 return tqstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) < 0 ;
1014 static bool WithRespectToFingerprints(
const GpgME::Key & left,
const GpgME::Key & right ) {
1015 return tqstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) == 0;
1018 void CertManager::slotDeleteCertificate() {
1019 mItemsToDelete = mKeyListView->selectedItems();
1020 if ( mItemsToDelete.isEmpty() )
1022 std::vector<GpgME::Key> keys;
1023 keys.reserve( mItemsToDelete.count() );
1024 TQStringList keyDisplayNames;
1025 for ( TQPtrListIterator<Kleo::KeyListViewItem> it( mItemsToDelete ) ; it.current() ; ++it )
1026 if ( !it.current()->key().isNull() ) {
1027 keys.push_back( it.current()->key() );
1028 keyDisplayNames.push_back( it.current()->text( 0 ) );
1033 if ( !mHierarchyAnalyser ) {
1034 mHierarchyAnalyser =
new HierarchyAnalyser(
this,
"mHierarchyAnalyser" );
1035 Kleo::KeyListJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob();
1037 connect( job, TQ_SIGNAL(nextKey(
const GpgME::Key&)),
1038 mHierarchyAnalyser, TQ_SLOT(slotNextKey(
const GpgME::Key&)) );
1039 connect( job, TQ_SIGNAL(result(
const GpgME::KeyListResult&)),
1040 this, TQ_SLOT(slotDeleteCertificate()) );
1041 connectJobToStatusBarProgress( job, i18n(
"Checking key dependencies...") );
1042 if (
const GpgME::Error error = job->start( TQStringList() ) ) {
1043 showKeyListError(
this, error );
1044 delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
1048 disconnectJobFromStatusBarProgress( 0 );
1050 std::vector<GpgME::Key> keysToDelete = keys;
1051 for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it )
1052 if ( !it->isNull() ) {
1053 const std::vector<GpgME::Key> subjects
1054 = mHierarchyAnalyser->subjectsForIssuerRecursive( it->primaryFingerprint() );
1055 keysToDelete.insert( keysToDelete.end(), subjects.begin(), subjects.end() );
1058 std::sort( keysToDelete.begin(), keysToDelete.end(), ByFingerprint );
1059 keysToDelete.erase( std::unique( keysToDelete.begin(), keysToDelete.end(),
1060 WithRespectToFingerprints ),
1061 keysToDelete.end() );
1063 delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
1065 if ( keysToDelete.size() > keys.size() )
1066 if ( KMessageBox::warningContinueCancel(
this,
1067 i18n(
"Some or all of the selected "
1068 "certificates are issuers (CA certificates) "
1069 "for other, non-selected certificates.\n"
1070 "Deleting a CA certificate will also delete "
1071 "all certificates issued by it."),
1072 i18n(
"Deleting CA Certificates") )
1073 != KMessageBox::Continue )
1076 const TQString msg = keysToDelete.size() > keys.size()
1077 ? i18n(
"Do you really want to delete this certificate and the %1 certificates it certified?",
1078 "Do you really want to delete these %n certificates and the %1 certificates they certified?",
1079 keys.size() ).arg( keysToDelete.size() - keys.size() )
1080 : i18n(
"Do you really want to delete this certificate?",
1081 "Do you really want to delete these %n certificates?", keys.size() ) ;
1083 if ( KMessageBox::warningContinueCancelList(
this, msg, keyDisplayNames,
1084 i18n(
"Delete Certificates" ),
1085 KGuiItem( i18n(
"Delete" ),
"edit-delete" ),
1086 "ConfirmDeleteCert", KMessageBox::Dangerous )
1087 != KMessageBox::Continue )
1090 if ( Kleo::DeleteJob * job = Kleo::CryptoBackendFactory::instance()->smime()->deleteJob() )
1093 TQString str = keys.size() == 1
1094 ? i18n(
"<qt><p>An error occurred while trying to delete "
1095 "the certificate:</p>"
1096 "<p><b>%1</b><p></qt>" )
1097 : i18n(
"<qt><p>An error occurred while trying to delete "
1098 "the certificates:</p>"
1099 "<p><b>%1</b><p></qt>" );
1100 KMessageBox::error(
this,
1101 str.arg( i18n(
"Operation not supported by the backend.") ),
1102 i18n(
"Certificate Deletion Failed") );
1105 mItemsToDelete.clear();
1106 for ( std::vector<GpgME::Key>::const_iterator it = keysToDelete.begin() ; it != keysToDelete.end() ; ++it )
1107 if ( Kleo::KeyListViewItem * item = mKeyListView->itemByFingerprint( it->primaryFingerprint() ) )
1108 mItemsToDelete.append( item );
1110 Kleo::MultiDeleteJob * job =
new Kleo::MultiDeleteJob( Kleo::CryptoBackendFactory::instance()->smime() );
1113 connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const GpgME::Key&)),
1114 TQ_SLOT(slotDeleteResult(
const GpgME::Error&,
const GpgME::Key&)) );
1116 connectJobToStatusBarProgress( job, i18n(
"Deleting keys...") );
1118 const GpgME::Error err = job->start( keys,
true );
1120 showDeleteError(
this, err );
1122 mProgressBar->setProgress( 0, 0 );
1125 void CertManager::slotDeleteResult(
const GpgME::Error & err,
const GpgME::Key & ) {
1127 showDeleteError(
this, err );
1129 const int infinity = 100;
1130 mItemsToDelete.setAutoDelete(
true );
1131 for (
int i = 0 ; i < infinity ; ++i ) {
1132 TQPtrListIterator<Kleo::KeyListViewItem> it( mItemsToDelete );
1133 while ( Kleo::KeyListViewItem * cur = it.current() ) {
1135 if ( cur->childCount() == 0 ) {
1136 mItemsToDelete.remove( cur );
1139 if ( mItemsToDelete.isEmpty() )
1142 mItemsToDelete.setAutoDelete(
false );
1143 Q_ASSERT( mItemsToDelete.isEmpty() );
1144 mItemsToDelete.clear();
1146 disconnectJobFromStatusBarProgress( err );
1149 void CertManager::slotViewDetails( Kleo::KeyListViewItem * item ) {
1150 if ( !item || item->key().isNull() )
1154 KDialogBase * dialog =
new KDialogBase(
this,
"dialog",
false, i18n(
"Additional Information for Key"), KDialogBase::Close, KDialogBase::Close );
1156 CertificateInfoWidgetImpl * top =
new CertificateInfoWidgetImpl( item->key(), isRemote(), dialog );
1157 dialog->setMainWidget( top );
1159 connect( top, TQ_SIGNAL(requestCertificateDownload(
const TQString&,
const TQString&)),
1160 TQ_SLOT(slotStartCertificateDownload(
const TQString&,
const TQString&)) );
1164 void CertManager::slotViewDetails()
1166 TQPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
1167 if ( items.isEmpty() )
1172 slotViewDetails( items.first() );
1175 void CertManager::slotSelectionChanged()
1177 mKeyListView->flushKeys();
1178 bool b = mKeyListView->hasSelection();
1179 mExportCertificateAction->setEnabled( b );
1180 mViewCertDetailsAction->setEnabled( b );
1181 mDeleteCertificateAction->setEnabled( b );
1182 #ifdef NOT_IMPLEMENTED_ANYWAY
1183 mRevokeCertificateAction->setEnabled( b );
1184 mExtendCertificateAction->setEnabled( b );
1186 mDownloadCertificateAction->setEnabled( b && mRemote );
1187 mValidateCertificateAction->setEnabled( !mRemote );
1190 void CertManager::slotExportCertificate() {
1191 TQPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
1192 if ( items.isEmpty() )
1195 TQStringList fingerprints;
1196 for ( TQPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
1197 if ( !it.current()->key().isNull() )
1198 if (
const char * fpr = it.current()->key().primaryFingerprint() )
1199 fingerprints.push_back( fpr );
1201 startCertificateExport( fingerprints );
1204 static void showCertificateExportError( TQWidget * parent,
const GpgME::Error & err ) {
1206 const TQString msg = i18n(
"<qt><p>An error occurred while trying to export "
1207 "the certificate:</p>"
1208 "<p><b>%1</b></p></qt>")
1209 .arg( TQString::fromLocal8Bit( err.asString() ) );
1210 KMessageBox::error( parent, msg, i18n(
"Certificate Export Failed") );
1213 void CertManager::startCertificateExport(
const TQStringList & fingerprints ) {
1214 if ( fingerprints.empty() )
1219 Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->publicKeyExportJob(
true );
1222 connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
1223 TQ_SLOT(slotCertificateExportResult(
const GpgME::Error&,
const TQByteArray&)) );
1225 connectJobToStatusBarProgress( job, i18n(
"Exporting certificate...") );
1227 const GpgME::Error err = job->start( fingerprints );
1229 showCertificateExportError(
this, err );
1231 mProgressBar->setProgress( 0, 0 );
1235 static bool checkOverwrite(
const KURL& url,
bool& overwrite, TQWidget* w )
1237 if ( TDEIO::NetAccess::exists( url,
false , w ) ) {
1238 if ( KMessageBox::Cancel ==
1239 KMessageBox::warningContinueCancel(
1241 i18n(
"A file named \"%1\" already exists. "
1242 "Are you sure you want to overwrite it?" ).arg( url.prettyURL() ),
1243 i18n(
"Overwrite File?" ),
1244 i18n(
"&Overwrite" ) ) )
1251 void CertManager::slotCertificateExportResult(
const GpgME::Error & err,
const TQByteArray & data ) {
1252 disconnectJobFromStatusBarProgress( err );
1254 showCertificateExportError(
this, err );
1258 kdDebug() <<
"CertManager::slotCertificateExportResult(): got " << data.size() <<
" bytes" << endl;
1260 const TQString filter = TQString(
"*.pem|") + i18n(
"ASCII Armored Certificate Bundles (*.pem)");
1261 const KURL url = KFileDialog::getOpenURL( TQString(),
1264 i18n(
"Save Certificate" ) );
1265 if ( !url.isValid() )
1268 bool overwrite =
false;
1269 if ( !checkOverwrite( url, overwrite,
this ) )
1272 TDEIO::Job* uploadJob = TDEIOext::put( data, url, -1, overwrite,
false );
1273 uploadJob->setWindow(
this );
1274 connect( uploadJob, TQ_SIGNAL( result( TDEIO::Job* ) ),
1275 this, TQ_SLOT( slotUploadResult( TDEIO::Job* ) ) );
1279 void CertManager::slotExportSecretKey() {
1280 Kleo::KeySelectionDialog dlg( i18n(
"Secret Key Export"),
1282 i18n(
"Select the secret key to export "
1283 "(<b>Warning: The PKCS#12 format is insecure; "
1284 "exporting secret keys is discouraged</b>):") +
1286 std::vector<GpgME::Key>(),
1287 Kleo::KeySelectionDialog::SecretKeys|Kleo::KeySelectionDialog::SMIMEKeys,
1290 this,
"secret key export key selection dialog" );
1293 if ( dlg.exec() != TQDialog::Accepted )
1296 startSecretKeyExport( dlg.fingerprint() );
1299 static void showSecretKeyExportError( TQWidget * parent,
const GpgME::Error & err ) {
1301 const TQString msg = i18n(
"<qt><p>An error occurred while trying to export "
1302 "the secret key:</p>"
1303 "<p><b>%1</b></p></qt>")
1304 .arg( TQString::fromLocal8Bit( err.asString() ) );
1305 KMessageBox::error( parent, msg, i18n(
"Secret-Key Export Failed") );
1308 void CertManager::startSecretKeyExport(
const TQString & fingerprint ) {
1309 if ( fingerprint.isEmpty() )
1315 Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config();
1317 if ( config && config->entry(
"gpgsm",
"Configuration",
"p12-charset" ) ) {
1320 static const char *charsets[] = {
1339 TQStringList charsetList;
1340 for (
const char** c = charsets; *c; ++c ) {
1341 charsetList.append( TQString::fromLatin1( *c ) );
1347 charset = KInputDialog::getItem( i18n(
"Exporting secret key..."),
1348 i18n(
"Choose a charset for encoding the pkcs#12 passphrase (utf8 is recommended)"),
1356 Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->secretKeyExportJob(
false, charset );
1359 connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
1360 TQ_SLOT(slotSecretKeyExportResult(
const GpgME::Error&,
const TQByteArray&)) );
1362 connectJobToStatusBarProgress( job, i18n(
"Exporting secret key...") );
1364 const GpgME::Error err = job->start( fingerprint );
1366 showSecretKeyExportError(
this, err );
1368 mProgressBar->setProgress( 0, 0 );
1371 void CertManager::slotSecretKeyExportResult(
const GpgME::Error & err,
const TQByteArray & data ) {
1372 disconnectJobFromStatusBarProgress( err );
1374 showSecretKeyExportError(
this, err );
1378 kdDebug() <<
"CertManager::slotSecretKeyExportResult(): got " << data.size() <<
" bytes" << endl;
1379 TQString filter = TQString(
"*.p12|") + i18n(
"PKCS#12 Key Bundle (*.p12)");
1380 KURL url = KFileDialog::getOpenURL( TQString(),
1383 i18n(
"Save Certificate" ) );
1384 if ( !url.isValid() )
1387 bool overwrite =
false;
1388 if ( !checkOverwrite( url, overwrite,
this ) )
1391 TDEIO::Job* uploadJob = TDEIOext::put( data, url, -1, overwrite,
false );
1392 uploadJob->setWindow(
this );
1393 connect( uploadJob, TQ_SIGNAL( result( TDEIO::Job* ) ),
1394 this, TQ_SLOT( slotUploadResult( TDEIO::Job* ) ) );
1397 void CertManager::slotUploadResult( TDEIO::Job* job )
1400 job->showErrorDialog();
1403 void CertManager::slotDropped(
const KURL::List& lst)
1405 mURLsToImport = lst;
1407 importNextURLOrRedisplay();
1410 void CertManager::importNextURLOrRedisplay()
1412 if ( !mURLsToImport.empty() ) {
1414 KURL url = mURLsToImport.front();
1415 mURLsToImport.pop_front();
1416 slotImportCertFromFile( url );
1420 startKeyListing(
false,
true, mPreviouslySelectedFingerprints );
1424 void CertManager::slotStartWatchGnuPG()
1426 TDEProcess certManagerProc;
1427 certManagerProc <<
"kwatchgnupg";
1429 if( !certManagerProc.start( TDEProcess::DontCare ) )
1430 KMessageBox::error(
this, i18n(
"Could not start GnuPG LogViewer (kwatchgnupg). "
1431 "Please check your installation!" ),
1432 i18n(
"Kleopatra Error" ) );
1435 #include "certmanager.moc"
We need to derive from Kleo::KeyListView simply to add support for drop events.
StoredTransferJob is a TransferJob (for downloading or uploading data) that also stores a TQByteArray...
TQByteArray data() const
Get hold of the downloaded data.