certmanager/lib Library API Documentation

keyrequester.cpp

00001 /* -*- c++ -*- 00002 keyrequester.cpp 00003 00004 This file is part of libkleopatra, the KDE keymanagement library 00005 Copyright (c) 2004 Klarälvdalens Datakonsult AB 00006 00007 Libkleopatra is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU General Public License as 00009 published by the Free Software Foundation; either version 2 of the 00010 License, or (at your option) any later version. 00011 00012 Libkleopatra is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 00021 In addition, as a special exception, the copyright holders give 00022 permission to link the code of this program with any edition of 00023 the Qt library by Trolltech AS, Norway (or with modified versions 00024 of Qt that use the same license as Qt), and distribute linked 00025 combinations including the two. You must obey the GNU General 00026 Public License in all respects for all of the code used other than 00027 Qt. If you modify this file, you may extend this exception to 00028 your version of the file, but you are not obligated to do so. If 00029 you do not wish to do so, delete this exception statement from 00030 your version. 00031 00032 00033 Based on kpgpui.cpp 00034 Copyright (C) 2001,2002 the KPGP authors 00035 See file libkdenetwork/AUTHORS.kpgp for details 00036 00037 This file is part of KPGP, the KDE PGP/GnuPG support library. 00038 00039 KPGP is free software; you can redistribute it and/or modify 00040 it under the terms of the GNU General Public License as published by 00041 the Free Software Foundation; either version 2 of the License, or 00042 (at your option) any later version. 00043 00044 You should have received a copy of the GNU General Public License 00045 along with this program; if not, write to the Free Software Foundation, 00046 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00047 */ 00048 00049 #ifdef HAVE_CONFIG_H 00050 #include <config.h> 00051 #endif 00052 00053 #include "keyrequester.h" 00054 00055 #include "keyselectiondialog.h" 00056 00057 #include <kleo/keylistjob.h> 00058 #include <kleo/dn.h> 00059 #include <kleo/cryptobackendfactory.h> 00060 00061 // gpgme++ 00062 #include <gpgmepp/key.h> 00063 #include <gpgmepp/keylistresult.h> 00064 00065 // KDE 00066 #include <klocale.h> 00067 #include <kiconloader.h> 00068 #include <kdialog.h> 00069 #include <kdebug.h> 00070 #include <kmessagebox.h> 00071 00072 // Qt 00073 #include <qpushbutton.h> 00074 #include <qlayout.h> 00075 #include <qtooltip.h> 00076 #include <qstring.h> 00077 #include <qstringlist.h> 00078 #include <qlabel.h> 00079 #include <qregexp.h> 00080 00081 #include <assert.h> 00082 00083 Kleo::KeyRequester::KeyRequester( unsigned int allowedKeys, bool multipleKeys, 00084 QWidget * parent, const char * name ) 00085 : QWidget( parent, name ), 00086 mOpenPGPBackend( 0 ), 00087 mSMIMEBackend( 0 ), 00088 mMulti( multipleKeys ), 00089 mKeyUsage( allowedKeys ), 00090 mJobs( 0 ), 00091 d( 0 ) 00092 { 00093 init(); 00094 } 00095 00096 Kleo::KeyRequester::KeyRequester( QWidget * parent, const char * name ) 00097 : QWidget( parent, name ), 00098 mOpenPGPBackend( 0 ), 00099 mSMIMEBackend( 0 ), 00100 mMulti( false ), 00101 mKeyUsage( 0 ), 00102 mJobs( 0 ), 00103 d( 0 ) 00104 { 00105 init(); 00106 } 00107 00108 void Kleo::KeyRequester::init() 00109 { 00110 QHBoxLayout * hlay = new QHBoxLayout( this, 0, KDialog::spacingHint() ); 00111 00112 // the label where the key id is to be displayed: 00113 mLabel = new QLabel( this ); 00114 mLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken ); 00115 00116 // the button to unset any key: 00117 mEraseButton = new QPushButton( this ); 00118 mEraseButton->setAutoDefault( false ); 00119 mEraseButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, 00120 QSizePolicy::Minimum ) ); 00121 mEraseButton->setPixmap( SmallIcon( "clear_left" ) ); 00122 QToolTip::add( mEraseButton, i18n("Clear") ); 00123 00124 // the button to call the KeySelectionDialog: 00125 mDialogButton = new QPushButton( i18n("Change..."), this ); 00126 mDialogButton->setAutoDefault( false ); 00127 00128 hlay->addWidget( mLabel, 1 ); 00129 hlay->addWidget( mEraseButton ); 00130 hlay->addWidget( mDialogButton ); 00131 00132 connect( mEraseButton, SIGNAL(clicked()), SLOT(slotEraseButtonClicked()) ); 00133 connect( mDialogButton, SIGNAL(clicked()), SLOT(slotDialogButtonClicked()) ); 00134 00135 setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, 00136 QSizePolicy::Fixed ) ); 00137 00138 setAllowedKeys( mKeyUsage ); 00139 } 00140 00141 Kleo::KeyRequester::~KeyRequester() { 00142 00143 } 00144 00145 const std::vector<GpgME::Key> & Kleo::KeyRequester::keys() const { 00146 return mKeys; 00147 } 00148 00149 const GpgME::Key & Kleo::KeyRequester::key() const { 00150 if ( mKeys.empty() ) 00151 return GpgME::Key::null; 00152 else 00153 return mKeys.front(); 00154 } 00155 00156 void Kleo::KeyRequester::setKeys( const std::vector<GpgME::Key> & keys ) { 00157 mKeys.clear(); 00158 for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it ) 00159 if ( !it->isNull() ) 00160 mKeys.push_back( *it ); 00161 updateKeys(); 00162 } 00163 00164 void Kleo::KeyRequester::setKey( const GpgME::Key & key ) { 00165 mKeys.clear(); 00166 if ( !key.isNull() ) 00167 mKeys.push_back( key ); 00168 updateKeys(); 00169 } 00170 00171 QString Kleo::KeyRequester::fingerprint() const { 00172 if ( mKeys.empty() ) 00173 return QString::null; 00174 else 00175 return mKeys.front().subkey(0).fingerprint(); 00176 } 00177 00178 QStringList Kleo::KeyRequester::fingerprints() const { 00179 QStringList result; 00180 for ( std::vector<GpgME::Key>::const_iterator it = mKeys.begin() ; it != mKeys.end() ; ++it ) 00181 if ( !it->isNull() ) 00182 if ( const char * fpr = it->subkey(0).fingerprint() ) 00183 result.push_back( fpr ); 00184 return result; 00185 } 00186 00187 void Kleo::KeyRequester::setFingerprint( const QString & fingerprint ) { 00188 startKeyListJob( fingerprint ); 00189 } 00190 00191 void Kleo::KeyRequester::setFingerprints( const QStringList & fingerprints ) { 00192 startKeyListJob( fingerprints ); 00193 } 00194 00195 void Kleo::KeyRequester::updateKeys() { 00196 if ( mKeys.empty() ) { 00197 mLabel->clear(); 00198 return; 00199 } 00200 if ( mKeys.size() > 1 ) 00201 setMultipleKeysEnabled( true ); 00202 00203 QStringList labelTexts; 00204 QString toolTipText; 00205 for ( std::vector<GpgME::Key>::const_iterator it = mKeys.begin() ; it != mKeys.end() ; ++it ) { 00206 if ( it->isNull() ) 00207 continue; 00208 const QString fpr = it->subkey(0).fingerprint(); 00209 labelTexts.push_back( fpr.right(8) ); 00210 toolTipText += fpr.right(8) + ": "; 00211 if ( const char * uid = it->userID(0).id() ) 00212 if ( it->protocol() == GpgME::Context::OpenPGP ) 00213 toolTipText += QString::fromUtf8( uid ); 00214 else 00215 toolTipText += Kleo::DN( uid ).prettyDN(); 00216 else 00217 toolTipText += i18n("<unknown>"); 00218 toolTipText += '\n'; 00219 } 00220 00221 mLabel->setText( labelTexts.join(", ") ); 00222 QToolTip::remove( mLabel ); 00223 QToolTip::add( mLabel, toolTipText ); 00224 } 00225 00226 static void showKeyListError( QWidget * parent, const GpgME::Error & err ) { 00227 assert( err ); 00228 const QString msg = i18n( "<qt><p>An error occurred while fetching " 00229 "the keys from the backend:</p>" 00230 "<p><b>%1</b></p></qt>" ) 00231 .arg( QString::fromLocal8Bit( err.asString() ) ); 00232 00233 KMessageBox::error( parent, msg, i18n( "Key Listing Failed" ) ); 00234 } 00235 00236 void Kleo::KeyRequester::startKeyListJob( const QStringList & fingerprints ) { 00237 if ( !mSMIMEBackend && !mOpenPGPBackend ) 00238 return; 00239 00240 mTmpKeys.clear(); 00241 mJobs = 0; 00242 00243 unsigned int count = 0; 00244 for ( QStringList::const_iterator it = fingerprints.begin() ; it != fingerprints.end() ; ++it ) 00245 if ( !(*it).stripWhiteSpace().isEmpty() ) 00246 ++count; 00247 00248 if ( !count ) { 00249 // don't fall into the trap that an empty pattern means 00250 // "return all keys" :) 00251 setKey( GpgME::Key::null ); 00252 return; 00253 } 00254 00255 if ( mOpenPGPBackend ) { 00256 KeyListJob * job = mOpenPGPBackend->keyListJob( false ); // local, no sigs 00257 if ( !job ) { 00258 KMessageBox::error( this, 00259 i18n("The OpenPGP backend does not support listing keys. " 00260 "Check your installation."), 00261 i18n("Key Listing Failed") ); 00262 } else { 00263 connect( job, SIGNAL(result(const GpgME::KeyListResult&)), 00264 SLOT(slotKeyListResult(const GpgME::KeyListResult&)) ); 00265 connect( job, SIGNAL(nextKey(const GpgME::Key&)), 00266 SLOT(slotNextKey(const GpgME::Key&)) ); 00267 00268 const GpgME::Error err = job->start( fingerprints, 00269 mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && 00270 !( mKeyUsage & Kleo::KeySelectionDialog::PublicKeys ) ); 00271 00272 if ( err ) 00273 showKeyListError( this, err ); 00274 else 00275 ++mJobs; 00276 } 00277 } 00278 00279 if ( mSMIMEBackend ) { 00280 KeyListJob * job = mSMIMEBackend->keyListJob( false ); // local, no sigs 00281 if ( !job ) { 00282 KMessageBox::error( this, 00283 i18n("The S/MIME backend does not support listing keys. " 00284 "Check your installation."), 00285 i18n("Key Listing Failed") ); 00286 } else { 00287 connect( job, SIGNAL(result(const GpgME::KeyListResult&)), 00288 SLOT(slotKeyListResult(const GpgME::KeyListResult&)) ); 00289 connect( job, SIGNAL(nextKey(const GpgME::Key&)), 00290 SLOT(slotNextKey(const GpgME::Key&)) ); 00291 00292 const GpgME::Error err = job->start( fingerprints, 00293 mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && 00294 !( mKeyUsage & Kleo::KeySelectionDialog::PublicKeys ) ); 00295 00296 if ( err ) 00297 showKeyListError( this, err ); 00298 else 00299 ++mJobs; 00300 } 00301 } 00302 00303 if ( mJobs > 0 ) { 00304 mEraseButton->setEnabled( false ); 00305 mDialogButton->setEnabled( false ); 00306 } 00307 } 00308 00309 void Kleo::KeyRequester::slotNextKey( const GpgME::Key & key ) { 00310 if ( !key.isNull() ) 00311 mTmpKeys.push_back( key ); 00312 } 00313 00314 void Kleo::KeyRequester::slotKeyListResult( const GpgME::KeyListResult & res ) { 00315 if ( res.error() ) 00316 showKeyListError( this, res.error() ); 00317 00318 if ( --mJobs <= 0 ) { 00319 mEraseButton->setEnabled( true ); 00320 mDialogButton->setEnabled( true ); 00321 00322 setKeys( mTmpKeys ); 00323 mTmpKeys.clear(); 00324 } 00325 } 00326 00327 00328 void Kleo::KeyRequester::slotDialogButtonClicked() { 00329 KeySelectionDialog * dlg = mKeys.empty() 00330 ? new KeySelectionDialog( mDialogCaption, mDialogMessage, mInitialQuery, mKeyUsage, mMulti ) 00331 : new KeySelectionDialog( mDialogCaption, mDialogCaption, mKeys, mKeyUsage, mMulti ) ; 00332 00333 if ( dlg->exec() == QDialog::Accepted ) { 00334 if ( mMulti ) 00335 setKeys( dlg->selectedKeys() ); 00336 else 00337 setKey( dlg->selectedKey() ); 00338 emit changed(); 00339 } 00340 00341 delete dlg; 00342 } 00343 00344 void Kleo::KeyRequester::slotEraseButtonClicked() { 00345 if ( !mKeys.empty() ) 00346 emit changed(); 00347 mKeys.clear(); 00348 updateKeys(); 00349 } 00350 00351 void Kleo::KeyRequester::setDialogCaption( const QString & caption ) { 00352 mDialogCaption = caption; 00353 } 00354 00355 void Kleo::KeyRequester::setDialogMessage( const QString & msg ) { 00356 mDialogMessage = msg; 00357 } 00358 00359 bool Kleo::KeyRequester::isMultipleKeysEnabled() const { 00360 return mMulti; 00361 } 00362 00363 void Kleo::KeyRequester::setMultipleKeysEnabled( bool multi ) { 00364 if ( multi == mMulti ) return; 00365 00366 if ( !multi && !mKeys.empty() ) 00367 mKeys.erase( mKeys.begin() + 1, mKeys.end() ); 00368 00369 mMulti = multi; 00370 updateKeys(); 00371 } 00372 00373 unsigned int Kleo::KeyRequester::allowedKeys() const { 00374 return mKeyUsage; 00375 } 00376 00377 void Kleo::KeyRequester::setAllowedKeys( unsigned int keyUsage ) { 00378 mKeyUsage = keyUsage; 00379 mOpenPGPBackend = 0; 00380 mSMIMEBackend = 0; 00381 00382 if ( mKeyUsage & KeySelectionDialog::OpenPGPKeys ) 00383 mOpenPGPBackend = Kleo::CryptoBackendFactory::instance()->openpgp(); 00384 if ( mKeyUsage & KeySelectionDialog::SMIMEKeys ) 00385 mSMIMEBackend = Kleo::CryptoBackendFactory::instance()->smime(); 00386 00387 if ( mOpenPGPBackend && !mSMIMEBackend ) { 00388 mDialogCaption = i18n("OpenPGP Key Selection"); 00389 mDialogMessage = i18n("Please select an OpenPGP key to use."); 00390 } else if ( !mOpenPGPBackend && mSMIMEBackend ) { 00391 mDialogCaption = i18n("S/MIME Key Selection"); 00392 mDialogMessage = i18n("Please select an S/MIME key to use."); 00393 } else { 00394 mDialogCaption = i18n("Key Selection"); 00395 mDialogMessage = i18n("Please select an (OpenPGP or S/MIME) key to use."); 00396 } 00397 } 00398 00399 QPushButton * Kleo::KeyRequester::dialogButton() { 00400 return mDialogButton; 00401 } 00402 00403 QPushButton * Kleo::KeyRequester::eraseButton() { 00404 return mEraseButton; 00405 } 00406 00407 static inline unsigned int foo( bool openpgp, bool smime, bool trusted, bool valid ) { 00408 unsigned int result = 0; 00409 if ( openpgp ) 00410 result |= Kleo::KeySelectionDialog::OpenPGPKeys; 00411 if ( smime ) 00412 result |= Kleo::KeySelectionDialog::SMIMEKeys; 00413 if ( trusted ) 00414 result |= Kleo::KeySelectionDialog::TrustedKeys; 00415 if ( valid ) 00416 result |= Kleo::KeySelectionDialog::ValidKeys; 00417 return result; 00418 } 00419 00420 static inline unsigned int encryptionKeyUsage( bool openpgp, bool smime, bool trusted, bool valid ) { 00421 return foo( openpgp, smime, trusted, valid ) | Kleo::KeySelectionDialog::EncryptionKeys | Kleo::KeySelectionDialog::PublicKeys; 00422 } 00423 00424 static inline unsigned int signingKeyUsage( bool openpgp, bool smime, bool trusted, bool valid ) { 00425 return foo( openpgp, smime, trusted, valid ) | Kleo::KeySelectionDialog::SigningKeys | Kleo::KeySelectionDialog::SecretKeys; 00426 } 00427 00428 Kleo::EncryptionKeyRequester::EncryptionKeyRequester( bool multi, unsigned int proto, 00429 QWidget * parent, const char * name, 00430 bool onlyTrusted, bool onlyValid ) 00431 : KeyRequester( encryptionKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ), multi, 00432 parent, name ) 00433 { 00434 } 00435 00436 Kleo::EncryptionKeyRequester::EncryptionKeyRequester( QWidget * parent, const char * name ) 00437 : KeyRequester( 0, false, parent, name ) 00438 { 00439 } 00440 00441 Kleo::EncryptionKeyRequester::~EncryptionKeyRequester() {} 00442 00443 00444 void Kleo::EncryptionKeyRequester::setAllowedKeys( unsigned int proto, bool onlyTrusted, bool onlyValid ) 00445 { 00446 KeyRequester::setAllowedKeys( encryptionKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ) ); 00447 } 00448 00449 Kleo::SigningKeyRequester::SigningKeyRequester( bool multi, unsigned int proto, 00450 QWidget * parent, const char * name, 00451 bool onlyTrusted, bool onlyValid ) 00452 : KeyRequester( signingKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ), multi, 00453 parent, name ) 00454 { 00455 } 00456 00457 Kleo::SigningKeyRequester::SigningKeyRequester( QWidget * parent, const char * name ) 00458 : KeyRequester( 0, false, parent, name ) 00459 { 00460 } 00461 00462 Kleo::SigningKeyRequester::~SigningKeyRequester() {} 00463 00464 void Kleo::SigningKeyRequester::setAllowedKeys( unsigned int proto, bool onlyTrusted, bool onlyValid ) 00465 { 00466 KeyRequester::setAllowedKeys( signingKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ) ); 00467 } 00468 00469 void Kleo::KeyRequester::virtual_hook( int, void* ) {} 00470 void Kleo::EncryptionKeyRequester::virtual_hook( int id, void * data ) { 00471 KeyRequester::virtual_hook( id, data ); 00472 } 00473 void Kleo::SigningKeyRequester::virtual_hook( int id, void * data ) { 00474 KeyRequester::virtual_hook( id, data ); 00475 } 00476 00477 #include "keyrequester.moc"
KDE Logo
This file is part of the documentation for certmanager/lib Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 27 12:50:05 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003