libkdenetwork Library API Documentation

kpgp.cpp

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