Fix retriggering of GPGMe socket notifiers in nested event loops

This resolves Bug 825
Add missing GPGMe feature checks to CMake
(cherry picked from commit 7bd54f5a79)
v3.5.13-sru
Timothy Pearson 11 years ago committed by Slávek Banko
parent 0cd5714096
commit 5b94ddbf72

@ -135,6 +135,73 @@ if( BUILD_LIBKDENETWORK OR BUILD_CERTMANAGER OR BUILD_KMAIL OR BUILD_KADDRESSBOO
if( NOT HAVE_GPGME_0_4_BRANCH ) if( NOT HAVE_GPGME_0_4_BRANCH )
message( STATUS " found 'gpgme', version ${GPGME_VERSION}" ) message( STATUS " found 'gpgme', version ${GPGME_VERSION}" )
endif( ) 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( ) endif( )

@ -333,13 +333,16 @@ Kleo::KeyListViewItem * Kleo::KeyListView::itemByFingerprint( const TQCString &
void Kleo::KeyListView::slotRefreshKey( const GpgME::Key & key ) { void Kleo::KeyListView::slotRefreshKey( const GpgME::Key & key ) {
const char * fpr = key.primaryFingerprint(); const char * fpr = key.primaryFingerprint();
if ( !fpr ) if ( !fpr ) {
return; return;
if ( KeyListViewItem * item = itemByFingerprint( fpr ) ) }
if ( KeyListViewItem * item = itemByFingerprint( fpr ) ) {
item->setKey ( key ); item->setKey ( key );
else }
else {
// none found -> add it // none found -> add it
slotAddKey( key ); slotAddKey( key );
}
} }
// slots for the emission of covariant signals: // slots for the emission of covariant signals:

@ -265,29 +265,33 @@ namespace {
} }
const TQPixmap * ColumnStrategy::pixmap( const GpgME::Key & key, int col ) const { const TQPixmap * ColumnStrategy::pixmap( const GpgME::Key & key, int col ) const {
if ( col != 0 ) if ( col != 0 ) {
return 0; return 0;
}
// this key did not undergo a validating keylisting yet: // this key did not undergo a validating keylisting yet:
if ( !( key.keyListMode() & GpgME::Context::Validate ) ) if ( !( key.keyListMode() & GpgME::Context::Validate ) ) {
return &mKeyUnknownPix; return &mKeyUnknownPix;
}
if ( !checkKeyUsage( key, mKeyUsage ) ) if ( !checkKeyUsage( key, mKeyUsage ) ) {
return &mKeyBadPix; return &mKeyBadPix;
}
if ( key.protocol() == GpgME::Context::CMS ) if ( key.protocol() == GpgME::Context::CMS ) {
return &mKeyGoodPix; return &mKeyGoodPix;
}
switch ( key.userID(0).validity() ) { switch ( key.userID(0).validity() ) {
default: default:
case GpgME::UserID::Unknown: case GpgME::UserID::Unknown:
case GpgME::UserID::Undefined: case GpgME::UserID::Undefined:
return &mKeyUnknownPix; return &mKeyUnknownPix;
case GpgME::UserID::Never: case GpgME::UserID::Never:
return &mKeyValidPix; return &mKeyValidPix;
case GpgME::UserID::Marginal: case GpgME::UserID::Marginal:
case GpgME::UserID::Full: case GpgME::UserID::Full:
case GpgME::UserID::Ultimate: case GpgME::UserID::Ultimate:
return &mKeyGoodPix; return &mKeyGoodPix;
} }
} }
@ -585,8 +589,9 @@ namespace {
void Kleo::KeySelectionDialog::startKeyListJobForBackend( const CryptoBackend::Protocol * backend, const std::vector<GpgME::Key> & keys, bool validate ) { void Kleo::KeySelectionDialog::startKeyListJobForBackend( const CryptoBackend::Protocol * backend, const std::vector<GpgME::Key> & keys, bool validate ) {
assert( backend ); assert( backend );
KeyListJob * job = backend->keyListJob( false, false, validate ); // local, w/o sigs, validation as givem KeyListJob * job = backend->keyListJob( false, false, validate ); // local, w/o sigs, validation as givem
if ( !job ) if ( !job ) {
return; return;
}
connect( job, TQT_SIGNAL(result(const GpgME::KeyListResult&)), connect( job, TQT_SIGNAL(result(const GpgME::KeyListResult&)),
TQT_SLOT(slotKeyListResult(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() ); std::transform( keys.begin(), keys.end(), std::back_inserter( fprs ), ExtractFingerprint() );
const GpgME::Error err = job->start( fprs, mKeyUsage & SecretKeys && !( mKeyUsage & PublicKeys ) ); const GpgME::Error err = job->start( fprs, mKeyUsage & SecretKeys && !( mKeyUsage & PublicKeys ) );
if ( err ) if ( err ) {
return showKeyListError( this, err ); return showKeyListError( this, err );
}
// FIXME: create a MultiProgressDialog: // FIXME: create a MultiProgressDialog:
(void)new ProgressDialog( job, validate ? i18n( "Checking selected keys..." ) : i18n( "Fetching keys..." ), this ); (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 ) { void Kleo::KeySelectionDialog::slotKeyListResult( const GpgME::KeyListResult & res ) {
if ( res.error() ) if ( res.error() ) {
showKeyListError( this, res.error() ); showKeyListError( this, res.error() );
else if ( res.isTruncated() ) }
else if ( res.isTruncated() ) {
++mTruncated; ++mTruncated;
}
if ( --mListJobCount > 0 ) if ( --mListJobCount > 0 ) {
return; // not yet finished... return; // not yet finished...
}
if ( mTruncated > 0 ) if ( mTruncated > 0 ) {
KMessageBox::information( this, KMessageBox::information( this,
i18n("<qt>One backend returned truncated output.<br>" i18n("<qt>One backend returned truncated output.<br>"
"Not all available keys are shown</qt>", "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>", "Not all available keys are shown</qt>",
mTruncated), mTruncated),
i18n("Key List Result") ); i18n("Key List Result") );
}
mKeyListView->flushKeys(); mKeyListView->flushKeys();
@ -677,13 +687,16 @@ void Kleo::KeySelectionDialog::slotCheckSelection( KeyListViewItem * item ) {
mSelectedKeys.clear(); mSelectedKeys.clear();
if ( !mKeyListView->isMultiSelection() ) { if ( !mKeyListView->isMultiSelection() ) {
if ( item ) if ( item ) {
mSelectedKeys.push_back( item->key() ); mSelectedKeys.push_back( item->key() );
}
} }
for ( KeyListViewItem * it = mKeyListView->firstChild() ; it ; it = it->nextSibling() ) for ( KeyListViewItem * it = mKeyListView->firstChild() ; it ; it = it->nextSibling() ) {
if ( it->isSelected() ) if ( it->isSelected() ) {
mSelectedKeys.push_back( it->key() ); mSelectedKeys.push_back( it->key() );
}
}
mKeysToCheck.clear(); mKeysToCheck.clear();
std::remove_copy_if( mSelectedKeys.begin(), mSelectedKeys.end(), std::remove_copy_if( mSelectedKeys.begin(), mSelectedKeys.end(),
@ -700,8 +713,9 @@ void Kleo::KeySelectionDialog::slotCheckSelection( KeyListViewItem * item ) {
} }
void Kleo::KeySelectionDialog::startValidatingKeyListing() { void Kleo::KeySelectionDialog::startValidatingKeyListing() {
if ( mKeysToCheck.empty() ) if ( mKeysToCheck.empty() ) {
return; return;
}
mListJobCount = 0; mListJobCount = 0;
mTruncated = 0; mTruncated = 0;
@ -711,11 +725,14 @@ void Kleo::KeySelectionDialog::startValidatingKeyListing() {
mKeyListView->setEnabled( false ); mKeyListView->setEnabled( false );
std::vector<GpgME::Key> smime, openpgp; std::vector<GpgME::Key> smime, openpgp;
for ( std::vector<GpgME::Key>::const_iterator it = mKeysToCheck.begin() ; it != mKeysToCheck.end() ; ++it ) for ( std::vector<GpgME::Key>::const_iterator it = mKeysToCheck.begin() ; it != mKeysToCheck.end() ; ++it ) {
if ( it->protocol() == GpgME::Context::OpenPGP ) if ( it->protocol() == GpgME::Context::OpenPGP ) {
openpgp.push_back( *it ); openpgp.push_back( *it );
else }
else {
smime.push_back( *it ); smime.push_back( *it );
}
}
if ( !openpgp.empty() ) { if ( !openpgp.empty() ) {
assert( mOpenPGPBackend ); assert( mOpenPGPBackend );

@ -17,6 +17,14 @@
// libkdemanager, certmanager // libkdemanager, certmanager
#cmakedefine HAVE_GPGME_0_4_BRANCH 1 #cmakedefine HAVE_GPGME_0_4_BRANCH 1
// libkdenetwork
#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 // certmanager
#cmakedefine MAX_CMD_LENGTH @MAX_CMD_LENGTH@ #cmakedefine MAX_CMD_LENGTH @MAX_CMD_LENGTH@
#cmakedefine HAVE_C99_INITIALIZERS 1 #cmakedefine HAVE_C99_INITIALIZERS 1

@ -1767,7 +1767,7 @@ void KMMainWidget::slotStartCertManager()
certManagerProc << "kleopatra"; certManagerProc << "kleopatra";
if( !certManagerProc.start( KProcess::DontCare ) ) if( !certManagerProc.start( KProcess::DontCare ) )
KMessageBox::error( this, i18n( "Could not start certificate manager; " KMessageBox::error( this, i18n( "Could not start certificate manager 'kleopatra'; "
"please check your installation." ), "please check your installation." ),
i18n( "KMail Error" ) ); i18n( "KMail Error" ) );
else else

@ -64,9 +64,10 @@ gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, const c
bool canceled = false; bool canceled = false;
gpgme_error_t err = GPG_ERR_NO_ERROR; gpgme_error_t err = GPG_ERR_NO_ERROR;
char * passphrase = provider ? provider->getPassphrase( uid_hint, desc, prev_was_bad, canceled ) : 0 ; char * passphrase = provider ? provider->getPassphrase( uid_hint, desc, prev_was_bad, canceled ) : 0 ;
if ( canceled ) if ( canceled ) {
err = makeError( GPG_ERR_CANCELED ); err = makeError( GPG_ERR_CANCELED );
else }
else {
if ( passphrase && *passphrase ) { if ( passphrase && *passphrase ) {
size_t passphrase_length = strlen( passphrase ); size_t passphrase_length = strlen( passphrase );
size_t written = 0; size_t written = 0;
@ -79,7 +80,7 @@ gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, const c
written += now_written; written += now_written;
} while ( written < passphrase_length ); } while ( written < passphrase_length );
} }
}
if ( passphrase && *passphrase ) if ( passphrase && *passphrase )
wipe( passphrase, strlen( passphrase ) ); wipe( passphrase, strlen( passphrase ) );
free( passphrase ); free( passphrase );

@ -30,6 +30,11 @@
#include <tqsocketnotifier.h> #include <tqsocketnotifier.h>
#include <tqapplication.h> #include <tqapplication.h>
#include <tqvaluelist.h>
TQValueList<int> writeActivity;
TQValueList<int> readActivity;
using namespace GpgME; using namespace GpgME;
QGpgME::EventLoopInteractor::EventLoopInteractor( TQObject * parent, const char * name ) QGpgME::EventLoopInteractor::EventLoopInteractor( TQObject * parent, const char * name )
@ -77,11 +82,21 @@ void QGpgME::EventLoopInteractor::unregisterWatcher( void * tag ) {
} }
void QGpgME::EventLoopInteractor::slotWriteActivity( int socket ) { void QGpgME::EventLoopInteractor::slotWriteActivity( int socket ) {
if (writeActivity.contains(socket)) {
return;
}
writeActivity.append(socket);
actOn( socket , Write ); actOn( socket , Write );
writeActivity.remove(socket);
} }
void QGpgME::EventLoopInteractor::slotReadActivity( int socket ) { void QGpgME::EventLoopInteractor::slotReadActivity( int socket ) {
if (readActivity.contains(socket)) {
return;
}
readActivity.append(socket);
actOn( socket , Read ); actOn( socket , Read );
readActivity.remove(socket);
} }
void QGpgME::EventLoopInteractor::nextTrustItemEvent( GpgME::Context * context, const GpgME::TrustItem & item ) { void QGpgME::EventLoopInteractor::nextTrustItemEvent( GpgME::Context * context, const GpgME::TrustItem & item ) {

Loading…
Cancel
Save