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