diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-04-28 16:44:42 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-04-28 16:44:42 -0500 |
commit | 7bd54f5a796f6f1276bbd310deaf1f2ac673954d (patch) | |
tree | 734f820f207e48208ae734b36ca12a8b90b9790b | |
parent | 8e5a6176843c174bd8dc1bc740518692bd0ab61d (diff) | |
download | tdepim-7bd54f5a796f6f1276bbd310deaf1f2ac673954d.tar.gz tdepim-7bd54f5a796f6f1276bbd310deaf1f2ac673954d.zip |
Fix retriggering of GPGMe socket notifiers in nested event loops
This resolves Bug 825
Add missing GPGMe feature checks to CMake
-rw-r--r-- | ConfigureChecks.cmake | 67 | ||||
-rw-r--r-- | certmanager/lib/ui/keylistview.cpp | 9 | ||||
-rw-r--r-- | certmanager/lib/ui/keyselectiondialog.cpp | 71 | ||||
-rw-r--r-- | config.h.cmake | 8 | ||||
-rw-r--r-- | kmail/kmmainwidget.cpp | 2 | ||||
-rw-r--r-- | libtdenetwork/gpgmepp/callbacks.cpp | 7 | ||||
-rw-r--r-- | libtdenetwork/qgpgme/eventloopinteractor.cpp | 15 |
7 files changed, 145 insertions, 34 deletions
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index aaa2eb93c..dd7034c7e 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -151,6 +151,73 @@ if( BUILD_LIBTDENETWORK OR BUILD_CERTMANAGER OR BUILD_KMAIL OR BUILD_KADDRESSBOO if( NOT HAVE_GPGME_0_4_BRANCH ) message( STATUS " found 'gpgme', version ${GPGME_VERSION}" ) endif( ) + + # check for various GPGME features + tde_save( CMAKE_CXX_FLAGS ) + tde_save( CMAKE_REQUIRED_LIBRARIES ) + string( REGEX REPLACE "-include tqt.h" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) + # See FIXME above regarding -D_FILE_OFFSET_BITS=64 + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GPGME_INCLUDE_DIRS} -D_FILE_OFFSET_BITS=64") + set( CMAKE_REQUIRED_LIBRARIES "${GPGME_LIBRARIES}") + + # check for GPGME_KEYLIST_MODE_VALIDATE + check_cxx_source_compiles(" + #include <gpgme.h> + int main() { + gpgme_keylist_mode_t mode = GPGME_KEYLIST_MODE_VALIDATE; + };" + HAVE_GPGME_KEYLIST_MODE_VALIDATE ) + + # check for gpgme_cancel + check_cxx_source_compiles(" + #include <gpgme.h> + int main() { + gpgme_ctx_t ctx = 0; + gpgme_error_t e = gpgme_cancel( ctx ); + };" + HAVE_GPGME_CANCEL ) + + # check for gpgme_key_t->keylist_mode + check_cxx_source_compiles(" + #include <gpgme.h> + int main() { + gpgme_key_t key = 0; + key->keylist_mode = 0; + };" + HAVE_GPGME_KEY_T_KEYLIST_MODE ) + + # check for gpgme_decrypt_result_t->wrong_key_usage + check_cxx_source_compiles(" + #include <gpgme.h> + int main() { + gpgme_decrypt_result_t res; + unsigned int wku = res->wrong_key_usage; + };" + HAVE_GPGME_WRONG_KEY_USAGE ) + + # check for GPGME_INCLUDE_CERTS_DEFAULT + check_cxx_source_compiles(" + #include <gpgme.h> + int main() { + int i = GPGME_INCLUDE_CERTS_DEFAULT; + };" + HAVE_GPGME_INCLUDE_CERTS_DEFAULT ) + + # check for gpgme_op_getauditlog + check_cxx_source_compiles(" + #include <gpgme.h> + int main() { + gpgme_ctx_t ctx = 0; + gpgme_data_t data = 0; + unsigned int flags = 0; + gpgme_error_t e = gpgme_op_getauditlog( ctx, data, flags ); + };" + HAVE_GPGME_OP_GETAUDITLOG ) + + # done checking for GPGME features + tde_restore( CMAKE_CXX_FLAGS ) + tde_restore( CMAKE_REQUIRED_LIBRARIES ) + endif( ) diff --git a/certmanager/lib/ui/keylistview.cpp b/certmanager/lib/ui/keylistview.cpp index 8e81b9768..00f69500b 100644 --- a/certmanager/lib/ui/keylistview.cpp +++ b/certmanager/lib/ui/keylistview.cpp @@ -333,13 +333,16 @@ Kleo::KeyListViewItem * Kleo::KeyListView::itemByFingerprint( const TQCString & void Kleo::KeyListView::slotRefreshKey( const GpgME::Key & key ) { const char * fpr = key.primaryFingerprint(); - if ( !fpr ) + if ( !fpr ) { return; - if ( KeyListViewItem * item = itemByFingerprint( fpr ) ) + } + if ( KeyListViewItem * item = itemByFingerprint( fpr ) ) { item->setKey ( key ); - else + } + else { // none found -> add it slotAddKey( key ); + } } // slots for the emission of covariant signals: diff --git a/certmanager/lib/ui/keyselectiondialog.cpp b/certmanager/lib/ui/keyselectiondialog.cpp index 9e005d583..c46228a43 100644 --- a/certmanager/lib/ui/keyselectiondialog.cpp +++ b/certmanager/lib/ui/keyselectiondialog.cpp @@ -265,29 +265,33 @@ namespace { } const TQPixmap * ColumnStrategy::pixmap( const GpgME::Key & key, int col ) const { - if ( col != 0 ) + if ( col != 0 ) { return 0; + } // this key did not undergo a validating keylisting yet: - if ( !( key.keyListMode() & GpgME::Context::Validate ) ) + if ( !( key.keyListMode() & GpgME::Context::Validate ) ) { return &mKeyUnknownPix; + } - if ( !checkKeyUsage( key, mKeyUsage ) ) + if ( !checkKeyUsage( key, mKeyUsage ) ) { return &mKeyBadPix; + } - if ( key.protocol() == GpgME::Context::CMS ) + if ( key.protocol() == GpgME::Context::CMS ) { return &mKeyGoodPix; + } switch ( key.userID(0).validity() ) { - default: - case GpgME::UserID::Unknown: - case GpgME::UserID::Undefined: - return &mKeyUnknownPix; - case GpgME::UserID::Never: - return &mKeyValidPix; - case GpgME::UserID::Marginal: - case GpgME::UserID::Full: - case GpgME::UserID::Ultimate: - return &mKeyGoodPix; + default: + case GpgME::UserID::Unknown: + case GpgME::UserID::Undefined: + return &mKeyUnknownPix; + case GpgME::UserID::Never: + return &mKeyValidPix; + case GpgME::UserID::Marginal: + case GpgME::UserID::Full: + case GpgME::UserID::Ultimate: + return &mKeyGoodPix; } } @@ -585,8 +589,9 @@ namespace { void Kleo::KeySelectionDialog::startKeyListJobForBackend( const CryptoBackend::Protocol * backend, const std::vector<GpgME::Key> & keys, bool validate ) { assert( backend ); KeyListJob * job = backend->keyListJob( false, false, validate ); // local, w/o sigs, validation as givem - if ( !job ) + if ( !job ) { return; + } connect( job, TQT_SIGNAL(result(const GpgME::KeyListResult&)), TQT_SLOT(slotKeyListResult(const GpgME::KeyListResult&)) ); @@ -599,8 +604,9 @@ void Kleo::KeySelectionDialog::startKeyListJobForBackend( const CryptoBackend::P std::transform( keys.begin(), keys.end(), std::back_inserter( fprs ), ExtractFingerprint() ); const GpgME::Error err = job->start( fprs, mKeyUsage & SecretKeys && !( mKeyUsage & PublicKeys ) ); - if ( err ) + if ( err ) { return showKeyListError( this, err ); + } // FIXME: create a MultiProgressDialog: (void)new ProgressDialog( job, validate ? i18n( "Checking selected keys..." ) : i18n( "Fetching keys..." ), this ); @@ -617,15 +623,18 @@ static void selectKeys( Kleo::KeyListView * klv, const std::vector<GpgME::Key> & } void Kleo::KeySelectionDialog::slotKeyListResult( const GpgME::KeyListResult & res ) { - if ( res.error() ) + if ( res.error() ) { showKeyListError( this, res.error() ); - else if ( res.isTruncated() ) + } + else if ( res.isTruncated() ) { ++mTruncated; + } - if ( --mListJobCount > 0 ) + if ( --mListJobCount > 0 ) { return; // not yet finished... + } - if ( mTruncated > 0 ) + if ( mTruncated > 0 ) { KMessageBox::information( this, i18n("<qt>One backend returned truncated output.<br>" "Not all available keys are shown</qt>", @@ -633,6 +642,7 @@ void Kleo::KeySelectionDialog::slotKeyListResult( const GpgME::KeyListResult & r "Not all available keys are shown</qt>", mTruncated), i18n("Key List Result") ); + } mKeyListView->flushKeys(); @@ -677,13 +687,16 @@ void Kleo::KeySelectionDialog::slotCheckSelection( KeyListViewItem * item ) { mSelectedKeys.clear(); if ( !mKeyListView->isMultiSelection() ) { - if ( item ) + if ( item ) { mSelectedKeys.push_back( item->key() ); + } } - for ( KeyListViewItem * it = mKeyListView->firstChild() ; it ; it = it->nextSibling() ) - if ( it->isSelected() ) + for ( KeyListViewItem * it = mKeyListView->firstChild() ; it ; it = it->nextSibling() ) { + if ( it->isSelected() ) { mSelectedKeys.push_back( it->key() ); + } + } mKeysToCheck.clear(); std::remove_copy_if( mSelectedKeys.begin(), mSelectedKeys.end(), @@ -700,8 +713,9 @@ void Kleo::KeySelectionDialog::slotCheckSelection( KeyListViewItem * item ) { } void Kleo::KeySelectionDialog::startValidatingKeyListing() { - if ( mKeysToCheck.empty() ) + if ( mKeysToCheck.empty() ) { return; + } mListJobCount = 0; mTruncated = 0; @@ -711,11 +725,14 @@ void Kleo::KeySelectionDialog::startValidatingKeyListing() { mKeyListView->setEnabled( false ); std::vector<GpgME::Key> smime, openpgp; - for ( std::vector<GpgME::Key>::const_iterator it = mKeysToCheck.begin() ; it != mKeysToCheck.end() ; ++it ) - if ( it->protocol() == GpgME::Context::OpenPGP ) + for ( std::vector<GpgME::Key>::const_iterator it = mKeysToCheck.begin() ; it != mKeysToCheck.end() ; ++it ) { + if ( it->protocol() == GpgME::Context::OpenPGP ) { openpgp.push_back( *it ); - else + } + else { smime.push_back( *it ); + } + } if ( !openpgp.empty() ) { assert( mOpenPGPBackend ); diff --git a/config.h.cmake b/config.h.cmake index 4c4aa536f..bc498ab1f 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -17,6 +17,14 @@ // libkdemanager, certmanager #cmakedefine HAVE_GPGME_0_4_BRANCH 1 +// libtdenetwork +#cmakedefine HAVE_GPGME_KEYLIST_MODE_VALIDATE 1 +#cmakedefine HAVE_GPGME_CANCEL 1 +#cmakedefine HAVE_GPGME_KEY_T_KEYLIST_MODE 1 +#cmakedefine HAVE_GPGME_WRONG_KEY_USAGE 1 +#cmakedefine HAVE_GPGME_INCLUDE_CERTS_DEFAULT 1 +#cmakedefine HAVE_GPGME_OP_GETAUDITLOG 1 + // certmanager #cmakedefine MAX_CMD_LENGTH @MAX_CMD_LENGTH@ #cmakedefine HAVE_C99_INITIALIZERS 1 diff --git a/kmail/kmmainwidget.cpp b/kmail/kmmainwidget.cpp index 97f7922f7..daad92215 100644 --- a/kmail/kmmainwidget.cpp +++ b/kmail/kmmainwidget.cpp @@ -1767,7 +1767,7 @@ void KMMainWidget::slotStartCertManager() certManagerProc << "kleopatra"; if( !certManagerProc.start( TDEProcess::DontCare ) ) - KMessageBox::error( this, i18n( "Could not start certificate manager; " + KMessageBox::error( this, i18n( "Could not start certificate manager 'kleopatra'; " "please check your installation." ), i18n( "KMail Error" ) ); else diff --git a/libtdenetwork/gpgmepp/callbacks.cpp b/libtdenetwork/gpgmepp/callbacks.cpp index ba9c30bf0..23cc55e82 100644 --- a/libtdenetwork/gpgmepp/callbacks.cpp +++ b/libtdenetwork/gpgmepp/callbacks.cpp @@ -64,9 +64,10 @@ gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, const c bool canceled = false; gpgme_error_t err = GPG_ERR_NO_ERROR; char * passphrase = provider ? provider->getPassphrase( uid_hint, desc, prev_was_bad, canceled ) : 0 ; - if ( canceled ) + if ( canceled ) { err = makeError( GPG_ERR_CANCELED ); - else + } + else { if ( passphrase && *passphrase ) { size_t passphrase_length = strlen( passphrase ); size_t written = 0; @@ -79,7 +80,7 @@ gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, const c written += now_written; } while ( written < passphrase_length ); } - + } if ( passphrase && *passphrase ) wipe( passphrase, strlen( passphrase ) ); free( passphrase ); diff --git a/libtdenetwork/qgpgme/eventloopinteractor.cpp b/libtdenetwork/qgpgme/eventloopinteractor.cpp index 3b07189d7..b6d9830d6 100644 --- a/libtdenetwork/qgpgme/eventloopinteractor.cpp +++ b/libtdenetwork/qgpgme/eventloopinteractor.cpp @@ -30,6 +30,11 @@ #include <tqsocketnotifier.h> #include <tqapplication.h> +#include <tqvaluelist.h> + +TQValueList<int> writeActivity; +TQValueList<int> readActivity; + using namespace GpgME; QGpgME::EventLoopInteractor::EventLoopInteractor( TQObject * parent, const char * name ) @@ -77,11 +82,21 @@ void QGpgME::EventLoopInteractor::unregisterWatcher( void * tag ) { } void QGpgME::EventLoopInteractor::slotWriteActivity( int socket ) { + if (writeActivity.contains(socket)) { + return; + } + writeActivity.append(socket); actOn( socket , Write ); + writeActivity.remove(socket); } void QGpgME::EventLoopInteractor::slotReadActivity( int socket ) { + if (readActivity.contains(socket)) { + return; + } + readActivity.append(socket); actOn( socket , Read ); + readActivity.remove(socket); } void QGpgME::EventLoopInteractor::nextTrustItemEvent( GpgME::Context * context, const GpgME::TrustItem & item ) { |