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