libkdenetwork Library API Documentation

kpgp.cpp

00001 /*  -*- mode: C++; c-file-style: "gnu" -*-
00002     kpgp.cpp
00003 
00004     Copyright (C) 2001,2002 the KPGP authors
00005     See file AUTHORS.kpgp for details
00006 
00007     This file is part of KPGP, the KDE PGP/GnuPG support library.
00008 
00009     KPGP is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software Foundation,
00016     Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
00017  */
00018 
00019 #include <stdio.h>
00020 #include <time.h>
00021 #include <stdlib.h>
00022 #include <assert.h>
00023 #include <stdarg.h>
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026 #include <string.h>
00027 #include <sys/socket.h>
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <sys/wait.h>
00031 #include <signal.h>
00032 
00033 #include <qlabel.h>
00034 #include <qcursor.h>
00035 #include <qapplication.h>
00036 
00037 #include <kdebug.h>
00038 #include <klocale.h>
00039 #include <kmessagebox.h>
00040 #include <kconfigbase.h>
00041 #include <kconfig.h>
00042 #include <kstaticdeleter.h>
00043 
00044 #include "kpgpbase.h"
00045 #include "kpgpui.h"
00046 #include "kpgp.h"
00047 
00048 namespace Kpgp {
00049 
00050 Module *Module::kpgpObject = 0L;
00051 static KStaticDeleter<Module> kpgpod;
00052 
00053 Module::Module()
00054   : mPublicKeys(),
00055     mPublicKeysCached(false),
00056     mSecretKeys(),
00057     mSecretKeysCached(false),
00058     passphrase(0), passphrase_buffer_len(0), havePassPhrase(false)
00059 {
00060   if (!kpgpObject) {
00061     kdDebug(5100) << "creating new pgp object" << endl;
00062   }
00063   kpgpObject=kpgpod.setObject(this);
00064   pgp = 0;
00065 
00066   config = new KConfig("kpgprc");
00067 
00068   init();
00069 }
00070 
00071 Module::~Module()
00072 {
00073   writeAddressData();
00074 
00075   if (kpgpObject == this) kpgpObject = kpgpod.setObject(0);
00076   clear(TRUE);
00077   delete config;
00078   delete pgp;
00079 }
00080 
00081 // ----------------- public methods -------------------------
00082 
00083 void
00084 Module::init()
00085 {
00086   wipePassPhrase();
00087 
00088   // read kpgp config file entries
00089   readConfig();
00090 
00091   // read the email address -> { encryption keys, encryption preference }
00092   // associations
00093   readAddressData();
00094 
00095   // do we have a pgp executable
00096   checkForPGP();
00097 
00098   // create the Base object later when it is
00099   // needed to avoid the costly check done for
00100   // the autodetection of PGP 2/6
00101   //assignPGPBase();
00102   delete pgp;
00103   pgp=0;
00104 }
00105 
00106 
00107 void
00108 Module::readConfig()
00109 {
00110   storePass = config->readBoolEntry("storePass", false);
00111   showEncryptionResult = config->readBoolEntry("showEncryptionResult", true);
00112   mShowKeyApprovalDlg = config->readBoolEntry( "showKeysForApproval", true );
00113   //pgpType = (Module::PGPType) config->readNumEntry("pgpType", tAuto);
00114   // We have no config GUI for this key anymore, and the KPGP backend isn't ported,
00115   // so let's just use Auto all the time.  See #92619.
00117   pgpType = tAuto;
00118   flagEncryptToSelf = config->readBoolEntry("encryptToSelf", true);
00119 }
00120 
00121 void
00122 Module::writeConfig(bool sync)
00123 {
00124   config->writeEntry("storePass", storePass);
00125   config->writeEntry("showEncryptionResult", showEncryptionResult);
00126   config->writeEntry( "showKeysForApproval", mShowKeyApprovalDlg );
00127   //config->writeEntry("pgpType", (int) pgpType);
00128   config->writeEntry("encryptToSelf", flagEncryptToSelf);
00129 
00130   if(sync)
00131     config->sync();
00132 
00135   delete pgp;
00136   pgp = 0;
00137 }
00138 
00139 
00140 void
00141 Module::setUser(const KeyID& keyID)
00142 {
00143   if (pgpUser != keyID) {
00144     pgpUser = keyID;
00145     wipePassPhrase();
00146   }
00147 }
00148 
00149 const KeyID
00150 Module::user(void) const
00151 {
00152   return pgpUser;
00153 }
00154 
00155 
00156 void
00157 Module::setEncryptToSelf(bool flag)
00158 {
00159   flagEncryptToSelf = flag;
00160 }
00161 
00162 bool
00163 Module::encryptToSelf(void) const
00164 {
00165   return flagEncryptToSelf;
00166 }
00167 
00168 
00169 void
00170 Module::setStorePassPhrase(bool flag)
00171 {
00172   storePass = flag;
00173 }
00174 
00175 bool
00176 Module::storePassPhrase(void) const
00177 {
00178   return storePass;
00179 }
00180 
00181 int
00182 Module::prepare( bool needPassPhrase, Block* block )
00183 {
00184   if (0 == pgp) assignPGPBase();
00185 
00186   if(!havePgp)
00187   {
00188     errMsg = i18n("Could not find PGP executable.\n"
00189                "Please check your PATH is set correctly.");
00190     return 0;
00191   }
00192 
00193   if( block && ( block->status() & NO_SEC_KEY ) )
00194     return 0;
00195 
00196   if(needPassPhrase && !havePassPhrase) {
00197     if( ( tGPG == pgpType ) && ( 0 != getenv("GPG_AGENT_INFO") ) ) {
00198       // the user uses gpg-agent which asks itself for the passphrase
00199       kdDebug(5100) << "user uses gpg-agent -> don't ask for passphrase\n";
00200       // set dummy passphrase (because else signing doesn't work -> FIXME)
00201       setPassPhrase( "dummy" );
00202     }
00203     else {
00204       QString ID;
00205       if( block )
00206         ID = block->requiredUserId();
00207       PassphraseDialog passdlg(0, i18n("OpenPGP Security Check"), true, ID);
00208       QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00209       int passdlgResult = passdlg.exec();
00210       QApplication::restoreOverrideCursor();
00211       if (passdlgResult == QDialog::Accepted) {
00212         if (!setPassPhrase(passdlg.passphrase())) {
00213           if (strlen(passdlg.passphrase()) >= 1024)
00214              errMsg = i18n("Passphrase is too long, it must contain less than 1024 characters.");
00215           else
00216              errMsg = i18n("Out of memory.");
00217     return 0;
00218         }
00219       } else {
00220         wipePassPhrase();
00221         return -1;
00222       }
00223     }
00224   }
00225   return 1;
00226 }
00227 
00228 void
00229 Module::wipePassPhrase(bool freeMem)
00230 {
00231   if ( passphrase ) {
00232     if ( passphrase_buffer_len )
00233       memset( passphrase, 0x00, passphrase_buffer_len );
00234     else {
00235       kdDebug(5100) << "wipePassPhrase: passphrase && !passphrase_buffer_len ???" << endl;
00236       passphrase = 0;
00237     }
00238   }
00239   if ( freeMem && passphrase ) {
00240     free( passphrase );
00241     passphrase = 0;
00242     passphrase_buffer_len = 0;
00243   }
00244   havePassPhrase = false;
00245 }
00246 
00247 bool
00248 Module::verify( Block& block )
00249 {
00250   int retval;
00251 
00252   if (0 == pgp) assignPGPBase();
00253 
00254   // everything ready
00255   if( !prepare( false, &block ) )
00256     return false;
00257   // ok now try to verify the message.
00258   retval = pgp->verify( block );
00259 
00260   if(retval & ERROR)
00261   {
00262     errMsg = pgp->lastErrorMessage();
00263     return false;
00264   }
00265   return true;
00266 }
00267 
00268 bool
00269 Module::decrypt( Block& block )
00270 {
00271   int retval;
00272 
00273   if (0 == pgp) assignPGPBase();
00274 
00275   do {
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       QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00285       int ret = KMessageBox::warningContinueCancel(0,
00286          i18n("You just entered an invalid passphrase.\n"
00287           "Do you want to try again, or "
00288           "cancel and view the message undecrypted?"),
00289          i18n("PGP Warning"), i18n("&Retry"));
00290       QApplication::restoreOverrideCursor();
00291       if ( ret == KMessageBox::Cancel ) break;
00292     } else
00293       break;
00294   } while ( true );
00295 
00296   // 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 QCString& charset )
00310 {
00311   return encrypt( block, QStringList(), keyId, true, charset );
00312 }
00313 
00314 Kpgp::Result
00315 Module::encrypt( Block& block,
00316                  const QStringList& receivers, const KeyID& keyId,
00317                  bool sign, const QCString& charset )
00318 {
00319   KeyIDList encryptionKeyIds; // 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     QString str = i18n("You entered an invalid passphrase.\n"
00344                        "Do you want to try again, continue and leave the "
00345                        "message unsigned, or cancel sending the message?");
00346     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00347     int ret = KMessageBox::warningYesNoCancel( 0, str,
00348                                                i18n("PGP Warning"),
00349                                                i18n("&Retry"),
00350                                                i18n("Send &Unsigned") );
00351     QApplication::restoreOverrideCursor();
00352     if( ret == KMessageBox::Cancel ) {
00353       return Kpgp::Canceled;
00354     }
00355     if( ret == KMessageBox::No ) {
00356       // 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     QString str = i18n("%1 = 'signing failed' error message",
00372                        "%1\nDo you want to send the message unsigned, "
00373                        "or cancel sending the message?")
00374                   .arg( pgp->lastErrorMessage() );
00375     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00376     int ret = KMessageBox::warningContinueCancel( 0, str,
00377                                                   i18n("PGP Warning"),
00378                                                   i18n("Send &Unsigned") );
00379     QApplication::restoreOverrideCursor();
00380     if( ret == KMessageBox::Cancel ) {
00381       return Kpgp::Canceled;
00382     }
00383     sign = false;
00384     status = doEncSign( block, encryptionKeyIds, sign );
00385   }
00386 
00387   // check for bad keys
00388   if( status & BADKEYS ) {
00389     QString str = i18n("%1 = 'bad keys' error message",
00390                        "%1\nDo you want to encrypt anyway, leave the "
00391                        "message as is, or cancel sending the message?")
00392                   .arg( pgp->lastErrorMessage() );
00393 
00394     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00395     int ret = KMessageBox::warningYesNoCancel( 0, str,
00396                                                i18n("PGP Warning"),
00397                                                i18n("Send &Encrypted"),
00398                                                i18n("Send &Unencrypted") );
00399     QApplication::restoreOverrideCursor();
00400     if( ret == KMessageBox::Cancel ) {
00401       return Kpgp::Canceled;
00402     }
00403     if( ret == KMessageBox::No ) {
00404       // 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     QString str = i18n("%1 = 'missing keys' error message",
00417                        "%1\nDo you want to leave the message as is, "
00418                        "or cancel sending the message?")
00419                   .arg( pgp->lastErrorMessage() );
00420     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00421     int ret = KMessageBox::warningContinueCancel( 0, str,
00422                                                   i18n("PGP Warning"),
00423                                                   i18n("&Send as Is") );
00424     QApplication::restoreOverrideCursor();
00425     if( ret == KMessageBox::Cancel ) {
00426       return Kpgp::Canceled;
00427     }
00428     block.reset();
00429     return Kpgp::Ok;
00430   }
00431 
00432   if( status & ERROR ) {
00433     // show error dialog
00434     errMsg = i18n( "The following error occurred:\n%1" )
00435              .arg( pgp->lastErrorMessage() );
00436     QString details = i18n( "This is the error message of %1:\n%2" )
00437                       .arg( ( pgpType == tGPG ) ? "GnuPG" : "PGP" )
00438                       .arg( block.error().data() );
00439     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00440     KMessageBox::detailedSorry( 0, errMsg, details );
00441     QApplication::restoreOverrideCursor();
00442     return Kpgp::Failure;
00443   }
00444 
00445   if( showCipherText() ) {
00446     // show cipher text dialog
00447     CipherTextDialog *cipherTextDlg = new CipherTextDialog( block.text(), charset );
00448     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00449     bool result = ( cipherTextDlg->exec() == QDialog::Accepted );
00450     QApplication::restoreOverrideCursor();
00451     delete cipherTextDlg;
00452     return result == QDialog::Accepted ? Kpgp::Ok : Kpgp::Canceled;
00453   }
00454   return Kpgp::Ok;
00455 }
00456 
00457 int
00458 Module::doEncSign( Block& block,
00459                    const KeyIDList& recipientKeyIds, bool sign )
00460 {
00461   int retval = 0;
00462 
00463   if( 0 == pgp ) assignPGPBase();
00464 
00465   // 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 QStringList& 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   QValueVector<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( QStringList::ConstIterator it = recipients.begin();
00511        it != recipients.end(); ++it, ++i ) {
00512     EncryptPref encrPref = encryptionPreference( *it );
00513     if( ( encrPref == UnknownEncryptPref ) || ( encrPref == NeverEncrypt ) )
00514       showKeysForApproval = true;
00515 
00516     KeyIDList keyIds = getEncryptionKeys( *it );
00517     if( keyIds.isEmpty() ) {
00518       showKeysForApproval = true;
00519     }
00520     recipientKeyIds[i] = keyIds;
00521   }
00522 
00523   kdDebug(5100) << "recipientKeyIds = (\n";
00524   QValueVector<KeyIDList>::const_iterator kit;
00525   for( kit = recipientKeyIds.begin(); kit != recipientKeyIds.end(); ++kit ) {
00526     kdDebug(5100) << "( 0x" << (*kit).toStringList().join( ", 0x" )
00527                   << " ),\n";
00528   }
00529   kdDebug(5100) << ")\n";
00530 
00531   if( showKeysForApproval || mShowKeyApprovalDlg ) {
00532     // #### 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     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00546     int ret = dlg.exec();
00547 
00548     if( ret == QDialog::Rejected ) {
00549         QApplication::restoreOverrideCursor();
00550         return Kpgp::Canceled;
00551     }
00552 
00553     recipientKeyIds = dlg.keys();
00554     QApplication::restoreOverrideCursor();
00555   }
00556 
00557   // flatten the list of lists of key IDs and count empty key ID lists
00558   unsigned int emptyListCount = 0;
00559   for( QValueVector<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     QString str = ( recipients.count() == 1 )
00581                   ? i18n("You did not select an encryption key for the "
00582                          "recipient of this message; therefore, the message "
00583                          "will not be encrypted.")
00584                   : i18n("You did not select an encryption key for any of the "
00585                          "recipients of this message; therefore, the message "
00586                          "will not be encrypted.");
00587     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00588     int ret = KMessageBox::warningContinueCancel( 0, str,
00589                                                   i18n("PGP Warning"),
00590                                                   i18n("Send &Unencrypted") );
00591     QApplication::restoreOverrideCursor();
00592     if( ret == KMessageBox::Cancel ) {
00593       return Kpgp::Canceled;
00594     }
00595     else
00596       encryptionKeyIds.clear();
00597   }
00598   else if( emptyListCount > 0 ) {
00599     QString str = ( emptyListCount == 1 )
00600                   ? i18n("You did not select an encryption key for one of "
00601                          "the recipients; this person will not be able to "
00602                          "decrypt the message if you encrypt it.")
00603                   : i18n("You did not select encryption keys for some of "
00604                          "the recipients; these persons will not be able to "
00605                          "decrypt the message if you encrypt it." );
00606     QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
00607     int ret = KMessageBox::warningYesNoCancel( 0, str,
00608                                                i18n("PGP Warning"),
00609                                                i18n("Send &Encrypted"),
00610                                                i18n("Send &Unencrypted") );
00611     QApplication::restoreOverrideCursor();
00612     if( ret == KMessageBox::Cancel ) {
00613       return Kpgp::Canceled;
00614     }
00615     else if( ret == KMessageBox::No ) {
00616       // the user selected "Send unencrypted"
00617       encryptionKeyIds.clear();
00618     }
00619   }
00620 
00621   return Kpgp::Ok;
00622 }
00623 
00624 int
00625 Module::encryptionPossible( const QStringList& recipients )
00626 {
00627   if( 0 == pgp ) assignPGPBase();
00628 
00629   if( !usePGP() )
00630     return 0;
00631 
00632   if( recipients.empty() )
00633     return 0;
00634 
00635   int noKey = 0, never = 0, unknown = 0, always = 0, aip = 0, ask = 0,
00636       askwp = 0;
00637   for( QStringList::ConstIterator it = recipients.begin();
00638        it != recipients.end(); ++it) {
00639     if( haveTrustedEncryptionKey( *it ) ) {
00640       EncryptPref encrPref = encryptionPreference( *it );
00641       switch( encrPref ) {
00642         case NeverEncrypt:
00643           never++;
00644           break;
00645         case UnknownEncryptPref:
00646           unknown++;
00647           break;
00648         case AlwaysEncrypt:
00649           always++;
00650           break;
00651         case AlwaysEncryptIfPossible:
00652           aip++;
00653           break;
00654         case AlwaysAskForEncryption:
00655           ask++;
00656           break;
00657         case AskWheneverPossible:
00658           askwp++;
00659           break;
00660       }
00661     }
00662     else {
00663       noKey++;
00664     }
00665   }
00666 
00667   if( ( always+aip > 0 ) && ( never+unknown+ask+askwp+noKey == 0 ) ) {
00668     return 1; // 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 QString& userID )
00743 {
00744   readPublicKeys();
00745 
00746   for( KeyListIterator it( mPublicKeys ); (*it); ++it )
00747     if( (*it)->matchesUserID( userID ) )
00748       return (*it);
00749 
00750   return 0;
00751 }
00752 
00753 Key*
00754 Module::secretKey(const KeyID& keyID)
00755 {
00756   readSecretKeys();
00757 
00758   for( KeyListIterator it( mSecretKeys ); (*it); ++it )
00759     if( keyID == (*it)->primaryKeyID() ||
00760     keyID == (*it)->primaryFingerprint() )
00761       return (*it);
00762 
00763   return 0;
00764 }
00765 
00766 Validity
00767 Module::keyTrust( const KeyID& keyID )
00768 {
00769   Key *key = publicKey( keyID );
00770 
00771   if( ( 0 == key ) || ( key->keyTrust() == KPGP_VALIDITY_UNKNOWN ) )
00772   { // (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 QString& userID )
00783 {
00784   Key *key = publicKey( userID );
00785 
00786   if( key == 0 )
00787     return KPGP_VALIDITY_UNKNOWN;
00788 
00789   if( key->keyTrust() == KPGP_VALIDITY_UNKNOWN )
00790   {
00791     key = rereadKey( key->primaryKeyID(), true );
00792     if( key == 0 )
00793       return KPGP_VALIDITY_UNKNOWN;
00794   }
00795 
00796   return key->keyTrust();
00797 }
00798 
00799 bool
00800 Module::isTrusted( const KeyID& keyID )
00801 {
00802   return ( keyTrust( keyID ) >= KPGP_VALIDITY_MARGINAL );
00803 }
00804 
00805 Key*
00806 Module::rereadKey( const KeyID& keyID, const bool readTrust /* = 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 QCString
00832 Module::getAsciiPublicKey(const KeyID& keyID)
00833 {
00834   if (0 == pgp) assignPGPBase();
00835 
00836   return pgp->getAsciiPublicKey(keyID);
00837 }
00838 
00839 
00840 bool Module::setPassPhrase(const char * aPass)
00841 {
00842   // 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 QString
00889 Module::lastErrorMsg(void) const
00890 {
00891   return errMsg;
00892 }
00893 
00894 bool
00895 Module::havePGP(void) const
00896 {
00897   return havePgp;
00898 }
00899 
00900 void
00901 Module::setShowCipherText(const bool flag)
00902 {
00903   showEncryptionResult = flag;
00904 }
00905 
00906 bool
00907 Module::showCipherText(void) const
00908 {
00909   return showEncryptionResult;
00910 }
00911 
00912 KeyID
00913 Module::selectSecretKey( const QString& title,
00914                          const QString& text,
00915                          const KeyID& keyId )
00916 {
00917   if( 0 == pgp ) {
00918     assignPGPBase();
00919   }
00920 
00921   if( usePGP() ) {
00922     return selectKey( secretKeys(), title, text, keyId, SecretKeys );
00923   }
00924   else {
00925     KMessageBox::sorry( 0, i18n("You either do not have GnuPG/PGP installed "
00926                                 "or you chose not to use GnuPG/PGP.") );
00927     return KeyID();
00928   }
00929 }
00930 
00931 KeyID
00932 Module::selectPublicKey( const QString& title,
00933                          const QString& text /* = QString::null */,
00934                          const KeyID& oldKeyId /* = KeyID() */,
00935                          const QString& address /* = QString::null */,
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 QString& title,
00969                           const QString& text /* = QString::null */,
00970                           const KeyIDList& oldKeyIds /* = KeyIDList() */,
00971                           const QString& address /* = QString::null */,
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       kdError(5100) << "there is no instance of kpgp available" << endl;
01011   }
01012   return kpgpObject;
01013 }
01014 
01015 
01016 KConfig *
01017 Module::getConfig()
01018 {
01019   return getKpgp()->config;
01020 }
01021 
01022 
01023 bool
01024 Module::prepareMessageForDecryption( const QCString& msg,
01025                                      QPtrList<Block>& pgpBlocks,
01026                                      QStrList& nonPgpBlocks )
01027 {
01028   BlockType pgpBlock = NoPgpBlock;
01029   int start = -1;   // 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 QString& person )
01108 {
01109   if( 0 == pgp ) assignPGPBase();
01110 
01111   if( !usePGP() ) return false;
01112 
01113   readPublicKeys();
01114 
01115   QString address = canonicalAddress( person ).lower();
01116 
01117   // 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 QString& person )
01168 {
01169   if( 0 == pgp ) assignPGPBase();
01170 
01171   if( !usePGP() ) return KeyIDList();
01172 
01173   readPublicKeys();
01174 
01175   QString address = canonicalAddress( person ).lower();
01176 
01177   // #### 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   QCString path;
01329   QStrList pSearchPaths;
01330   int index = 0;
01331   int lastindex = -1;
01332 
01333   havePgp=FALSE;
01334 
01335   path = getenv("PATH");
01336   while((index = path.find(":",lastindex+1)) != -1)
01337   {
01338     pSearchPaths.append(path.mid(lastindex+1,index-lastindex-1));
01339     lastindex = index;
01340   }
01341   if(lastindex != (int)path.length() - 1)
01342     pSearchPaths.append( path.mid(lastindex+1,path.length()-lastindex) );
01343 
01344   QStrListIterator it(pSearchPaths);
01345 
01346   haveGpg=FALSE;
01347   // 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       default:
01439         kdDebug(5100) << "Kpgp: assign pgp - default" << endl;
01440         if (haveGpg)
01441         {
01442           kdDebug(5100) << "Kpgp: pgpBase is gpg " << endl;
01443           pgp = new BaseG();
01444           pgpType = tGPG;
01445         }
01446         else if(havePGP5)
01447         {
01448           kdDebug(5100) << "Kpgp: pgpBase is pgp 5" << endl;
01449           pgp = new Base5();
01450           pgpType = tPGP5;
01451         }
01452         else
01453         {
01454           Base6 *pgp_v6 = new Base6();
01455           if (!pgp_v6->isVersion6())
01456           {
01457             kdDebug(5100) << "Kpgp: pgpBase is pgp 2 " << endl;
01458             delete pgp_v6;
01459             pgp = new Base2();
01460             pgpType = tPGP2;
01461           }
01462           else
01463           {
01464             kdDebug(5100) << "Kpgp: pgpBase is pgp 6 " << endl;
01465             pgp = pgp_v6;
01466             pgpType = tPGP6;
01467           }
01468         }
01469     } // switch
01470   }
01471   else
01472   {
01473     // dummy handler
01474     kdDebug(5100) << "Kpgp: pgpBase is dummy " << endl;
01475     pgp = new Base();
01476     pgpType = tOff;
01477   }
01478 }
01479 
01480 QString
01481 Module::canonicalAddress( const QString& _adress )
01482 {
01483   int index,index2;
01484 
01485   QString address = _adress.simplifyWhiteSpace();
01486   address = address.stripWhiteSpace();
01487 
01488   // just leave pure e-mail address.
01489   if((index = address.find("<")) != -1)
01490     if((index2 = address.find("@",index+1)) != -1)
01491       if((index2 = address.find(">",index2+1)) != -1)
01492     return address.mid(index,index2-index+1);
01493 
01494   if((index = address.find("@")) == -1)
01495   {
01496     // local address
01497     //char hostname[1024];
01498     //gethostname(hostname,1024);
01499     //return "<" + address + "@" + hostname + ">";
01500     return "<" + address + "@localdomain>";
01501   }
01502   else
01503   {
01504     int index1 = address.findRev(" ",index);
01505     int index2 = address.find(" ",index);
01506     if(index2 == -1) index2 = address.length();
01507     return "<" + address.mid(index1+1 ,index2-index1-1) + ">";
01508   }
01509 }
01510 
01511 void
01512 Module::readPublicKeys( bool reread )
01513 {
01514   if( 0 == pgp ) assignPGPBase();
01515 
01516   if( !usePGP() )
01517   {
01518     mPublicKeys.clear();
01519     mPublicKeysCached = false;
01520     return;
01521   }
01522 
01523   if( !mPublicKeysCached || reread )
01524   {
01525     if( mPublicKeys.isEmpty() )
01526     {
01527       mPublicKeys = pgp->publicKeys();
01528     }
01529     else
01530     {
01531       KeyList newPublicKeyList = pgp->publicKeys();
01532 
01533       // merge the trust info from the old key list into the new key list
01534       // FIXME: This is currently O(K^2) where K = #keys. As the key lists
01535       //        are sorted this can be done in O(K).
01536       KeyListIterator it( newPublicKeyList );
01537       for( it.toFirst(); (*it); ++it )
01538       {
01539         Key* oldKey = publicKey( (*it)->primaryKeyID() );
01540         if( oldKey )
01541         {
01542           (*it)->cloneKeyTrust( oldKey );
01543         }
01544       }
01545 
01546       mPublicKeys = newPublicKeyList;
01547     }
01548 
01549     mPublicKeysCached = true;
01550     mPublicKeys.setAutoDelete( true );
01551   }
01552 }
01553 
01554 void
01555 Module::readSecretKeys( bool reread )
01556 {
01557   if( 0 == pgp ) assignPGPBase();
01558 
01559   if( !usePGP() )
01560   {
01561     mSecretKeys.clear();
01562     mSecretKeysCached = false;
01563     return;
01564   }
01565 
01566   if( mSecretKeys.isEmpty() || reread )
01567   {
01568     if( mSecretKeys.isEmpty() )
01569     {
01570       mSecretKeys = pgp->secretKeys();
01571     }
01572     else
01573     {
01574       KeyList newSecretKeyList = pgp->secretKeys();
01575 
01576       // merge the trust info from the old key list into the new key list
01577       // FIXME: This is currently O(K^2) where K = #keys. As the key lists
01578       //        are sorted this can be done in O(K).
01579       KeyListIterator it( newSecretKeyList );
01580       for( it.toFirst(); (*it); ++it )
01581       {
01582         Key* oldKey = secretKey( (*it)->primaryKeyID() );
01583         if( oldKey )
01584         {
01585           (*it)->cloneKeyTrust( oldKey );
01586         }
01587       }
01588 
01589       mSecretKeys = newSecretKeyList;
01590     }
01591 
01592     mSecretKeysCached = true;
01593     mSecretKeys.setAutoDelete( true );
01594   }
01595 }
01596 
01597 KeyID
01598 Module::selectKey( const KeyList& keys,
01599                    const QString& title,
01600                    const QString& text /* = QString::null */ ,
01601                    const KeyID& keyId /* = KeyID() */ ,
01602                    const unsigned int allowedKeys /* = AllKeys */ )
01603 {
01604   KeyID retval = KeyID();
01605 
01606   KeySelectionDialog dlg( keys, title, text, KeyIDList( keyId ), false,
01607                           allowedKeys, false );
01608 
01609   QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01610   bool rej = ( dlg.exec() == QDialog::Rejected );
01611   QApplication::restoreOverrideCursor();
01612 
01613   if( !rej ) {
01614     retval = dlg.key();
01615   }
01616 
01617   return retval;
01618 }
01619 
01620 KeyIDList
01621 Module::selectKeys( const KeyList& keys,
01622                     const QString& title,
01623                     const QString& text /* = QString::null */ ,
01624                     const KeyIDList& keyIds /* = KeyIDList() */ ,
01625                     const unsigned int allowedKeys /* = AllKeys */ )
01626 {
01627   KeyIDList retval = KeyIDList();
01628 
01629   KeySelectionDialog dlg( keys, title, text, keyIds, false, allowedKeys,
01630                           true );
01631 
01632   QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01633   bool rej = ( dlg.exec() == QDialog::Rejected );
01634   QApplication::restoreOverrideCursor();
01635 
01636   if( !rej ) {
01637     retval = dlg.keys();
01638   }
01639 
01640   return retval;
01641 }
01642 
01643 
01644 KeyID
01645 Module::selectKey( bool& rememberChoice,
01646                    const KeyList& keys,
01647                    const QString& title,
01648                    const QString& text /* = QString::null */ ,
01649                    const KeyID& keyId /* = KeyID() */ ,
01650                    const unsigned int allowedKeys /* = AllKeys */ )
01651 {
01652   KeyID retval = KeyID();
01653 
01654   KeySelectionDialog dlg( keys, title, text, KeyIDList( keyId ), false,
01655                           allowedKeys, false );
01656 
01657   QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01658   bool rej = ( dlg.exec() == QDialog::Rejected );
01659   QApplication::restoreOverrideCursor();
01660 
01661   if( !rej ) {
01662     retval = dlg.key();
01663     rememberChoice = dlg.rememberSelection();
01664   }
01665   else {
01666     rememberChoice = false;
01667   }
01668 
01669   return retval;
01670 }
01671 
01672 KeyIDList
01673 Module::selectKeys( bool& rememberChoice,
01674                     const KeyList& keys,
01675                     const QString& title,
01676                     const QString& text /* = QString::null */ ,
01677                     const KeyIDList& keyIds /* = KeyIDList() */ ,
01678                     const unsigned int allowedKeys /* = AllKeys */ )
01679 {
01680   KeyIDList retval = KeyIDList();
01681 
01682   KeySelectionDialog dlg( keys, title, text, keyIds, true, allowedKeys,
01683                           true );
01684 
01685   QApplication::setOverrideCursor( QCursor(QCursor::ArrowCursor) );
01686   bool rej = ( dlg.exec() == QDialog::Rejected );
01687   QApplication::restoreOverrideCursor();
01688 
01689   if( !rej ) {
01690     retval = dlg.keys();
01691     rememberChoice = dlg.rememberSelection();
01692   }
01693   else {
01694     rememberChoice = false;
01695   }
01696 
01697   return retval;
01698 }
01699 
01700 KeyIDList
01701 Module::keysForAddress( const QString& address )
01702 {
01703   if( address.isEmpty() ) {
01704     return KeyIDList();
01705   }
01706   QString addr = canonicalAddress( address ).lower();
01707   if( addressDataDict.contains( addr ) ) {
01708     return addressDataDict[addr].keyIds;
01709   }
01710   else {
01711     return KeyIDList();
01712   }
01713 }
01714 
01715 void
01716 Module::setKeysForAddress( const QString& address, const KeyIDList& keyIds )
01717 {
01718   if( address.isEmpty() ) {
01719     return;
01720   }
01721   QString addr = canonicalAddress( address ).lower();
01722   if( addressDataDict.contains( addr ) ) {
01723     addressDataDict[addr].keyIds = keyIds;
01724   }
01725   else {
01726     AddressData data;
01727     data.encrPref = UnknownEncryptPref;
01728     data.keyIds = keyIds;
01729     addressDataDict.insert( addr, data );
01730   }
01731 
01732   //writeAddressData();
01733 }
01734 
01735 void
01736 Module::readAddressData()
01737 {
01738   QString address;
01739   AddressData data;
01740 
01741   KConfigGroup general( config, "General" );
01742   int num = general.readNumEntry( "addressEntries", 0 );
01743 
01744   addressDataDict.clear();
01745   for( int i=1; i<=num; i++ ) {
01746     KConfigGroup addrGroup( config, QString("Address #%1").arg(i).local8Bit() );
01747     address = addrGroup.readEntry( "Address" );
01748     data.keyIds = KeyIDList::fromStringList( addrGroup.readListEntry( "Key IDs" ) );
01749     data.encrPref = (EncryptPref) addrGroup.readNumEntry( "EncryptionPreference",
01750                                                           UnknownEncryptPref );
01751 //     kdDebug(5100) << "Read address " << i << ": " << address
01752 //                   << "\nKey IDs: 0x" << data.keyIds.toStringList().join(", 0x")
01753 //                   << "\nEncryption preference: " << data.encrPref << endl;
01754     if ( !address.isEmpty() ) {
01755       addressDataDict.insert( address, data );
01756     }
01757   }
01758 }
01759 
01760 void
01761 Module::writeAddressData()
01762 {
01763   KConfigGroup general( config, "General" );
01764   general.writeEntry( "addressEntries", addressDataDict.count() );
01765 
01766   int i;
01767   AddressDataDict::Iterator it;
01768   for ( i=1, it = addressDataDict.begin();
01769         it != addressDataDict.end();
01770         ++it, i++ ) {
01771     KConfigGroup addrGroup( config, QString("Address #%1").arg(i).local8Bit() );
01772     addrGroup.writeEntry( "Address", it.key() );
01773     addrGroup.writeEntry( "Key IDs", it.data().keyIds.toStringList() );
01774     addrGroup.writeEntry( "EncryptionPreference", it.data().encrPref );
01775   }
01776 
01777   config->sync();
01778 }
01779 
01780 EncryptPref
01781 Module::encryptionPreference( const QString& address )
01782 {
01783   QString addr = canonicalAddress( address ).lower();
01784   if( addressDataDict.contains( addr ) ) {
01785     return addressDataDict[addr].encrPref;
01786   }
01787   else {
01788     return UnknownEncryptPref;
01789   }
01790 }
01791 
01792 void
01793 Module::setEncryptionPreference( const QString& address,
01794                                  const EncryptPref pref )
01795 {
01796   if( address.isEmpty() ) {
01797     return;
01798   }
01799   QString addr = canonicalAddress( address ).lower();
01800   if( addressDataDict.contains( addr ) ) {
01801     addressDataDict[addr].encrPref = pref;
01802   }
01803   else {
01804     AddressData data;
01805     data.encrPref = pref;
01806     addressDataDict.insert( addr, data );
01807   }
01808 }
01809 
01810 } // namespace Kpgp
KDE Logo
This file is part of the documentation for libkdenetwork Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Apr 4 04:44:06 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003