00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
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
00062
#include <gpgmepp/key.h>
00063
#include <gpgmepp/keylistresult.h>
00064
00065
00066
#include <klocale.h>
00067
#include <kiconloader.h>
00068
#include <kdialog.h>
00069
#include <kdebug.h>
00070
#include <kmessagebox.h>
00071
00072
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
00113 mLabel =
new QLabel(
this );
00114 mLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken );
00115
00116
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
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
00250
00251
setKey( GpgME::Key::null );
00252
return;
00253 }
00254
00255
if ( mOpenPGPBackend ) {
00256 KeyListJob * job = mOpenPGPBackend->keyListJob(
false );
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 );
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"