00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <time.h>
00021 #include <stdlib.h>
00022 #include <assert.h>
00023 #include <stdarg.h>
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026 #include <string.h>
00027 #include <sys/socket.h>
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <sys/wait.h>
00031 #include <signal.h>
00032
00033 #include <qlabel.h>
00034 #include <qcursor.h>
00035 #include <qapplication.h>
00036
00037 #include <kdebug.h>
00038 #include <klocale.h>
00039 #include <kmessagebox.h>
00040 #include <kconfigbase.h>
00041 #include <kconfig.h>
00042 #include <kstaticdeleter.h>
00043
00044 #include "kpgpbase.h"
00045 #include "kpgpui.h"
00046 #include "kpgp.h"
00047
00048 namespace Kpgp {
00049
00050 Module *Module::kpgpObject = 0L;
00051 static KStaticDeleter<Module> kpgpod;
00052
00053 Module::Module()
00054 : mPublicKeys(),
00055 mPublicKeysCached(false),
00056 mSecretKeys(),
00057 mSecretKeysCached(false),
00058 passphrase(0), passphrase_buffer_len(0), havePassPhrase(false)
00059 {
00060 if (!kpgpObject) {
00061 kdDebug(5100) << "creating new pgp object" << endl;
00062 }
00063 kpgpObject=kpgpod.setObject(Module::kpgpObject, this);
00064 pgp = 0;
00065
00066 config = new KConfig("kpgprc");
00067
00068 init();
00069 }
00070
00071 Module::~Module()
00072 {
00073 writeAddressData();
00074
00075 if (kpgpObject == this) kpgpObject = kpgpod.setObject( Module::kpgpObject, 0, false );
00076 clear(TRUE);
00077 delete config;
00078 delete pgp;
00079 }
00080
00081
00082
00083 void
00084 Module::init()
00085 {
00086 wipePassPhrase();
00087
00088
00089 readConfig();
00090
00091
00092
00093 readAddressData();
00094
00095
00096 checkForPGP();
00097
00098
00099
00100
00101
00102 delete pgp;
00103 pgp=0;
00104 }
00105
00106
00107 void
00108 Module::readConfig()
00109 {
00110 storePass = config->readBoolEntry("storePass", false);
00111 showEncryptionResult = config->readBoolEntry("showEncryptionResult", true);
00112 mShowKeyApprovalDlg = config->readBoolEntry( "showKeysForApproval", true );
00113
00114
00116 pgpType = tAuto;
00117 flagEncryptToSelf = config->readBoolEntry("encryptToSelf", true);
00118 }
00119
00120 void
00121 Module::writeConfig(bool sync)
00122 {
00123 config->writeEntry("storePass", storePass);
00124 config->writeEntry("showEncryptionResult", showEncryptionResult);
00125 config->writeEntry( "showKeysForApproval", mShowKeyApprovalDlg );
00126
00127 config->writeEntry("encryptToSelf", flagEncryptToSelf);
00128
00129 if(sync)
00130 config->sync();
00131
00134 delete pgp;
00135 pgp = 0;
00136 }
00137
00138
00139 void
00140 Module::setUser(const KeyID& keyID)
00141 {
00142 if (pgpUser != keyID) {
00143 pgpUser = keyID;
00144 wipePassPhrase();
00145 }
00146 }
00147
00148 const KeyID
00149 Module::user(void) const
00150 {
00151 return pgpUser;
00152 }
00153
00154
00155 void
00156 Module::setEncryptToSelf(bool flag)
00157 {
00158 flagEncryptToSelf = flag;
00159 }
00160
00161 bool
00162 Module::encryptToSelf(void) const
00163 {
00164 return flagEncryptToSelf;
00165 }
00166
00167
00168 void
00169 Module::setStorePassPhrase(bool flag)
00170 {
00171 storePass = flag;
00172 }
00173
00174 bool
00175 Module::storePassPhrase(void) const
00176 {
00177 return storePass;
00178 }
00179
00180 int
00181 Module::prepare( bool needPassPhrase, Block* block )
00182 {
00183 if (0 == pgp) assignPGPBase();
00184
00185 if(!havePgp)
00186 {
00187 errMsg = i18n("Could not find PGP executable.\n"
00188 "Please check your PATH is set correctly.");
00189 return 0;
00190 }
00191
00192 if( block && ( block->status() & NO_SEC_KEY ) )
00193 return 0;
00194
00195 if(needPassPhrase && !havePassPhrase) {
00196 if( ( tGPG == pgpType ) && ( 0 != getenv("GPG_AGENT_INFO") ) ) {
00197
00198 kdDebug(5100) << "user uses gpg-agent -> don't ask for passphrase\n";
00199
00200 setPassPhrase( "dummy" );
00201 }
00202 else {
00203 QString ID;
00204 if( block )
00205 ID = block->requiredUserId();
00206 PassphraseDialog passdlg(0, i18n("OpenPGP Security Check"), true, ID);
00207 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00208 int passdlgResult = passdlg.exec();
00209 QApplication::restoreOverrideCursor();
00210 if (passdlgResult == QDialog::Accepted) {
00211 if (!setPassPhrase(passdlg.passphrase())) {
00212 if (strlen(passdlg.passphrase()) >= 1024)
00213 errMsg = i18n("Passphrase is too long, it must contain fewer than 1024 characters.");
00214 else
00215 errMsg = i18n("Out of memory.");
00216 return 0;
00217 }
00218 } else {
00219 wipePassPhrase();
00220 return -1;
00221 }
00222 }
00223 }
00224 return 1;
00225 }
00226
00227 void
00228 Module::wipePassPhrase(bool freeMem)
00229 {
00230 if ( passphrase ) {
00231 if ( passphrase_buffer_len )
00232 memset( passphrase, 0x00, passphrase_buffer_len );
00233 else {
00234 kdDebug(5100) << "wipePassPhrase: passphrase && !passphrase_buffer_len ???" << endl;
00235 passphrase = 0;
00236 }
00237 }
00238 if ( freeMem && passphrase ) {
00239 free( passphrase );
00240 passphrase = 0;
00241 passphrase_buffer_len = 0;
00242 }
00243 havePassPhrase = false;
00244 }
00245
00246 bool
00247 Module::verify( Block& block )
00248 {
00249 int retval;
00250
00251 if (0 == pgp) assignPGPBase();
00252
00253
00254 if( !prepare( false, &block ) )
00255 return false;
00256
00257 retval = pgp->verify( block );
00258
00259 if(retval & ERROR)
00260 {
00261 errMsg = pgp->lastErrorMessage();
00262 return false;
00263 }
00264 return true;
00265 }
00266
00267 bool
00268 Module::decrypt( Block& block )
00269 {
00270 int retval;
00271
00272 if (0 == pgp) assignPGPBase();
00273
00274 do {
00275
00276
00277 if( prepare( true, &block ) != 1 )
00278 return FALSE;
00279
00280 retval = pgp->decrypt( block, passphrase );
00281
00282 if( retval & BADPHRASE ) {
00283 wipePassPhrase();
00284 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00285 int ret = KMessageBox::warningContinueCancel(0,
00286 i18n("You just entered an invalid passphrase.\n"
00287 "Do you want to try again, or "
00288 "cancel and view the message undecrypted?"),
00289 i18n("PGP Warning"), i18n("&Retry"));
00290 QApplication::restoreOverrideCursor();
00291 if ( ret == KMessageBox::Cancel ) break;
00292 } else
00293 break;
00294 } while ( true );
00295
00296
00297 cleanupPass();
00298
00299 if(retval & ERROR)
00300 {
00301 errMsg = pgp->lastErrorMessage();
00302 return false;
00303 }
00304 return true;
00305 }
00306
00307 Kpgp::Result
00308 Module::clearsign( Block& block,
00309 const KeyID& keyId, const QCString& charset )
00310 {
00311 return encrypt( block, QStringList(), keyId, true, charset );
00312 }
00313
00314 Kpgp::Result
00315 Module::encrypt( Block& block,
00316 const QStringList& receivers, const KeyID& keyId,
00317 bool sign, const QCString& charset )
00318 {
00319 KeyIDList encryptionKeyIds;
00320 int status = 0;
00321 errMsg = "";
00322
00323 if( 0 == pgp ) assignPGPBase();
00324
00325 setUser( keyId );
00326
00327 if( !receivers.empty() ) {
00328 Kpgp::Result result = getEncryptionKeys( encryptionKeyIds, receivers,
00329 keyId );
00330 if( Kpgp::Ok != result ) {
00331 return result;
00332 }
00333 }
00334
00335 status = doEncSign( block, encryptionKeyIds, sign );
00336
00337 if( status & CANCEL )
00338 return Kpgp::Canceled;
00339
00340
00341 while( status & BADPHRASE ) {
00342 wipePassPhrase();
00343 QString str = i18n("You entered an invalid passphrase.\n"
00344 "Do you want to try again, continue and leave the "
00345 "message unsigned, or cancel sending the message?");
00346 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00347 int ret = KMessageBox::warningYesNoCancel( 0, str,
00348 i18n("PGP Warning"),
00349 i18n("&Retry"),
00350 i18n("Send &Unsigned") );
00351 QApplication::restoreOverrideCursor();
00352 if( ret == KMessageBox::Cancel ) {
00353 return Kpgp::Canceled;
00354 }
00355 if( ret == KMessageBox::No ) {
00356
00357 if( encryptionKeyIds.isEmpty() ) {
00358 block.reset();
00359 return Kpgp::Ok;
00360 }
00361 else {
00362 sign = false;
00363 }
00364 }
00365
00366 status = doEncSign( block, encryptionKeyIds, sign );
00367 }
00368
00369
00370 if( status & ERR_SIGNING ) {
00371 QString str = i18n("%1 = 'signing failed' error message",
00372 "%1\nDo you want to send the message unsigned, "
00373 "or cancel sending the message?")
00374 .arg( pgp->lastErrorMessage() );
00375 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00376 int ret = KMessageBox::warningContinueCancel( 0, str,
00377 i18n("PGP Warning"),
00378 i18n("Send &Unsigned") );
00379 QApplication::restoreOverrideCursor();
00380 if( ret == KMessageBox::Cancel ) {
00381 return Kpgp::Canceled;
00382 }
00383 sign = false;
00384 status = doEncSign( block, encryptionKeyIds, sign );
00385 }
00386
00387
00388 if( status & BADKEYS ) {
00389 QString str = i18n("%1 = 'bad keys' error message",
00390 "%1\nDo you want to encrypt anyway, leave the "
00391 "message as-is, or cancel sending the message?")
00392 .arg( pgp->lastErrorMessage() );
00393
00394 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00395 int ret = KMessageBox::warningYesNoCancel( 0, str,
00396 i18n("PGP Warning"),
00397 i18n("Send &Encrypted"),
00398 i18n("Send &Unencrypted") );
00399 QApplication::restoreOverrideCursor();
00400 if( ret == KMessageBox::Cancel ) {
00401 return Kpgp::Canceled;
00402 }
00403 if( ret == KMessageBox::No ) {
00404
00405 if( sign ) {
00406 doEncSign( block, KeyIDList(), sign );
00407 }
00408 else {
00409 block.reset();
00410 }
00411 return Kpgp::Ok;
00412 }
00413 }
00414
00415 if( status & MISSINGKEY ) {
00416 QString str = i18n("%1 = 'missing keys' error message",
00417 "%1\nDo you want to leave the message as-is, "
00418 "or cancel sending the message?")
00419 .arg( pgp->lastErrorMessage() );
00420 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00421 int ret = KMessageBox::warningContinueCancel( 0, str,
00422 i18n("PGP Warning"),
00423 i18n("&Send As-Is") );
00424 QApplication::restoreOverrideCursor();
00425 if( ret == KMessageBox::Cancel ) {
00426 return Kpgp::Canceled;
00427 }
00428 block.reset();
00429 return Kpgp::Ok;
00430 }
00431
00432 if( status & ERROR ) {
00433
00434 errMsg = i18n( "The following error occurred:\n%1" )
00435 .arg( pgp->lastErrorMessage() );
00436 QString details = i18n( "This is the error message of %1:\n%2" )
00437 .arg( ( pgpType == tGPG ) ? "GnuPG" : "PGP" )
00438 .arg( block.error().data() );
00439 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00440 KMessageBox::detailedSorry( 0, errMsg, details );
00441 QApplication::restoreOverrideCursor();
00442 return Kpgp::Failure;
00443 }
00444
00445 if( showCipherText() ) {
00446
00447 CipherTextDialog *cipherTextDlg = new CipherTextDialog( block.text(), charset );
00448 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00449 bool result = ( cipherTextDlg->exec() == QDialog::Accepted );
00450 QApplication::restoreOverrideCursor();
00451 delete cipherTextDlg;
00452 return result == QDialog::Accepted ? Kpgp::Ok : Kpgp::Canceled;
00453 }
00454 return Kpgp::Ok;
00455 }
00456
00457 int
00458 Module::doEncSign( Block& block,
00459 const KeyIDList& recipientKeyIds, bool sign )
00460 {
00461 int retval = 0;
00462
00463 if( 0 == pgp ) assignPGPBase();
00464
00465
00466 if( !havePgp ) return OK;
00467
00468 if( sign ) {
00469 int result = prepare( true, &block );
00470 switch( result ) {
00471 case -1:
00472 return CANCEL;
00473 case 0:
00474 return ERROR;
00475 }
00476 retval = pgp->encsign( block, recipientKeyIds, passphrase );
00477 }
00478 else {
00479 if( !prepare( false, &block ) ) return ERROR;
00480 retval = pgp->encrypt( block, recipientKeyIds );
00481 }
00482
00483 cleanupPass();
00484
00485 return retval;
00486 }
00487
00488 Kpgp::Result
00489 Module::getEncryptionKeys( KeyIDList& encryptionKeyIds,
00490 const QStringList& recipients,
00491 const KeyID& keyId )
00492 {
00493 if( recipients.empty() ) {
00494 encryptionKeyIds.clear();
00495 return Kpgp::Ok;
00496 }
00497
00498
00499
00500 QValueVector<KeyIDList> recipientKeyIds( recipients.count() + 1 );
00501
00502 if( encryptToSelf() ) {
00503 recipientKeyIds[0] = KeyIDList( keyId );
00504 }
00505 else {
00506 recipientKeyIds[0] = KeyIDList();
00507 }
00508 bool showKeysForApproval = false;
00509 int i = 1;
00510 for( QStringList::ConstIterator it = recipients.begin();
00511 it != recipients.end(); ++it, ++i ) {
00512 EncryptPref encrPref = encryptionPreference( *it );
00513 if( ( encrPref == UnknownEncryptPref ) || ( encrPref == NeverEncrypt ) )
00514 showKeysForApproval = true;
00515
00516 KeyIDList keyIds = getEncryptionKeys( *it );
00517 if( keyIds.isEmpty() ) {
00518 showKeysForApproval = true;
00519 }
00520 recipientKeyIds[i] = keyIds;
00521 }
00522
00523 kdDebug(5100) << "recipientKeyIds = (\n";
00524 QValueVector<KeyIDList>::const_iterator kit;
00525 for( kit = recipientKeyIds.begin(); kit != recipientKeyIds.end(); ++kit ) {
00526 kdDebug(5100) << "( 0x" << (*kit).toStringList().join( ", 0x" )
00527 << " ),\n";
00528 }
00529 kdDebug(5100) << ")\n";
00530
00531 if( showKeysForApproval || mShowKeyApprovalDlg ) {
00532
00533
00534 unsigned int allowedKeys = PublicKeys | EncryptionKeys | ValidKeys | TrustedKeys;
00535 #if 0
00536
00537 if( pgpType != tGPG ) {
00538
00539 allowedKeys |= TrustedKeys;
00540 }
00541 #endif
00542
00543 KeyApprovalDialog dlg( recipients, recipientKeyIds, allowedKeys );
00544
00545 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00546 int ret = dlg.exec();
00547
00548 if( ret == QDialog::Rejected ) {
00549 QApplication::restoreOverrideCursor();
00550 return Kpgp::Canceled;
00551 }
00552
00553 recipientKeyIds = dlg.keys();
00554 QApplication::restoreOverrideCursor();
00555 }
00556
00557
00558 unsigned int emptyListCount = 0;
00559 for( QValueVector<KeyIDList>::const_iterator it = recipientKeyIds.begin();
00560 it != recipientKeyIds.end(); ++it ) {
00561 if( (*it).isEmpty() ) {
00562
00563 if( it != recipientKeyIds.begin() ) {
00564 emptyListCount++;
00565 }
00566 }
00567 else {
00568 for( KeyIDList::ConstIterator kit = (*it).begin();
00569 kit != (*it).end(); kit++ ) {
00570 encryptionKeyIds.append( *kit );
00571 }
00572 }
00573 }
00574
00575
00576
00577
00578
00579 if( recipientKeyIds.size() == emptyListCount + 1 ) {
00580 QString str = ( recipients.count() == 1 )
00581 ? i18n("You did not select an encryption key for the "
00582 "recipient of this message; therefore, the message "
00583 "will not be encrypted.")
00584 : i18n("You did not select an encryption key for any of the "
00585 "recipients of this message; therefore, the message "
00586 "will not be encrypted.");
00587 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00588 int ret = KMessageBox::warningContinueCancel( 0, str,
00589 i18n("PGP Warning"),
00590 i18n("Send &Unencrypted") );
00591 QApplication::restoreOverrideCursor();
00592 if( ret == KMessageBox::Cancel ) {
00593 return Kpgp::Canceled;
00594 }
00595 else
00596 encryptionKeyIds.clear();
00597 }
00598 else if( emptyListCount > 0 ) {
00599 QString str = ( emptyListCount == 1 )
00600 ? i18n("You did not select an encryption key for one of "
00601 "the recipients; this person will not be able to "
00602 "decrypt the message if you encrypt it.")
00603 : i18n("You did not select encryption keys for some of "
00604 "the recipients; these persons will not be able to "
00605 "decrypt the message if you encrypt it." );
00606 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00607 int ret = KMessageBox::warningYesNoCancel( 0, str,
00608 i18n("PGP Warning"),
00609 i18n("Send &Encrypted"),
00610 i18n("Send &Unencrypted") );
00611 QApplication::restoreOverrideCursor();
00612 if( ret == KMessageBox::Cancel ) {
00613 return Kpgp::Canceled;
00614 }
00615 else if( ret == KMessageBox::No ) {
00616
00617 encryptionKeyIds.clear();
00618 }
00619 }
00620
00621 return Kpgp::Ok;
00622 }
00623
00624 int
00625 Module::encryptionPossible( const QStringList& recipients )
00626 {
00627 if( 0 == pgp ) assignPGPBase();
00628
00629 if( !usePGP() )
00630 return 0;
00631
00632 if( recipients.empty() )
00633 return 0;
00634
00635 int noKey = 0, never = 0, unknown = 0, always = 0, aip = 0, ask = 0,
00636 askwp = 0;
00637 for( QStringList::ConstIterator it = recipients.begin();
00638 it != recipients.end(); ++it) {
00639 if( haveTrustedEncryptionKey( *it ) ) {
00640 EncryptPref encrPref = encryptionPreference( *it );
00641 switch( encrPref ) {
00642 case NeverEncrypt:
00643 never++;
00644 break;
00645 case UnknownEncryptPref:
00646 unknown++;
00647 break;
00648 case AlwaysEncrypt:
00649 always++;
00650 break;
00651 case AlwaysEncryptIfPossible:
00652 aip++;
00653 break;
00654 case AlwaysAskForEncryption:
00655 ask++;
00656 break;
00657 case AskWheneverPossible:
00658 askwp++;
00659 break;
00660 }
00661 }
00662 else {
00663 noKey++;
00664 }
00665 }
00666
00667 if( ( always+aip > 0 ) && ( never+unknown+ask+askwp+noKey == 0 ) ) {
00668 return 1;
00669 }
00670
00671 if( ( unknown+ask+askwp > 0 ) && ( never+noKey == 0 ) ) {
00672 return 2;
00673 }
00674
00675 if( ( never+noKey > 0 ) && ( always+ask == 0 ) ) {
00676 return 0;
00677 }
00678
00679 return -1;
00680 }
00681
00682 bool
00683 Module::signKey(const KeyID& keyId)
00684 {
00685 if (0 == pgp) assignPGPBase();
00686
00687 if( prepare( true ) != 1 )
00688 return FALSE;
00689 if(pgp->signKey(keyId, passphrase) & ERROR)
00690 {
00691 errMsg = pgp->lastErrorMessage();
00692 return false;
00693 }
00694 return true;
00695 }
00696
00697
00698 const KeyList
00699 Module::publicKeys()
00700 {
00701 if (0 == pgp) assignPGPBase();
00702
00703 if (!prepare()) return KeyList();
00704
00705 if( !mPublicKeysCached ) {
00706 readPublicKeys();
00707 }
00708
00709 return mPublicKeys;
00710 }
00711
00712
00713 const KeyList
00714 Module::secretKeys()
00715 {
00716 if (0 == pgp) assignPGPBase();
00717
00718 if (!prepare()) return KeyList();
00719
00720 if( !mSecretKeysCached ) {
00721 readSecretKeys();
00722 }
00723
00724 return mSecretKeys;
00725 }
00726
00727
00728 Key*
00729 Module::publicKey(const KeyID& keyID)
00730 {
00731 readPublicKeys();
00732
00733 for( KeyListIterator it( mPublicKeys ); (*it); ++it )
00734 if( keyID == (*it)->primaryKeyID() ||
00735 keyID == (*it)->primaryFingerprint() )
00736 return (*it);
00737
00738 return 0;
00739 }
00740
00741 Key*
00742 Module::publicKey( const QString& userID )
00743 {
00744 readPublicKeys();
00745
00746 for( KeyListIterator it( mPublicKeys ); (*it); ++it )
00747 if( (*it)->matchesUserID( userID ) )
00748 return (*it);
00749
00750 return 0;
00751 }
00752
00753 Key*
00754 Module::secretKey(const KeyID& keyID)
00755 {
00756 readSecretKeys();
00757
00758 for( KeyListIterator it( mSecretKeys ); (*it); ++it )
00759 if( keyID == (*it)->primaryKeyID() ||
00760 keyID == (*it)->primaryFingerprint() )
00761 return (*it);
00762
00763 return 0;
00764 }
00765
00766 Validity
00767 Module::keyTrust( const KeyID& keyID )
00768 {
00769 Key *key = publicKey( keyID );
00770
00771 if( ( 0 == key ) || ( key->keyTrust() == KPGP_VALIDITY_UNKNOWN ) )
00772 {
00773 key = rereadKey( keyID, true );
00774 if( key == 0 )
00775 return KPGP_VALIDITY_UNKNOWN;
00776 }
00777
00778 return key->keyTrust();
00779 }
00780
00781 Validity
00782 Module::keyTrust( const QString& userID )
00783 {
00784 Key *key = publicKey( userID );
00785
00786 if( key == 0 )
00787 return KPGP_VALIDITY_UNKNOWN;
00788
00789 if( key->keyTrust() == KPGP_VALIDITY_UNKNOWN )
00790 {
00791 key = rereadKey( key->primaryKeyID(), true );
00792 if( key == 0 )
00793 return KPGP_VALIDITY_UNKNOWN;
00794 }
00795
00796 return key->keyTrust();
00797 }
00798
00799 bool
00800 Module::isTrusted( const KeyID& keyID )
00801 {
00802 return ( keyTrust( keyID ) >= KPGP_VALIDITY_MARGINAL );
00803 }
00804
00805 Key*
00806 Module::rereadKey( const KeyID& keyID, const bool readTrust )
00807 {
00808 if( 0 == pgp ) assignPGPBase();
00809
00810
00811 Key* oldKey = publicKey( keyID );
00812
00813 Key* newKey = pgp->readPublicKey( keyID, readTrust, oldKey );
00814
00815 if( ( 0 == oldKey ) && ( 0 != newKey ) )
00816 {
00817 mPublicKeys.inSort( newKey );
00818 kdDebug(5100) << "New public key 0x" << newKey->primaryKeyID() << " ("
00819 << newKey->primaryUserID() << ").\n";
00820 }
00821 else if( ( 0 != oldKey ) && ( 0 == newKey ) )
00822 {
00823 kdDebug(5100) << "Public key 0x" << oldKey->primaryKeyID() << " ("
00824 << oldKey->primaryUserID() << ") will be removed.\n";
00825 mPublicKeys.removeRef( oldKey );
00826 }
00827
00828 return newKey;
00829 }
00830
00831 QCString
00832 Module::getAsciiPublicKey(const KeyID& keyID)
00833 {
00834 if (0 == pgp) assignPGPBase();
00835
00836 return pgp->getAsciiPublicKey(keyID);
00837 }
00838
00839
00840 bool Module::setPassPhrase(const char * aPass)
00841 {
00842
00843
00844 wipePassPhrase();
00845
00846 if (aPass)
00847 {
00848 size_t newlen = strlen( aPass );
00849 if ( newlen >= 1024 ) {
00850
00851
00852
00853 return false;
00854 }
00855 if ( passphrase_buffer_len < newlen + 1 ) {
00856
00857
00858 if ( passphrase )
00859 free( passphrase );
00860 passphrase_buffer_len = (newlen + 1 + 15) & ~0xF;
00861 passphrase = (char*)malloc( passphrase_buffer_len );
00862 if (!passphrase) {
00863 passphrase_buffer_len = 0;
00864 return false;
00865 }
00866 }
00867 memcpy( passphrase, aPass, newlen + 1 );
00868 havePassPhrase = true;
00869 }
00870 return true;
00871 }
00872
00873 bool
00874 Module::changePassPhrase()
00875 {
00876
00877 KMessageBox::information(0,i18n("This feature is\nstill missing"));
00878 return FALSE;
00879 }
00880
00881 void
00882 Module::clear(const bool erasePassPhrase)
00883 {
00884 if(erasePassPhrase)
00885 wipePassPhrase(true);
00886 }
00887
00888 const QString
00889 Module::lastErrorMsg(void) const
00890 {
00891 return errMsg;
00892 }
00893
00894 bool
00895 Module::havePGP(void) const
00896 {
00897 return havePgp;
00898 }
00899
00900 void
00901 Module::setShowCipherText(const bool flag)
00902 {
00903 showEncryptionResult = flag;
00904 }
00905
00906 bool
00907 Module::showCipherText(void) const
00908 {
00909 return showEncryptionResult;
00910 }
00911
00912 KeyID
00913 Module::selectSecretKey( const QString& title,
00914 const QString& text,
00915 const KeyID& keyId )
00916 {
00917 if( 0 == pgp ) {
00918 assignPGPBase();
00919 }
00920
00921 if( usePGP() ) {
00922 return selectKey( secretKeys(), title, text, keyId, SecretKeys );
00923 }
00924 else {
00925 KMessageBox::sorry( 0, i18n("You either do not have GnuPG/PGP installed "
00926 "or you chose not to use GnuPG/PGP.") );
00927 return KeyID();
00928 }
00929 }
00930
00931 KeyID
00932 Module::selectPublicKey( const QString& title,
00933 const QString& text ,
00934 const KeyID& oldKeyId ,
00935 const QString& address ,
00936 const unsigned int allowedKeys )
00937 {
00938 if( 0 == pgp ) {
00939 assignPGPBase();
00940 }
00941
00942 if( usePGP() ) {
00943 KeyID keyId;
00944
00945 if( address.isEmpty() ) {
00946 keyId = selectKey( publicKeys(), title, text, oldKeyId, allowedKeys );
00947 }
00948 else {
00949 bool rememberChoice;
00950 keyId = selectKey( rememberChoice, publicKeys(), title, text, oldKeyId,
00951 allowedKeys );
00952 if( !keyId.isEmpty() && rememberChoice ) {
00953 setKeysForAddress( address, KeyIDList( keyId ) );
00954 }
00955 }
00956
00957 return keyId;
00958 }
00959 else {
00960 KMessageBox::sorry( 0, i18n("You either do not have GnuPG/PGP installed "
00961 "or you chose not to use GnuPG/PGP.") );
00962 return KeyID();
00963 }
00964 }
00965
00966
00967 KeyIDList
00968 Module::selectPublicKeys( const QString& title,
00969 const QString& text ,
00970 const KeyIDList& oldKeyIds ,
00971 const QString& address ,
00972 const unsigned int allowedKeys )
00973 {
00974 if( 0 == pgp ) {
00975 assignPGPBase();
00976 }
00977
00978 if( usePGP() ) {
00979 KeyIDList keyIds;
00980
00981 if( address.isEmpty() ) {
00982 keyIds = selectKeys( publicKeys(), title, text, oldKeyIds, allowedKeys );
00983 }
00984 else {
00985 bool rememberChoice;
00986 keyIds = selectKeys( rememberChoice, publicKeys(), title, text,
00987 oldKeyIds, allowedKeys );
00988 if( !keyIds.isEmpty() && rememberChoice ) {
00989 setKeysForAddress( address, keyIds );
00990 }
00991 }
00992
00993 return keyIds;
00994 }
00995 else {
00996 KMessageBox::sorry( 0, i18n("You either do not have GnuPG/PGP installed "
00997 "or you chose not to use GnuPG/PGP.") );
00998 return KeyIDList();
00999 }
01000 }
01001
01002
01003
01004
01005 Module *
01006 Module::getKpgp()
01007 {
01008 if (!kpgpObject)
01009 {
01010 kdError(5100) << "there is no instance of kpgp available" << endl;
01011 }
01012 return kpgpObject;
01013 }
01014
01015
01016 KConfig *
01017 Module::getConfig()
01018 {
01019 return getKpgp()->config;
01020 }
01021
01022
01023 bool
01024 Module::prepareMessageForDecryption( const QCString& msg,
01025 QPtrList<Block>& pgpBlocks,
01026 QStrList& nonPgpBlocks )
01027 {
01028 BlockType pgpBlock = NoPgpBlock;
01029 int start = -1;
01030 int lastEnd = -1;
01031
01032 pgpBlocks.setAutoDelete( true );
01033 pgpBlocks.clear();
01034 nonPgpBlocks.setAutoDelete( true );
01035 nonPgpBlocks.clear();
01036
01037 if( msg.isEmpty() )
01038 {
01039 nonPgpBlocks.append( "" );
01040 return false;
01041 }
01042
01043 if( !strncmp( msg.data(), "-----BEGIN PGP ", 15 ) )
01044 start = 0;
01045 else
01046 {
01047 start = msg.find( "\n-----BEGIN PGP" ) + 1;
01048 if( start == 0 )
01049 {
01050 nonPgpBlocks.append( msg );
01051 return false;
01052 }
01053 }
01054
01055 while( start != -1 )
01056 {
01057 int nextEnd, nextStart;
01058
01059
01060 if( !strncmp( msg.data() + start + 15, "SIGNED", 6 ) )
01061 pgpBlock = ClearsignedBlock;
01062 else
01063 pgpBlock = UnknownBlock;
01064
01065 nextEnd = msg.find( "\n-----END PGP", start + 15 );
01066 if( nextEnd == -1 )
01067 {
01068 nonPgpBlocks.append( msg.mid( lastEnd+1 ) );
01069 break;
01070 }
01071 nextStart = msg.find( "\n-----BEGIN PGP", start + 15 );
01072
01073 if( ( nextStart == -1 ) || ( nextEnd < nextStart ) ||
01074 ( pgpBlock == ClearsignedBlock ) )
01075 {
01076
01077 nonPgpBlocks.append( msg.mid( lastEnd+1, start-lastEnd-1 ) );
01078 lastEnd = msg.find( "\n", nextEnd + 14 );
01079 if( lastEnd == -1 )
01080 {
01081 pgpBlocks.append( new Block( msg.mid( start ) ) );
01082 nonPgpBlocks.append( "" );
01083 break;
01084 }
01085 else
01086 {
01087 pgpBlocks.append( new Block( msg.mid( start, lastEnd+1-start ) ) );
01088 if( ( nextStart != -1 ) && ( nextEnd > nextStart ) )
01089 nextStart = msg.find( "\n-----BEGIN PGP", lastEnd+1 );
01090 }
01091 }
01092
01093 start = nextStart;
01094 if( start == -1 )
01095 nonPgpBlocks.append( msg.mid( lastEnd+1 ) );
01096 else
01097 start++;
01098 }
01099
01100 return ( !pgpBlocks.isEmpty() );
01101 }
01102
01103
01104
01105
01106 bool
01107 Module::haveTrustedEncryptionKey( const QString& person )
01108 {
01109 if( 0 == pgp ) assignPGPBase();
01110
01111 if( !usePGP() ) return false;
01112
01113 readPublicKeys();
01114
01115 QString address = canonicalAddress( person ).lower();
01116
01117
01118 KeyIDList keyIds = keysForAddress( address );
01119 if( !keyIds.isEmpty() ) {
01120
01121 for( KeyIDList::ConstIterator it = keyIds.begin();
01122 it != keyIds.end(); ++it ) {
01123 keyTrust( *it );
01124
01125 Key *key = publicKey( *it );
01126 if( key && ( key->isValidEncryptionKey() ) &&
01127 ( key->keyTrust() >= KPGP_VALIDITY_MARGINAL ) )
01128 return true;
01129 }
01130 }
01131
01132
01133 KeyListIterator it( mPublicKeys );
01134
01135
01136 for( it.toFirst(); (*it); ++it ) {
01137
01138 if( (*it)->matchesUserID( person, false ) ) {
01139 keyTrust( (*it)->primaryKeyID() );
01140
01141 if( ( (*it)->isValidEncryptionKey() ) &&
01142 ( (*it)->keyTrust() >= KPGP_VALIDITY_MARGINAL ) ) {
01143 return true;
01144 }
01145 }
01146 }
01147
01148
01149
01150 for( it.toFirst(); (*it); ++it ) {
01151
01152 if( (*it)->matchesUserID( address, false ) ) {
01153 keyTrust( (*it)->primaryKeyID() );
01154
01155 if( ( (*it)->isValidEncryptionKey() ) &&
01156 ( (*it)->keyTrust() >= KPGP_VALIDITY_MARGINAL ) ) {
01157 return true;
01158 }
01159 }
01160 }
01161
01162
01163 return false;
01164 }
01165
01166 KeyIDList
01167 Module::getEncryptionKeys( const QString& person )
01168 {
01169 if( 0 == pgp ) assignPGPBase();
01170
01171 if( !usePGP() ) return KeyIDList();
01172
01173 readPublicKeys();
01174
01175 QString address = canonicalAddress( person ).lower();
01176
01177
01178
01179 unsigned int allowedKeys = PublicKeys | EncryptionKeys | ValidKeys | TrustedKeys;
01180 #if 0
01181
01182 if( pgpType != tGPG ) {
01183
01184 allowedKeys |= TrustedKeys;
01185 }
01186 #endif
01187
01188
01189 KeyIDList keyIds = keysForAddress( address );
01190 if( !keyIds.isEmpty() ) {
01191 kdDebug(5100) << "Using encryption keys 0x"
01192 << keyIds.toStringList().join( ", 0x" )
01193 << " for " << person << endl;
01194
01195 bool keysOk = true;
01196 for( KeyIDList::ConstIterator it = keyIds.begin();
01197 it != keyIds.end(); ++it ) {
01198 keyTrust( *it );
01199
01200 Key *key = publicKey( *it );
01201 if( !( key && ( key->isValidEncryptionKey() ) &&
01202 ( key->keyTrust() >= KPGP_VALIDITY_MARGINAL ) ) )
01203 keysOk = false;
01204 }
01205 if( keysOk ) {
01206 return keyIds;
01207 }
01208 else {
01209 bool rememberChoice;
01210 keyIds = selectKeys( rememberChoice, mPublicKeys,
01211 i18n("Encryption Key Selection"),
01212 i18n("if in your language something like "
01213 "'key(s)' isn't possible please "
01214 "use the plural in the translation",
01215 "There is a problem with the "
01216 "encryption key(s) for \"%1\".\n\n"
01217 "Please re-select the key(s) which should "
01218 "be used for this recipient."
01219 ).arg(person),
01220 keyIds,
01221 allowedKeys );
01222 if( !keyIds.isEmpty() ) {
01223 if( rememberChoice ) {
01224 setKeysForAddress( person, keyIds );
01225 }
01226 return keyIds;
01227 }
01228 }
01229 }
01230
01231
01232 KeyListIterator it( mPublicKeys );
01233 KeyList matchingKeys;
01234
01235
01236 kdDebug(5100) << "Looking for keys matching " << person << " ...\n";
01237 for( it.toFirst(); (*it); ++it ) {
01238
01239 if( (*it)->matchesUserID( person, false ) ) {
01240 keyTrust( (*it)->primaryKeyID() );
01241
01242 if( ( (*it)->isValidEncryptionKey() ) &&
01243 ( (*it)->keyTrust() >= KPGP_VALIDITY_MARGINAL ) ) {
01244 kdDebug(5100) << "Matching trusted key found: "
01245 << (*it)->primaryKeyID() << endl;
01246 matchingKeys.append( *it );
01247 }
01248 }
01249 }
01250
01251
01252
01253 kdDebug(5100) << "Looking for keys matching " << address << " ...\n";
01254 if( matchingKeys.isEmpty() ) {
01255 for ( it.toFirst(); (*it); ++it ) {
01256
01257 if( (*it)->matchesUserID( address, false ) ) {
01258 keyTrust( (*it)->primaryKeyID() );
01259
01260 if( ( (*it)->isValidEncryptionKey() ) &&
01261 ( (*it)->keyTrust() >= KPGP_VALIDITY_MARGINAL ) ) {
01262 kdDebug(5100) << "Matching trusted key found: "
01263 << (*it)->primaryKeyID() << endl;
01264 matchingKeys.append( *it );
01265 }
01266 }
01267 }
01268 }
01269
01270
01271 if( matchingKeys.isEmpty() ) {
01272
01273 bool rememberChoice;
01274 KeyIDList keyIds = selectKeys( rememberChoice, mPublicKeys,
01275 i18n("Encryption Key Selection"),
01276 i18n("if in your language something like "
01277 "'key(s)' isn't possible please "
01278 "use the plural in the translation",
01279 "No valid and trusted OpenPGP key was "
01280 "found for \"%1\".\n\n"
01281 "Select the key(s) which should "
01282 "be used for this recipient."
01283 ).arg(person),
01284 KeyIDList(),
01285 allowedKeys );
01286 if( !keyIds.isEmpty() ) {
01287 if( rememberChoice ) {
01288 setKeysForAddress( person, keyIds );
01289 }
01290 return keyIds;
01291 }
01292 }
01293
01294 else if( matchingKeys.count() == 1 ) {
01295 return KeyIDList( matchingKeys.getFirst()->primaryKeyID() );
01296 }
01297
01298 else {
01299 bool rememberChoice;
01300 KeyIDList keyIds = selectKeys( rememberChoice, matchingKeys,
01301 i18n("Encryption Key Selection"),
01302 i18n("if in your language something like "
01303 "'key(s)' isn't possible please "
01304 "use the plural in the translation",
01305 "More than one key matches \"%1\".\n\n"
01306 "Select the key(s) which should "
01307 "be used for this recipient."
01308 ).arg(person),
01309 KeyIDList(),
01310 allowedKeys );
01311 if( !keyIds.isEmpty() ) {
01312 if( rememberChoice ) {
01313 setKeysForAddress( person, keyIds );
01314 }
01315 return keyIds;
01316 }
01317 }
01318
01319 return KeyIDList();
01320 }
01321
01322
01323
01324 bool
01325 Module::checkForPGP(void)
01326 {
01327
01328 QCString path;
01329 QStrList pSearchPaths;
01330 int index = 0;
01331 int lastindex = -1;
01332
01333 havePgp=FALSE;
01334
01335 path = getenv("PATH");
01336 while((index = path.find(":",lastindex+1)) != -1)
01337 {
01338 pSearchPaths.append(path.mid(lastindex+1,index-lastindex-1));
01339 lastindex = index;
01340 }
01341 if(lastindex != (int)path.length() - 1)
01342 pSearchPaths.append( path.mid(lastindex+1,path.length()-lastindex) );
01343
01344 QStrListIterator it(pSearchPaths);
01345
01346 haveGpg=FALSE;
01347
01348
01349 for ( it.toFirst() ; it.current() ; ++it )
01350 {
01351 path = (*it);
01352 path += "/gpg";
01353 if ( !access( path, X_OK ) )
01354 {
01355 kdDebug(5100) << "Kpgp: gpg found" << endl;
01356 havePgp=TRUE;
01357 haveGpg=TRUE;
01358 break;
01359 }
01360 }
01361
01362
01363 havePGP5=FALSE;
01364 for ( it.toFirst() ; it.current() ; ++it )
01365 {
01366 path = (*it);
01367 path += "/pgpe";
01368 if ( !access( path, X_OK ) )
01369 {
01370 kdDebug(5100) << "Kpgp: pgp 5 found" << endl;
01371 havePgp=TRUE;
01372 havePGP5=TRUE;
01373 break;
01374 }
01375 }
01376
01377
01378 if (!havePgp) {
01379 for ( it.toFirst() ; it.current() ; ++it )
01380 {
01381 path = it.current();
01382 path += "/pgp";
01383 if ( !access( path, X_OK ) )
01384 {
01385 kdDebug(5100) << "Kpgp: pgp 2 or 6 found" << endl;
01386 havePgp=TRUE;
01387 break;
01388 }
01389 }
01390 }
01391
01392 if (!havePgp)
01393 {
01394 kdDebug(5100) << "Kpgp: no pgp found" << endl;
01395 }
01396
01397 return havePgp;
01398 }
01399
01400 void
01401 Module::assignPGPBase(void)
01402 {
01403 if (pgp)
01404 delete pgp;
01405
01406 if(havePgp)
01407 {
01408 switch (pgpType)
01409 {
01410 case tGPG:
01411 kdDebug(5100) << "Kpgp: assign pgp - gpg" << endl;
01412 pgp = new BaseG();
01413 break;
01414
01415 case tPGP2:
01416 kdDebug(5100) << "Kpgp: assign pgp - pgp 2" << endl;
01417 pgp = new Base2();
01418 break;
01419
01420 case tPGP5:
01421 kdDebug(5100) << "Kpgp: assign pgp - pgp 5" << endl;
01422 pgp = new Base5();
01423 break;
01424
01425 case tPGP6:
01426 kdDebug(5100) << "Kpgp: assign pgp - pgp 6" << endl;
01427 pgp = new Base6();
01428 break;
01429
01430 case tOff:
01431
01432 kdDebug(5100) << "Kpgp: pgpBase is dummy " << endl;
01433 pgp = new Base();
01434 break;
01435
01436 case tAuto:
01437 kdDebug(5100) << "Kpgp: assign pgp - auto" << endl;
01438
01439 default:
01440 kdDebug(5100) << "Kpgp: assign pgp - default" << endl;
01441 if (haveGpg)
01442 {
01443 kdDebug(5100) << "Kpgp: pgpBase is gpg " << endl;
01444 pgp = new BaseG();
01445 pgpType = tGPG;
01446 }
01447 else if(havePGP5)
01448 {
01449 kdDebug(5100) << "Kpgp: pgpBase is pgp 5" << endl;
01450 pgp = new Base5();
01451 pgpType = tPGP5;
01452 }
01453 else
01454 {
01455 Base6 *pgp_v6 = new Base6();
01456 if (!pgp_v6->isVersion6())
01457 {
01458 kdDebug(5100) << "Kpgp: pgpBase is pgp 2 " << endl;
01459 delete pgp_v6;
01460 pgp = new Base2();
01461 pgpType = tPGP2;
01462 }
01463 else
01464 {
01465 kdDebug(5100) << "Kpgp: pgpBase is pgp 6 " << endl;
01466 pgp = pgp_v6;
01467 pgpType = tPGP6;
01468 }
01469 }
01470 }
01471 }
01472 else
01473 {
01474
01475 kdDebug(5100) << "Kpgp: pgpBase is dummy " << endl;
01476 pgp = new Base();
01477 pgpType = tOff;
01478 }
01479 }
01480
01481 QString
01482 Module::canonicalAddress( const QString& _adress )
01483 {
01484 int index,index2;
01485
01486 QString address = _adress.simplifyWhiteSpace();
01487 address = address.stripWhiteSpace();
01488
01489
01490 if((index = address.find("<")) != -1)
01491 if((index2 = address.find("@",index+1)) != -1)
01492 if((index2 = address.find(">",index2+1)) != -1)
01493 return address.mid(index,index2-index+1);
01494
01495 if((index = address.find("@")) == -1)
01496 {
01497
01498
01499
01500
01501 return "<" + address + "@localdomain>";
01502 }
01503 else
01504 {
01505 int index1 = address.findRev(" ",index);
01506 int index2 = address.find(" ",index);
01507 if(index2 == -1) index2 = address.length();
01508 return "<" + address.mid(index1+1 ,index2-index1-1) + ">";
01509 }
01510 }
01511
01512 void
01513 Module::readPublicKeys( bool reread )
01514 {
01515 if( 0 == pgp ) assignPGPBase();
01516
01517 if( !usePGP() )
01518 {
01519 mPublicKeys.clear();
01520 mPublicKeysCached = false;
01521 return;
01522 }
01523
01524 if( !mPublicKeysCached || reread )
01525 {
01526 if( mPublicKeys.isEmpty() )
01527 {
01528 mPublicKeys = pgp->publicKeys();
01529 }
01530 else
01531 {
01532 KeyList newPublicKeyList = pgp->publicKeys();
01533
01534
01535
01536
01537 KeyListIterator it( newPublicKeyList );
01538 for( it.toFirst(); (*it); ++it )
01539 {
01540 Key* oldKey = publicKey( (*it)->primaryKeyID() );
01541 if( oldKey )
01542 {
01543 (*it)->cloneKeyTrust( oldKey );
01544 }
01545 }
01546
01547 mPublicKeys = newPublicKeyList;
01548 }
01549
01550 mPublicKeysCached = true;
01551 mPublicKeys.setAutoDelete( true );
01552 }
01553 }
01554
01555 void
01556 Module::readSecretKeys( bool reread )
01557 {
01558 if( 0 == pgp ) assignPGPBase();
01559
01560 if( !usePGP() )
01561 {
01562 mSecretKeys.clear();
01563 mSecretKeysCached = false;
01564 return;
01565 }
01566
01567 if( mSecretKeys.isEmpty() || reread )
01568 {
01569 if( mSecretKeys.isEmpty() )
01570 {
01571 mSecretKeys = pgp->secretKeys();
01572 }
01573 else
01574 {
01575 KeyList newSecretKeyList = pgp->secretKeys();
01576
01577
01578
01579
01580 KeyListIterator it( newSecretKeyList );
01581 for( it.toFirst(); (*it); ++it )
01582 {
01583 Key* oldKey = secretKey( (*it)->primaryKeyID() );
01584 if( oldKey )
01585 {
01586 (*it)->cloneKeyTrust( oldKey );
01587 }
01588 }
01589
01590 mSecretKeys = newSecretKeyList;
01591 }
01592
01593 mSecretKeysCached = true;
01594 mSecretKeys.setAutoDelete( true );
01595 }
01596 }
01597
01598 KeyID
01599 Module::selectKey( const KeyList& keys,
01600 const QString& title,
01601 const QString& text ,
01602 const KeyID& keyId ,
01603 const unsigned int allowedKeys )
01604 {
01605 KeyID retval = KeyID();
01606
01607 KeySelectionDialog dlg( keys, title, text, KeyIDList( keyId ), false,
01608 allowedKeys, false );
01609
01610 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01611 bool rej = ( dlg.exec() == QDialog::Rejected );
01612 QApplication::restoreOverrideCursor();
01613
01614 if( !rej ) {
01615 retval = dlg.key();
01616 }
01617
01618 return retval;
01619 }
01620
01621 KeyIDList
01622 Module::selectKeys( const KeyList& keys,
01623 const QString& title,
01624 const QString& text ,
01625 const KeyIDList& keyIds ,
01626 const unsigned int allowedKeys )
01627 {
01628 KeyIDList retval = KeyIDList();
01629
01630 KeySelectionDialog dlg( keys, title, text, keyIds, false, allowedKeys,
01631 true );
01632
01633 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01634 bool rej = ( dlg.exec() == QDialog::Rejected );
01635 QApplication::restoreOverrideCursor();
01636
01637 if( !rej ) {
01638 retval = dlg.keys();
01639 }
01640
01641 return retval;
01642 }
01643
01644
01645 KeyID
01646 Module::selectKey( bool& rememberChoice,
01647 const KeyList& keys,
01648 const QString& title,
01649 const QString& text ,
01650 const KeyID& keyId ,
01651 const unsigned int allowedKeys )
01652 {
01653 KeyID retval = KeyID();
01654
01655 KeySelectionDialog dlg( keys, title, text, KeyIDList( keyId ), false,
01656 allowedKeys, false );
01657
01658 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01659 bool rej = ( dlg.exec() == QDialog::Rejected );
01660 QApplication::restoreOverrideCursor();
01661
01662 if( !rej ) {
01663 retval = dlg.key();
01664 rememberChoice = dlg.rememberSelection();
01665 }
01666 else {
01667 rememberChoice = false;
01668 }
01669
01670 return retval;
01671 }
01672
01673 KeyIDList
01674 Module::selectKeys( bool& rememberChoice,
01675 const KeyList& keys,
01676 const QString& title,
01677 const QString& text ,
01678 const KeyIDList& keyIds ,
01679 const unsigned int allowedKeys )
01680 {
01681 KeyIDList retval = KeyIDList();
01682
01683 KeySelectionDialog dlg( keys, title, text, keyIds, true, allowedKeys,
01684 true );
01685
01686 QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01687 bool rej = ( dlg.exec() == QDialog::Rejected );
01688 QApplication::restoreOverrideCursor();
01689
01690 if( !rej ) {
01691 retval = dlg.keys();
01692 rememberChoice = dlg.rememberSelection();
01693 }
01694 else {
01695 rememberChoice = false;
01696 }
01697
01698 return retval;
01699 }
01700
01701 KeyIDList
01702 Module::keysForAddress( const QString& address )
01703 {
01704 if( address.isEmpty() ) {
01705 return KeyIDList();
01706 }
01707 QString addr = canonicalAddress( address ).lower();
01708 if( addressDataDict.contains( addr ) ) {
01709 return addressDataDict[addr].keyIds;
01710 }
01711 else {
01712 return KeyIDList();
01713 }
01714 }
01715
01716 void
01717 Module::setKeysForAddress( const QString& address, const KeyIDList& keyIds )
01718 {
01719 if( address.isEmpty() ) {
01720 return;
01721 }
01722 QString addr = canonicalAddress( address ).lower();
01723 if( addressDataDict.contains( addr ) ) {
01724 addressDataDict[addr].keyIds = keyIds;
01725 }
01726 else {
01727 AddressData data;
01728 data.encrPref = UnknownEncryptPref;
01729 data.keyIds = keyIds;
01730 addressDataDict.insert( addr, data );
01731 }
01732
01733
01734 }
01735
01736 void
01737 Module::readAddressData()
01738 {
01739 QString address;
01740 AddressData data;
01741
01742 KConfigGroup general( config, "General" );
01743 int num = general.readNumEntry( "addressEntries", 0 );
01744
01745 addressDataDict.clear();
01746 for( int i=1; i<=num; i++ ) {
01747 KConfigGroup addrGroup( config, QString("Address #%1").arg(i).local8Bit() );
01748 address = addrGroup.readEntry( "Address" );
01749 data.keyIds = KeyIDList::fromStringList( addrGroup.readListEntry( "Key IDs" ) );
01750 data.encrPref = (EncryptPref) addrGroup.readNumEntry( "EncryptionPreference",
01751 UnknownEncryptPref );
01752
01753
01754
01755 if ( !address.isEmpty() ) {
01756 addressDataDict.insert( address, data );
01757 }
01758 }
01759 }
01760
01761 void
01762 Module::writeAddressData()
01763 {
01764 KConfigGroup general( config, "General" );
01765 general.writeEntry( "addressEntries", addressDataDict.count() );
01766
01767 int i;
01768 AddressDataDict::Iterator it;
01769 for ( i=1, it = addressDataDict.begin();
01770 it != addressDataDict.end();
01771 ++it, i++ ) {
01772 KConfigGroup addrGroup( config, QString("Address #%1").arg(i).local8Bit() );
01773 addrGroup.writeEntry( "Address", it.key() );
01774 addrGroup.writeEntry( "Key IDs", it.data().keyIds.toStringList() );
01775 addrGroup.writeEntry( "EncryptionPreference", it.data().encrPref );
01776 }
01777
01778 config->sync();
01779 }
01780
01781 EncryptPref
01782 Module::encryptionPreference( const QString& address )
01783 {
01784 QString addr = canonicalAddress( address ).lower();
01785 if( addressDataDict.contains( addr ) ) {
01786 return addressDataDict[addr].encrPref;
01787 }
01788 else {
01789 return UnknownEncryptPref;
01790 }
01791 }
01792
01793 void
01794 Module::setEncryptionPreference( const QString& address,
01795 const EncryptPref pref )
01796 {
01797 if( address.isEmpty() ) {
01798 return;
01799 }
01800 QString addr = canonicalAddress( address ).lower();
01801 if( addressDataDict.contains( addr ) ) {
01802 addressDataDict[addr].encrPref = pref;
01803 }
01804 else {
01805 AddressData data;
01806 data.encrPref = pref;
01807 addressDataDict.insert( addr, data );
01808 }
01809 }
01810
01811 }