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