[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    [PATCH] Use the Kpgp key handling also with the OpenPGP plugin
From:       Ingo =?iso-8859-15?q?Kl=F6cker?= <kloecker () kde ! org>
Date:       2002-09-29 18:30:17
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


Hi,

the attached patch fixes the inconsistent key handling of the built-in 
"OpenPGP" support and the OpenPGP support via the plugin. Now in both 
cases our nice key browser is used instead of the not very comfortable 
key selection dialog of the Aegypten project. For S/MIME still the 
Aegypten code is used.

Advantages:
- Automatic encryption works also with the OpenPGP plugin.
- Encrypt to self works with the OpenPGP plugin.
- You get the nice built-in key selection dialog.
- Multiple encryption keys per recipients works with the OpenPGP plugin.
- Arbitrary address <-> encryption keys associations are also used with 
the OpenPGP plugin.

Disadvantages:
- The settings for "Automatic encryption" and "Encrypt to self" are on 
the OpenPGP configuration page. Therefore it might be a little bit 
confusing that they also apply to the OpenPGP plugin. But I don't think 
that these are serious drawbacks.

BTW, I also fixed the bug that some message parts where not 
signed/encrypted even if one answered "Yes, sign all parts" resp. "Yes, 
encrypt all parts".

Furthermore, I moved a lot of code from KMComposeWin::pgpEncryptedMsg 
into two new functions. That's why the patch is so large.

Regards,
Ingo


["use-kpgp-key-selection-code-also-with-openpgp-plugin.diff" (text/x-diff)]

Index: kmcomposewin.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmcomposewin.h,v
retrieving revision 1.173
diff -u -3 -p -r1.173 kmcomposewin.h
--- kmcomposewin.h	2002/09/11 22:52:48	1.173
+++ kmcomposewin.h	2002/09/29 17:35:55
@@ -590,6 +590,17 @@ private:
                               QCString& encryptCertFingerprints );
 
   /**
+   * Get encryption certificate for a recipient (the Aegypten way).
+   */
+  QCString getEncryptionCertificate( const QString& recipient );
+
+  /**
+   * Check for expiry of various certificates.
+   */
+  bool checkForEncryptCertificateExpiry( const QString& recipient,
+                                         const QCString& certFingerprint );
+
+  /**
    * Build a MIME object (or a flat text resp.) based upon
    * structuring information returned by a crypto plugin that was
    * called via pgpSignedMsg() (or pgpEncryptedMsg(), resp.).
Index: kmcomposewin.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmcomposewin.cpp,v
retrieving revision 1.600
diff -u -3 -p -r1.600 kmcomposewin.cpp
--- kmcomposewin.cpp	2002/09/29 13:15:54	1.600
+++ kmcomposewin.cpp	2002/09/29 17:35:54
@@ -1399,19 +1399,22 @@ bool KMComposeWin::applyChanges(void)
     kernel->identityManager()->identityForUoidOrDefault( \
mIdentity->currentIdentity() );  QCString pgpUserId = ident.pgpIdentity();
 
-  Kpgp::Module *pgp = Kpgp::Module::getKpgp();
-
   // check settings of composer buttons *and* attachment check boxes
   bool doSignCompletely    = doSign;
   bool doEncryptCompletely = doEncrypt;
+  bool doEncryptPartially  = doEncrypt;
   if( mSelectedCryptPlug && (0 < mAtmList.count() ) ) {
     int idx=0;
     KMMessagePart *attachPart;
     for( attachPart = mAtmList.first();
          attachPart;
          attachPart=mAtmList.next(), ++idx ) {
-      if( !encryptFlagOfAttachment( idx ) )
+      if( encryptFlagOfAttachment( idx ) ) {
+        doEncryptPartially = true;
+      }
+      else {
         doEncryptCompletely = false;
+      }
       if( !signFlagOfAttachment(    idx ) )
         doSignCompletely = false;
     }
@@ -1452,45 +1455,17 @@ bool KMComposeWin::applyChanges(void)
     }
   }
 
-  if( bOk && !doEncryptCompletely ) {
-    if( mSelectedCryptPlug ) {
-      // note: only ask for encrypting if "Warn me" flag is set! (khz)
-      if( mSelectedCryptPlug->warnSendUnencrypted() ) {
-        int ret =
-        KMessageBox::warningYesNoCancel( this,
-          QString( "<qt><b>"
-            + i18n("Warning:")
-            + "</b><br>"
-            + ((doEncrypt && !doEncryptCompletely)
-              ? i18n("You specified not to encrypt some parts of this message, but"
-                     " you wanted to be warned not to send unencrypted messages!")
-              : i18n("You specified not to encrypt this message, but"
-                     " you wanted to be warned not to send unencrypted messages!") )
-            + "<br>&nbsp;<br><b>"
-            + i18n("Encrypt all parts of this message?")
-            + "</b></qt>" ),
-          i18n("Encryption Warning"),
-          KGuiItem( i18n("&Encrypt All Parts") ),
-          KGuiItem( i18n("Send &as is") ) );
-        if( ret == KMessageBox::Cancel )
-          bOk = false;
-        else if( ret == KMessageBox::Yes ) {
-          doEncrypt = true;
-          doEncryptCompletely = true;
-        }
-      }
-
-      /*
-      note: Processing the mSelectedCryptPlug->encryptEmail() flag here would
-            be absolutely wrong: this is used for specifying
-                if messages should be encrypted 'in general'.
-            --> This sets the initial state of a freshly started Composer.
-            --> This does *not* mean overriding user setting made while
-                editing in that composer window!         (khz, 2002/06/26)
-      */
-
-    } else if( mAutoPgpEncrypt && !pgpUserId.isEmpty() ) {
-      // determine the complete list of recipients
+  if( bOk ) {
+    // check whether the user selected built-in OpenPGP or the OpenPGP plugin
+    bool bUsingOpenPgp = !mSelectedCryptPlug || ( mSelectedCryptPlug &&
+                   ( -1 != mSelectedCryptPlug->libName().find( "openpgp" ) ) );
+    // check whether encryption is possible
+    bool bEncryptionPossible = !Kpgp::Module::getKpgp()->encryptToSelf()
+                               || !pgpUserId.isEmpty();
+    if( !doEncryptPartially && mAutoPgpEncrypt && bEncryptionPossible &&
+        bUsingOpenPgp ) {
+      // check if encryption is possible and if yes suggest encryption
+      // first determine the complete list of recipients
       QString _to = to().simplifyWhiteSpace();
       if( !cc().isEmpty() ) {
         if( !_to.endsWith(",") )
@@ -1502,12 +1477,13 @@ bool KMComposeWin::applyChanges(void)
           _to += ",";
         _to += mMsg->bcc().simplifyWhiteSpace();
       }
-      // check if the message should be encrypted via old build-in pgp code
       QStringList allRecipients = KMMessage::splitEmailAddrList(_to);
+      // now check if encrypting to these recipients is possible and desired
+      Kpgp::Module *pgp = Kpgp::Module::getKpgp();
       int status = pgp->encryptionPossible( allRecipients );
-      if( status == 1 )
+      if( 1 == status )
         doEncrypt = true;
-      else if( status == 2 )
+      else if( 2 == status )
       { // the user wants to be asked or has to be asked
         kernel->kbp()->idle();
         int ret;
@@ -1532,7 +1508,10 @@ bool KMComposeWin::applyChanges(void)
         kernel->kbp()->busy();
         if( KMessageBox::Cancel == ret )
           return false;
-        doEncrypt = ( KMessageBox::Yes == ret );
+        else if( ret == KMessageBox::Yes ) {
+          doEncrypt = true;
+          doEncryptCompletely = true;
+        }
       }
       else if( status == -1 )
       { // warn the user that there are conflicting encryption preferences
@@ -1549,8 +1528,60 @@ bool KMComposeWin::applyChanges(void)
         doEncrypt = ( ret == KMessageBox::Yes );
       }
     }
+    else if( !doEncryptCompletely && mSelectedCryptPlug ) {
+      // note: only ask for encrypting if "Warn me" flag is set! (khz)
+      if( mSelectedCryptPlug->warnSendUnencrypted() ) {
+        int ret =
+        KMessageBox::warningYesNoCancel( this,
+          QString( "<qt><b>"
+            + i18n("Warning:")
+            + "</b><br>"
+            + ((doEncrypt && !doEncryptCompletely)
+              ? i18n("You specified not to encrypt some parts of this message, but"
+                     " you wanted to be warned not to send unencrypted messages!")
+              : i18n("You specified not to encrypt this message, but"
+                     " you wanted to be warned not to send unencrypted messages!") )
+            + "<br>&nbsp;<br><b>"
+            + i18n("Encrypt all parts of this message?")
+            + "</b></qt>" ),
+          i18n("Encryption Warning"),
+          KGuiItem( i18n("&Encrypt All Parts") ),
+          KGuiItem( i18n("Send &as is") ) );
+        if( ret == KMessageBox::Cancel )
+          bOk = false;
+        else if( ret == KMessageBox::Yes ) {
+          doEncrypt = true;
+          doEncryptCompletely = true;
+        }
+      }
+
+      /*
+      note: Processing the mSelectedCryptPlug->encryptEmail() flag here would
+            be absolutely wrong: this is used for specifying
+                if messages should be encrypted 'in general'.
+            --> This sets the initial state of a freshly started Composer.
+            --> This does *not* mean overriding user setting made while
+                editing in that composer window!         (khz, 2002/06/26)
+      */
+
+    }
   }
 
+  if( bOk ) {
+    // if necessary mark all attachments for signing/encryption
+    if( mSelectedCryptPlug && ( 0 < mAtmList.count() ) &&
+        ( doSignCompletely || doEncryptCompletely ) ) {
+      for( KMAtmListViewItem* lvi = (KMAtmListViewItem*)mAtmItemList.first();
+           lvi;
+           lvi = (KMAtmListViewItem*)mAtmItemList.next() ) {
+        if( doSignCompletely )
+          lvi->setSign( true );
+        if( doEncryptCompletely )
+          lvi->setEncrypt( true );
+      }
+    }
+  }
+
   // This c-string (init empty here) is set by *first* testing of expiring
   // signature certificate and stops us from repeatedly asking same questions.
   QCString signCertFingerprint;
@@ -2623,7 +2654,52 @@ QByteArray KMComposeWin::pgpSignedMsg( Q
 
     bool bSign = true;
 
-    if( signCertFingerprint.isEmpty() ){
+    if( signCertFingerprint.isEmpty() ) {
+      // find out whether we are dealing with the OpenPGP or the S/MIME plugin
+      if( -1 != mSelectedCryptPlug->libName().find( "openpgp" ) ) {
+        // We are dealing with the OpenPGP plugin. Use Kpgp to determine
+        // the signing key.
+        // get the OpenPGP key ID for the chosen identity
+        const KMIdentity & ident =
+          kernel->identityManager()->identityForUoidOrDefault( \
mIdentity->currentIdentity() ); +        QCString userKeyId = ident.pgpIdentity();
+        if( !userKeyId.isEmpty() ) {
+          Kpgp::Module *pgp = Kpgp::Module::getKpgp();
+          Kpgp::Key* key = pgp->publicKey( userKeyId );
+          if( key ) {
+            signCertFingerprint = key->primaryFingerprint();
+            kdDebug(5006) << "                          Signer: " << from()
+                          << "\nFingerprint of signature key: "
+                          << QString( signCertFingerprint ) << endl;
+          }
+          else {
+            KMessageBox::sorry( this,
+                                i18n("<qt>This message could not be signed "
+                                     "because the OpenPGP which should be "
+                                     "used for signing messages with this "
+                                     "identity couldn't be found in your "
+                                     "keyring.<br><br>"
+                                     "You can change the OpenPGP key "
+                                     "which should be used with the current "
+                                     "identity in the identity \
configuration.</qt>"), +                                i18n("Missing Signing Key") \
); +            bSign = false;
+          }
+        }
+        else {
+          KMessageBox::sorry( this,
+                              i18n("<qt>This message could not be signed "
+                                   "because you didn't define the OpenPGP "
+                                   "key which should be used for signing "
+                                   "messages with this identity.<br><br>"
+                                   "You can define the OpenPGP key "
+                                   "which should be used with the current "
+                                   "identity in the identity configuration.</qt>"),
+                              i18n("Undefined Signing Key") );
+          bSign = false;
+        }
+      }
+      else { // S/MIME
         int certSize = 0;
         QByteArray certificate;
         QString selectedCert;
@@ -2692,7 +2768,7 @@ QByteArray KMComposeWin::pgpSignedMsg( Q
                     bSign = false;
             }
         }
-
+      }
 
 /* ----------------------------- */
 #ifdef DEBUG
@@ -2968,220 +3044,65 @@ QByteArray KMComposeWin::pgpEncryptedMsg
 
 
     if( encryptCertFingerprints.isEmpty() ){
-
-      QString selectedCert;
-      KListBoxDialog dialog( selectedCert, "", i18n( "&Select certificate:" ) );
-      dialog.resize( 700, 200 );
-      bool useDialog;
-      int certSize = 0;
-      QByteArray certificateList;
-
-      for( QStringList::ConstIterator it = recipients.begin(); it != \
                recipients.end(); ++it ) {
-        QCString addressee = (*it).utf8();
-        addressee.replace(QRegExp("\\x0001"), " ");
-        kdDebug(5006) << "\n\n1st try:  Retrieving keys for: " << *it << endl;
-
-
-        bool askForDifferentSearchString = false;
-        do {
-
-          certSize = 0;
-          char* certificatePtr = 0;
-          bool findCertsOk;
-          if( askForDifferentSearchString )
-            findCertsOk = false;
-          else {
-            findCertsOk = mSelectedCryptPlug->findCertificates( &(*addressee),
-                                                      &certificatePtr,
-                                                      &certSize,
-                                                      false )
-                          && (0 < certSize);
-            kdDebug(5006) << "         keys retrieved successfully: " << findCertsOk \
                << "\n" << endl;
-            kdDebug() << "findCertificates() 1st try returned " << certificatePtr << \
                endl;
-            if( findCertsOk )
-              certificateList.assign( certificatePtr, certSize );
-          }
-          while( !findCertsOk ) {
-            bool bOk = false;
-            addressee = KLineEditDlg::getText(
-                          askForDifferentSearchString
-                          ? i18n("Look for other certificates")
-                          : i18n("No certificate found"),
-                          i18n("Enter different address for recipient %1 "
-                              "or enter \" * \" to see all certificates:").arg(*it),
-                          addressee, &bOk, this ).stripWhiteSpace().utf8();
-            askForDifferentSearchString = false;
-            if( bOk ) {
-              addressee = addressee.simplifyWhiteSpace();
-              if( ("\"*\"" == addressee) ||
-                  ("\" *\"" == addressee) ||
-                  ("\"* \"" == addressee) ||
-                  ("\" * \"" == addressee))  // You never know what users type.  :-)
-                addressee = "*";
-              kdDebug(5006) << "\n\nnext try: Retrieving keys for: " << addressee << \
                endl;
-              certSize = 0;
-              char* certificatePtr = 0;
-              findCertsOk = mSelectedCryptPlug->findCertificates(
-                                            &(*addressee),
-                                            &certificatePtr,
-                                            &certSize,
-                                            false )
-                            && (0 < certSize);
-              kdDebug(5006) << "         keys retrieved successfully: " << \
                findCertsOk << "\n" << endl;
-              kdDebug() << "findCertificates() 2nd try returned " << certificatePtr \
                << endl;
-              if( findCertsOk )
-                certificateList.assign( certificatePtr, certSize );
-            } else {
-              bEncrypt = false;
-              break;
-            }
-          }
-          if( bEncrypt && findCertsOk ) {
-
-            // fill selection dialog listbox
-            dialog.entriesLB->clear();
-            // show dialog even if only one entry to allow specifying of
-            // another search string _instead_of_ the recipients address
-            bool bAllwaysShowDialog = true;
+      // find out whether we are dealing with the OpenPGP or the S/MIME plugin
+      if( -1 != mSelectedCryptPlug->libName().find( "openpgp" ) ) {
+        // We are dealing with the OpenPGP plugin. Use Kpgp to determine
+        // the encryption keys.
+        // get the OpenPGP key ID for the chosen identity
+        const KMIdentity & ident =
+          kernel->identityManager()->identityForUoidOrDefault( \
mIdentity->currentIdentity() ); +        QCString userKeyId = ident.pgpIdentity();
+        Kpgp::Module *pgp = Kpgp::Module::getKpgp();
+        Kpgp::KeyIDList encryptionKeyIds;
+        Kpgp::Result result =
+          pgp->getEncryptionKeys( encryptionKeyIds, recipients, userKeyId );
 
-            useDialog = false;
-            int iA = 0;
-            int iZ = 0;
-            while( iZ < certSize ) {
-              if( (certificateList.at(iZ) == '\1') || (certificateList.at(iZ) == \
                '\0') ) {
-                kdDebug(5006) << "iA=" << iA << " iZ=" << iZ << endl;
-                char c = certificateList.at(iZ);
-                if( (bAllwaysShowDialog || (c == '\1')) && !useDialog ) {
-                  // set up selection dialog
-                  useDialog = true;
-                  dialog.setCaption( i18n( "Select certificate for encryption "
-                                           "[%1]" )
-                                     .arg(*it) );
-                  dialog.setLabelAbove(
-                    i18n( "&Select certificate for recipient %1:" )
-                    .arg( *it ) );
-                }
-                certificateList.at(iZ) = '\0';
-                QString s = QString::fromUtf8( &certificateList.at(iA) );
-                certificateList.at(iZ) = c;
-                if( useDialog )
-                  dialog.entriesLB->insertItem( s );
-                else
-                  selectedCert = s;
-                ++iZ;
-                iA = iZ;
-              }
-              ++iZ;
-            }
-            // run selection dialog and retrieve user choice
-            // OR take the single entry (if only one was found)
-            if( useDialog ) {
-              dialog.setCommentBelow(
-                i18n("(Certificates matching address \"%1\", press "
-                     "[Cancel] to use different address for recipient %2.)")
-                .arg(addressee)
-                .arg(*it) );
-              dialog.entriesLB->setFocus();
-              dialog.entriesLB->setSelected( 0, true );
-              askForDifferentSearchString = (dialog.exec() != QDialog::Accepted);
+        if( Kpgp::Ok == result ) {
+          // loop over all key IDs
+          for( Kpgp::KeyIDList::ConstIterator it = encryptionKeyIds.begin();
+               it != encryptionKeyIds.end(); ++it ) {
+            Kpgp::Key* key = pgp->publicKey( *it );
+            if( key ) {
+              QCString certFingerprint = key->primaryFingerprint();
+              kdDebug(5006) << "Fingerprint of encryption key: "
+                            << QString( certFingerprint ) << endl;
+              // add this key to the list of encryption keys
+              if( !encryptCertFingerprints.isEmpty() )
+                encryptCertFingerprints += '\1';
+              encryptCertFingerprints += certFingerprint;
             }
           }
-        } while ( askForDifferentSearchString );
-
-
-        if( bEncrypt ) {
-          QCString certFingerprint = selectedCert.utf8();
-          certFingerprint.remove( 0, certFingerprint.findRev( '(' )+1 );
-          certFingerprint.truncate( certFingerprint.length()-1 );
-          kdDebug(5006) << "\n\n                    Recipient: " << *it
-                    <<   "\nFingerprint of encryption key: " << QString( \
                certFingerprint ) << "\n\n" << endl;
-
-          // Check for expiry of various certificates, but only if the
-          // plugin supports this.
-          if( mSelectedCryptPlug->hasFeature( Feature_WarnEncryptCertificateExpiry ) \
                ) {
-              QString captionWarn = i18n( "Certificate Warning [%1]" )
-                                    .arg( *it );
-              if( bEncrypt ) {
-                  int encRecvDaysLeft = \
                mSelectedCryptPlug->receiverCertificateDaysLeftToExpiry( \
                certFingerprint );
-                  if( mSelectedCryptPlug->receiverCertificateExpiryNearWarning() &&
-                      encRecvDaysLeft <
-                      \
                mSelectedCryptPlug->receiverCertificateExpiryNearWarningInterval() ) \
                {
-                      QString txt1;
-                      if( 0 < encRecvDaysLeft )
-                          txt1 = i18n( "The certificate of the recipient you want to \
send this message to expires in %1 days.<br>This means that after this period, the \
recipient will not be able to read your message any longer." ).arg( encRecvDaysLeft \
                );
-                      else if( 0 > encRecvDaysLeft )
-                          txt1 = i18n( "The certificate of the recipient you want to \
send this message to expired %1 days ago.<br>This means that the recipient will not \
                be able to read your message." ).arg( -encRecvDaysLeft );
-                      else
-                          txt1 = i18n( "The certificate of the recipient you want to \
send this message to expires today.<br>This means that beginning from tomorrow, the \
                recipient will not be able to read your message any longer." );
-                      int ret = KMessageBox::warningYesNo( this,
-                                  i18n( "<qt><p>%1</p>"
-                                        "<p>Do you still want to use this "
-                                        "certificate?</p></qt>" )
-                                  .arg( txt1 ),
-                                  captionWarn,
-                                  KGuiItem( i18n("&Use Certificate") ),
-                                  KGuiItem( i18n("&Don't Use Certificate") ) );
-                      if( ret == KMessageBox::No )
-                          bEncrypt = false;
-                  }
-              }
-
-              if( bEncrypt ) {
-                  int certInChainDaysLeft = \
                mSelectedCryptPlug->certificateInChainDaysLeftToExpiry( \
                certFingerprint );
-                  if( mSelectedCryptPlug->certificateInChainExpiryNearWarning() &&
-                      certInChainDaysLeft <
-                      \
                mSelectedCryptPlug->certificateInChainExpiryNearWarningInterval() ) {
-                      QString txt1;
-                      if( 0 < certInChainDaysLeft )
-                          txt1 = i18n( "One of the certificates in the chain of the \
certificate of the recipient you want to send this message to expires in %1 \
days.<br>This means that after this period, the recipient might not be able to read \
                your message any longer." ).arg( certInChainDaysLeft );
-                      else if( 0 > certInChainDaysLeft )
-                          txt1 = i18n( "One of the certificates in the chain of the \
certificate of the recipient you want to send this message to expired %1 days \
ago.<br>This means that the recipient might not be able to read your message." ).arg( \
                -certInChainDaysLeft );
-                      else
-                          txt1 = i18n( "One of the certificates in the chain of the \
certificate of the recipient you want to send this message to expires today.<br>This \
means that beginning from tomorrow, the recipient might not be able to read your \
                message any longer." );
-                      int ret = KMessageBox::warningYesNo( this,
-                                  i18n( "<qt><p>%1</p>"
-                                        "<p>Do you still want to use this "
-                                        "certificate?</p></qt>" )
-                                  .arg( txt1 ),
-                                  captionWarn,
-                                  KGuiItem( i18n("&Use Certificate") ),
-                                  KGuiItem( i18n("&Don't Use Certificate") ) );
-                      if( ret == KMessageBox::No )
-                          bEncrypt = false;
-                  }
-              }
-
-              /*  The following test is not neccessary, since we _got_ the \
                certificate
-                  by looking for all certificates of our addressee - so it _must_ be \
                valid
-                  for the respective address!
-
-                  // Check whether the receiver address is contained in
-                  // the certificate.
-                  if( bEncrypt && \
                mSelectedCryptPlug->receiverEmailAddressNotInCertificateWarning() &&
-                  !mSelectedCryptPlug->isEmailInCertificate( QString( \
                KMMessage::getEmailAddr( recipient ) ).utf8(),
-                  certFingerprint ) )  {
-                  int ret = KMessageBox::warningYesNo( this,
-                  i18n( "The certificate does not contain the email address of the \
sender.\nThis means that it will not be possible for the recipient to read this \
                message.\n\nDo you still want to use this certificate?" ),
-                  captionWarn );
-                  if( ret == KMessageBox::No )
-                  bEncrypt = false;
-                  }
-              */
-          }
+        }
+        else {
+          bEncrypt = false; 
+        }
+      }
+      else {
+        for( QStringList::ConstIterator it = recipients.begin();
+             ( bEncrypt && it != recipients.end() );
+             ++it ) {
+          QCString certFingerprint = getEncryptionCertificate( *it );
+        
+          bEncrypt = !certFingerprint.isEmpty();
 
           if( bEncrypt ) {
-            if( !encryptCertFingerprints.isEmpty() )
-              encryptCertFingerprints += '\1';
-            encryptCertFingerprints += certFingerprint;
+            certFingerprint.remove( 0, certFingerprint.findRev( '(' )+1 );
+            certFingerprint.truncate( certFingerprint.length()-1 );
+            kdDebug(5006) << "\n\n                    Recipient: " << *it
+                          <<   "\nFingerprint of encryption key: "
+                          << QString( certFingerprint ) << "\n\n" << endl;
+
+            bEncrypt = checkForEncryptCertificateExpiry( *it,
+                                                         certFingerprint );
+
+            if( bEncrypt ) {
+              if( !encryptCertFingerprints.isEmpty() )
+                encryptCertFingerprints += '\1';
+              encryptCertFingerprints += certFingerprint;
+            }
           }
-          else
-            break;
         }
-
-        if( !bEncrypt )  break;
-
       }
-
     } // if( encryptCertFingerprints.isEmpty() )
 
 
@@ -3237,7 +3158,241 @@ QByteArray KMComposeWin::pgpEncryptedMsg
 }
 
 
+//-----------------------------------------------------------------------------
+QCString
+KMComposeWin::getEncryptionCertificate( const QString& recipient )
+{
+  bool bEncrypt = true;
+
+  QCString addressee = recipient.utf8();
+  addressee.replace(QRegExp("\\x0001"), " ");
+  kdDebug(5006) << "\n\n1st try:  Retrieving keys for: " << recipient << endl;
+
+
+  QString selectedCert;
+  KListBoxDialog dialog( selectedCert, "", i18n( "&Select certificate:" ) );
+  dialog.resize( 700, 200 );
+  bool useDialog;
+  int certSize = 0;
+  QByteArray certificateList;
+
+  bool askForDifferentSearchString = false;
+  do {
+
+    certSize = 0;
+    char* certificatePtr = 0;
+    bool findCertsOk;
+    if( askForDifferentSearchString )
+      findCertsOk = false;
+    else {
+      findCertsOk = mSelectedCryptPlug->findCertificates( &(*addressee),
+                                                &certificatePtr,
+                                                &certSize,
+                                                false )
+                    && (0 < certSize);
+      kdDebug(5006) << "         keys retrieved successfully: " << findCertsOk << \
"\n" << endl; +      kdDebug() << "findCertificates() 1st try returned " << \
certificatePtr << endl; +      if( findCertsOk )
+        certificateList.assign( certificatePtr, certSize );
+    }
+    while( !findCertsOk ) {
+      bool bOk = false;
+      addressee = KLineEditDlg::getText(
+                    askForDifferentSearchString
+                    ? i18n("Look for other certificates")
+                    : i18n("No certificate found"),
+                    i18n("Enter different address for recipient %1 "
+                        "or enter \" * \" to see all certificates:")
+                    .arg(recipient),
+                    addressee, &bOk, this ).stripWhiteSpace().utf8();
+      askForDifferentSearchString = false;
+      if( bOk ) {
+        addressee = addressee.simplifyWhiteSpace();
+        if( ("\"*\"" == addressee) ||
+            ("\" *\"" == addressee) ||
+            ("\"* \"" == addressee) ||
+            ("\" * \"" == addressee))  // You never know what users type.  :-)
+          addressee = "*";
+        kdDebug(5006) << "\n\nnext try: Retrieving keys for: " << addressee << endl;
+        certSize = 0;
+        char* certificatePtr = 0;
+        findCertsOk = mSelectedCryptPlug->findCertificates(
+                                      &(*addressee),
+                                      &certificatePtr,
+                                      &certSize,
+                                      false )
+                      && (0 < certSize);
+        kdDebug(5006) << "         keys retrieved successfully: " << findCertsOk << \
"\n" << endl; +        kdDebug() << "findCertificates() 2nd try returned " << \
certificatePtr << endl; +        if( findCertsOk )
+          certificateList.assign( certificatePtr, certSize );
+      } else {
+        bEncrypt = false;
+        break;
+      }
+    }
+    if( bEncrypt && findCertsOk ) {
+
+      // fill selection dialog listbox
+      dialog.entriesLB->clear();
+      // show dialog even if only one entry to allow specifying of
+      // another search string _instead_of_ the recipients address
+      bool bAlwaysShowDialog = true;
+
+      useDialog = false;
+      int iA = 0;
+      int iZ = 0;
+      while( iZ < certSize ) {
+        if( (certificateList.at(iZ) == '\1') || (certificateList.at(iZ) == '\0') ) {
+          kdDebug(5006) << "iA=" << iA << " iZ=" << iZ << endl;
+          char c = certificateList.at(iZ);
+          if( (bAlwaysShowDialog || (c == '\1')) && !useDialog ) {
+            // set up selection dialog
+            useDialog = true;
+            dialog.setCaption( i18n( "Select certificate for encryption [%1]" )
+                              .arg( recipient ) );
+            dialog.setLabelAbove(
+              i18n( "&Select certificate for recipient %1:" )
+              .arg( recipient ) );
+          }
+          certificateList.at(iZ) = '\0';
+          QString s = QString::fromUtf8( &certificateList.at(iA) );
+          certificateList.at(iZ) = c;
+          if( useDialog )
+            dialog.entriesLB->insertItem( s );
+          else
+            selectedCert = s;
+          ++iZ;
+          iA = iZ;
+        }
+        ++iZ;
+      }
+      // run selection dialog and retrieve user choice
+      // OR take the single entry (if only one was found)
+      if( useDialog ) {
+        dialog.setCommentBelow(
+          i18n("(Certificates matching address \"%1\", "
+               "press [Cancel] to use different address for recipient %2.)")
+          .arg( addressee )
+          .arg( recipient ) );
+        dialog.entriesLB->setFocus();
+        dialog.entriesLB->setSelected( 0, true );
+        askForDifferentSearchString = (dialog.exec() != QDialog::Accepted);
+      }
+    }
+  } while ( askForDifferentSearchString );
+
+  if( bEncrypt )
+    return selectedCert.utf8();
+  else
+    return QCString();
+}
+
+
+bool KMComposeWin::checkForEncryptCertificateExpiry( const QString& recipient,
+                                                     const QCString& certFingerprint \
) +{
+  bool bEncrypt = true;
+
+  // Check for expiry of various certificates, but only if the
+  // plugin supports this.
+  if( mSelectedCryptPlug->hasFeature( Feature_WarnEncryptCertificateExpiry ) ) {
+    QString captionWarn = i18n( "Certificate Warning [%1]" ).arg( recipient );
+
+    int encRecvDaysLeft =
+      mSelectedCryptPlug->receiverCertificateDaysLeftToExpiry( certFingerprint );
+    if( mSelectedCryptPlug->receiverCertificateExpiryNearWarning() &&
+        encRecvDaysLeft <
+        mSelectedCryptPlug->receiverCertificateExpiryNearWarningInterval() ) {
+      QString txt1;
+      if( 0 < encRecvDaysLeft )
+        txt1 = i18n( "The certificate of the recipient you want to send this "
+                     "message to expires in %1 days.<br>This means that after "
+                     "this period, the recipient will not be able to read "
+                     "your message any longer." )
+               .arg( encRecvDaysLeft );
+      else if( 0 > encRecvDaysLeft )
+        txt1 = i18n( "The certificate of the recipient you want to send this "
+                     "message to expired %1 days ago.<br>This means that the "
+                     "recipient will not be able to read your message." )
+               .arg( -encRecvDaysLeft );
+      else
+        txt1 = i18n( "The certificate of the recipient you want to send this "
+                     "message to expires today.<br>This means that beginning "
+                     "from tomorrow, the recipient will not be able to read "
+                     "your message any longer." );
+      int ret = KMessageBox::warningYesNo( this,
+                                  i18n( "<qt><p>%1</p>"
+                                        "<p>Do you still want to use "
+                                        "this certificate?</p></qt>" )
+                                  .arg( txt1 ),
+                                  captionWarn,
+                                  KGuiItem( i18n("&Use Certificate") ),
+                                  KGuiItem( i18n("&Don't Use Certificate") ) );
+      if( ret == KMessageBox::No )
+        bEncrypt = false;
+    }
 
+    if( bEncrypt ) {
+      int certInChainDaysLeft =
+        mSelectedCryptPlug->certificateInChainDaysLeftToExpiry( certFingerprint );
+      if( mSelectedCryptPlug->certificateInChainExpiryNearWarning() &&
+          certInChainDaysLeft <
+          mSelectedCryptPlug->certificateInChainExpiryNearWarningInterval() ) {
+        QString txt1;
+        if( 0 < certInChainDaysLeft )
+          txt1 = i18n( "One of the certificates in the chain of the "
+                       "certificate of the recipient you want to send this "
+                       "message to expires in %1 days.<br>"
+                       "This means that after this period, the recipient "
+                       "might not be able to read your message any longer." )
+                 .arg( certInChainDaysLeft );
+        else if( 0 > certInChainDaysLeft )
+          txt1 = i18n( "One of the certificates in the chain of the "
+                       "certificate of the recipient you want to send this "
+                       "message to expired %1 days ago.<br>"
+                       "This means that the recipient might not be able to "
+                       "read your message." )
+                 .arg( -certInChainDaysLeft );
+        else
+          txt1 = i18n( "One of the certificates in the chain of the "
+                       "certificate of the recipient you want to send this "
+                       "message to expires today.<br>This means that "
+                       "beginning from tomorrow, the recipient might not be "
+                       "able to read your message any longer." );
+        int ret = KMessageBox::warningYesNo( this,
+                                  i18n( "<qt><p>%1</p>"
+                                        "<p>Do you still want to use this "
+                                        "certificate?</p></qt>" )
+                                  .arg( txt1 ),
+                                  captionWarn,
+                                  KGuiItem( i18n("&Use Certificate") ),
+                                  KGuiItem( i18n("&Don't Use Certificate") ) );
+        if( ret == KMessageBox::No )
+          bEncrypt = false;
+      }
+    }
+
+      /*  The following test is not neccessary, since we _got_ the certificate
+          by looking for all certificates of our addressee - so it _must_ be valid
+          for the respective address!
+
+          // Check whether the receiver address is contained in
+          // the certificate.
+          if( bEncrypt && \
mSelectedCryptPlug->receiverEmailAddressNotInCertificateWarning() && +          \
!mSelectedCryptPlug->isEmailInCertificate( QString( KMMessage::getEmailAddr( \
recipient ) ).utf8(), +          certFingerprint ) )  {
+          int ret = KMessageBox::warningYesNo( this,
+          i18n( "The certificate does not contain the email address of the \
sender.\nThis means that it will not be possible for the recipient to read this \
message.\n\nDo you still want to use this certificate?" ), +          captionWarn );
+          if( ret == KMessageBox::No )
+          bEncrypt = false;
+          }
+      */
+  }
+
+  return bEncrypt;
+}
 
 
 


[Attachment #6 (application/pgp-signature)]
_______________________________________________
KMail Developers mailing list
kmail@mail.kde.org
http://mail.kde.org/mailman/listinfo/kmail

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic